[cdo] 01/16: new upstream 1.9.1

Alastair McKinstry mckinstry at moszumanska.debian.org
Wed Oct 25 08:21:38 UTC 2017


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

mckinstry pushed a commit to branch debian/master
in repository cdo.

commit e3888adaaeaf028e4e3ee3dcd5ebc8bd4224114d
Author: Alastair McKinstry <mckinstry at debian.org>
Date:   Fri Oct 13 10:02:09 2017 +0100

    new upstream 1.9.1
---
 ChangeLog                                          |    72 +
 Makefile.am                                        |     2 +-
 Makefile.in                                        |     2 +-
 NEWS                                               |    20 +-
 OPERATORS                                          |     9 +
 cdo.spec                                           |     6 +-
 cdo.spec.in                                        |     4 +-
 config/default                                     |    14 +-
 configure                                          |    24 +-
 configure.ac                                       |     4 +-
 contrib/cdoCompletion.bash                         |     9 +-
 contrib/cdoCompletion.tcsh                         |     9 +-
 contrib/cdoCompletion.zsh                          |     9 +-
 doc/cdo.pdf                                        |   Bin 2716247 -> 2720332 bytes
 doc/cdo_cmor.pdf                                   |   Bin 0 -> 261892 bytes
 doc/cdo_eca.pdf                                    |   Bin 215421 -> 214702 bytes
 doc/cdo_magics.pdf                                 |   Bin 829886 -> 829854 bytes
 doc/cdo_refcard.pdf                                |   Bin 96906 -> 97632 bytes
 libcdi/ChangeLog                                   |    52 +
 libcdi/app/cdi.c                                   |    36 +-
 libcdi/app/printinfo.h                             |    58 +-
 libcdi/configure                                   |    22 +-
 libcdi/configure.ac                                |     2 +-
 libcdi/doc/cdi_cman.pdf                            |   Bin 337122 -> 335148 bytes
 libcdi/doc/cdi_fman.pdf                            |   Bin 365396 -> 363677 bytes
 libcdi/examples/Makefile.am                        |     7 +-
 libcdi/examples/Makefile.in                        |    24 +-
 libcdi/examples/cdi_write.c                        |     4 +-
 libcdi/examples/cdi_write_const.c                  |     4 +-
 libcdi/examples/cdi_write_ens.c                    |     2 +-
 libcdi/examples/cdi_write_f2003.f90                |     4 +-
 libcdi/examples/cdi_write_hybrid.c                 |     8 +-
 .../examples/{cdi_write.c => cdi_write_relativ.c}  |     6 +-
 libcdi/interfaces/cdi.cpp                          |     4 +-
 libcdi/interfaces/python/table.py                  |     2 +-
 libcdi/src/Makefile.am                             |     1 +
 libcdi/src/Makefile.in                             |    28 +-
 libcdi/src/calendar.c                              |     2 +-
 libcdi/src/cdf.c                                   |    88 +-
 libcdi/src/cdf.h                                   |     9 +-
 libcdi/src/cdf_config.h                            |    18 +
 libcdi/src/cdf_int.h                               |     6 +-
 libcdi/src/cdf_read.c                              |    17 +-
 libcdi/src/cdf_util.c                              |     5 +-
 libcdi/src/cdf_write.c                             |    52 +-
 libcdi/src/cdi.h                                   |    48 +-
 libcdi/src/cdi.inc                                 |    63 +-
 libcdi/src/cdiFortran.c                            |    11 +-
 libcdi/src/cdi_int.c                               |    98 +-
 libcdi/src/cdi_int.h                               |     8 +-
 libcdi/src/cdilib.c                                | 28671 +++++++++----------
 libcdi/src/cgribexlib.c                            |  1438 +-
 libcdi/src/grid.c                                  |    68 +-
 libcdi/src/grid.h                                  |     2 +-
 libcdi/src/iterator.c                              |    19 +-
 libcdi/src/iterator_fallback.c                     |     2 +-
 libcdi/src/mo_cdi.f90                              |    84 +-
 libcdi/src/pio_server.c                            |     3 +
 libcdi/src/stream.c                                |   227 +-
 libcdi/src/stream_cdf_i.c                          |   119 +-
 libcdi/src/stream_cdf_o.c                          |    90 +-
 libcdi/src/stream_cdf_time.c                       |    27 +-
 libcdi/src/stream_cgribex.c                        |    18 +-
 libcdi/src/stream_ext.c                            |     8 +-
 libcdi/src/stream_gribapi.c                        |     6 +-
 libcdi/src/stream_history.c                        |     8 +-
 libcdi/src/stream_ieg.c                            |     6 +-
 libcdi/src/stream_read.c                           |     3 +
 libcdi/src/stream_record.c                         |    14 +-
 libcdi/src/stream_srv.c                            |     4 +-
 libcdi/src/stream_write.c                          |     4 +
 libcdi/src/table.c                                 |     1 +
 libcdi/src/taxis.c                                 |    18 +-
 libcdi/src/timebase.c                              |     4 +-
 libcdi/src/varscan.c                               |    30 +-
 libcdi/src/vlist.c                                 |    26 +-
 libcdi/src/vlist.h                                 |     2 +-
 libcdi/src/vlist_var.c                             |    62 +-
 libcdi/src/zaxis.c                                 |    30 +-
 libcdi/src/zaxis.h                                 |     2 +-
 libcdi/tests/test_cdf_const.in                     |     6 +-
 libcdi/tests/test_cdf_write.c                      |     2 +-
 libcdi/tests/test_resource_copy.c                  |     6 +-
 src/Adisit.cc                                      |     4 +-
 src/Afterburner.cc                                 |   154 +-
 src/Arith.cc                                       |    15 +-
 src/CDIread.cc                                     |     1 +
 src/CDIwrite.cc                                    |     3 +-
 src/CMOR.cc                                        |  2767 +-
 src/Cat.cc                                         |     6 +-
 src/Change_e5slm.cc                                |     8 +-
 src/Cloudlayer.cc                                  |     8 +-
 src/Consecstat.cc                                  |     2 +-
 src/Copy.cc                                        |     8 +-
 src/Derivepar.cc                                   |     4 +-
 src/Detrend.cc                                     |    29 +-
 src/Distgrid.cc                                    |     2 +-
 src/Duplicate.cc                                   |     4 +-
 src/EOFs.cc                                        |   141 +-
 src/Echam5ini.cc                                   |     4 +-
 src/Enlarge.cc                                     |     1 +
 src/Enlargegrid.cc                                 |     1 +
 src/Ensstat.cc                                     |     4 +-
 src/Ensstat3.cc                                    |     2 +-
 src/Eof3d.cc                                       |   157 +-
 src/Eofcoeff.cc                                    |    25 +-
 src/Eofcoeff3d.cc                                  |    45 +-
 src/EstFreq.cc                                     |   161 +
 src/Exprf.cc                                       |     4 +-
 src/Filedes.cc                                     |     1 +
 src/Fillmiss.cc                                    |    39 +-
 src/Filter.cc                                      |     9 +-
 src/Fldstat.cc                                     |    23 +-
 src/Fldstat2.cc                                    |    23 +-
 src/Gengrid.cc                                     |     6 +-
 src/Gradsdes.cc                                    |    12 +-
 src/Gridcell.cc                                    |     2 +-
 src/Hi.cc                                          |     2 +-
 src/Importamsr.cc                                  |     6 +-
 src/Importbinary.cc                                |    12 +-
 src/Importcmsaf.cc                                 |     6 +-
 src/Importobs.cc                                   |     2 +-
 src/Input.cc                                       |     2 +-
 src/Intgrid.cc                                     |     1 +
 src/Intgridtraj.cc                                 |    35 +-
 src/Intlevel.cc                                    |     2 +-
 src/Intlevel3d.cc                                  |     2 +-
 src/Makefile.am                                    |     3 +
 src/Makefile.in                                    |   120 +-
 src/MapReduce.cc                                   |     1 +
 src/Merge.cc                                       |     4 +-
 src/Mergetime.cc                                   |     2 +-
 src/Mrotuv.cc                                      |     4 +-
 src/Mrotuvb.cc                                     |     2 +-
 src/Pressure.cc                                    |     2 +-
 src/Remap.cc                                       |   135 +-
 src/Remapeta.cc                                    |  1003 +-
 src/Rhopot.cc                                      |     2 +-
 src/Runpctl.cc                                     |     5 +-
 src/Runstat.cc                                     |     3 +-
 src/Samplegridicon.cc                              |   230 +-
 src/Seascount.cc                                   |     2 +-
 src/Seaspctl.cc                                    |     5 +-
 src/Seasstat.cc                                    |     3 +-
 src/Selbox.cc                                      |     6 +-
 src/Select.cc                                      |    29 +-
 src/Selmulti.cc                                    |     4 +-
 src/Selrec.cc                                      |     5 +-
 src/Seltime.cc                                     |    12 +-
 src/Selvar.cc                                      |     2 +-
 src/Setgrid.cc                                     |     5 +-
 src/Sethalo.cc                                     |     8 +-
 src/Settime.cc                                     |    23 +-
 src/Showattribute.cc                               |   192 +
 src/Showattribute.h                                |     1 +
 src/Showinfo.cc                                    |    37 +-
 src/Sinfo.cc                                       |    27 +-
 src/Smooth.cc                                      |    28 +-
 src/Sort.cc                                        |     2 +-
 src/Split.cc                                       |     2 +-
 src/Splitrec.cc                                    |     2 +-
 src/Splitsel.cc                                    |    14 +-
 src/Splittime.cc                                   |    12 +-
 src/Splityear.cc                                   |    12 +-
 src/Timcount.cc                                    |     2 +-
 src/Timpctl.cc                                     |     5 +-
 src/Timselpctl.cc                                  |     5 +-
 src/Timselstat.cc                                  |     5 +-
 src/Timsort.cc                                     |     2 +-
 src/Timstat.cc                                     |     8 +-
 src/Trend.cc                                       |    12 +-
 src/Vargen.cc                                      |     7 +-
 src/Verifygrid.cc                                  |     9 +-
 src/Vertcum.cc                                     |     2 +-
 src/Vertintap.cc                                   |   198 +-
 src/Vertintml.cc                                   |    24 +-
 src/Wct.cc                                         |     2 +-
 src/WindTrans.cc                                   |     2 +-
 src/XTimstat.cc                                    |    22 +-
 src/YAR.cc                                         |   123 +-
 src/Ydaypctl.cc                                    |     4 +-
 src/Ydaystat.cc                                    |     2 +-
 src/Ydrunpctl.cc                                   |     6 +-
 src/Ydrunstat.cc                                   |    10 +-
 src/Yearmonstat.cc                                 |     7 +-
 src/Yhourstat.cc                                   |     2 +-
 src/Ymonpctl.cc                                    |     4 +-
 src/Ymonstat.cc                                    |     2 +-
 src/Yseaspctl.cc                                   |     4 +-
 src/Yseasstat.cc                                   |     2 +-
 src/after_fctrans.cc                               |   263 +-
 src/after_sptrans.cc                               |    29 +-
 src/after_vertint.cc                               |    24 +-
 src/afterburner.h                                  |     1 +
 src/afterburnerlib.cc                              |    77 +-
 src/argument.cc                                    |    41 +-
 src/argument.h                                     |     4 +-
 src/cdo.cc                                         |    34 +-
 src/cdo_int.h                                      |     6 +
 src/cdo_task.h                                     |     2 +-
 src/cdo_vlist.cc                                   |     7 +-
 src/cdotest.cc                                     |     2 +-
 src/clipping/area.c                                |    18 +-
 src/clipping/area.h                                |     2 +-
 src/clipping/clipping.c                            |    50 +-
 src/clipping/clipping.h                            |     2 +-
 src/clipping/dep_list.h                            |     2 +-
 src/clipping/ensure_array_size.c                   |     2 +-
 src/clipping/ensure_array_size.h                   |     2 +-
 src/clipping/geometry.h                            |    15 +-
 src/clipping/grid.h                                |     6 +-
 src/clipping/grid_cell.c                           |    42 +-
 src/clipping/grid_cell.h                           |    14 +-
 src/clipping/intersection.c                        |    56 +-
 src/clipping/points.h                              |    34 +-
 src/clipping/utils.c                               |     2 +-
 src/clipping/utils.h                               |     8 +-
 src/ecacore.cc                                     |    20 +-
 src/exception.cc                                   |    21 +-
 src/expr.cc                                        |     7 +-
 src/features.cc                                    |     6 +
 src/field.h                                        |     1 +
 src/field2.cc                                      |    53 +-
 src/functs.h                                       |     1 +
 src/gradsdeslib.cc                                 |     2 +-
 src/grid.cc                                        |    49 +-
 src/grid.h                                         |     2 +
 src/grid_define.cc                                 |     4 +-
 src/grid_print.cc                                  |     2 +-
 src/grid_proj.cc                                   |     8 +-
 src/grid_read.cc                                   |    15 +-
 src/grid_search.cc                                 |   108 +-
 src/grid_search.h                                  |    24 +-
 src/griddes.cc                                     |    10 +-
 src/griddes.h                                      |     2 +-
 src/griddes_h5.cc                                  |     4 +-
 src/griddes_nc.cc                                  |    17 +-
 src/hetaeta.cc                                     |   382 +-
 src/interpol.cc                                    |     4 +-
 src/job.cc                                         |     8 +-
 src/kdtreelib/kdtree_cartesian.cc                  |    37 +-
 src/magics_template_parser.cc                      |     4 +
 src/modules.cc                                     |    62 +-
 src/modules.h                                      |     5 +-
 src/operator_help.h                                |   143 +-
 src/pipe.cc                                        |   118 +-
 src/pipe.h                                         |    11 +-
 src/pmlist.cc                                      |     7 +-
 src/printinfo.h                                    |    58 +-
 src/process.cc                                     |  1075 +-
 src/process.h                                      |    47 +-
 src/pstream.cc                                     |   717 +-
 src/pstream.h                                      |    24 +-
 src/pthread_debug.cc                               |    42 +-
 src/pthread_debug.h                                |     8 +
 src/remap.h                                        |    82 +-
 src/remap_bicubic_scrip.cc                         |     8 +-
 src/remap_bilinear_scrip.cc                        |    12 +-
 src/remap_conserv.cc                               |   171 +-
 src/remap_conserv_scrip.cc                         |   450 +-
 src/remap_distwgt.cc                               |   190 +-
 src/remap_scrip_io.cc                              |    78 +-
 src/remap_search_latbins.cc                        |    78 +-
 src/remap_search_reg2d.cc                          |    25 +-
 src/remap_store_link.cc                            |    40 +-
 src/remap_store_link.h                             |    20 +-
 src/remap_store_link_cnsrv.cc                      |    30 +-
 src/remap_store_link_cnsrv.h                       |    14 +-
 src/remaplib.cc                                    |   309 +-
 src/remapsort.cc                                   |    98 +-
 src/specspace.cc                                   |     2 +-
 src/util.cc                                        |    12 +-
 src/util.h                                         |     2 +-
 src/zaxis.cc                                       |    77 +-
 src/zaxis_print.cc                                 |    17 +-
 test/EOF.test.in                                   |    13 +-
 test/File.test.in                                  |     2 +
 test/Makefile.am                                   |     2 +-
 test/Makefile.in                                   |    53 +-
 test/Multiyearstat.test.in                         |    23 +-
 test/README                                        |     2 +-
 test/Remapeta.test.in                              |    47 +
 test/Runstat.test.in                               |    23 +-
 test/Seasstat.test.in                              |    23 +-
 test/Timselstat.test.in                            |    23 +-
 test/Timstat.test.in                               |    23 +-
 test/Ydrunstat.test.in                             |    23 +-
 test/data/Makefile.am                              |     3 +-
 test/data/Makefile.in                              |     3 +-
 test/data/VCT.L62                                  |    63 +
 test/data/grib_testfile01_sinfo_ref                |     4 +-
 test/data/grib_testfile02_sinfo_ref                |     4 +-
 test/data/grib_testfile03_sinfo_ref                |     4 +-
 test/data/netcdf_testfile01_sinfon_ref             |     4 +-
 test/data/netcdf_testfile02_sinfon_ref             |     4 +-
 test/data/remapeta1.nc                             |   Bin 0 -> 4696 bytes
 test/data/remapeta2.nc                             |   Bin 0 -> 6128 bytes
 test/data/remapeta_ref                             |   Bin 0 -> 7004 bytes
 298 files changed, 22651 insertions(+), 21311 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 51cdfe2..5a3dfee 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,75 @@
+2017-10-05  Uwe Schulzweida
+
+	* Using CDI library version 1.9.1
+	* Version 1.9.1 release
+
+2017-10-04  Uwe Schulzweida
+
+	* Added operator setmiss
+	* CMOR: Fix building error [Bug #7936]
+
+2017-09-30  Uwe Schulzweida
+
+	* sinfo: Added time type
+
+2017-09-28  Uwe Schulzweida
+
+	* Changed NFFT from 64 to 8
+
+2017-09-22  Uwe Schulzweida
+
+	* fc2gp: optimize memory handling for openmp version
+
+2017-09-22  Uwe Schulzweida
+
+	* setgrid: added key word datatype (float/double)
+	* setzaxis: added key word datatype (float/double)
+	* setzaxis: check attributes for reserved key names
+
+2017-09-20  Uwe Schulzweida
+
+	* Added support for NC_FORMAT_CDF5
+
+2017-09-19  Uwe Schulzweida
+
+	* expr: AND fall through OR (bug fix)
+
+2017-09-16  Uwe Schulzweida
+
+	* remap: added support for grid_mapping attribute proj4_params (bug fix)
+
+2017-09-11  Uwe Schulzweida
+
+	* ap2pl: added support for input data on half levels
+
+2017-09-09  Uwe Schulzweida
+
+	* selindexbox: breaks uvRelativeToGrid flag [Bug #7901]
+	* grid_copy_attributes: copy flag uvRelativeToGrid
+
+2017-09-01  Uwe Schulzweida
+
+	* Implementation of option --reduce_dim for z axis
+
+2017-08-31  Uwe Schulzweida
+
+	* Implementation of option --reduce_dim for time axis
+	* Implementation of option --reduce_dim for x/y axis
+
+2017-08-30  Uwe Schulzweida
+
+	* tee: added docu
+	* eof: check missing values
+
+2017-08-14  Uwe Schulzweida
+
+	* eof, eof3d: set default of env. CDO_WEIGHT_MODE to off
+	* eof3d, eofcoeff3d: preserve variable name on output files [report: Frank Kauker]
+
+2017-08-12  Uwe Schulzweida
+
+	* eof3d: weight was allocated for only one level (bug fix) [report: Frank Kauker]
+
 2017-07-27  Uwe Schulzweida
 
 	* Using CDI library version 1.9.0
diff --git a/Makefile.am b/Makefile.am
index df6b08d..73f00df 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,7 @@
 # Process this file with automake to produce Makefile.in
 SUBDIRS = libcdi src contrib test/data test
 #
-EXTRA_DIST=config/default OPERATORS doc/cdo.pdf doc/cdo_eca.pdf doc/cdo_magics.pdf doc/cdo_refcard.pdf cdo.spec README
+EXTRA_DIST=config/default OPERATORS doc/cdo.pdf doc/cdo_cmor.pdf doc/cdo_eca.pdf doc/cdo_magics.pdf doc/cdo_refcard.pdf cdo.spec README
 #
 ACLOCAL_AMFLAGS = -I m4
 #
diff --git a/Makefile.in b/Makefile.in
index 47b7a81..8a5cb0f 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -384,7 +384,7 @@ top_srcdir = @top_srcdir@
 # Process this file with automake to produce Makefile.in
 SUBDIRS = libcdi src contrib test/data test
 #
-EXTRA_DIST = config/default OPERATORS doc/cdo.pdf doc/cdo_eca.pdf doc/cdo_magics.pdf doc/cdo_refcard.pdf cdo.spec README
+EXTRA_DIST = config/default OPERATORS doc/cdo.pdf doc/cdo_cmor.pdf doc/cdo_eca.pdf doc/cdo_magics.pdf doc/cdo_refcard.pdf cdo.spec README
 #
 ACLOCAL_AMFLAGS = -I m4
 #
diff --git a/NEWS b/NEWS
index 7d3895b..f938a48 100644
--- a/NEWS
+++ b/NEWS
@@ -1,10 +1,28 @@
 CDO NEWS
 --------
 
-Version 1.9.0 (27 August 2017):
+Version 1.9.1 (27 September 2017):
+
+   New features:
+     * Added support for NC_FORMAT_CDF5
+     * Extend option --reduce_dim to all dimension for all operators
+   New operators:
+     * tee - Duplicate a data stream
+   Changes operators:
+     * eof, eof3d: set default value of environment variable CDO_WEIGHT_MODE to off
+     * sinfo: Added time type
+     * ap2pl: added support for input data on half levels
+   Fixed bugs:
+     * selindexbox: breaks uvRelativeToGrid flag [Bug #7901]
+     * expr: AND fall through OR
+     * --cmor option doesn't work for lon/lat bounds (introduced in 1.9.0)
+     * eof3d: weight array was allocated for only one level
+
+Version 1.9.0 (27 July 2017):
 
    New features:
      * Code changed from ANSI C99 to ISO C++11
+     * Added configure option for ecCodes --with-eccodes=<yes|no|directory>
      * Added range operator to all statistic modules (e.g. yearrange, zonrange)
    Fixed bugs:
      * expr: improve ternary operator, no brackets needed anymore.
diff --git a/OPERATORS b/OPERATORS
index 890c745..15828bc 100644
--- a/OPERATORS
+++ b/OPERATORS
@@ -26,6 +26,8 @@ Operator catalog:
    Showinfo      showcode        Show code numbers
    Showinfo      showname        Show variable names
    Showinfo      showstdname     Show standard names
+   Showinfo      showatts        Show all attributes
+   Showinfo      showattsglob    Show all global attributes
    Showinfo      showlevel       Show levels
    Showinfo      showltype       Show GRIB level types
    Showinfo      showyear        Show years
@@ -33,6 +35,8 @@ Operator catalog:
    Showinfo      showdate        Show date information
    Showinfo      showtime        Show time information
    Showinfo      showtimestamp   Show timestamp
+   Showattribute showattribute   Show a global attribute or a variable attribute
+   Showattribute showattsvar     Show all variable attributes.
    Filedes       partab          Parameter table
    Filedes       codetab         Parameter code table
    Filedes       griddes         Grid description
@@ -43,6 +47,7 @@ Operator catalog:
 -------------------------------------------------------------
    Copy          copy            Copy datasets
    Copy          cat             Concatenate datasets
+   Tee           tee             Duplicate a data stream
    Replace       replace         Replace variables
    Duplicate     duplicate       Duplicates a dataset
    Mergegrid     mergegrid       Merge grid
@@ -578,6 +583,10 @@ Operator catalog:
    Hurr          hurr            Hurricane days index per time period
    CMORlite      cmorlite        CMOR lite
 -------------------------------------------------------------
+   CMOR
+-------------------------------------------------------------
+   CMOR          cmor            Climate Model Output Rewriting
+-------------------------------------------------------------
    Magics
 -------------------------------------------------------------
    Magplot       contour         Contour plot
diff --git a/cdo.spec b/cdo.spec
index d1bd5c8..501232c 100644
--- a/cdo.spec
+++ b/cdo.spec
@@ -4,14 +4,14 @@
 
 Name:           cdo
 #BuildRequires:  
-Version:        1.9.0
+Version:        1.9.1
 Release:        1
 Summary:        Climate Data Operators
 License:        GNU GENERAL PUBLIC LICENSE Version 2, June 1991
 Group:          Productivity/Graphics/Visualization/Other
 Requires:       netcdf
 Autoreqprov:    on
-URL:            https://code.zmaw.de/projects/cdo
+URL:            https://code.mpimet.mpg.de/projects/cdo
 Source0:        cdo-%{version}.tar.gz
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 
@@ -29,7 +29,7 @@ Authors:
     Luis Kornblueh, <luis.kornblueh AT mpimet.mpg.de>
     Cedrick Ansorge, <cedrick.ansorge AT mpimet.mpg.de>
     Ralf Quast, <ralf.quast AT brockmann-consult.de>
-    Send questions, comments and bug reports to <https://code.zmaw.de/projects/cdo>
+    Send questions, comments and bug reports to <https://code.mpimet.mpg.de/projects/cdo>
 
 
 %prep
diff --git a/cdo.spec.in b/cdo.spec.in
index 057833d..94effc5 100644
--- a/cdo.spec.in
+++ b/cdo.spec.in
@@ -11,7 +11,7 @@ License:        GNU GENERAL PUBLIC LICENSE Version 2, June 1991
 Group:          Productivity/Graphics/Visualization/Other
 Requires:       netcdf
 Autoreqprov:    on
-URL:            https://code.zmaw.de/projects/cdo
+URL:            https://code.mpimet.mpg.de/projects/cdo
 Source0:        cdo-%{version}.tar.gz
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 
@@ -29,7 +29,7 @@ Authors:
     Luis Kornblueh, <luis.kornblueh AT mpimet.mpg.de>
     Cedrick Ansorge, <cedrick.ansorge AT mpimet.mpg.de>
     Ralf Quast, <ralf.quast AT brockmann-consult.de>
-    Send questions, comments and bug reports to <https://code.zmaw.de/projects/cdo>
+    Send questions, comments and bug reports to <https://code.mpimet.mpg.de/projects/cdo>
 
 
 %prep
diff --git a/config/default b/config/default
index 9430c05..e5600d6 100755
--- a/config/default
+++ b/config/default
@@ -48,7 +48,7 @@ case "${HOSTNAME}" in
                     $CDOLIBS \
                     LDFLAGS="-Wl,-rpath,$HOME/local/eccodes-2.3.0/lib -Wl,-rpath,/opt/intel/lib" \
 	            CXX=icpc CXXFLAGS="-g -Wall -O2 -qopt-report=5 -march=native" \
-	            CC=icc   CFLAGS="-g -Wall -O2 -qopt-report=5 -march=native"
+	            CC=icc   CFLAGS="-g -Wall -O2 -qopt-report=5 -march=native -fp-model strict"
         elif  test "$COMP" = clang ; then
 	  ${CONFPATH}configure --prefix=$HOME/local \
                     --enable-maintainer-mode \
@@ -104,13 +104,13 @@ case "${HOSTNAME}" in
                  --with-proj=/opt/local"
 
         if  test "$COMP" = intel ; then
-	  ${CONFPATH}configure --prefix=$HOME/local --disable-openmp \
-                    $CDOLIBS \
+	  ${CONFPATH}configure --prefix=$HOME/local \
+                    $CDOLIBS LDFLAGS="-Wl,-rpath,$HOME/local/eccodes-2.3.0/lib" \
 	            CXX=icpc CXXFLAGS="-g -Wall -O2 -qopt-report=5 -march=native" \
 	            CC=icc   CFLAGS="-g -Wall -O2 -qopt-report=5 -march=native"
         elif  test "$COMP" = clang ; then
 	  ${CONFPATH}configure \
-                    $CDOLIBS \
+                    $CDOLIBS LDFLAGS="-Wl,-rpath,$HOME/local/eccodes-2.3.0/lib" \
 	            CXX=clang++ CXXFLAGS="-g -Wall -pedantic -O3" \
 	            CC=clang    CFLAGS="-g -Wall -pedantic -O3"
         elif  test "$COMP" = clang4 ; then
@@ -120,7 +120,7 @@ case "${HOSTNAME}" in
 	            CC=clang-mp-4.0    CFLAGS="-g -Wall -pedantic -O3"
         elif  test "$COMP" = pgi ; then
 	  ${CONFPATH}configure --disable-openmp \
-                    $CDOLIBS \
+                    $CDOLIBS LDFLAGS="-Wl,-rpath,$HOME/local/eccodes-2.3.0/lib" \
 	            CXX=pgc++ CXXFLAGS="-g -fast" \
 	            CC=pgcc   CFLAGS="-g -fast"
         else
@@ -231,8 +231,8 @@ case "${HOSTNAME}" in
                     --with-fftw3 \
                     $CDOLIBS \
                     LDFLAGS="-Wl,-rpath,/sw/rhel6-x64/eccodes/eccodes-2.3.0-gcc48/lib" \
-	            CXX=icpc CXXFLAGS="-g -Wall -O2 -qopt-report=5 -march=native" \
-	            CC=icc   CFLAGS="-g -Wall -O2 -qopt-report=5 -march=native"
+	            CXX=icpc CXXFLAGS="-g -Wall -O2 -qopt-report=5 -march=core-avx2" \
+	            CC=icc   CFLAGS="-g -Wall -O2 -qopt-report=5 -march=core-avx2"
         elif  test "$COMP" = pgi ; then
           ${CONFPATH}configure --disable-openmp \
                     $CDOLIBS \
diff --git a/configure b/configure
index 0c857de..a5ddc92 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for cdo 1.9.0.
+# Generated by GNU Autoconf 2.68 for cdo 1.9.1.
 #
 # Report bugs to <http://mpimet.mpg.de/cdo>.
 #
@@ -570,8 +570,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='cdo'
 PACKAGE_TARNAME='cdo'
-PACKAGE_VERSION='1.9.0'
-PACKAGE_STRING='cdo 1.9.0'
+PACKAGE_VERSION='1.9.1'
+PACKAGE_STRING='cdo 1.9.1'
 PACKAGE_BUGREPORT='http://mpimet.mpg.de/cdo'
 PACKAGE_URL=''
 
@@ -1401,7 +1401,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.9.0 to adapt to many kinds of systems.
+\`configure' configures cdo 1.9.1 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1471,7 +1471,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of cdo 1.9.0:";;
+     short | recursive ) echo "Configuration of cdo 1.9.1:";;
    esac
   cat <<\_ACEOF
 
@@ -1623,7 +1623,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-cdo configure 1.9.0
+cdo configure 1.9.1
 generated by GNU Autoconf 2.68
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -2216,7 +2216,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.9.0, which was
+It was created by cdo $as_me 1.9.1, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
@@ -3165,7 +3165,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='cdo'
- VERSION='1.9.0'
+ VERSION='1.9.1'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -22387,7 +22387,7 @@ ac_config_files="$ac_config_files test/File.test test/Read_grib.test test/Read_n
 
 ac_config_files="$ac_config_files test/Comp.test test/Compc.test"
 
-ac_config_files="$ac_config_files test/Cat.test test/Gridarea.test test/Genweights.test test/Remap.test test/Remap2.test"
+ac_config_files="$ac_config_files test/Cat.test test/Gridarea.test test/Genweights.test test/Remap.test test/Remap2.test test/Remapeta.test"
 
 ac_config_files="$ac_config_files test/EOF.test test/Select.test test/Spectral.test test/Vertint.test"
 
@@ -22983,7 +22983,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.9.0, which was
+This file was extended by cdo $as_me 1.9.1, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -23049,7 +23049,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-cdo config.status 1.9.0
+cdo config.status 1.9.1
 configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
@@ -23567,6 +23567,7 @@ do
     "test/Genweights.test") CONFIG_FILES="$CONFIG_FILES test/Genweights.test" ;;
     "test/Remap.test") CONFIG_FILES="$CONFIG_FILES test/Remap.test" ;;
     "test/Remap2.test") CONFIG_FILES="$CONFIG_FILES test/Remap2.test" ;;
+    "test/Remapeta.test") CONFIG_FILES="$CONFIG_FILES test/Remapeta.test" ;;
     "test/EOF.test") CONFIG_FILES="$CONFIG_FILES test/EOF.test" ;;
     "test/Select.test") CONFIG_FILES="$CONFIG_FILES test/Select.test" ;;
     "test/Spectral.test") CONFIG_FILES="$CONFIG_FILES test/Spectral.test" ;;
@@ -25101,6 +25102,7 @@ _LT_EOF
     "test/Genweights.test":F) chmod a+x "$ac_file" ;;
     "test/Remap.test":F) chmod a+x "$ac_file" ;;
     "test/Remap2.test":F) chmod a+x "$ac_file" ;;
+    "test/Remapeta.test":F) chmod a+x "$ac_file" ;;
     "test/EOF.test":F) chmod a+x "$ac_file" ;;
     "test/Select.test":F) chmod a+x "$ac_file" ;;
     "test/Spectral.test":F) chmod a+x "$ac_file" ;;
diff --git a/configure.ac b/configure.ac
index b0faa81..0e21606 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4,7 +4,7 @@
 #  autoconf 2.68
 #  libtool  2.4.2
 
-AC_INIT([cdo], [1.9.0], [http://mpimet.mpg.de/cdo])
+AC_INIT([cdo], [1.9.1], [http://mpimet.mpg.de/cdo])
 
 AC_DEFINE_UNQUOTED(CDO, ["$PACKAGE_VERSION"], [CDO version])
 
@@ -260,7 +260,7 @@ 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/Comp.test test/Compc.test],[chmod a+x "$ac_file"])
-AC_CONFIG_FILES([test/Cat.test test/Gridarea.test test/Genweights.test test/Remap.test test/Remap2.test],[chmod a+x "$ac_file"])
+AC_CONFIG_FILES([test/Cat.test test/Gridarea.test test/Genweights.test test/Remap.test test/Remap2.test test/Remapeta.test],[chmod a+x "$ac_file"])
 AC_CONFIG_FILES([test/EOF.test test/Select.test test/Spectral.test test/Vertint.test],[chmod a+x "$ac_file"])
 AC_CONFIG_FILES([test/Timstat.test test/Timselstat.test test/Seasstat.test test/Runstat.test test/Multiyearstat.test test/Ydrunstat.test],[chmod a+x "$ac_file"])
 AC_CONFIG_FILES([test/Gridboxstat.test test/Vertstat.test test/Fldstat.test test/Fldpctl.test test/Ensstat.test test/Enspctl.test],[chmod a+x "$ac_file"])
diff --git a/contrib/cdoCompletion.bash b/contrib/cdoCompletion.bash
index f9b93af..4bc3ce8 100644
--- a/contrib/cdoCompletion.bash
+++ b/contrib/cdoCompletion.bash
@@ -9,7 +9,7 @@ complete -W "
 --precision \
 --reduce_dim \
 --remap_genweights \
---sort \
+--sortname \
 --timestat_date \
 -C, \
 -L \
@@ -69,6 +69,7 @@ chtabnum -chtabnum \
 chunit -chunit \
 chvar -chvar \
 cloudlayer -cloudlayer \
+cmor -cmor \
 cmorlite -cmorlite \
 codetab -codetab \
 collgrid -collgrid \
@@ -191,6 +192,7 @@ eofspatial -eofspatial \
 eoftime -eoftime \
 eq -eq \
 eqc -eqc \
+estfreq -estfreq \
 exp -exp \
 export_e5ml -export_e5ml \
 export_e5res -export_e5res \
@@ -547,6 +549,7 @@ setgriduri -setgriduri \
 sethalo -sethalo \
 setlevel -setlevel \
 setltype -setltype \
+setmiss -setmiss \
 setmisstoc -setmisstoc \
 setmisstodis -setmisstodis \
 setmisstonn -setmisstonn \
@@ -579,6 +582,10 @@ shaded -shaded \
 shifttime -shifttime \
 shiftx -shiftx \
 shifty -shifty \
+showattribute -showattribute \
+showatts -showatts \
+showattsglob -showattsglob \
+showattsvar -showattsvar \
 showcode -showcode \
 showdate -showdate \
 showformat -showformat \
diff --git a/contrib/cdoCompletion.tcsh b/contrib/cdoCompletion.tcsh
index 8722137..73da97f 100644
--- a/contrib/cdoCompletion.tcsh
+++ b/contrib/cdoCompletion.tcsh
@@ -9,7 +9,7 @@ set cdoCmpl = (\
 -precision \
 -reduce_dim \
 -remap_genweights \
--sort \
+-sortname \
 -timestat_date \
 C, \
 L \
@@ -69,6 +69,7 @@ chtabnum \
 chunit \
 chvar \
 cloudlayer \
+cmor \
 cmorlite \
 codetab \
 collgrid \
@@ -191,6 +192,7 @@ eofspatial \
 eoftime \
 eq \
 eqc \
+estfreq \
 exp \
 export_e5ml \
 export_e5res \
@@ -547,6 +549,7 @@ setgriduri \
 sethalo \
 setlevel \
 setltype \
+setmiss \
 setmisstoc \
 setmisstodis \
 setmisstonn \
@@ -579,6 +582,10 @@ shaded \
 shifttime \
 shiftx \
 shifty \
+showattribute \
+showatts \
+showattsglob \
+showattsvar \
 showcode \
 showdate \
 showformat \
diff --git a/contrib/cdoCompletion.zsh b/contrib/cdoCompletion.zsh
index 7fb7fe9..8179992 100644
--- a/contrib/cdoCompletion.zsh
+++ b/contrib/cdoCompletion.zsh
@@ -9,7 +9,7 @@ compctl -k "(
 --precision \
 --reduce_dim \
 --remap_genweights \
---sort \
+--sortname \
 --timestat_date \
 -C, \
 -L \
@@ -69,6 +69,7 @@ chtabnum -chtabnum \
 chunit -chunit \
 chvar -chvar \
 cloudlayer -cloudlayer \
+cmor -cmor \
 cmorlite -cmorlite \
 codetab -codetab \
 collgrid -collgrid \
@@ -191,6 +192,7 @@ eofspatial -eofspatial \
 eoftime -eoftime \
 eq -eq \
 eqc -eqc \
+estfreq -estfreq \
 exp -exp \
 export_e5ml -export_e5ml \
 export_e5res -export_e5res \
@@ -547,6 +549,7 @@ setgriduri -setgriduri \
 sethalo -sethalo \
 setlevel -setlevel \
 setltype -setltype \
+setmiss -setmiss \
 setmisstoc -setmisstoc \
 setmisstodis -setmisstodis \
 setmisstonn -setmisstonn \
@@ -579,6 +582,10 @@ shaded -shaded \
 shifttime -shifttime \
 shiftx -shiftx \
 shifty -shifty \
+showattribute -showattribute \
+showatts -showatts \
+showattsglob -showattsglob \
+showattsvar -showattsvar \
 showcode -showcode \
 showdate -showdate \
 showformat -showformat \
diff --git a/doc/cdo.pdf b/doc/cdo.pdf
index f258c39..582f288 100644
Binary files a/doc/cdo.pdf and b/doc/cdo.pdf differ
diff --git a/doc/cdo_cmor.pdf b/doc/cdo_cmor.pdf
new file mode 100644
index 0000000..a7d3022
Binary files /dev/null and b/doc/cdo_cmor.pdf differ
diff --git a/doc/cdo_eca.pdf b/doc/cdo_eca.pdf
index 1457d38..9478a28 100644
Binary files a/doc/cdo_eca.pdf and b/doc/cdo_eca.pdf differ
diff --git a/doc/cdo_magics.pdf b/doc/cdo_magics.pdf
index e2a0b66..641c3d4 100644
Binary files a/doc/cdo_magics.pdf and b/doc/cdo_magics.pdf differ
diff --git a/doc/cdo_refcard.pdf b/doc/cdo_refcard.pdf
index e28f936..554fb87 100644
Binary files a/doc/cdo_refcard.pdf and b/doc/cdo_refcard.pdf differ
diff --git a/libcdi/ChangeLog b/libcdi/ChangeLog
index 6fb088f..54014e4 100644
--- a/libcdi/ChangeLog
+++ b/libcdi/ChangeLog
@@ -1,3 +1,55 @@
+2017-10-05  Uwe Schulzweida
+
+        * using CGRIBEX library version 1.9.0
+	* Version 1.9.1 released
+
+2017-09-28  Uwe Schulzweida
+
+	* Renamed TAXIS_CONSTANT to TIME_CONSTANT
+
+2017-09-20  Uwe Schulzweida
+
+	* vlistCopyFlag: copy datatype (bug fix)
+
+2017-09-20  Uwe Schulzweida
+
+	* Added support for CDI_FILETYPE_NC5
+
+2017-09-18  Uwe Schulzweida
+
+	* CDI_PROJ_LCC: don't overwrite NetCDF units (bug fix)
+
+2017-09-13  Uwe Schulzweida
+
+	* Added interface function taxisWithBounds()
+
+2017-09-07  Uwe Schulzweida
+
+	* Read NC_FORMAT_CDF5 data as CDF2 (preliminary fix)
+
+2017-09-05  Uwe Schulzweida
+
+	* netcdf: added support for GRID_TRAJECTORY
+
+2017-09-01  Uwe Schulzweida
+
+	* Implementation of CDI_reduce_dim for z axis
+
+2017-08-30  Uwe Schulzweida
+
+	* Implementation of CDI_reduce_dim for time axis
+	* Implementation of CDI_reduce_dim for x/y axis
+	* cdfDefAxisCommon: bug fix for zaxis bounds in CDI_cmor_mode
+
+2017-08-08  Uwe Schulzweida
+
+	* Bug fix for CF conform hybrid sigma pressure levels
+
+2017-08-04  Uwe Schulzweida
+
+	* Added CALENDAR_GREGORIAN
+	* cdiGridTypeInit: don't overwrite exsisting attributes (bug fix)
+
 2017-07-27  Uwe Schulzweida
 
         * using CGRIBEX library version 1.8.1
diff --git a/libcdi/app/cdi.c b/libcdi/app/cdi.c
index b392bb6..701a204 100644
--- a/libcdi/app/cdi.c
+++ b/libcdi/app/cdi.c
@@ -75,8 +75,8 @@ static int datamode = DP_MODE;
 static
 void version(void)
 {
-  int   filetypes[] = {CDI_FILETYPE_SRV, CDI_FILETYPE_EXT, CDI_FILETYPE_IEG, CDI_FILETYPE_GRB, CDI_FILETYPE_GRB2, CDI_FILETYPE_NC, CDI_FILETYPE_NC2, CDI_FILETYPE_NC4, CDI_FILETYPE_NC4C};
-   const char *typenames[] = {        "srv",        "ext",        "ieg",        "grb",        "grb2",        "nc",        "nc2",        "nc4",        "nc4c"};
+  int   filetypes[] = {CDI_FILETYPE_SRV, CDI_FILETYPE_EXT, CDI_FILETYPE_IEG, CDI_FILETYPE_GRB, CDI_FILETYPE_GRB2, CDI_FILETYPE_NC, CDI_FILETYPE_NC2, CDI_FILETYPE_NC4, CDI_FILETYPE_NC4C, CDI_FILETYPE_NC5};
+   const char *typenames[] = {        "srv",        "ext",        "ieg",        "grb",        "grb2",        "nc",        "nc2",        "nc4",        "nc4c",        "nc5"};
 
   fprintf(stderr, "CDI version 1.8\n");
 #if defined (COMPILER)
@@ -164,7 +164,7 @@ void usage(void)
   fprintf(stderr, "\n");
   fprintf(stderr, "  Options:\n");
   fprintf(stderr, "    -d             Print debugging information\n");
-  fprintf(stderr, "    -f <format>    Format of the output file. (grb, grb2, nc, nc2, nc4, nc4c, src, ext or ieg)\n");
+  fprintf(stderr, "    -f <format>    Format of the output file. (grb, grb2, nc, nc2, nc4, nc4c, nc5, srv, ext or ieg)\n");
   fprintf(stderr, "    -s             give short information if ofile is missing\n");
   fprintf(stderr, "    -t <table>     Parameter table name/file\n");
   fprintf(stderr, "                   Predefined tables: ");
@@ -178,7 +178,7 @@ void usage(void)
   fprintf(stderr, "       jpeg        JPEG compression of GRIB2 records\n");
   fprintf(stderr, "        zip[_1-9]  Deflate compression of netCDF4 variables\n");
   fprintf(stderr, "\n");
-  fprintf(stderr, "  Report bugs to <http://code.zmaw.de/projects/cdi>\n");
+  fprintf(stderr, "  Report bugs to <https://code.mpimet.mpg.de/projects/cdi>\n");
 }
 
 
@@ -344,9 +344,9 @@ void printShortinfo(int streamID, int vlistID, int vardis)
       int nsubtypes = vlistNsubtypes(vlistID);
 
       if ( nsubtypes > 0 )
-        fprintf(stdout, "   Var : Institut Source   Ttype    Subtypes Num  Levels Num  Gridsize Num Dtype : ");
+	fprintf(stdout, "   Var : Institut Source   T Steptype Subtypes Levels Num    Points Num Dtype : ");
       else
-        fprintf(stdout, "   Var : Institut Source   Ttype    Levels Num  Gridsize Num Dtype : ");
+	fprintf(stdout, "   Var : Institut Source   T Steptype Levels Num    Points Num Dtype : ");
 
       if ( vardis )
 	fprintf(stdout, "Parameter name\n");
@@ -361,24 +361,27 @@ void printShortinfo(int streamID, int vlistID, int vardis)
 
 	  fprintf(stdout, "%6d : ", varID + 1);
 
-	  /* institute info */
+	  // institute info
 	  const char *instptr = institutInqNamePtr(vlistInqVarInstitut(vlistID, varID));
 	  strcpy(tmpname, "unknown");
 	  if ( instptr ) strncpy(tmpname, instptr, CDI_MAX_NAME);
 	  limit_string_length(tmpname, CDI_MAX_NAME);
 	  fprintf(stdout, "%-8s ", tmpname);
 
-	  /* source info */
+	  // source info
 	  const char *modelptr = modelInqNamePtr(vlistInqVarModel(vlistID, varID));
 	  strcpy(tmpname, "unknown");
 	  if ( modelptr ) strncpy(tmpname, modelptr, CDI_MAX_NAME);
 	  limit_string_length(tmpname, CDI_MAX_NAME);
 	  fprintf(stdout, "%-8s ", tmpname);
 
-	  /* tsteptype */
+          // timetype
+          int timetype = vlistInqVarTimetype(vlistID, varID);
+          fprintf(stdout, "%c ", timetype==TIME_CONSTANT ? 'c' : 'v');
+
+	  // tsteptype
 	  int tsteptype = vlistInqVarTsteptype(vlistID, varID);
-	  if      ( tsteptype == TSTEP_CONSTANT ) fprintf(stdout, "%-8s ", "constant");
-	  else if ( tsteptype == TSTEP_INSTANT  ) fprintf(stdout, "%-8s ", "instant");
+	  if      ( tsteptype == TSTEP_INSTANT  ) fprintf(stdout, "%-8s ", "instant");
 	  else if ( tsteptype == TSTEP_INSTANT2 ) fprintf(stdout, "%-8s ", "instant");
 	  else if ( tsteptype == TSTEP_INSTANT3 ) fprintf(stdout, "%-8s ", "instant");
 	  else if ( tsteptype == TSTEP_MIN      ) fprintf(stdout, "%-8s ", "min");
@@ -560,7 +563,7 @@ void setDefaultDataType(char *datatypestr)
 	  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");
+	      fprintf(stderr, "Use I8/I16/I32/F32/F64 for nc/nc2/nc4/nc4c/nc5; F32/F64 for grb2/srv/ext/ieg; P1 - P24 for grb/grb2.\n");
 	      exit(EXIT_FAILURE);
 	    }
 	}
@@ -644,6 +647,7 @@ void setDefaultFileType(char *filetypestr)
       else if ( memcmp(filetypestr, "nc2",  3)  == 0 ) { ftstr += 3; DefaultFileType = CDI_FILETYPE_NC2; }
       else if ( memcmp(filetypestr, "nc4c", 4)  == 0 ) { ftstr += 4; DefaultFileType = CDI_FILETYPE_NC4C;}
       else if ( memcmp(filetypestr, "nc4",  3)  == 0 ) { ftstr += 3; DefaultFileType = CDI_FILETYPE_NC4; }
+      else if ( memcmp(filetypestr, "nc5",  3)  == 0 ) { ftstr += 3; DefaultFileType = CDI_FILETYPE_NC5; }
       else if ( memcmp(filetypestr, "nc1",  3)  == 0 ) { ftstr += 3; DefaultFileType = CDI_FILETYPE_NC;  }
       else if ( memcmp(filetypestr, "nc",   2)  == 0 ) { ftstr += 2; DefaultFileType = CDI_FILETYPE_NC2; }
       else if ( memcmp(filetypestr, "srv",  3)  == 0 ) { ftstr += 3; DefaultFileType = CDI_FILETYPE_SRV; }
@@ -652,7 +656,7 @@ void setDefaultFileType(char *filetypestr)
       else
 	{
 	  fprintf(stderr, "Unsupported filetype %s!\n", filetypestr);
-	  fprintf(stderr, "Available filetypes: grb, grb2, nc, nc2, nc4, nc4c, srv, ext and ieg\n");
+	  fprintf(stderr, "Available filetypes: grb, grb2, nc, nc2, nc4, nc4c, nc5, srv, ext and ieg\n");
 	  exit(EXIT_FAILURE);
 	}
 
@@ -668,8 +672,8 @@ void setDefaultFileType(char *filetypestr)
 	    {
 	      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");
+	      fprintf(stderr, "    format = grb, grb2, nc, nc2, nc4, nc4c, nc5, srv, ext or ieg\n");
+	      fprintf(stderr, "    nbits  = 32/64 for grb2/nc/nc2/nc4/nc4c/nc5/srv/ext/ieg; 1 - 24 for grb/grb2\n");
 	      exit(EXIT_FAILURE);
 	    }
 	}
@@ -977,7 +981,7 @@ int main(int argc, char *argv[])
 	    {
 	      for ( varID = 0; varID < nvars; varID++ )
 		{
-		  if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT && tsID > 0 ) continue;
+		  if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT && tsID > 0 ) continue;
 
 		  number   = vlistInqVarNumber(vlistID1, varID);
 		  gridID   = vlistInqVarGrid(vlistID1, varID);
diff --git a/libcdi/app/printinfo.h b/libcdi/app/printinfo.h
index 01b9b8d..052055b 100644
--- a/libcdi/app/printinfo.h
+++ b/libcdi/app/printinfo.h
@@ -62,52 +62,32 @@ void printFiletype(int streamID, int vlistID)
 {
   int filetype = streamInqFiletype(streamID);
 
+  // clang-format off
   switch ( filetype )
     {
-    case CDI_FILETYPE_GRB:
-      printf("GRIB");
-      break;
-    case CDI_FILETYPE_GRB2:
-      printf("GRIB2");
-      break;
-    case CDI_FILETYPE_NC:
-      printf("NetCDF");
-      break;
-    case CDI_FILETYPE_NC2:
-      printf("NetCDF2");
-      break;
-    case CDI_FILETYPE_NC4:
-      printf("NetCDF4");
-      break;
-    case CDI_FILETYPE_NC4C:
-      printf("NetCDF4 classic");
-      break;
-    case CDI_FILETYPE_SRV:
-      printf("SERVICE");
-      break;
-    case CDI_FILETYPE_EXT:
-      printf("EXTRA");
-      break;
-    case CDI_FILETYPE_IEG:
-      printf("IEG");
-      break;
-    default:
-      printf("  File format: unsupported filetype %d" , filetype);
-      break;
+    case CDI_FILETYPE_GRB:  printf("GRIB");  break;
+    case CDI_FILETYPE_GRB2: printf("GRIB2");  break;
+    case CDI_FILETYPE_NC:   printf("NetCDF");  break;
+    case CDI_FILETYPE_NC2:  printf("NetCDF2");  break;
+    case CDI_FILETYPE_NC4:  printf("NetCDF4");  break;
+    case CDI_FILETYPE_NC4C: printf("NetCDF4 classic");  break;
+    case CDI_FILETYPE_NC5:  printf("NetCDF5");  break;
+    case CDI_FILETYPE_SRV:  printf("SERVICE");  break;
+    case CDI_FILETYPE_EXT:  printf("EXTRA");  break;
+    case CDI_FILETYPE_IEG:  printf("IEG");  break;
+    default: printf("  File format: unsupported filetype %d" , filetype);  break;
     }
 
   if ( filetype == CDI_FILETYPE_SRV || filetype == CDI_FILETYPE_EXT || filetype == CDI_FILETYPE_IEG )
     {
       switch ( streamInqByteorder(streamID) )
 	{
-	case CDI_BIGENDIAN:
-	  printf("  BIGENDIAN"); break;
-	case CDI_LITTLEENDIAN:
-	  printf("  LITTLEENDIAN"); break;
-	default:
-	  printf("  byteorder: %d undefined", streamInqByteorder(streamID)); break;
+	case CDI_BIGENDIAN:    printf("  BIGENDIAN");  break;
+	case CDI_LITTLEENDIAN: printf("  LITTLEENDIAN");  break;
+	default: printf("  byteorder: %d undefined", streamInqByteorder(streamID));  break;
 	}
     }
+  // clang-format on
 
   if ( filetype == CDI_FILETYPE_GRB || filetype == CDI_FILETYPE_NC4 || filetype == CDI_FILETYPE_NC4C )
     {
@@ -282,7 +262,7 @@ void printGridInfoKernel(int gridID, int index, bool lproj)
   size_t ysize    = gridInqYsize(gridID);
   size_t xysize   = xsize*ysize;
 
-  // int prec     = gridInqPrec(gridID);
+  // int prec     = gridInqDatatype(gridID);
   // int dig = (prec == CDI_DATATYPE_FLT64) ? 15 : 7;
   int dig = 7;
 #ifdef CDO
@@ -482,7 +462,7 @@ void printZaxisInfo(int vlistID)
       int zaxistype = zaxisInqType(zaxisID);
       int ltype     = zaxisInqLtype(zaxisID);
       int levelsize = zaxisInqSize(zaxisID);
-      // int prec      = zaxisInqPrec(zaxisID);
+      // int prec      = zaxisInqDatatype(zaxisID);
       // int dig = (prec == CDI_DATATYPE_FLT64) ? 15 : 7;
       int dig = 7;
 #ifdef CDO
@@ -591,7 +571,7 @@ void printZaxisInfo(int vlistID)
           if ( number > 0 )
             {
               fprintf(stdout, "%33s : ", "zaxis");
-              fprintf(stdout, "number = %d\n", number);
+              fprintf(stdout, "number=%d\n", number);
             }
 
           unsigned char uuidOfVGrid[CDI_UUID_SIZE];
diff --git a/libcdi/configure b/libcdi/configure
index 44a7d8e..436c24f 100755
--- a/libcdi/configure
+++ b/libcdi/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for cdi 1.9.0.
+# Generated by GNU Autoconf 2.68 for cdi 1.9.1.
 #
 # Report bugs to <http://mpimet.mpg.de/cdi>.
 #
@@ -570,8 +570,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='cdi'
 PACKAGE_TARNAME='cdi'
-PACKAGE_VERSION='1.9.0'
-PACKAGE_STRING='cdi 1.9.0'
+PACKAGE_VERSION='1.9.1'
+PACKAGE_STRING='cdi 1.9.1'
 PACKAGE_BUGREPORT='http://mpimet.mpg.de/cdi'
 PACKAGE_URL=''
 
@@ -1466,7 +1466,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.9.0 to adapt to many kinds of systems.
+\`configure' configures cdi 1.9.1 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1536,7 +1536,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of cdi 1.9.0:";;
+     short | recursive ) echo "Configuration of cdi 1.9.1:";;
    esac
   cat <<\_ACEOF
 
@@ -1735,7 +1735,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-cdi configure 1.9.0
+cdi configure 1.9.1
 generated by GNU Autoconf 2.68
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -2580,7 +2580,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.9.0, which was
+It was created by cdi $as_me 1.9.1, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
@@ -3532,7 +3532,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='cdi'
- VERSION='1.9.0'
+ VERSION='1.9.1'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -23449,7 +23449,7 @@ Usage: $0 [OPTIONS]
 Report bugs to <bug-libtool at gnu.org>."
 
 lt_cl_version="\
-cdi config.lt 1.9.0
+cdi config.lt 1.9.1
 configured by $0, generated by GNU Autoconf 2.68.
 
 Copyright (C) 2011 Free Software Foundation, Inc.
@@ -30808,7 +30808,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.9.0, which was
+This file was extended by cdi $as_me 1.9.1, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -30874,7 +30874,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-cdi config.status 1.9.0
+cdi config.status 1.9.1
 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 9d52c3c..eea364f 100644
--- a/libcdi/configure.ac
+++ b/libcdi/configure.ac
@@ -4,7 +4,7 @@
 #  autoconf 2.68
 #  libtool  2.4.2
 
-AC_INIT([cdi], [1.9.0], [http://mpimet.mpg.de/cdi])
+AC_INIT([cdi], [1.9.1], [http://mpimet.mpg.de/cdi])
 
 AC_DEFINE_UNQUOTED(CDI, ["$PACKAGE_VERSION"], [CDI version])
 
diff --git a/libcdi/doc/cdi_cman.pdf b/libcdi/doc/cdi_cman.pdf
index 7f71ee9..2e09c38 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 9366b4b..85d3e4d 100644
Binary files a/libcdi/doc/cdi_fman.pdf and b/libcdi/doc/cdi_fman.pdf differ
diff --git a/libcdi/examples/Makefile.am b/libcdi/examples/Makefile.am
index a6387b5..05dca45 100644
--- a/libcdi/examples/Makefile.am
+++ b/libcdi/examples/Makefile.am
@@ -2,8 +2,7 @@
 #
 EXTRA_DIST = cdi_read_f2003.f90 cdi_write_f2003.f90
 #
-noinst_PROGRAMS = cdi_write cdi_write_ens cdi_write_hybrid cdi_read \
-	cdi_copy
+noinst_PROGRAMS = cdi_write cdi_write_relativ cdi_write_ens cdi_write_hybrid cdi_read cdi_copy
 if CREATE_ISOC
   noinst_PROGRAMS += cdi_read_f2003 cdi_write_f2003
 endif
@@ -17,9 +16,11 @@ LDADD = $(top_builddir)/src/libcdi.la
 #
 cdi_write_SOURCES        = cdi_write.c
 #
+cdi_write_relativ_SOURCES = cdi_write_relativ.c
+#
 cdi_write_ens_SOURCES    = cdi_write_ens.c
 #
-cdi_write_const_SOURCES    = cdi_write_const.c
+cdi_write_const_SOURCES  = cdi_write_const.c
 #
 cdi_write_hybrid_SOURCES = cdi_write_hybrid.c
 #
diff --git a/libcdi/examples/Makefile.in b/libcdi/examples/Makefile.in
index 9be7838..efcfe5f 100644
--- a/libcdi/examples/Makefile.in
+++ b/libcdi/examples/Makefile.in
@@ -78,9 +78,10 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
-noinst_PROGRAMS = cdi_write$(EXEEXT) cdi_write_ens$(EXEEXT) \
-	cdi_write_hybrid$(EXEEXT) cdi_read$(EXEEXT) cdi_copy$(EXEEXT) \
-	$(am__EXEEXT_1) $(am__EXEEXT_2)
+noinst_PROGRAMS = cdi_write$(EXEEXT) cdi_write_relativ$(EXEEXT) \
+	cdi_write_ens$(EXEEXT) cdi_write_hybrid$(EXEEXT) \
+	cdi_read$(EXEEXT) cdi_copy$(EXEEXT) $(am__EXEEXT_1) \
+	$(am__EXEEXT_2)
 @CREATE_ISOC_TRUE at am__append_1 = cdi_read_f2003 cdi_write_f2003
 @ENABLE_NETCDF_TRUE at am__append_2 = cdi_write_const
 subdir = examples
@@ -179,6 +180,10 @@ am_cdi_write_hybrid_OBJECTS = cdi_write_hybrid.$(OBJEXT)
 cdi_write_hybrid_OBJECTS = $(am_cdi_write_hybrid_OBJECTS)
 cdi_write_hybrid_LDADD = $(LDADD)
 cdi_write_hybrid_DEPENDENCIES = $(top_builddir)/src/libcdi.la
+am_cdi_write_relativ_OBJECTS = cdi_write_relativ.$(OBJEXT)
+cdi_write_relativ_OBJECTS = $(am_cdi_write_relativ_OBJECTS)
+cdi_write_relativ_LDADD = $(LDADD)
+cdi_write_relativ_DEPENDENCIES = $(top_builddir)/src/libcdi.la
 AM_V_P = $(am__v_P_ at AM_V@)
 am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
 am__v_P_0 = false
@@ -231,11 +236,13 @@ am__v_FCLD_1 =
 SOURCES = $(cdi_copy_SOURCES) $(cdi_read_SOURCES) \
 	$(cdi_read_f2003_SOURCES) $(cdi_write_SOURCES) \
 	$(cdi_write_const_SOURCES) $(cdi_write_ens_SOURCES) \
-	$(cdi_write_f2003_SOURCES) $(cdi_write_hybrid_SOURCES)
+	$(cdi_write_f2003_SOURCES) $(cdi_write_hybrid_SOURCES) \
+	$(cdi_write_relativ_SOURCES)
 DIST_SOURCES = $(cdi_copy_SOURCES) $(cdi_read_SOURCES) \
 	$(cdi_read_f2003_SOURCES) $(cdi_write_SOURCES) \
 	$(cdi_write_const_SOURCES) $(cdi_write_ens_SOURCES) \
-	$(cdi_write_f2003_SOURCES) $(cdi_write_hybrid_SOURCES)
+	$(cdi_write_f2003_SOURCES) $(cdi_write_hybrid_SOURCES) \
+	$(cdi_write_relativ_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -457,6 +464,8 @@ LDADD = $(top_builddir)/src/libcdi.la
 #
 cdi_write_SOURCES = cdi_write.c
 #
+cdi_write_relativ_SOURCES = cdi_write_relativ.c
+#
 cdi_write_ens_SOURCES = cdi_write_ens.c
 #
 cdi_write_const_SOURCES = cdi_write_const.c
@@ -555,6 +564,10 @@ cdi_write_hybrid$(EXEEXT): $(cdi_write_hybrid_OBJECTS) $(cdi_write_hybrid_DEPEND
 	@rm -f cdi_write_hybrid$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(cdi_write_hybrid_OBJECTS) $(cdi_write_hybrid_LDADD) $(LIBS)
 
+cdi_write_relativ$(EXEEXT): $(cdi_write_relativ_OBJECTS) $(cdi_write_relativ_DEPENDENCIES) $(EXTRA_cdi_write_relativ_DEPENDENCIES) 
+	@rm -f cdi_write_relativ$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(cdi_write_relativ_OBJECTS) $(cdi_write_relativ_LDADD) $(LIBS)
+
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
 
@@ -567,6 +580,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdi_write_const.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdi_write_ens.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdi_write_hybrid.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdi_write_relativ.Po at am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
diff --git a/libcdi/examples/cdi_write.c b/libcdi/examples/cdi_write.c
index 6a8926d..acc1500 100644
--- a/libcdi/examples/cdi_write.c
+++ b/libcdi/examples/cdi_write.c
@@ -33,8 +33,8 @@ int main(void)
   int vlistID = vlistCreate();
 
   // Define the variables
-  int varID1 = vlistDefVar(vlistID, gridID, zaxisID1, TSTEP_INSTANT);
-  int varID2 = vlistDefVar(vlistID, gridID, zaxisID2, TSTEP_INSTANT);
+  int varID1 = vlistDefVar(vlistID, gridID, zaxisID1, TIME_VARYING);
+  int varID2 = vlistDefVar(vlistID, gridID, zaxisID2, TIME_VARYING);
 
   // Define the variable names
   vlistDefVarName(vlistID, varID1, "varname1");
diff --git a/libcdi/examples/cdi_write_const.c b/libcdi/examples/cdi_write_const.c
index 6f63ede..7520c6e 100644
--- a/libcdi/examples/cdi_write_const.c
+++ b/libcdi/examples/cdi_write_const.c
@@ -35,8 +35,8 @@ int main(void)
   vlistID = vlistCreate();
 
   // Define the variables
-  varID1 = vlistDefVar(vlistID, gridID, zaxisID1, TSTEP_CONSTANT);
-  varID2 = vlistDefVar(vlistID, gridID, zaxisID2, TSTEP_CONSTANT);
+  varID1 = vlistDefVar(vlistID, gridID, zaxisID1, TIME_CONSTANT);
+  varID2 = vlistDefVar(vlistID, gridID, zaxisID2, TIME_CONSTANT);
 
   // Define the variable names
   vlistDefVarName(vlistID, varID1, "varname1");
diff --git a/libcdi/examples/cdi_write_ens.c b/libcdi/examples/cdi_write_ens.c
index f89af0e..2fea3c9 100644
--- a/libcdi/examples/cdi_write_ens.c
+++ b/libcdi/examples/cdi_write_ens.c
@@ -36,7 +36,7 @@ int main(void)
   instID  = institutDef( 252, 0, NULL, NULL );
 
   vlistID = vlistCreate();
-  varID = vlistDefVar(vlistID, gridID, zaxisID, TSTEP_INSTANT);
+  varID = vlistDefVar(vlistID, gridID, zaxisID, TIME_VARYING);
   
   vlistDefVarEnsemble( vlistID, varID, 1, 2, 3);
   
diff --git a/libcdi/examples/cdi_write_f2003.f90 b/libcdi/examples/cdi_write_f2003.f90
index 9b25ed2..8c53a33 100644
--- a/libcdi/examples/cdi_write_f2003.f90
+++ b/libcdi/examples/cdi_write_f2003.f90
@@ -43,8 +43,8 @@
       vlistID = vlistCreate()
 
 !     Define the variables
-      varID1 = vlistDefVar(vlistID, gridID, zaxisID1, TIME_VARIABLE)
-      varID2 = vlistDefVar(vlistID, gridID, zaxisID2, TIME_VARIABLE)
+      varID1 = vlistDefVar(vlistID, gridID, zaxisID1, TIME_VARYING)
+      varID2 = vlistDefVar(vlistID, gridID, zaxisID2, TIME_VARYING)
 
 !     Define the variable names
       varname = "varname1" // c_null_char
diff --git a/libcdi/examples/cdi_write_hybrid.c b/libcdi/examples/cdi_write_hybrid.c
index 7eadc0e..24504c8 100644
--- a/libcdi/examples/cdi_write_hybrid.c
+++ b/libcdi/examples/cdi_write_hybrid.c
@@ -54,10 +54,10 @@ int main(void)
   vlistID = vlistCreate();
 
   // Define the variables
-  varID1 = vlistDefVar(vlistID, gridID, zaxisID1, TSTEP_INSTANT);
-  varID2 = vlistDefVar(vlistID, gridID, zaxisID2, TSTEP_INSTANT);
-  varID3 = vlistDefVar(vlistID, gridID, zaxisID3, TSTEP_INSTANT);
-  varID4 = vlistDefVar(vlistID, gridID, zaxisID4, TSTEP_INSTANT);
+  varID1 = vlistDefVar(vlistID, gridID, zaxisID1, TIME_VARYING);
+  varID2 = vlistDefVar(vlistID, gridID, zaxisID2, TIME_VARYING);
+  varID3 = vlistDefVar(vlistID, gridID, zaxisID3, TIME_VARYING);
+  varID4 = vlistDefVar(vlistID, gridID, zaxisID4, TIME_VARYING);
 
   // Define the variable names
   vlistDefVarName(vlistID, varID1, "sp");
diff --git a/libcdi/examples/cdi_write.c b/libcdi/examples/cdi_write_relativ.c
similarity index 92%
copy from libcdi/examples/cdi_write.c
copy to libcdi/examples/cdi_write_relativ.c
index 6a8926d..d48a3e1 100644
--- a/libcdi/examples/cdi_write.c
+++ b/libcdi/examples/cdi_write_relativ.c
@@ -33,15 +33,15 @@ int main(void)
   int vlistID = vlistCreate();
 
   // Define the variables
-  int varID1 = vlistDefVar(vlistID, gridID, zaxisID1, TSTEP_INSTANT);
-  int varID2 = vlistDefVar(vlistID, gridID, zaxisID2, TSTEP_INSTANT);
+  int varID1 = vlistDefVar(vlistID, gridID, zaxisID1, TIME_VARYING);
+  int varID2 = vlistDefVar(vlistID, gridID, zaxisID2, TIME_VARYING);
 
   // Define the variable names
   vlistDefVarName(vlistID, varID1, "varname1");
   vlistDefVarName(vlistID, varID2, "varname2");
 
   // Create a Time axis
-  int taxisID = taxisCreate(TAXIS_ABSOLUTE);
+  int taxisID = taxisCreate(TAXIS_RELATIVE);
 
   // Assign the Time axis to the variable list
   vlistDefTaxis(vlistID, taxisID);
diff --git a/libcdi/interfaces/cdi.cpp b/libcdi/interfaces/cdi.cpp
index 70c12d8..7d69e11 100644
--- a/libcdi/interfaces/cdi.cpp
+++ b/libcdi/interfaces/cdi.cpp
@@ -38,7 +38,7 @@ CdiGrid::CdiGrid(int gridid) {
   getValues();
   getBounds();
 
-  prec = gridInqPrec(gridID);
+  prec = gridInqDatatype(gridID);
 
   gridInqXname(gridID    , _xname);
   gridInqXlongname(gridID, _xlongname);
@@ -212,7 +212,7 @@ CdiZaxis::CdiZaxis(int zaxisid) {
 
   zaxisID = zaxisid;
   size    = zaxisInqSize(zaxisID);
-  prec    = zaxisInqPrec(zaxisID);
+  prec    = zaxisInqDatatype(zaxisID);
   type    = zaxisInqType(zaxisID);
   ltype   = zaxisInqLtype(zaxisID);
 
diff --git a/libcdi/interfaces/python/table.py b/libcdi/interfaces/python/table.py
index f2c7d19..d02b387 100644
--- a/libcdi/interfaces/python/table.py
+++ b/libcdi/interfaces/python/table.py
@@ -9,7 +9,7 @@ def htmlSkel(experiment):
   return ['<html> <head> <title>ECHAM Experiment: '+ experiment +'</title></head>' +
   """<body>
 <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script> 
-<script type="text/javascript" src="https://code.zmaw.de/files/cdo/html/tableFold.js"></script>""",
+<script type="text/javascript" src="https://code.mpimet.mpg.de/files/cdo/html/tableFold.js"></script>""",
   '''</body>
     </html>
   ''']
diff --git a/libcdi/src/Makefile.am b/libcdi/src/Makefile.am
index a286427..7c5cdcf 100644
--- a/libcdi/src/Makefile.am
+++ b/libcdi/src/Makefile.am
@@ -22,6 +22,7 @@ libcdi_la_SOURCES = 	 \
 	calendar.h	 \
 	cdf.c            \
 	cdf.h	 	 \
+	cdf_config.h	 \
 	cdf_int.c	 \
 	cdf_int.h	 \
 	cdf_util.c	 \
diff --git a/libcdi/src/Makefile.in b/libcdi/src/Makefile.in
index 5d2ae72..4990e5f 100644
--- a/libcdi/src/Makefile.in
+++ b/libcdi/src/Makefile.in
@@ -169,8 +169,8 @@ LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
 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 \
-	cdf_util.c cdf_util.h cdi.h cdi_error.c cdi_limits.h \
+	calendar.c calendar.h cdf.c cdf.h cdf_config.h cdf_int.c \
+	cdf_int.h cdf_util.c cdf_util.h cdi.h cdi_error.c cdi_limits.h \
 	cdi_util.c cgribex.h cgribexlib.c datetime.h dmemory.c \
 	dmemory.h cksum.c cksum.h cdi_cksum.c cdi_cksum.h cdi_uuid.h \
 	dtypes.h error.c error.h exse.h extra.h extralib.c file.c \
@@ -512,18 +512,18 @@ noinst_LTLIBRARIES = libcdiresunpack.la $(am__append_1) \
 @ENABLE_CDI_LIB_TRUE at include_HEADERS = cdi.h cdi.inc $(am__append_5)
 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 cdf_util.c \
-	cdf_util.h cdi.h cdi_error.c cdi_limits.h cdi_util.c cgribex.h \
-	cgribexlib.c datetime.h dmemory.c dmemory.h cksum.c cksum.h \
-	cdi_cksum.c cdi_cksum.h cdi_uuid.h dtypes.h error.c error.h \
-	exse.h extra.h extralib.c file.c file.h gaussgrid.c \
-	gaussgrid.h gribapi.c gribapi.h 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 referenceCounting.c \
-	referenceCounting.h resource_handle.c resource_handle.h \
-	service.h servicelib.c stream_cdf_i.c stream_cdf_o.c \
-	stream_cdf_time.c stream_cdf.h stream_cgribex.c \
+	calendar.h cdf.c cdf.h cdf_config.h cdf_int.c cdf_int.h \
+	cdf_util.c cdf_util.h cdi.h cdi_error.c cdi_limits.h \
+	cdi_util.c cgribex.h cgribexlib.c datetime.h dmemory.c \
+	dmemory.h cksum.c cksum.h cdi_cksum.c cdi_cksum.h cdi_uuid.h \
+	dtypes.h error.c error.h exse.h extra.h extralib.c file.c \
+	file.h gaussgrid.c gaussgrid.h gribapi.c gribapi.h \
+	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 \
+	referenceCounting.c referenceCounting.h resource_handle.c \
+	resource_handle.h service.h servicelib.c stream_cdf_i.c \
+	stream_cdf_o.c stream_cdf_time.c stream_cdf.h stream_cgribex.c \
 	stream_cgribex.h stream_ext.c stream_ext.h stream_grb.c \
 	stream_grb.h stream_gribapi.h stream_history.c stream_ieg.c \
 	stream_ieg.h cdi_int.c cdi_int.h stream_record.c stream_srv.c \
diff --git a/libcdi/src/calendar.c b/libcdi/src/calendar.c
index 8ade92a..8c74bf3 100644
--- a/libcdi/src/calendar.c
+++ b/libcdi/src/calendar.c
@@ -58,7 +58,7 @@ int days_per_year(int calendar, int year)
 
   if ( daysperyear == 0 )
     {
-      if ( year == 1582 && calendar == CALENDAR_STANDARD )
+      if ( year == 1582 && (calendar == CALENDAR_STANDARD || calendar == CALENDAR_GREGORIAN) )
         daysperyear = 355;
       else if ( (year%4 == 0 && year%100 != 0) || year%400 == 0 )
         daysperyear = 366;
diff --git a/libcdi/src/cdf.c b/libcdi/src/cdf.c
index 4d55129..47866d1 100644
--- a/libcdi/src/cdf.c
+++ b/libcdi/src/cdf.c
@@ -1,5 +1,5 @@
-#if defined (HAVE_CONFIG_H)
-#  include "config.h"
+#ifdef  HAVE_CONFIG_H
+#include "config.h"
 #endif
 
 #include <stdio.h>
@@ -16,32 +16,32 @@
 
 const char *cdfLibraryVersion(void)
 {
-#if  defined  (HAVE_LIBNETCDF)
+#ifdef  HAVE_LIBNETCDF
   return nc_inq_libvers();
 #else
   return "library undefined";
 #endif
 }
 
-#if  defined(HAVE_H5GET_LIBVERSION)
-#if  defined(__cplusplus)
+#ifdef  HAVE_H5GET_LIBVERSION
+#ifdef  __cplusplus
 extern "C" {
 #endif
   int H5get_libversion(unsigned *, unsigned *, unsigned *);
-#if defined(__cplusplus)
+#ifdef  __cplusplus
 }
 #endif
 #endif
 
 const char *hdfLibraryVersion(void)
 {
-#if  defined(HAVE_H5GET_LIBVERSION)
+#ifdef  HAVE_H5GET_LIBVERSION
   static char hdf_libvers[256];
   unsigned majnum, minnum, relnum;
 
   H5get_libversion(&majnum, &minnum, &relnum);
 
-#if  defined(HAVE_NC4HDF5_THREADSAFE)
+#ifdef  HAVE_NC4HDF5_THREADSAFE
   sprintf(hdf_libvers, "%u.%u.%u threadsafe", majnum, minnum, relnum);
 #else
   sprintf(hdf_libvers, "%u.%u.%u", majnum, minnum, relnum);
@@ -64,7 +64,7 @@ void cdfDebug(int debug)
     Message("debug level %d", debug);
 }
 
-#if  defined  (HAVE_LIBNETCDF)
+#ifdef  HAVE_LIBNETCDF
 static
 void cdfComment(int ncid)
 {
@@ -92,11 +92,10 @@ void cdfComment(int ncid)
 static int cdfOpenFile(const char *filename, const char *mode, int *filetype)
 {
   int ncid = -1;
-#if  defined  (HAVE_LIBNETCDF)
+#ifdef  HAVE_LIBNETCDF
   int fmode = tolower(*mode);
   int writemode = NC_CLOBBER;
   int readmode = NC_NOWRITE;
-  int status;
 
   if ( filename == NULL )
     ncid = CDI_EINVAL;
@@ -105,25 +104,28 @@ static int cdfOpenFile(const char *filename, const char *mode, int *filetype)
       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 = CDI_FILETYPE_NC4C;
-		}
-	    }
-#endif
+          {
+            int status = cdf_open(filename, readmode, &ncid);
+            if ( status > 0 && ncid < 0 ) ncid = CDI_ESYSTEM;
+#ifdef  HAVE_NETCDF4
+            else
+              {
+                int format;
+                (void) nc_inq_format(ncid, &format);
+                if ( format == NC_FORMAT_NETCDF4_CLASSIC )
+                  *filetype = CDI_FILETYPE_NC4C;
+              }
+#endif
+          }
 	  break;
 	case 'w':
-#if  defined  (NC_64BIT_OFFSET)
+#ifdef  NC_64BIT_OFFSET
 	  if      ( *filetype == CDI_FILETYPE_NC2  ) writemode |= NC_64BIT_OFFSET;
 #endif
-#if  defined  (HAVE_NETCDF4)
+#ifdef  NC_64BIT_DATA
+	  if      ( *filetype == CDI_FILETYPE_NC5  ) writemode |= NC_64BIT_DATA;
+#endif
+#ifdef  HAVE_NETCDF4
 	  if      ( *filetype == CDI_FILETYPE_NC4  ) writemode |= NC_NETCDF4;
 	  else if ( *filetype == CDI_FILETYPE_NC4C ) writemode |= NC_NETCDF4 | NC_CLASSIC_MODEL;
 #endif
@@ -144,34 +146,20 @@ static int cdfOpenFile(const char *filename, const char *mode, int *filetype)
 }
 
 
-int cdfOpen(const char *filename, const char *mode)
-{
-  int filetype = CDI_FILETYPE_NC;
-
-  if ( CDF_Debug )
-    Message("Open %s with mode %c", filename, *mode);
-
-  int fileID = cdfOpenFile(filename, mode, &filetype);
-
-  if ( CDF_Debug )
-    Message("File %s opened with id %d", filename, fileID);
-
-  return fileID;
-}
-
-
-int cdfOpen64(const char *filename, const char *mode)
+int cdfOpen(const char *filename, const char *mode, int filetype)
 {
   int fileID = -1;
-  int filetype = CDI_FILETYPE_NC2;
   bool open_file = true;
 
   if ( CDF_Debug )
     Message("Open %s with mode %c", filename, *mode);
 
-#if  defined  (HAVE_LIBNETCDF)
-#if  ! defined  (NC_64BIT_OFFSET)
-  open_file = false;
+#ifdef  HAVE_LIBNETCDF
+#ifndef  NC_64BIT_OFFSET
+  if ( filetype == CDI_FILETYPE_NC2 ) open_file = false;
+#endif
+#ifndef  NC_64BIT_DATA
+  if ( filetype == CDI_FILETYPE_NC5 ) open_file = false;
 #endif
 #endif
 
@@ -180,7 +168,7 @@ int cdfOpen64(const char *filename, const char *mode)
       fileID = cdfOpenFile(filename, mode, &filetype);
 
       if ( CDF_Debug )
-	Message("File %s opened with id %d", filename, fileID);
+        Message("File %s opened with id %d", filename, fileID);
     }
   else
     {
@@ -199,7 +187,7 @@ int cdf4Open(const char *filename, const char *mode, int *filetype)
   if ( CDF_Debug )
     Message("Open %s with mode %c", filename, *mode);
 
-#if  defined  (HAVE_NETCDF4)
+#ifdef  HAVE_NETCDF4
   open_file = true;
 #endif
 
@@ -221,7 +209,7 @@ int cdf4Open(const char *filename, const char *mode, int *filetype)
 
 static void cdfCloseFile(int fileID)
 {
-#if  defined  (HAVE_LIBNETCDF)
+#ifdef  HAVE_LIBNETCDF
   cdf_close(fileID);
 #endif
 }
diff --git a/libcdi/src/cdf.h b/libcdi/src/cdf.h
index c15acf0..9ffc9a2 100644
--- a/libcdi/src/cdf.h
+++ b/libcdi/src/cdf.h
@@ -1,5 +1,5 @@
-#ifndef _CDF_H
-#define _CDF_H
+#ifndef  CDF_H
+#define  CDF_H
 
 void cdfDebug(int debug);
 
@@ -8,12 +8,11 @@ extern int CDF_Debug;
 const char *cdfLibraryVersion(void);
 const char *hdfLibraryVersion(void);
 
-int  cdfOpen(const char *filename, const char *mode);
-int  cdfOpen64(const char *filename, const char *mode);
+int  cdfOpen(const char *filename, const char *mode, int filetype);
 int  cdf4Open(const char *filename, const char *mode, int *filetype);
 void cdfClose(int fileID);
 
-#endif  /* _CDF_H */
+#endif  /* CDF_H */
 /*
  * Local Variables:
  * c-file-style: "Java"
diff --git a/libcdi/src/cdf_config.h b/libcdi/src/cdf_config.h
new file mode 100644
index 0000000..38730f4
--- /dev/null
+++ b/libcdi/src/cdf_config.h
@@ -0,0 +1,18 @@
+#ifndef  CDF_CONFIG_H_
+#define  CDF_CONFIG_H_
+
+#ifdef  HAVE_CONFIG_H
+#include  "config.h"
+#endif
+
+#ifdef  HAVE_LIBNETCDF
+
+#include  <netcdf.h>
+
+#ifdef  NC_FORMAT_64BIT_DATA
+#define  HAVE_NETCDF5  1
+#endif
+
+#endif
+
+#endif
diff --git a/libcdi/src/cdf_int.h b/libcdi/src/cdf_int.h
index d4dfd0f..72bb510 100644
--- a/libcdi/src/cdf_int.h
+++ b/libcdi/src/cdf_int.h
@@ -1,5 +1,5 @@
-#ifndef _CDF_INT_H
-#define _CDF_INT_H
+#ifndef  CDF_INT_H
+#define  CDF_INT_H
 
 #if  defined  (HAVE_LIBNETCDF)
 
@@ -97,7 +97,7 @@ typedef void (*cdi_cdf_def_var_funcp)(int ncid, const char *name,
 
 #endif
 
-#endif  /* _CDF_INT_H */
+#endif  /* CDF_INT_H */
 /*
  * Local Variables:
  * c-file-style: "Java"
diff --git a/libcdi/src/cdf_read.c b/libcdi/src/cdf_read.c
index 50747db..fc72912 100644
--- a/libcdi/src/cdf_read.c
+++ b/libcdi/src/cdf_read.c
@@ -24,8 +24,8 @@ void cdfReadGridTraj(stream_t *streamptr, int gridID)
   int fileID  = streamptr->fileID;
 
   int gridindex = vlistGridIndex(vlistID, gridID);
-  int lonID = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X];
-  int latID = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_Y];
+  int lonID = streamptr->ncgrid[gridindex].ncIDs[CDF_VARID_X];
+  int latID = streamptr->ncgrid[gridindex].ncIDs[CDF_VARID_Y];
 
   int tsID = streamptr->curTsID;
   size_t index = (size_t)tsID;
@@ -43,9 +43,9 @@ void cdfGetSlapDescription(stream_t *streamptr, int varID, size_t (*start)[4], s
 {
   int vlistID = streamptr->vlistID;
   int tsID = streamptr->curTsID;
-  int gridID    = vlistInqVarGrid(vlistID, varID);
-  int zaxisID   = vlistInqVarZaxis(vlistID, varID);
-  int tsteptype = vlistInqVarTsteptype(vlistID, varID);
+  int gridID = vlistInqVarGrid(vlistID, varID);
+  int zaxisID = vlistInqVarZaxis(vlistID, varID);
+  int timetype = vlistInqVarTimetype(vlistID, varID);
   int gridindex = vlistGridIndex(vlistID, gridID);
 
   if ( CDI_Debug ) Message("tsID = %d", tsID);
@@ -70,7 +70,7 @@ void cdfGetSlapDescription(stream_t *streamptr, int varID, size_t (*start)[4], s
       (*count)[ndims] = length; \
       ndims++; \
     } while(0)
-  if ( tsteptype != TSTEP_CONSTANT ) addDimension((size_t)tsID, 1);
+  if ( timetype != TIME_CONSTANT ) addDimension((size_t)tsID, 1);
   if ( zid != CDI_UNDEFID ) addDimension(0, (size_t)zaxisInqSize(zaxisID));
   if ( yid != CDI_UNDEFID ) addDimension(0, (size_t)gridInqYsize(gridID));
   if ( xid != CDI_UNDEFID ) addDimension(0, (size_t)gridInqXsize(gridID));
@@ -420,7 +420,7 @@ void cdfGetSliceSlapDescription(stream_t *streamptr, int varId, int levelId, boo
   int ncvarid = streamptr->vars[varId].ncvarid;
 
   int gridId = vlistInqVarGrid(vlistId, varId);
-  int tsteptype = vlistInqVarTsteptype(vlistId, varId);
+  int timetype = vlistInqVarTimetype(vlistId, varId);
   int gridsize = gridInqSize(gridId);
 
   streamptr->numvals += gridsize;
@@ -443,7 +443,7 @@ void cdfGetSliceSlapDescription(stream_t *streamptr, int varId, int levelId, boo
       ndims++; \
   } while(0)
 
-  if ( tsteptype != TSTEP_CONSTANT ) addDimension((size_t)tsID, 1);
+  if ( timetype != TIME_CONSTANT ) addDimension((size_t)tsID, 1);
   if ( skipdim == 1 ) addDimension(0, 1);
 
   for ( int id = 0; id < 3; ++id )
@@ -453,7 +453,6 @@ void cdfGetSliceSlapDescription(stream_t *streamptr, int varId, int levelId, boo
       if ( curDimId == CDI_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);
diff --git a/libcdi/src/cdf_util.c b/libcdi/src/cdf_util.c
index 6a3c1c6..858af27 100644
--- a/libcdi/src/cdf_util.c
+++ b/libcdi/src/cdf_util.c
@@ -316,9 +316,10 @@ void set_zaxistype(const char *attstring, int *zaxistype)
 
 void set_calendar(const char *attstring, int *calendar)
 {
-  if ( str_is_equal(attstring, "standard") ||
-       str_is_equal(attstring, "gregorian") )
+  if ( str_is_equal(attstring, "standard") )
     *calendar = CALENDAR_STANDARD;
+  else if ( str_is_equal(attstring, "gregorian") )
+    *calendar = CALENDAR_GREGORIAN;
   else if ( str_is_equal(attstring, "none") )
     *calendar = CALENDAR_NONE;
   else if ( str_is_equal(attstring, "proleptic") )
diff --git a/libcdi/src/cdf_write.c b/libcdi/src/cdf_write.c
index f2f5eef..49484fe 100644
--- a/libcdi/src/cdf_write.c
+++ b/libcdi/src/cdf_write.c
@@ -97,7 +97,8 @@ void cdfDefVarMissval(stream_t *streamptr, int varID, int dtype, int lcheck)
       if ( lcheck == 0 ||
            streamptr->ncmode != 2 ||
            streamptr->filetype == CDI_FILETYPE_NC ||
-           streamptr->filetype == CDI_FILETYPE_NC2 )
+           streamptr->filetype == CDI_FILETYPE_NC2||
+           streamptr->filetype == CDI_FILETYPE_NC5 )
         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);
@@ -341,12 +342,12 @@ int cdfDefVar(stream_t *streamptr, int varID)
   if ( streamptr->vars[varID].ncvarid != CDI_UNDEFID )
     return streamptr->vars[varID].ncvarid;
 
-  int vlistID   = streamptr->vlistID;
-  int gridID    = vlistInqVarGrid(vlistID, varID);
-  int zaxisID   = vlistInqVarZaxis(vlistID, varID);
-  int tsteptype = vlistInqVarTsteptype(vlistID, varID);
-  int code      = vlistInqVarCode(vlistID, varID);
-  int param     = vlistInqVarParam(vlistID, varID);
+  int vlistID  = streamptr->vlistID;
+  int gridID   = vlistInqVarGrid(vlistID, varID);
+  int zaxisID  = vlistInqVarZaxis(vlistID, varID);
+  int timetype = vlistInqVarTimetype(vlistID, varID);
+  int code     = vlistInqVarCode(vlistID, varID);
+  int param    = vlistInqVarParam(vlistID, varID);
   int pnum, pcat, pdis;
   cdiDecodeParam(param, &pnum, &pcat, &pdis);
 
@@ -381,7 +382,7 @@ int cdfDefVar(stream_t *streamptr, int varID)
 
   int tid = streamptr->basetime.ncdimid;
 
-  if ( tsteptype != TSTEP_CONSTANT )
+  if ( vlistHasTime(vlistID) && timetype != TIME_CONSTANT )
     {
       if ( tid == CDI_UNDEFID ) Error("Internal problem, time undefined!");
       chunks[ndims] = 1;
@@ -587,7 +588,7 @@ int cdfDefVar(stream_t *streamptr, int varID)
 
   if ( gridtype == GRID_TRAJECTORY )
     {
-      cdf_put_att_text(fileID, ncvarid, "coordinates", 9, "tlon tlat" );
+      cdf_put_att_text(fileID, ncvarid, "coordinates", 9, "lon lat" );
     }
   else if ( gridtype == GRID_LONLAT && xid == CDI_UNDEFID && yid == CDI_UNDEFID && gridsize == 1 )
     {
@@ -1002,13 +1003,11 @@ void cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data
   long ntsteps = streamptr->ntsteps;
   if ( CDI_Debug ) Message("ntsteps = %ld", ntsteps);
 
-  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
-
   int ncvarid = cdfDefVar(streamptr, varID);
 
-  int gridID    = vlistInqVarGrid(vlistID, varID);
-  int zaxisID   = vlistInqVarZaxis(vlistID, varID);
-  int tsteptype = vlistInqVarTsteptype(vlistID, varID);
+  int gridID   = vlistInqVarGrid(vlistID, varID);
+  int zaxisID  = vlistInqVarZaxis(vlistID, varID);
+  int timetype = vlistInqVarTimetype(vlistID, varID);
 
   int xid = CDI_UNDEFID, yid = CDI_UNDEFID;
   if ( gridInqType(gridID) == GRID_TRAJECTORY )
@@ -1025,7 +1024,7 @@ void cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data
   int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
   int zid = streamptr->zaxisID[zaxisindex];
 
-  if ( tsteptype != TSTEP_CONSTANT )
+  if ( timetype != TIME_CONSTANT )
     {
       start[ndims] = (size_t)ntsteps - 1;
       count[ndims] = 1;
@@ -1097,16 +1096,13 @@ void cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
   int fileID  = streamInqFileID(streamID);
 
   long ntsteps = streamptr->ntsteps;
-  if ( CDI_Debug )
-    Message("ntsteps = %ld", ntsteps);
-
-  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
+  if ( CDI_Debug ) Message("ntsteps = %ld", ntsteps);
 
   int ncvarid = cdfDefVar(streamptr, varID);
 
-  int gridID    = vlistInqVarGrid(vlistID, varID);
-  int zaxisID   = vlistInqVarZaxis(vlistID, varID);
-  int tsteptype = vlistInqVarTsteptype(vlistID, varID);
+  int gridID   = vlistInqVarGrid(vlistID, varID);
+  int zaxisID  = vlistInqVarZaxis(vlistID, varID);
+  int timetype = vlistInqVarTimetype(vlistID, varID);
 
   if ( gridInqType(gridID) == GRID_TRAJECTORY )
     {
@@ -1122,7 +1118,7 @@ void cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
   int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
   int zid = streamptr->zaxisID[zaxisindex];
 
-  if ( tsteptype != TSTEP_CONSTANT )
+  if ( timetype != TIME_CONSTANT )
     {
       start[ndims] = (size_t)ntsteps - 1;
       count[ndims] = 1;
@@ -1197,13 +1193,11 @@ void cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtyp
   long ntsteps = streamptr->ntsteps;
   if ( CDI_Debug ) Message("ntsteps = %ld", ntsteps);
 
-  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
-
   int ncvarid = cdfDefVar(streamptr, varID);
 
-  int gridID    = vlistInqVarGrid(vlistID, varID);
-  int zaxisID   = vlistInqVarZaxis(vlistID, varID);
-  int tsteptype = vlistInqVarTsteptype(vlistID, varID);
+  int gridID   = vlistInqVarGrid(vlistID, varID);
+  int zaxisID  = vlistInqVarZaxis(vlistID, varID);
+  int timetype = vlistInqVarTimetype(vlistID, varID);
   vlistInqVarDimorder(vlistID, varID, &dimorder);
 
   if ( gridInqType(gridID) == GRID_TRAJECTORY )
@@ -1223,7 +1217,7 @@ void cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtyp
   bool swapxy = (dimorder[2] == 2 || dimorder[0] == 1) && xid != CDI_UNDEFID && yid != CDI_UNDEFID;
 
   size_t ndims = 0;
-  if ( tsteptype != TSTEP_CONSTANT )
+  if ( timetype != TIME_CONSTANT )
     {
       start[ndims] = (size_t)ntsteps - 1;
       count[ndims] = 1;
diff --git a/libcdi/src/cdi.h b/libcdi/src/cdi.h
index 1308607..4ad9bc0 100644
--- a/libcdi/src/cdi.h
+++ b/libcdi/src/cdi.h
@@ -50,12 +50,13 @@ extern "C" {
 #define  CDI_FILETYPE_GRB           1   // File type GRIB
 #define  CDI_FILETYPE_GRB2          2   // File type GRIB version 2
 #define  CDI_FILETYPE_NC            3   // File type NetCDF
-#define  CDI_FILETYPE_NC2           4   // File type NetCDF version 2 (64-bit)
+#define  CDI_FILETYPE_NC2           4   // File type NetCDF version 2 (64-bit offset)
 #define  CDI_FILETYPE_NC4           5   // File type NetCDF version 4
 #define  CDI_FILETYPE_NC4C          6   // File type NetCDF version 4 (classic)
-#define  CDI_FILETYPE_SRV           7   // File type SERVICE
-#define  CDI_FILETYPE_EXT           8   // File type EXTRA
-#define  CDI_FILETYPE_IEG           9   // File type IEG
+#define  CDI_FILETYPE_NC5           7   // File type NetCDF version 5 (64-bit data)
+#define  CDI_FILETYPE_SRV           8   // File type SERVICE
+#define  CDI_FILETYPE_EXT           9   // File type EXTRA
+#define  CDI_FILETYPE_IEG          10   // File type IEG
 
 #define  FILETYPE_GRB           1
 #define  FILETYPE_GRB2          2
@@ -224,12 +225,12 @@ typedef struct  {
 
 /* TIME types */
 
-#define  TIME_CONSTANT              0  /* obsolate, use TSTEP_CONSTANT                          */
-#define  TIME_VARIABLE              1  /* obsolate, use TSTEP_INSTANT                           */
+#define  TIME_CONSTANT              0  /* Time constant              */
+#define  TIME_VARYING               1  /* Time varying               */
+#define  TIME_VARIABLE              1  /* obsolate, use TIME_VARYING */
 
 /* TSTEP types */
 
-#define  TSTEP_CONSTANT             0  /* Constant            */
 #define  TSTEP_INSTANT              1  /* Instant             */
 #define  TSTEP_AVG                  2  /* Average             */
 #define  TSTEP_ACCUM                3  /* Accumulation        */
@@ -267,11 +268,12 @@ typedef struct  {
 /* 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
+#define  CALENDAR_GREGORIAN       1
+#define  CALENDAR_PROLEPTIC       2
+#define  CALENDAR_360DAYS         3
+#define  CALENDAR_365DAYS         4
+#define  CALENDAR_366DAYS         5
+#define  CALENDAR_NONE            6
 
 /* number of unsigned char needed to store UUID */
 #define  CDI_UUID_SIZE           16
@@ -554,21 +556,24 @@ int     vlistInqModel(int vlistID);
 /* VLIST VAR routines */
 
 /*      vlistDefVarTiles: Create a new tile-based variable */
-int     vlistDefVarTiles(int vlistID, int gridID, int zaxisID, int tsteptype, int tilesetID);
+int     vlistDefVarTiles(int vlistID, int gridID, int zaxisID, int timetype, int tilesetID);
 
 /*      vlistDefVar: Create a new variable */
-int     vlistDefVar(int vlistID, int gridID, int zaxisID, int tsteptype);
+int     vlistDefVar(int vlistID, int gridID, int zaxisID, int timetype);
 
 void    vlistChangeVarGrid(int vlistID, int varID, int gridID);
 void    vlistChangeVarZaxis(int vlistID, int varID, int zaxisID);
 
-void    vlistInqVar(int vlistID, int varID, int *gridID, int *zaxisID, int *tsteptype);
+void    vlistInqVar(int vlistID, int varID, int *gridID, int *zaxisID, int *timetype);
 int     vlistInqVarGrid(int vlistID, int varID);
 int     vlistInqVarZaxis(int vlistID, int varID);
 
 /* used in MPIOM */
 int     vlistInqVarID(int vlistID, int code);
 
+void    vlistDefVarTimetype(int vlistID, int varID, int timetype);
+int     vlistInqVarTimetype(int vlistID, int varID);
+
 void    vlistDefVarTsteptype(int vlistID, int varID, int tsteptype);
 
 /*      vlistInqVarTsteptype: Get the timestep type of a Variable */
@@ -881,11 +886,11 @@ void    gridInqXstdname(int gridID, char *xstdname);
 /*      gridInqYstdname: Get the standard name of a Y-axis */
 void    gridInqYstdname(int gridID, char *ystdname);
 
-/*      gridDefPrec: Define the precision of a Grid */
-void    gridDefPrec(int gridID, int prec);
+/*      gridDefDatatype: Define the data type of a Grid */
+void    gridDefDatatype(int gridID, int prec);
 
-/*      gridInqPrec: Get the precision of a Grid */
-int     gridInqPrec(int gridID);
+/*      gridInqDatatype: Get the data type of a Grid */
+int     gridInqDatatype(int gridID);
 
 /*      gridInqXval: Get one value of a X-axis */
 double  gridInqXval(int gridID, int index);
@@ -1070,8 +1075,8 @@ void    zaxisInqUnits(int zaxisID, char *units);
 /*      zaxisInqStdname: Get the standard name of a Z-axis */
 void    zaxisInqStdname(int zaxisID, char *stdname);
 
-void    zaxisDefPrec(int zaxisID, int prec);
-int     zaxisInqPrec(int zaxisID);
+void    zaxisDefDatatype(int zaxisID, int prec);
+int     zaxisInqDatatype(int zaxisID);
 
 void    zaxisDefPositive(int zaxisID, int positive);
 int     zaxisInqPositive(int zaxisID);
@@ -1147,6 +1152,7 @@ int     taxisInqFdate(int taxisID);
 int     taxisInqFtime(int taxisID);
 
 int     taxisHasBounds(int taxisID);
+void    taxisWithBounds(int taxisID);
 
 void    taxisDeleteBounds(int taxisID);
 
diff --git a/libcdi/src/cdi.inc b/libcdi/src/cdi.inc
index b1e5583..bb59831 100644
--- a/libcdi/src/cdi.inc
+++ b/libcdi/src/cdi.inc
@@ -4,7 +4,7 @@
 !
 ! Author:
 ! -------
-! Uwe Schulzweida, MPI-MET, Hamburg,   July 2017
+! Uwe Schulzweida, MPI-MET, Hamburg,   October 2017
 !
 
       INTEGER    CDI_MAX_NAME
@@ -70,12 +70,14 @@
       PARAMETER (CDI_FILETYPE_NC4       =  5)
       INTEGER    CDI_FILETYPE_NC4C
       PARAMETER (CDI_FILETYPE_NC4C      =  6)
+      INTEGER    CDI_FILETYPE_NC5
+      PARAMETER (CDI_FILETYPE_NC5       =  7)
       INTEGER    CDI_FILETYPE_SRV
-      PARAMETER (CDI_FILETYPE_SRV       =  7)
+      PARAMETER (CDI_FILETYPE_SRV       =  8)
       INTEGER    CDI_FILETYPE_EXT
-      PARAMETER (CDI_FILETYPE_EXT       =  8)
+      PARAMETER (CDI_FILETYPE_EXT       =  9)
       INTEGER    CDI_FILETYPE_IEG
-      PARAMETER (CDI_FILETYPE_IEG       =  9)
+      PARAMETER (CDI_FILETYPE_IEG       = 10)
       INTEGER    FILETYPE_GRB
       PARAMETER (FILETYPE_GRB           =  1)
       INTEGER    FILETYPE_GRB2
@@ -358,13 +360,13 @@
 !
       INTEGER    TIME_CONSTANT
       PARAMETER (TIME_CONSTANT          =  0)
+      INTEGER    TIME_VARYING
+      PARAMETER (TIME_VARYING           =  1)
       INTEGER    TIME_VARIABLE
       PARAMETER (TIME_VARIABLE          =  1)
 !
 !  TSTEP types
 !
-      INTEGER    TSTEP_CONSTANT
-      PARAMETER (TSTEP_CONSTANT         =  0)
       INTEGER    TSTEP_INSTANT
       PARAMETER (TSTEP_INSTANT          =  1)
       INTEGER    TSTEP_AVG
@@ -430,16 +432,18 @@
 !
       INTEGER    CALENDAR_STANDARD
       PARAMETER (CALENDAR_STANDARD      =  0)
+      INTEGER    CALENDAR_GREGORIAN
+      PARAMETER (CALENDAR_GREGORIAN     =  1)
       INTEGER    CALENDAR_PROLEPTIC
-      PARAMETER (CALENDAR_PROLEPTIC     =  1)
+      PARAMETER (CALENDAR_PROLEPTIC     =  2)
       INTEGER    CALENDAR_360DAYS
-      PARAMETER (CALENDAR_360DAYS       =  2)
+      PARAMETER (CALENDAR_360DAYS       =  3)
       INTEGER    CALENDAR_365DAYS
-      PARAMETER (CALENDAR_365DAYS       =  3)
+      PARAMETER (CALENDAR_365DAYS       =  4)
       INTEGER    CALENDAR_366DAYS
-      PARAMETER (CALENDAR_366DAYS       =  4)
+      PARAMETER (CALENDAR_366DAYS       =  5)
       INTEGER    CALENDAR_NONE
-      PARAMETER (CALENDAR_NONE          =  5)
+      PARAMETER (CALENDAR_NONE          =  6)
 !
 !  number of unsigned char needed to store UUID
 !
@@ -947,7 +951,7 @@
 !                                    (INTEGER         vlistID,
 !                                     INTEGER         gridID,
 !                                     INTEGER         zaxisID,
-!                                     INTEGER         tsteptype,
+!                                     INTEGER         timetype,
 !                                     INTEGER         tilesetID)
       EXTERNAL        vlistDefVarTiles
 
@@ -955,7 +959,7 @@
 !                                    (INTEGER         vlistID,
 !                                     INTEGER         gridID,
 !                                     INTEGER         zaxisID,
-!                                     INTEGER         tsteptype)
+!                                     INTEGER         timetype)
       EXTERNAL        vlistDefVar
 
 !                     vlistChangeVarGrid
@@ -975,7 +979,7 @@
 !                                     INTEGER         varID,
 !                                     INTEGER         gridID,
 !                                     INTEGER         zaxisID,
-!                                     INTEGER         tsteptype)
+!                                     INTEGER         timetype)
       EXTERNAL        vlistInqVar
 
       INTEGER         vlistInqVarGrid
@@ -996,6 +1000,17 @@
 !                                     INTEGER         code)
       EXTERNAL        vlistInqVarID
 
+!                     vlistDefVarTimetype
+!                                    (INTEGER         vlistID,
+!                                     INTEGER         varID,
+!                                     INTEGER         timetype)
+      EXTERNAL        vlistDefVarTimetype
+
+      INTEGER         vlistInqVarTimetype
+!                                    (INTEGER         vlistID,
+!                                     INTEGER         varID)
+      EXTERNAL        vlistInqVarTimetype
+
 !                     vlistDefVarTsteptype
 !                                    (INTEGER         vlistID,
 !                                     INTEGER         varID,
@@ -1724,14 +1739,14 @@
 !                                     CHARACTER*(*)   ystdname)
       EXTERNAL        gridInqYstdname
 
-!                     gridDefPrec
+!                     gridDefDatatype
 !                                    (INTEGER         gridID,
 !                                     INTEGER         prec)
-      EXTERNAL        gridDefPrec
+      EXTERNAL        gridDefDatatype
 
-      INTEGER         gridInqPrec
+      INTEGER         gridInqDatatype
 !                                    (INTEGER         gridID)
-      EXTERNAL        gridInqPrec
+      EXTERNAL        gridInqDatatype
 
       DOUBLEPRECISION gridInqXval
 !                                    (INTEGER         gridID,
@@ -2099,14 +2114,14 @@
 !                                     CHARACTER*(*)   stdname)
       EXTERNAL        zaxisInqStdname
 
-!                     zaxisDefPrec
+!                     zaxisDefDatatype
 !                                    (INTEGER         zaxisID,
 !                                     INTEGER         prec)
-      EXTERNAL        zaxisDefPrec
+      EXTERNAL        zaxisDefDatatype
 
-      INTEGER         zaxisInqPrec
+      INTEGER         zaxisInqDatatype
 !                                    (INTEGER         zaxisID)
-      EXTERNAL        zaxisInqPrec
+      EXTERNAL        zaxisInqDatatype
 
 !                     zaxisDefPositive
 !                                    (INTEGER         zaxisID,
@@ -2277,6 +2292,10 @@
 !                                    (INTEGER         taxisID)
       EXTERNAL        taxisHasBounds
 
+!                     taxisWithBounds
+!                                    (INTEGER         taxisID)
+      EXTERNAL        taxisWithBounds
+
 !                     taxisDeleteBounds
 !                                    (INTEGER         taxisID)
       EXTERNAL        taxisDeleteBounds
diff --git a/libcdi/src/cdiFortran.c b/libcdi/src/cdiFortran.c
index 70de7f1..6b8e702 100644
--- a/libcdi/src/cdiFortran.c
+++ b/libcdi/src/cdiFortran.c
@@ -233,6 +233,8 @@ FCALLSCFUN2 (INT, vlistInqVarZaxis, VLISTINQVARZAXIS, vlistinqvarzaxis, INT, INT
 /*  used in MPIOM  */
 
 FCALLSCFUN2 (INT, vlistInqVarID, VLISTINQVARID, vlistinqvarid, INT, INT)
+FCALLSCSUB3 (vlistDefVarTimetype, VLISTDEFVARTIMETYPE, vlistdefvartimetype, INT, INT, INT)
+FCALLSCFUN2 (INT, vlistInqVarTimetype, VLISTINQVARTIMETYPE, vlistinqvartimetype, INT, INT)
 FCALLSCSUB3 (vlistDefVarTsteptype, VLISTDEFVARTSTEPTYPE, vlistdefvartsteptype, INT, INT, INT)
 FCALLSCFUN2 (INT, vlistInqVarTsteptype, VLISTINQVARTSTEPTYPE, vlistinqvartsteptype, INT, INT)
 FCALLSCSUB3 (vlistDefVarCompType, VLISTDEFVARCOMPTYPE, vlistdefvarcomptype, INT, INT, INT)
@@ -370,8 +372,8 @@ FCALLSCSUB2 (gridDefYunits, GRIDDEFYUNITS, griddefyunits, INT, STRING)
 FCALLSCSUB2 (gridInqYunits, GRIDINQYUNITS, gridinqyunits, INT, PSTRING)
 FCALLSCSUB2 (gridInqXstdname, GRIDINQXSTDNAME, gridinqxstdname, INT, PSTRING)
 FCALLSCSUB2 (gridInqYstdname, GRIDINQYSTDNAME, gridinqystdname, INT, PSTRING)
-FCALLSCSUB2 (gridDefPrec, GRIDDEFPREC, griddefprec, INT, INT)
-FCALLSCFUN1 (INT, gridInqPrec, GRIDINQPREC, gridinqprec, INT)
+FCALLSCSUB2 (gridDefDatatype, GRIDDEFDATATYPE, griddefdatatype, INT, INT)
+FCALLSCFUN1 (INT, gridInqDatatype, GRIDINQDATATYPE, gridinqdatatype, INT)
 FCALLSCFUN2 (DOUBLE, gridInqXval, GRIDINQXVAL, gridinqxval, INT, INT)
 FCALLSCFUN2 (DOUBLE, gridInqYval, GRIDINQYVAL, gridinqyval, INT, INT)
 FCALLSCFUN1 (DOUBLE, gridInqXinc, GRIDINQXINC, gridinqxinc, INT)
@@ -454,8 +456,8 @@ FCALLSCSUB2 (zaxisInqLongname, ZAXISINQLONGNAME, zaxisinqlongname, INT, PSTRING)
 FCALLSCSUB2 (zaxisDefUnits, ZAXISDEFUNITS, zaxisdefunits, INT, STRING)
 FCALLSCSUB2 (zaxisInqUnits, ZAXISINQUNITS, zaxisinqunits, INT, PSTRING)
 FCALLSCSUB2 (zaxisInqStdname, ZAXISINQSTDNAME, zaxisinqstdname, INT, PSTRING)
-FCALLSCSUB2 (zaxisDefPrec, ZAXISDEFPREC, zaxisdefprec, INT, INT)
-FCALLSCFUN1 (INT, zaxisInqPrec, ZAXISINQPREC, zaxisinqprec, INT)
+FCALLSCSUB2 (zaxisDefDatatype, ZAXISDEFDATATYPE, zaxisdefdatatype, INT, INT)
+FCALLSCFUN1 (INT, zaxisInqDatatype, ZAXISINQDATATYPE, zaxisinqdatatype, INT)
 FCALLSCSUB2 (zaxisDefPositive, ZAXISDEFPOSITIVE, zaxisdefpositive, INT, INT)
 FCALLSCFUN1 (INT, zaxisInqPositive, ZAXISINQPOSITIVE, zaxisinqpositive, INT)
 FCALLSCSUB1 (zaxisDefScalar, ZAXISDEFSCALAR, zaxisdefscalar, INT)
@@ -495,6 +497,7 @@ FCALLSCSUB2 (taxisDefFtime, TAXISDEFFTIME, taxisdefftime, INT, INT)
 FCALLSCFUN1 (INT, taxisInqFdate, TAXISINQFDATE, taxisinqfdate, INT)
 FCALLSCFUN1 (INT, taxisInqFtime, TAXISINQFTIME, taxisinqftime, INT)
 FCALLSCFUN1 (INT, taxisHasBounds, TAXISHASBOUNDS, taxishasbounds, INT)
+FCALLSCSUB1 (taxisWithBounds, TAXISWITHBOUNDS, taxiswithbounds, INT)
 FCALLSCSUB1 (taxisDeleteBounds, TAXISDELETEBOUNDS, taxisdeletebounds, INT)
 FCALLSCSUB3 (taxisDefVdateBounds, TAXISDEFVDATEBOUNDS, taxisdefvdatebounds, INT, INT, INT)
 FCALLSCSUB3 (taxisDefVtimeBounds, TAXISDEFVTIMEBOUNDS, taxisdefvtimebounds, INT, INT, INT)
diff --git a/libcdi/src/cdi_int.c b/libcdi/src/cdi_int.c
index ac2cbbd..d36b2cb 100644
--- a/libcdi/src/cdi_int.c
+++ b/libcdi/src/cdi_int.c
@@ -1,5 +1,5 @@
-#if defined (HAVE_CONFIG_H)
-#  include "config.h"
+#ifdef  HAVE_CONFIG_H
+#include "config.h"
 #endif
 
 #include <stdarg.h>
@@ -12,13 +12,13 @@
 #include "dmemory.h"
 #include "file.h"
 #include "gribapi.h"
-#ifdef HAVE_LIBNETCDF
+#ifdef  HAVE_LIBNETCDF
 #include "stream_cdf.h"
 #endif
 #include "namespace.h"
 #include "resource_handle.h"
 
-#if  defined  (HAVE_LIBCGRIBEX)
+#ifdef  HAVE_LIBCGRIBEX
 #include "cgribex.h"
 #endif
 
@@ -40,6 +40,7 @@ int cdiConvention           = CDI_CONVENTION_ECHAM;
 int cdiInventoryMode        = 1;
 int CDI_Version_Info        = 1;
 int CDI_cmor_mode           = 0;
+int CDI_reduce_dim          = 0;
 size_t CDI_netcdf_hdr_pad   = 0UL;
 bool CDI_netcdf_lazy_grid_load = false;
 
@@ -56,6 +57,7 @@ static const char Filetypes[][9] = {
   "NetCDF2",
   "NetCDF4",
   "NetCDF4c",
+  "NetCDF5",
   "SERVICE",
   "EXTRA",
   "IEG",
@@ -75,18 +77,14 @@ int cdiHaveMissval = 0;
 
 static long cdiGetenvInt(const char *envName)
 {
-  char *envString;
   long envValue = -1;
-  long fact = 1;
-
-  envString = getenv(envName);
 
+  char *envString = getenv(envName);
   if ( envString )
     {
-      int loop, len;
-
-      len = (int) strlen(envString);
-      for ( loop = 0; loop < len; loop++ )
+      long fact = 1;
+      int len = (int) strlen(envString);
+      for ( int loop = 0; loop < len; loop++ )
 	{
 	  if ( ! isdigit((int) envString[loop]) )
 	    {
@@ -110,7 +108,7 @@ static long cdiGetenvInt(const char *envName)
       if ( CDI_Debug ) Message("set %s to %ld", envName, envValue);
     }
 
-  return (envValue);
+  return envValue;
 }
 
 static void
@@ -126,25 +124,25 @@ cdiPrintDefaults(void)
 void cdiPrintVersion(void)
 {
   fprintf(stderr, "     CDI library version : %s\n", cdiLibraryVersion());
-#if  defined  (HAVE_LIBCGRIBEX)
+#ifdef  HAVE_LIBCGRIBEX
   fprintf(stderr, " CGRIBEX library version : %s\n", cgribexLibraryVersion());
 #endif
-#if  defined  (HAVE_LIBGRIB_API)
+#ifdef  HAVE_LIBGRIB_API
   fprintf(stderr, "GRIB_API library version : %s\n", gribapiLibraryVersionString());
 #endif
-#if  defined  (HAVE_LIBNETCDF)
+#ifdef  HAVE_LIBNETCDF
   fprintf(stderr, "  NetCDF library version : %s\n", cdfLibraryVersion());
 #endif
-#if  defined  (HAVE_NC4HDF5)
+#ifdef  HAVE_NC4HDF5
   fprintf(stderr, "    HDF5 library version : %s\n", hdfLibraryVersion());
 #endif
-#if  defined  (HAVE_LIBSERVICE)
+#ifdef  HAVE_LIBSERVICE
   fprintf(stderr, " SERVICE library version : %s\n", srvLibraryVersion());
 #endif
-#if  defined  (HAVE_LIBEXTRA)
+#ifdef  HAVE_LIBEXTRA
   fprintf(stderr, "   EXTRA library version : %s\n", extLibraryVersion());
 #endif
-#if  defined  (HAVE_LIBIEG)
+#ifdef  HAVE_LIBIEG
   fprintf(stderr, "     IEG library version : %s\n", iegLibraryVersion());
 #endif
   fprintf(stderr, "    FILE library version : %s\n", fileLibraryVersion());
@@ -192,6 +190,7 @@ static void cdiPrintDatatypes(void)
 #undef XSTRING
 }
 
+
 void cdiDebug(int level)
 {
   if ( level == 1 || (level &  2) ) CDI_Debug = 1;
@@ -235,37 +234,40 @@ int cdiHaveFiletype(int filetype)
 
   switch (filetype)
     {
-#if  defined  (HAVE_LIBSERVICE)
-    case CDI_FILETYPE_SRV:  { status = 1; break; }
+#ifdef  HAVE_LIBSERVICE
+    case CDI_FILETYPE_SRV:  status = 1; break;
 #endif
-#if  defined  (HAVE_LIBEXTRA)
-    case CDI_FILETYPE_EXT:  { status = 1; break; }
+#ifdef  HAVE_LIBEXTRA
+    case CDI_FILETYPE_EXT:  status = 1; break;
 #endif
-#if  defined  (HAVE_LIBIEG)
-    case CDI_FILETYPE_IEG:  { status = 1; break; }
+#ifdef  HAVE_LIBIEG
+    case CDI_FILETYPE_IEG:  status = 1; break;
 #endif
-#if  defined  (HAVE_LIBGRIB)
+#ifdef  HAVE_LIBGRIB
 #if  defined  (HAVE_LIBGRIB_API) || defined  (HAVE_LIBCGRIBEX)
-    case CDI_FILETYPE_GRB:  { status = 1; break; }
+    case CDI_FILETYPE_GRB:  status = 1; break;
 #endif
-#if  defined  (HAVE_LIBGRIB_API)
-    case CDI_FILETYPE_GRB2: { status = 1; break; }
+#ifdef  HAVE_LIBGRIB_API
+    case CDI_FILETYPE_GRB2: status = 1; break;
 #endif
 #endif
-#if  defined  (HAVE_LIBNETCDF)
-    case CDI_FILETYPE_NC:   { status = 1; break; }
-#if  defined  (HAVE_NETCDF2)
-    case CDI_FILETYPE_NC2:  { status = 1; break; }
+#ifdef  HAVE_LIBNETCDF
+    case CDI_FILETYPE_NC:   status = 1; break;
+#ifdef  HAVE_NETCDF2
+    case CDI_FILETYPE_NC2:  status = 1; break;
+#endif
+#ifdef  HAVE_NETCDF4
+    case CDI_FILETYPE_NC4:  status = 1; break;
+    case CDI_FILETYPE_NC4C: status = 1; break;
 #endif
-#if  defined  (HAVE_NETCDF4)
-    case CDI_FILETYPE_NC4:  { status = 1; break; }
-    case CDI_FILETYPE_NC4C: { status = 1; break; }
+#ifdef  HAVE_NETCDF5
+    case CDI_FILETYPE_NC5:  status = 1; break;
 #endif
 #endif
-    default: { status = 0; break; }
+    default: status = 0; break;
     }
 
-  return (status);
+  return status;
 }
 
 void cdiDefTableID(int tableID)
@@ -322,7 +324,7 @@ void cdiInitialize(void)
       char *envstr;
       long value;
 
-#if  defined  (HAVE_LIBCGRIBEX)
+#ifdef  HAVE_LIBCGRIBEX
       gribFixZSE(1);   // 1: Fix ZeroShiftError of simple packed spherical harmonics
       gribSetConst(1); // 1: Don't pack constant fields on regular grids
 #endif
@@ -425,6 +427,8 @@ void cdiInitialize(void)
 	{
 	  if      ( strncmp(envstr, "standard", 8) == 0 )
 	    cdiDefaultCalendar = CALENDAR_STANDARD;
+	  else if ( strncmp(envstr, "gregorian", 9) == 0 )
+	    cdiDefaultCalendar = CALENDAR_GREGORIAN;
 	  else if ( strncmp(envstr, "proleptic", 9) == 0 )
 	    cdiDefaultCalendar = CALENDAR_PROLEPTIC;
 	  else if ( strncmp(envstr, "360days", 7) == 0 )
@@ -439,7 +443,7 @@ void cdiInitialize(void)
 	  if ( CDI_Debug )
 	    Message("Default calendar set to %s!", envstr);
 	}
-#if  defined  (HAVE_LIBCGRIBEX)
+#ifdef  HAVE_LIBCGRIBEX
       gribSetCalendar(cdiDefaultCalendar);
 #endif
 
@@ -454,15 +458,10 @@ void cdiInitialize(void)
 
 const char *strfiletype(int filetype)
 {
-  const char *name;
   int size = (int) (sizeof(Filetypes)/sizeof(char *));
+  const char *name = (filetype > 0 && filetype < size) ? Filetypes[filetype] : Filetypes[0];
 
-  if ( filetype > 0 && filetype < size )
-    name = Filetypes[filetype];
-  else
-    name = Filetypes[0];
-
-  return (name);
+  return name;
 }
 
 
@@ -475,6 +474,7 @@ void cdiDefGlobal(const char *string, int val)
   else if ( strcmp(string, "HAVE_MISSVAL")     == 0 ) cdiHaveMissval = val;
   else if ( strcmp(string, "NC_CHUNKSIZEHINT") == 0 ) cdiNcChunksizehint = val;
   else if ( strcmp(string, "CMOR_MODE")        == 0 ) CDI_cmor_mode = val;
+  else if ( strcmp(string, "REDUCE_DIM")       == 0 ) CDI_reduce_dim = val;
   else if ( strcmp(string, "NETCDF_HDR_PAD")   == 0 ) CDI_netcdf_hdr_pad = (size_t) val;
   else if ( strcmp(string, "NETCDF_LAZY_GRID_LOAD") == 0)
     CDI_netcdf_lazy_grid_load = (bool)val;
@@ -494,7 +494,7 @@ double cdiInqMissval(void)
 {
   cdiInitialize();
 
-  return (cdiDefaultMissval);
+  return cdiDefaultMissval;
 }
 
 /*
diff --git a/libcdi/src/cdi_int.h b/libcdi/src/cdi_int.h
index b687486..7a0fd20 100644
--- a/libcdi/src/cdi_int.h
+++ b/libcdi/src/cdi_int.h
@@ -1,5 +1,5 @@
-#ifndef _CDI_INT_H
-#define _CDI_INT_H
+#ifndef  CDI_INT_H
+#define  CDI_INT_H
 
 #if defined (HAVE_CONFIG_H)
 #include "config.h"
@@ -14,6 +14,7 @@
 #include <sys/types.h>
 
 #include "cdi.h"
+#include "cdf_config.h"
 
 /* dummy use of unused parameters to silence compiler warnings */
 #ifndef UNUSED
@@ -341,6 +342,7 @@ extern int cdiConvention;
 extern int cdiInventoryMode;
 extern int CDI_Version_Info;
 extern int CDI_cmor_mode;
+extern int CDI_reduce_dim;
 extern size_t CDI_netcdf_hdr_pad;
 extern bool CDI_netcdf_lazy_grid_load;
 extern int STREAM_Debug;
@@ -483,7 +485,7 @@ void gridGenYvals(int gridtype, int ysize, double yfirst, double ylast, double y
 }
 #endif
 
-#endif  /* _CDI_INT_H */
+#endif  /* CDI_INT_H */
 /*
  * Local Variables:
  * c-file-style: "Java"
diff --git a/libcdi/src/cdilib.c b/libcdi/src/cdilib.c
index f623ab6..9295e75 100644
--- a/libcdi/src/cdilib.c
+++ b/libcdi/src/cdilib.c
@@ -1,7 +1,7 @@
 
-/* Automatically generated by m214003 at 2017-06-19, do not edit */
+/* Automatically generated by m214003 at 2016-06-07, do not edit */
 
-/* CDILIB_VERSION="1.9.0" */
+/* CDILIB_VERSION="1.7.2" */
 
 #ifdef _ARCH_PWR6
 #pragma options nostrict
@@ -58,8 +58,8 @@
 #  define  HAVE_LIBIEG       1
 #endif
 
-#ifndef ERROR_H
-#define ERROR_H
+#ifndef _ERROR_H
+#define _ERROR_H
 
 #include <stdarg.h>
 #include <stdlib.h>
@@ -130,7 +130,7 @@ cdiAbortC_serial(const char *caller, const char *filename,
 }
 #endif
 
-#endif  /* ERROR_H */
+#endif  /* _ERROR_H */
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -157,129 +157,102 @@ extern "C" {
 #endif
 
 
-#define  CDI_MAX_NAME             256   // max length of a name
+#define  CDI_MAX_NAME           256   /* max length of a name                 */
 
-#define  CDI_UNDEFID               -1
-#define  CDI_GLOBAL                -1   // Global var ID for vlist
+#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_PDPENDIAN              2
+#define  CDI_BIGENDIAN            0   /* Byte order BIGENDIAN                 */
+#define  CDI_LITTLEENDIAN         1   /* Byte order LITTLEENDIAN              */
+#define  CDI_PDPENDIAN            2
 
-#define  CDI_REAL                   1   // Real numbers
-#define  CDI_COMP                   2   // Complex numbers
-#define  CDI_BOTH                   3   // Both numbers
+#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_EEOF                  -1   // The end of file was encountered
-#define  CDI_ESYSTEM              -10   // Operating system error
-#define  CDI_EINVAL               -20   // Invalid argument
-#define  CDI_EISDIR               -21   // Is a directory
-#define  CDI_EISEMPTY             -22   // Is empty
-#define  CDI_EUFTYPE              -23   // Unsupported file type
-#define  CDI_ELIBNAVAIL           -24   // xxx library not available
-#define  CDI_EUFSTRUCT            -25   // Unsupported file structure
-#define  CDI_EUNC4                -26   // Unsupported NetCDF4 structure
-#define  CDI_EDIMSIZE             -27   // Invalid dimension size
-#define  CDI_ELIMIT               -99   // Internal limits exceeded
+#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             */
 
 /* File types */
 
-#define  CDI_FILETYPE_GRB           1   // File type GRIB
-#define  CDI_FILETYPE_GRB2          2   // File type GRIB version 2
-#define  CDI_FILETYPE_NC            3   // File type NetCDF
-#define  CDI_FILETYPE_NC2           4   // File type NetCDF version 2 (64-bit)
-#define  CDI_FILETYPE_NC4           5   // File type NetCDF version 4
-#define  CDI_FILETYPE_NC4C          6   // File type NetCDF version 4 (classic)
-#define  CDI_FILETYPE_SRV           7   // File type SERVICE
-#define  CDI_FILETYPE_EXT           8   // File type EXTRA
-#define  CDI_FILETYPE_IEG           9   // File type IEG
-
-#define  FILETYPE_GRB           1
-#define  FILETYPE_GRB2          2
-#define  FILETYPE_NC            3
-#define  FILETYPE_NC2           4
-#define  FILETYPE_NC4           5
-#define  FILETYPE_NC4C          6
-#define  FILETYPE_SRV           7
-#define  FILETYPE_EXT           8
-#define  FILETYPE_IEG           9
+#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  CDI_COMPRESS_NONE          0
-#define  CDI_COMPRESS_SZIP          1
-#define  CDI_COMPRESS_GZIP          2
-#define  CDI_COMPRESS_BZIP2         3
-#define  CDI_COMPRESS_ZIP           4
-#define  CDI_COMPRESS_JPEG          5
+#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  CDI_DATATYPE_PACK          0
-#define  CDI_DATATYPE_PACK1         1
-#define  CDI_DATATYPE_PACK2         2
-#define  CDI_DATATYPE_PACK3         3
-#define  CDI_DATATYPE_PACK4         4
-#define  CDI_DATATYPE_PACK5         5
-#define  CDI_DATATYPE_PACK6         6
-#define  CDI_DATATYPE_PACK7         7
-#define  CDI_DATATYPE_PACK8         8
-#define  CDI_DATATYPE_PACK9         9
-#define  CDI_DATATYPE_PACK10       10
-#define  CDI_DATATYPE_PACK11       11
-#define  CDI_DATATYPE_PACK12       12
-#define  CDI_DATATYPE_PACK13       13
-#define  CDI_DATATYPE_PACK14       14
-#define  CDI_DATATYPE_PACK15       15
-#define  CDI_DATATYPE_PACK16       16
-#define  CDI_DATATYPE_PACK17       17
-#define  CDI_DATATYPE_PACK18       18
-#define  CDI_DATATYPE_PACK19       19
-#define  CDI_DATATYPE_PACK20       20
-#define  CDI_DATATYPE_PACK21       21
-#define  CDI_DATATYPE_PACK22       22
-#define  CDI_DATATYPE_PACK23       23
-#define  CDI_DATATYPE_PACK24       24
-#define  CDI_DATATYPE_PACK25       25
-#define  CDI_DATATYPE_PACK26       26
-#define  CDI_DATATYPE_PACK27       27
-#define  CDI_DATATYPE_PACK28       28
-#define  CDI_DATATYPE_PACK29       29
-#define  CDI_DATATYPE_PACK30       30
-#define  CDI_DATATYPE_PACK31       31
-#define  CDI_DATATYPE_PACK32       32
-#define  CDI_DATATYPE_CPX32        64
-#define  CDI_DATATYPE_CPX64       128
-#define  CDI_DATATYPE_FLT32       132
-#define  CDI_DATATYPE_FLT64       164
-#define  CDI_DATATYPE_INT8        208
-#define  CDI_DATATYPE_INT16       216
-#define  CDI_DATATYPE_INT32       232
-#define  CDI_DATATYPE_UINT8       308
-#define  CDI_DATATYPE_UINT16      316
-#define  CDI_DATATYPE_UINT32      332
-
 #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  CDI_DATATYPE_INT         251
-#define  CDI_DATATYPE_FLT         252
-#define  CDI_DATATYPE_TXT         253
-#define  CDI_DATATYPE_CPX         254
-#define  CDI_DATATYPE_UCHAR       255
-#define  CDI_DATATYPE_LONG        256
-
 #define  DATATYPE_INT           251
 #define  DATATYPE_FLT           252
 #define  DATATYPE_TXT           253
@@ -289,9 +262,9 @@ extern "C" {
 
 /* Chunks */
 
-#define  CDI_CHUNK_AUTO             1  /* use default chunk size                                */
-#define  CDI_CHUNK_GRID             2
-#define  CDI_CHUNK_LINES            3
+#define  CHUNK_AUTO                 1  /* use default chunk size                                */
+#define  CHUNK_GRID                 2
+#define  CHUNK_LINES                3
 
 /* GRID types */
 
@@ -306,13 +279,10 @@ extern "C" {
 #define  GRID_UNSTRUCTURED          9  /* General unstructured grid                             */
 #define  GRID_CURVILINEAR          10  /* Curvilinear grid                                      */
 #define  GRID_LCC                  11  /* Lambert Conformal Conic (GRIB)                        */
-#define  GRID_PROJECTION           12  /* Projected coordinates                                 */
-#define  GRID_CHARXY               13  /* One horizontal character dimension                    */
-
-#define  CDI_PROJ_RLL              21  /* Rotated Latitude Longitude                            */
-#define  CDI_PROJ_LCC              22  /* Lambert Conformal Conic                               */
-#define  CDI_PROJ_LAEA             23  /* Lambert Azimuthal Equal Area                          */
-#define  CDI_PROJ_SINU             24  /* Sinusoidal                                            */
+#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 */
 
@@ -342,7 +312,6 @@ extern "C" {
 #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                                */
-#define  ZAXIS_CHAR                26  /* Area types                                            */
 
 /* SUBTYPE types */
 
@@ -528,9 +497,9 @@ const char *streamFilesuffix(int filetype);
 
 off_t   streamNvals(int streamID);
 
-int     streamInqNvars(int streamID);
+int     streamInqNvars ( int streamID );
 
-/* STREAM var I/O routines (random access) */
+/* STREAM var I/O routines */
 
 /*      streamWriteVar: Write a variable */
 void    streamWriteVar(int streamID, int varID, const double data[], int nmiss);
@@ -551,7 +520,7 @@ void    streamReadVarSliceF(int streamID, int varID, int levelID, float data[],
 void    streamWriteVarChunk(int streamID, int varID, const int rect[3][2], const double data[], int nmiss);
 
 
-/* STREAM record I/O routines (sequential access) */
+/* STREAM record I/O routines */
 
 void    streamDefRecord(int streamID, int  varID, int  levelID);
 void    streamInqRecord(int streamID, int *varID, int *levelID);
@@ -846,29 +815,27 @@ const char *vlistInqVarNamePtr(int vlistID, int varID);
 const char *vlistInqVarLongnamePtr(int vlistID, int varID);
 const char *vlistInqVarUnitsPtr(int vlistID, int varID);
 
-/* CDI attributes */
+/* VLIST attributes */
 
-/*      cdiInqNatts: Get number of attributes assigned to this variable */
-int     cdiInqNatts(int cdiID, int varID, int *nattsp);
-/*      cdiInqAtt: Get information about an attribute */
-int     cdiInqAtt(int cdiID, int varID, int attrnum, char *name, int *typep, int *lenp);
-int     cdiDelAtt(int cdiID, int varID, const char *name);
+/*      vlistInqNatts: Get number of variable attributes assigned to this variable */
+int     vlistInqNatts(int vlistID, int varID, int *nattsp);
+/*      vlistInqAtt: Get information about an attribute */
+int     vlistInqAtt(int vlistID, int varID, int attrnum, char *name, int *typep, int *lenp);
+int     vlistDelAtt(int vlistID, int varID, const char *name);
 
-int     cdiCopyAtts(int cdiID1, int varID1, int cdiID2, int varID2);
+/*      vlistDefAttInt: Define an integer attribute */
+int     vlistDefAttInt(int vlistID, int varID, const char *name, int type, int len, const int ip[]);
+/*      vlistDefAttFlt: Define a floating point attribute */
+int     vlistDefAttFlt(int vlistID, int varID, const char *name, int type, int len, const double dp[]);
+/*      vlistDefAttTxt: Define a text attribute */
+int     vlistDefAttTxt(int vlistID, int varID, const char *name, int len, const char *tp_cbuf);
 
-/*      cdiDefAttInt: Define an integer attribute */
-int     cdiDefAttInt(int cdiID, int varID, const char *name, int type, int len, const int ip[]);
-/*      cdiDefAttFlt: Define a floating point attribute */
-int     cdiDefAttFlt(int cdiID, int varID, const char *name, int type, int len, const double dp[]);
-/*      cdiDefAttTxt: Define a text attribute */
-int     cdiDefAttTxt(int cdiID, int varID, const char *name, int len, const char *tp_cbuf);
-
-/*      cdiInqAttInt: Get the value(s) of an integer attribute */
-int     cdiInqAttInt(int cdiID, int varID, const char *name, int mlen, int ip[]);
-/*      cdiInqAttFlt: Get the value(s) of a floating point attribute */
-int     cdiInqAttFlt(int cdiID, int varID, const char *name, int mlen, double dp[]);
-/*      cdiInqAttTxt: Get the value(s) of a text attribute */
-int     cdiInqAttTxt(int cdiID, int varID, const char *name, int mlen, char *tp_cbuf);
+/*      vlistInqAttInt: Get the value(s) of an integer attribute */
+int     vlistInqAttInt(int vlistID, int varID, const char *name, int mlen, int ip[]);
+/*      vlistInqAttFlt: Get the value(s) of a floating point attribute */
+int     vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double dp[]);
+/*      vlistInqAttTxt: Get the value(s) of a text attribute */
+int     vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp_cbuf);
 
 
 /* GRID routines */
@@ -884,7 +851,7 @@ int     gridInqMaskGME(int gridID, int mask[]);
 void    gridDefMask(int gridID, const int mask[]);
 int     gridInqMask(int gridID, int mask[]);
 
-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);
@@ -895,15 +862,6 @@ void    gridDestroy(int gridID);
 /*      gridDuplicate: Duplicate a Grid */
 int     gridDuplicate(int gridID);
 
-/*      gridDefProj: Define the projection ID of a Grid */
-void    gridDefProj(int gridID, int projID);
-
-/*      gridInqProj: Get the projection ID of a Grid */
-int     gridInqProj(int gridID);
-
-/*      gridInqProjType: Get the projection type */
-int     gridInqProjType(int gridID);
-
 /*      gridInqType: Get the type of a Grid */
 int     gridInqType(int gridID);
 
@@ -934,57 +892,28 @@ void    gridDefXvals(int gridID, const double xvals[]);
 /*      gridInqXvals: Get all values of a X-axis */
 int     gridInqXvals(int gridID, double xvals[]);
 
-/*      gridInqXIsc: Find out whether X-coordinate is of type CHAR */
-int     gridInqXIsc(int gridID);
-
-/*      gridInqXCvals: Get strings from X-axis in case grid is of type GRID_CHARXY */
-int     gridInqXCvals(int gridID, char *xcvals[]);
-
 /*      gridDefYvals: Define the values of a Y-axis */
 void    gridDefYvals(int gridID, const double yvals[]);
 
 /*      gridInqYvals: Get all values of a Y-axis */
 int     gridInqYvals(int gridID, double yvals[]);
 
-/*      gridInqYIsc: Find out whether Y-coordinate is of type CHAR */
-int     gridInqYIsc(int gridID);
-
-/*      gridInqYCvals: Get strings from Y-axis in case grid is of type GRID_CHARXY */
-int     gridInqYCvals(int gridID, char *ycvals[]);
-
 /* CDI grid string key values */
-#define  CDI_KEY_XNAME       901  // X-axis name
-#define  CDI_KEY_XDIMNAME    902  // X-axis dimension name
-#define  CDI_KEY_XLONGNAME   903  // X-axis longname
-#define  CDI_KEY_XUNITS      904  // X-axis units
-#define  CDI_KEY_YNAME       911  // Y-axis name
-#define  CDI_KEY_YDIMNAME    912  // Y-axis dimension name
-#define  CDI_KEY_YLONGNAME   913  // Y-axis longname
-#define  CDI_KEY_YUNITS      914  // Y-axis units
-#define  CDI_KEY_VDIMNAME    920  // Vertex dimension name
-#define  CDI_KEY_MAPPING     921  // Grid mapping var name
-#define  CDI_KEY_MAPNAME     922  // Grid mapping name
-
-/* CDI zaxis string key values */
-#define  CDI_KEY_NAME        941  // Z-axis name
-#define  CDI_KEY_DIMNAME     942  // Z-axis dimension name
-#define  CDI_KEY_LONGNAME    943  // Z-axis longname
-#define  CDI_KEY_UNITS       944  // Z-axis units
-#define  CDI_KEY_PSNAME      950  // Z-axis surface pressure name
-#define  CDI_KEY_P0NAME      951  // Z-axis reference pressure name
-#define  CDI_KEY_P0VALUE     952  // Z-axis reference pressure in Pa
-
-//      cdiGridDefKeyStr: Define a CDI grid string value from a key
-int     cdiGridDefKeyStr(int gridID, int key, int size, const char *mesg);
-
-//      cdiGridInqKeyStr: Get a CDI grid string value from a key
-int     cdiGridInqKeyStr(int gridID, int key, int size, char *mesg);
-
-//      cdiZaxisDefKeyFlt: Define a CDI Z-axis floating point value from a key
-int     cdiZaxisDefKeyFlt(int zaxisID, int key, double value);
-
-//      cdiZaxisInqKeyFlt: Get a CDI Z-axis floating point value from a key
-int     cdiZaxisInqKeyFlt(int zaxisID, int key, double *value);
+#define  CDI_GRID_XNAME      901  // X-axis name
+#define  CDI_GRID_YNAME      902  // Y-axis name
+#define  CDI_GRID_XDIMNAME   903  // X-axis dimension name
+#define  CDI_GRID_YDIMNAME   904  // Y-axis dimension name
+#define  CDI_GRID_VDIMNAME   905  // Vertex dimension name
+#define  CDI_GRID_XLONGNAME  906  // X-axis longname
+#define  CDI_GRID_YLONGNAME  907  // Y-axis longname
+#define  CDI_GRID_XUNITS     908  // X-axis units
+#define  CDI_GRID_YUNITS     909  // Y-axis units
+
+//      cdiGridDefString: Define a CDI grid string value from a key
+int     cdiGridDefString(int gridID, int key, int size, const char *mesg);
+
+//      cdiGridInqString: Get a CDI grid string value from a key
+int     cdiGridInqString(int gridID, int key, int size, char *mesg);
 
 /*      gridDefXname: Define the name of a X-axis */
 void    gridDefXname(int gridID, const char *xname);
@@ -1044,9 +973,24 @@ double  gridInqXinc(int gridID);
 double  gridInqYinc(int gridID);
 
 int     gridIsCircular(int gridID);
-
+int     gridIsRotated(int gridID);
+void    gridDefXpole(int gridID, double xpole);
+double  gridInqXpole(int gridID);
+void    gridDefYpole(int gridID, double ypole);
+double  gridInqYpole(int gridID);
+void    gridDefAngle(int gridID, double angle);
+double  gridInqAngle(int gridID);
 int     gridInqTrunc(int gridID);
 void    gridDefTrunc(int gridID, int trunc);
+/* Hexagonal GME grid */
+void    gridDefGMEnd(int gridID, int nd);
+int     gridInqGMEnd(int gridID);
+void    gridDefGMEni(int gridID, int ni);
+int     gridInqGMEni(int gridID);
+void    gridDefGMEni2(int gridID, int ni2);
+int     gridInqGMEni2(int gridID);
+void    gridDefGMEni3(int gridID, int ni3);
+int     gridInqGMEni3(int gridID);
 
 /* Reference of an unstructured grid */
 
@@ -1082,17 +1026,18 @@ void    gridInqUUID(int gridID, unsigned char *uuid);
 void    gridInqUUID(int gridID, unsigned char uuid[CDI_UUID_SIZE]);
 #endif
 
-/* Rotated Lon/Lat grid */
-void    gridDefParamRLL(int gridID, double xpole, double ypole, double angle);
-void    gridInqParamRLL(int gridID, double *xpole, double *ypole, double *angle);
+/* Lambert Conformal Conic grid (GRIB version) */
+void gridDefLCC(int gridID, double originLon, double originLat, double lonParY, double lat1, double lat2, double xinc, double yinc, int projflag, int scanflag);
+void gridInqLCC(int gridID, double *originLon, double *originLat, double *lonParY, double *lat1, double *lat2, double *xinc, double *yinc, int *projflag, int *scanflag);
 
-/* Hexagonal GME grid */
-void    gridDefParamGME(int gridID, int nd, int ni, int ni2, int ni3);
-void    gridInqParamGME(int gridID, int *nd, int *ni, int *ni2, int *ni3);
+/* Lambert Conformal Conic 2 grid (PROJ version) */
+void gridDefLcc2(int gridID, double earth_radius, double lon_0, double lat_0, double lat_1, double lat_2);
+void gridInqLcc2(int gridID, double *earth_radius, double *lon_0, double *lat_0, double *lat_1, double *lat_2);
+
+/* Lambert Azimuthal Equal Area grid */
+void gridDefLaea(int gridID, double earth_radius, double lon_0, double lat_0);
+void gridInqLaea(int gridID, double *earth_radius, double *lon_0, double *lat_0);
 
-  /* Lambert Conformal Conic grid (GRIB version) */
-void gridDefParamLCC(int gridID, double missval, double lon_0, double lat_0, double lat_1, double lat_2, double a, double rf, double xval_0, double yval_0, double x_0, double y_0);
-int gridInqParamLCC(int gridID, double missval, double *lon_0, double *lat_0, double *lat_1, double *lat_2, double *a, double *rf, double *xval_0, double *yval_0, double *x_0, double *y_0);
 
 void    gridDefArea(int gridID, const double area[]);
 void    gridInqArea(int gridID, double area[]);
@@ -1123,16 +1068,9 @@ void    gridChangeType(int gridID, int gridtype);
 void    gridDefComplexPacking(int gridID, int lpack);
 int     gridInqComplexPacking(int gridID);
 
-void    gridDefUvRelativeToGrid(int gridID, int uvRelativeToGrid);
-int     gridInqUvRelativeToGrid(int gridID);
-
-void    gridDefScanningMode(int gridID, int mode);
-int     gridInqScanningMode(int gridID);
-
 /* ZAXIS routines */
 
 void    zaxisName(int zaxistype, char *zaxisname);
-const char *zaxisNamePtr(int leveltype);
 
 /*      zaxisCreate: Create a vertical Z-axis */
 int     zaxisCreate(int zaxistype, int size);
@@ -1149,22 +1087,15 @@ int     zaxisInqSize(int zaxisID);
 /*      zaxisDuplicate: Duplicate a Z-axis */
 int     zaxisDuplicate(int zaxisID);
 
-void    zaxisPrint(int zaxisID);
+void    zaxisResize(int zaxisID, int size);
+
+void    zaxisPrint(int zaxisID, int index);
 
 /*      zaxisDefLevels: Define the levels of a Z-axis */
 void    zaxisDefLevels(int zaxisID, const double levels[]);
 
-/*      zaxisDefCvals: Define area types of a Z-axis */
-void    zaxisDefCvals(int zaxisID, const char *cvals[], size_t clength);
-
 /*      zaxisInqLevels: Get all levels of a Z-axis */
-int     zaxisInqLevels(int zaxisID, double levels[]);
-
-/*      zaxisInqCLen: Get maximal string length of character Z-axis */
-int     zaxisInqCLen(int zaxisID);
-
-/*      zaxisInqCVals: Get all string values of a character Z-axis */
-int     zaxisInqCVals(int zaxisID, char ***clevels);
+void    zaxisInqLevels(int zaxisID, double levels[]);
 
 /*      zaxisDefLevel: Define one level of a Z-axis */
 void    zaxisDefLevel(int zaxisID, int levelID, double levels);
@@ -1190,11 +1121,18 @@ void    zaxisDefUUID(int zaxisID, const unsigned char uuid[CDI_UUID_SIZE]);
 /*      zaxisInqUUID: Get the UUID of a generalized Z-axis */
 void    zaxisInqUUID(int zaxisID, unsigned char uuid[CDI_UUID_SIZE]);
 
-//      cdiZaxisDefKeyStr: Define a CDI Z-axis string value from a key
-int     cdiZaxisDefKeyStr(int zaxisID, int key, int size, const char *mesg);
+/* CDI zaxis string key values */
+#define  CDI_ZAXIS_NAME      801  // Z-axis name
+#define  CDI_ZAXIS_DIMNAME   802  // Z-axis dimension name
+#define  CDI_ZAXIS_VDIMNAME  803  // Vertex dimension name
+#define  CDI_ZAXIS_LONGNAME  804  // Z-axis longname
+#define  CDI_ZAXIS_UNITS     805  // Z-axis units
+
+//      cdiZaxisDefString: Define a CDI Z-axis string value from a key
+int     cdiZaxisDefString(int zaxisID, int key, int size, const char *mesg);
 
-//      cdiZaxisInqKeyStr: Get a CDI Z-axis string value from a key
-int     cdiZaxisInqKeyStr(int zaxisID, int key, int size, char *mesg);
+//      cdiZaxisInqString: Get a CDI Z-axis string value from a key
+int     cdiZaxisInqString(int zaxisID, int key, int size, char *mesg);
 
 /*      zaxisDefName: Define the name of a Z-axis */
 void    zaxisDefName(int zaxisID, const char *name_optional);
@@ -1217,6 +1155,12 @@ void    zaxisInqUnits(int zaxisID, char *units);
 /*      zaxisInqStdname: Get the standard name of a Z-axis */
 void    zaxisInqStdname(int zaxisID, char *stdname);
 
+/*      zaxisDefPsName: Define the name of the surface pressure variable of a hybrid sigma pressure Z-axis */
+void    zaxisDefPsName(int zaxisID, const char *psname_optional);
+
+/*      zaxisInqPsName: Get the name of the surface pressure variable of a hybrid sigma pressure Z-axis */
+void    zaxisInqPsName(int zaxisID, char *psname);
+
 void    zaxisDefPrec(int zaxisID, int prec);
 int     zaxisInqPrec(int zaxisID);
 
@@ -1229,6 +1173,7 @@ int     zaxisInqScalar(int zaxisID);
 void    zaxisDefLtype(int zaxisID, int ltype);
 int     zaxisInqLtype(int zaxisID);
 
+const double *zaxisInqLevelsPtr(int zaxisID);
 void    zaxisDefVct(int zaxisID, int size, const double vct[]);
 void    zaxisInqVct(int zaxisID, double vct[]);
 int     zaxisInqVctSize(int zaxisID);
@@ -1445,8 +1390,6 @@ void gribapiLibraryVersion(int *major_version, int *minor_version, int *revision
 #ifndef _BASETIME_H
 #define _BASETIME_H
 
-#include <stdbool.h>
-
 //#define USE_TIMECACHE 1
 #define MAX_TIMECACHE_SIZE 1024
 
@@ -1463,7 +1406,7 @@ typedef struct {
   int   ncdimid;
   int   ncvarboundsid;
   int   leadtimeid;
-  bool  lwrf;     /* true for time axis in WRF format */
+  int   lwrf;     /* TRUE for time axis in WRF format */
   timecache_t *timevar_cache;
 }
 basetime_t;
@@ -1484,20 +1427,21 @@ void basetimeInit(basetime_t *basetime);
 #endif
 
 #include <stdio.h>
-#include <stdbool.h>
 
 
+#undef  UNDEFID
+#define UNDEFID  CDI_UNDEFID
 
 void basetimeInit(basetime_t *basetime)
 {
   if ( basetime == NULL )
     Error("Internal problem! Basetime not allocated.");
 
-  basetime->ncvarid       = CDI_UNDEFID;
-  basetime->ncdimid       = CDI_UNDEFID;
-  basetime->ncvarboundsid = CDI_UNDEFID;
-  basetime->leadtimeid    = CDI_UNDEFID;
-  basetime->lwrf          = false;
+  basetime->ncvarid       = UNDEFID;
+  basetime->ncdimid       = UNDEFID;
+  basetime->ncvarboundsid = UNDEFID;
+  basetime->leadtimeid    = UNDEFID;
+  basetime->lwrf          = 0;
   basetime->timevar_cache = NULL;
 }
 /*
@@ -1638,8 +1582,8 @@ void swap8byte(void *ptr, size_t size);
  * require-trailing-newline: t
  * End:
  */
-#ifndef BINARY_H
-#define BINARY_H
+#ifndef _BINARY_H
+#define _BINARY_H
 
 #ifdef HAVE_CONFIG_H
 #endif
@@ -1679,7 +1623,7 @@ int binReadFlt64(int fileID, int byteswap, size_t size, FLT64 *ptr);
 int binWriteFlt32(int fileID, int byteswap, size_t size, FLT32 *ptr);
 int binWriteFlt64(int fileID, int byteswap, size_t size, FLT64 *ptr);
 
-#endif  /* BINARY_H */
+#endif  /* _BINARY_H */
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -2037,9 +1981,9 @@ void decode_juldaysec(int calendar, int julday, int secofday, int *year, int *mo
 
 
 
-static const int month_360[12] = {30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30};
-static const int month_365[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-static const int month_366[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+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};
 
 
 int calendar_dpy(int calendar)
@@ -2056,9 +2000,9 @@ int calendar_dpy(int calendar)
 
 int days_per_month(int calendar, int year, int month)
 {
+  int *dpm = NULL;
   int daysperyear = calendar_dpy(calendar);
 
-  const int *dpm;
   if      ( daysperyear == 360 ) dpm = month_360;
   else if ( daysperyear == 365 ) dpm = month_365;
   else                           dpm = month_366;
@@ -2103,11 +2047,11 @@ int days_per_year(int calendar, int year)
 static void decode_day(int dpy, int days, int *year, int *month, int *day)
 {
   int i = 0;
+  int *dpm = NULL;
 
   *year = (days-1) / dpy;
   days -= (*year*dpy);
 
-  const int *dpm = NULL;
   if      ( dpy == 360 ) dpm = month_360;
   else if ( dpy == 365 ) dpm = month_365;
   else if ( dpy == 366 ) dpm = month_366;
@@ -2126,9 +2070,9 @@ static void decode_day(int dpy, int days, int *year, int *month, int *day)
 
 static int encode_day(int dpy, int year, int month, int day)
 {
+  int *dpm = NULL;
   long rval = (long)dpy * year + day;
 
-  const int *dpm = NULL;
   if      ( dpy == 360 ) dpm = month_360;
   else if ( dpy == 365 ) dpm = month_365;
   else if ( dpy == 366 ) dpm = month_366;
@@ -2466,7 +2410,6 @@ enum reshListMismatch {
 
 int reshListCompare(int nsp0, int nsp1);
 void reshListPrint(FILE *fp);
-int reshGetTxCode(cdiResH resH);
 
 #endif
 /*
@@ -2481,8 +2424,6 @@ int reshGetTxCode(cdiResH resH);
 #ifndef _TAXIS_H
 #define _TAXIS_H
 
-#include <stdbool.h>
-
 #ifndef RESOURCE_HANDLE_H
 #endif
 
@@ -2490,9 +2431,8 @@ typedef struct {
   /* Date format  YYYYMMDD */
   /* Time format    hhmmss */
   int     self;
-  bool    used;
+  short   used;
   short   has_bounds;
-  int     datatype;       // datatype
   int     type;           // time type
   int     vdate;          // verification date
   int     vtime;          // verification time
@@ -2503,16 +2443,15 @@ typedef struct {
   int     calendar;
   int     unit;           // time unit
   int     numavg;
-  bool    climatology;
+  int     climatology;
   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;
-  char   *units;
+  char*   name;
+  char*   longname;
 }
 taxis_t;
 
@@ -2525,10 +2464,8 @@ 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    ptaxisDefDatatype(taxis_t *taxisptr, int datatype);
 void    ptaxisDefName(taxis_t *taxisptr, const char *name);
-void    ptaxisDefLongname(taxis_t *taxisptr, const char *longname);
-void    ptaxisDefUnits(taxis_t *taxisptr, const char *units);
+void    ptaxisDefLongname(taxis_t *taxisptr, const char *name);
 void    taxisDestroyKernel(taxis_t *taxisptr);
 #if !defined (SX)
 extern const resOps taxisOps;
@@ -2680,6 +2617,7 @@ int  extDefDataDP(void *ext, const double *data);
 #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]
@@ -2806,7 +2744,7 @@ char *strdup(const char *s);
 #endif
 
 
-#ifndef  ERROR_H
+#ifndef  _ERROR_H
 #endif
 #ifndef _BASETIME_H
 #endif
@@ -2908,17 +2846,9 @@ typedef struct
   int       ilevel2;
   int       ltype;
   short     tsteptype;
-#ifdef HIRLAM_EXTENSIONS
-    // NOTE: tsteptype MUST be part of attributes used to compare variables!
-    // Modern NWP models (HARMONIE, HIRLAM) use timeRangeIndicator to specify
-    // if the field is instantanous or accumulated.
-    // Both types are typically in the same GRIB-file.
-    // (181; 105, 0, timeRangeIndicator=0) .. instantanous rain
-    // (181; 105, 0, timeRangeIndicator=4) .. accumulated rain  .. both can be in the same grib file
-#endif // HIRLAM_EXTENSIONS
+  short     used;
   short     varID;
   short     levelID;
-  short     used;
   char      varname[32]; /* needed for grib decoding with GRIB_API */
   var_tile_t tiles;      /* tile-related meta-data, currently for GRIB-API only. */
 }
@@ -2934,7 +2864,7 @@ typedef struct {
                          /* tsID>0 number of non constant records */
   int       nallrecs;    /* number of all records                 */
   int       curRecID;    /* current record ID                     */
-  bool      next;
+  long      next;
   off_t     position;    /* timestep file position                */
   taxis_t   taxis;
 }
@@ -2952,14 +2882,14 @@ typedef struct {
 typedef struct {
   int            ncvarid;
   int            subtypeSize;
-  sleveltable_t *recordTable; // record IDs for each subtype
-  bool           defmiss;     // true: if missval is defined in file
-  bool           isUsed;
+  sleveltable_t *recordTable; /* record IDs for each subtype */
+  int            defmiss;     /* TRUE if missval is defined in file */
 
+  int            isUsed;
   int            gridID;
   int            zaxisID;
-  int            tsteptype;   // TSTEP_*
-  int            subtypeID;   // subtype ID, e.g. for tile-related meta-data (currently for GRIB-API only).
+  int            tsteptype;   /* TSTEP_* */
+  int            subtypeID;   /* subtype ID, e.g. for tile-related meta-data (currently for GRIB-API only). */
 }
 svarinfo_t;
 
@@ -2972,21 +2902,6 @@ typedef struct {
 }
 VCT;
 
-#ifdef HAVE_LIBNETCDF
-enum {
-  CDF_DIMID_X,
-  CDF_DIMID_Y,
-  CDF_VARID_X,
-  CDF_VARID_Y,
-  CDF_VARID_A,
-  CDF_SIZE_ncIDs,
-};
-typedef struct {
-  int gridID;
-  int ncIDs[CDF_SIZE_ncIDs];
-}
-ncgrid_t;
-#endif
 
 typedef struct {
   int         self;
@@ -3012,21 +2927,22 @@ typedef struct {
   basetime_t  basetime;
   int         ncmode;
   int         vlistID;
-#ifdef HAVE_LIBNETCDF
-  ncgrid_t    ncgrid[MAX_GRIDS_PS];
+  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         nczvarID[MAX_ZAXES_PS];
-  VCT         vct;
-#endif
+  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
-  bool        sortname;
-  bool        sortparam;
 #if defined (GRIBCONTAINER2D)
   void      **gribContainers;
 #else
@@ -3053,7 +2969,7 @@ typedef enum {
 typedef struct
 {
   char*                  keyword;        /* keyword string */
-  bool                   update;
+  int                    update;
   key_val_pair_datatype  data_type;      /* data type of this key/value pair */
   double                 dbl_val;        /* double value (data_type == t_double) */
   int                    int_val;        /* integer value (data_type == t_int) */
@@ -3068,10 +2984,8 @@ typedef enum {
 } CdiTimeType;
 
 
-#define  CDI_FILETYPE_UNDEF          -1   /* Unknown/not yet defined file type */
 
 
-extern int cdiDebugExt;
 extern int CDI_Debug;      /* If set to 1, debuggig (default 0)            */
 extern int CDI_Recopt;
 extern int cdiGribApiDebug;
@@ -3087,11 +3001,9 @@ extern int cdiChunkType;
 extern int cdiSplitLtype105;
 extern int cdiDataUnreduced;
 extern int cdiSortName;
-extern int cdiSortParam;
 extern int cdiHaveMissval;
-extern bool cdiIgnoreAttCoordinates;
-extern bool cdiCoordinatesLonLat;
-extern bool cdiIgnoreValidRange;
+extern int cdiIgnoreAttCoordinates;
+extern int cdiIgnoreValidRange;
 extern int cdiSkipRecords;
 extern int cdiConvention;
 extern int cdiInventoryMode;
@@ -3123,6 +3035,8 @@ int     streamInqFileID(int streamID);
 
 void    gridDefHasDims(int gridID, int hasdims);
 int     gridInqHasDims(int gridID);
+const char *gridNamePtr(int gridtype);
+const char   *zaxisNamePtr(int leveltype);
 int     zaxisInqLevelID(int zaxisID, double level);
 
 void    streamCheckID(const char *caller, int streamID);
@@ -3146,8 +3060,6 @@ void    vlist_check_contents(int vlistID);
 
 void    cdi_create_records(stream_t *streamptr, int tsID);
 
-void streamFCopyRecord(stream_t *streamptr2, stream_t *streamptr1, const char *container_name);
-
 int     recordNewEntry(stream_t *streamptr, int tsID);
 
 void    cdiCreateTimesteps(stream_t *streamptr);
@@ -3156,6 +3068,8 @@ void    recordInitEntry(record_t *record);
 
 void    cdiCheckZaxis(int zaxisID);
 
+void    cdiPrintDatatypes(void);
+
 void    cdiDefAccesstype(int streamID, int type);
 int     cdiInqAccesstype(int streamID);
 
@@ -3327,7 +3241,6 @@ void cdf_put_att_double(int ncid, int varid, const char *name, nc_type xtype, si
 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_long  (int ncid, int varid, const char *name, long *ip);
 void cdf_get_att_double(int ncid, int varid, const char *name, double *dp);
 
 void cdf_inq_att    (int ncid, int varid, const char *name, nc_type * xtypep, size_t * lenp);
@@ -3336,8 +3249,6 @@ 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);
 
-void cdf_def_var_chunking(int ncid, int varid, int storage, const size_t *chunksizesp);
-
 typedef int (*cdi_nc__create_funcp)(const char *path, int cmode,
                                     size_t initialsz, size_t *chunksizehintp,
                                     int *ncidp);
@@ -3469,22 +3380,22 @@ static int cdfOpenFile(const char *filename, const char *mode, int *filetype)
 	      (void) nc_inq_format(ncid, &format);
 	      if ( format == NC_FORMAT_NETCDF4_CLASSIC )
 		{
-		  *filetype = CDI_FILETYPE_NC4C;
+		  *filetype = FILETYPE_NC4C;
 		}
 	    }
 #endif
 	  break;
 	case 'w':
 #if  defined  (NC_64BIT_OFFSET)
-	  if      ( *filetype == CDI_FILETYPE_NC2  ) writemode |= NC_64BIT_OFFSET;
+	  if      ( *filetype == FILETYPE_NC2  ) writemode |= NC_64BIT_OFFSET;
 #endif
 #if  defined  (HAVE_NETCDF4)
-	  if      ( *filetype == CDI_FILETYPE_NC4  ) writemode |= NC_NETCDF4;
-	  else if ( *filetype == CDI_FILETYPE_NC4C ) writemode |= NC_NETCDF4 | NC_CLASSIC_MODEL;
+	  if      ( *filetype == FILETYPE_NC4  ) writemode |= NC_NETCDF4;
+	  else if ( *filetype == FILETYPE_NC4C ) writemode |= NC_NETCDF4 | NC_CLASSIC_MODEL;
 #endif
 	  cdf_create(filename, writemode, &ncid);
 	  if ( CDI_Version_Info ) cdfComment(ncid);
-          cdf_put_att_text(ncid, NC_GLOBAL, "Conventions", 6, "CF-1.6");
+          cdf_put_att_text(ncid, NC_GLOBAL, "Conventions", 6, "CF-1.4");
 	  break;
 	case 'a':
 	  cdf_open(filename, NC_WRITE, &ncid);
@@ -3501,7 +3412,7 @@ static int cdfOpenFile(const char *filename, const char *mode, int *filetype)
 
 int cdfOpen(const char *filename, const char *mode)
 {
-  int filetype = CDI_FILETYPE_NC;
+  int filetype = FILETYPE_NC;
 
   if ( CDF_Debug )
     Message("Open %s with mode %c", filename, *mode);
@@ -3518,15 +3429,15 @@ int cdfOpen(const char *filename, const char *mode)
 int cdfOpen64(const char *filename, const char *mode)
 {
   int fileID = -1;
-  int filetype = CDI_FILETYPE_NC2;
-  bool open_file = true;
+  int open_file = TRUE;
+  int filetype = FILETYPE_NC2;
 
   if ( CDF_Debug )
     Message("Open %s with mode %c", filename, *mode);
 
 #if  defined  (HAVE_LIBNETCDF)
 #if  ! defined  (NC_64BIT_OFFSET)
-  open_file = false;
+  open_file = FALSE;
 #endif
 #endif
 
@@ -3549,13 +3460,13 @@ int cdfOpen64(const char *filename, const char *mode)
 int cdf4Open(const char *filename, const char *mode, int *filetype)
 {
   int fileID = -1;
-  bool open_file = false;
+  int open_file = FALSE;
 
   if ( CDF_Debug )
     Message("Open %s with mode %c", filename, *mode);
 
 #if  defined  (HAVE_NETCDF4)
-  open_file = true;
+  open_file = TRUE;
 #endif
 
   if ( open_file )
@@ -3743,12 +3654,12 @@ void cdf_create(const char *path, int cmode, int *ncidp)
 int cdf_open(const char *path, int omode, int *ncidp)
 {
   int status = 0;
-  bool dapfile = false;
+  int dapfile = FALSE;
   struct stat filestat;
   size_t chunksizehint = 0;
 
 #if  defined  (HAVE_LIBNC_DAP)
-  if ( strncmp(path, "http:", 5) == 0 || strncmp(path, "https:", 6) == 0 ) dapfile = true;
+  if ( strncmp(path, "http:", 5) == 0 || strncmp(path, "https:", 6) == 0 ) dapfile = TRUE;
 #endif
 
   if ( dapfile )
@@ -4357,19 +4268,6 @@ void cdf_get_att_int(int ncid, int varid, const char *name, int *ip)
 }
 
 
-void cdf_get_att_long(int ncid, int varid, const char *name, long *ip)
-{
-#if  defined  (HAVE_NETCDF4)
-  int status = nc_get_att_long(ncid, varid, name, ip);
-
-  if ( CDF_Debug || status != NC_NOERR )
-    Message("ncid = %d varid = %d att = %s val = %ld", ncid, varid, name, *ip);
-
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
-#endif
-}
-
-
 void cdf_get_att_double(int ncid, int varid, const char *name, double *dp)
 {
   int status;
@@ -4438,16 +4336,224 @@ void cdf_inq_attid(int ncid, int varid, const char *name, int *attnump)
   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:
+ */
+#ifndef CDI_CKSUM_H_
+#define CDI_CKSUM_H_
+
+#include <inttypes.h>
 
-#if  defined  (HAVE_NETCDF4)
-void cdf_def_var_chunking(int ncid, int varid, int storage, const size_t *chunksizesp)
+uint32_t cdiCheckSum(int type, int count, const void *data);
+
+#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
+
+#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);
+
+/*
+ * 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
+
+#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)
 {
-  int status = nc_def_var_chunking(ncid, varid, storage, chunksizesp);
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  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;
 }
+
+static inline void
+serializeStrTabPack(const char **strTab, int numStr,
+                    void *buf, int buf_size, int *position, void *context)
+{
+  uint32_t d = 0;
+  xassert(numStr >= 0);
+  for (size_t i = 0; i < (size_t)numStr; ++i)
+  {
+    int len = (int)strlen(strTab[i]);
+    serializePack(&len, 1, DATATYPE_INT,
+                  buf, buf_size, position, context);
+    serializePack(strTab[i], len, DATATYPE_TXT,
+                  buf, buf_size, position, context);
+    d ^= cdiCheckSum(DATATYPE_TXT, len, strTab[i]);
+  }
+  serializePack(&d, 1, DATATYPE_UINT32,
+                buf, buf_size, position, context);
+}
+
+static inline void
+serializeStrTabUnpack(const void *buf, int buf_size, int *position,
+                      char **strTab, int numStr, void *context)
+{
+  uint32_t d, d2 = 0;
+  xassert(numStr >= 0);
+  for (size_t i = 0; i < (size_t)numStr; ++i)
+    {
+      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, len, strTab[i]);
+    }
+  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
+
+#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;
+}
+
+/*
+ * 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 <errno.h>
+
+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";
+
+  switch (cdiErrno) {
+  case CDI_ESYSTEM:
+    {
+      const char *cp = 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:
  * c-file-style: "Java"
@@ -4512,368 +4618,134 @@ extern void    memFree   (void *ptr, const char *file, const char *functionname,
  * require-trailing-newline: t
  * End:
  */
-#ifndef  CDF_UTIL_H_
-#define  CDF_UTIL_H_
-
-#include <stdbool.h>
-
-void str_tolower(char *str);
-bool str_is_equal(const char *vstr, const char *cstr);
-
-int get_timeunit(size_t len, const char *ptu);
-
-bool is_time_units(const char *timeunits);
-bool is_timeaxis_units(const char *timeunits);
-
-bool is_height_units(const char *units);
-bool is_pressure_units(const char *units);
-bool is_DBL_axis(/*const char *units,*/ const char *longname);
-bool is_depth_axis(const char *stdname, const char *longname);
-bool is_height_axis(const char *stdname, const char *longname);
-
-bool is_lon_axis(const char *units, const char *stdname);
-bool is_lat_axis(const char *units, const char *stdname);
-
-bool is_x_axis(const char *units, const char *stdname);
-bool is_y_axis(const char *units, const char *stdname);
-
-void set_gridtype(const char *attstring, int *gridtype);
-void set_zaxistype(const char *attstring, int *zaxistype);
-void set_calendar(const char *attstring, int *calendar);
+#ifndef _GRIBAPI_H
+#define _GRIBAPI_H
 
+#ifdef HAVE_LIBGRIB_API
+#include <grib_api.h>
+#ifndef  _ERROR_H
+#endif
 #endif
-#include <string.h>
-#include <ctype.h>
-
-
-void str_tolower(char *str)
-{
-  if ( str )
-    for ( size_t i = 0; str[i]; ++i )
-      str[i] = (char)tolower((int)str[i]);
-}
-
-bool str_is_equal(const char *vstr, const char *cstr)
-{
-  bool is_equal = false;
-  size_t clen = (cstr != NULL) ? strlen(cstr) : 0;
-
-  if ( vstr && *vstr ) is_equal = (memcmp(vstr, cstr, clen) == 0);
-
-  return is_equal;
-}
-
-int get_timeunit(size_t len, const char *ptu)
-{
-  int timeunit = -1;
-
-  if ( len > 2 )
-    {
-      if      ( str_is_equal(ptu, "sec") )            timeunit = TUNIT_SECOND;
-      else if ( str_is_equal(ptu, "minute") )         timeunit = TUNIT_MINUTE;
-      else if ( str_is_equal(ptu, "hour") )           timeunit = TUNIT_HOUR;
-      else if ( str_is_equal(ptu, "day") )            timeunit = TUNIT_DAY;
-      else if ( str_is_equal(ptu, "month") )          timeunit = TUNIT_MONTH;
-      else if ( str_is_equal(ptu, "calendar_month") ) timeunit = TUNIT_MONTH;
-      else if ( str_is_equal(ptu, "year") )           timeunit = TUNIT_YEAR;
-    }
-  else if ( len == 1 && ptu[0] == 's' )
-    timeunit = TUNIT_SECOND;
-
-  return timeunit;
-}
-
-
-bool is_time_units(const char *timeunits)
-{
-  bool status = str_is_equal(timeunits, "sec")
-             || str_is_equal(timeunits, "minute")
-             || str_is_equal(timeunits, "hour")
-             || str_is_equal(timeunits, "day")
-             || str_is_equal(timeunits, "month")
-             || str_is_equal(timeunits, "calendar_month")
-             || str_is_equal(timeunits, "year");
-
-  return status;
-}
-
-
-bool is_timeaxis_units(const char *timeunits)
-{
-  bool status = false;
-
-  size_t len = strlen(timeunits);
-  char *tu = (char *) Malloc((len+1)*sizeof(char));
-  memcpy(tu, timeunits, (len+1) * sizeof(char));
-  char *ptu = tu;
-
-  for ( size_t i = 0; i < len; i++ ) ptu[i] = (char)tolower((int)ptu[i]);
-
-  int timeunit = get_timeunit(len, ptu);
-  if ( timeunit != -1 )
-    {
-      while ( ! isspace(*ptu) && *ptu != 0 ) ptu++;
-      if ( *ptu )
-        {
-          while ( isspace(*ptu) ) ptu++;
-
-          int timetype = str_is_equal(ptu, "as") ? TAXIS_ABSOLUTE :
-                         str_is_equal(ptu, "since") ? TAXIS_RELATIVE : -1;
-
-          status = timetype != -1;
-        }
-    }
-
-  Free(tu);
-
-  return status;
-}
-
-
-bool is_height_units(const char *units)
-{
-  int u0 = units[0];
-
-  bool status
-    = (u0=='m' && (!units[1] || strncmp(units, "meter", 5) == 0))
-    || (!units[2] && units[1]=='m' && (u0=='c' || u0=='d' || u0=='k'));
-
-  return status;
-}
-
-
-bool is_pressure_units(const char *units)
-{
-  bool status = false;
-
-  if ( strncmp(units, "millibar", 8) == 0 ||
-       strncmp(units, "mb", 2)       == 0 ||
-       strncmp(units, "hectopas", 8) == 0 ||
-       strncmp(units, "hPa", 3)      == 0 ||
-       strncmp(units, "Pa", 2)       == 0 )
-    {
-      status = true;
-    }
-
-  return status;
-}
 
+#ifndef  _CDI_INT_H
+#endif
 
-bool is_DBL_axis(/*const char *units,*/ const char *longname)
-{
-  bool status = false;
+#define  GRIBAPI_MISSVAL  -9.E33
 
-  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;
-    }
+/* 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                                          */
 
-  return status;
-}
+/* 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                            */
 
+const char *gribapiLibraryVersionString(void);
+void gribContainersNew(stream_t * streamptr);
+void gribContainersDelete(stream_t * streamptr);
 
-bool is_depth_axis(const char *stdname, const char *longname)
+#ifdef HAVE_LIBGRIB_API
+static inline void *gribHandleNew(int editionNumber)
 {
-  bool status = false;
+  void *gh = (void *)grib_handle_new_from_samples(NULL, (editionNumber == 1) ? "GRIB1" : "GRIB2");
 
-  if ( strcmp(stdname, "depth") == 0 )
-    status = true;
-  else
-    if ( strcmp(longname, "depth_below_sea") == 0 ||
-         strcmp(longname, "depth below sea") == 0 )
-      {
-        status = true;
-      }
+  if ( gh == NULL ) Error("grib_handle_new_from_samples failed!");
 
-  return status;
+  return gh;
 }
 
-
-bool is_height_axis(const char *stdname, const char *longname)
+static inline int my_grib_set_double(grib_handle* h, const char* key, double val)
 {
-  bool status = false;
-
-  if ( strcmp(stdname, "height") == 0 )
-    status = true;
-  else
-    if ( strcmp(longname, "height") == 0 ||
-         strcmp(longname, "height above the surface") == 0 )
-      {
-        status = true;
-      }
+  if ( cdiGribApiDebug )
+    fprintf(stderr, "grib_set_double(\tgrib_handle* h, \"%s\", %f)\n", key, val);
 
-  return status;
+  int ret_val = grib_set_double(h, key, val);
+  if (ret_val != 0)
+    fprintf(stderr, "!!! failed call to grib_set_double(\tgrib_handle* h, \"%s\", %f) !!!\n", key, val);
+  return ret_val;
 }
 
-
-bool is_lon_axis(const char *units, const char *stdname)
+static inline int my_grib_set_long(grib_handle* h, const char* key, long val)
 {
-  bool status = false;
-  char lc_units[16];
-
-  memcpy(lc_units, units, 15);
-  lc_units[15] = 0;
-  str_tolower(lc_units);
-
-  if ( (str_is_equal(lc_units, "degree") || str_is_equal(lc_units, "radian")) &&
-       (str_is_equal(stdname, "grid_longitude") || str_is_equal(stdname, "longitude")) )
-    {
-      status = true;
-    }
-  else if ( str_is_equal(lc_units, "degree")
-            && !str_is_equal(stdname, "grid_latitude")
-            && !str_is_equal(stdname, "latitude") )
-    {
-      int ioff = 6;
-      if ( lc_units[ioff] == 's' ) ioff++;
-      if ( lc_units[ioff] == '_' ) ioff++;
-      if ( lc_units[ioff] == 'e' ) status = true;
-    }
+  if ( cdiGribApiDebug )
+    fprintf(stderr, "grib_set_long(  \tgrib_handle* h, \"%s\", %ld)\n", key, val);
 
-  return status;
+  int ret_val = grib_set_long(h, key, val);
+  if (ret_val != 0)
+    fprintf(stderr, "!!! failed call to grib_set_long(  \tgrib_handle* h, \"%s\", %ld) !!!\n", key, val);
+  return ret_val;
 }
 
-
-bool is_lat_axis(const char *units, const char *stdname)
+static inline int my_grib_set_string(grib_handle* h, const char* key, const char* val, size_t* length)
 {
-  bool status = false;
-  char lc_units[16];
-
-  memcpy(lc_units, units, 15);
-  lc_units[15] = 0;
-  str_tolower(lc_units);
-
-  if ( (str_is_equal(lc_units, "degree") || str_is_equal(lc_units, "radian")) &&
-        (str_is_equal(stdname, "grid_latitude") || str_is_equal(stdname, "latitude")) )
-    {
-      status = true;
-    }
-  else if ( str_is_equal(lc_units, "degree")
-            && !str_is_equal(stdname, "grid_longitude")
-            && !str_is_equal(stdname, "longitude") )
-    {
-      int ioff = 6;
-      if ( lc_units[ioff] == 's' ) ioff++;
-      if ( lc_units[ioff] == '_' ) ioff++;
-      if ( lc_units[ioff] == 'n' || lc_units[ioff] == 's' ) status = true;
-    }
-
-  return status;
-}
-
+  if ( cdiGribApiDebug )
+    fprintf(stderr, "grib_set_string(\tgrib_handle* h, \"%s\", \"%s\")\n", key, val);
 
-bool is_x_axis(const char *units, const char *stdname)
-{
-  (void)units;
-  return (strcmp(stdname, "projection_x_coordinate") == 0);
+  int ret_val = grib_set_string(h, key, val, length);
+  if (ret_val != 0)
+    fprintf(stderr, "!!! grib_set_string(\tgrib_handle* h, \"%s\", \"%s\") !!!\n", key, val);
+  return ret_val;
 }
 
-
-bool is_y_axis(const char *units, const char *stdname)
+static inline void gribHandleDelete(void *gh)
 {
-  (void)units;
-  return (strcmp(stdname, "projection_y_coordinate") == 0);
+  grib_handle_delete((struct grib_handle *)gh);
 }
+#else
+#define gribHandleNew(editionNumber) (NULL)
+#define gribHandleDelete(gh)
+#endif
 
-
-void set_gridtype(const char *attstring, int *gridtype)
-{
-  if      ( strcmp(attstring, "gaussian reduced") == 0 )
-    *gridtype = GRID_GAUSSIAN_REDUCED;
-  else if ( strcmp(attstring, "gaussian") == 0 )
-    *gridtype = GRID_GAUSSIAN;
-  else if ( strncmp(attstring, "spectral", 8) == 0 )
-    *gridtype = GRID_SPECTRAL;
-  else if ( strncmp(attstring, "fourier", 7) == 0 )
-    *gridtype = GRID_FOURIER;
-  else if ( strcmp(attstring, "trajectory") == 0 )
-    *gridtype = GRID_TRAJECTORY;
-  else if ( strcmp(attstring, "generic") == 0 )
-    *gridtype = GRID_GENERIC;
-  else if ( strcmp(attstring, "cell") == 0 )
-    *gridtype = GRID_UNSTRUCTURED;
-  else if ( strcmp(attstring, "unstructured") == 0 )
-    *gridtype = GRID_UNSTRUCTURED;
-  else if ( strcmp(attstring, "curvilinear") == 0 )
-    *gridtype = GRID_CURVILINEAR;
-  else if ( strcmp(attstring, "characterxy") == 0 )
-    *gridtype = GRID_CHARXY;
-  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 bool warn = true;
-      if ( warn )
-        {
-          warn = false;
-          Warning("NetCDF attribute grid_type='%s' unsupported!", attstring);
-        }
-    }
+typedef struct {
+  int init;
+  void *gribHandle;
 }
+gribContainer_t;
 
-
-void set_zaxistype(const char *attstring, int *zaxistype)
-{
-  if      ( strcmp(attstring, "toa") == 0 ) *zaxistype = ZAXIS_TOA;
-  else if ( strcmp(attstring, "cloudbase") == 0 ) *zaxistype = ZAXIS_CLOUD_BASE;
-  else if ( strcmp(attstring, "cloudtop") == 0 ) *zaxistype = ZAXIS_CLOUD_TOP;
-  else if ( strcmp(attstring, "isotherm0") == 0 ) *zaxistype = ZAXIS_ISOTHERM_ZERO;
-  else if ( strcmp(attstring, "seabottom") == 0 ) *zaxistype = ZAXIS_SEA_BOTTOM;
-  else if ( strcmp(attstring, "lakebottom") == 0 ) *zaxistype = ZAXIS_LAKE_BOTTOM;
-  else if ( strcmp(attstring, "sedimentbottom") == 0 ) *zaxistype = ZAXIS_SEDIMENT_BOTTOM;
-  else if ( strcmp(attstring, "sedimentbottomta") == 0 ) *zaxistype = ZAXIS_SEDIMENT_BOTTOM_TA;
-  else if ( strcmp(attstring, "sedimentbottomtw") == 0 ) *zaxistype = ZAXIS_SEDIMENT_BOTTOM_TW;
-  else if ( strcmp(attstring, "mixlayer") == 0 ) *zaxistype = ZAXIS_MIX_LAYER;
-  else if ( strcmp(attstring, "atmosphere") == 0 ) *zaxistype = ZAXIS_ATMOSPHERE;
-  else
-    {
-      static bool warn = true;
-      if ( warn )
-        {
-          warn = false;
-          Warning("NetCDF attribute level_type='%s' unsupported!", attstring);
-        }
-    }  
-}
-
-
-void set_calendar(const char *attstring, int *calendar)
-{
-  if ( str_is_equal(attstring, "standard") ||
-       str_is_equal(attstring, "gregorian") )
-    *calendar = CALENDAR_STANDARD;
-  else if ( str_is_equal(attstring, "none") )
-    *calendar = CALENDAR_NONE;
-  else if ( str_is_equal(attstring, "proleptic") )
-    *calendar = CALENDAR_PROLEPTIC;
-  else if ( str_is_equal(attstring, "360") )
-    *calendar = CALENDAR_360DAYS;
-  else if ( str_is_equal(attstring, "365") ||
-            str_is_equal(attstring, "noleap") )
-    *calendar = CALENDAR_365DAYS;
-  else if ( str_is_equal(attstring, "366") ||
-            str_is_equal(attstring, "all_leap") )
-    *calendar = CALENDAR_366DAYS;
-  else
-    Warning("calendar >%s< unsupported!", attstring);
-}
+#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);
@@ -4887,8 +4759,6 @@ void   cdfDefRecord(stream_t * streamptr);
 
 void   cdfCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
 
-void   cdfDefineAttributes(int vlistID, int varID, int fileID, int ncvarID);
-
 void   cdf_read_record(stream_t *streamptr, int memtype, void *data, int *nmiss);
 void   cdf_write_record(stream_t *streamptr, int memtype, const void *data, int nmiss);
 
@@ -4904,10 +4774,6 @@ void   cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
 void cdfDefVarDeflate(int ncid, int ncvarid, int deflate_level);
 void cdfDefTime(stream_t* streamptr);
 
-void cdf_scale_add(size_t size, double *data, double addoffset, double scalefactor);
-
-int cdfDefDatatype(int datatype, int filetype);
-
 #endif
 /*
  * Local Variables:
@@ -4918,810 +4784,699 @@ int cdfDefDatatype(int datatype, int filetype);
  * require-trailing-newline: t
  * End:
  */
-#ifndef CDI_ATT_H
-#define CDI_ATT_H
+#ifndef _CGRIBEX_H
+#define _CGRIBEX_H
 
-#ifdef HAVE_CONFIG_H
-#endif
+#include <stdio.h>
+#include <sys/types.h>
 
-#ifndef _CDI_LIMITS_H
-#endif
+#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                                   */
 
 /*
- * CDI attribute
+ *  Macros for the indicator section ( Section 0 )
  */
-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;
-
+#define  ISEC0_GRIB_Len             (isec0[ 0])  /*  Number of octets in the GRIB message              */
+#define  ISEC0_GRIB_Version         (isec0[ 1])  /*  GRIB edition number                               */
 
-typedef struct {
-  size_t     nalloc;		/* number allocated >= nelems */
-  size_t     nelems;		/* length of the array */
-  cdi_att_t  value[MAX_ATTRIBUTES];
-} cdi_atts_t;
 
+/*
+ *  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
 
-int cdiAttsGetSize(void *p, int varID, void *context);
 
-void cdiAttsPack(void *p, int varID, void *buf, int size, int *position, void *context);
+#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    */
 
-void cdiAttsUnpack(int cdiID, int varID, void *buf, int size, int *position, void *context);
+#define  ISEC1_ECMWF_LocalExtension (isec1[36])
+#define  ISEC1_ECMWF_Class          (isec1[37])
 
-#endif
 
 /*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
+ *  Macros for the grid definition section ( Section 2 )
  */
-#ifndef _GRID_H
-#define _GRID_H
-
-#include <stdbool.h>
+#define  ISEC2_GridType             (isec2[ 0])  /* Data representation type */
 
+/* Triangular grids */
 
-extern double grid_missval;
-extern int (*proj_lonlat_to_lcc_func)();
-extern int (*proj_lcc_to_lonlat_func)();
+#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)          */
 
-typedef unsigned char mask_t;
+/* Spherical harmonic coeficients */
 
-typedef struct grid_t grid_t;
+#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                          */
 
-struct gridVirtTable
-{
-  void (*destroy)(grid_t *gridptr);
-  grid_t *(*copy)(grid_t *gridptr);
-  void (*copyScalarFields)(grid_t *gridptrOrig, grid_t *gridptrDup);
-  void (*copyArrayFields)(grid_t *gridptrOrig, grid_t *gridptrDup);
-  void (*defXVals)(grid_t *gridptr, const double *xvals);
-  void (*defYVals)(grid_t *gridptr, const double *yvals);
-  void (*defMask)(grid_t *gridptr, const int *mask);
-  void (*defMaskGME)(grid_t *gridptr, const int *mask);
-  void (*defXBounds)(grid_t *gridptr, const double *xbounds);
-  void (*defYBounds)(grid_t *gridptr, const double *ybounds);
-  void (*defArea)(grid_t *gridptr, const double *area);
-  double (*inqXVal)(grid_t *gridptr, int index);
-  double (*inqYVal)(grid_t *gridptr, int index);
-  int (*inqXVals)(grid_t *gridptr, double *xvals);
-  int (*inqXCvals)(grid_t *gridptr, char **xcvals);
-  int (*inqXIsc)(grid_t *gridptr);
-  int (*inqYVals)(grid_t *gridptr, double *yvals);
-  int (*inqYCvals)(grid_t *gridptr, char **ycvals);
-  int (*inqYIsc)(grid_t *gridptr);
-  const double *(*inqXValsPtr)(grid_t *gridptr);
-  const char **(*inqXCvalsPtr)(grid_t *gridptr);
-  const double *(*inqYValsPtr)(grid_t *gridptr);
-  const char **(*inqYCvalsPtr)(grid_t *gridptr);
-  /* return if for both grids, all xval and all yval are equal */
-  bool (*compareXYFull)(grid_t *gridRef, grid_t *gridTest);
-  /* return if for both grids, x[0], y[0], x[size-1] and y[size-1] are
-   * respectively equal */
-  bool (*compareXYAO)(grid_t *gridRef, grid_t *gridTest);
-  void (*inqArea)(grid_t *gridptr, double *area);
-  const double *(*inqAreaPtr)(grid_t *gridptr);
-  int (*hasArea)(grid_t *gridptr);
-  int (*inqMask)(grid_t *gridptr, int *mask);
-  int (*inqMaskGME)(grid_t *gridptr, int *mask_gme);
-  int (*inqXBounds)(grid_t *gridptr, double *xbounds);
-  int (*inqYBounds)(grid_t *gridptr, double *ybounds);
-  const double *(*inqXBoundsPtr)(grid_t *gridptr);
-  const double *(*inqYBoundsPtr)(grid_t *gridptr);
-};
+/* Gaussian grids */
 
-struct gridaxis_t {
-  char    name[CDI_MAX_NAME];
-  char    longname[CDI_MAX_NAME];
-  char    units[CDI_MAX_NAME];
-  char    dimname[CDI_MAX_NAME];
-  const char *stdname;
-  int     size;                  // number of values
-  short   flag;                  // 0: undefined 1:vals 2:first+inc
-  double  first, last, inc;
-  double *vals;
-  int clength;
-  char  **cvals;
-  double *bounds;
-};
+#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     */
 
-// GME Grid
-struct grid_gme_t {
-  int     nd, ni, ni2, ni3;       /* parameter for GRID_GME         */
-};
+/* 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               */
 
-struct grid_t {
-  char    vdimname[CDI_MAX_NAME];
-  char    mapname[CDI_MAX_NAME];
-  char    mapping[CDI_MAX_NAME];
-  char   *name;
-  int     self;
-  int     size;
-  int     type;                   /* grid type                      */
-  int     prec;                   /* grid precision                 */
-  int     proj;                   /* grid projection                */
-  int     projtype;               /* grid projection type           */
-  mask_t *mask;
-  mask_t *mask_gme;
-  double *area;
-  struct grid_gme_t  gme;
-  int     number, position;       /* parameter for GRID_REFERENCE   */
-  int     trunc;                  /* parameter for GRID_SPECTEAL    */
-  int     nvertex;
-  char   *reference;
-  unsigned char uuid[CDI_UUID_SIZE]; /* uuid for grid reference        */
-  int    *rowlon;
-  int     nrowlon;
-  int     np;                     /* number of parallels between a pole and the equator */
-  signed char isCyclic;           /* three possible states:
-                                   * -1 if unknown,
-                                   * 0 if found not cyclic, or
-                                   * 1 for global cyclic grids
-                                   */
-  bool    lcomplex;
-  bool    hasdims;
-  bool uvRelativeToGrid;  /* Some models deliver wind U,V relative to the grid-cell */
-  struct gridaxis_t x;
-  struct gridaxis_t y;
-  const struct gridVirtTable *vtable;
-  cdi_atts_t atts;
-  int  scanningMode;
-  bool iScansNegatively, jScansPositively, jPointsAreConsecutive;
-  /* scanningMode  = 128 * iScansNegatively + 64 * jScansPositively + 32 * jPointsAreConsecutive;
-               64  = 128 * 0                + 64 *        1         + 32 * 0
-               00  = 128 * 0                + 64 *        0         + 32 * 0
-               96  = 128 * 0                + 64 *        1         + 32 * 1
-     Default / implicit scanning mode is 64:
-                        i and j scan positively, i points are consecutive (row-major)        */
-};
 
+#define  ISEC2_Reduced              (isec2[16])  /* 0: regular, 1: reduced grid                   */
 
-void grid_init(grid_t *gridptr);
-void cdiGridTypeInit(grid_t *gridptr, int gridtype, int size);
-void grid_free(grid_t *gridptr);
-grid_t *grid_to_pointer(int gridID);
-extern const struct gridVirtTable cdiGridVtable;
+#define  ISEC2_RowLonPtr            (&isec2[22])
+#define  ISEC2_RowLon(i)            (isec2[22+i]) /* Number of points along each parallel         */
 
-unsigned cdiGridCount(void);
+/* */
 
-void gridVerifyProj(int gridID);
+#define  ISEC2_LatSP                (isec2[12])  /* Latitude of the southern pole of rotation     */
+#define  ISEC2_LonSP                (isec2[13])  /* Longitude of the southern pole of rotation    */
 
-const double *gridInqXvalsPtr(int gridID);
-const double *gridInqYvalsPtr(int gridID);
+#define  FSEC2_RotAngle             (fsec2[ 0])  /* Angle of rotation                             */
+#define  FSEC2_StrFact              (fsec2[ 1])  /* Stretching factor                             */
 
-const char **gridInqXCvalsPtr(int gridID);
-const char **gridInqYCvalsPtr(int gridID);
+/*
+ *  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                 */
 
-const double *gridInqXboundsPtr(int gridID);
-const double *gridInqYboundsPtr(int gridID);
-const double *gridInqAreaPtr(int gridID);
+/*
+ *  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                  */
 
-const char *gridInqReferencePtr(int gridID);
 
-int gridGenerate(const grid_t *grid);
+#ifdef __cplusplus
+extern "C" {
+#endif
 
-//int gridIsEqual(int gridID1, int gridID2);
 
-void cdiGridGetIndexList(unsigned, int * );
+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
-gridUnpack(char * unpackBuffer, int unpackBufferSize,
-           int * unpackBufferPos, int originNamespace, void *context,
-           int force_id);
 
-struct addIfNewRes
-{
-  int Id;
-  int isNew;
-};
+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, const char *hoper, int *kret);
 
-struct addIfNewRes cdiVlistAddGridIfNew(int vlistID, grid_t *grid, int mode);
+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, const char *hoper, int *kret);
 
-int gridVerifyGribParamLCC(double missval, double *lon_0, double *lat_0, double *lat_1, double *lat_2,
-                           double *a, double *rf, double *xval_0, double *yval_0, double *x_0, double *y_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:
- */
-#ifndef  CDF_LAZY_GRID_H_
-#define  CDF_LAZY_GRID_H_
+const char *cgribexLibraryVersion(void);
 
-#if defined (HAVE_CONFIG_H)
-#endif
+void  gribDebug(int debug);
+void  gribSetCalendar(int calendar);
 
-#ifdef HAVE_MMAP
-#include <unistd.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#endif
-#ifdef HAVE_LIBPTHREAD
-#include <pthread.h>
-#endif
+void  gribDateTime(int *isec1, int *date, int *time);
+int   gribRefDate(int *isec1);
+int   gribRefTime(int *isec1);
+int   gribTimeIsFC(int *isec1);
 
-#include <string.h>
+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);
 
-struct cdfLazyGrid
-{
-  grid_t base;
-  const struct gridVirtTable *baseVtable;
-  struct cdfLazyGridIds {
-    int datasetNCId, varNCId;
-  } cellAreaGet, xBoundsGet, yBoundsGet;
-  struct xyValGet {
-    double scalefactor, addoffset;
-    size_t start[3], count[3], size, dimsize;
-    int datasetNCId, varNCId;
-    short ndims;
-  } xValsGet, yValsGet;
-#ifdef HAVE_LIBPTHREAD
-  pthread_mutex_t loadSerialize;
-#endif
-};
+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);
 
-extern double *cdfPendingLoad;
+int   grib_info_for_grads(off_t recpos, long recsize, unsigned char *gribbuffer, int *intnum, float *fltnum, off_t *bignum);
 
-void cdfLazyGridRenew(struct cdfLazyGrid *restrict *restrict gridpptr, int gridtype);
-void cdfBaseGridRenew(struct cdfLazyGrid *restrict *restrict gridpptr, int gridtype);
+double calculate_pfactor_float(const float* spectralField, long fieldTruncation, long subsetTruncation);
+double calculate_pfactor_double(const double* spectralField, long fieldTruncation, long subsetTruncation);
 
-void cdfLazyGridDestroy(struct cdfLazyGrid *lazyGrid);
 
+#if defined (__cplusplus)
+}
 #endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
+
+#endif  /* _CGRIBEX_H */ 
+
 #if defined (HAVE_CONFIG_H)
 #endif
 
-#ifdef HAVE_LIBNETCDF
+#include <stdarg.h>
+#include <ctype.h>
 
+#ifdef HAVE_LIBNETCDF
+#endif
 
-static struct gridVirtTable cdfLazyGridVtable;
-double *cdfPendingLoad;
-#ifdef HAVE_LIBPTHREAD
-static pthread_once_t cdfLazyInitialized = PTHREAD_ONCE_INIT;
-#else
-static bool cdfLazyInitialized;
+#if  defined  (HAVE_LIBCGRIBEX)
 #endif
 
+int cdiDefaultCalendar = CALENDAR_PROLEPTIC;
 
-#ifdef HAVE_LIBPTHREAD
-#define lock_lazy_load(plGrid) pthread_mutex_lock(&((plGrid)->loadSerialize))
-#define unlock_lazy_load(plGrid) pthread_mutex_unlock(&((plGrid)->loadSerialize))
-#define destroy_lazy_load_lock(plGrid) pthread_mutex_destroy(&((plGrid)->loadSerialize))
-#define init_lazy_load_lock(plGrid) pthread_mutex_init(&((plGrid)->loadSerialize), NULL)
-#else
-#define lock_lazy_load(plGrid)
-#define unlock_lazy_load(plGrid)
-#define destroy_lazy_load_lock(plGrid)
-#define init_lazy_load_lock(plGrid)
-#endif
+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 cdiIgnoreAttCoordinates = FALSE;
+int cdiIgnoreValidRange     = FALSE;
+int cdiSkipRecords          = 0;
+int cdiConvention           = CDI_CONVENTION_ECHAM;
+int cdiInventoryMode        = 1;
+int CDI_Version_Info        = 1;
+int CDI_cmor_mode           = 0;
+size_t CDI_netcdf_hdr_pad   = 0UL;
+bool CDI_netcdf_lazy_grid_load = false;
+
+char *cdiPartabPath   = NULL;
+int   cdiPartabIntern = 1;
+
+double cdiDefaultMissval = -9.E33;
+
+static const char Filetypes[][9] = {
+  "UNKNOWN",
+  "GRIB",
+  "GRIB2",
+  "NetCDF",
+  "NetCDF2",
+  "NetCDF4",
+  "NetCDF4c",
+  "SERVICE",
+  "EXTRA",
+  "IEG",
+  "HDF5",
+};
+
+int CDI_Debug   = 0;    /* If set to 1, debugging           */
+int CDI_Recopt = 0;
 
+int cdiGribApiDebug     = 0;
+int cdiDefaultLeveltype = -1;
+int cdiDataUnreduced = 0;
+int cdiSortName = 0;
+int cdiHaveMissval = 0;
 
 
-void cdfLazyGridDestroy(struct cdfLazyGrid *lazyGrid)
+static long cdiGetenvInt(const char *envName)
 {
-  if (lazyGrid->base.area == cdfPendingLoad)  lazyGrid->base.area = NULL;
-  if (lazyGrid->base.x.vals == cdfPendingLoad) lazyGrid->base.x.vals = NULL;
-  if (lazyGrid->base.y.vals == cdfPendingLoad) lazyGrid->base.y.vals = NULL;
-  if (lazyGrid->base.x.bounds == cdfPendingLoad) lazyGrid->base.x.bounds = NULL;
-  if (lazyGrid->base.y.bounds == cdfPendingLoad) lazyGrid->base.y.bounds = NULL;
-  destroy_lazy_load_lock(lazyGrid);
+  char *envString;
+  long envValue = -1;
+  long fact = 1;
+
+  envString = getenv(envName);
+
+  if ( envString )
+    {
+      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);
+    }
+
+  return (envValue);
 }
 
-static void cdfLazyGridDelete(grid_t *grid)
+static void
+cdiPrintDefaults(void)
 {
-  struct cdfLazyGrid *cdfGrid = (struct cdfLazyGrid *)grid;
-  void (*baseDestroy)(grid_t *grid) = cdfGrid->baseVtable->destroy;
-  cdfLazyGridDestroy(cdfGrid);
-  baseDestroy(grid);
+  fprintf(stderr, "default instID     :  %d\n"
+          "default modelID    :  %d\n"
+          "default tableID    :  %d\n"
+          "default missval    :  %g\n", cdiDefaultInstID,
+          cdiDefaultModelID, cdiDefaultTableID, cdiDefaultMissval);
 }
 
-static void cdfLazyGridDestroyOnce(void)
+void cdiPrintVersion(void)
 {
-  /*
-#ifdef HAVE_MMAP
-  size_t pgSize = cdiGetPageSize(false);
-  munmap(cdfPendingLoad, pgSize);
+  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_NC4HDF5)
+  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());
 }
 
-static void
-cdfLazyGridDefArea(grid_t *grid, const double *area)
+void cdiDebug(int level)
 {
-  struct cdfLazyGrid *cdfGrid = (struct cdfLazyGrid *)grid;
-  lock_lazy_load(cdfGrid);
-  if (grid->area == cdfPendingLoad) grid->area = NULL;
-  cdfGrid->cellAreaGet.datasetNCId = -1;
-  cdfGrid->cellAreaGet.varNCId = -1;
-  cdfGrid->baseVtable->defArea(grid, area);
-  unlock_lazy_load(cdfGrid);
-}
+  if ( level == 1 || (level &  2) ) CDI_Debug = 1;
 
+  if ( CDI_Debug ) Message("debug level %d", level);
 
-static const double *
-cdfLazyGridInqAreaPtr(grid_t *grid)
-{
-  struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
-  lock_lazy_load(lazyGrid);
-  if (grid->area == cdfPendingLoad)
+  if ( level == 1 || (level &  4) ) memDebug(1);
+
+  if ( level == 1 || (level &  8) ) fileDebug(1);
+
+  if ( level == 1 || (level & 16) )
     {
-      grid->area = (double *)Malloc((size_t)grid->size * sizeof(double));
-      cdf_get_var_double(lazyGrid->cellAreaGet.datasetNCId,
-                         lazyGrid->cellAreaGet.varNCId, grid->area);
+#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
     }
-  unlock_lazy_load(lazyGrid);
-  return lazyGrid->baseVtable->inqAreaPtr(grid);
-}
 
-static void
-cdfLazyGridInqArea(grid_t *grid, double *area)
-{
-  grid->vtable->inqAreaPtr(grid);
-  struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
-  lazyGrid->baseVtable->inqArea(grid, area);
+  if ( CDI_Debug )
+    {
+      cdiPrintDefaults();
+      cdiPrintDatatypes();
+    }
 }
 
 
-static void
-cdfLazyLoadXYVals(struct xyValGet *valsGet, double **valsp)
+int cdiHaveFiletype(int filetype)
 {
-  double *grid_vals = (double *)Malloc(valsGet->size * sizeof (double));
-  *valsp = grid_vals;
-  if ( valsGet->ndims == 3 )
-    cdf_get_vara_double(valsGet->datasetNCId, valsGet->varNCId,
-                        valsGet->start, valsGet->count, grid_vals);
-  else
-    cdf_get_var_double(valsGet->datasetNCId, valsGet->varNCId, grid_vals);
-  cdf_scale_add(valsGet->size, grid_vals, valsGet->addoffset, valsGet->scalefactor);
-}
+  int status = 0;
 
-static const double *
-cdfLazyGridInqXValsPtr(grid_t *grid)
-{
-  struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
-  lock_lazy_load(lazyGrid);
-  if (grid->x.vals == cdfPendingLoad)
-    cdfLazyLoadXYVals(&lazyGrid->xValsGet, &grid->x.vals);
-  unlock_lazy_load(lazyGrid);
-  return lazyGrid->baseVtable->inqXValsPtr(grid);
+  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; }
+    }
+
+  return (status);
 }
 
-static const double *
-cdfLazyGridInqYValsPtr(grid_t *grid)
+void cdiDefTableID(int tableID)
 {
-  struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
-  lock_lazy_load(lazyGrid);
-  if (grid->y.vals == cdfPendingLoad)
-    cdfLazyLoadXYVals(&lazyGrid->yValsGet, &grid->y.vals);
-  unlock_lazy_load(lazyGrid);
-  return lazyGrid->baseVtable->inqYValsPtr(grid);
+  cdiDefaultTableID = tableID;
+  int modelID = cdiDefaultModelID = tableInqModel(tableID);
+  cdiDefaultInstID = modelInqInstitut(modelID);
 }
 
-static double
-cdfLazyGridInqXYVal(grid_t *grid, size_t index,
-                    const struct xyValGet *valsGet, double *vals,
-                    const double *(*inqValsPtr)(grid_t *gridptr))
+static
+void cdiSetChunk(const char *chunkAlgo)
 {
-  size_t size = valsGet->size;
-  double v;
-  if ( vals == cdfPendingLoad )
+  //char *pch;
+  //size_t len = strlen(chunkAlgo);
+  int algo = -1;
+
+  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 )
     {
-      /* prevent full load if only first/last values get inspected */
-      if ( index == 0 || index == size - 1 )
+      int ix, iy;
+      ix = atoi(chunkAlgo);
+      iy = atoi(pch+1);
+      if ( ix > 0 && iy > 0 )
         {
-          size_t indexND[3];
-          if ( valsGet->ndims == 3 )
-            {
-              indexND[0] = 0;
-              indexND[1] = index / valsGet->count[2];
-              indexND[2] = index % valsGet->count[2];
-            }
-          else if ( valsGet->ndims == 2)
-            {
-              indexND[0] = index / (size_t)grid->x.size;
-              indexND[1] = index % (size_t)grid->x.size;
-            }
-          else
-            indexND[0] = index;
-          cdf_get_var1_double(valsGet->datasetNCId, valsGet->varNCId, indexND, &v);
+          cdiChunkX = ix;
+          cdiChunkY = iy;
+          algo = CHUNK_USER;
         }
       else
-        {
-          const double *grid_vals = inqValsPtr(grid);
-          v = grid_vals[index];
-        }
+        Warning("Invalid environment variable CDI_CHUNK_ALGO: %s", chunkAlgo);
     }
-  else if ( vals )
-    v = vals[index];
+  */
   else
-    v = 0.0;
-  return v;
-}
+    Warning("Invalid environment variable CDI_CHUNK_ALGO: %s", chunkAlgo);
 
-static void
-cdfLazyGridDefXVals(grid_t *grid, const double *vals)
-{
-  struct cdfLazyGrid *cdfGrid = (struct cdfLazyGrid *)grid;
-  lock_lazy_load(cdfGrid);
-  if (grid->x.vals == cdfPendingLoad)
-    grid->x.vals = NULL;
-  cdfGrid->xValsGet.datasetNCId = -1;
-  cdfGrid->xValsGet.varNCId = -1;
-  cdfGrid->baseVtable->defXVals(grid, vals);
-  unlock_lazy_load(cdfGrid);
+  if ( algo != -1 )
+    {
+      cdiChunkType = algo;
+      if ( CDI_Debug ) Message("set ChunkAlgo to %s", chunkAlgo);
+    }
 }
 
-static void
-cdfLazyGridDefYVals(grid_t *grid, const double *vals)
-{
-  struct cdfLazyGrid *cdfGrid = (struct cdfLazyGrid *)grid;
-  lock_lazy_load(cdfGrid);
-  if (grid->y.vals == cdfPendingLoad)
-    grid->y.vals = NULL;
-  cdfGrid->yValsGet.datasetNCId = -1;
-  cdfGrid->yValsGet.varNCId = -1;
-  cdfGrid->baseVtable->defYVals(grid, vals);
-  unlock_lazy_load(cdfGrid);
-}
 
-static double
-cdfLazyGridInqXVal(grid_t *grid, int index)
+void cdiInitialize(void)
 {
-  struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
-  lock_lazy_load(lazyGrid);
-  double rv = cdfLazyGridInqXYVal(grid, (size_t)index, &lazyGrid->xValsGet,
-                                  grid->x.vals, grid->vtable->inqXValsPtr);
-  unlock_lazy_load(lazyGrid);
-  return rv;
-}
+  static int Init_CDI = FALSE;
+  char *envstr;
+  long value;
 
-static double
-cdfLazyGridInqYVal(grid_t *grid, int index)
-{
-  struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
-  lock_lazy_load(lazyGrid);
-  double rv = cdfLazyGridInqXYVal(grid, (size_t)index, &lazyGrid->yValsGet,
-                                  grid->y.vals, grid->vtable->inqYValsPtr);
-  unlock_lazy_load(lazyGrid);
-  return rv;
-}
+  if ( ! Init_CDI )
+    {
+      Init_CDI = TRUE;
 
-static bool
-cdfLazyXYValGetCompare(struct cdfLazyGrid *lazyGridRef,
-                       struct cdfLazyGrid *lazyGridTest)
-{
-  struct xyValGet *valsGetXRef = &lazyGridRef->xValsGet,
-    *valsGetYRef = &lazyGridRef->yValsGet,
-    *valsGetXTest = &lazyGridTest->xValsGet,
-    *valsGetYTest = &lazyGridTest->yValsGet;
-  if (valsGetXRef->datasetNCId == -1
-      || valsGetXTest->datasetNCId == -1
-      || valsGetYRef->datasetNCId == -1
-      || valsGetYTest->datasetNCId == -1)
-    return lazyGridRef->baseVtable->compareXYFull(&lazyGridRef->base,
-                                                  &lazyGridTest->base);
-  return valsGetXRef->datasetNCId != valsGetXTest->datasetNCId
-    ||   valsGetXRef->varNCId     != valsGetXTest->varNCId
-    ||   valsGetYRef->datasetNCId != valsGetYTest->datasetNCId
-    ||   valsGetYRef->varNCId     != valsGetYTest->varNCId;
-}
+#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
 
-static bool
-cdfLazyCompareXYFull(grid_t *gridRef, grid_t *gridTest)
-{
-  bool diff;
-  struct cdfLazyGrid *lazyGridRef = (struct cdfLazyGrid *)gridRef;
-  if (gridTest->vtable == &cdfLazyGridVtable)
-    diff = cdfLazyXYValGetCompare(lazyGridRef, (struct cdfLazyGrid *)gridTest);
-  else
-    diff = lazyGridRef->baseVtable->compareXYFull(gridRef, gridTest);
-  return diff;
-}
-
-static bool
-cdfLazyCompareXYAO(grid_t *gridRef, grid_t *gridTest)
-{
-  bool diff;
-  struct cdfLazyGrid *lazyGridRef = (struct cdfLazyGrid *)gridRef;
-  if (gridTest->vtable == &cdfLazyGridVtable)
-    diff = cdfLazyXYValGetCompare(lazyGridRef, (struct cdfLazyGrid *)gridTest);
-  else
-    diff = lazyGridRef->baseVtable->compareXYAO(gridRef, gridTest);
-  return diff;
-}
+      value = cdiGetenvInt("CDI_DEBUG");
+      if ( value >= 0 ) CDI_Debug = (int) value;
 
+      value = cdiGetenvInt("CDI_GRIBAPI_DEBUG");
+      if ( value >= 0 ) cdiGribApiDebug = (int) value;
 
-static const double *
-cdfLazyGridInqXBoundsPtr(grid_t *grid)
-{
-  struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
-  lock_lazy_load(lazyGrid);
-  if (grid->x.bounds == cdfPendingLoad)
-    {
-      grid->x.bounds = (double *)Malloc((size_t)grid->nvertex
-                                       * (size_t)grid->size * sizeof(double));
-      cdf_get_var_double(lazyGrid->xBoundsGet.datasetNCId,
-                         lazyGrid->xBoundsGet.varNCId, grid->x.bounds);
-    }
-  unlock_lazy_load(lazyGrid);
-  return lazyGrid->baseVtable->inqXBoundsPtr(grid);
-}
+      value = cdiGetenvInt("CDI_RECOPT");
+      if ( value >= 0 ) CDI_Recopt = (int) value;
 
-static void
-cdfLazyGridDefXBounds(grid_t *grid, const double *xbounds)
-{
-  struct cdfLazyGrid *cdfGrid = (struct cdfLazyGrid *)grid;
-  lock_lazy_load(cdfGrid);
-  if (grid->x.bounds == cdfPendingLoad)
-    grid->x.bounds = NULL;
-  cdfGrid->xBoundsGet.datasetNCId = -1;
-  cdfGrid->xBoundsGet.varNCId = -1;
-  cdfGrid->baseVtable->defXBounds(grid, xbounds);
-  unlock_lazy_load(cdfGrid);
-}
+      value = cdiGetenvInt("CDI_REGULARGRID");
+      if ( value >= 0 ) cdiDataUnreduced = (int) value;
 
-static void
-cdfLazyGridDefYBounds(grid_t *grid, const double *ybounds)
-{
-  struct cdfLazyGrid *cdfGrid = (struct cdfLazyGrid *)grid;
-  lock_lazy_load(cdfGrid);
-  if (grid->y.bounds == cdfPendingLoad)
-    grid->y.bounds = NULL;
-  cdfGrid->yBoundsGet.datasetNCId = -1;
-  cdfGrid->yBoundsGet.varNCId = -1;
-  cdfGrid->baseVtable->defYBounds(grid, ybounds);
-  unlock_lazy_load(cdfGrid);
-}
+      value = cdiGetenvInt("CDI_SORTNAME");
+      if ( value >= 0 ) cdiSortName = (int) value;
 
-static const double *
-cdfLazyGridInqYBoundsPtr(grid_t *grid)
-{
-  struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
-  lock_lazy_load(lazyGrid);
-  if (grid->y.bounds == cdfPendingLoad)
-    {
-      grid->y.bounds = (double *)Malloc((size_t)grid->nvertex
-                                       * (size_t)grid->size * sizeof(double));
-      cdf_get_var_double(lazyGrid->yBoundsGet.datasetNCId,
-                         lazyGrid->yBoundsGet.varNCId, grid->y.bounds);
-    }
-  unlock_lazy_load(lazyGrid);
-  return lazyGrid->baseVtable->inqYBoundsPtr(grid);
-}
+      value = cdiGetenvInt("CDI_HAVE_MISSVAL");
+      if ( value >= 0 ) cdiHaveMissval = (int) value;
 
-static void
-cdfLazyGridCopyScalarFields(grid_t *gridptrOrig, grid_t *gridptrDup)
-{
-  struct cdfLazyGrid *lazyGridDup = (struct cdfLazyGrid *)gridptrDup,
-    *lazyGridOrig = (struct cdfLazyGrid *)gridptrOrig;
-  lazyGridOrig->baseVtable->copyScalarFields(gridptrOrig, &lazyGridDup->base);
-  lazyGridDup->baseVtable = lazyGridOrig->baseVtable;
-  lazyGridDup->cellAreaGet = lazyGridOrig->cellAreaGet;
-  lazyGridDup->xBoundsGet = lazyGridOrig->xBoundsGet;
-  lazyGridDup->yBoundsGet = lazyGridOrig->yBoundsGet;
-  lazyGridDup->xValsGet = lazyGridOrig->xValsGet;
-  lazyGridDup->yValsGet = lazyGridOrig->yValsGet;
-  init_lazy_load_lock(lazyGridDup);
-}
+      value = cdiGetenvInt("CDI_LEVELTYPE");
+      if ( value >= 0 ) cdiDefaultLeveltype = (int) value;
 
-static void
-cdfLazyGridCopyArrayFields(grid_t *gridptrOrig, grid_t *gridptrDup)
-{
-  size_t nrowlon = (size_t)gridptrOrig->nrowlon;
-  size_t gridsize = (size_t)gridptrOrig->size;
-  int gridtype = gridptrOrig->type;
-  int irregular = gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED;
-  if ( nrowlon )
-    {
-      gridptrDup->rowlon = (int *)Malloc(nrowlon * sizeof (int));
-      memcpy(gridptrDup->rowlon, gridptrOrig->rowlon, nrowlon * sizeof(int));
-    }
+      value = cdiGetenvInt("CDI_NETCDF_HDR_PAD");
+      if ( value >= 0 ) CDI_netcdf_hdr_pad = (size_t) value;
 
-  if ( gridptrOrig->x.vals != NULL && gridptrOrig->x.vals != cdfPendingLoad )
-    {
-      size_t size  = irregular ? gridsize : (size_t)gridptrOrig->x.size;
+      envstr = getenv("CDI_MISSVAL");
+      if ( envstr ) cdiDefaultMissval = atof(envstr);
+      /*
+      envstr = getenv("NC_MISSING_VALUE");
+      if ( envstr ) cdiNcMissingValue = atoi(envstr);
+      */
+      envstr = getenv("NC_CHUNKSIZEHINT");
+      if ( envstr ) cdiNcChunksizehint = atoi(envstr);
 
-      gridptrDup->x.vals = (double *)Malloc(size * sizeof (double));
-      memcpy(gridptrDup->x.vals, gridptrOrig->x.vals, size * sizeof (double));
-    }
+      envstr = getenv("CDI_CHUNK_ALGO");
+      if ( envstr ) cdiSetChunk(envstr);
 
-  if ( gridptrOrig->y.vals != NULL && gridptrOrig->y.vals != cdfPendingLoad )
-    {
-      size_t size  = irregular ? gridsize : (size_t)gridptrOrig->y.size;
+      envstr = getenv("SPLIT_LTYPE_105");
+      if ( envstr ) cdiSplitLtype105 = atoi(envstr);
 
-      gridptrDup->y.vals = (double *)Malloc(size * sizeof (double));
-      memcpy(gridptrDup->y.vals, gridptrOrig->y.vals, size * sizeof (double));
-    }
+      envstr = getenv("IGNORE_ATT_COORDINATES");
+      if ( envstr ) cdiIgnoreAttCoordinates = atoi(envstr);
 
-  if ( gridptrOrig->x.bounds != NULL && gridptrOrig->x.bounds != cdfPendingLoad )
-    {
-      size_t size  = (irregular ? gridsize : (size_t)gridptrOrig->x.size)
-        * (size_t)gridptrOrig->nvertex;
+      envstr = getenv("IGNORE_VALID_RANGE");
+      if ( envstr ) cdiIgnoreValidRange = atoi(envstr);
 
-      gridptrDup->x.bounds = (double *)Malloc(size * sizeof (double));
-      memcpy(gridptrDup->x.bounds, gridptrOrig->x.bounds, size * sizeof (double));
-    }
+      envstr = getenv("CDI_SKIP_RECORDS");
+      if ( envstr )
+	{
+	  cdiSkipRecords = atoi(envstr);
+	  cdiSkipRecords = cdiSkipRecords > 0 ? cdiSkipRecords : 0;
+	}
 
-  if ( gridptrOrig->y.bounds != NULL && gridptrOrig->y.bounds != cdfPendingLoad )
-    {
-      size_t size = (irregular ? gridsize : (size_t)gridptrOrig->y.size)
-        * (size_t)gridptrOrig->nvertex;
+      envstr = getenv("CDI_CONVENTION");
+      if ( envstr )
+	{
+	  if ( strcmp(envstr, "CF") == 0 || strcmp(envstr, "cf") == 0 )
+	    {
+	      cdiConvention = CDI_CONVENTION_CF;
+	      if ( CDI_Debug )
+		Message("CDI convention was set to CF!");
+	    }
+	}
 
-      gridptrDup->y.bounds = (double *)Malloc(size * sizeof (double));
-      memcpy(gridptrDup->y.bounds, gridptrOrig->y.bounds, size * sizeof (double));
-    }
+      envstr = getenv("CDI_INVENTORY_MODE");
+      if ( envstr )
+	{
+	  if ( strncmp(envstr, "time", 4) == 0 )
+	    {
+	      cdiInventoryMode = 2;
+	      if ( CDI_Debug )
+		Message("Inventory mode was set to timestep!");
+	    }
+	}
 
-  {
-    if ( gridptrOrig->area != NULL && gridptrOrig->area != cdfPendingLoad )
-      {
-        size_t size = gridsize;
+      envstr = getenv("CDI_VERSION_INFO");
+      if ( envstr )
+        {
+          int ival = atoi(envstr);
+          if ( ival == 0 || ival == 1 )
+            {
+              CDI_Version_Info = ival;
+              if ( CDI_Debug )
+                Message("CDI_Version_Info = %s", envstr);
+            }
+        }
 
-        gridptrDup->area = (double *)Malloc(size * sizeof (double));
-        memcpy(gridptrDup->area, gridptrOrig->area, size * sizeof (double));
-      }
-  }
 
-  if ( gridptrOrig->mask != NULL )
-    {
-      size_t size = gridsize;
+      envstr = getenv("CDI_CALENDAR");
+      if ( envstr )
+	{
+	  if      ( strncmp(envstr, "standard", 8) == 0 )
+	    cdiDefaultCalendar = CALENDAR_STANDARD;
+	  else if ( strncmp(envstr, "proleptic", 9) == 0 )
+	    cdiDefaultCalendar = CALENDAR_PROLEPTIC;
+	  else if ( strncmp(envstr, "360days", 7) == 0 )
+	    cdiDefaultCalendar = CALENDAR_360DAYS;
+	  else if ( strncmp(envstr, "365days", 7) == 0 )
+	    cdiDefaultCalendar = CALENDAR_365DAYS;
+	  else if ( strncmp(envstr, "366days", 7) == 0 )
+	    cdiDefaultCalendar = CALENDAR_366DAYS;
+	  else if ( strncmp(envstr, "none", 4) == 0 )
+	    cdiDefaultCalendar = CALENDAR_NONE;
 
-      gridptrDup->mask = (mask_t *)Malloc(size * sizeof(mask_t));
-      memcpy(gridptrDup->mask, gridptrOrig->mask, size * sizeof (mask_t));
-    }
+	  if ( CDI_Debug )
+	    Message("Default calendar set to %s!", envstr);
+	}
+#if  defined  (HAVE_LIBCGRIBEX)
+      gribSetCalendar(cdiDefaultCalendar);
+#endif
 
-  if ( gridptrOrig->mask_gme != NULL )
-    {
-      size_t size = gridsize;
+      envstr = getenv("PARTAB_INTERN");
+      if ( envstr ) cdiPartabIntern = atoi(envstr);
 
-      gridptrDup->mask_gme = (mask_t *)Malloc(size * sizeof (mask_t));
-      memcpy(gridptrDup->mask_gme, gridptrOrig->mask_gme, size * sizeof(mask_t));
+      envstr = getenv("PARTAB_PATH");
+      if ( envstr ) cdiPartabPath = strdup(envstr);
     }
 }
 
-static grid_t *
-cdfLazyGridCopy(grid_t *gridptrOrig)
-{
-  struct cdfLazyGrid *lazyGridDup
-    = (struct cdfLazyGrid *)Malloc(sizeof (*lazyGridDup));
-  gridptrOrig->vtable->copyScalarFields(gridptrOrig, &lazyGridDup->base);
-  gridptrOrig->vtable->copyArrayFields(gridptrOrig, &lazyGridDup->base);
-  return &lazyGridDup->base;
-}
 
-static void
-cdfLazyGridInitOnce(void)
+const char *strfiletype(int filetype)
 {
-  cdfLazyGridVtable = cdiGridVtable;
-  cdfLazyGridVtable.destroy = cdfLazyGridDelete;
-  cdfLazyGridVtable.copy = cdfLazyGridCopy;
-  cdfLazyGridVtable.copyScalarFields = cdfLazyGridCopyScalarFields;
-  cdfLazyGridVtable.copyArrayFields = cdfLazyGridCopyArrayFields;
-  cdfLazyGridVtable.defArea = cdfLazyGridDefArea;
-  cdfLazyGridVtable.inqAreaPtr = cdfLazyGridInqAreaPtr;
-  cdfLazyGridVtable.inqArea = cdfLazyGridInqArea;
-  cdfLazyGridVtable.inqXValsPtr = cdfLazyGridInqXValsPtr;
-  cdfLazyGridVtable.inqYValsPtr = cdfLazyGridInqYValsPtr;
-  cdfLazyGridVtable.inqXVal = cdfLazyGridInqXVal;
-  cdfLazyGridVtable.inqYVal = cdfLazyGridInqYVal;
-  cdfLazyGridVtable.defXVals = cdfLazyGridDefXVals;
-  cdfLazyGridVtable.defYVals = cdfLazyGridDefYVals;
-  cdfLazyGridVtable.compareXYFull = cdfLazyCompareXYFull;
-  cdfLazyGridVtable.compareXYAO = cdfLazyCompareXYAO;
-  cdfLazyGridVtable.defXBounds = cdfLazyGridDefXBounds;
-  cdfLazyGridVtable.defYBounds = cdfLazyGridDefYBounds;
-  cdfLazyGridVtable.inqXBoundsPtr = cdfLazyGridInqXBoundsPtr;
-  cdfLazyGridVtable.inqYBoundsPtr = cdfLazyGridInqYBoundsPtr;
-  /* create inaccessible memory area, if possible, this serves as
-   * dummy value for pointers to data not yet loaded */
-  /*
-#ifdef HAVE_MMAP
-  {
-    size_t pgSize = cdiGetPageSize(false);
-    static const char devZero[] = "/dev/zero";
-    int fd = open(devZero, O_RDWR);
-    if (fd == -1)
-      SysError("Could not open %s to map anonymous memory", devZero);
-    void *cdfInvalid = mmap(NULL, pgSize, PROT_NONE, MAP_PRIVATE, fd, 0);
-    if (cdfInvalid == MAP_FAILED)
-      SysError("Could not mmap anonymous memory");
-    cdfPendingLoad = cdfInvalid;
-    int rc = close(fd);
-    if (rc == -1)
-      SysError("Could not close %s file handle %d after mapping anonymous"
-               " memory", devZero, fd);
-  }
-#else
-  */
-  cdfPendingLoad = (double *)&cdfPendingLoad;
-  //#endif
-  atexit(cdfLazyGridDestroyOnce);
-#ifndef HAVE_LIBPTHREAD
-  cdfLazyInitialized = true;
-#endif
-}
+  const char *name;
+  int size = (int) (sizeof(Filetypes)/sizeof(char *));
 
-static void
-cdfBaseGridInit(grid_t *grid, int gridtype)
-{
-  grid_init(grid);
-  cdiGridTypeInit(grid, gridtype, 0);
+  if ( filetype > 0 && filetype < size )
+    name = Filetypes[filetype];
+  else
+    name = Filetypes[0];
+
+  return (name);
 }
 
-static void
-cdfLazyGridInit(struct cdfLazyGrid *grid, int gridtype)
+
+void cdiDefGlobal(const char *string, int val)
 {
-#ifdef HAVE_LIBPTHREAD
-  pthread_once(&cdfLazyInitialized, cdfLazyGridInitOnce);
-#else
-  if (cdfLazyInitialized) ; else cdfLazyGridInitOnce();
-#endif
-  cdfBaseGridInit(&grid->base, gridtype);
-  grid->baseVtable = grid->base.vtable;
-  grid->cellAreaGet.datasetNCId = -1;
-  grid->cellAreaGet.varNCId = -1;
-  grid->xValsGet.datasetNCId = -1;
-  grid->xValsGet.varNCId = -1;
-  grid->yValsGet.datasetNCId = -1;
-  grid->yValsGet.varNCId = -1;
-  grid->xBoundsGet.datasetNCId = -1;
-  grid->xBoundsGet.varNCId = -1;
-  grid->yBoundsGet.datasetNCId = -1;
-  grid->yBoundsGet.varNCId = -1;
-  grid->base.vtable = &cdfLazyGridVtable;
-  init_lazy_load_lock(grid);
+  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, "CMOR_MODE")        == 0 ) CDI_cmor_mode = val;
+  else if ( strcmp(string, "NETCDF_HDR_PAD")   == 0 ) CDI_netcdf_hdr_pad = (size_t) val;
+  else if ( strcmp(string, "NETCDF_LAZY_GRID_LOAD") == 0)
+    CDI_netcdf_lazy_grid_load = (bool)val;
+  else Warning("Unsupported global key: %s", string);
 }
 
 
-void cdfLazyGridRenew(struct cdfLazyGrid *restrict *restrict gridpptr, int gridtype)
+void cdiDefMissval(double missval)
 {
-  struct cdfLazyGrid *restrict grid = *gridpptr;
-  if (!grid)
-    *gridpptr = grid = (struct cdfLazyGrid *)Malloc(sizeof (*grid));
-  cdfLazyGridInit(grid, gridtype);
+  cdiInitialize();
+
+  cdiDefaultMissval = missval;
 }
 
 
-void cdfBaseGridRenew(struct cdfLazyGrid *restrict *restrict gridpptr, int gridtype)
+double cdiInqMissval(void)
 {
-  struct cdfLazyGrid *restrict grid = *gridpptr;
-  if (!grid)
-    *gridpptr = grid = (struct cdfLazyGrid *)Malloc(sizeof (grid_t));
-  cdfBaseGridInit((grid_t*)grid, gridtype);
-}
+  cdiInitialize();
 
-#endif
+  return (cdiDefaultMissval);
+}
 
 /*
  * Local Variables:
@@ -5732,220 +5487,168 @@ void cdfBaseGridRenew(struct cdfLazyGrid *restrict *restrict gridpptr, int gridt
  * 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);
 
+#if defined (HAVE_CONFIG_H)
 #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
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
 
-#include <inttypes.h>
-#include <sys/types.h>
 
-void
-memcrc_r(uint32_t *state, const unsigned char *block, size_t block_len);
+void cdiDecodeParam(int param, int *pnum, int *pcat, int *pdis)
+{
+  unsigned uparam = (unsigned)param;
+  unsigned upnum;
 
-void
-memcrc_r_eswap(uint32_t *state, const unsigned char *elems, size_t num_elems,
-               size_t elem_size);
+  *pdis = 0xff   & uparam;
+  *pcat = 0xff   & uparam >> 8;
+  upnum = 0xffff & uparam >> 16;
+  if ( upnum > 0x7fffU ) upnum = 0x8000U - upnum;
+  *pnum = (int)upnum;
+}
 
-uint32_t
-memcrc_finish(uint32_t *state, off_t total_size);
 
-uint32_t
-memcrc(const unsigned char *b, size_t n);
+int cdiEncodeParam(int pnum, int pcat, int pdis)
+{
+  unsigned uparam, upnum;
 
-/*
- * 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
+  if ( pcat < 0 || pcat > 255 ) pcat = 255;
+  if ( pdis < 0 || pdis > 255 ) pdis = 255;
 
-#ifndef SERIALIZE_H
-#define SERIALIZE_H
+  upnum = (unsigned)pnum;
+  if ( pnum < 0 ) upnum = (unsigned)(0x8000 - pnum);
 
-#include <string.h>
+  uparam = upnum << 16 | (unsigned)(pcat << 8) | (unsigned)pdis;
 
-#ifndef  CDI_CKSUM_H_
-#endif
-#ifndef  ERROR_H
-#endif
+  return ((int)uparam);
+}
 
-/*
- * 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 cdiDecodeDate(int date, int *year, int *month, int *day)
 {
-  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, CDI_DATATYPE_INT, context)
-      + serializeGetSize((int)len, CDI_DATATYPE_TXT, context);
-  }
-  packBuffSize +=
-    serializeGetSize(1, CDI_DATATYPE_UINT32, context);
-  return packBuffSize;
+
+  int iyear = date / 10000;
+  *year = iyear;
+  int idate = abs(date - iyear * 10000),
+    imonth = idate / 100;
+  *month = imonth;
+  *day   = idate - imonth * 100;
 }
 
-static inline void
-serializeStrTabPack(const char **strTab, int numStr,
-                    void *buf, int buf_size, int *position, void *context)
+
+int cdiEncodeDate(int year, int month, int day)
 {
-  uint32_t d = 0;
-  xassert(numStr >= 0);
-  for (size_t i = 0; i < (size_t)numStr; ++i)
-  {
-    int len = (int)strlen(strTab[i]);
-    serializePack(&len, 1, CDI_DATATYPE_INT,
-                  buf, buf_size, position, context);
-    serializePack(strTab[i], len, CDI_DATATYPE_TXT,
-                  buf, buf_size, position, context);
-    d ^= cdiCheckSum(CDI_DATATYPE_TXT, len, strTab[i]);
-  }
-  serializePack(&d, 1, CDI_DATATYPE_UINT32,
-                buf, buf_size, position, context);
+  int iyear = abs(year),
+    date = iyear * 10000 + month * 100 + day;
+  if ( year < 0 ) date = -date;
+  return (date);
 }
 
-static inline void
-serializeStrTabUnpack(const void *buf, int buf_size, int *position,
-                      char **strTab, int numStr, void *context)
+
+void cdiDecodeTime(int time, int *hour, int *minute, int *second)
 {
-  uint32_t d, d2 = 0;
-  xassert(numStr >= 0);
-  for (size_t i = 0; i < (size_t)numStr; ++i)
-    {
-      int len;
-      serializeUnpack(buf, buf_size, position,
-                      &len, 1, CDI_DATATYPE_INT, context);
-      serializeUnpack(buf, buf_size, position,
-                      strTab[i], len, CDI_DATATYPE_TXT, context);
-      strTab[i][len] = '\0';
-      d2 ^= cdiCheckSum(CDI_DATATYPE_TXT, len, strTab[i]);
-    }
-  serializeUnpack(buf, buf_size, position,
-                  &d, 1, CDI_DATATYPE_UINT32, context);
-  xassert(d == d2);
+  int ihour = time / 10000,
+    itime = time - ihour * 10000,
+    iminute = itime / 100;
+  *hour   = ihour;
+  *minute = iminute;
+  *second = itime - iminute * 100;
 }
 
-/*
- * 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
+int cdiEncodeTime(int hour, int minute, int second)
+{
+  int time = hour*10000 + minute*100 + second;
 
-#include <inttypes.h>
-#include <sys/types.h>
-#include <stdlib.h>
+  return time;
+}
 
 
-uint32_t cdiCheckSum(int type, int count, const void *buffer)
+void cdiParamToString(int param, char *paramstr, int maxlen)
 {
-  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;
-}
+  int dis, cat, num;
+  int len;
 
-/*
- * 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
+  cdiDecodeParam(param, &num, &cat, &dis);
 
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
+  size_t umaxlen = maxlen >= 0 ? (unsigned)maxlen : 0U;
+  if ( dis == 255 && (cat == 255 || cat == 0 ) )
+    len = snprintf(paramstr, umaxlen, "%d", num);
+  else  if ( dis == 255 )
+    len = snprintf(paramstr, umaxlen, "%d.%d", num, cat);
+  else
+    len = snprintf(paramstr, umaxlen, "%d.%d.%d", num, cat, dis);
 
-const char *cdiStringError(int cdiErrno)
+  if ( len >= maxlen || len < 0)
+    fprintf(stderr, "Internal problem (%s): size of input string is too small!\n", __func__);
+}
+
+
+const char *cdiUnitNamePtr(int cdi_unit)
 {
-  static const char UnknownError[] = "Unknown Error";
-  static const char _EISDIR[]      = "Is a directory";
-  static const char _EISEMPTY[]    = "File is empty";
-  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 _EDIMSIZE[]    = "Invalid dimension size";
-  static const char _ELIMIT[]      = "Internal limits exceeded";
+  const char *cdiUnits[] = {
+    /*  0 */  "undefined",
+    /*  1 */  "Pa",
+    /*  2 */  "hPa",
+    /*  3 */  "mm",
+    /*  4 */  "cm",
+    /*  5 */  "dm",
+    /*  6 */  "m",
+  };
+  enum { numUnits = (int) (sizeof(cdiUnits)/sizeof(char *)) };
+  const char *name = ( cdi_unit > 0 && cdi_unit < numUnits ) ?
+    cdiUnits[cdi_unit] : NULL;
+  return name;
+}
 
-  switch (cdiErrno) {
-  case CDI_ESYSTEM:
+size_t
+cdiGetPageSize(bool largePageAlign)
+{
+  long pagesize = -1L;
+#if HAVE_DECL__SC_LARGE_PAGESIZE || HAVE_DECL__SC_PAGE_SIZE || HAVE_DECL__SC_PAGESIZE
+  bool nameAssigned = false;
+  int name;
+#  if HAVE_DECL__SC_LARGE_PAGESIZE
+  if (largePageAlign)
     {
-      const char *cp = strerror(errno);
-      if ( cp == NULL ) break;
-      return cp;
+      name = _SC_LARGE_PAGESIZE;
+      nameAssigned = true;
     }
-  case CDI_EISDIR:     return _EISDIR;
-  case CDI_EISEMPTY:   return _EISEMPTY;
-  case CDI_EUFTYPE:    return _EUFTYPE;
-  case CDI_ELIBNAVAIL: return _ELIBNAVAIL;
-  case CDI_EUFSTRUCT:  return _EUFSTRUCT;
-  case CDI_EUNC4:      return _EUNC4;
-  case CDI_EDIMSIZE:   return _EDIMSIZE;
-  case CDI_ELIMIT:     return _ELIMIT;
-  }
-
-  return UnknownError;
+  else
+#  else
+    (void)largePageAlign;
+#  endif
+    {
+#  if HAVE_DECL__SC_PAGESIZE || HAVE_DECL__SC_PAGE_SIZE
+      name =
+#    if HAVE_DECL__SC_PAGESIZE
+        _SC_PAGESIZE
+#    elif HAVE_DECL__SC_PAGE_SIZE
+        _SC_PAGE_SIZE
+#    endif
+        ;
+      nameAssigned = true;
+#  endif
+    }
+  if (nameAssigned)
+    pagesize = sysconf(name);
+#endif
+  if (pagesize == -1L)
+    pagesize =
+#if HAVE_DECL_PAGESIZE
+      PAGESIZE
+#elif HAVE_DECL_PAGE_SIZE
+      PAGE_SIZE
+#else
+      commonPageSize
+#endif
+      ;
+  return (size_t)pagesize;
 }
 
+
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -5955,1271 +5658,225 @@ const char *cdiStringError(int cdiErrno)
  * require-trailing-newline: t
  * End:
  */
-#ifndef _GRIBAPI_H
-#define _GRIBAPI_H
 
-#ifdef HAVE_LIBGRIB_API
-#include <grib_api.h>
-#ifndef  ERROR_H
+/* Automatically generated by m214003 at 2016-06-03, do not edit */
+
+/* CGRIBEXLIB_VERSION="1.7.5" */
+
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5) || defined (__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#pragma GCC diagnostic ignored "-Wsign-conversion"
+#pragma GCC diagnostic warning "-Wstrict-overflow"
 #endif
+
+#ifdef _ARCH_PWR6
+#pragma options nostrict
 #endif
 
-#ifndef  _CDI_INT_H
+#if defined (HAVE_CONFIG_H)
 #endif
 
-#define  GRIBAPI_MISSVAL  -9.E33
+#include <string.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <inttypes.h>
 
-/* 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                            */
 
-const char *gribapiLibraryVersionString(void);
-void gribContainersNew(stream_t * streamptr);
-void gribContainersDelete(stream_t * streamptr);
+#ifndef _TEMPLATES_H
+#define _TEMPLATES_H
 
-#ifdef HAVE_LIBGRIB_API
-static inline void *gribHandleNew(int editionNumber)
-{
-  void *gh = (void *)grib_handle_new_from_samples(NULL, (editionNumber == 1) ? "GRIB1" : "GRIB2");
+#define CAT(X,Y)      X##_##Y
+#define TEMPLATE(X,Y) CAT(X,Y)
 
-  if ( gh == NULL ) Error("grib_handle_new_from_samples failed!");
+#endif 
+#ifndef GRIB_INT_H
+#define GRIB_INT_H
 
-  return gh;
-}
+#if defined (HAVE_CONFIG_H)
+#endif
 
-static inline 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);
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <float.h>
 
-  int ret_val = grib_set_double(h, key, val);
-  if (ret_val != 0)
-    fprintf(stderr, "!!! failed call to grib_set_double(\tgrib_handle* h, \"%s\", %f) !!!\n", key, val);
-  return ret_val;
-}
 
-static inline 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);
+#if ! defined   (_CGRIBEX_H)
+#endif
+#if ! defined   (_ERROR_H)
+#endif
+#if ! defined   (_DTYPES_H)
+#endif
 
-  int ret_val = grib_set_long(h, key, val);
-  if (ret_val != 0)
-    fprintf(stderr, "!!! failed call to grib_set_long(  \tgrib_handle* h, \"%s\", %ld) !!!\n", key, val);
-  return ret_val;
-}
+#if ! defined   (FALSE)
+#  define  FALSE  0
+#endif
 
-static inline 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);
+#if ! defined   (TRUE)
+#  define  TRUE  1
+#endif
 
-  int ret_val = grib_set_string(h, key, val, length);
-  if (ret_val != 0)
-    fprintf(stderr, "!!! grib_set_string(\tgrib_handle* h, \"%s\", \"%s\") !!!\n", key, val);
-  return ret_val;
-}
+#if ! defined   (UCHAR)
+#  define  UCHAR  unsigned char
+#endif
 
-static inline void gribHandleDelete(void *gh)
-{
-  grib_handle_delete((struct grib_handle *)gh);
-}
-#else
-#define gribHandleNew(editionNumber) (NULL)
-#define gribHandleDelete(gh)
+
+#if defined (CRAY) || defined (SX) || defined (__uxpch__)
+#  define VECTORCODE
 #endif
 
-typedef struct {
-  bool init;
-  void *gribHandle;
-}
-gribContainer_t;
 
-#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 CGRIBEX_H
-#define CGRIBEX_H
+#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
 
-#include <stdio.h>
-#include <stdbool.h>
-#include <sys/types.h>
+#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])
 
-#define  GRIB_MISSVAL  -9.E33
+#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
 
-/* 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_ISOBARIC_PA         210
-#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                                          */
+#ifndef IS_EQUAL
+#  define IS_NOT_EQUAL(x,y) (x < y || y < x)
+#  define IS_EQUAL(x,y)     (!IS_NOT_EQUAL(x,y))
+#endif
 
-/* 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                                   */
+/* dummy use of unused parameters to silence compiler warnings */
+#ifndef UNUSED
+#  define  UNUSED(x) (void)(x)
+#endif
 
-/*
- *  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                               */
+#define  JP23SET    0x7FFFFF  /* 2**23 - 1 (---> 8388607)  */
 
+#define  POW_2_M24  0.000000059604644775390625  /*  pow(2.0, -24.0) */
 
-/*
- *  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
+#ifdef __cplusplus
+extern "C" {
+#endif
 
+#define intpow2(x) (ldexp(1.0, (x)))
 
-#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    */
+int gribrec_len(unsigned b1, unsigned b2, unsigned b3);
+int correct_bdslen(int bdslen, long recsize, long gribpos);
 
-#define  ISEC1_ECMWF_LocalExtension (isec1[36])
-#define  ISEC1_ECMWF_Class          (isec1[37])
+/* CDI converter routines */
 
+/* param format:  DDDCCCNNN */
 
-/*
- *  Macros for the grid definition section ( Section 2 )
- */
-#define  ISEC2_GridType             (isec2[ 0])  /* Data representation type */
+void    cdiDecodeParam(int param, int *dis, int *cat, int *num);
+int     cdiEncodeParam(int dis, int cat, int num);
 
-/* Triangular grids */
+/* date format:  YYYYMMDD */
+/* time format:  hhmmss   */
 
-#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)          */
+void    cdiDecodeDate(int date, int *year, int *month, int *day);
+int     cdiEncodeDate(int year, int month, int day);
 
-/* Spherical harmonic coeficients */
+void    cdiDecodeTime(int time, int *hour, int *minute, int *second);
+int     cdiEncodeTime(int hour, int minute, int second);
 
-#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                          */
+/* CALENDAR types */
 
-/* Gaussian grids */
+#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
 
-#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     */
+extern FILE *grprsm;
 
-/* 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               */
+extern int  CGRIBEX_Debug;
 
+void   gprintf(const char *caller, const char *fmt, ...);
 
-#define  ISEC2_Reduced              (isec2[16])  /* 0: regular, 1: reduced grid                   */
+void   grsdef(void);
 
-#define  ISEC2_RowLonPtr            (&isec2[22])
-#define  ISEC2_RowLon(i)            (isec2[22+i]) /* Number of points along each parallel         */
+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);
 
-/* */
+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, size_t pcStart, size_t trunc, size_t nsp);
+void   gather_complex_float(float *fpdata, size_t pcStart, size_t trunc, size_t nsp);
 
-#define  ISEC2_LatSP                (isec2[12])  /* Latitude of the southern pole of rotation     */
-#define  ISEC2_LonSP                (isec2[13])  /* Longitude of the southern pole of rotation    */
+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);
 
-#define  FSEC2_RotAngle             (fsec2[ 0])  /* Angle of rotation                             */
-#define  FSEC2_StrFact              (fsec2[ 1])  /* Stretching factor                             */
+#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);
 
-/*
- *  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                 */
+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);
 
-/*
- *  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                  */
+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);
 
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+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 defined (__cplusplus)
+}
+#endif
 
-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);
+#endif  /* GRIB_INT_H */
+#ifndef _GRIBDECODE_H
+#define _GRIBDECODE_H
 
-
-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, const 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, const 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);
-bool  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(size_t recsize, unsigned char *gribbuffer, size_t *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);
-size_t gribGetSize(int fileID);
-int   gribCheckSeek(int fileID, long *offset, int *version);
-int   gribFileSeek(int fileID, long *offset);
-size_t 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_float(const float* spectralField, long fieldTruncation, long subsetTruncation);
-double calculate_pfactor_double(const double* spectralField, long fieldTruncation, long subsetTruncation);
-
-
-#if defined (__cplusplus)
-}
-#endif
-
-#endif  /* CGRIBEX_H */ 
-
-#if defined (HAVE_CONFIG_H)
-#endif
-
-#include <stdarg.h>
-#include <ctype.h>
-
-#ifdef HAVE_LIBNETCDF
-#endif
-
-#if  defined  (HAVE_LIBCGRIBEX)
-#endif
-
-int cdiDefaultCalendar = CALENDAR_PROLEPTIC;
-
-int cdiDefaultInstID   = CDI_UNDEFID;
-int cdiDefaultModelID  = CDI_UNDEFID;
-int cdiDefaultTableID  = CDI_UNDEFID;
-//int cdiNcMissingValue  = CDI_UNDEFID;
-int cdiNcChunksizehint = CDI_UNDEFID;
-int cdiChunkType       = CDI_CHUNK_GRID;
-int cdiSplitLtype105   = CDI_UNDEFID;
-
-bool cdiIgnoreAttCoordinates = false;
-bool cdiCoordinatesLonLat    = false;
-bool cdiIgnoreValidRange     = false;
-int cdiSkipRecords          = 0;
-int cdiConvention           = CDI_CONVENTION_ECHAM;
-int cdiInventoryMode        = 1;
-int CDI_Version_Info        = 1;
-int CDI_cmor_mode           = 0;
-size_t CDI_netcdf_hdr_pad   = 0UL;
-bool CDI_netcdf_lazy_grid_load = false;
-
-char *cdiPartabPath   = NULL;
-int   cdiPartabIntern = 1;
-
-double cdiDefaultMissval = -9.E33;
-
-static const char Filetypes[][9] = {
-  "UNKNOWN",
-  "GRIB",
-  "GRIB2",
-  "NetCDF",
-  "NetCDF2",
-  "NetCDF4",
-  "NetCDF4c",
-  "SERVICE",
-  "EXTRA",
-  "IEG",
-  "HDF5",
-};
-
-int CDI_Debug   = 0;    /* If set to 1, debugging           */
-int CDI_Recopt = 0;
-
-int cdiGribApiDebug     = 0;
-int cdiDefaultLeveltype = -1;
-int cdiDataUnreduced = 0;
-int cdiSortName = 0;
-int cdiSortParam = 0;
-int cdiHaveMissval = 0;
-
-
-static long cdiGetenvInt(const char *envName)
-{
-  char *envString;
-  long envValue = -1;
-  long fact = 1;
-
-  envString = getenv(envName);
-
-  if ( envString )
-    {
-      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);
-    }
-
-  return (envValue);
-}
-
-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);
-}
-
-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_NC4HDF5)
-  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());
-}
-
-static void cdiPrintDatatypes(void)
-{
-#define XSTRING(x)	#x
-#define STRING(x)	XSTRING(x)
-  fprintf (stderr, "+-------------+-------+\n"
-           "| types       | bytes |\n"
-           "+-------------+-------+\n"
-           "| void *      |   %3d |\n"
-           "+-------------+-------+\n"
-           "| char        |   %3d |\n"
-           "+-------------+-------+\n"
-           "| bool        |   %3d |\n"
-           "| short       |   %3d |\n"
-           "| int         |   %3d |\n"
-           "| long        |   %3d |\n"
-           "| long long   |   %3d |\n"
-           "| size_t      |   %3d |\n"
-           "| off_t       |   %3d |\n"
-           "+-------------+-------+\n"
-           "| float       |   %3d |\n"
-           "| double      |   %3d |\n"
-           "| long double |   %3d |\n"
-           "+-------------+-------+\n\n"
-           "+-------------+-----------+\n"
-           "| INT32       | %-9s |\n"
-           "| INT64       | %-9s |\n"
-           "| FLT32       | %-9s |\n"
-           "| FLT64       | %-9s |\n"
-           "+-------------+-----------+\n"
-           "\n  byte ordering is %s\n\n",
-           (int) sizeof(void *), (int) sizeof(char), (int) sizeof(bool),
-           (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(long long),
-           (int) sizeof(size_t), (int) sizeof(off_t),
-           (int) sizeof(float), (int) sizeof(double), (int) sizeof(long double),
-           STRING(INT32), STRING(INT64), STRING(FLT32), STRING(FLT64),
-           ((HOST_ENDIANNESS == CDI_BIGENDIAN) ? "BIGENDIAN"
-            : ((HOST_ENDIANNESS == CDI_LITTLEENDIAN) ? "LITTLEENDIAN"
-               : "Unhandled endianness!")));
-#undef STRING
-#undef XSTRING
-}
-
-void cdiDebug(int level)
-{
-  if ( level == 1 || (level &  2) ) CDI_Debug = 1;
-
-  if ( CDI_Debug ) Message("debug level %d", level);
-
-  if ( level == 1 || (level &  4) ) memDebug(1);
-
-  if ( level == 1 || (level &  8) ) fileDebug(1);
-
-  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
-    }
-
-  if ( CDI_Debug )
-    {
-      cdiPrintDefaults();
-      cdiPrintDatatypes();
-    }
-}
-
-
-int cdiHaveFiletype(int filetype)
-{
-  int status = 0;
-
-  switch (filetype)
-    {
-#if  defined  (HAVE_LIBSERVICE)
-    case CDI_FILETYPE_SRV:  { status = 1; break; }
-#endif
-#if  defined  (HAVE_LIBEXTRA)
-    case CDI_FILETYPE_EXT:  { status = 1; break; }
-#endif
-#if  defined  (HAVE_LIBIEG)
-    case CDI_FILETYPE_IEG:  { status = 1; break; }
-#endif
-#if  defined  (HAVE_LIBGRIB)
-#if  defined  (HAVE_LIBGRIB_API) || defined  (HAVE_LIBCGRIBEX)
-    case CDI_FILETYPE_GRB:  { status = 1; break; }
-#endif
-#if  defined  (HAVE_LIBGRIB_API)
-    case CDI_FILETYPE_GRB2: { status = 1; break; }
-#endif
-#endif
-#if  defined  (HAVE_LIBNETCDF)
-    case CDI_FILETYPE_NC:   { status = 1; break; }
-#if  defined  (HAVE_NETCDF2)
-    case CDI_FILETYPE_NC2:  { status = 1; break; }
-#endif
-#if  defined  (HAVE_NETCDF4)
-    case CDI_FILETYPE_NC4:  { status = 1; break; }
-    case CDI_FILETYPE_NC4C: { status = 1; break; }
-#endif
-#endif
-    default: { status = 0; break; }
-    }
-
-  return (status);
-}
-
-void cdiDefTableID(int tableID)
-{
-  cdiDefaultTableID = tableID;
-  int modelID = cdiDefaultModelID = tableInqModel(tableID);
-  cdiDefaultInstID = modelInqInstitut(modelID);
-}
-
-static
-void cdiSetChunk(const char *chunkAlgo)
-{
-  //char *pch;
-  //size_t len = strlen(chunkAlgo);
-  int algo = -1;
-
-  if      ( strcmp("auto",  chunkAlgo)   == 0 ) algo = CDI_CHUNK_AUTO;
-  else if ( strcmp("grid",  chunkAlgo)   == 0 ) algo = CDI_CHUNK_GRID;
-  else if ( strcmp("lines", chunkAlgo)   == 0 ) algo = CDI_CHUNK_LINES;
-  /*
-  else if ( (pch = strstr(chunkAlgo,"x")) != 0 )
-    {
-      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);
-    }
-  */
-  else
-    Warning("Invalid environment variable CDI_CHUNK_ALGO: %s", chunkAlgo);
-
-  if ( algo != -1 )
-    {
-      cdiChunkType = algo;
-      if ( CDI_Debug ) Message("set ChunkAlgo to %s", chunkAlgo);
-    }
-}
-
-
-void cdiInitialize(void)
-{
-  static bool Init_CDI = false;
-
-  if ( ! Init_CDI )
-    {
-      Init_CDI = true;
-      char *envstr;
-      long value;
-
-#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
-
-      value = cdiGetenvInt("CDI_DEBUG");
-      if ( value >= 0 ) CDI_Debug = (int) value;
-
-      value = cdiGetenvInt("CDI_GRIBAPI_DEBUG");
-      if ( value >= 0 ) cdiGribApiDebug = (int) value;
-
-      value = cdiGetenvInt("CDI_RECOPT");
-      if ( value >= 0 ) CDI_Recopt = (int) value;
-
-      value = cdiGetenvInt("CDI_REGULARGRID");
-      if ( value >= 0 ) cdiDataUnreduced = (int) value;
-
-      value = cdiGetenvInt("CDI_SORTNAME");
-      if ( value >= 0 ) cdiSortName = (int) value;
-
-      value = cdiGetenvInt("CDI_SORTPARAM");
-      if ( value >= 0 ) cdiSortParam = (int) value;
-
-      value = cdiGetenvInt("CDI_HAVE_MISSVAL");
-      if ( value >= 0 ) cdiHaveMissval = (int) value;
-
-      value = cdiGetenvInt("CDI_LEVELTYPE");
-      if ( value >= 0 ) cdiDefaultLeveltype = (int) value;
-
-      value = cdiGetenvInt("CDI_NETCDF_HDR_PAD");
-      if ( value >= 0 ) CDI_netcdf_hdr_pad = (size_t) value;
-
-      envstr = getenv("CDI_MISSVAL");
-      if ( envstr ) cdiDefaultMissval = atof(envstr);
-      /*
-      envstr = getenv("NC_MISSING_VALUE");
-      if ( envstr ) cdiNcMissingValue = atoi(envstr);
-      */
-      envstr = getenv("NC_CHUNKSIZEHINT");
-      if ( envstr ) cdiNcChunksizehint = atoi(envstr);
-
-      envstr = getenv("CDI_CHUNK_ALGO");
-      if ( envstr ) cdiSetChunk(envstr);
-
-      envstr = getenv("SPLIT_LTYPE_105");
-      if ( envstr ) cdiSplitLtype105 = atoi(envstr);
-
-      envstr = getenv("IGNORE_ATT_COORDINATES");
-      if ( envstr ) cdiIgnoreAttCoordinates = atoi(envstr) > 0;
-
-      envstr = getenv("CDI_COORDINATES_LONLAT");
-      if ( envstr ) cdiCoordinatesLonLat = atoi(envstr) > 0;
-
-      envstr = getenv("IGNORE_VALID_RANGE");
-      if ( envstr ) cdiIgnoreValidRange = atoi(envstr) > 0;
-
-      envstr = getenv("CDI_SKIP_RECORDS");
-      if ( envstr )
-	{
-	  cdiSkipRecords = atoi(envstr);
-	  cdiSkipRecords = cdiSkipRecords > 0 ? cdiSkipRecords : 0;
-	}
-
-      envstr = getenv("CDI_CONVENTION");
-      if ( envstr )
-	{
-	  if ( strcmp(envstr, "CF") == 0 || strcmp(envstr, "cf") == 0 )
-	    {
-	      cdiConvention = CDI_CONVENTION_CF;
-	      if ( CDI_Debug )
-		Message("CDI convention was set to CF!");
-	    }
-	}
-
-      envstr = getenv("CDI_INVENTORY_MODE");
-      if ( envstr )
-	{
-	  if ( strncmp(envstr, "time", 4) == 0 )
-	    {
-	      cdiInventoryMode = 2;
-	      if ( CDI_Debug )
-		Message("Inventory mode was set to timestep!");
-	    }
-	}
-
-      envstr = getenv("CDI_VERSION_INFO");
-      if ( envstr )
-        {
-          int ival = atoi(envstr);
-          if ( ival == 0 || ival == 1 )
-            {
-              CDI_Version_Info = ival;
-              if ( CDI_Debug )
-                Message("CDI_Version_Info = %s", envstr);
-            }
-        }
-
-
-      envstr = getenv("CDI_CALENDAR");
-      if ( envstr )
-	{
-	  if      ( strncmp(envstr, "standard", 8) == 0 )
-	    cdiDefaultCalendar = CALENDAR_STANDARD;
-	  else if ( strncmp(envstr, "proleptic", 9) == 0 )
-	    cdiDefaultCalendar = CALENDAR_PROLEPTIC;
-	  else if ( strncmp(envstr, "360days", 7) == 0 )
-	    cdiDefaultCalendar = CALENDAR_360DAYS;
-	  else if ( strncmp(envstr, "365days", 7) == 0 )
-	    cdiDefaultCalendar = CALENDAR_365DAYS;
-	  else if ( strncmp(envstr, "366days", 7) == 0 )
-	    cdiDefaultCalendar = CALENDAR_366DAYS;
-	  else if ( strncmp(envstr, "none", 4) == 0 )
-	    cdiDefaultCalendar = CALENDAR_NONE;
-
-	  if ( CDI_Debug )
-	    Message("Default calendar set to %s!", envstr);
-	}
-#if  defined  (HAVE_LIBCGRIBEX)
-      gribSetCalendar(cdiDefaultCalendar);
-#endif
-
-      envstr = getenv("PARTAB_INTERN");
-      if ( envstr ) cdiPartabIntern = atoi(envstr);
-
-      envstr = getenv("PARTAB_PATH");
-      if ( envstr ) cdiPartabPath = strdup(envstr);
-    }
-}
-
-
-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, "SORTPARAM")        == 0 ) cdiSortParam = val;
-  else if ( strcmp(string, "HAVE_MISSVAL")     == 0 ) cdiHaveMissval = val;
-  else if ( strcmp(string, "NC_CHUNKSIZEHINT") == 0 ) cdiNcChunksizehint = val;
-  else if ( strcmp(string, "CMOR_MODE")        == 0 ) CDI_cmor_mode = val;
-  else if ( strcmp(string, "NETCDF_HDR_PAD")   == 0 ) CDI_netcdf_hdr_pad = (size_t) val;
-  else if ( strcmp(string, "NETCDF_LAZY_GRID_LOAD") == 0)
-    CDI_netcdf_lazy_grid_load = (bool)val;
-  else Warning("Unsupported global key: %s", string);
-}
-
-
-void cdiDefMissval(double missval)
-{
-  cdiInitialize();
-
-  cdiDefaultMissval = missval;
-}
-
-
-double cdiInqMissval(void)
-{
-  cdiInitialize();
-
-  return (cdiDefaultMissval);
-}
-
-/*
- * 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 <unistd.h>
-
-
-void cdiDecodeParam(int param, int *pnum, int *pcat, int *pdis)
-{
-  unsigned uparam = (unsigned)param;
-  unsigned upnum;
-
-  *pdis = 0xff   & uparam;
-  *pcat = 0xff   & uparam >> 8;
-  upnum = 0xffff & uparam >> 16;
-  if ( upnum > 0x7fffU ) upnum = 0x8000U - upnum;
-  *pnum = (int)upnum;
-}
-
-
-int cdiEncodeParam(int pnum, int pcat, int pdis)
-{
-  unsigned uparam, upnum;
-
-  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 cdiDecodeDate(int date, int *year, int *month, int *day)
-{
-
-  int iyear = date / 10000;
-  *year = iyear;
-  int idate = abs(date - iyear * 10000),
-    imonth = idate / 100;
-  *month = imonth;
-  *day   = idate - imonth * 100;
-}
-
-
-int cdiEncodeDate(int year, int month, int day)
-{
-  int iyear = abs(year),
-    date = iyear * 10000 + month * 100 + day;
-  if ( year < 0 ) date = -date;
-  return (date);
-}
-
-
-void cdiDecodeTime(int time, int *hour, int *minute, int *second)
-{
-  int ihour = time / 10000,
-    itime = time - ihour * 10000,
-    iminute = itime / 100;
-  *hour   = ihour;
-  *minute = iminute;
-  *second = itime - iminute * 100;
-}
-
-
-int cdiEncodeTime(int hour, int minute, int second)
-{
-  int time = hour*10000 + minute*100 + second;
-
-  return time;
-}
-
-
-void cdiParamToString(int param, char *paramstr, int maxlen)
-{
-  int dis, cat, num;
-  int len;
-
-  cdiDecodeParam(param, &num, &cat, &dis);
-
-  size_t umaxlen = maxlen >= 0 ? (unsigned)maxlen : 0U;
-  if ( dis == 255 && (cat == 255 || cat == 0 ) )
-    len = snprintf(paramstr, umaxlen, "%d", num);
-  else  if ( dis == 255 )
-    len = snprintf(paramstr, umaxlen, "%d.%d", num, cat);
-  else
-    len = snprintf(paramstr, umaxlen, "%d.%d.%d", num, cat, dis);
-
-  if ( len >= maxlen || len < 0)
-    fprintf(stderr, "Internal problem (%s): size of input string is too small!\n", __func__);
-}
-
-
-const char *cdiUnitNamePtr(int cdi_unit)
-{
-  const char *cdiUnits[] = {
-    /*  0 */  "undefined",
-    /*  1 */  "Pa",
-    /*  2 */  "hPa",
-    /*  3 */  "mm",
-    /*  4 */  "cm",
-    /*  5 */  "dm",
-    /*  6 */  "m",
-  };
-  enum { numUnits = (int) (sizeof(cdiUnits)/sizeof(char *)) };
-  const char *name = ( cdi_unit > 0 && cdi_unit < numUnits ) ?
-    cdiUnits[cdi_unit] : NULL;
-  return name;
-}
-
-size_t
-cdiGetPageSize(bool largePageAlign)
-{
-  long pagesize = -1L;
-#if HAVE_DECL__SC_LARGE_PAGESIZE || HAVE_DECL__SC_PAGE_SIZE || HAVE_DECL__SC_PAGESIZE
-  bool nameAssigned = false;
-  int name;
-#  if HAVE_DECL__SC_LARGE_PAGESIZE
-  if (largePageAlign)
-    {
-      name = _SC_LARGE_PAGESIZE;
-      nameAssigned = true;
-    }
-  else
-#  else
-    (void)largePageAlign;
-#  endif
-    {
-#  if HAVE_DECL__SC_PAGESIZE || HAVE_DECL__SC_PAGE_SIZE
-      name =
-#    if HAVE_DECL__SC_PAGESIZE
-        _SC_PAGESIZE
-#    elif HAVE_DECL__SC_PAGE_SIZE
-        _SC_PAGE_SIZE
-#    endif
-        ;
-      nameAssigned = true;
-#  endif
-    }
-  if (nameAssigned)
-    pagesize = sysconf(name);
-#endif
-  if (pagesize == -1L)
-    pagesize =
-#if HAVE_DECL_PAGESIZE
-      PAGESIZE
-#elif HAVE_DECL_PAGE_SIZE
-      PAGE_SIZE
-#else
-      commonPageSize
-#endif
-      ;
-  return (size_t)pagesize;
-}
-
-
-/*
- * 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 2017-06-06, do not edit */
-
-/* CGRIBEXLIB_VERSION="1.8.1" */
-
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5) || defined (__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wconversion"
-#pragma GCC diagnostic ignored "-Wsign-conversion"
-#pragma GCC diagnostic warning "-Wstrict-overflow"
-#endif
-
-#ifdef _ARCH_PWR6
-#pragma options nostrict
-#endif
-
-#if defined (HAVE_CONFIG_H)
-#endif
-
-#include <string.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <sys/types.h>
-#include <inttypes.h>
-
-
-
-#ifndef CGRIBEX_TEMPLATES_H
-#define CGRIBEX_TEMPLATES_H
-
-#define CAT(X,Y)      X##_##Y
-#define TEMPLATE(X,Y) CAT(X,Y)
-
-#endif 
-#ifndef GRIB_INT_H
-#define GRIB_INT_H
-
-#if defined (HAVE_CONFIG_H)
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <math.h>
-#include <float.h>
-
-
-#if ! defined   (CGRIBEX_H)
-#endif
-#if ! defined   (ERROR_H)
-#endif
-#if ! defined   (DTYPES_H)
-#endif
-
-
-#if ! defined   (UCHAR)
-#  define  UCHAR  unsigned char
-#endif
-
-
-#if defined (CRAY) || defined (SX) || defined (__uxpch__)
-#  define VECTORCODE
-#endif
-
-
-#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
-
-#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])
-
-#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 IS_EQUAL
-#  define IS_NOT_EQUAL(x,y) (x < y || y < x)
-#  define IS_EQUAL(x,y)     (!IS_NOT_EQUAL(x,y))
-#endif
-
-/* dummy use of unused parameters to silence compiler warnings */
-#ifndef UNUSED
-#  define  UNUSED(x) (void)(x)
-#endif
-
-#define  JP23SET    0x7FFFFF  /* 2**23 - 1 (---> 8388607)  */
-
-#define  POW_2_M24  0.000000059604644775390625  /*  pow(2.0, -24.0) */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define intpow2(x) (ldexp(1.0, (x)))
-
-int gribrec_len(unsigned b1, unsigned b2, unsigned b3);
-int correct_bdslen(int bdslen, long recsize, long gribpos);
-
-/* CDI converter routines */
-
-/* param format:  DDDCCCNNN */
-
-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);
-
-/* 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
-
-extern FILE *grprsm;
-
-extern int  CGRIBEX_Debug;
-
-void   gprintf(const char *caller, const char *fmt, ...);
-
-void   grsdef(void);
-
-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);
-
-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, size_t pcStart, size_t trunc, size_t nsp);
-void   gather_complex_float(float *fpdata, size_t pcStart, size_t trunc, size_t nsp);
-
-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  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);
-
-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);
-
-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 defined (__cplusplus)
-}
-#endif
-
-#endif  /* GRIB_INT_H */
-#ifndef GRIBDECODE_H
-#define GRIBDECODE_H
-
-#define  UNDEFINED          9.999e20
+#define  UNDEFINED          9.999e20
 
 
 #define  GET_INT3(a,b,c)    ((1-(int) ((unsigned) (a & 128) >> 6)) * (int) (((a & 127) << 16)+(b<<8)+c))
@@ -7356,9 +6013,9 @@ int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **i
 #define  GRIB2_SECLEN(section)   (GET_UINT4(section[0], section[1], section[2], section[3]))
 #define  GRIB2_SECNUM(section)   (GET_UINT1(section[4]))
 
-#endif  /* GRIBDECODE_H */
-#ifndef CGRIBEX_GRIB_ENCODE_H
-#define CGRIBEX_GRIB_ENCODE_H
+#endif  /* _GRIBDECODE_H */
+#ifndef _GRIB_ENCODE_H
+#define _GRIB_ENCODE_H
 
 #include <limits.h>
 
@@ -7395,7 +6052,7 @@ enum {
   Put3Byte(mantissa);            \
 }
 
-#endif  /* CGRIBEX_GRIB_ENCODE_H */
+#endif  /* _GRIB_ENCODE_H */
 #ifndef CODEC_COMMON_H
 #define CODEC_COMMON_H
 #define gribSwapByteOrder_uint16(ui16)  ((uint16_t)((ui16<<8) | (ui16>>8)))
@@ -8166,7 +6823,6 @@ xlc_r -g -O3 -qhot -q64 -qarch=auto -qtune=auto -qreport -DTEST_ENCODE encode_ar
 #endif
 
 #include <stdint.h>
-#include <math.h>
 
 #ifndef DISABLE_SIMD
 #if   defined(__GNUC__) && (__GNUC__ >= 4)
@@ -8936,6 +7592,7 @@ LABEL900:
 
   return (pval);
 } /* decfp2 */
+#include <stdio.h>
 #include <stdint.h>
 #include <string.h>
 #include <stdarg.h>
@@ -8944,11 +7601,14 @@ LABEL900:
 
 int gribRefDate(int *isec1)
 {
-  int century = ISEC1_Century;
+  int date, ryear, rmonth, rday;
+  int century;
+
+  century = ISEC1_Century;
   if ( century < 0 ) century = -century;
   century -= 1;
 
-  int ryear   = ISEC1_Year;
+  ryear   = ISEC1_Year;
 
   /* if ( century != 0 ) */
     {
@@ -8967,44 +7627,50 @@ int gribRefDate(int *isec1)
 	ryear = 1;
     }
 
-  int rmonth  = ISEC1_Month;
-  int rday    = ISEC1_Day;
+  rmonth  = ISEC1_Month;
+  rday    = ISEC1_Day;
 
-  int date = cdiEncodeDate(ryear, rmonth, rday);
+  date = cdiEncodeDate(ryear, rmonth, rday);
 
-  return date ;
+  return (date) ;
 }
 
 
 int gribRefTime(int *isec1)
 {
-  int rhour   = ISEC1_Hour;
-  int rminute = ISEC1_Minute;
+  int time, rhour, rminute;
 
-  int time = cdiEncodeTime(rhour, rminute, 0);
+  rhour   = ISEC1_Hour;
+  rminute = ISEC1_Minute;
 
-  return time;
+  time = cdiEncodeTime(rhour, rminute, 0);
+
+  return (time) ;
 }
 
 
-bool gribTimeIsFC(int *isec1)
+int gribTimeIsFC(int *isec1)
 {
-  bool isFC = false;
+  int isFC = FALSE;
+  int time_period;
 
-  int time_period =  (ISEC1_TimeRange == 10) ? (ISEC1_TimePeriod1<<8) + ISEC1_TimePeriod2 : ISEC1_TimePeriod1;
+  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;
+      if ( ISEC1_TimeRange == 0 || ISEC1_TimeRange == 10 ) isFC = TRUE;
     }
 
-  return isFC;
+  return (isFC);
 }
 
 
 void gribDateTime(int *isec1, int *date, int *time)
 {
-  static bool lprint = true;
+  static int lprint = TRUE;
   int julday, secofday;
   int64_t addsec = 0;
   int64_t time_period = 0;
@@ -9076,7 +7742,7 @@ void gribDateTime(int *isec1, int *date, int *time)
 	  if ( lprint )
 	    {
 	      gprintf(__func__, "Time unit %d unsupported", ISEC1_TimeUnit);
-	      lprint = false;
+	      lprint = FALSE;
 	    }
 	  break;
 	}
@@ -10940,10 +9606,8 @@ read3ByteMSBFirst(void *fileptr)
   return (int)((b1 << 16) + (b2 << 8) + b3);
 }
 
-
-size_t gribReadSize(int fileID)
+int gribReadSize(int fileID)
 {
-  size_t rgribsize = 0;
   void *fileptr = filePtr(fileID);
   off_t pos = fileGetPos(fileID); 
 
@@ -10994,7 +9658,6 @@ size_t gribReadSize(int fileID)
       if ( CGRIBEX_Debug ) Message("bdssize     = %d", bdssize);
 
       gribsize = issize + pdssize + gdssize + bmssize + bdssize + essize;
-      rgribsize = (size_t) gribsize;
     }
   else if ( gribversion == 1 )
     {
@@ -11030,50 +9693,51 @@ size_t gribReadSize(int fileID)
 	  bdssize = correct_bdslen(bdssize, gribsize, issize+pdssize+gdssize+bmssize);
 	  if ( CGRIBEX_Debug ) Message("bdssize     = %d", bdssize);
 
-	  gribsize = issize + pdssize + gdssize + bmssize + bdssize + essize;
+	  gribsize = issize+pdssize+gdssize+bmssize+bdssize+essize;
 	}
-      rgribsize = (size_t) gribsize;
     }
   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 */
-      rgribsize = 0;
-      for ( int i = 0; i < 8; i++ ) rgribsize = (rgribsize << 8) | filePtrGetc(fileptr);
+      gribsize = 0;
+      for ( i = 0; i < 8; i++ ) gribsize = (gribsize << 8) | filePtrGetc(fileptr);
     }
   else
     {
-      rgribsize = 0;
+      gribsize = 0;
       Warning("GRIB version %d unsupported!", gribversion);
     }
 
-  if ( filePtrEOF(fileptr) ) rgribsize = 0;
+  if ( filePtrEOF(fileptr) ) gribsize = 0;
 
-  if ( CGRIBEX_Debug ) Message("gribsize = %zu", rgribsize);
+  if ( CGRIBEX_Debug )
+    Message("gribsize    = %d", gribsize);
 
   fileSetPos(fileID, pos, SEEK_SET);
 
-  return rgribsize;
+  return gribsize;
 }
 
 
-size_t gribGetSize(int fileID)
+int gribGetSize(int fileID)
 {
   long offset;
   int ierr = gribFileSeek(fileID, &offset); /* position file pointer after GRIB */
   if ( ierr > 0 )
     {
       Warning("GRIB record not found!");
-      return 0;
+      return (0);
     }
 
   if      ( ierr == -1 ) return 0;
   else if ( ierr ==  1 ) return 0;
 
-  size_t recSize = gribReadSize(fileID);
+  int recSize = gribReadSize(fileID);
 
-  if ( CGRIBEX_Debug ) Message("recsize = %zu", recSize);
+  if ( CGRIBEX_Debug ) Message("recsize = %d", recSize);
 
   fileSetPos(fileID, (off_t) -4, SEEK_CUR);
 
@@ -11094,7 +9758,7 @@ int gribRead(int fileID, unsigned char *buffer, size_t *buffersize)
   if      ( ierr == -1 ) { *buffersize = 0; return -1; }
   else if ( ierr ==  1 ) { *buffersize = 0; return -2; }
 
-  size_t recSize  = gribReadSize(fileID);
+  size_t recSize  = (size_t)gribReadSize(fileID);
   size_t readSize = recSize;
 
   if ( readSize > *buffersize )
@@ -11152,6 +9816,7 @@ int gribrec_len(unsigned b1, unsigned b2, unsigned b3)
   return gribsize;
 }
 
+#include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
 
@@ -11250,7 +9915,7 @@ C     ----------------------------------------------------------------
   */
   char *envString;
   char *env_stream;
-  static bool lfirst = true;
+  static int lfirst = TRUE;
   extern int CGRIBEX_Const;
 
   if ( ! lfirst ) return;
@@ -11392,7 +10057,7 @@ C     ----------------------------------------------------------------
   /*
     Mark common area values set by user.
   */
-  lfirst = false;
+  lfirst = FALSE;
   /*
     Exhaustive use of all possible second-order packing methods
     for HOPER='K'. Set to off.
@@ -12024,7 +10689,7 @@ int correct_bdslen(int bdslen, long recsize, long gribpos)
     the (default) rounding for GRIB products is 120 bytes.
   */
   if ( recsize > JP23SET ) bdslen = (int)(recsize - gribpos - bdslen);
-  return bdslen;
+  return (bdslen);
 }
 
 
@@ -12049,7 +10714,7 @@ int grib1Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **p
     {
       fprintf(stderr, "Wrong GRIB indicator section: found >%c%c%c%c<\n",
 	      section[0], section[1], section[2], section[3]);
-      return -1;
+      return (-1);
     }
 
   recsize = gribrec_len(section[4], section[5], section[6]);
@@ -12105,7 +10770,7 @@ int grib1Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **p
   if ( gribbufsize < gribsize )
     {
       fprintf(stderr, "Length of GRIB message is inconsistent (grib_buffer_size=%ld < grib_record_size=%ld)!\n", gribbufsize, gribsize);
-      return 1;
+      return (1);
     }
 
   /* end section - "7777" in ascii */
@@ -12113,10 +10778,10 @@ int grib1Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **p
     {
       fprintf(stderr, "Missing GRIB end section: found >%c%c%c%c<\n",
 	      bufpointer[0], bufpointer[1], bufpointer[2], bufpointer[3]);
-      return -2;
+      return (-2);
     }
 
-  return 0;
+  return (0);
 }
 
 
@@ -12149,14 +10814,14 @@ int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **i
     {
       fprintf(stderr, "wrong indicator section >%c%c%c%c<\n",
 	      section[0], section[1], section[2], section[3]);
-      return -1;
+      return (-1);
     }
 
   gribversion = GRIB_EDITION(section);
   if ( gribversion != 2 )
     {
       fprintf(stderr, "wrong GRIB version %d\n", gribversion);
-      return -1;      
+      return (-1);      
     }
 
   gribsize = 0;
@@ -12173,7 +10838,7 @@ int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **i
   if ( sec_num != 1 )
     {
       fprintf(stderr, "Unexpected section1 number %d\n", sec_num);
-      return -1;
+      return (-1);
     }
 
   *idsp = section;
@@ -12207,7 +10872,7 @@ int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **i
   else
     {
       fprintf(stderr, "Unexpected section3 number %d\n", sec_num);
-      return -1;
+      return (-1);
     }
 
   grib_len += sec_len;
@@ -12221,7 +10886,7 @@ int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **i
   if ( sec_num != 4 )
     {
       fprintf(stderr, "Unexpected section4 number %d\n", sec_num);
-      return -1;
+      return (-1);
     }
 
   *pdsp = section;
@@ -12237,7 +10902,7 @@ int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **i
   if ( sec_num != 5 )
     {
       fprintf(stderr, "Unexpected section5 number %d\n", sec_num);
-      return -1;
+      return (-1);
     }
 
   *drsp = section;
@@ -12253,7 +10918,7 @@ int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **i
   if ( sec_num != 6 )
     {
       fprintf(stderr, "Unexpected section6 number %d\n", sec_num);
-      return -1;
+      return (-1);
     }
 
   *bmsp = section;
@@ -12269,7 +10934,7 @@ int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **i
   if ( sec_num != 7 )
     {
       fprintf(stderr, "Unexpected section7 number %d\n", sec_num);
-      return -1;
+      return (-1);
     }
 
   *bdsp = section;
@@ -12300,10 +10965,10 @@ int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **i
     {
       fprintf(stderr, "Missing end section >%2x %2x %2x %2x<\n",
 	      section[0], section[1], section[2], section[3]);
-      return -2;
+      return (-2);
     }
 
-  return 0;
+  return (0);
 }
 
 
@@ -12324,7 +10989,7 @@ int grib_info_for_grads(off_t recpos, long recsize, unsigned char *gribbuffer,
     {
       fprintf(stderr, "wrong indicator section >%c%c%c%c<\n",
 	      section[0], section[1], section[2], section[3]);
-      return -1;
+      return (-1);
     }
 
   gribversion = GRIB_EDITION(section);
@@ -12377,7 +11042,7 @@ int grib_info_for_grads(off_t recpos, long recsize, unsigned char *gribbuffer,
   if ( gribsize > recsize )
     {
       fprintf(stderr, "GRIB buffer size %ld too small! Min size = %ld\n", recsize, gribsize);
-      return 1;
+      return (1);
     }
 
   /* end section - "7777" in ascii */
@@ -12405,7 +11070,7 @@ int grib_info_for_grads(off_t recpos, long recsize, unsigned char *gribbuffer,
   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;
+  return (0);
 }
 
 
@@ -12921,7 +11586,7 @@ void repair1(unsigned char *gbuf, long gbufsize)
   int bds_head = 11;
   int bds_ext = 0, bds_ubits;
   int datstart = 0;
-  // bool llarge = false;
+  /* int llarge = FALSE; */
 
   long gribrecsize;
   nerr = grib1Sections(gbuf, gbufsize, &pds, &gds, &bms, &bds, &gribrecsize);
@@ -12938,7 +11603,7 @@ void repair1(unsigned char *gbuf, long gbufsize)
     }
 
   /* recLen = gribrec_len(gbuf[4], gbuf[5], gbuf[6]); */
-  /* if ( recLen > JP23SET ) llarge = true; */
+  /* if ( recLen > JP23SET ) llarge = TRUE; */
 
   bds_len   = BDS_Len;
   bds_nbits = BDS_NumBits;
@@ -13032,25 +11697,34 @@ void gribRepair1(int nrec, long recsize, unsigned char *gribbuffer)
 #if defined (HAVE_CONFIG_H)
 #endif
 
-#if  defined (HAVE_LIBSZ)
+#if  defined (HAVE_LIBSZ) || defined (HAVE_LIBAEC)
 #if defined(__cplusplus)
 extern "C" {
 #endif
-#include <szlib.h>
+#if defined (HAVE_LIBAEC)
+#  include <libaec.h>
+#else
+#  include <szlib.h>
+#endif
 #if defined (__cplusplus)
 }
 #endif
 
-#define OPTIONS_MASK        (SZ_RAW_OPTION_MASK | SZ_MSB_OPTION_MASK | SZ_NN_OPTION_MASK)
+#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
 
-#define PIXELS_PER_BLOCK    (8)
-#define PIXELS_PER_SCANLINE (PIXELS_PER_BLOCK*128)
+#  define PIXELS_PER_BLOCK    (8)
+#  define PIXELS_PER_SCANLINE (PIXELS_PER_BLOCK*128)
 
-#define MIN_COMPRESS        (0.95)
-#define MIN_SIZE            (256)
+#  define MIN_COMPRESS        (0.95)
+#  define MIN_SIZE            (256)
 #endif
 
 #define  Z_SZIP  128
+#define  Z_AEC   130
 
 
 #define SetLen3(var, offset, value) ((var[offset+0] = 0xFF & (value >> 16)), \
@@ -13062,93 +11736,120 @@ extern "C" {
 				     (var[offset+3] = 0xFF & (value      )))
 
 
-int gribGetZip(size_t recsize, unsigned char *gribbuffer, size_t *urecsize)
+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 = gribVersion(gribbuffer, recsize);
+  int gribversion = gribVersion(gribbuffer, (size_t)recsize);
 
-  if ( gribversion == 2 ) return compress;
+  if ( gribversion == 2 ) return (compress);
 
   long gribrecsize;
-  int nerr = grib1Sections(gribbuffer, (long)recsize, &pds, &gds, &bms, &bds, &gribrecsize);
+  nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
   if ( nerr < 0 )
     {
       fprintf(stdout, "GRIB message error\n");
-      return compress;
+      return (compress);
     }
 
   if ( nerr > 0 )
     {
       fprintf(stdout, "GRIB data corrupted!\n");
-      return compress;
+      return (compress);
     }
 
   /* bds_len   = BDS_Len; */
   /* bds_nbits = BDS_NumBits; */
-  int bds_flag  = BDS_Flag;
+  bds_flag  = BDS_Flag;
   /* lspherc   =  bds_flag >> 7; */
   /* lcomplex  = (bds_flag >> 6)&1; */
-  int lcompress = (bds_flag >> 4)&1;
+  lcompress = (bds_flag >> 4)&1;
 
-  size_t gribsize = 0;
+  *urecsize = 0;
   if ( lcompress )
     {
       compress = BDS_Z;
-      if ( compress == Z_SZIP ) gribsize = (size_t) gribrec_len(bds[14], bds[15], bds[16]);
+      if ( compress == Z_SZIP || compress == Z_AEC )
+	{
+	  gribsize = gribrec_len(bds[14], bds[15], bds[16]);
+	}
     }
 
   *urecsize = gribsize;
 
-  return compress;
+  return (compress);
 }
 
 
 int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize)
 {
-#if ! defined(HAVE_LIBSZ)
+  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 gribLen = gribrec_len(dbuf[4], dbuf[5], dbuf[6]);
-  int llarge = (gribLen > JP23SET);
+  gribLen = gribrec_len(dbuf[4], dbuf[5], dbuf[6]);
+  if ( gribLen > JP23SET ) llarge = TRUE;
 
-  int rec_len = gribLen;
+  rec_len = gribLen;
 
   long gribrecsize;
-  int nerr = grib1Sections(dbuf, dbufsize, &pds, &gds, &bms, &bds, &gribrecsize);
+  nerr = grib1Sections(dbuf, dbufsize, &pds, &gds, &bms, &bds, &gribrecsize);
   if ( nerr < 0 )
     {
       fprintf(stdout, "GRIB message error\n");
-      return rec_len;
+      return (rec_len);
     }
 
   if ( nerr > 0 )
     {
       fprintf(stdout, "GRIB data corrupted!\n");
-      return rec_len;
+      return (rec_len);
     }
 
-#if  defined(HAVE_LIBSZ)
+#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;
 
-    int bds_zstart  = 14;
-    int bds_zoffset = 12;
+    bds_zstart  = 14;
+    bds_zoffset = 12;
     if ( llarge ) bds_zoffset += 2;
 
-    int bds_len   = BDS_Len;
+    bds_len   = BDS_Len;
     bds_len   = correct_bdslen(bds_len, gribLen, bds-dbuf);
-    int bds_nbits = BDS_NumBits;
-    int bds_flag  = BDS_Flag;
-    int bds_ubits = bds_flag & 15;
-    int lspherc   =  bds_flag >> 7;
-    int lcomplex  = (bds_flag >> 6)&1;
+    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 )
@@ -13159,23 +11860,36 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
 	    linfo = 0;
 	    fprintf(stderr, "GRIB szip only supports 8, 16, 24 and 32 bit data!\n");
 	  }
-	return rec_len;
+	return (rec_len);
       }
 
-    int bits_per_sample = (bds_nbits == 24) ? 8 : bds_nbits;
+#if defined (HAVE_LIBSZ)
+    if ( bds_nbits == 24 )
+      bits_per_sample    = 8;
+    else
+#endif
+      bits_per_sample    = bds_nbits;
 
-    SZ_com_t sz_param;          /* szip parameter block */
+#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
 
     if ( lspherc )
       {
 	if ( lcomplex  )
 	  {
-	    int jup  = bds[15];
-	    int ioff = (jup+1)*(jup+2);
+	    int jup, ioff;
+	    jup  = bds[15];
+	    ioff = (jup+1)*(jup+2);
 	    bds_ext = 4 + 3 + 4*ioff;
 	  }
 	else
@@ -13184,25 +11898,27 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
 	  }
       }
 
-    size_t datstart = bds_head + bds_ext;
+    datstart = bds_head + bds_ext;
 
-    size_t datsize = ((((bds_len - datstart)*8-bds_ubits)/bds_nbits)*bds_nbits)/8;
+    datsize = ((((bds_len - datstart)*8-bds_ubits)/bds_nbits)*bds_nbits)/8;
 
-    if ( datsize < MIN_SIZE ) return rec_len;
+    if ( datsize < MIN_SIZE ) return (rec_len);
     /*
     fprintf(stderr, "%d %d %d %d\n", bds_len, datstart, bds_len - datstart, datsize);
     */
-    size_t sourceLen = datsize;
-    size_t destLen   = sbufsize;
+    sourceLen = datsize;
+    destLen   = sbufsize;
     
-    unsigned char *source = bds + datstart;
-    unsigned char *dest = sbuf;
+    source = bds + datstart;
+    dest = sbuf;
 
+#if defined (HAVE_LIBSZ)
     if ( bds_nbits == 24 )
       {
-	long nelem = sourceLen/3;
+	long nelem;
+	nelem = sourceLen/3;
 	pbuf = (unsigned char*) Malloc(sourceLen);
-	for ( long i = 0; i < nelem; i++ )
+	for ( i = 0; i < nelem; i++ )
 	  {
 	    pbuf[        i] = source[3*i  ];
 	    pbuf[  nelem+i] = source[3*i+1];
@@ -13210,8 +11926,24 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
 	  }
 	source = pbuf;
       }
+#endif
+
+#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 status = SZ_BufftoBuffCompress(dest, &destLen, source, sourceLen, &sz_param);
+    destLen = strm.total_out;
+#else
+    status = SZ_BufftoBuffCompress(dest, &destLen, source, sourceLen, &sz_param);
     if ( status != SZ_OK )
       {
 	if ( status == SZ_NO_ENCODER_ERROR )
@@ -13225,6 +11957,7 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
 	else
 	  Warning("SZ ERROR: %d code %3d level %3d", status, PDS_Parameter, PDS_Level2);
       }
+#endif
     
     if ( pbuf ) Free(pbuf);
     /*
@@ -13242,7 +11975,7 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
 	gribLenOld = gribLen;
 
 	if ( bds_ext )
-	  for ( long i = bds_ext-1; i >= 0; --i )
+	  for ( i = bds_ext-1; i >= 0; --i )
 	    bds[bds_zoffset+bds_head+i] = bds[bds_head+i];
 
 	/*
@@ -13274,12 +12007,15 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
 	    SetLen3(bds, bds_zstart+6, destLen);
 	  }
 
-	int bdsLen = datstart + bds_zoffset + destLen;
+	bdsLen = datstart + bds_zoffset + destLen;
 
 	bds[11] = 0;
 	bds[12] = 0;
-
+#if defined (HAVE_LIBAEC)
+	BDS_Z   = Z_AEC;
+#else
 	BDS_Z   = Z_SZIP;
+#endif
 
 	BDS_Flag += 16;
 	if ( (bdsLen%2) == 1 )
@@ -13299,6 +12035,7 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
 
 	if ( llarge )
 	  {
+	    long itemp;
 	    long bdslen = gribLen - 4;
 
 	    /*
@@ -13311,7 +12048,7 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
 	    */
 	    while ( gribLen%120 ) dbuf[gribLen++] = 0;
 
-	    long itemp = gribLen / (-120);
+	    itemp = gribLen / (-120);
 	    itemp = JP23SET - itemp + 1;
 
 	    SetLen3(dbuf, 4, itemp);
@@ -13343,7 +12080,7 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
 
   if ( libszwarn )
     {
-      Warning("Compression disabled, szlib not available!");
+      Warning("Compression disabled, szlib or libaec not available!");
       libszwarn = 0;
     }
 #endif
@@ -13355,21 +12092,24 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
 
   rec_len = gribLen;
 
-  return rec_len;
+  return (rec_len);
 }
 
 
 int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize)
 {
-#if ! defined(HAVE_LIBSZ)
+#if ! (defined (HAVE_LIBSZ) || defined (HAVE_LIBAEC))
   static int libszwarn = 1;
 #endif
   unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
   size_t gribLen = 0;
+  unsigned char *dest, *source;
   size_t destLen, sourceLen;
+  int /* bds_len, */ bds_nbits, bds_flag, lspherc, lcomplex /*, lcompress*/;
   enum { bds_head = 11 };
   int bds_ext = 0;
-  bool llarge = false;
+  int bds_zoffset, bds_zstart;
+  int llarge = FALSE;
 
   UNUSED(dbufsize);
 
@@ -13378,36 +12118,37 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
   if ( nerr < 0 )
     {
       fprintf(stdout, "GRIB message error\n");
-      return 0;
+      return (0);
     }
 
   if ( nerr > 0 )
     {
       fprintf(stdout, "GRIB data corrupted!\n");
-      return 0;
+      return (0);
     }
 
-  int bds_zstart = 14;
+  bds_zstart = 14;
 
   int recLen = gribrec_len(bds[bds_zstart], bds[bds_zstart+1], bds[bds_zstart+2]);
-  if ( recLen > JP23SET ) llarge = true;
+  if ( recLen > JP23SET ) llarge = TRUE;
 
-  int bds_zoffset = 12;
+  bds_zoffset = 12;
   if ( llarge ) bds_zoffset += 2;
 
   /* bds_len   = BDS_Len; */
-  int bds_nbits = BDS_NumBits;
-  int bds_flag  = BDS_Flag;
-  int lspherc   =  bds_flag >> 7;
-  int lcomplex  = (bds_flag >> 6)&1;
+  bds_nbits = BDS_NumBits;
+  bds_flag  = BDS_Flag;
+  lspherc   =  bds_flag >> 7;
+  lcomplex  = (bds_flag >> 6)&1;
   /* lcompress = (bds_flag >> 4)&1; */
 
   if ( lspherc )
     {
       if ( lcomplex  )
 	{
-	  int jup  = bds[bds_zoffset+15];
-	  int ioff = (jup+1)*(jup+2);
+	  int jup, ioff;
+	  jup  = bds[bds_zoffset+15];
+	  ioff = (jup+1)*(jup+2);
 	  bds_ext = 4 + 3 + 4*ioff;
 	}
       else
@@ -13418,7 +12159,7 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
 
   size_t datstart = bds_head + (size_t)bds_ext;
 
-  unsigned char *source = bds + datstart + bds_zoffset;
+  source = bds + datstart + bds_zoffset;
   if ( llarge )
     sourceLen = ((size_t) ((bds[21]<<24)+(bds[22]<<16)+(bds[23]<<8)+bds[24]));
   else
@@ -13428,16 +12169,16 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
   if ( nerr < 0 )
     {
       fprintf(stdout, "GRIB message error\n");
-      return 0;
+      return (0);
     }
 
   if ( nerr > 0 )
     {
       fprintf(stdout, "GRIB data corrupted!\n");
-      return 0;
+      return (0);
     }
 
-  unsigned char *dest = bds + datstart;
+  dest = bds + datstart;
   if ( llarge )
     destLen = ((size_t) ((bds[17]<<24)+(bds[18]<<16)+(bds[19]<<8)+bds[20]));
   else
@@ -13447,28 +12188,63 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
 
   size_t bdsLen = datstart + destLen;
 
-#if  defined(HAVE_LIBSZ)
+#if  defined (HAVE_LIBSZ) || defined (HAVE_LIBAEC)
   {
-    int bits_per_sample = (bds_nbits == 24) ? 8 : bds_nbits;
-
+    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;
+
+#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
 
     if ( bds_ext )
-      for ( long i = 0; i < bds_ext; ++i )
+      for ( i = 0; i < bds_ext; ++i )
 	bds[bds_head+i] = bds[bds_zoffset+bds_head+i];
 
-    /*    fprintf(stderr, "gribUnzip: sourceLen %ld; destLen %ld\n", (long)sourceLen, (long)destLen);
+    /*
+    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);
     */
 
-    size_t tmpLen = destLen;
+    tmpLen = destLen;
+#if defined (HAVE_LIBAEC)
+    strm.next_in   = source;
+    strm.avail_in  = sourceLen;
+    strm.next_out  = dest;
+    strm.avail_out = tmpLen;
 
-    int status = SZ_BufftoBuffDecompress(dest, &tmpLen, source, sourceLen, &sz_param);
+    status = aec_buffer_decode(&strm);
+    if ( status != AEC_OK )
+      Warning("AEC ERROR: %d code %3d level %3d", status, PDS_Parameter, PDS_Level2);
+
+    tmpLen = strm.total_out;
+#else
+    status = SZ_BufftoBuffDecompress(dest, &tmpLen, source, sourceLen, &sz_param);
     if ( status != SZ_OK )
       {
 	if ( status == SZ_NO_ENCODER_ERROR )
@@ -13482,6 +12258,7 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
 	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);
@@ -13490,11 +12267,14 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
       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 = tmpLen/3;
-	unsigned char *pbuf = (unsigned char*) Malloc(tmpLen);
-	for ( long i = 0; i < nelem; i++ )
+	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];
@@ -13503,8 +12283,9 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
 	memcpy(dest, pbuf, tmpLen);
 	Free(pbuf);
       }
+#endif
 
-    int bds_ubits = BDS_Flag & 15;
+    bds_ubits = BDS_Flag & 15;
     BDS_Flag -= bds_ubits;
 
     if ( (bdsLen%2) == 1 )
@@ -13572,7 +12353,7 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
   
   if ( libszwarn )
     {
-      Warning("Decompression disabled, szlib not available!");
+      Warning("Decompression disabled, szlib or libaec not available!");
       libszwarn = 0;
     }
 #endif
@@ -15447,16 +14228,18 @@ int gribVersion(unsigned char *is, size_t buffersize)
   if ( buffersize < 8 )
     Error("Buffer too small (current size %d)!", (int) buffersize);
 
-  return GRIB_EDITION(is);
+  return (GRIB_EDITION(is));
 }
 
 static 
 double GET_Real(unsigned char *grib)
 {
-  int iexp  = GET_UINT1(grib[0]);
-  int imant = GET_UINT3(grib[1], grib[2], grib[3]);
+  int iexp, imant;
+
+  iexp  = GET_UINT1(grib[0]);
+  imant = GET_UINT3(grib[1], grib[2], grib[3]);
 
-  return decfp2(iexp, imant);
+  return (decfp2(iexp, imant));
 }
 
 static 
@@ -15464,7 +14247,7 @@ int decodeIS(unsigned char *is, int *isec0, int *iret)
 {
   int isLen = 0;
   int grib1offset;
-  bool lgrib = false, lbudg = false, ltide = false;
+  int lgrib = FALSE, lbudg = FALSE, ltide = FALSE;
 
   /*
     Octets 1 - 4 : The letters G R I B.
@@ -15476,22 +14259,22 @@ int decodeIS(unsigned char *is, int *isec0, int *iret)
   /*
     Check that 'GRIB' is found where expected.
   */
-  if ( GRIB_START(is) ) lgrib = true;
+  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;
+  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 )
+  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 || ltide )
+  if ( lbudg == TRUE || ltide == TRUE )
     {
       *iret = 305;
       gprintf(__func__, "Pseudo-grib data unsupported.");
@@ -15516,7 +14299,7 @@ int decodeIS(unsigned char *is, int *isec0, int *iret)
 
   isLen = 4 + grib1offset;
 
-  return isLen;
+  return (isLen);
 }
 
 static 
@@ -15602,20 +14385,19 @@ int decodePDS(unsigned char *pds, int *isec0, int *isec1)
   ISEC1_LevelType      = PDS_LevelType;
 
   if ( (ISEC1_LevelType !=  20) && 
-       (ISEC1_LevelType != GRIB1_LTYPE_99)           && 
-       (ISEC1_LevelType != GRIB1_LTYPE_ISOBARIC)     && 
-       (ISEC1_LevelType != GRIB1_LTYPE_ISOBARIC_PA)  && 
-       (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 != 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 != GRIB1_LTYPE_SEADEPTH)  && 
        (ISEC1_LevelType != 210) )
     {
       ISEC1_Level1 = PDS_Level1;
@@ -15718,7 +14500,7 @@ int decodePDS(unsigned char *pds, int *isec0, int *isec1)
 	}
     }
 
-  return pdsLen;
+  return (pdsLen);
 }
 
 
@@ -16211,7 +14993,7 @@ static
 int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2, int *numGridVals)
 {
   /* int imisng = 0; */
-  bool  ReducedGrid = false, VertCoorTab = false;
+  int  ReducedGrid = FALSE, VertCoorTab = FALSE;
 #if defined (VECTORCODE)
   unsigned char *igrib;
   GRIBPACK *lgrib = NULL;
@@ -16231,17 +15013,17 @@ int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2,
     { /* Either vct or reduced grid */
       if ( GDS_NV != 0 )
 	{ /* we have vct */
-	  VertCoorTab = true;
+	  VertCoorTab = TRUE;
 	  int ipl =  4*GDS_NV + ipvpl - 1;
 	  if ( ipl < gdsLen )
 	    {
-	      ReducedGrid = true;
+	      ReducedGrid = TRUE;
 	    }
 	}
       else
 	{
-	  VertCoorTab = false;
-	  ReducedGrid = true;
+	  VertCoorTab = FALSE;
+	  ReducedGrid = TRUE;
 	}
       /*	  ReducedGrid = (gdsLen - 32 - 4*GDS_NV); */
     }
@@ -16258,7 +15040,7 @@ int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2,
       if ( jlenl == GDS_NumLat )
 	{
 	  *numGridVals = 0;
-	  ISEC2_Reduced = true;
+	  ISEC2_Reduced = TRUE;
 	  for ( int i = 0; i < jlenl; i++ )
 	    {
 	      ISEC2_RowLon(i) = GET_UINT2(gds[locnl+2*i], gds[locnl+2*i+1]);
@@ -16267,7 +15049,7 @@ int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2,
 	}
       else
 	{
-	  ReducedGrid = false;
+	  ReducedGrid = FALSE;
 	}
     }
 
@@ -16311,14 +15093,18 @@ int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2,
 	    ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_STR ||
 	    ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_ROTSTR )
     {
-      // iret = decodeGDS_GG(gds, gdspos, isec0, isec2, imisng);
+      /*
+      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);
+      /*
+      iret = decodeGDS_LL(gds, gdspos, isec0, isec2, imisng);
+      */
     }
   else if ( ISEC2_GridType == GRIB1_GTYPE_LCC )
     {
@@ -16351,7 +15137,9 @@ int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2,
       isec2[ 8] = 0;
       isec2[ 9] = 0;
       isec2[10] = 0;
-      // iret = decodeGDS_SH(gds, gdspos, isec0, isec2, imisng);
+      /*
+      iret = decodeGDS_SH(gds, gdspos, isec0, isec2, imisng);
+      */
     }
   else if ( ISEC2_GridType == GRIB1_GTYPE_GME )
     {
@@ -16365,19 +15153,16 @@ int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2,
       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);
+      /*
+      iret = decodeGDS_TR(gds, gdspos, isec0, isec2, imisng);
+      */
     }
   else
     {
-      static bool lwarn = true;
       ISEC2_NumLon = GDS_NumLon;
       ISEC2_NumLat = GDS_NumLat;
       *numGridVals  = ISEC2_NumLon*ISEC2_NumLat;
-      if ( lwarn )
-        {
-          lwarn = false;
-          Message("GRIB gridtype %d unsupported", ISEC2_GridType);
-        }
+      Message("Gridtype %d unsupported", ISEC2_GridType);
     }
 
   /*    vertical coordinate parameters for hybrid levels.     */
@@ -16388,7 +15173,7 @@ int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2,
   isec2[17] = 0;
   isec2[18] = 0;
 
-  if ( VertCoorTab )
+  if ( VertCoorTab == TRUE )
     {
       int locnv;
       if ( ISEC0_GRIB_Version  == 0 )
@@ -16440,7 +15225,7 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
 			  T *fsec4, int fsec4len, int dfunc, int bdsLenIn, int numGridVals, int llarge, int *iret)
 {
   unsigned char *igrib;
-  bool lspherc = false, lcomplex = false;
+  int lspherc = FALSE, lcomplex = FALSE;
   int lcompress;
   int jup, kup, mup;
   int locnd;
@@ -16481,7 +15266,7 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
   /* 0------- grid point           */
   /* 1------- spherical harmonics  */
 
-  lspherc = (bds_flag >> 7)&1;
+  lspherc = bds_flag >> 7;
 
   if ( lspherc ) isec4[2] = 128;
   else           isec4[2] = 0;
@@ -16726,15 +15511,15 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
 {
   UCHAR *is = NULL, *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
   int isLen = 0, pdsLen = 0, gdsLen = 0, bmsLen = 0, bdsLen = 0, esLen = 0;
-  bool gdsIncluded = false;
-  bool bmsIncluded = false;
+  int gdsIncluded = FALSE;
+  int bmsIncluded = FALSE;
   int bitmapSize = 0;
   int imaskSize = 0;
-  bool ldebug = false;
-  bool llarge = false, l_iorj = false;
-  bool lsect2 = false, lsect3 = false;
+  int ldebug = FALSE;
+  int llarge = FALSE, l_iorj = FALSE;
+  int lsect2 = FALSE, lsect3 = FALSE;
   int numGridVals = 0;
-  static bool lmissvalinfo = 1;
+  static int lmissvalinfo = 1;
 
   UNUSED(kleng);
 
@@ -16742,7 +15527,7 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
 
   grsdef();
 
-  ISEC2_Reduced = false;
+  ISEC2_Reduced = FALSE;
 
   /*
     ----------------------------------------------------------------
@@ -16750,6 +15535,7 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
     ----------------------------------------------------------------
   */
   is = (unsigned char *) &kgrib[0];
+
   isLen = decodeIS(is, isec0, iret);
 
   /*
@@ -16762,7 +15548,7 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
     {
       if ( ldebug )
 	gprintf(__func__, "Special case, negative length multiplied by -120");
-      llarge = true;
+      llarge = TRUE;
       ISEC0_GRIB_Len *= (-120);
     }
   /*
@@ -16856,6 +15642,7 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
     ----------------------------------------------------------------
   */ 
   pds = is + isLen;
+
   pdsLen = decodePDS(pds, isec0, isec1);
 
   /*
@@ -16868,6 +15655,7 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
   if ( gdsIncluded )
     {
       gds = is + isLen + pdsLen;
+
       gdsLen = TEMPLATE(decodeGDS,T)(gds, isec0, isec2, fsec2, &numGridVals);
     }
 
@@ -16882,8 +15670,8 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
   if ( bmsIncluded )
     {
       bms = is + isLen + pdsLen + gdsLen;
-      bmsLen = BMS_Len;
 
+      bmsLen = BMS_Len;
       imaskSize = (bmsLen - 6)<<3;
       bitmapSize = imaskSize - BMS_UnusedBits;
       /*
@@ -16897,7 +15685,9 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
     ----------------------------------------------------------------
   */
   bds = is + isLen + pdsLen + gdsLen + bmsLen;
+
   bdsLen = ISEC0_GRIB_Len - (isLen + pdsLen + gdsLen + bmsLen);
+
   bdsLen = TEMPLATE(decodeBDS,T)(ISEC1_DecScaleFactor, bds, isec2, isec4, 
 				 fsec4, fsec4len, dfunc, bdsLen, numGridVals, llarge, iret);
 
@@ -16910,7 +15700,7 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
       if ( dfunc != 'L' && dfunc != 'J' )
 	if ( DBL_IS_NAN(FSEC3_MissVal) && lmissvalinfo )
 	  {
-	    lmissvalinfo = false;
+	    lmissvalinfo = 0;
 	    FSEC3_MissVal = (T)GRIB_MISSVAL;
 	    Message("Missing value = NaN is unsupported, set to %g!", GRIB_MISSVAL);
 	  }
@@ -17119,7 +15909,7 @@ static
 int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2, int *numGridVals)
 {
   /* int imisng = 0; */
-  bool  ReducedGrid = false, VertCoorTab = false;
+  int  ReducedGrid = FALSE, VertCoorTab = FALSE;
 #if defined (VECTORCODE)
   unsigned char *igrib;
   GRIBPACK *lgrib = NULL;
@@ -17139,17 +15929,17 @@ int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2,
     { /* Either vct or reduced grid */
       if ( GDS_NV != 0 )
 	{ /* we have vct */
-	  VertCoorTab = true;
+	  VertCoorTab = TRUE;
 	  int ipl =  4*GDS_NV + ipvpl - 1;
 	  if ( ipl < gdsLen )
 	    {
-	      ReducedGrid = true;
+	      ReducedGrid = TRUE;
 	    }
 	}
       else
 	{
-	  VertCoorTab = false;
-	  ReducedGrid = true;
+	  VertCoorTab = FALSE;
+	  ReducedGrid = TRUE;
 	}
       /*	  ReducedGrid = (gdsLen - 32 - 4*GDS_NV); */
     }
@@ -17166,7 +15956,7 @@ int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2,
       if ( jlenl == GDS_NumLat )
 	{
 	  *numGridVals = 0;
-	  ISEC2_Reduced = true;
+	  ISEC2_Reduced = TRUE;
 	  for ( int i = 0; i < jlenl; i++ )
 	    {
 	      ISEC2_RowLon(i) = GET_UINT2(gds[locnl+2*i], gds[locnl+2*i+1]);
@@ -17175,7 +15965,7 @@ int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2,
 	}
       else
 	{
-	  ReducedGrid = false;
+	  ReducedGrid = FALSE;
 	}
     }
 
@@ -17219,14 +16009,18 @@ int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2,
 	    ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_STR ||
 	    ISEC2_GridType == GRIB1_GTYPE_GAUSSIAN_ROTSTR )
     {
-      // iret = decodeGDS_GG(gds, gdspos, isec0, isec2, imisng);
+      /*
+      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);
+      /*
+      iret = decodeGDS_LL(gds, gdspos, isec0, isec2, imisng);
+      */
     }
   else if ( ISEC2_GridType == GRIB1_GTYPE_LCC )
     {
@@ -17259,7 +16053,9 @@ int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2,
       isec2[ 8] = 0;
       isec2[ 9] = 0;
       isec2[10] = 0;
-      // iret = decodeGDS_SH(gds, gdspos, isec0, isec2, imisng);
+      /*
+      iret = decodeGDS_SH(gds, gdspos, isec0, isec2, imisng);
+      */
     }
   else if ( ISEC2_GridType == GRIB1_GTYPE_GME )
     {
@@ -17273,19 +16069,16 @@ int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2,
       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);
+      /*
+      iret = decodeGDS_TR(gds, gdspos, isec0, isec2, imisng);
+      */
     }
   else
     {
-      static bool lwarn = true;
       ISEC2_NumLon = GDS_NumLon;
       ISEC2_NumLat = GDS_NumLat;
       *numGridVals  = ISEC2_NumLon*ISEC2_NumLat;
-      if ( lwarn )
-        {
-          lwarn = false;
-          Message("GRIB gridtype %d unsupported", ISEC2_GridType);
-        }
+      Message("Gridtype %d unsupported", ISEC2_GridType);
     }
 
   /*    vertical coordinate parameters for hybrid levels.     */
@@ -17296,7 +16089,7 @@ int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2,
   isec2[17] = 0;
   isec2[18] = 0;
 
-  if ( VertCoorTab )
+  if ( VertCoorTab == TRUE )
     {
       int locnv;
       if ( ISEC0_GRIB_Version  == 0 )
@@ -17348,7 +16141,7 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
 			  T *fsec4, int fsec4len, int dfunc, int bdsLenIn, int numGridVals, int llarge, int *iret)
 {
   unsigned char *igrib;
-  bool lspherc = false, lcomplex = false;
+  int lspherc = FALSE, lcomplex = FALSE;
   int lcompress;
   int jup, kup, mup;
   int locnd;
@@ -17389,7 +16182,7 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
   /* 0------- grid point           */
   /* 1------- spherical harmonics  */
 
-  lspherc = (bds_flag >> 7)&1;
+  lspherc = bds_flag >> 7;
 
   if ( lspherc ) isec4[2] = 128;
   else           isec4[2] = 0;
@@ -17634,15 +16427,15 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
 {
   UCHAR *is = NULL, *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
   int isLen = 0, pdsLen = 0, gdsLen = 0, bmsLen = 0, bdsLen = 0, esLen = 0;
-  bool gdsIncluded = false;
-  bool bmsIncluded = false;
+  int gdsIncluded = FALSE;
+  int bmsIncluded = FALSE;
   int bitmapSize = 0;
   int imaskSize = 0;
-  bool ldebug = false;
-  bool llarge = false, l_iorj = false;
-  bool lsect2 = false, lsect3 = false;
+  int ldebug = FALSE;
+  int llarge = FALSE, l_iorj = FALSE;
+  int lsect2 = FALSE, lsect3 = FALSE;
   int numGridVals = 0;
-  static bool lmissvalinfo = 1;
+  static int lmissvalinfo = 1;
 
   UNUSED(kleng);
 
@@ -17650,7 +16443,7 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
 
   grsdef();
 
-  ISEC2_Reduced = false;
+  ISEC2_Reduced = FALSE;
 
   /*
     ----------------------------------------------------------------
@@ -17658,6 +16451,7 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
     ----------------------------------------------------------------
   */
   is = (unsigned char *) &kgrib[0];
+
   isLen = decodeIS(is, isec0, iret);
 
   /*
@@ -17670,7 +16464,7 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
     {
       if ( ldebug )
 	gprintf(__func__, "Special case, negative length multiplied by -120");
-      llarge = true;
+      llarge = TRUE;
       ISEC0_GRIB_Len *= (-120);
     }
   /*
@@ -17764,6 +16558,7 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
     ----------------------------------------------------------------
   */ 
   pds = is + isLen;
+
   pdsLen = decodePDS(pds, isec0, isec1);
 
   /*
@@ -17776,6 +16571,7 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
   if ( gdsIncluded )
     {
       gds = is + isLen + pdsLen;
+
       gdsLen = TEMPLATE(decodeGDS,T)(gds, isec0, isec2, fsec2, &numGridVals);
     }
 
@@ -17790,8 +16586,8 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
   if ( bmsIncluded )
     {
       bms = is + isLen + pdsLen + gdsLen;
-      bmsLen = BMS_Len;
 
+      bmsLen = BMS_Len;
       imaskSize = (bmsLen - 6)<<3;
       bitmapSize = imaskSize - BMS_UnusedBits;
       /*
@@ -17805,7 +16601,9 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
     ----------------------------------------------------------------
   */
   bds = is + isLen + pdsLen + gdsLen + bmsLen;
+
   bdsLen = ISEC0_GRIB_Len - (isLen + pdsLen + gdsLen + bmsLen);
+
   bdsLen = TEMPLATE(decodeBDS,T)(ISEC1_DecScaleFactor, bds, isec2, isec4, 
 				 fsec4, fsec4len, dfunc, bdsLen, numGridVals, llarge, iret);
 
@@ -17818,7 +16616,7 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
       if ( dfunc != 'L' && dfunc != 'J' )
 	if ( DBL_IS_NAN(FSEC3_MissVal) && lmissvalinfo )
 	  {
-	    lmissvalinfo = false;
+	    lmissvalinfo = 0;
 	    FSEC3_MissVal = (T)GRIB_MISSVAL;
 	    Message("Missing value = NaN is unsupported, set to %g!", GRIB_MISSVAL);
 	  }
@@ -18072,7 +16870,7 @@ void encodeES(GRIBPACK *lGrib, long *gribLen, long bdsstart)
 
       if ( z > JP23SET*120 )
 	{
-	  fprintf(stderr, "Abort: GRIB1 record too large (size = %ld; max = %d)!\n", z, JP23SET*120);
+	  fprintf(stderr, "Abort: GRIB record too large (max = %d)!\n", JP23SET*120);
 	  exit(1);
 	}
 
@@ -18268,15 +17066,14 @@ void encodePDS(GRIBPACK *lpds, long pdsLen, int *isec1)
   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_ISOBARIC_PA)  &&
-       (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 != 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) &&
@@ -18365,9 +17162,6 @@ void encodePDS(GRIBPACK *lpds, long pdsLen, int *isec1)
 #ifdef T
 
 
-#define round_float roundf
-#define round_double round
-
 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)
@@ -18385,7 +17179,6 @@ void TEMPLATE(encode_array_common,T)(int numBits, size_t packStart, size_t datas
   for ( i = packStart; i < datasize; i++ )
     {
       /* note float -> unsigned int .. truncate */
-      // ival = (unsigned int)(TEMPLATE(round,T)((data[i] - zref) * factor));
       ival = (unsigned int) ((data[i] - zref) * factor + (T)0.5);
       /*
 	if ( ival > max_nbpv_pow2 ) ival = max_nbpv_pow2;
@@ -18431,7 +17224,6 @@ void TEMPLATE(encode_array_2byte,T)(size_t datasize, GRIBPACK *restrict lGrib,
     {
       for ( size_t i = 0; i < datasize; i++ )
         {
-          // sgrib[i] = (uint16_t)(TEMPLATE(round,T)((data[i] - zref) * factor));
           sgrib[i] = (uint16_t) ((data[i] - zref) * factor + (T)0.5);
         }
     }
@@ -18440,7 +17232,6 @@ void TEMPLATE(encode_array_2byte,T)(size_t datasize, GRIBPACK *restrict lGrib,
       uint16_t ui16;
       for ( size_t i = 0; i < datasize; i++ )
         {
-          // ui16 = (uint16_t)(TEMPLATE(round,T)((data[i] - zref) * factor));
           ui16 = (uint16_t) ((data[i] - zref) * factor + (T)0.5);
           sgrib[i] = gribSwapByteOrder_uint16(ui16);
         }
@@ -18468,7 +17259,6 @@ void TEMPLATE(encode_array_2byte,T)(size_t datasize, GRIBPACK *restrict lGrib,
 #endif
   for ( i = 0; i < datasize; i++ )
     {
-      // tmp = TEMPLATE(round,T)((data[i] - zref) * factor);
       tmp = ((data[i] - zref) * factor + (T)0.5);
       ui16 = (uint16_t) tmp;
       lGrib[z  ] = ui16 >>  8;
@@ -18512,7 +17302,6 @@ void TEMPLATE(encode_array,T)(int numBits, size_t packStart, size_t datasize,
 #endif
       for ( i = 0; i < datasize; i++ )
 	{
-	  // tmp = TEMPLATE(round,T)((data[i] - zref) * factor);
 	  tmp = ((data[i] - zref) * factor + (T)0.5);
 	  lGrib[z  ] = (GRIBPACK)tmp;
           z++;
@@ -18576,7 +17365,6 @@ void TEMPLATE(encode_array,T)(int numBits, size_t packStart, size_t datasize,
 #endif
       for ( i = 0; i < datasize; i++ )
 	{
-	  // tmp = TEMPLATE(round,T)((data[i] - zref) * factor);
 	  tmp = ((data[i] - zref) * factor + (T)0.5);
           ui32 = (uint32_t) tmp;
           lGrib[z  ] =  (GRIBPACK)(ui32 >> 16);
@@ -18606,7 +17394,6 @@ void TEMPLATE(encode_array,T)(int numBits, size_t packStart, size_t datasize,
 #endif
       for ( i = 0; i < datasize; i++ )
 	{
-	  // tmp = TEMPLATE(round,T)((data[i] - zref) * factor);
 	  tmp = ((data[i] - zref) * factor + (T)0.5);
           ui32 = (uint32_t) tmp;
           lGrib[z  ] =  (GRIBPACK)(ui32 >> 24);
@@ -18644,17 +17431,17 @@ void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t dat
   U_BYTEORDER;
   size_t i, j, z = *gz;
 #ifdef _ARCH_PWR6
-  enum { CGRIBEX__UNROLL_DEPTH_2 = 8 };
+#define __UNROLL_DEPTH_2 8
 #else
-  enum { CGRIBEX__UNROLL_DEPTH_2 = 128 };
+#define __UNROLL_DEPTH_2 128
 #endif
   size_t residual;
   size_t ofs;
-  T dval[CGRIBEX__UNROLL_DEPTH_2];
+  T dval[__UNROLL_DEPTH_2];
 
   data += packStart;
   datasize -= packStart;
-  residual =  datasize % CGRIBEX__UNROLL_DEPTH_2;
+  residual =  datasize % __UNROLL_DEPTH_2;
   ofs = datasize - residual;
 
   // reducing FP operations to single FMA is slowing down on pwr6 ...
@@ -18665,14 +17452,13 @@ void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t dat
       hpmStart(2, "pack 8 bit unrolled");
 #endif
       unsigned char *cgrib = (unsigned char *) (lGrib + z);
-      for ( i = 0; i < datasize - residual; i += CGRIBEX__UNROLL_DEPTH_2 )
+      for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 ) 
 	{
-	  for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
 	    {
-	      // dval[j] = TEMPLATE(round,T)((data[i+j] - zref) * factor);
 	      dval[j] = ((data[i+j] - zref) * factor + (T)0.5);
 	    }
-	  for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
 	    {
 #ifdef _ARCH_PWR6
 	      *cgrib++ =  (unsigned long) dval[j];
@@ -18680,11 +17466,10 @@ void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t dat
 	      *cgrib++ =  (unsigned char) dval[j];
 #endif
 	    }
-	  z += CGRIBEX__UNROLL_DEPTH_2;
+	  z += __UNROLL_DEPTH_2;
 	}
       for (j = 0; j < residual; j++) 
 	{
-	  // dval[j] = TEMPLATE(round,T)((data[ofs+j] - zref) * factor);
 	  dval[j] = ((data[ofs+j] - zref) * factor + (T)0.5);
 	}
       for (j = 0; j < residual; j++) 
@@ -18713,16 +17498,15 @@ void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t dat
 #endif
       uint16_t *sgrib = (uint16_t *) (lGrib+z);
 
-      for ( i = 0; i < datasize - residual; i += CGRIBEX__UNROLL_DEPTH_2 )
+      for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 ) 
 	{
-	  for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
 	    {
-	      // dval[j] = TEMPLATE(round,T)((data[i+j] - zref) * factor);
 	      dval[j] = ((data[i+j] - zref) * factor + (T)0.5);
 	    }
 	  if ( IS_BIGENDIAN() )
 	    {
-	      for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+	      for (j = 0; j < __UNROLL_DEPTH_2; j++) 
 		{
 #ifdef _ARCH_PWR6
 		  *sgrib++ = (unsigned long) dval[j];
@@ -18730,21 +17514,20 @@ void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t dat
 		  *sgrib++ = (uint16_t) dval[j];
 #endif
 		}
-	      z += 2*CGRIBEX__UNROLL_DEPTH_2;
+	      z += 2*__UNROLL_DEPTH_2;
 	    }
 	  else
 	    {
-	      for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+	      for (j = 0; j < __UNROLL_DEPTH_2; j++) 
 		{
 		  ival = (uint16_t) dval[j];
                   *sgrib++ = gribSwapByteOrder_uint16(ival);
 		}
-	      z += 2*CGRIBEX__UNROLL_DEPTH_2;
+	      z += 2*__UNROLL_DEPTH_2;
 	    }
 	}
       for (j = 0; j < residual; j++) 
 	{
-	  // dval[j] = TEMPLATE(round,T)((data[ofs+j] - zref) * factor);
 	  dval[j] = ((data[ofs+j] - zref) * factor + (T)0.5);
 	}
       if ( IS_BIGENDIAN() )
@@ -18783,14 +17566,13 @@ void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t dat
 #else
       uint32_t ival;
 #endif
-      for ( i = 0; i < datasize - residual; i += CGRIBEX__UNROLL_DEPTH_2 )
+      for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 ) 
 	{
-	  for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
 	    {
-	      // dval[j] = TEMPLATE(round,T)((data[i+j] - zref) * factor);
 	      dval[j] = ((data[i+j] - zref) * factor + (T)0.5);
 	    }
-	  for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
 	    {
 #ifdef _ARCH_PWR6
 	      ival = (unsigned long) dval[j];
@@ -18805,7 +17587,6 @@ void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t dat
 	}
       for (j = 0; j < residual; j++) 
 	{
-	  // dval[j] = TEMPLATE(round,T)((data[ofs+j] - zref) * factor);
 	  dval[j] = ((data[ofs+j] - zref) * factor + (T)0.5);
 	}
       for (j = 0; j < residual; j++) 
@@ -18831,16 +17612,15 @@ void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t dat
       uint32_t ival;
 #endif
       unsigned int *igrib = (unsigned int *) (lGrib + z);
-      for ( i = 0; i < datasize - residual; i += CGRIBEX__UNROLL_DEPTH_2 )
+      for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 ) 
  {
-	  for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
 	    {
-	      // dval[j] = TEMPLATE(round,T)((data[i+j] - zref) * factor);
 	      dval[j] = ((data[i+j] - zref) * factor + (T)0.5);
 	    }
 	  if ( IS_BIGENDIAN() )
 	    {
-	      for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+	      for (j = 0; j < __UNROLL_DEPTH_2; j++) 
 		{
 #ifdef _ARCH_PWR6
 		  *igrib = (unsigned long) dval[j];
@@ -18853,7 +17633,7 @@ void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t dat
 	    }
 	  else
 	    {
-	      for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+	      for (j = 0; j < __UNROLL_DEPTH_2; j++) 
 		{
                   ival = (uint32_t) dval[j];
 		  lGrib[z  ] =  (GRIBPACK)(ival >> 24);
@@ -18866,7 +17646,6 @@ void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t dat
 	}
       for (j = 0; j < residual; j++) 
 	{
-          // dval[j] = TEMPLATE(round,T)((data[ofs+j] - zref) * factor);
 	  dval[j] = ((data[ofs+j] - zref) * factor + (T)0.5);
 	}
       if ( IS_BIGENDIAN() )
@@ -18911,6 +17690,7 @@ void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t dat
     }
 
   *gz = z;
+#undef __UNROLL_DEPTH_2
 }
 
 #endif /* T */
@@ -18928,9 +17708,6 @@ void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t dat
 #ifdef T
 
 
-#define round_float roundf
-#define round_double round
-
 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)
@@ -18948,7 +17725,6 @@ void TEMPLATE(encode_array_common,T)(int numBits, size_t packStart, size_t datas
   for ( i = packStart; i < datasize; i++ )
     {
       /* note float -> unsigned int .. truncate */
-      // ival = (unsigned int)(TEMPLATE(round,T)((data[i] - zref) * factor));
       ival = (unsigned int) ((data[i] - zref) * factor + (T)0.5);
       /*
 	if ( ival > max_nbpv_pow2 ) ival = max_nbpv_pow2;
@@ -18994,7 +17770,6 @@ void TEMPLATE(encode_array_2byte,T)(size_t datasize, GRIBPACK *restrict lGrib,
     {
       for ( size_t i = 0; i < datasize; i++ )
         {
-          // sgrib[i] = (uint16_t)(TEMPLATE(round,T)((data[i] - zref) * factor));
           sgrib[i] = (uint16_t) ((data[i] - zref) * factor + (T)0.5);
         }
     }
@@ -19003,7 +17778,6 @@ void TEMPLATE(encode_array_2byte,T)(size_t datasize, GRIBPACK *restrict lGrib,
       uint16_t ui16;
       for ( size_t i = 0; i < datasize; i++ )
         {
-          // ui16 = (uint16_t)(TEMPLATE(round,T)((data[i] - zref) * factor));
           ui16 = (uint16_t) ((data[i] - zref) * factor + (T)0.5);
           sgrib[i] = gribSwapByteOrder_uint16(ui16);
         }
@@ -19031,7 +17805,6 @@ void TEMPLATE(encode_array_2byte,T)(size_t datasize, GRIBPACK *restrict lGrib,
 #endif
   for ( i = 0; i < datasize; i++ )
     {
-      // tmp = TEMPLATE(round,T)((data[i] - zref) * factor);
       tmp = ((data[i] - zref) * factor + (T)0.5);
       ui16 = (uint16_t) tmp;
       lGrib[z  ] = ui16 >>  8;
@@ -19075,7 +17848,6 @@ void TEMPLATE(encode_array,T)(int numBits, size_t packStart, size_t datasize,
 #endif
       for ( i = 0; i < datasize; i++ )
 	{
-	  // tmp = TEMPLATE(round,T)((data[i] - zref) * factor);
 	  tmp = ((data[i] - zref) * factor + (T)0.5);
 	  lGrib[z  ] = (GRIBPACK)tmp;
           z++;
@@ -19139,7 +17911,6 @@ void TEMPLATE(encode_array,T)(int numBits, size_t packStart, size_t datasize,
 #endif
       for ( i = 0; i < datasize; i++ )
 	{
-	  // tmp = TEMPLATE(round,T)((data[i] - zref) * factor);
 	  tmp = ((data[i] - zref) * factor + (T)0.5);
           ui32 = (uint32_t) tmp;
           lGrib[z  ] =  (GRIBPACK)(ui32 >> 16);
@@ -19169,7 +17940,6 @@ void TEMPLATE(encode_array,T)(int numBits, size_t packStart, size_t datasize,
 #endif
       for ( i = 0; i < datasize; i++ )
 	{
-	  // tmp = TEMPLATE(round,T)((data[i] - zref) * factor);
 	  tmp = ((data[i] - zref) * factor + (T)0.5);
           ui32 = (uint32_t) tmp;
           lGrib[z  ] =  (GRIBPACK)(ui32 >> 24);
@@ -19207,17 +17977,17 @@ void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t dat
   U_BYTEORDER;
   size_t i, j, z = *gz;
 #ifdef _ARCH_PWR6
-  enum { CGRIBEX__UNROLL_DEPTH_2 = 8 };
+#define __UNROLL_DEPTH_2 8
 #else
-  enum { CGRIBEX__UNROLL_DEPTH_2 = 128 };
+#define __UNROLL_DEPTH_2 128
 #endif
   size_t residual;
   size_t ofs;
-  T dval[CGRIBEX__UNROLL_DEPTH_2];
+  T dval[__UNROLL_DEPTH_2];
 
   data += packStart;
   datasize -= packStart;
-  residual =  datasize % CGRIBEX__UNROLL_DEPTH_2;
+  residual =  datasize % __UNROLL_DEPTH_2;
   ofs = datasize - residual;
 
   // reducing FP operations to single FMA is slowing down on pwr6 ...
@@ -19228,14 +17998,13 @@ void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t dat
       hpmStart(2, "pack 8 bit unrolled");
 #endif
       unsigned char *cgrib = (unsigned char *) (lGrib + z);
-      for ( i = 0; i < datasize - residual; i += CGRIBEX__UNROLL_DEPTH_2 )
+      for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 ) 
 	{
-	  for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
 	    {
-	      // dval[j] = TEMPLATE(round,T)((data[i+j] - zref) * factor);
 	      dval[j] = ((data[i+j] - zref) * factor + (T)0.5);
 	    }
-	  for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
 	    {
 #ifdef _ARCH_PWR6
 	      *cgrib++ =  (unsigned long) dval[j];
@@ -19243,11 +18012,10 @@ void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t dat
 	      *cgrib++ =  (unsigned char) dval[j];
 #endif
 	    }
-	  z += CGRIBEX__UNROLL_DEPTH_2;
+	  z += __UNROLL_DEPTH_2;
 	}
       for (j = 0; j < residual; j++) 
 	{
-	  // dval[j] = TEMPLATE(round,T)((data[ofs+j] - zref) * factor);
 	  dval[j] = ((data[ofs+j] - zref) * factor + (T)0.5);
 	}
       for (j = 0; j < residual; j++) 
@@ -19276,16 +18044,15 @@ void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t dat
 #endif
       uint16_t *sgrib = (uint16_t *) (lGrib+z);
 
-      for ( i = 0; i < datasize - residual; i += CGRIBEX__UNROLL_DEPTH_2 )
+      for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 ) 
 	{
-	  for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
 	    {
-	      // dval[j] = TEMPLATE(round,T)((data[i+j] - zref) * factor);
 	      dval[j] = ((data[i+j] - zref) * factor + (T)0.5);
 	    }
 	  if ( IS_BIGENDIAN() )
 	    {
-	      for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+	      for (j = 0; j < __UNROLL_DEPTH_2; j++) 
 		{
 #ifdef _ARCH_PWR6
 		  *sgrib++ = (unsigned long) dval[j];
@@ -19293,21 +18060,20 @@ void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t dat
 		  *sgrib++ = (uint16_t) dval[j];
 #endif
 		}
-	      z += 2*CGRIBEX__UNROLL_DEPTH_2;
+	      z += 2*__UNROLL_DEPTH_2;
 	    }
 	  else
 	    {
-	      for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+	      for (j = 0; j < __UNROLL_DEPTH_2; j++) 
 		{
 		  ival = (uint16_t) dval[j];
                   *sgrib++ = gribSwapByteOrder_uint16(ival);
 		}
-	      z += 2*CGRIBEX__UNROLL_DEPTH_2;
+	      z += 2*__UNROLL_DEPTH_2;
 	    }
 	}
       for (j = 0; j < residual; j++) 
 	{
-	  // dval[j] = TEMPLATE(round,T)((data[ofs+j] - zref) * factor);
 	  dval[j] = ((data[ofs+j] - zref) * factor + (T)0.5);
 	}
       if ( IS_BIGENDIAN() )
@@ -19346,14 +18112,13 @@ void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t dat
 #else
       uint32_t ival;
 #endif
-      for ( i = 0; i < datasize - residual; i += CGRIBEX__UNROLL_DEPTH_2 )
+      for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 ) 
 	{
-	  for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
 	    {
-	      // dval[j] = TEMPLATE(round,T)((data[i+j] - zref) * factor);
 	      dval[j] = ((data[i+j] - zref) * factor + (T)0.5);
 	    }
-	  for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
 	    {
 #ifdef _ARCH_PWR6
 	      ival = (unsigned long) dval[j];
@@ -19368,7 +18133,6 @@ void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t dat
 	}
       for (j = 0; j < residual; j++) 
 	{
-	  // dval[j] = TEMPLATE(round,T)((data[ofs+j] - zref) * factor);
 	  dval[j] = ((data[ofs+j] - zref) * factor + (T)0.5);
 	}
       for (j = 0; j < residual; j++) 
@@ -19394,16 +18158,15 @@ void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t dat
       uint32_t ival;
 #endif
       unsigned int *igrib = (unsigned int *) (lGrib + z);
-      for ( i = 0; i < datasize - residual; i += CGRIBEX__UNROLL_DEPTH_2 )
+      for ( i = 0; i < datasize - residual; i += __UNROLL_DEPTH_2 ) 
  {
-	  for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+	  for (j = 0; j < __UNROLL_DEPTH_2; j++) 
 	    {
-	      // dval[j] = TEMPLATE(round,T)((data[i+j] - zref) * factor);
 	      dval[j] = ((data[i+j] - zref) * factor + (T)0.5);
 	    }
 	  if ( IS_BIGENDIAN() )
 	    {
-	      for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+	      for (j = 0; j < __UNROLL_DEPTH_2; j++) 
 		{
 #ifdef _ARCH_PWR6
 		  *igrib = (unsigned long) dval[j];
@@ -19416,7 +18179,7 @@ void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t dat
 	    }
 	  else
 	    {
-	      for (j = 0; j < CGRIBEX__UNROLL_DEPTH_2; j++)
+	      for (j = 0; j < __UNROLL_DEPTH_2; j++) 
 		{
                   ival = (uint32_t) dval[j];
 		  lGrib[z  ] =  (GRIBPACK)(ival >> 24);
@@ -19429,7 +18192,6 @@ void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t dat
 	}
       for (j = 0; j < residual; j++) 
 	{
-          // dval[j] = TEMPLATE(round,T)((data[ofs+j] - zref) * factor);
 	  dval[j] = ((data[ofs+j] - zref) * factor + (T)0.5);
 	}
       if ( IS_BIGENDIAN() )
@@ -19474,6 +18236,7 @@ void TEMPLATE(encode_array_unrolled,T)(int numBits, size_t packStart, size_t dat
     }
 
   *gz = z;
+#undef __UNROLL_DEPTH_2
 }
 
 #endif /* T */
@@ -19733,7 +18496,7 @@ int TEMPLATE(encodeBDS,T)(GRIBPACK *lGrib, long *gribLen, int decscale, int *ise
   int bds_ext = 0;
   /* ibits = BitsPerInt; */
   int exponent, mantissa;
-  bool lspherc = false;
+  int lspherc = FALSE;
   int isubset = 0, itemp = 0, itrunc = 0;
   T factor = 1, fmin, fmax;
   const double jpepsln = 1.0e-12; /* -----> tolerance used to check equality     */
@@ -19748,7 +18511,10 @@ int TEMPLATE(encodeBDS,T)(GRIBPACK *lGrib, long *gribLen, int decscale, int *ise
       lspherc =  ( isec2[0] == 50 || isec2[0] == 60 ||
                    isec2[0] == 70 || isec2[0] == 80 );
 
-      isec4[2] = lspherc ? 128 : 0;
+      if ( lspherc )
+	isec4[2] = 128;
+      else
+	isec4[2] = 0;
     }
   else
     {
@@ -19759,8 +18525,8 @@ int TEMPLATE(encodeBDS,T)(GRIBPACK *lGrib, long *gribLen, int decscale, int *ise
 
   /* Complex packing supported for spherical harmonics. */
 
-  bool lcomplex = ( lspherc && ( isec4[3] == 64 ) ) ||
-                  ( lspherc && isec2 && ( isec2[5] == 2 ) );
+  int lcomplex = ( lspherc && ( isec4[3] == 64 ) ) ||
+                 ( lspherc && isec2 && ( isec2[5] == 2 ) );
 
   /* Check input specification is consistent */
 
@@ -20026,7 +18792,7 @@ void TEMPLATE(grib_encode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
   /*
   if ( ( isec4[3] == 64 ) && ( isec2[5] == 2 ) )
     {
-      static bool lwarn_cplx = true;
+      static int lwarn_cplx = TRUE;
 
       if ( lwarn_cplx )
 	Message("Complex packing of spectral data unsupported, using simple packing!");
@@ -20034,7 +18800,7 @@ void TEMPLATE(grib_encode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
       isec2[5] = 1;
       isec4[3] = 0;
 
-      lwarn_cplx = false;
+      lwarn_cplx = FALSE;
     }
   */
   TEMPLATE(encodeGDS,T)(lGrib, &gribLen, isec2, fsec2);
@@ -20339,7 +19105,7 @@ int TEMPLATE(encodeBDS,T)(GRIBPACK *lGrib, long *gribLen, int decscale, int *ise
   int bds_ext = 0;
   /* ibits = BitsPerInt; */
   int exponent, mantissa;
-  bool lspherc = false;
+  int lspherc = FALSE;
   int isubset = 0, itemp = 0, itrunc = 0;
   T factor = 1, fmin, fmax;
   const double jpepsln = 1.0e-12; /* -----> tolerance used to check equality     */
@@ -20354,7 +19120,10 @@ int TEMPLATE(encodeBDS,T)(GRIBPACK *lGrib, long *gribLen, int decscale, int *ise
       lspherc =  ( isec2[0] == 50 || isec2[0] == 60 ||
                    isec2[0] == 70 || isec2[0] == 80 );
 
-      isec4[2] = lspherc ? 128 : 0;
+      if ( lspherc )
+	isec4[2] = 128;
+      else
+	isec4[2] = 0;
     }
   else
     {
@@ -20365,8 +19134,8 @@ int TEMPLATE(encodeBDS,T)(GRIBPACK *lGrib, long *gribLen, int decscale, int *ise
 
   /* Complex packing supported for spherical harmonics. */
 
-  bool lcomplex = ( lspherc && ( isec4[3] == 64 ) ) ||
-                  ( lspherc && isec2 && ( isec2[5] == 2 ) );
+  int lcomplex = ( lspherc && ( isec4[3] == 64 ) ) ||
+                 ( lspherc && isec2 && ( isec2[5] == 2 ) );
 
   /* Check input specification is consistent */
 
@@ -20632,7 +19401,7 @@ void TEMPLATE(grib_encode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
   /*
   if ( ( isec4[3] == 64 ) && ( isec2[5] == 2 ) )
     {
-      static bool lwarn_cplx = true;
+      static int lwarn_cplx = TRUE;
 
       if ( lwarn_cplx )
 	Message("Complex packing of spectral data unsupported, using simple packing!");
@@ -20640,7 +19409,7 @@ void TEMPLATE(grib_encode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
       isec2[5] = 1;
       isec4[3] = 0;
 
-      lwarn_cplx = false;
+      lwarn_cplx = FALSE;
     }
   */
   TEMPLATE(encodeGDS,T)(lGrib, &gribLen, isec2, fsec2);
@@ -20702,7 +19471,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.8.1" " of ""Jun  6 2017"" ""11:54:18";
+static const char grb_libvers[] = "1.7.5" " of ""Jun  3 2016"" ""14:44:00";
 const char *
 cgribexLibraryVersion(void)
 {
@@ -22204,8 +20973,6 @@ int extWrite(int fileID, void *ext)
 #include <limits.h>
 #include <stdarg.h>
 #include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
 #include <string.h>
 #include <unistd.h>
 #include <sys/types.h>
@@ -22240,6 +21007,14 @@ char *strdup(const char *s);
 #endif
 
 
+#if ! defined   (FALSE)
+#  define  FALSE  0
+#endif
+
+#if ! defined   (TRUE)
+#  define  TRUE   1
+#endif
+
 /* #define  MAX_FILES  FOPEN_MAX */
 #define  MAX_FILES  4096
 
@@ -22247,7 +21022,7 @@ static int _file_max = MAX_FILES;
 
 static void file_initialize(void);
 
-static bool _file_init = false;
+static int _file_init = FALSE;
 
 #if  defined  (HAVE_LIBPTHREAD)
 #include <pthread.h>
@@ -22258,14 +21033,14 @@ static pthread_mutex_t _file_mutex;
 #  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)
+   if ( _file_init == FALSE ) pthread_once(&_file_init_thread, file_initialize)
 
 #else
 
 #  define FILE_LOCK()
 #  define FILE_UNLOCK()
 #  define FILE_INIT()        \
-   if ( _file_init == false ) file_initialize()
+   if ( _file_init == FALSE ) file_initialize()
 
 #endif
 
@@ -22310,7 +21085,7 @@ enum F_I_L_E_Flags
   };
 
 
-static bool FileInfo = false;
+static int FileInfo  = FALSE;
 
 
 #if ! defined (MIN_BUF_SIZE)
@@ -22335,7 +21110,7 @@ static void file_table_print(void);
  * A version string.
  */
 #undef   LIBVERSION
-#define  LIBVERSION      1.8.3
+#define  LIBVERSION      1.8.2
 #define  XSTRING(x)	 #x
 #define  STRING(x) 	 XSTRING(x)
 static const char file_libvers[] = STRING(LIBVERSION) " of " __DATE__ " " __TIME__;
@@ -22375,7 +21150,7 @@ void file_list_new(void)
 {
   assert(_fileList == NULL);
 
-  _fileList = (filePtrToIdx *) Malloc((size_t)_file_max*sizeof(filePtrToIdx));
+  _fileList = (filePtrToIdx *) Malloc((size_t)_file_max * sizeof (filePtrToIdx));
 }
 
 static
@@ -22391,7 +21166,9 @@ void file_list_delete(void)
 static
 void file_init_pointer(void)
 {
-  for ( int i = 0; i < _file_max; i++ )
+  int  i;
+
+  for ( i = 0; i < _file_max; i++ )
     {
       _fileList[i].next = _fileList + i + 1;
       _fileList[i].idx  = i;
@@ -22421,14 +21198,14 @@ bfile_t *file_to_pointer(int idx)
   else
     Error("file index %d undefined!", idx);
 
-  return fileptr;
+  return (fileptr);
 }
 
 /* Create an index from a pointer */
 static
 int file_from_pointer(bfile_t *ptr)
 {
-  int idx = -1;
+  int      idx = -1;
   filePtrToIdx *newptr;
 
   if ( ptr )
@@ -22454,7 +21231,7 @@ int file_from_pointer(bfile_t *ptr)
   else
     Error("Internal problem (pointer %p undefined)", ptr);
 
-  return idx;
+  return (idx);
 }
 
 static
@@ -22488,16 +21265,21 @@ void file_init_entry(bfile_t *fileptr)
 static
 bfile_t *file_new_entry(void)
 {
-  bfile_t *fileptr = (bfile_t *) Malloc(sizeof(bfile_t));
+  bfile_t *fileptr;
+
+  fileptr = (bfile_t *) Malloc(sizeof(bfile_t));
+
   if ( fileptr ) file_init_entry(fileptr);
 
-  return fileptr;
+  return (fileptr);
 }
 
 static
 void file_delete_entry(bfile_t *fileptr)
 {
-  int idx = fileptr->self;
+  int idx;
+
+  idx = fileptr->self;
 
   FILE_LOCK();
 
@@ -22516,41 +21298,49 @@ void file_delete_entry(bfile_t *fileptr)
 
 const char *fileLibraryVersion(void)
 {
-  return file_libvers;
+  return (file_libvers);
 }
 
+
 static
 int pagesize(void)
 {
 #if defined(_SC_PAGESIZE)
-  return (int) sysconf(_SC_PAGESIZE);
+  return ((int) sysconf(_SC_PAGESIZE));
 #else
 #ifndef POSIXIO_DEFAULT_PAGESIZE
 #define POSIXIO_DEFAULT_PAGESIZE 4096
 #endif
-  return (int) POSIXIO_DEFAULT_PAGESIZE;
+  return ((int) POSIXIO_DEFAULT_PAGESIZE);
 #endif
 }
 
 static
 double file_time()
 {
+  double tseconds = 0.0;
   struct timeval mytime;
   gettimeofday(&mytime, NULL);
-  double tseconds = (double) mytime.tv_sec + (double) mytime.tv_usec*1.0e-6;
-  return tseconds;
+  tseconds = (double) mytime.tv_sec + (double) mytime.tv_usec*1.0e-6;
+  return (tseconds);
 }
 
 void fileDebug(int debug)
 {
   FILE_Debug = debug;
-  if ( FILE_Debug ) Message("Debug level %d", debug);
+
+  if ( FILE_Debug )
+    Message("Debug level %d", debug);
 }
 
 
 void *filePtr(int fileID)
 {
-  return (void*)file_to_pointer(fileID);
+  bfile_t *fileptr;
+
+  fileptr = file_to_pointer(fileID);
+
+  return (fileptr);
 }
 
 static
@@ -22568,7 +21358,9 @@ void file_pointer_info(const char *caller, int fileID)
 int fileSetBufferType(int fileID, int type)
 {
   int ret = 0;
-  bfile_t *fileptr = file_to_pointer(fileID);
+  bfile_t *fileptr;
+
+  fileptr = file_to_pointer(fileID);
 
   if ( fileptr )
     {
@@ -22587,22 +21379,27 @@ int fileSetBufferType(int fileID, int type)
   if ( type == FILE_BUFTYPE_MMAP ) ret = 1;
 #endif
 
-  return ret;
+  return (ret);
 }
 
 int fileFlush(int fileID)
 {
+  bfile_t *fileptr;
   int retval = 0;
-  bfile_t *fileptr = file_to_pointer(fileID);
+
+  fileptr = file_to_pointer(fileID);
+
   if ( fileptr ) retval = fflush(fileptr->fp);
 
-  return retval;
+  return (retval);
 }
 
 
 void fileClearerr(int fileID)
 {
-  bfile_t *fileptr = file_to_pointer(fileID);
+  bfile_t *fileptr;
+
+  fileptr = file_to_pointer(fileID);
 
   if ( fileptr )
     {
@@ -22614,21 +21411,25 @@ void fileClearerr(int fileID)
 
 int filePtrEOF(void *vfileptr)
 {
-  int retval = 0;
   bfile_t *fileptr = (bfile_t *) vfileptr;
+  int retval = 0;
+
   if ( fileptr ) retval = (fileptr->flag & FILE_EOF) != 0;
 
-  return retval;
+  return (retval);
 }
 
 
 int fileEOF(int fileID)
 {
+  bfile_t *fileptr;
   int retval = 0;
-  bfile_t *fileptr = file_to_pointer(fileID);
+
+  fileptr = file_to_pointer(fileID);
+
   if ( fileptr ) retval = (fileptr->flag & FILE_EOF) != 0;
 
-  return retval;
+  return (retval);
 }
 
 void fileRewind(int fileID)
@@ -22641,7 +21442,9 @@ void fileRewind(int fileID)
 off_t fileGetPos(int fileID)
 {
   off_t filepos = 0;
-  bfile_t *fileptr = file_to_pointer(fileID);
+  bfile_t *fileptr;
+
+  fileptr = file_to_pointer(fileID);
 
   if ( fileptr )
     {
@@ -22653,21 +21456,23 @@ off_t fileGetPos(int fileID)
 
   if ( FILE_Debug ) Message("Position %ld", filepos);
 
-  return filepos;
+  return (filepos);
 }
 
 
 int fileSetPos(int fileID, off_t offset, int whence)
 {
   int status = 0;
-  bfile_t *fileptr = file_to_pointer(fileID);
+  bfile_t *fileptr;
+
+  fileptr = file_to_pointer(fileID);
 
   if ( FILE_Debug ) Message("Offset %8ld  Whence %3d", (long) offset, whence);
 
   if ( fileptr == 0 )
     {
       file_pointer_info(__func__, fileID);
-      return 1;
+      return (1);
     }
 
   switch (whence)
@@ -22748,17 +21553,19 @@ int fileSetPos(int fileID, off_t offset, int whence)
     if ( (fileptr->flag & FILE_EOF) != 0 )
       fileptr->flag -= FILE_EOF;
 
-  return status;
+  return (status);
 }
 
 static
 void file_table_print(void)
 {
+  int fileID;
   int lprintHeader = 1;
+  bfile_t *fileptr;
 
-  for ( int fileID = 0; fileID < _file_max; fileID++ )
+  for ( fileID = 0; fileID < _file_max; fileID++ )
     {
-      bfile_t *fileptr = file_to_pointer(fileID);
+      fileptr = file_to_pointer(fileID);
 
       if ( fileptr )
 	{
@@ -22805,34 +21612,43 @@ void file_table_print(void)
 
 char *fileInqName(int fileID)
 {
+  bfile_t *fileptr;
   char *name = NULL;
-  bfile_t *fileptr = file_to_pointer(fileID);
+
+  fileptr = file_to_pointer(fileID);
+
   if ( fileptr ) name = fileptr->name;
 
-  return name;
+  return (name);
 }
 
 
 int fileInqMode(int fileID)
 {
+  bfile_t *fileptr;
   int mode = 0;
-  bfile_t *fileptr = file_to_pointer(fileID);
+
+  fileptr = file_to_pointer(fileID);
+
   if ( fileptr ) mode = fileptr->mode;
 
-  return mode;
+  return (mode);
 }
 
 static
 long file_getenv(const char *envName)
 {
+  char *envString;
   long envValue = -1;
   long fact = 1;
 
-  char *envString = getenv(envName);
+  envString = getenv(envName);
 
   if ( envString )
     {
-      for ( int loop = 0; loop < (int) strlen(envString); loop++ )
+      int loop;
+
+      for ( loop = 0; loop < (int) strlen(envString); loop++ )
 	{
 	  if ( ! isdigit((int) envString[loop]) )
 	    {
@@ -22855,13 +21671,14 @@ long file_getenv(const char *envName)
       if ( FILE_Debug ) Message("Set %s to %ld", envName, envValue);
     }
 
-  return envValue;
+  return (envValue);
 }
 
 static
 void file_initialize(void)
 {
   long value;
+  char *envString;
 
 #if  defined  (HAVE_LIBPTHREAD)
   /* initialize global API mutex lock */
@@ -22877,7 +21694,7 @@ void file_initialize(void)
   if ( FILE_Debug )
     Message("FILE_MAX = %d", _file_max);
 
-  FileInfo = file_getenv("FILE_INFO") > 0;
+  FileInfo  = (int) file_getenv("FILE_INFO");
 
   value  = file_getenv("FILE_BUFSIZE");
   if ( value >= 0 ) FileBufferSizeEnv = value;
@@ -22918,7 +21735,7 @@ void file_initialize(void)
 #if defined (O_NONBLOCK)
   FileFlagWrite = O_NONBLOCK;
 #endif
-  char *envString = getenv("FILE_FLAG_WRITE");
+  envString = getenv("FILE_FLAG_WRITE");
   if ( envString )
     {
 #if defined (O_NONBLOCK)
@@ -22958,7 +21775,7 @@ void file_initialize(void)
 
   if ( FILE_Debug ) atexit(file_table_print);
 
-  _file_init = true;
+  _file_init = TRUE;
 }
 
 static
@@ -23034,18 +21851,20 @@ 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->flag & FILE_EOF) != 0 ) return (EOF);
 
   if ( fileptr->buffer == NULL ) file_set_buffer(fileptr);
 
-  if ( fileptr->bufferSize == 0 ) return EOF;
+  if ( fileptr->bufferSize == 0 ) return (EOF);
 
-  int fd = fileptr->fd;
+  fd = fileptr->fd;
 
 #if defined (HAVE_MMAP)
   if ( fileptr->bufferType == FILE_BUFTYPE_MMAP )
@@ -23063,7 +21882,8 @@ int file_fill_buffer(bfile_t *fileptr)
 
 	  if ( fileptr->buffer )
 	    {
-              int ret = munmap(fileptr->buffer, fileptr->mappedSize);
+              int ret;
+	      ret = munmap(fileptr->buffer, fileptr->mappedSize);
 	      if ( ret == -1 ) SysError("munmap error for read %s", fileptr->name);
 	      fileptr->buffer = NULL;
 	    }
@@ -23080,19 +21900,22 @@ int file_fill_buffer(bfile_t *fileptr)
   else
 #endif
     {
-      off_t retseek = lseek(fileptr->fd, fileptr->bufferPos, SEEK_SET);
+      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);
-      if ( nread > 0 ) offset = fileptr->position - fileptr->bufferPos;
     }
 
   if ( nread <= 0 )
     {
-      fileptr->flag |= (nread == 0) ? FILE_EOF : FILE_ERROR;
+      if ( nread == 0 )
+	fileptr->flag |= FILE_EOF;
+      else
+	fileptr->flag |= FILE_ERROR;
+
       fileptr->bufferCnt = 0;
-      return EOF;
+      return (EOF);
     }
 
   fileptr->bufferPtr = fileptr->buffer;
@@ -23124,7 +21947,7 @@ int file_fill_buffer(bfile_t *fileptr)
 
   fileptr->bufferNumFill++;
 
-  return (unsigned char) *fileptr->bufferPtr;
+  return ((unsigned char) *fileptr->bufferPtr);
 }
 
 static
@@ -23155,7 +21978,7 @@ void file_copy_from_buffer(bfile_t *fileptr, void *ptr, size_t size)
 static
 size_t file_read_from_buffer(bfile_t *fileptr, void *ptr, size_t size)
 {
-  size_t nread;
+  size_t nread, rsize;
   size_t offset = 0;
 
   if ( FILE_Debug )
@@ -23164,7 +21987,7 @@ size_t file_read_from_buffer(bfile_t *fileptr, void *ptr, size_t size)
   if ( ((long)fileptr->bufferCnt) < 0L )
     Error("Internal problem. bufferCnt = %ld", (long) fileptr->bufferCnt);
 
-  size_t rsize = size;
+  rsize = size;
 
   while ( fileptr->bufferCnt < rsize )
     {
@@ -23217,12 +22040,13 @@ 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;
 
   FILE_INIT();
 
-  int fmode = tolower((int) mode[0]);
+  fmode = tolower((int) mode[0]);
 
   switch ( fmode )
     {
@@ -23249,7 +22073,7 @@ int fileOpen_serial(const char *filename, const char *mode)
 
   if ( fp )
     {
-      if ( stat(filename, &filestat) != 0 ) return fileID;
+      if ( stat(filename, &filestat) != 0 ) return (fileID);
 
       fileptr = file_new_entry();
       if ( fileptr )
@@ -23260,7 +22084,7 @@ int fileOpen_serial(const char *filename, const char *mode)
     }
   else if ( fd >= 0 )
     {
-      if ( fstat(fd, &filestat) != 0 ) return fileID;
+      if ( fstat(fd, &filestat) != 0 ) return (fileID);
 
       fileptr = file_new_entry();
       if ( fileptr )
@@ -23296,7 +22120,7 @@ int fileOpen_serial(const char *filename, const char *mode)
 	Message("File %s opened with ID %d", filename, fileID);
     }
 
-  return fileID;
+  return (fileID);
 }
 
 /*
@@ -23311,6 +22135,7 @@ int fileClose(int fileID)
 
 int fileClose_serial(int fileID)
 {
+  char *name;
   int ret;
   const char *fbtname[] = {"unknown", "standard", "mmap"};
   const char *ftname[] = {"unknown", "open", "fopen"};
@@ -23320,15 +22145,15 @@ int fileClose_serial(int fileID)
   if ( fileptr == NULL )
     {
       file_pointer_info(__func__, fileID);
-      return 1;
+      return (1);
     }
 
-  char *name = fileptr->name;
+  name = fileptr->name;
 
   if ( FILE_Debug )
     Message("fileID = %d  filename = %s", fileID, name);
 
-  if ( FileInfo )
+  if ( FileInfo > 0 )
     {
       fprintf(stderr, "____________________________________________\n");
       fprintf(stderr, " file ID          : %d\n",  fileID);
@@ -23367,7 +22192,9 @@ int fileClose_serial(int fileID)
 	}
 
       if ( fileptr->time_in_sec > 0 )
-        rout = (double)fileptr->byteTrans / (1024.*1024.*fileptr->time_in_sec);
+        {
+          rout = (double)fileptr->byteTrans / (1024.*1024.*fileptr->time_in_sec);
+        }
 
       fprintf(stderr, " wall time [s]    : %.2f\n", fileptr->time_in_sec);
       fprintf(stderr, " data rate [MB/s] : %.1f\n", rout);
@@ -23410,20 +22237,22 @@ int fileClose_serial(int fileID)
 
   file_delete_entry(fileptr);
 
-  return 0;
+  return (0);
 }
 
 
 int filePtrGetc(void *vfileptr)
 {
   int ivalue = EOF;
+  int fillret = 0;
   bfile_t *fileptr = (bfile_t *) vfileptr;
 
   if ( fileptr )
     {
       if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
 	{
-	  int fillret = (fileptr->bufferCnt == 0) ? file_fill_buffer(fileptr) : 0;
+	  if ( fileptr->bufferCnt == 0 ) fillret = file_fill_buffer(fileptr);
+
 	  if ( fillret >= 0 )
 	    {
 	      ivalue = (unsigned char) *fileptr->bufferPtr++;
@@ -23447,14 +22276,20 @@ int filePtrGetc(void *vfileptr)
 	}
     }
 
-  return ivalue;
+  return (ivalue);
 }
 
 
 int fileGetc(int fileID)
 {
-  bfile_t *fileptr = file_to_pointer(fileID);
-  return filePtrGetc((void *)fileptr);
+  int ivalue;
+  bfile_t *fileptr;
+
+  fileptr = file_to_pointer(fileID);
+
+  ivalue = filePtrGetc((void *)fileptr);
+
+  return (ivalue);
 }
 
 
@@ -23471,7 +22306,12 @@ size_t filePtrRead(void *vfileptr, void *restrict ptr, size_t size)
 	{
 	  nread = fread(ptr, 1, size, fileptr->fp);
 	  if ( nread != size )
-            fileptr->flag |= (nread == 0) ? FILE_EOF : FILE_ERROR;
+	    {
+	      if ( nread == 0 )
+		fileptr->flag |= FILE_EOF;
+	      else
+		fileptr->flag |= FILE_ERROR;
+	    }
 	}
 
       fileptr->position  += (off_t)nread;
@@ -23481,14 +22321,16 @@ size_t filePtrRead(void *vfileptr, void *restrict ptr, size_t size)
 
   if ( FILE_Debug ) Message("size %ld  nread %ld", size, nread);
 
-  return nread;
+  return (nread);
 }
 
 
 size_t fileRead(int fileID, void *restrict ptr, size_t size)
 {
   size_t nread = 0;
-  bfile_t *fileptr = file_to_pointer(fileID);
+  bfile_t *fileptr;
+
+  fileptr = file_to_pointer(fileID);
 
   if ( fileptr )
     {
@@ -23519,19 +22361,23 @@ size_t fileRead(int fileID, void *restrict ptr, size_t size)
 
   if ( FILE_Debug ) Message("size %ld  nread %ld", size, nread);
 
-  return nread;
+  return (nread);
 }
 
 
 size_t fileWrite(int fileID, const void *restrict ptr, size_t size)
 {
   size_t nwrite = 0;
-  bfile_t *fileptr = file_to_pointer(fileID);
+  bfile_t *fileptr;
+
+  fileptr = file_to_pointer(fileID);
 
   if ( fileptr )
     {
       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 )
@@ -23555,7 +22401,7 @@ size_t fileWrite(int fileID, const void *restrict ptr, size_t size)
       fileptr->access++;
     }
 
-  return nwrite;
+  return (nwrite);
 }
 /*
  * Local Variables:
@@ -23569,14 +22415,11 @@ size_t fileWrite(int fileID, const void *restrict ptr, size_t size)
 #ifndef _GAUSSGRID_H
 #define _GAUSSGRID_H
 
-#include <stdbool.h>
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 void gaussaw(double *restrict pa, double *restrict pw, size_t nlat);
-bool isGaussGrid(size_t ysize, double yinc, const double *yvals);
 
 #if defined (__cplusplus)
 }
@@ -23602,24 +22445,43 @@ bool isGaussGrid(size_t ysize, double yinc, const double *yvals);
 
 
 
+#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,
+void cpledn(size_t kn, size_t kodd, double *pfn, double pdx, int kflag, 
             double *pw, double *pdxn, double *pxmod)
 {
+  double zdlk;
+  double zdlldn;
+  double zdlx;
+  double zdlmod;
+  double zdlxn;
+
+  size_t ik;
+
   /* 1.0 Newton iteration step */
 
-  double zdlx = pdx;
-  double zdlk = 0.0;
-  if ( kodd == 0 ) zdlk = 0.5*pfn[0];
-  double zdlxn  = 0.0;
-  double zdlldn = 0.0;
+  zdlx = pdx;
+  zdlk = 0.0;
+  if (kodd == 0) 
+    {
+      zdlk = 0.5*pfn[0];
+    }
+  zdlxn  = 0.0;
+  zdlldn = 0.0;
 
-  size_t ik = 1;
+  ik = 1;
 
-  if ( kflag == 0 )
+  if (kflag == 0) 
     {
-      for ( size_t jn = 2-kodd; jn <= kn; jn += 2 )
+      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);
@@ -23628,7 +22490,7 @@ void cpledn(size_t kn, size_t kodd, double *pfn, double pdx, int kflag,
 	  ik++;
 	}
       /* Newton method */
-      double zdlmod = -(zdlk/zdlldn);
+      zdlmod = -(zdlk/zdlldn);
       zdlxn = zdlx + zdlmod;
       *pdxn = zdlxn;
       *pxmod = zdlmod;
@@ -23636,9 +22498,9 @@ void cpledn(size_t kn, size_t kodd, double *pfn, double pdx, int kflag,
 
   /* 2.0 Compute weights */
 
-  if ( kflag == 1 )
+  if (kflag == 1) 
     {
-      for ( size_t jn = 2-kodd; jn <= kn; jn += 2 )
+      for(size_t jn = 2-kodd; jn <= kn; jn += 2) 
 	{
 	  /* normalised derivative */
 	  zdlldn = zdlldn - pfn[ik]*(double)(jn)*sin((double)(jn)*zdlx);
@@ -23654,21 +22516,24 @@ 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 */
 
-  int iflag  =  0;
-  int itemax = 20;
+  iflag  =  0;
+  itemax = 20;
 
   size_t iodd   = (kn % 2);
 
-  double zdlx   =  *pl;
+  zdlx   =  *pl;
 
   /* 2.0 Newton iteration */
 
-  for ( int jter = 1; jter <= itemax+1; jter++ )
+  for (int jter = 1; jter <= itemax+1; jter++)
     {
       cpledn(kn, iodd, pfn, zdlx, iflag, &zw, &zdlxn, &pmod);
       zdlx = zdlxn;
@@ -23683,7 +22548,7 @@ void gawl(double *pfn, double *pl, double *pw, size_t kn)
 }
 
 static
-void gauaw(size_t kn, double *restrict pl, double *restrict pw)
+void gauaw(size_t kn, double *__restrict__ pl, double *__restrict__ pw)
 {
   /*
    * 1.0 Initialize Fourier coefficients for ordinary Legendre polynomials
@@ -23691,22 +22556,26 @@ void gauaw(size_t kn, double *restrict pl, double *restrict pw)
    * 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    = (double *) Malloc((kn+1) * (kn+1) * sizeof(double));
-  double *zfnlat = (double *) Malloc((kn/2+1+1)*sizeof(double));
+  double *zfn, *zfnlat;
+
+  double z, zfnn;
+
+  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++ )
+  for (size_t jn = 1; jn <= kn; jn++)
     {
-      double zfnn = zfn[0];
+      zfnn = zfn[0];
       for (size_t jgl = 1; jgl <= jn; jgl++)
 	{
-	  zfnn *= sqrt(1.0-0.25/((double)(jgl*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 )
+      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)));
@@ -23718,11 +22587,11 @@ void gauaw(size_t kn, double *restrict pl, double *restrict pw)
 
   size_t iodd = kn % 2;
   size_t ik = iodd;
-  for ( size_t jgl = iodd; jgl <= kn; jgl += 2 )
+  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
@@ -23730,17 +22599,16 @@ void gauaw(size_t kn, double *restrict pl, double *restrict pw)
    */
 
   size_t ins2 = kn/2+(kn % 2);
-  double z;
 
-  for ( size_t jgl = 1; jgl <= ins2; jgl++ )
+  for (size_t jgl = 1; jgl <= ins2; jgl++) 
     {
-      z = ((double)(4*jgl-1))*M_PI/((double)(4*kn+2));
+      z = ((double)(4*jgl-1))*M_PI/((double)(4*kn+2)); 
       pl[jgl-1] = z+1.0/(tan(z)*((double)(8*kn*kn)));
     }
 
   /* 2.2 Computes roots and weights for transformed theta */
 
-  for ( size_t jgl = ins2; jgl >= 1 ; jgl-- )
+  for (size_t jgl = ins2; jgl >= 1 ; jgl--) 
     {
       size_t jglm1 = jgl-1;
       gawl(zfnlat, &(pl[jglm1]), &(pw[jglm1]), kn);
@@ -23748,12 +22616,12 @@ void gauaw(size_t kn, double *restrict pl, double *restrict pw)
 
   /* convert to physical latitude */
 
-  for ( size_t jgl = 0; jgl < ins2; jgl++ )
+  for (size_t jgl = 0; jgl < ins2; jgl++) 
     {
       pl[jgl] = cos(pl[jgl]);
     }
 
-  for ( size_t jgl = 1; jgl <= kn/2; jgl++ )
+  for (size_t jgl = 1; jgl <= kn/2; jgl++) 
     {
       size_t jglm1 = jgl-1;
       size_t isym =  kn-jgl;
@@ -23767,48 +22635,103 @@ void gauaw(size_t kn, double *restrict pl, double *restrict pw)
   return;
 }
 
-
-void gaussaw(double *restrict pa, double *restrict pw, size_t nlat)
+#if 0
+static
+void gauaw_old(double *pa, double *pw, int nlat)
 {
-  //gauaw_old(pa, pw, nlat);
-  gauaw(nlat, pa, pw);
-}
+  /*
+   * 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;
 
-bool isGaussGrid(size_t ysize, double yinc, const double *yvals)
-{
-  bool lgauss = false;
+  int isym, iter, ins2, jn, j;
+  double za, zw, zan;
+  double z, zk, zkm1, zkm2, zx, zxn, zldn, zmod;
 
-  if ( IS_EQUAL(yinc, 0) && ysize > 2 ) /* check if gaussian */
+  /*
+   * Perform the Newton loop
+   * Find 0 of Legendre polynomial with Newton loop
+   */
+
+  ins2 = nlat/2 + nlat%2;
+
+  for ( j = 0; j < ins2; j++ )
     {
-      size_t i;
-      double *yv = (double *) Malloc(ysize*sizeof(double));
-      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;
+      z = (double) (4*(j+1)-1)*M_PI / (double) (4*nlat+2);
+      pa[j] = cos(z + 1.0/(tan(z)*(double)(8*nlat*nlat)));
+    }
 
-      for ( i = 0; i < ysize; i++ )
-        if ( fabs(yv[i] - yvals[i]) >
-             ((yv[0] - yv[1])/500) ) break;
+  for ( j = 0; j < ins2; j++ )
+    {
 
-      if ( i == ysize ) lgauss = true;
+      za = pa[j];
 
-      /* 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;
+      iter = 0;
+      do
+	{
+	  iter++;
+	  zk = 0.0;
 
-          if ( i == ysize ) lgauss = true;
-        }
+	  /* Newton iteration step */
 
-      Free(yv);
+	  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;
+
+	  /* computes weight */
+
+	  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 );
+
+      pa[j] = zan;
+      pw[j] = 2.0*zw;
+    }
+
+#if defined (SX)
+#pragma vdir nodep
+#endif
+  for (j = 0; j < nlat/2; j++)
+    {
+      isym = nlat-(j+1);
+      pa[isym] = -pa[j];
+      pw[isym] =  pw[j];
     }
 
-  return lgauss;
+  return;
+}
+#endif
+
+void gaussaw(double *restrict pa, double *restrict pw, size_t nlat)
+{
+  //gauaw_old(pa, pw, nlat);
+  gauaw(nlat, pa, pw);
 }
 
 /*
@@ -23823,6 +22746,7 @@ int main (int rgc, char *argv[])
   int i;
 
   gauaw(ngl, pl, pw);
+  gauaw_old(plo, pwo, ngl);
   for (i = 0; i < ngl; i++)
     {
       pl[i]  = asin(pl[i])/M_PI*180.0;
@@ -23858,7 +22782,7 @@ int main (int rgc, char *argv[])
 
 static char gribapi_libvers[64] = "";
 #if  defined  (HAVE_LIBGRIB_API)
-static bool gribapi_libvers_init;
+static int gribapi_libvers_init;
 #endif
 
 
@@ -23886,7 +22810,7 @@ const char *gribapiLibraryVersionString(void)
       gribapiLibraryVersion(&major_version, &minor_version, &revision_version);
 
       sprintf(gribapi_libvers, "%d.%d.%d", major_version, minor_version, revision_version);
-      gribapi_libvers_init = true;
+      gribapi_libvers_init = 1;
     }
 #endif
 
@@ -23896,10 +22820,12 @@ const char *gribapiLibraryVersionString(void)
 
 void gribContainersNew(stream_t * streamptr)
 {
-  int editionNumber = (streamptr->filetype == CDI_FILETYPE_GRB) ? 1 : 2;
+  int editionNumber = 2;
 
+  if ( streamptr->filetype == FILETYPE_GRB ) editionNumber = 1;
+  (void)editionNumber;
 #if  defined  (HAVE_LIBCGRIBEX)
-  if ( editionNumber == 1 )
+  if ( streamptr->filetype == FILETYPE_GRB )
     {
     }
   else
@@ -23919,7 +22845,7 @@ void gribContainersNew(stream_t * streamptr)
           for ( int levelID = 0; levelID < nlevs; ++levelID )
             {
               gribContainers[varID][levelID].gribHandle = gribHandleNew(editionNumber);
-              gribContainers[varID][levelID].init = false;
+              gribContainers[varID][levelID].init = FALSE;
             }
 	}
 
@@ -23931,7 +22857,7 @@ void gribContainersNew(stream_t * streamptr)
       for ( int varID = 0; varID < nvars; ++varID )
         {
           gribContainers[varID].gribHandle = gribHandleNew(editionNumber);
-          gribContainers[varID].init = false;
+          gribContainers[varID].init = FALSE;
 	}
 
       streamptr->gribContainers = (void *) gribContainers;
@@ -23981,6 +22907,169 @@ void gribContainersDelete(stream_t * streamptr)
  * require-trailing-newline: t
  * End:
  */
+#ifndef _GRID_H
+#define _GRID_H
+
+#include <stdbool.h>
+
+typedef unsigned char mask_t;
+
+typedef struct grid_t grid_t;
+
+struct gridVirtTable
+{
+  void (*destroy)(grid_t *gridptr);
+  grid_t *(*copy)(grid_t *gridptr);
+  void (*copyScalarFields)(grid_t *gridptrOrig, grid_t *gridptrDup);
+  void (*copyArrayFields)(grid_t *gridptrOrig, grid_t *gridptrDup);
+  void (*defXVals)(grid_t *gridptr, const double *xvals);
+  void (*defYVals)(grid_t *gridptr, const double *yvals);
+  void (*defMask)(grid_t *gridptr, const int *mask);
+  void (*defMaskGME)(grid_t *gridptr, const int *mask);
+  void (*defXBounds)(grid_t *gridptr, const double *xbounds);
+  void (*defYBounds)(grid_t *gridptr, const double *ybounds);
+  void (*defArea)(grid_t *gridptr, const double *area);
+  double (*inqXVal)(grid_t *gridptr, int index);
+  double (*inqYVal)(grid_t *gridptr, int index);
+  int (*inqXVals)(grid_t *gridptr, double *xvals);
+  int (*inqYVals)(grid_t *gridptr, double *yvals);
+  const double *(*inqXValsPtr)(grid_t *gridptr);
+  const double *(*inqYValsPtr)(grid_t *gridptr);
+  /* return if for both grids, all xval and all yval are equal */
+  bool (*compareXYFull)(grid_t *gridRef, grid_t *gridTest);
+  /* return if for both grids, x[0], y[0], x[size-1] and y[size-1] are
+   * respectively equal */
+  bool (*compareXYAO)(grid_t *gridRef, grid_t *gridTest);
+  void (*inqArea)(grid_t *gridptr, double *area);
+  const double *(*inqAreaPtr)(grid_t *gridptr);
+  int (*hasArea)(grid_t *gridptr);
+  int (*inqMask)(grid_t *gridptr, int *mask);
+  int (*inqMaskGME)(grid_t *gridptr, int *mask_gme);
+  int (*inqXBounds)(grid_t *gridptr, double *xbounds);
+  int (*inqYBounds)(grid_t *gridptr, double *ybounds);
+  const double *(*inqXBoundsPtr)(grid_t *gridptr);
+  const double *(*inqYBoundsPtr)(grid_t *gridptr);
+};
+
+struct grid_t {
+  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;
+  short   lcc_defined;
+  short   lcc2_defined;
+  int     laea_defined;
+  double  lcc2_lon_0;             /* Lambert Conformal Conic 2      */
+  double  lcc2_lat_0;
+  double  lcc2_lat_1;
+  double  lcc2_lat_2;
+  double  lcc2_a;
+  double  laea_lon_0;             /* Lambert Azimuthal Equal Area   */
+  double  laea_lat_0;
+  double  laea_a;
+  double  xpole, ypole, angle;    /* rotated north pole             */
+  short   isCyclic;               /* TRUE for global cyclic grids   */
+  short   isRotated;              /* TRUE for rotated grids         */
+  short   xdef;                   /* 0: undefined 1:xvals 2:x0+xinc */
+  short   ydef;                   /* 0: undefined 1:yvals 2:y0+yinc */
+  int     nd, ni, ni2, ni3;       /* parameter for GRID_GME         */
+  int     number, position;       /* parameter for GRID_REFERENCE   */
+  int     trunc;                  /* parameter for GRID_SPECTEAL    */
+  int     nvertex;
+  char   *reference;
+  unsigned char uuid[CDI_UUID_SIZE]; /* uuid for grid reference        */
+  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 */
+  short   lcomplex;
+  short   hasdims;
+  const char *xstdname;
+  const char *ystdname;
+  char    xdimname[CDI_MAX_NAME];
+  char    ydimname[CDI_MAX_NAME];
+  char    vdimname[CDI_MAX_NAME];
+  char    xname[CDI_MAX_NAME];
+  char    yname[CDI_MAX_NAME];
+  char    xlongname[CDI_MAX_NAME];
+  char    ylongname[CDI_MAX_NAME];
+  char    xunits[CDI_MAX_NAME];
+  char    yunits[CDI_MAX_NAME];
+  char   *name;
+  const struct gridVirtTable *vtable;
+  void *extraData;
+};
+
+
+void grid_init(grid_t *gridptr);
+void
+cdiGridTypeInit(grid_t *gridptr, int gridtype, int size);
+void grid_free(grid_t *gridptr);
+grid_t *gridID2Ptr(int gridID);
+extern const struct gridVirtTable cdiGridVtable;
+
+unsigned cdiGridCount(void);
+
+const double *gridInqXvalsPtr(int gridID);
+const double *gridInqYvalsPtr(int gridID);
+
+const double *gridInqXboundsPtr(int gridID);
+const double *gridInqYboundsPtr(int gridID);
+const double *gridInqAreaPtr(int gridID);
+
+const char *gridInqXnamePtr(int gridID);
+const char *gridInqYnamePtr(int gridID);
+
+const char *gridInqReferencePtr(int gridID);
+
+int gridGenerate(const grid_t *grid);
+
+void cdiGridGetIndexList(unsigned, int * );
+
+void
+gridUnpack(char * unpackBuffer, int unpackBufferSize,
+           int * unpackBufferPos, int originNamespace, void *context,
+           int force_id);
+
+struct addIffNewRes
+{
+  int Id;
+  int isNew;
+};
+
+struct addIffNewRes cdiVlistAddGridIfNew(int vlistID, grid_t *grid, int mode);
+
+#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
 
@@ -24014,16 +23103,6 @@ int gribapiGetParam(grib_handle *gh);
 int gribapiGetGridType(grib_handle *gh);
 void gribapiGetGrid(grib_handle *gh, grid_t *grid);
 
-#ifdef HIRLAM_EXTENSIONS
-void gribapiSetDataTimeRangeIndicator(grib_handle *gh, int timeRangeIndicator);
-void gribapiGetDataTimeRangeIndicator(grib_handle *gh, int *timeRangeIndicator);
-#endif // #ifdef HIRLAM_EXTENSIONS
-
-extern struct cdiGribAPI_ts_str_map_elem {
-  long productionTemplate;
-  const char sname[8];
-} cdiGribAPI_ts_str_map[];
-
 #endif
 
 #endif
@@ -24060,29 +23139,28 @@ extern struct cdiGribAPI_ts_str_map_elem {
 //A simple wrapper for grib_get_string() that returns a newly allocated string.
 char* gribCopyString(grib_handle* gribHandle, const char* key)
 {
+  char* result = NULL;
   size_t length;
 #ifdef HAVE_GRIB_GET_LENGTH
-  if (!grib_get_length(gribHandle, key, &length))
+  if(!grib_get_length(gribHandle, key, &length))
     {
-      char *result = (char *)Malloc(length);
-      if (!grib_get_string(gribHandle, key, result, &length))
-        result = (char *) Realloc(result, length);
-      else
-        {
+    char* result = (char *) Malloc(length);
+    if(!grib_get_string(gribHandle, key, result, &length))
+    result = (char *) Realloc(result, length);
+
+    else
+      {
           Free(result);
           result = NULL;
-        }
-      return result;
+      }
     }
-  else
-    return NULL;
 #else
   length = 1024;         /* there's an implementation limit
                           * that makes strings longer than
                           * this unlikely in grib_api versions
                           * not providing grib_get_length */
   int rc;
-  char *result = (char *) Malloc(length);
+  result = (char *) Malloc(length);
   while ((rc = grib_get_string(gribHandle, key, result, &length))
          == GRIB_BUFFER_TOO_SMALL || rc == GRIB_ARRAY_TOO_SMALL)
     {
@@ -24101,8 +23179,8 @@ char* gribCopyString(grib_handle* gribHandle, const char* key)
       Free(result);
       result = NULL;
     }
-  return result;
 #endif
+  return result;
 }
 
 //A simple wrapper for grib_get_string() for the usecase that the result is only compared to a given constant string.
@@ -24155,8 +23233,8 @@ long gribGetLong(grib_handle* gh, const char* key)
 long gribGetLongDefault(grib_handle* gribHandle, const char* key, long defaultValue)
 {
   long result;
-  if ( grib_get_long(gribHandle, key, &result) || result == GRIB_MISSING_LONG )
-    result = defaultValue;
+  if(grib_get_long(gribHandle, key, &result)) return defaultValue;
+  if(result == GRIB_MISSING_LONG) return defaultValue;
   return result;
 }
 
@@ -24172,9 +23250,8 @@ double gribGetDouble(grib_handle* gh, const char* key)
 double gribGetDoubleDefault(grib_handle* gribHandle, const char* key, double defaultValue)
 {
   double result;
-  if ( grib_get_double(gribHandle, key, &result)
-       || IS_EQUAL(result, GRIB_MISSING_DOUBLE) )
-    result = defaultValue;
+  if(grib_get_double(gribHandle, key, &result)) return defaultValue;
+  if(IS_EQUAL(result, GRIB_MISSING_DOUBLE)) return defaultValue;
   return result;
 }
 
@@ -24310,7 +23387,7 @@ static int getAvailabilityOfRelativeTimes(grib_handle* gh, bool* outHaveForecast
         return 0;
 
       //case 55 and case 40455 are the same: 55 is the proposed standard value, 40455 is the value in the local use range that is used by the dwd until the standard is updated.
-      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 55: case 56: case 60: case 1000: case 1002: case 1100: case 40033: case 40455: case 40456:
+      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 55: case 60: case 1000: case 1002: case 1100: case 40033: case 40455:
         *outHaveForecastTime = true, *outHaveTimeRange = false;
         return 0;
 
@@ -24323,7 +23400,6 @@ static int getAvailabilityOfRelativeTimes(grib_handle* gh, bool* outHaveForecast
     }
 }
 
-
 char* gribMakeTimeString(grib_handle* gh, CdiTimeType timeType)
 {
   //Get the parts of the reference date.
@@ -24371,31 +23447,15 @@ char* gribMakeTimeString(grib_handle* gh, CdiTimeType timeType)
   return makeDateString(&date);
 }
 
-
 int gribapiTimeIsFC(grib_handle *gh)
 {
-  if (gribEditionNumber(gh) <= 1) return true;
+  if(gribEditionNumber(gh) <= 1) return true;
 
   long sigofrtime;
   FAIL_ON_GRIB_ERROR(grib_get_long, gh, "significanceOfReferenceTime", &sigofrtime);
   return sigofrtime != 3;
 }
 
-struct cdiGribAPI_ts_str_map_elem cdiGribAPI_ts_str_map[] = {
-  [TSTEP_INSTANT] = {  0, "instant" },
-  [TSTEP_AVG] = { 8, "avg" },
-  [TSTEP_ACCUM] = {  8, "accum" },
-  [TSTEP_MAX] = {  8, "max" },
-  [TSTEP_MIN] = {  8, "min" },
-  [TSTEP_DIFF] = {  8, "diff" },
-  [TSTEP_RMS] = {  8, "rms" },
-  [TSTEP_SD] = {  8, "sd" },
-  [TSTEP_COV] = { 8, "cov" },
-  [TSTEP_RATIO] = {  8, "ratio" },
-  { 0, "" }
-};
-
-
 //Fetches the value of the "stepType" key and converts it into a constant in the TSTEP_* range.
 int gribapiGetTsteptype(grib_handle *gh)
 {
@@ -24411,84 +23471,44 @@ int gribapiGetTsteptype(grib_handle *gh)
       status = grib_get_string(gh, "stepType", stepType, &len);
       if ( status == 0 && len > 1 && len < 256 )
         {
-          for (int i = TSTEP_INSTANT; cdiGribAPI_ts_str_map[i].sname[0]; ++i)
-            if ( strncmp(cdiGribAPI_ts_str_map[i].sname, stepType, len) == 0 )
-              {
-                tsteptype = i;
-                goto tsteptypeFound;
-              }
-
-          if ( lprint )
+          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);
         }
-#ifdef HIRLAM_EXTENSIONS
-      {
-      // Normaly cdo looks in grib for attribute called "stepType", see above.
-      // BUT NWP models such as Hirlam and Harmonie 37h1.2, use "timeRangeIndicator" instead!
-      // Where for example:       0: for instanteneous fields; 4: for accumulated fields
-      //  0:   Forecast product valid at reference time + P1
-      //  2:   Product with a valid time ranging between reference time + P1 and reference time + P2
-      //  4:   Accumulation (reference time + P1 to reference time + P2)
-      //  5:   Difference(reference time + P2 minus reference time + P1) product considered valid at reference time + P2
-      // More details on WMO standards:
-      //               http://www.wmo.int/pages/prog/www/WDM/Guides/Guide-binary-2.html
-      //tsteptype = TSTEP_INSTANT;  // default value for any case
-      long timeRangeIND = 0; // typically 0: for instanteneous fields; 4: for accumulated fields
-      int rc = grib_get_long(gh, "timeRangeIndicator", &timeRangeIND);
-      if (rc != 0) {
-            //if ( lprint )
-            Warning("Could not get 'stepType' either 'timeRangeIndicator'. Using defualt!");
-            return (tsteptype);
-      }
-      extern int cdiGribUseTimeRangeIndicator;
-      cdiGribUseTimeRangeIndicator = 1;
-      switch ( timeRangeIND )
-          {
-              case 0:  tsteptype = TSTEP_INSTANT; break;
-              case 2:  tsteptype = TSTEP_INSTANT2;
-                       strcpy(stepType, "instant2");  // was incorrectly set before into accum
-                       break;
-              case 4:  tsteptype = TSTEP_ACCUM; break;
-              case 5:  tsteptype = TSTEP_DIFF; break;
-              default:
-                if ( lprint )
-                {
-                  if (CDI_Debug)
-                      Warning("timeRangeIND = %d;  stepType= %s; tsteptype=%d unsupported timeRangeIND at the moment, set to instant!", timeRangeIND, stepType, tsteptype);
-                  lprint = false;
-                }
-                break;
-          }
-      if (CDI_Debug)
-          Warning("timeRangeIND = %d;  stepType= %s; tsteptype=%d", timeRangeIND, stepType, tsteptype);
-      }
-#endif // HIRLAM_EXTENSIONS
     }
-  tsteptypeFound:
-  return tsteptype;
-}
 
+  return (tsteptype);
+}
 
 int gribGetDatatype(grib_handle* gribHandle)
 {
   int datatype;
   if(gribEditionNumber(gribHandle) > 1 && gribCheckString(gribHandle, "packingType", "grid_ieee"))
     {
-      datatype = gribCheckLong(gribHandle, "precision", 1) ? CDI_DATATYPE_FLT32 : CDI_DATATYPE_FLT64;
+      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 : CDI_DATATYPE_PACK;
+      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;
@@ -24507,7 +23527,6 @@ int gribapiGetParam(grib_handle *gh)
   return cdiEncodeParam((int)pnum, (int)pcat, (int)pdis);
 }
 
-
 int gribapiGetGridType(grib_handle *gh)
 {
   int gridtype = GRID_GENERIC;
@@ -24516,10 +23535,12 @@ int gribapiGetGridType(grib_handle *gh)
       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_PROJECTION; 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;
@@ -24540,12 +23561,6 @@ void gribapiGetGrid(grib_handle *gh, grid_t *grid)
 {
   long editionNumber = gribEditionNumber(gh);
   int gridtype = gribapiGetGridType(gh);
-  int projtype = (gridtype == GRID_PROJECTION && gribapiGetIsRotated(gh)) ? CDI_PROJ_RLL : CDI_UNDEFID;
-  if ( gridtype == GRID_LCC )
-    {
-      gridtype = GRID_PROJECTION;
-      projtype = CDI_PROJ_LCC;
-    }
   /*
   if ( streamptr->unreduced && gridtype == GRID_GAUSSIAN_REDUCED )
     {
@@ -24562,287 +23577,306 @@ void gribapiGetGrid(grib_handle *gh, grid_t *grid)
   long numberOfPoints;
   FAIL_ON_GRIB_ERROR(grib_get_long, gh, "numberOfPoints", &numberOfPoints);
 
-  long lpar;
-
-  if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN || projtype == CDI_PROJ_RLL )
+  switch (gridtype)
     {
-      long nlon, nlat;
-      FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Ni", &nlon);
-      FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Nj", &nlat);
+    case GRID_LONLAT:
+    case GRID_GAUSSIAN:
+      {
+        long nlon, nlat;
+        FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Ni", &nlon);
+        FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Nj", &nlat);
 
-      if ( gridtype == GRID_GAUSSIAN )
-        {
-          FAIL_ON_GRIB_ERROR(grib_get_long, gh, "numberOfParallelsBetweenAPoleAndTheEquator", &lpar);
-          grid->np = (int)lpar;
-        }
+        if ( gridtype == GRID_GAUSSIAN )
+          {
+            long lpar;
+            FAIL_ON_GRIB_ERROR(grib_get_long, gh, "numberOfParallelsBetweenAPoleAndTheEquator", &lpar);
+            grid->np = (int)lpar;
+          }
 
-      if ( numberOfPoints != nlon*nlat )
-        Error("numberOfPoints (%ld) and gridSize (%ld) differ!", numberOfPoints, nlon*nlat);
-
-      grid->size   = (int)numberOfPoints;
-      grid->x.size = (int)nlon;
-      grid->y.size = (int)nlat;
-      grid->x.inc  = 0;
-      grid->y.inc  = 0;
-      grid->x.flag = 0;
-      FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfFirstGridPointInDegrees", &grid->x.first);
-      FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfLastGridPointInDegrees",  &grid->x.last);
-      FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfFirstGridPointInDegrees",  &grid->y.first);
-      FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfLastGridPointInDegrees",   &grid->y.last);
-      if ( nlon > 1 )
-        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "iDirectionIncrementInDegrees", &grid->x.inc);
-      if ( gridtype == GRID_LONLAT && nlat > 1 )
-        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "jDirectionIncrementInDegrees", &grid->y.inc);
-
-      long iscan, jscan;
-      FAIL_ON_GRIB_ERROR(grib_get_long, gh, "iScansNegatively", &iscan);
-      FAIL_ON_GRIB_ERROR(grib_get_long, gh, "jScansPositively", &jscan);
-      if (  iscan ) grid->x.inc = - grid->x.inc;
-      if ( !jscan ) grid->y.inc = - grid->y.inc;
-
-      if ( grid->x.inc < -999 || grid->x.inc > 999 ) grid->x.inc = 0;
-      if ( grid->y.inc < -999 || grid->y.inc > 999 ) grid->y.inc = 0;
-
-      /* if ( IS_NOT_EQUAL(grid->x.first, 0) || IS_NOT_EQUAL(grid->x.last, 0) ) */
-      {
-        if ( grid->x.size > 1 )
+        if ( numberOfPoints != nlon*nlat )
+          Error("numberOfPoints (%ld) and gridSize (%ld) differ!", numberOfPoints, nlon*nlat);
+
+        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
+        grid->size  = (int)numberOfPoints;
+        grid->xsize = (int)nlon;
+        grid->ysize = (int)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);
+        if ( nlon > 1 )
+          FAIL_ON_GRIB_ERROR(grib_get_double, gh, "iDirectionIncrementInDegrees", &grid->xinc);
+        if ( gridtype == GRID_LONLAT && nlat > 1 )
+          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 ( grid->yinc > 0 && grid->yfirst > grid->ylast ) grid->yinc = -grid->yinc;
+
+        /* if ( IS_NOT_EQUAL(grid->xfirst, 0) || IS_NOT_EQUAL(grid->xlast, 0) ) */
           {
-            if ( editionNumber <= 1 )
+            if ( grid->xsize > 1 )
               {
-                /* correct xinc if necessary */
-                if ( IS_EQUAL(grid->x.first, 0) && grid->x.last > 354 )
+                if ( (grid->xfirst >= grid->xlast) && (grid->xfirst >= 180) ) grid->xfirst -= 360;
+
+                if ( editionNumber <= 1 )
                   {
-                    double xinc = 360. / grid->x.size;
-                    if ( fabs(grid->x.inc-xinc) > 0.0 )
+                    /* correct xinc if necessary */
+                    if ( IS_EQUAL(grid->xfirst, 0) && grid->xlast > 354 )
                       {
-                        grid->x.inc = xinc;
-                        if ( CDI_Debug ) Message("set xinc to %g", grid->x.inc);
+                        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->x.flag = 2;
-      }
-      grid->y.flag = 0;
-      /* if ( IS_NOT_EQUAL(grid->y.first, 0) || IS_NOT_EQUAL(grid->y.last, 0) ) */
-      {
-        if ( grid->y.size > 1 )
+        grid->ydef = 0;
+        /* if ( IS_NOT_EQUAL(grid->yfirst, 0) || IS_NOT_EQUAL(grid->ylast, 0) ) */
           {
-            if ( editionNumber <= 1 )
+            if ( grid->ysize > 1 )
               {
+                if ( editionNumber <= 1 )
+                  {
+                  }
               }
+            grid->ydef = 2;
           }
-        grid->y.flag = 2;
+        break;
       }
-    }
-  else if ( gridtype == GRID_GAUSSIAN_REDUCED )
-    {
-      FAIL_ON_GRIB_ERROR(grib_get_long, gh, "numberOfParallelsBetweenAPoleAndTheEquator", &lpar);
-      grid->np = (int)lpar;
-
-      FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Nj", &lpar);
-      int nlat = (int)lpar;
-
-      grid->size   = (int)numberOfPoints;
-
-      grid->nrowlon = nlat;
-      grid->rowlon = (int *) Malloc((size_t)nlat * sizeof (int));
-      long *pl     = (long *) Malloc((size_t)nlat * sizeof (long));
-      size_t dummy = (size_t)nlat;
-      FAIL_ON_GRIB_ERROR(grib_get_long_array, gh, "pl", pl, &dummy);
-      for ( int i = 0; i < nlat; ++i ) grid->rowlon[i] = (int)pl[i];
-      Free(pl);
-
-      grid->y.size  = nlat;
-      grid->x.inc   = 0;
-      grid->y.inc   = 0;
-      grid->x.flag  = 0;
-      FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfFirstGridPointInDegrees", &grid->x.first);
-      FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfLastGridPointInDegrees",  &grid->x.last);
-      FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfFirstGridPointInDegrees",  &grid->y.first);
-      FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfLastGridPointInDegrees",   &grid->y.last);
-
-      // FAIL_ON_GRIB_ERROR(grib_get_double, gh, "iDirectionIncrementInDegrees", &grid->x.inc);
-      // if ( IS_EQUAL(grid->x.inc, GRIB_MISSING_DOUBLE) ) grid->x.inc = 0;
-
-      /* if ( IS_NOT_EQUAL(grid->x.first, 0) || IS_NOT_EQUAL(grid->x.last, 0) ) */
+    case GRID_GAUSSIAN_REDUCED:
       {
-        if ( grid->x.size > 1 )
+        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->nrowlon = nlat;
+        grid->rowlon = (int *) Malloc((size_t)nlat * sizeof (int));
+        long *pl     = (long *) Malloc((size_t)nlat * sizeof (long));
+        size_t 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->x.first > grid->x.last) && (grid->x.first >= 180) ) grid->x.first -= 360;
-
-            if ( editionNumber <= 1 )
+            if ( grid->xsize > 1 )
               {
-                /* correct xinc if necessary */
-                if ( IS_EQUAL(grid->x.first, 0) && grid->x.last > 354 )
+                if ( (grid->xfirst > grid->xlast) && (grid->xfirst >= 180) ) grid->xfirst -= 360;
+
+                if ( editionNumber <= 1 )
                   {
-                    double xinc = 360. / grid->x.size;
-                    if ( fabs(grid->x.inc-xinc) > 0.0 )
+                    /* correct xinc if necessary */
+                    if ( IS_EQUAL(grid->xfirst, 0) && grid->xlast > 354 )
                       {
-                        grid->x.inc = xinc;
-                        if ( CDI_Debug ) Message("set xinc to %g", grid->x.inc);
+                        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->x.flag = 2;
-      }
-      grid->y.flag = 0;
-      /* if ( IS_NOT_EQUAL(grid->y.first, 0) || IS_NOT_EQUAL(grid->y.last, 0) ) */
-      {
-        if ( grid->y.size > 1 )
+        grid->ydef  = 0;
+        /* if ( IS_NOT_EQUAL(grid->yfirst, 0) || IS_NOT_EQUAL(grid->ylast, 0) ) */
           {
-            if ( editionNumber <= 1 )
+            if ( grid->ysize > 1 )
               {
+                if ( editionNumber <= 1 )
+                  {
+                  }
               }
+            grid->ydef = 2;
           }
-        grid->y.flag = 2;
+        break;
       }
-    }
-  else if ( projtype == CDI_PROJ_LCC )
-    {
-      FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Nx", &lpar);
-      int nlon = (int)lpar;
-      FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Ny", &lpar);
-      int nlat = (int)lpar;
+    case GRID_LCC:
+      {
+        int nlon, nlat;
+        long lpar;
 
-      if ( numberOfPoints != nlon*nlat )
-        Error("numberOfPoints (%d) and gridSize (%d) differ!", (int)numberOfPoints, nlon*nlat);
+        FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Nx", &lpar);
+        nlon = (int)lpar;
+        FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Ny", &lpar);
+        nlat = (int)lpar;
 
-      grid->size  = (int)numberOfPoints;
-      grid->x.size = nlon;
-      grid->y.size = nlat;
+        if ( numberOfPoints != nlon*nlat )
+          Error("numberOfPoints (%d) and gridSize (%d) differ!", (int)numberOfPoints, nlon*nlat);
 
-      double xinc, yinc;
-      FAIL_ON_GRIB_ERROR(grib_get_double, gh, "DxInMetres", &xinc);
-      FAIL_ON_GRIB_ERROR(grib_get_double, gh, "DyInMetres", &yinc);
+        grid->size  = (int)numberOfPoints;
+        grid->xsize = nlon;
+        grid->ysize = nlat;
 
-      grid->x.first = 0;
-      grid->x.last  = 0;
-      grid->x.inc   = xinc;
-      grid->y.first = 0;
-      grid->y.last  = 0;
-      grid->y.inc   = yinc;
-      grid->x.flag  = 2;
-      grid->y.flag  = 2;
-    }
-  else if ( gridtype == 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;
+        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);
 
-      grid->size  = (int)datasize;
+        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;
+          }
 
-      FAIL_ON_GRIB_ERROR(grib_get_long, gh, "J", &lpar);
-      grid->trunc = (int)lpar;
-    }
-  else if ( gridtype == GRID_GME )
-    {
-      grid->size  = (int)numberOfPoints;
-      if ( grib_get_long(gh, "nd", &lpar) == 0 ) grid->gme.nd  = (int)lpar;
-      if ( grib_get_long(gh, "Ni", &lpar) == 0 ) grid->gme.ni  = (int)lpar;
-      if ( grib_get_long(gh, "n2", &lpar) == 0 ) grid->gme.ni2 = (int)lpar;
-      if ( grib_get_long(gh, "n3", &lpar) == 0 ) grid->gme.ni3 = (int)lpar;
-    }
-  else if ( gridtype == GRID_UNSTRUCTURED )
-    {
-      unsigned char uuid[CDI_UUID_SIZE];
-      /*
+        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;
-      */
-      grid->size  = (int)numberOfPoints;
+        */
 
-      if ( grib_get_long(gh, "numberOfGridUsed", &lpar) == 0 )
-        {
-          grid->number   = (int)lpar;
-          if ( grib_get_long(gh, "numberOfGridInReference", &lpar) == 0 )
-            grid->position = (int)lpar;
-          /*
+        /* 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);
-            }
-        }
-    }
-  else if ( gridtype == GRID_GENERIC )
-    {
-      int nlon = 0, nlat = 0;
-      if ( grib_get_long(gh, "Ni", &lpar) == 0 ) nlon = (int)lpar;
-      if ( grib_get_long(gh, "Nj", &lpar) == 0 ) nlat = (int)lpar;
+              {
+                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;
 
-      grid->size  = (int)numberOfPoints;
+        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
+        grid->size  = (int)numberOfPoints;
 
-      if ( nlon > 0 && nlat > 0 && nlon*nlat == grid->size )
-        {
-          grid->x.size = nlon;
-          grid->y.size = nlat;
-        }
-      else
-        {
-          grid->x.size = 0;
-          grid->y.size = 0;
-        }
-    }
-  else
-    {
-      Error("Unsupported grid type: %s", gridNamePtr(gridtype));
-    }
+        if ( nlon > 0 && nlat > 0 && nlon*nlat == grid->size )
+          {
+            grid->xsize = nlon;
+            grid->ysize = nlat;
+          }
+        else
+          {
+            grid->xsize = 0;
+            grid->ysize = 0;
+          }
 
-  if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_LONLAT || gridtype == GRID_PROJECTION )
-    {
-      long temp;
-      GRIB_CHECK(grib_get_long(gh, "uvRelativeToGrid", &temp), 0);
-      assert(temp == 0 || temp == 1);
-      grid->uvRelativeToGrid = (bool)temp;
+        break;
+      }
+    default:
+      {
+        Error("Unsupported grid type: %s", gridNamePtr(gridtype));
+        break;
+      }
     }
 
-  if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_LONLAT || gridtype == GRID_PROJECTION )
+  grid->isRotated = FALSE;
+  if ( gribapiGetIsRotated(gh) )
     {
-      long temp;
-      GRIB_CHECK(grib_get_long(gh, "iScansNegatively", &temp), 0);
-      grid->iScansNegatively = (bool)temp;
-      GRIB_CHECK(grib_get_long(gh, "jScansPositively", &temp), 0);
-      grid->jScansPositively = (bool)temp;
-      GRIB_CHECK(grib_get_long(gh, "jPointsAreConsecutive", &temp), 0);
-      grid->jPointsAreConsecutive = (bool)temp;
-      grid->scanningMode = 128*grid->iScansNegatively + 64*grid->jScansPositively + 32*grid->jPointsAreConsecutive;
-      /* scanningMode  = 128 * iScansNegatively + 64 * jScansPositively + 32 * jPointsAreConsecutive;
-                   64  = 128 * 0                + 64 *        1         + 32 * 0
-                   00  = 128 * 0                + 64 *        0         + 32 * 0
-                   96  = 128 * 0                + 64 *        1         + 32 * 1
-         Default / implicit scanning mode is 64:
-                            i and j scan positively, i points are consecutive (row-major)        */
-#ifdef HIRLAM_EXTENSIONS
-      if (cdiDebugExt>=30)
-      {
-        //  indicatorOfParameter=33,indicatorOfTypeOfLevel=105,level
-        long paramId, levelTypeId, levelId;
-        GRIB_CHECK(grib_get_long(gh, "indicatorOfParameter", &paramId), 0);
-        GRIB_CHECK(grib_get_long(gh, "indicatorOfTypeOfLevel", &levelTypeId), 0);
-        GRIB_CHECK(grib_get_long(gh, "level", &levelId), 0);
-        Message("(param,ltype,level) = (%3d,%3d,%4d); Scanning mode = %02d -> bits:(%1d.%1d.%1d)*32;  uvRelativeToGrid = %02d",\
-                (int)paramId, (int)levelTypeId, (int)levelId,
-                grid->scanningMode,grid->jPointsAreConsecutive,
-                grid->jScansPositively,grid->iScansNegatively,
-                grid->uvRelativeToGrid);
-      }
-#endif //HIRLAM_EXTENSIONS
+      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 */
+      if ( fabs(grid->ypole) > 0 ) grid->ypole = -grid->ypole;
+      grid->xpole =  grid->xpole - 180;
+      if ( fabs(grid->angle) > 0 ) grid->angle = -grid->angle;
     }
 
+  grid->xvals = NULL;
+  grid->yvals = NULL;
   grid->type  = gridtype;
-  grid->projtype  = projtype;
 }
 #endif
 /*
@@ -24933,7 +23967,7 @@ int reshUnpackResources(char * unpackBuffer, int unpackBufferSize,
 #ifdef HAVE_CONFIG_H
 #endif
 
-#ifndef  ERROR_H
+#ifndef  _ERROR_H
 #endif
 
 #include <stddef.h>  /* size_t */
@@ -24943,10 +23977,34 @@ int reshUnpackResources(char * unpackBuffer, int unpackBufferSize,
 
 #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;
+
+
+typedef struct {
+  size_t     nalloc;		/* number allocated >= nelems */
+  size_t     nelems;		/* length of the array */
+  cdi_att_t  value[MAX_ATTRIBUTES];
+} cdi_atts_t;
+
 
 typedef struct
 {
-  bool     flag;
+  int      flag;
   int      index;
   int      mlevelID;
   int      flevelID;
@@ -24971,15 +24029,15 @@ ensinfo_t;
 
 typedef struct
 {
-  bool        isUsed;
-  bool        flag;
+  int         flag;
+  int         isUsed;
   int         mvarID;
   int         fvarID;
   int         param;
   int         gridID;
   int         zaxisID;
   int         tsteptype; /* TSTEP_* */
-  int         datatype;  /* CDI_DATATYPE_PACKX for GRIB data, else CDI_DATATYPE_FLT32 or CDI_DATATYPE_FLT64 */
+  int         datatype;  /* DATATYPE_PACKX for GRIB data, else DATATYPE_FLT32 or DATATYPE_FLT64 */
   int         instID;
   int         modelID;
   int         tableID;
@@ -24989,8 +24047,8 @@ typedef struct
   int         productDefinitionTemplate;
   int         chunktype;
   int         xyz;
-  bool        missvalused; /* true if missval is defined */
-  bool        lvalidrange;
+  int         missvalused; /* TRUE if missval is defined */
+  int         lvalidrange;
   char       *name;
   char       *longname;
   char       *stdname;
@@ -25019,9 +24077,9 @@ var_t;
 typedef struct
 {
   //set when a vlist is passed to streamDefVlist() to safeguard against modifications of the wrong vlist object
-  bool        immutable;
+  bool    immutable;
   //set if this vlist has been created by CDI itself, and must not be destroyed by the user, consequently
-  bool        internal;
+  bool    internal;
   int         self;
   int         nvars;        /* number of variables                */
   int         ngrids;
@@ -25056,7 +24114,8 @@ void     vlistDefVarTsteptype(int vlistID, int varID, int tsteptype);
 int      vlistInqVarMissvalUsed(int vlistID, int varID);
 int      vlistHasTime(int vlistID);
 
-int      cdiDelAtts(int vlistID, int varID);
+int      vlistDelAtts(int vlistID, int varID);
+int      vlistCopyVarAtts(int vlistID1, int varID_1, int vlistID2, int varID_2);
 
 void     vlistUnpack(char * buffer, int bufferSize, int * pos,
                      int originNamespace, void *context, int force_id);
@@ -25069,33 +24128,29 @@ int     vlistInqVarValidrange(int vlistID, int varID, double *validrange);
 
 void vlistInqVarDimorder(int vlistID, int varID, int (*outDimorder)[3]);
 
-int cdi_att_compare(vlist_t *a, int varIDA, vlist_t *b, int varIDB, int attnum);
+int vlist_att_compare(vlist_t *a, int varIDA, vlist_t *b, int varIDB, int attnum);
 
 void resize_opt_grib_entries(var_t *var, int nentries);
 
 
 
-static inline
-void vlistAdd2GridIDs(vlist_t *vlistptr, int gridID)
+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 ( gridIsEqual(vlistptr->gridIDs[index], gridID) ) break;
-    }
-
+    if (vlistptr->gridIDs[index] == gridID ) break;
   if ( index == ngrids )
     {
-      if ( ngrids >= MAX_GRIDS_PS )
+      if (ngrids >= MAX_GRIDS_PS)
         Error("Internal limit exceeded: more than %d grids.", MAX_GRIDS_PS);
-      vlistptr->gridIDs[ngrids] = gridID;
       ++(vlistptr->ngrids);
+      vlistptr->gridIDs[ngrids] = gridID;
     }
 }
 
-static inline
-void vlistAdd2ZaxisIDs(vlist_t *vlistptr, int zaxisID)
+static inline void
+vlistAdd2ZaxisIDs(vlist_t *vlistptr, int zaxisID)
 {
   int index, nzaxis = vlistptr->nzaxis;
   for ( index = 0; index < nzaxis; index++ )
@@ -25106,25 +24161,24 @@ void vlistAdd2ZaxisIDs(vlist_t *vlistptr, int zaxisID)
       if ( nzaxis >= MAX_ZAXES_PS )
 	Error("Internal limit exceeded: more than %d zaxis.", MAX_ZAXES_PS);
       vlistptr->zaxisIDs[nzaxis] = zaxisID;
-      ++(vlistptr->nzaxis);
+      vlistptr->nzaxis++;
     }
 }
 
-static inline
-void vlistAdd2SubtypeIDs(vlist_t *vlistptr, int subtypeID)
+static inline void
+vlistAdd2SubtypeIDs(vlist_t *vlistptr, int subtypeID)
 {
   if ( subtypeID == CDI_UNDEFID ) return;
 
   int index, nsubs = vlistptr->nsubtypes;
   for ( index = 0; index < nsubs; index++ )
-    if ( vlistptr->subtypeIDs[index] == subtypeID ) break;
-
+    if (vlistptr->subtypeIDs[index] == subtypeID ) break;
   if ( index == nsubs )
     {
-      if ( nsubs >= MAX_SUBTYPES_PS )
+      if (nsubs >= MAX_SUBTYPES_PS)
         Error("Internal limit exceeded: more than %d subs.", MAX_SUBTYPES_PS);
-      vlistptr->subtypeIDs[nsubs] = subtypeID;
       ++(vlistptr->nsubtypes);
+      vlistptr->subtypeIDs[nsubs] = subtypeID;
     }
 }
 
@@ -25160,9 +24214,8 @@ resOps vlistOps;
 #include <limits.h> /* INT_MAX     */
 
 
-double grid_missval = -9999.;
-int (*proj_lonlat_to_lcc_func)() = NULL;
-int (*proj_lcc_to_lonlat_func)() = NULL;
+#undef  UNDEFID
+#define UNDEFID -1
 
 /* the value in the second pair of brackets must match the length of
  * the longest string (including terminating NUL) */
@@ -25179,8 +24232,10 @@ static const char Grids[][17] = {
   /*  9 */  "unstructured",
   /* 10 */  "curvilinear",
   /* 11 */  "lcc",
-  /* 12 */  "projection",
-  /* 13 */  "characterXY",
+  /* 12 */  "lcc2",
+  /* 13 */  "laea",
+  /* 14 */  "sinusoidal",
+  /* 15 */  "projection",
 };
 
 /* must match table below */
@@ -25188,7 +24243,6 @@ enum xystdname_idx {
   grid_xystdname_grid_latlon,
   grid_xystdname_latlon,
   grid_xystdname_projection,
-  grid_xystdname_char,
 };
 static const char xystdname_tab[][2][24] = {
   [grid_xystdname_grid_latlon] = { "grid_longitude",
@@ -25197,8 +24251,7 @@ static const char xystdname_tab[][2][24] = {
                               "latitude" },
   [grid_xystdname_projection] = { "projection_x_coordinate",
                                   "projection_y_coordinate" },
-  [grid_xystdname_char] = { "region",
-                            "region" },
+
 };
 
 
@@ -25207,7 +24260,8 @@ 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 void   gridPack        ( void * gridptr, void * buff, int size,
+				int *position, void *context);
 static int    gridTxCode      ( void );
 
 static const resOps gridOps = {
@@ -25221,130 +24275,105 @@ static const resOps gridOps = {
 
 static int  GRID_Debug = 0;   /* If set to 1, debugging */
 
-
-grid_t *grid_to_pointer(int gridID)
+grid_t *gridID2Ptr(int gridID)
 {
   return (grid_t *)reshGetVal(gridID, &gridOps);
 }
-
+#define gridID2Ptr(gridID) (grid_t *)reshGetVal(gridID, &gridOps)
 #define gridMark4Update(gridID) reshSetStatus(gridID, &gridOps, RESH_DESYNC_IN_USE)
 
-static
-bool cdiInqAttConvertedToFloat(int gridID, int atttype, const char *attname, int attlen, double *attflt)
-{
-  bool status = true;
-
-  if ( atttype == CDI_DATATYPE_INT32 )
-    {
-      int attint[attlen];
-      cdiInqAttInt(gridID, CDI_GLOBAL, attname, attlen, attint);
-      for ( int i = 0; i < attlen; ++i ) attflt[i] = (double)attint[i];
-    }
-  else if ( atttype == CDI_DATATYPE_FLT32 || atttype == CDI_DATATYPE_FLT64 )
-    {
-      cdiInqAttFlt(gridID, CDI_GLOBAL, attname, attlen, attflt);
-    }
-  else
-    {
-      status = false;
-    }
-
-  return status;
-}
-
 
 void grid_init(grid_t *gridptr)
 {
   gridptr->self          = CDI_UNDEFID;
   gridptr->type          = CDI_UNDEFID;
   gridptr->proj          = CDI_UNDEFID;
-  gridptr->projtype      = CDI_UNDEFID;
   gridptr->mask          = NULL;
   gridptr->mask_gme      = NULL;
-  gridptr->x.vals        = NULL;
-  gridptr->x.cvals       = NULL;
-  gridptr->x.clength     = 0;
-  gridptr->y.vals        = NULL;
-  gridptr->y.cvals       = NULL;
-  gridptr->y.clength     = 0;
-  gridptr->x.bounds      = NULL;
-  gridptr->y.bounds      = NULL;
+  gridptr->xvals         = NULL;
+  gridptr->yvals         = NULL;
   gridptr->area          = NULL;
+  gridptr->xbounds       = NULL;
+  gridptr->ybounds       = NULL;
   gridptr->rowlon        = NULL;
   gridptr->nrowlon       = 0;
-
-  gridptr->x.first       = 0.0;
-  gridptr->x.last        = 0.0;
-  gridptr->x.inc         = 0.0;
-  gridptr->y.first       = 0.0;
-  gridptr->y.last        = 0.0;
-  gridptr->y.inc         = 0.0;
-
-  gridptr->gme.nd        = 0;
-  gridptr->gme.ni        = 0;
-  gridptr->gme.ni2       = 0;
-  gridptr->gme.ni3       = 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->x.size        = 0;
-  gridptr->y.size        = 0;
+  gridptr->xsize         = 0;
+  gridptr->ysize         = 0;
   gridptr->np            = 0;
-  gridptr->x.flag        = 0;
-  gridptr->y.flag        = 0;
+  gridptr->xdef          = 0;
+  gridptr->ydef          = 0;
   gridptr->isCyclic      = CDI_UNDEFID;
-
-  gridptr->lcomplex      = false;
-  gridptr->hasdims       = true;
-  gridptr->x.dimname[0]  = 0;
-  gridptr->y.dimname[0]  = 0;
-  gridptr->x.name[0]     = 0;
-  gridptr->y.name[0]     = 0;
-  gridptr->x.longname[0] = 0;
-  gridptr->y.longname[0] = 0;
-  gridptr->x.units[0]    = 0;
-  gridptr->y.units[0]    = 0;
-  gridptr->x.stdname     = NULL;
-  gridptr->y.stdname     = NULL;
+  gridptr->isRotated     = FALSE;
+  gridptr->xpole         = 0.0;
+  gridptr->ypole         = 0.0;
+  gridptr->angle         = 0.0;
+  gridptr->lcomplex      = 0;
+  gridptr->hasdims       = TRUE;
+  gridptr->xdimname[0]   = 0;
+  gridptr->ydimname[0]   = 0;
   gridptr->vdimname[0]   = 0;
-  gridptr->mapname[0]    = 0;
-  gridptr->mapping[0]    = 0;
+  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      = NULL;
+  gridptr->ystdname      = NULL;
   memset(gridptr->uuid, 0, CDI_UUID_SIZE);
   gridptr->name          = NULL;
   gridptr->vtable        = &cdiGridVtable;
-  gridptr->atts.nalloc   = MAX_ATTRIBUTES;
-  gridptr->atts.nelems   = 0;
-  gridptr->uvRelativeToGrid      = 0;   // Some models deliver wind U,V relative to the grid-cell
-  gridptr->iScansNegatively      = 0;
-  gridptr->jScansPositively      = 1;
-  gridptr->jPointsAreConsecutive = 0;
-  gridptr->scanningMode          = 128*gridptr->iScansNegatively + 64*gridptr->jScansPositively + 32*gridptr->jPointsAreConsecutive;
-  /* scanningMode  = 128 * iScansNegatively + 64 * jScansPositively + 32 * jPointsAreConsecutive;
-               64  = 128 * 0                + 64 *        1         + 32 * 0
-               00  = 128 * 0                + 64 *        0         + 32 * 0
-               96  = 128 * 0                + 64 *        1         + 32 * 1
-     Default / implicit scanning mode is 64:
-                        i and j scan positively, i points are consecutive (row-major)        */
+  gridptr->extraData     = NULL;
 }
 
 
-static
-void grid_free_components(grid_t *gridptr)
+static void
+grid_free_components(grid_t *gridptr)
 {
   void *p2free[] = { gridptr->mask, gridptr->mask_gme,
-                     gridptr->x.vals, gridptr->y.vals,
-                     gridptr->x.cvals, gridptr->y.cvals,
-                     gridptr->x.bounds, gridptr->y.bounds,
-                     gridptr->rowlon, gridptr->area,
-                     gridptr->reference, gridptr->name};
-
-  for ( size_t i = 0; i < sizeof(p2free)/sizeof(p2free[0]); ++i )
-    if ( p2free[i] ) Free(p2free[i]);
+                   gridptr->xvals, gridptr->yvals,
+                   gridptr->xbounds, gridptr->ybounds,
+                   gridptr->rowlon, gridptr->area,
+                   gridptr->reference, gridptr->name };
+  for (size_t i = 0; i < sizeof (p2free) / sizeof (p2free[0]); ++i)
+    if (p2free[i]) Free(p2free[i]);
 }
 
 void grid_free(grid_t *gridptr)
@@ -25353,46 +24382,46 @@ void grid_free(grid_t *gridptr)
   grid_init(gridptr);
 }
 
-static
-grid_t *gridNewEntry(cdiResH resH)
+static grid_t *
+gridNewEntry(cdiResH resH)
 {
   grid_t *gridptr = (grid_t*) Malloc(sizeof(grid_t));
   grid_init(gridptr);
-
-  if ( resH == CDI_UNDEFID )
+  if (resH == CDI_UNDEFID)
     gridptr->self = reshPut(gridptr, &gridOps);
   else
     {
       gridptr->self = resH;
       reshReplace(resH, gridptr, &gridOps);
     }
-
   return gridptr;
 }
 
 static
 void gridInit(void)
 {
-  static bool gridInitialized = false;
+  static int gridInitialized = 0;
+
   if ( gridInitialized ) return;
-  gridInitialized = true;
+
+  gridInitialized = 1;
 
   const char *env = getenv("GRID_DEBUG");
   if ( env ) GRID_Debug = atoi(env);
 }
 
-static
-void grid_copy_base_scalar_fields(grid_t *gridptrOrig, grid_t *gridptrDup)
+static void
+grid_copy_base_scalar_fields(grid_t *gridptrOrig, grid_t *gridptrDup)
 {
   memcpy(gridptrDup, gridptrOrig, sizeof(grid_t));
   gridptrDup->self = CDI_UNDEFID;
-  if ( gridptrOrig->reference )
+  if (gridptrOrig->reference)
     gridptrDup->reference = strdupx(gridptrOrig->reference);
 }
 
 
-static
-grid_t *grid_copy_base(grid_t *gridptrOrig)
+static grid_t *
+grid_copy_base(grid_t *gridptrOrig)
 {
   grid_t *gridptrDup = (grid_t *)Malloc(sizeof (*gridptrDup));
   gridptrOrig->vtable->copyScalarFields(gridptrOrig, gridptrDup);
@@ -25400,7 +24429,6 @@ grid_t *grid_copy_base(grid_t *gridptrOrig)
   return gridptrDup;
 }
 
-
 unsigned cdiGridCount(void)
 {
   return reshCountType(&gridOps);
@@ -25422,74 +24450,100 @@ void gridGetString(char *name, const char *gridstrname, size_t len)
   name[len - 1] = 0;
 }
 
-static inline
-void gridSetName(char *gridstrname, const char *name)
+static inline void
+gridSetName(char *gridstrname, const char *name)
 {
   strncpy(gridstrname, name, CDI_MAX_NAME);
   gridstrname[CDI_MAX_NAME - 1] = 0;
 }
 
-
-void cdiGridTypeInit(grid_t *gridptr, int gridtype, int size)
+void
+cdiGridTypeInit(grid_t *gridptr, int gridtype, int size)
 {
   gridptr->type = gridtype;
   gridptr->size = size;
 
-  if      ( gridtype == GRID_CURVILINEAR  ) gridptr->nvertex = 4;
-  else if ( gridtype == GRID_UNSTRUCTURED ) gridptr->x.size = size;
-
   switch (gridtype)
     {
+    case GRID_CURVILINEAR:
+      gridptr->nvertex = 4;
+      /* Fall through */
     case GRID_LONLAT:
     case GRID_GAUSSIAN:
     case GRID_GAUSSIAN_REDUCED:
     case GRID_TRAJECTORY:
-    case GRID_CURVILINEAR:
-    case GRID_UNSTRUCTURED:
-    case GRID_GME:
       {
         if ( gridtype == GRID_TRAJECTORY )
           {
-            if ( gridptr->x.name[0] == 0 ) gridSetName(gridptr->x.name, "tlon");
-            if ( gridptr->y.name[0] == 0 ) gridSetName(gridptr->y.name, "tlat");
+            if ( gridptr->xname[0] == 0 ) gridSetName(gridptr->xname, "tlon");
+            if ( gridptr->yname[0] == 0 ) gridSetName(gridptr->yname, "tlat");
           }
         else
           {
-            if ( gridptr->x.name[0] == 0 ) gridSetName(gridptr->x.name, "lon");
-            if ( gridptr->y.name[0] == 0 ) gridSetName(gridptr->y.name, "lat");
+            if ( gridptr->xname[0] == 0 ) gridSetName(gridptr->xname, "lon");
+            if ( gridptr->yname[0] == 0 ) gridSetName(gridptr->yname, "lat");
           }
+        gridSetName(gridptr->xlongname, "longitude");
+        gridSetName(gridptr->ylongname, "latitude");
 
-        gridSetName(gridptr->x.longname, "longitude");
-        gridSetName(gridptr->y.longname, "latitude");
-
-        gridptr->x.stdname = xystdname_tab[grid_xystdname_latlon][0];
-        gridptr->y.stdname = xystdname_tab[grid_xystdname_latlon][1];
-        gridSetName(gridptr->x.units, "degrees_east");
-        gridSetName(gridptr->y.units, "degrees_north");
+        /*
+        if ( gridtype == GRID_CURVILINEAR )
+          {
+            gridptr->xstdname = xystdname_tab[grid_xystdname_grid_latlon][0];
+            gridptr->ystdname = xystdname_tab[grid_xystdname_grid_latlon][1];
+            gridDefXunits(gridID, "degrees");
+            gridDefYunits(gridID, "degrees");
+          }
+        else
+        */
+          {
+            gridptr->xstdname = xystdname_tab[grid_xystdname_latlon][0];
+            gridptr->ystdname = xystdname_tab[grid_xystdname_latlon][1];
+            gridSetName(gridptr->xunits, "degrees_east");
+            gridSetName(gridptr->yunits, "degrees_north");
+          }
 
         break;
       }
-    case GRID_CHARXY:
+    case GRID_UNSTRUCTURED:
+      gridptr->xsize = size;
+      /* Fall through */
+    case GRID_GME:
       {
-        if ( gridptr->x.cvals )
-          gridptr->x.stdname = xystdname_tab[grid_xystdname_char][0];
-        if ( gridptr->y.cvals )
-          gridptr->y.stdname = xystdname_tab[grid_xystdname_char][0];
+        if ( gridptr->xname[0] == 0 ) gridSetName(gridptr->xname, "lon");
+        if ( gridptr->yname[0] == 0 ) gridSetName(gridptr->yname, "lat");
+        gridptr->xstdname = xystdname_tab[grid_xystdname_latlon][0];
+        gridptr->ystdname = xystdname_tab[grid_xystdname_latlon][1];
+        gridSetName(gridptr->xunits, "degrees_east");
+        gridSetName(gridptr->yunits, "degrees_north");
+        break;
       }
     case GRID_GENERIC:
-    case GRID_PROJECTION:
       {
-        if ( gridptr->x.name[0] == 0 ) gridSetName(gridptr->x.name, "x");
-        if ( gridptr->y.name[0] == 0 ) gridSetName(gridptr->y.name, "y");
-        if ( gridtype == GRID_PROJECTION )
-          {
-            gridSetName(gridptr->mapname, "Projection");
 
-            gridptr->x.stdname = xystdname_tab[grid_xystdname_projection][0];
-            gridptr->y.stdname = xystdname_tab[grid_xystdname_projection][1];
-            gridSetName(gridptr->x.units, "m");
-            gridSetName(gridptr->y.units, "m");
-          }
+        /* gridptr->xsize = size; */
+        if ( gridptr->xname[0] == 0 ) gridSetName(gridptr->xname, "x");
+        if ( gridptr->yname[0] == 0 ) gridSetName(gridptr->yname, "y");
+        /*
+        strcpy(gridptr->xstdname, "grid_longitude");
+        strcpy(gridptr->ystdname, "grid_latitude");
+        gridptr->xstdname = xystdname_tab[grid_xystdname_grid_latlon][0];
+        gridptr->ystdname = xystdname_tab[grid_xystdname_grid_latlon][1];
+        gridDefXunits(gridID, "degrees");
+        gridDefYunits(gridID, "degrees");
+        */
+        break;
+      }
+    case GRID_LCC2:
+    case GRID_SINUSOIDAL:
+    case GRID_LAEA:
+      {
+        if ( gridptr->xname[0] == 0 ) gridSetName(gridptr->xname, "x");
+        if ( gridptr->yname[0] == 0 ) gridSetName(gridptr->yname, "y");
+        gridptr->xstdname = xystdname_tab[grid_xystdname_projection][0];
+        gridptr->ystdname = xystdname_tab[grid_xystdname_projection][1];
+        gridSetName(gridptr->xunits, "m");
+        gridSetName(gridptr->yunits, "m");
         break;
       }
     }
@@ -25636,7 +24690,7 @@ void gridGenYvals(int gridtype, int ysize, double yfirst, double ylast, double y
 @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_PROJECTION}, @func{GRID_SPECTRAL},
+                     @func{GRID_LONLAT}, @func{GRID_LCC}, @func{GRID_SPECTRAL},
                      @func{GRID_GME}, @func{GRID_CURVILINEAR} and @func{GRID_UNSTRUCTURED}.
     @Item  size      Number of gridpoints.
 
@@ -25690,9 +24744,11 @@ int gridCreate(int gridtype, int size)
 static
 void gridDestroyKernel( grid_t * gridptr )
 {
+  int id;
+
   xassert ( gridptr );
 
-  int id = gridptr->self;
+  id = gridptr->self;
 
   grid_free_components(gridptr);
   Free( gridptr );
@@ -25712,12 +24768,11 @@ void gridDestroyKernel( grid_t * gridptr )
 */
 void gridDestroy(int gridID)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
   gridptr->vtable->destroy(gridptr);
 }
 
-static
-void gridDestroyP(void * gridptr)
+void gridDestroyP ( void * gridptr )
 {
   ((grid_t *)gridptr)->vtable->destroy((grid_t *)gridptr);
 }
@@ -25727,7 +24782,7 @@ const char *gridNamePtr(int gridtype)
 {
   int size = (int) (sizeof(Grids)/sizeof(Grids[0]));
 
-  const char *name = (gridtype >= 0 && gridtype < size) ? Grids[gridtype] : Grids[GRID_GENERIC];
+  const char *name = gridtype >= 0 && gridtype < size ? Grids[gridtype] : Grids[GRID_GENERIC];
 
   return name;
 }
@@ -25739,33 +24794,25 @@ void gridName(int gridtype, char *gridname)
 }
 
 static
-void *grid_key_to_ptr(grid_t *gridptr, int key)
+char *grid_key_to_string(grid_t *gridptr, int key)
 {
-  void *keyptr = NULL;
+  char *gridstring = NULL;
 
   switch (key)
     {
-    case CDI_KEY_XNAME:      keyptr = (void*)gridptr->x.name; break;
-    case CDI_KEY_XLONGNAME:  keyptr = (void*)gridptr->x.longname; break;
-    case CDI_KEY_XUNITS:     keyptr = (void*)gridptr->x.units; break;
-    case CDI_KEY_YNAME:      keyptr = (void*)gridptr->y.name; break;
-    case CDI_KEY_YLONGNAME:  keyptr = (void*)gridptr->y.longname; break;
-    case CDI_KEY_YUNITS:     keyptr = (void*)gridptr->y.units; break;
-    case CDI_KEY_XDIMNAME:   keyptr = (void*)gridptr->x.dimname; break;
-    case CDI_KEY_YDIMNAME:   keyptr = (void*)gridptr->y.dimname; break;
-    case CDI_KEY_VDIMNAME:   keyptr = (void*)gridptr->vdimname; break;
-    case CDI_KEY_MAPPING:    keyptr = (void*)gridptr->mapname; break;
-    case CDI_KEY_MAPNAME:    keyptr = (void*)gridptr->mapping; break;
+    case CDI_GRID_XDIMNAME: gridstring = gridptr->xdimname; break;
+    case CDI_GRID_YDIMNAME: gridstring = gridptr->ydimname; break;
+    case CDI_GRID_VDIMNAME: gridstring = gridptr->vdimname; break;
     }
 
-  return keyptr;
+  return gridstring;
 }
 
 /*
- at Function  cdiGridDefKeyStr
+ at Function  cdiGridDefString
 @Title     Define a CDI grid string value from a key
 
- at Prototype int cdiGridDefKeyStr(int gridID, int key, int size, const char *mesg)
+ at Prototype int cdiGridDefString(int gridID, int key, int size, const char *mesg)
 @Parameter
     @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
     @Item  key      The key to be searched
@@ -25773,37 +24820,37 @@ void *grid_key_to_ptr(grid_t *gridptr, int key)
     @Item  mesg     The address of a string where the data will be read
 
 @Description
-The function @func{cdiGridDefKeyStr} defines a CDI grid string value from a key.
+The function @func{cdiGridDefString} defines a CDI grid string value from a key.
 
 @Result
- at func{cdiGridDefKeyStr} returns 0 if OK and integer value on error.
+ at func{cdiGridDefString} returns 0 if OK and integer value on error.
 
 @EndFunction
 */
-int cdiGridDefKeyStr(int gridID, int key, int size, const char *mesg)
+int cdiGridDefString(int gridID, int key, int size, const char *mesg)
 {
   if ( size < 1 || mesg == NULL || *mesg == 0 ) return -1;
 
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  char *keyptr = (char*)grid_key_to_ptr(gridptr, key);
-  if ( keyptr == NULL )
+  char *gridstring = grid_key_to_string(gridptr, key);
+  if ( gridstring == NULL )
     {
       Warning("CDI grid string key %d not supported!", key);
       return -1;
     }
 
-  gridSetString(keyptr, mesg, (size_t)size);
+  gridSetString(gridstring, mesg, (size_t)size);
   gridMark4Update(gridID);
 
   return 0;
 }
 
 /*
- at Function  cdiGridInqKeyStr
+ at Function  cdiGridInqString
 @Title     Get a CDI grid string value from a key
 
- at Prototype int cdiGridInqKeyStr(int gridID, int key, int size, char *mesg)
+ at Prototype int cdiGridInqString(int gridID, int key, int size, char *mesg)
 @Parameter
     @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
     @Item  key      The key to be searched.
@@ -25814,26 +24861,26 @@ int cdiGridDefKeyStr(int gridID, int key, int size, const char *mesg)
                     is given by the predefined constant @func{CDI_MAX_NAME}.
 
 @Description
-The function @func{cdiGridInqKeyStr} return a CDI grid string value from a key.
+The function @func{cdiGridInqString} return a CDI grid string value from a key.
 
 @Result
- at func{cdiGridInqKeyStr} returns 0 if OK and integer value on error.
+ at func{cdiGridInqString} returns 0 if OK and integer value on error.
 
 @EndFunction
 */
-int cdiGridInqKeyStr(int gridID, int key, int size, char *mesg)
+int cdiGridInqString(int gridID, int key, int size, char *mesg)
 {
   if ( size < 1 || mesg == NULL ) return -1;
 
-  grid_t *gridptr = grid_to_pointer(gridID);
-  const char *keyptr = (const char*)grid_key_to_ptr(gridptr, key);
-  if ( keyptr == NULL)
+  grid_t *gridptr = gridID2Ptr(gridID);
+  const char *gridstring = grid_key_to_string(gridptr, key);
+  if ( gridstring == NULL)
     {
       Warning("CDI grid string key %d not supported!", key);
       return -1;
     }
 
-  gridGetString(mesg, keyptr, (size_t)size);
+  gridGetString(mesg, gridstring, (size_t)size);
 
   return 0;
 }
@@ -25854,7 +24901,12 @@ The function @func{gridDefXname} defines the name of a X-axis.
 */
 void gridDefXname(int gridID, const char *xname)
 {
-  (void)cdiGridDefKeyStr(gridID, CDI_KEY_XNAME, CDI_MAX_NAME, xname);
+  if ( xname && *xname )
+    {
+      grid_t *gridptr = gridID2Ptr(gridID);
+      gridSetName(gridptr->xname, xname);
+      gridMark4Update(gridID);
+    }
 }
 
 /*
@@ -25873,7 +24925,12 @@ The function @func{gridDefXlongname} defines the longname of a X-axis.
 */
 void gridDefXlongname(int gridID, const char *xlongname)
 {
-  (void)cdiGridDefKeyStr(gridID, CDI_KEY_XLONGNAME, CDI_MAX_NAME, xlongname);
+  if ( xlongname )
+    {
+      grid_t *gridptr = gridID2Ptr(gridID);
+      gridSetName(gridptr->xlongname, xlongname);
+      gridMark4Update(gridID);
+    }
 }
 
 /*
@@ -25892,7 +24949,12 @@ The function @func{gridDefXunits} defines the units of a X-axis.
 */
 void gridDefXunits(int gridID, const char *xunits)
 {
-  (void)cdiGridDefKeyStr(gridID, CDI_KEY_XUNITS, CDI_MAX_NAME, xunits);
+  if ( xunits )
+    {
+      grid_t *gridptr = gridID2Ptr(gridID);
+      gridSetName(gridptr->xunits, xunits);
+      gridMark4Update(gridID);
+    }
 }
 
 /*
@@ -25911,7 +24973,12 @@ The function @func{gridDefYname} defines the name of a Y-axis.
 */
 void gridDefYname(int gridID, const char *yname)
 {
-  (void)cdiGridDefKeyStr(gridID, CDI_KEY_YNAME, CDI_MAX_NAME, yname);
+  if ( yname && *yname )
+    {
+      grid_t *gridptr = gridID2Ptr(gridID);
+      gridSetName(gridptr->yname, yname);
+      gridMark4Update(gridID);
+    }
 }
 
 /*
@@ -25930,7 +24997,12 @@ The function @func{gridDefYlongname} defines the longname of a Y-axis.
 */
 void gridDefYlongname(int gridID, const char *ylongname)
 {
-  (void)cdiGridDefKeyStr(gridID, CDI_KEY_YLONGNAME, CDI_MAX_NAME, ylongname);
+  if ( ylongname )
+    {
+      grid_t *gridptr = gridID2Ptr(gridID);
+      gridSetName(gridptr->ylongname, ylongname);
+      gridMark4Update(gridID);
+    }
 }
 
 /*
@@ -25949,7 +25021,12 @@ The function @func{gridDefYunits} defines the units of a Y-axis.
 */
 void gridDefYunits(int gridID, const char *yunits)
 {
-  (void)cdiGridDefKeyStr(gridID, CDI_KEY_YUNITS, CDI_MAX_NAME, yunits);
+  if ( yunits )
+    {
+      grid_t *gridptr = gridID2Ptr(gridID);
+      gridSetName(gridptr->yunits, yunits);
+      gridMark4Update(gridID);
+    }
 }
 
 /*
@@ -25973,7 +25050,15 @@ The function @func{gridInqXname} returns the name of a X-axis.
 */
 void gridInqXname(int gridID, char *xname)
 {
-  (void)cdiGridInqKeyStr(gridID, CDI_KEY_XNAME, CDI_MAX_NAME, xname);
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  strcpy(xname, gridptr->xname);
+}
+
+const char *gridInqXnamePtr(int gridID)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
+  return gridptr->xname;
 }
 
 /*
@@ -25997,7 +25082,9 @@ The function @func{gridInqXlongname} returns the longname of a X-axis.
 */
 void gridInqXlongname(int gridID, char *xlongname)
 {
-  (void)cdiGridInqKeyStr(gridID, CDI_KEY_XLONGNAME, CDI_MAX_NAME, xlongname);
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  strcpy(xlongname, gridptr->xlongname);
 }
 
 /*
@@ -26021,18 +25108,19 @@ The function @func{gridInqXunits} returns the units of a X-axis.
 */
 void gridInqXunits(int gridID, char *xunits)
 {
-  (void)cdiGridInqKeyStr(gridID, CDI_KEY_XUNITS, CDI_MAX_NAME, xunits);
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  strcpy(xunits, gridptr->xunits);
 }
 
 
 void gridInqXstdname(int gridID, char *xstdname)
 {
-  if ( xstdname )
-    {
-      xstdname[0] = 0;
-      grid_t *gridptr = grid_to_pointer(gridID);
-      if ( gridptr->x.stdname ) strcpy(xstdname, gridptr->x.stdname);
-    }
+  grid_t *gridptr = gridID2Ptr(gridID);
+  if ( gridptr->xstdname )
+    strcpy(xstdname, gridptr->xstdname);
+  else
+    xstdname[0] = 0;
 }
 
 /*
@@ -26056,14 +25144,22 @@ The function @func{gridInqYname} returns the name of a Y-axis.
 */
 void gridInqYname(int gridID, char *yname)
 {
-  (void)cdiGridInqKeyStr(gridID, CDI_KEY_YNAME, CDI_MAX_NAME, yname);
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  strcpy(yname, gridptr->yname);
+}
+
+const char *gridInqYnamePtr(int gridID)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
+  return gridptr->yname;
 }
 
 /*
 @Function  gridInqYlongname
 @Title     Get the longname of a Y-axis
 
- at Prototype void gridInqYlongname(int gridID, char *longname)
+ at Prototype void gridInqXlongname(int gridID, char *longname)
 @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
@@ -26080,7 +25176,9 @@ The function @func{gridInqYlongname} returns the longname of a Y-axis.
 */
 void gridInqYlongname(int gridID, char *ylongname)
 {
-  (void)cdiGridInqKeyStr(gridID, CDI_KEY_YLONGNAME, CDI_MAX_NAME, ylongname);
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  strcpy(ylongname, gridptr->ylongname);
 }
 
 /*
@@ -26104,87 +25202,18 @@ The function @func{gridInqYunits} returns the units of a Y-axis.
 */
 void gridInqYunits(int gridID, char *yunits)
 {
-  (void)cdiGridInqKeyStr(gridID, CDI_KEY_YUNITS, CDI_MAX_NAME, yunits);
-}
-
-
-void gridInqYstdname(int gridID, char *ystdname)
-{
-  if ( ystdname )
-    {
-      ystdname[0] = 0;
-      grid_t *gridptr = grid_to_pointer(gridID);
-      if ( gridptr->y.stdname ) strcpy(ystdname, gridptr->y.stdname);
-    }
-}
-
-
-void gridDefProj(int gridID, int projID)
-{
-  grid_t *gridptr = grid_to_pointer(gridID);
-  gridptr->proj = projID;
-
-  if ( gridptr->type == GRID_CURVILINEAR )
-    {
-      grid_t *projptr = grid_to_pointer(projID);
-      if ( projptr->x.name[0] ) strcpy(gridptr->x.dimname, projptr->x.name);
-      if ( projptr->y.name[0] ) strcpy(gridptr->y.dimname, projptr->y.name);
-    }
-}
-
-
-int gridInqProj(int gridID)
-{
-  grid_t *gridptr = grid_to_pointer(gridID);
-  return gridptr->proj;
-}
-
-
-int gridInqProjType(int gridID)
-{
-  grid_t *gridptr = grid_to_pointer(gridID);
-
-  int projtype = gridptr->projtype;
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  if ( projtype == -1 )
-    {
-      char mapping[CDI_MAX_NAME]; mapping[0] = 0;
-      cdiGridInqKeyStr(gridID, CDI_KEY_MAPNAME, CDI_MAX_NAME, mapping);
-      if ( mapping[0] )
-        {
-          if      ( strcmp(mapping, "rotated_latitude_longitude") == 0 )   projtype = CDI_PROJ_RLL;
-          else if ( strcmp(mapping, "lambert_azimuthal_equal_area") == 0 ) projtype = CDI_PROJ_LAEA;
-          else if ( strcmp(mapping, "lambert_conformal_conic") == 0 )      projtype = CDI_PROJ_LCC;
-          else if ( strcmp(mapping, "sinusoidal") == 0 )                   projtype = CDI_PROJ_SINU;
-
-          gridptr->projtype = projtype;
-        }
-    }
-
-  return projtype;
+  strcpy(yunits, gridptr->yunits);
 }
 
-
-void gridVerifyProj(int gridID)
+void gridInqYstdname(int gridID, char *ystdname)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
-
-  int projtype = gridInqProjType(gridID);
-
-  if ( projtype == CDI_PROJ_RLL )
-    {
-      gridptr->x.stdname = xystdname_tab[grid_xystdname_grid_latlon][0];
-      gridptr->y.stdname = xystdname_tab[grid_xystdname_grid_latlon][1];
-      gridSetName(gridptr->x.units, "degrees");
-      gridSetName(gridptr->y.units, "degrees");
-    }
-  else if ( projtype == CDI_PROJ_LCC )
-    {
-      gridptr->x.stdname = xystdname_tab[grid_xystdname_projection][0];
-      gridptr->y.stdname = xystdname_tab[grid_xystdname_projection][1];
-      gridSetName(gridptr->x.units, "m");
-      gridSetName(gridptr->y.units, "m");
-    }
+  grid_t *gridptr = gridID2Ptr(gridID);
+  if ( gridptr->ystdname )
+    strcpy(ystdname, gridptr->ystdname);
+  else
+    ystdname[0] = 0;
 }
 
 /*
@@ -26202,14 +25231,14 @@ The function @func{gridInqType} returns the type of a Grid.
 @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_PROJECTION}, @func{GRID_SPECTRAL}, @func{GRID_GME},
+ at func{GRID_LONLAT}, @func{GRID_LCC}, @func{GRID_SPECTRAL}, @func{GRID_GME},
 @func{GRID_CURVILINEAR} and @func{GRID_UNSTRUCTURED}.
 
 @EndFunction
 */
 int gridInqType(int gridID)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
   return gridptr->type;
 }
@@ -26233,14 +25262,14 @@ The function @func{gridInqSize} returns the size of a Grid.
 */
 int gridInqSize(int gridID)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
   int size = gridptr->size;
 
   if ( size == 0 )
     {
-      int xsize = gridptr->x.size;
-      int ysize = gridptr->y.size;
+      int xsize = gridptr->xsize;
+      int ysize = gridptr->ysize;
 
       if ( ysize )
         size = xsize * ysize;
@@ -26269,7 +25298,7 @@ int nsp2trunc(int nsp)
 
 int gridInqTrunc(int gridID)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
   if ( gridptr->trunc == 0 )
     {
@@ -26277,7 +25306,7 @@ int gridInqTrunc(int gridID)
         gridptr->trunc = nsp2trunc(gridptr->size);
       /*
       else if      ( gridptr->type == GRID_GAUSSIAN )
-        gridptr->trunc = nlat2trunc(gridptr->y.size);
+        gridptr->trunc = nlat2trunc(gridptr->ysize);
       */
     }
 
@@ -26287,7 +25316,7 @@ int gridInqTrunc(int gridID)
 
 void gridDefTrunc(int gridID, int trunc)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
   if ( gridptr->trunc != trunc )
     {
@@ -26312,7 +25341,7 @@ The function @func{gridDefXsize} defines the number of values of a X-axis.
 */
 void gridDefXsize(int gridID, int xsize)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
   int gridSize = gridInqSize(gridID);
   if ( xsize > gridSize )
@@ -26322,18 +25351,18 @@ void gridDefXsize(int gridID, int xsize)
   if ( gridType == GRID_UNSTRUCTURED && xsize != gridSize )
     Error("xsize %d must be equal to gridsize %d for gridtype: UNSTRUCTURED", xsize, gridSize);
 
-  if ( gridptr->x.size != xsize )
+  if ( gridptr->xsize != xsize )
     {
       gridMark4Update(gridID);
-      gridptr->x.size = xsize;
+      gridptr->xsize = xsize;
     }
 
-  if ( gridType != GRID_UNSTRUCTURED && gridType != GRID_PROJECTION )
+  if ( gridType != GRID_UNSTRUCTURED )
     {
-      long axisproduct = gridptr->x.size*gridptr->y.size;
+      long axisproduct = gridptr->xsize*gridptr->ysize;
       if ( axisproduct > 0 && axisproduct != gridSize )
         Error("Inconsistent grid declaration! (xsize=%d ysize=%d gridsize=%d)",
-              gridptr->x.size, gridptr->y.size, gridSize);
+              gridptr->xsize, gridptr->ysize, gridSize);
     }
 }
 
@@ -26349,7 +25378,7 @@ void gridDefXsize(int gridID, int xsize)
 */
 void gridDefPrec(int gridID, int prec)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
   if ( gridptr->prec != prec )
     {
@@ -26370,7 +25399,8 @@ void gridDefPrec(int gridID, int prec)
 */
 int gridInqPrec(int gridID)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
+
   return gridptr->prec;
 }
 
@@ -26392,8 +25422,9 @@ The function @func{gridInqXsize} returns the number of values of a X-axis.
 */
 int gridInqXsize(int gridID)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
-  return gridptr->x.size;
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  return gridptr->xsize;
 }
 
 /*
@@ -26412,29 +25443,28 @@ The function @func{gridDefYsize} defines the number of values of a Y-axis.
 */
 void gridDefYsize(int gridID, int ysize)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
   int gridSize = gridInqSize(gridID);
 
   if ( ysize > gridSize )
     Error("ysize %d is greater then gridsize %d", ysize, gridSize);
 
-  int gridType = gridInqType(gridID);
-  if ( gridType == GRID_UNSTRUCTURED && ysize != gridSize )
+  if ( gridInqType(gridID) == GRID_UNSTRUCTURED && ysize != gridSize )
     Error("ysize %d must be equal gridsize %d for gridtype: UNSTRUCTURED", ysize, gridSize);
 
-  if ( gridptr->y.size != ysize )
+  if ( gridptr->ysize != ysize )
     {
       gridMark4Update(gridID);
-      gridptr->y.size = ysize;
+      gridptr->ysize = ysize;
     }
 
-  if ( gridType != GRID_UNSTRUCTURED && gridType != GRID_PROJECTION )
+  if ( gridInqType(gridID) != GRID_UNSTRUCTURED )
     {
-      long axisproduct = gridptr->x.size*gridptr->y.size;
+      long axisproduct = gridptr->xsize*gridptr->ysize;
       if ( axisproduct > 0 && axisproduct != gridSize )
         Error("Inconsistent grid declaration! (xsize=%d ysize=%d gridsize=%d)",
-              gridptr->x.size, gridptr->y.size, gridSize);
+              gridptr->xsize, gridptr->ysize, gridSize);
     }
 }
 
@@ -26456,8 +25486,9 @@ The function @func{gridInqYsize} returns the number of values of a Y-axis.
 */
 int gridInqYsize(int gridID)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
-  return gridptr->y.size;
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  return gridptr->ysize;
 }
 
 /*
@@ -26477,7 +25508,7 @@ of a Gaussian grid.
 */
 void gridDefNP(int gridID, int np)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
   if ( gridptr->np != np )
     {
@@ -26505,7 +25536,8 @@ of a Gaussian grid.
 */
 int gridInqNP(int gridID)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
+
   return gridptr->np;
 }
 
@@ -26521,7 +25553,7 @@ int gridInqNP(int gridID)
 */
 void gridDefRowlon(int gridID, int nrowlon, const int rowlon[])
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
   gridptr->rowlon = (int *) Malloc((size_t)nrowlon * sizeof(int));
   gridptr->nrowlon = nrowlon;
@@ -26541,7 +25573,7 @@ void gridDefRowlon(int gridID, int nrowlon, const int rowlon[])
 */
 void gridInqRowlon(int gridID, int *rowlon)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
   if ( gridptr->rowlon == 0 )  Error("undefined pointer!");
 
@@ -26579,7 +25611,7 @@ gridInqMaskSerial(grid_t *gridptr, int *mask)
 
 int gridInqMask(int gridID, int *mask)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
   return gridptr->vtable->inqMask(gridptr, mask);
 }
 
@@ -26613,7 +25645,7 @@ gridDefMaskSerial(grid_t *gridptr, const int *mask)
 
 void gridDefMask(int gridID, const int *mask)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
   gridptr->vtable->defMask(gridptr, mask);
   gridMark4Update(gridID);
 }
@@ -26626,7 +25658,7 @@ gridInqMaskGMESerial(grid_t *gridptr, int *mask_gme)
 
 int gridInqMaskGME(int gridID, int *mask)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
   return gridptr->vtable->inqMaskGME(gridptr, mask);
 }
 
@@ -26649,13 +25681,14 @@ gridDefMaskGMESerial(grid_t *gridptr, const int *mask)
 
 void gridDefMaskGME(int gridID, const int *mask)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
   gridptr->vtable->defMaskGME(gridptr, mask);
   gridMark4Update(gridID);
 }
 
-static
-int gridInqXValsSerial(grid_t *gridptr, double *xvals)
+
+static int
+gridInqXValsSerial(grid_t *gridptr, double *xvals)
 {
   long size;
   if ( gridptr->type == GRID_CURVILINEAR || gridptr->type == GRID_UNSTRUCTURED )
@@ -26663,12 +25696,12 @@ int gridInqXValsSerial(grid_t *gridptr, double *xvals)
   else if ( gridptr->type == GRID_GAUSSIAN_REDUCED )
     size = 2;
   else
-    size = gridptr->x.size;
+    size = gridptr->xsize;
 
   if ( CDI_Debug && size == 0 )
     Warning("size undefined for gridID = %d", gridptr->self);
 
-  if ( gridptr->x.vals )
+  if ( gridptr->xvals )
     {
       if ( size && xvals )
         {
@@ -26682,37 +25715,6 @@ int gridInqXValsSerial(grid_t *gridptr, double *xvals)
   return (int)size;
 }
 
-static
-int gridInqXCvalsSerial(grid_t *gridptr, char **xcvals)
-{
-  if ( gridptr->type != GRID_CHARXY )
-    Error("Function only valid for grid type 'GRID_CHARXY'.");
-
-  int size = gridptr->x.size;
-  int maxclength = 0;
-
-  const char **gridptr_xcvals = gridptr->vtable->inqXCvalsPtr(gridptr);
-  if ( gridptr_xcvals && size && xcvals )
-    {
-      maxclength = gridptr->x.clength;
-      for ( int i = 0; i < size; i++ )
-        memcpy(xcvals[i], gridptr_xcvals[i], (size_t)maxclength*sizeof(char));
-    }
-
-  return maxclength;
-}
-
-static
-int gridInqXIscSerial(grid_t *gridptr)
-{
-  int clen = gridptr->x.clength;
-  /*
-  if ( gridptr->type != GRID_CHARXY )
-    Error("Axis type is 'char' but grid is not type 'GRID_CHARXY'.");
-  */
-  return clen;
-}
-
 /*
 @Function  gridInqXvals
 @Title     Get all values of a X-axis
@@ -26735,26 +25737,13 @@ Otherwise, 0 is returned and @func{xvals} is empty.
 */
 int gridInqXvals(int gridID, double *xvals)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
   return gridptr->vtable->inqXVals(gridptr, xvals);
 }
 
 
-int gridInqXCvals(int gridID, char **xcvals)
-{
-  grid_t *gridptr = grid_to_pointer(gridID);
-  return gridptr->vtable->inqXCvals(gridptr, xcvals);
-}
-
-
-int gridInqXIsc(int gridID)
-{
-  grid_t *gridptr = grid_to_pointer(gridID);
-  return gridptr->vtable->inqXIsc(gridptr);
-}
-
-static
-void gridDefXValsSerial(grid_t *gridptr, const double *xvals)
+static void
+gridDefXValsSerial(grid_t *gridptr, const double *xvals)
 {
   int gridtype = gridptr->type;
 
@@ -26764,47 +25753,16 @@ void gridDefXValsSerial(grid_t *gridptr, const double *xvals)
   else if ( gridtype == GRID_GAUSSIAN_REDUCED )
     size = 2;
   else
-    size = gridptr->x.size;
+    size = gridptr->xsize;
 
   if ( size == 0 )
     Error("Size undefined for gridID = %d", gridptr->self);
 
-  if (gridptr->x.vals && CDI_Debug)
+  if (gridptr->xvals && CDI_Debug)
     Warning("values already defined!");
-  gridptr->x.vals = (double *)Realloc(gridptr->x.vals,
+  gridptr->xvals = (double *)Realloc(gridptr->xvals,
                                       (size_t)size * sizeof(double));
-  memcpy(gridptr->x.vals, xvals, (size_t)size * sizeof (double));
-}
-
-static
-int gridInqYCvalsSerial(grid_t *gridptr, char **ycvals)
-{
-  if ( gridptr->type != GRID_CHARXY )
-    Error("Function only valid for grid type 'GRID_CHARXY'.");
-
-  int size = gridptr->y.size;
-  int maxclength = 0;
-
-  const char **gridptr_ycvals = gridptr->vtable->inqYCvalsPtr(gridptr);
-  if ( gridptr_ycvals && size && ycvals )
-    {
-      maxclength = gridptr->y.clength;
-      for ( int i = 0; i < size; i++ )
-        memcpy(ycvals[i], gridptr_ycvals[i], (size_t)maxclength*sizeof(char));
-    }
-
-  return maxclength;
-}
-
-static
-int gridInqYIscSerial(grid_t *gridptr)
-{
-  int clen = gridptr->y.clength;
-  /*
-  if ( gridptr->type != GRID_CHARXY )
-    Error("Axis type is 'char' but grid is not type 'GRID_CHARXY'.");
-  */
-  return clen;
+  memcpy(gridptr->xvals, xvals, (size_t)size * sizeof (double));
 }
 
 /*
@@ -26823,22 +25781,23 @@ The function @func{gridDefXvals} defines all values of the X-axis.
 */
 void gridDefXvals(int gridID, const double *xvals)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
   gridptr->vtable->defXVals(gridptr, xvals);
   gridMark4Update(gridID);
 }
 
-static
-int gridInqYValsSerial(grid_t *gridptr, double *yvals)
+static int
+gridInqYValsSerial(grid_t *gridptr, double *yvals)
 {
   int gridtype = gridptr->type;
-  long size = (gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED)
-            ? gridptr->size : gridptr->y.size;
+  long size
+    = (gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED)
+    ? gridptr->size : gridptr->ysize;
 
   if ( CDI_Debug && size == 0 )
     Warning("size undefined for gridID = %d!", gridptr->self);
 
-  if ( gridptr->y.vals )
+  if ( gridptr->yvals )
     {
       if ( size && yvals )
         {
@@ -26874,39 +25833,26 @@ Otherwise, 0 is returned and @func{yvals} is empty.
 */
 int gridInqYvals(int gridID, double *yvals)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
   return gridptr->vtable->inqYVals(gridptr, yvals);
 }
 
-
-int gridInqYCvals(int gridID, char **ycvals)
-{
-  grid_t *gridptr = grid_to_pointer(gridID);
-  return gridptr->vtable->inqYCvals(gridptr, ycvals);
-}
-
-
-int gridInqYIsc(int gridID)
-{
-  grid_t *gridptr = grid_to_pointer(gridID);
-  return gridptr->vtable->inqYIsc(gridptr);
-}
-
-static
-void gridDefYValsSerial(grid_t *gridptr, const double *yvals)
+static void
+gridDefYValsSerial(grid_t *gridptr, const double *yvals)
 {
   int gridtype = gridptr->type;
-  long size = (gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED)
-            ? gridptr->size : gridptr->y.size;
+  long size
+    = (gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED)
+    ? gridptr->size : gridptr->ysize;
 
   if ( size == 0 )
     Error("Size undefined for gridID = %d!", gridptr->self);
 
-  if ( gridptr->y.vals && CDI_Debug )
+  if (gridptr->yvals && CDI_Debug)
     Warning("Values already defined!");
 
-  gridptr->y.vals = (double *)Realloc(gridptr->y.vals, (size_t)size * sizeof (double));
-  memcpy(gridptr->y.vals, yvals, (size_t)size * sizeof (double));
+  gridptr->yvals = (double *)Realloc(gridptr->yvals, (size_t)size * sizeof (double));
+  memcpy(gridptr->yvals, yvals, (size_t)size * sizeof (double));
 }
 
 
@@ -26926,7 +25872,7 @@ The function @func{gridDefYvals} defines all values of the Y-axis.
 */
 void gridDefYvals(int gridID, const double *yvals)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
   gridptr->vtable->defYVals(gridptr, yvals);
   gridMark4Update(gridID);
 }
@@ -26934,21 +25880,21 @@ void gridDefYvals(int gridID, const double *yvals)
 static double
 gridInqXValSerial(grid_t *gridptr, int index)
 {
-  double xval = gridptr->x.vals ? gridptr->x.vals[index] : 0;
+  double xval = gridptr->xvals ? gridptr->xvals[index] : 0;
   return xval;
 }
 
 
 double gridInqXval(int gridID, int index)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
   return gridptr->vtable->inqXVal(gridptr, index);
 }
 
 static double
 gridInqYValSerial(grid_t *gridptr, int index)
 {
-  double yval = gridptr->y.vals ? gridptr->y.vals[index] : 0;
+  double yval = gridptr->yvals ? gridptr->yvals[index] : 0;
   return yval;
 }
 
@@ -26964,7 +25910,7 @@ gridInqYValSerial(grid_t *gridptr, int index)
 */
 double gridInqYval(int gridID, int index)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
   return gridptr->vtable->inqYVal(gridptr, index);
 }
 
@@ -26980,24 +25926,24 @@ double gridInqYval(int gridID, int index)
 */
 double gridInqXinc(int gridID)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
-  double xinc = gridptr->x.inc;
+  grid_t *gridptr = gridID2Ptr(gridID);
+  double xinc = gridptr->xinc;
   const double *restrict xvals = gridptr->vtable->inqXValsPtr(gridptr);
 
   if ( (! (fabs(xinc) > 0)) && xvals )
     {
-      int xsize = gridptr->x.size;
+      int xsize = gridptr->xsize;
       if ( xsize > 1 )
         {
           xinc = fabs(xvals[xsize-1] - xvals[0])/(xsize-1);
-          for ( int i = 2; i < xsize; i++ )
+          for (size_t i = 2; i < (size_t)xsize; i++ )
             if ( fabs(fabs(xvals[i-1] - xvals[i]) - xinc) > 0.01*xinc )
               {
                 xinc = 0;
                 break;
               }
 
-          gridptr->x.inc = xinc;
+          gridptr->xinc = xinc;
         }
     }
 
@@ -27016,13 +25962,13 @@ double gridInqXinc(int gridID)
 */
 double gridInqYinc(int gridID)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
-  double yinc = gridptr->y.inc;
+  grid_t *gridptr = gridID2Ptr(gridID);
+  double yinc = gridptr->yinc;
   const double *yvals = gridptr->vtable->inqYValsPtr(gridptr);
 
   if ( (! (fabs(yinc) > 0)) && yvals )
     {
-      int ysize = gridptr->y.size;
+      int ysize = gridptr->ysize;
       if ( ysize > 1 )
         {
           yinc = yvals[1] - yvals[0];
@@ -27034,7 +25980,7 @@ double gridInqYinc(int gridID)
                 break;
               }
 
-          gridptr->y.inc = yinc;
+          gridptr->yinc = yinc;
         }
     }
 
@@ -27051,37 +25997,161 @@ double gridInqYinc(int gridID)
 
 @EndFunction
 */
-void gridInqParamRLL(int gridID, double *xpole, double *ypole, double *angle)
+double gridInqXpole(int gridID)
 {
-  *xpole = 0; *ypole = 0; *angle = 0;
+  // Xpole -> grid_north_pole_longitude
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  const char *projection = "rotated_latitude_longitude";
-  char mapping[CDI_MAX_NAME]; mapping[0] = 0;
-  cdiGridInqKeyStr(gridID, CDI_KEY_MAPNAME, CDI_MAX_NAME, mapping);
-  if ( mapping[0] && strcmp(mapping, projection) == 0 )
+  return gridptr->xpole;
+}
+
+/*
+ at Function
+ at Title
+
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
+
+ at EndFunction
+*/
+void gridDefXpole(int gridID, double xpole)
+{
+  // Xpole -> grid_north_pole_longitude
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  if ( gridptr->xstdname && memcmp(gridptr->xstdname, "grid", 4) != 0 )
+    gridptr->xstdname = xystdname_tab[grid_xystdname_grid_latlon][0];
+
+  if ( gridptr->isRotated != TRUE || IS_NOT_EQUAL(gridptr->xpole, xpole) )
     {
-      int atttype, attlen;
-      char attname[CDI_MAX_NAME+1];
+      gridptr->isRotated = TRUE;
+      gridptr->xpole = xpole;
+      gridMark4Update(gridID);
+    }
+}
 
-      int natts;
-      cdiInqNatts(gridID, CDI_GLOBAL, &natts);
+/*
+ at Function
+ at Title
 
-      for ( int iatt = 0; iatt < natts; ++iatt )
-        {
-          cdiInqAtt(gridID, CDI_GLOBAL, iatt, attname, &atttype, &attlen);
-          if ( attlen != 1 ) continue;
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
 
-          double attflt;
-          if ( cdiInqAttConvertedToFloat(gridID, atttype, attname, attlen, &attflt) )
-            {
-              if      ( strcmp(attname, "grid_north_pole_longitude") == 0 ) *xpole = attflt;
-              else if ( strcmp(attname, "grid_north_pole_latitude")  == 0 ) *ypole = attflt;
-              else if ( strcmp(attname, "north_pole_grid_longitude") == 0 ) *angle = attflt;
-            }
-        }
+ at EndFunction
+*/
+double gridInqYpole(int gridID)
+{
+  // Ypole -> grid_north_pole_latitude
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  return gridptr->ypole;
+}
+
+/*
+ at Function
+ at Title
+
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
+
+ at EndFunction
+*/
+void gridDefYpole(int gridID, double ypole)
+{
+  // Ypole -> grid_north_pole_latitude
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  if ( gridptr->ystdname && memcmp(gridptr->ystdname, "grid", 4) != 0 )
+    gridptr->ystdname = xystdname_tab[grid_xystdname_grid_latlon][1];
+
+  if ( gridptr->isRotated != TRUE || IS_NOT_EQUAL(gridptr->ypole, ypole) )
+    {
+      gridptr->isRotated = TRUE;
+      gridptr->ypole = ypole;
+      gridMark4Update(gridID);
+    }
+}
+
+/*
+ at Function
+ at Title
+
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
+
+ at EndFunction
+*/
+double gridInqAngle(int gridID)
+{
+  // Angle -> north_pole_grid_longitude
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  return gridptr->angle;
+}
+
+/*
+ at Function
+ at Title
+
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
+
+ at EndFunction<
+*/
+void gridDefAngle(int gridID, double angle)
+{
+  // Angle -> north_pole_grid_longitude
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  if ( gridptr->isRotated != TRUE || IS_NOT_EQUAL(gridptr->angle, angle) )
+    {
+      gridptr->isRotated = TRUE;
+      gridptr->angle = angle;
+      gridMark4Update(gridID);
+    }
+}
+
+/*
+ at Function
+ at Title
+
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
+
+ at EndFunction
+*/
+int gridInqGMEnd(int gridID)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  return gridptr->nd;
+}
+
+/*
+ at Function
+ at Title
+
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
+
+ at EndFunction
+*/
+void gridDefGMEnd(int gridID, int nd)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  if (gridptr->nd != nd)
+    {
+      gridptr->nd = nd;
+      gridMark4Update(gridID);
     }
-  else
-    Warning("%s mapping parameter missing!", projection);
 }
 
 /*
@@ -27094,21 +26164,49 @@ void gridInqParamRLL(int gridID, double *xpole, double *ypole, double *angle)
 
 @EndFunction
 */
-void gridDefParamRLL(int gridID, double xpole, double ypole, double angle)
+int gridInqGMEni(int gridID)
 {
-  cdiGridDefKeyStr(gridID, CDI_KEY_MAPPING, CDI_MAX_NAME, "rotated_pole");
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  return gridptr->ni;
+}
+
+/*
+ at Function
+ at Title
 
-  const char *mapping = "rotated_latitude_longitude";
-  cdiGridDefKeyStr(gridID, CDI_KEY_MAPNAME, CDI_MAX_NAME, mapping);
-  cdiDefAttTxt(gridID, CDI_GLOBAL, "grid_mapping_name", (int)(strlen(mapping)), mapping);
-  cdiDefAttFlt(gridID, CDI_GLOBAL, "grid_north_pole_longitude", CDI_DATATYPE_FLT64, 1, &xpole);
-  cdiDefAttFlt(gridID, CDI_GLOBAL, "grid_north_pole_latitude", CDI_DATATYPE_FLT64, 1, &ypole);
-  if ( IS_NOT_EQUAL(angle, 0) ) cdiDefAttFlt(gridID, CDI_GLOBAL, "north_pole_grid_longitude", CDI_DATATYPE_FLT64, 1, &angle);
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
 
-  grid_t *gridptr = grid_to_pointer(gridID);
-  gridptr->projtype = CDI_PROJ_RLL;
+ at EndFunction
+*/
+void gridDefGMEni(int gridID, int ni)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  if ( gridptr->ni != ni )
+    {
+      gridptr->ni = ni;
+      gridMark4Update(gridID);
+    }
+}
+
+/*
+ at Function
+ at Title
+
+ at Prototype
+ at Parameter
+    @Item  Grid identifier
+
+ at EndFunction
+*/
+int gridInqGMEni2(int gridID)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  gridVerifyProj(gridID);
+  return gridptr->ni2;
 }
 
 /*
@@ -27121,14 +26219,15 @@ void gridDefParamRLL(int gridID, double xpole, double ypole, double angle)
 
 @EndFunction
 */
-void gridInqParamGME(int gridID, int *nd, int *ni, int *ni2, int *ni3)
+void gridDefGMEni2(int gridID, int ni2)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  *nd  = gridptr->gme.nd;
-  *ni  = gridptr->gme.ni;
-  *ni2 = gridptr->gme.ni2;
-  *ni3 = gridptr->gme.ni3;
+  if ( gridptr->ni2 != ni2 )
+    {
+      gridptr->ni2 = ni2;
+      gridMark4Update(gridID);
+    }
 }
 
 /*
@@ -27141,16 +26240,20 @@ void gridInqParamGME(int gridID, int *nd, int *ni, int *ni2, int *ni3)
 
 @EndFunction
 */
-void gridDefParamGME(int gridID, int nd, int ni, int ni2, int ni3)
+int gridInqGMEni3(int gridID)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  return gridptr->ni3;
+}
 
-  if ( gridptr->gme.nd != nd )
+void gridDefGMEni3(int gridID, int ni3)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  if ( gridptr->ni3 != ni3 )
     {
-      gridptr->gme.nd  = nd;
-      gridptr->gme.ni  = ni;
-      gridptr->gme.ni2 = ni2;
-      gridptr->gme.ni3 = ni3;
+      gridptr->ni3 = ni3;
       gridMark4Update(gridID);
     }
 }
@@ -27167,7 +26270,7 @@ void gridDefParamGME(int gridID, int nd, int ni, int ni2, int ni3)
 */
 void gridChangeType(int gridID, int gridtype)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
   if ( CDI_Debug )
     Message("Changed grid type from %s to %s", gridNamePtr(gridptr->type), gridNamePtr(gridtype));
@@ -27182,12 +26285,11 @@ void gridChangeType(int gridID, int gridtype)
 static
 void grid_check_cyclic(grid_t *gridptr)
 {
-  gridptr->isCyclic = 0;
+  gridptr->isCyclic = FALSE;
   enum { numVertices = 4 };
-  size_t xsize = gridptr->x.size >= 0 ? (size_t)gridptr->x.size : 0,
-         ysize = gridptr->y.size >= 0 ? (size_t)gridptr->y.size : 0;
+  size_t xsize = gridptr->xsize >= 0 ? (size_t)gridptr->xsize : 0,
+    ysize = gridptr->ysize >= 0 ? (size_t)gridptr->ysize : 0;
   const double *xvals = gridptr->vtable->inqXValsPtr(gridptr),
-               *yvals = gridptr->vtable->inqYValsPtr(gridptr),
     (*xbounds)[numVertices]
     = (const double (*)[numVertices])gridptr->vtable->inqXBoundsPtr(gridptr);
 
@@ -27202,31 +26304,23 @@ void grid_check_cyclic(grid_t *gridptr)
           double 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 = 1;
+            if ( fabs(x0 - xvals[0]) < 0.01*xinc ) gridptr->isCyclic = TRUE;
         }
     }
   else if ( gridptr->type == GRID_CURVILINEAR )
     {
-      bool lcheck = true;
-      if ( yvals && xvals )
-        {
-          if ( (fabs(yvals[0] - yvals[xsize-1]) > fabs(yvals[0] - yvals[xsize*ysize-xsize])) &&
-               (fabs(yvals[xsize*ysize-xsize] - yvals[xsize*ysize-1]) > fabs(yvals[xsize-1] - yvals[xsize*ysize-1])) )
-            lcheck = false;
-        }
-      else lcheck = false;
-
-      if ( lcheck && xvals && xsize > 1 )
+      if ( xvals && xsize > 1 )
         {
           size_t nc = 0;
           for ( size_t j = 0; j < ysize; ++j )
             {
               size_t i1 = j*xsize,
-                     i2 = j*xsize+1,
-                     in = j*xsize+(xsize-1);
+                i2 = j*xsize+1,
+                in = j*xsize+(xsize-1);
               double val1 = xvals[i1],
-                     val2 = xvals[i2],
-                     valn = xvals[in];
+                val2 = xvals[i2],
+                valn = xvals[in];
+
               double xinc = fabs(val2-val1);
 
 	      if ( val1 <    1 && valn > 300 ) val1 += 360;
@@ -27239,16 +26333,16 @@ void grid_check_cyclic(grid_t *gridptr)
 
               nc += fabs(x0-val1) < 0.5*xinc;
             }
-          gridptr->isCyclic = nc > ysize/2;
+          gridptr->isCyclic = nc > ysize/2 ? TRUE : FALSE;
         }
 
-      if ( lcheck && xbounds && xsize > 1 )
+      if ( xbounds && xsize > 1 )
 	{
           bool isCyclic = true;
 	  for ( size_t j = 0; j < ysize; ++j )
 	    {
 	      size_t i1 = j*xsize,
-                     i2 = j*xsize+(xsize-1);
+                i2 = j*xsize+(xsize-1);
 	      for (size_t k1 = 0; k1 < numVertices; ++k1 )
 		{
 		  double val1 = xbounds[i1][k1];
@@ -27272,7 +26366,7 @@ void grid_check_cyclic(grid_t *gridptr)
               foundCloseVertices:
               ;
 	    }
-          gridptr->isCyclic = isCyclic;
+          gridptr->isCyclic = (int) isCyclic;
 	}
     }
 }
@@ -27280,19 +26374,27 @@ void grid_check_cyclic(grid_t *gridptr)
 
 int gridIsCircular(int gridID)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
   if ( gridptr->isCyclic == CDI_UNDEFID ) grid_check_cyclic(gridptr);
 
   return gridptr->isCyclic;
 }
 
+
+int gridIsRotated(int gridID)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  return gridptr->isRotated;
+}
+
 static
 bool compareXYvals(grid_t *gridRef, grid_t *gridTest)
 {
   bool differ = false;
 
-  int xsizeTest = gridTest->x.size, ysizeTest = gridTest->y.size;
+  int xsizeTest = gridTest->xsize, ysizeTest = gridTest->ysize;
   if ( !differ && xsizeTest > 0 && xsizeTest == gridRef->vtable->inqXVals(gridRef, NULL) )
     {
       const double *restrict xvalsRef = gridRef->vtable->inqXValsPtr(gridRef),
@@ -27325,95 +26427,96 @@ static
 bool compareXYvals2(grid_t *gridRef, grid_t *gridTest)
 {
   int gridsize = gridTest->size;
-  bool differ = ((gridTest->x.vals == NULL) ^ (gridRef->x.vals == NULL))
-             || ((gridTest->y.vals == NULL) ^ (gridRef->y.vals == NULL));
+  bool differ
+    = ((gridTest->xvals == NULL) ^ (gridRef->xvals == NULL))
+    || ((gridTest->yvals == NULL) ^ (gridRef->yvals == NULL));
 
   typedef double (*inqVal)(grid_t *grid, int index);
   inqVal inqXValRef = gridRef->vtable->inqXVal,
-         inqYValRef = gridRef->vtable->inqYVal,
-         inqXValTest = gridTest->vtable->inqXVal,
-         inqYValTest = gridTest->vtable->inqYVal;
+    inqYValRef = gridRef->vtable->inqXVal,
+    inqXValTest = gridTest->vtable->inqXVal,
+    inqYValTest = gridTest->vtable->inqYVal;
 
-  if ( !differ && gridTest->x.vals )
+  if ( !differ && gridTest->xvals )
     differ = fabs(inqXValTest(gridTest, 0) - inqXValRef(gridRef, 0)) > 1.e-9
-          || fabs(inqXValTest(gridTest, gridsize-1) - inqXValRef(gridRef, gridsize-1)) > 1.e-9;
+      || fabs(inqXValTest(gridTest, gridsize-1) - inqXValRef(gridRef, gridsize-1)) > 1.e-9;
 
-  if ( !differ && gridTest->y.vals )
+  if ( !differ && gridTest->yvals )
     differ = fabs(inqYValTest(gridTest, 0) - inqYValRef(gridRef, 0)) > 1.e-9
-          || fabs(inqYValTest(gridTest, gridsize-1) - inqYValRef(gridRef, gridsize-1)) > 1.e-9;
+      || fabs(inqYValTest(gridTest, gridsize-1) - inqYValRef(gridRef, gridsize-1)) > 1.e-9;
 
   return differ;
 }
 
 static
-bool gridCompare(int gridID, const grid_t *grid, bool coord_compare)
+bool gridCompare(int gridID, const grid_t *grid)
 {
   bool differ = true;
-  const grid_t *gridRef = grid_to_pointer(gridID);
+  grid_t *gridRef = gridID2Ptr(gridID);
 
   if ( grid->type == gridRef->type || grid->type == GRID_GENERIC )
     {
       if ( grid->size == gridRef->size )
 	{
 	  differ = false;
-	  if ( grid->type == GRID_LONLAT || grid->type == GRID_PROJECTION )
+	  if ( grid->type == GRID_LONLAT )
 	    {
 	      /*
 	      printf("gridID      %d\n", gridID);
-	      printf("grid.xdef   %d\n", grid->x.flag);
-	      printf("grid.ydef   %d\n", grid->y.flag);
-	      printf("grid.xsize  %d\n", grid->x.size);
-	      printf("grid.ysize  %d\n", grid->y.size);
-	      printf("grid.xfirst %f\n", grid->x.first);
-	      printf("grid.yfirst %f\n", grid->y.first);
+	      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->x.inc);
-	      printf("grid.yinc   %f\n", grid->y.inc);
+	      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->x.size == gridRef->x.size && grid->y.size == gridRef->y.size )
+	      if ( grid->xsize == gridRef->xsize && grid->ysize == gridRef->ysize )
 		{
-		  if ( grid->x.flag == 2 && grid->y.flag == 2 )
+		  if ( grid->xdef == 2 && grid->ydef == 2 )
 		    {
-		      if ( ! (IS_EQUAL(grid->x.first, 0) && IS_EQUAL(grid->x.last, 0) && IS_EQUAL(grid->x.inc, 0)) &&
-			   ! (IS_EQUAL(grid->y.first, 0) && IS_EQUAL(grid->y.last, 0) && IS_EQUAL(grid->y.inc, 0)) &&
-			   IS_NOT_EQUAL(grid->x.first, grid->x.last) && IS_NOT_EQUAL(grid->y.first, grid->y.last) )
+		      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->x.first, gridInqXval(gridID, 0)) ||
-			       IS_NOT_EQUAL(grid->y.first, gridInqYval(gridID, 0)))
+			  if ( IS_NOT_EQUAL(grid->xfirst, gridInqXval(gridID, 0)) ||
+			       IS_NOT_EQUAL(grid->yfirst, gridInqYval(gridID, 0)))
 			    {
 			      differ = true;
 			    }
-			  if ( !differ && fabs(grid->x.inc) > 0 &&
-			       fabs(fabs(grid->x.inc) - fabs(gridRef->x.inc)) > fabs(grid->x.inc/1000))
+			  if ( !differ && fabs(grid->xinc) > 0 &&
+			       fabs(fabs(grid->xinc) - fabs(gridRef->xinc)) > fabs(grid->xinc/1000))
 			    {
 			      differ = true;
 			    }
-			  if ( !differ && fabs(grid->y.inc) > 0 &&
-			       fabs(fabs(grid->y.inc) - fabs(gridRef->y.inc)) > fabs(grid->y.inc/1000))
+			  if ( !differ && fabs(grid->yinc) > 0 &&
+			       fabs(fabs(grid->yinc) - fabs(gridRef->yinc)) > fabs(grid->yinc/1000))
 			    {
 			      differ = true;
 			    }
 			}
 		    }
-		  else if ( grid->x.vals && grid->y.vals )
-                    differ = gridRef->vtable->compareXYFull((grid_t *)gridRef, (grid_t *)grid);
+		  else if ( grid->xvals && grid->yvals )
+                    differ = gridRef->vtable->compareXYFull(gridRef, (grid_t *)grid);
 		}
 	      else
 		differ = true;
 	    }
 	  else if ( grid->type == GRID_GENERIC )
 	    {
-	      if ( grid->x.size == gridRef->x.size && grid->y.size == gridRef->y.size )
+	      if ( grid->xsize == gridRef->xsize && grid->ysize == gridRef->ysize )
 		{
-		  if ( grid->x.flag == 1 && grid->y.flag == 1
-                       && grid->x.vals && grid->y.vals )
-                    differ = gridRef->vtable->compareXYFull((grid_t *)gridRef, (grid_t *)grid);
+		  if ( grid->xdef == 1 && grid->ydef == 1
+                       && grid->xvals && grid->yvals )
+                    differ = gridRef->vtable->compareXYFull(gridRef, (grid_t *)grid);
 		}
-	      else if ( (grid->y.size == 0 || grid->y.size == 1) &&
-			grid->x.size == gridRef->x.size*gridRef->y.size )
+	      else if ( (grid->ysize == 0 || grid->ysize == 1) &&
+			grid->xsize == gridRef->xsize*gridRef->ysize )
 		{
 		}
 	      else
@@ -27421,21 +26524,21 @@ bool gridCompare(int gridID, const grid_t *grid, bool coord_compare)
 	    }
 	  else if ( grid->type == GRID_GAUSSIAN )
 	    {
-	      if ( grid->x.size == gridRef->x.size && grid->y.size == gridRef->y.size )
+	      if ( grid->xsize == gridRef->xsize && grid->ysize == gridRef->ysize )
 		{
-		  if ( grid->x.flag == 2 && grid->y.flag == 2 )
+		  if ( grid->xdef == 2 && grid->ydef == 2 )
 		    {
-		      if ( ! (IS_EQUAL(grid->x.first, 0) && IS_EQUAL(grid->x.last, 0) && IS_EQUAL(grid->x.inc, 0)) &&
-			   ! (IS_EQUAL(grid->y.first, 0) && IS_EQUAL(grid->y.last, 0)) )
-			if ( fabs(grid->x.first - gridInqXval(gridID, 0)) > 0.0015 ||
-			     fabs(grid->y.first - gridInqYval(gridID, 0)) > 0.0015 ||
-			     (fabs(grid->x.inc)>0 && fabs(fabs(grid->x.inc) - fabs(gridRef->x.inc)) > fabs(grid->x.inc/1000)) )
+		      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(gridRef->xinc)) > fabs(grid->xinc/1000)) )
 			  {
 			    differ = true;
 			  }
 		    }
-		  else if ( grid->x.vals && grid->y.vals )
-                    differ = gridRef->vtable->compareXYFull((grid_t *)gridRef, (grid_t *)grid);
+		  else if ( grid->xvals && grid->yvals )
+                    differ = gridRef->vtable->compareXYFull(gridRef, (grid_t *)grid);
 		}
 	      else
 		differ = true;
@@ -27444,89 +26547,62 @@ bool gridCompare(int gridID, const grid_t *grid, bool coord_compare)
 	    {
 	      /*
 	      printf("gridID      %d\n", gridID);
-	      printf("grid.xsize  %d\n", grid->x.size);
-	      printf("grid.ysize  %d\n", grid->y.size);
-	      printf("grid.xfirst %f\n", grid->x.vals[0]);
-	      printf("grid.yfirst %f\n", grid->y.vals[0]);
+	      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->x.vals[grid->size-1]);
-	      printf("grid.ylast  %f\n", grid->y.vals[grid->size-1]);
+	      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->x.size == gridRef->x.size && grid->y.size == gridRef->y.size )
-                differ = gridRef->vtable->compareXYAO((grid_t *)gridRef, (grid_t *)grid);
+	      if ( grid->xsize == gridRef->xsize && grid->ysize == gridRef->ysize )
+                differ = gridRef->vtable->compareXYAO(gridRef, (grid_t *)grid);
 	    }
 	  else if ( grid->type == GRID_UNSTRUCTURED )
 	    {
-              if ( coord_compare )
+              /* FIXME: not octet 0 but octet 7 is guaranteed  non-zero
+               * for any non-NULL UUID */
+              differ = differ || ( gridRef->uuid[0] && grid->uuid[0] && memcmp(gridRef->uuid, grid->uuid, CDI_UUID_SIZE) != 0 );
+
+              if ( !differ &&
+                   ((grid->xvals == NULL) ^ (gridRef->xvals == NULL)) &&
+                   ((grid->yvals == NULL) ^ (gridRef->yvals == NULL)) )
                 {
-                  differ = grid->nvertex != gridRef->nvertex
-                    || gridRef->vtable->compareXYAO((grid_t *)gridRef, (grid_t *)grid);
+                  int nvertexA, nvertexB, numberA, numberB;
+                  differ = ( (nvertexA = grid->nvertex)
+                             && (nvertexB = gridRef->nvertex)
+                             && (nvertexA != nvertexB) )
+                    || (numberA = grid->number, numberB = gridRef->number,
+                        ( (numberA)
+                          && numberB
+                          && (numberA != numberB) )
+                        || ( (numberA && numberB)
+                             && (grid->position) != (gridRef->position) ) );
                 }
-              else
+              else if ( !differ )
                 {
-                  /* FIXME: not octet 0 but octet 7 is guaranteed  non-zero for any non-NULL UUID */
-                  differ = differ || (gridRef->uuid[0] && grid->uuid[0] && memcmp(gridRef->uuid, grid->uuid, CDI_UUID_SIZE) != 0);
-
-                  if ( !differ &&
-                       ((grid->x.vals == NULL) ^ (gridRef->x.vals == NULL)) &&
-                       ((grid->y.vals == NULL) ^ (gridRef->y.vals == NULL)) )
-                    {
-                      int nvertexA, nvertexB, numberA, numberB;
-                      differ = ( (nvertexA = grid->nvertex)
-                                 && (nvertexB = gridRef->nvertex)
-                                 && (nvertexA != nvertexB) )
-                        || (numberA = grid->number, numberB = gridRef->number,
-                            ( (numberA)
-                              && numberB
-                              && (numberA != numberB) )
-                            || ( (numberA && numberB)
-                                 && (grid->position) != (gridRef->position) ) );
-                    }
-                  else if ( !differ )
-                    {
-                      differ = grid->nvertex != gridRef->nvertex
-                        || grid->number != gridRef->number
-                        || (grid->number > 0 && grid->position != gridRef->position)
-                        || gridRef->vtable->compareXYAO((grid_t *)gridRef, (grid_t *)grid);
-                    }
+                  differ = grid->nvertex != gridRef->nvertex
+                    || grid->number != gridRef->number
+                    || (grid->number > 0 && grid->position != gridRef->position)
+                    || gridRef->vtable->compareXYAO(gridRef, (grid_t *)grid);
                 }
-            }
+              }
 	}
     }
 
-  if ( (grid->scanningMode != gridInqScanningMode(gridID)) || (grid->uvRelativeToGrid != gridInqUvRelativeToGrid(gridID)) )
-    {
-      // often grid definition may differ in UV-relativeToGrid
-      differ = 1;
-#ifdef HIRLAM_EXTENSIONS
-      if ( cdiDebugExt>=200 )
-        printf("gridCompare(gridID=%d): Differs: grid.scanningMode [%d] != gridInqScanningMode(gridID) [%d] or  grid.uvRelativeToGrid [%ld] != gridInqUvRelativeToGrid(gridID) [%d]\n",
-               gridID, grid->scanningMode, gridInqScanningMode(gridID), grid->uvRelativeToGrid, gridInqUvRelativeToGrid(gridID) );
-#endif // HIRLAM_EXTENSIONS
-    }
   return differ;
 }
 
-/*
-int gridIsEqual(int gridID1, int gridID2)
-{
-  const grid_t *grid2 = grid_to_pointer(gridID2);
-
-  int grid_is_equal = gridCompare(gridID1, grid2, true) == false;
-
-  return grid_is_equal;
-}
-*/
 
-int gridCompareP(void *gridptr1, void *gridptr2)
+int gridCompareP ( void * gridptr1, void * gridptr2 )
 {
-  grid_t *g1 = ( grid_t * ) gridptr1;
-  grid_t *g2 = ( grid_t * ) gridptr2;
+  grid_t * g1 = ( grid_t * ) gridptr1;
+  grid_t * g2 = ( grid_t * ) gridptr2;
   enum { equal = 0,
          differ = -1 };
   int i, size;
@@ -27536,40 +26612,62 @@ int gridCompareP(void *gridptr1, void *gridptr2)
 
   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->x.flag        != g2->x.flag       ) return differ;
-  if ( g1->y.flag        != g2->y.flag       ) return differ;
-  if ( g1->gme.nd        != g2->gme.nd       ) return differ;
-  if ( g1->gme.ni        != g2->gme.ni       ) return differ;
-  if ( g1->gme.ni2       != g2->gme.ni2      ) return differ;
-  if ( g1->gme.ni3       != g2->gme.ni3      ) 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->x.size        != g2->x.size       ) return differ;
-  if ( g1->y.size        != g2->y.size       ) return differ;
+  if ( g1->xsize         != g2->xsize        ) return differ;
+  if ( g1->ysize         != g2->ysize        ) return differ;
   if ( g1->lcomplex      != g2->lcomplex     ) return differ;
 
-  if ( IS_NOT_EQUAL(g1->x.first       , g2->x.first)       ) return differ;
-  if ( IS_NOT_EQUAL(g1->y.first	      , g2->y.first)       ) return differ;
-  if ( IS_NOT_EQUAL(g1->x.last        , g2->x.last)        ) return differ;
-  if ( IS_NOT_EQUAL(g1->y.last        , g2->y.last)        ) return differ;
-  if ( IS_NOT_EQUAL(g1->x.inc	      , g2->x.inc)         ) return differ;
-  if ( IS_NOT_EQUAL(g1->y.inc	      , g2->y.inc)         ) return differ;
-  if ( IS_NOT_EQUAL(g1->uvRelativeToGrid     , g2->uvRelativeToGrid)     ) return differ;
-  if ( IS_NOT_EQUAL(g1->scanningMode         , g2->scanningMode)         ) 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;
 
   const double *restrict g1_xvals = g1->vtable->inqXValsPtr(g1),
-               *restrict g2_xvals = g2->vtable->inqXValsPtr(g2);
+    *restrict g2_xvals = g2->vtable->inqXValsPtr(g2);
   if ( g1_xvals )
     {
       if ( g1->type == GRID_UNSTRUCTURED || g1->type == GRID_CURVILINEAR )
         size = g1->size;
       else
-        size = g1->x.size;
+        size = g1->xsize;
       xassert ( size );
 
       if ( !g2_xvals ) return differ;
@@ -27581,13 +26679,13 @@ int gridCompareP(void *gridptr1, void *gridptr2)
     return differ;
 
   const double *restrict g1_yvals = g1->vtable->inqYValsPtr(g1),
-               *restrict g2_yvals = g2->vtable->inqYValsPtr(g2);
+    *restrict g2_yvals = g2->vtable->inqYValsPtr(g2);
   if ( g1_yvals )
     {
       if ( g1->type == GRID_UNSTRUCTURED || g1->type == GRID_CURVILINEAR )
 	size = g1->size;
       else
-	size = g1->y.size;
+	size = g1->ysize;
       xassert ( size );
 
       if ( !g2_yvals ) return differ;
@@ -27599,7 +26697,7 @@ int gridCompareP(void *gridptr1, void *gridptr2)
     return differ;
 
   const double *restrict g1_area = g1->vtable->inqAreaPtr(g1),
-               *restrict g2_area = g2->vtable->inqAreaPtr(g2);
+    *restrict g2_area = g2->vtable->inqAreaPtr(g2);
   if ( g1_area )
     {
       xassert ( g1->size );
@@ -27620,7 +26718,7 @@ int gridCompareP(void *gridptr1, void *gridptr2)
         if ( g1->type == GRID_CURVILINEAR || g1->type == GRID_UNSTRUCTURED )
           size = g1->nvertex * g1->size;
         else
-          size = g1->nvertex * g1->x.size;
+          size = g1->nvertex * g1->xsize;
         xassert ( size );
 
         if ( !(g2_xbounds = g2->vtable->inqXBoundsPtr(g2)) ) return differ;
@@ -27640,28 +26738,26 @@ int gridCompareP(void *gridptr1, void *gridptr2)
         if ( g1->type == GRID_CURVILINEAR || g1->type == GRID_UNSTRUCTURED )
           size = g1->nvertex * g1->size;
         else
-          size = g1->nvertex * g1->y.size;
+          size = g1->nvertex * g1->ysize;
         xassert ( size );
 
         if ( ! (g2_ybounds = g2->vtable->inqYBoundsPtr(g2)) ) return differ;
 
         for ( i = 0; i < size; i++ )
-          if ( IS_NOT_EQUAL(g1->y.bounds[i], g2->y.bounds[i]) ) return differ;
+          if ( IS_NOT_EQUAL(g1->ybounds[i], g2->ybounds[i]) ) return differ;
       }
     else if ( g2->vtable->inqYBoundsPtr(g2) )
       return differ;
   }
 
-  if (strcmp(g1->x.name, g2->x.name)) return differ;
-  if (strcmp(g1->y.name, g2->y.name)) return differ;
-  if (strcmp(g1->x.longname, g2->x.longname)) return differ;
-  if (strcmp(g1->y.longname, g2->y.longname)) return differ;
-  if (g1->x.stdname != g2->x.stdname) return differ;
-  if (g1->y.stdname != g2->y.stdname) return differ;
-  if (strcmp(g1->x.units, g2->x.units)) return differ;
-  if (strcmp(g1->y.units, g2->y.units)) return differ;
-
-  if (strcmp(g1->mapping, g2->mapping)) return differ;
+  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 (g1->xstdname != g2->xstdname) return differ;
+  if (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 )
     {
@@ -27689,14 +26785,13 @@ int gridCompareP(void *gridptr1, void *gridptr2)
   else if ( g2->mask_gme )
     return differ;
 
-  if ( memcmp(g1->uuid, g2->uuid, CDI_UUID_SIZE) )
+  if (memcmp(g1->uuid, g2->uuid, CDI_UUID_SIZE))
     return differ;
 
   return equal;
 }
 
-static
-void gridComplete(grid_t *grid)
+static void gridComplete(grid_t *grid)
 {
   int gridID = grid->self;
   gridDefPrec(gridID, grid->prec);
@@ -27709,74 +26804,108 @@ void gridComplete(grid_t *grid)
     case GRID_UNSTRUCTURED:
     case GRID_CURVILINEAR:
     case GRID_GENERIC:
+    case GRID_LCC:
+    case GRID_LCC2:
+    case GRID_SINUSOIDAL:
+    case GRID_LAEA:
     case GRID_PROJECTION:
-    case GRID_CHARXY:
       {
-	if ( grid->x.size > 0 ) gridDefXsize(gridID, grid->x.size);
-	if ( grid->y.size > 0 ) gridDefYsize(gridID, grid->y.size);
+	if ( grid->xsize > 0 ) gridDefXsize(gridID, grid->xsize);
+	if ( grid->ysize > 0 ) gridDefYsize(gridID, grid->ysize);
 
         if ( gridtype == GRID_GAUSSIAN ) gridDefNP(gridID, grid->np);
 
 	if ( grid->nvertex > 0 )
 	  gridDefNvertex(gridID, grid->nvertex);
 
-	if ( grid->x.flag == 2 )
+	if ( grid->xdef == 2 )
 	  {
-            assert(gridtype != GRID_UNSTRUCTURED && gridtype != GRID_CURVILINEAR);
-	    double *xvals = (double *) Malloc((size_t)grid->x.size * sizeof (double));
-	    gridGenXvals(grid->x.size, grid->x.first, grid->x.last, grid->x.inc, xvals);
-	    grid->x.vals = xvals;
-	    // gridDefXinc(gridID, grid->x.inc);
+            assert(gridtype != GRID_UNSTRUCTURED
+                   && gridtype != GRID_CURVILINEAR);
+	    double *xvals
+              = (double *) Malloc((size_t)grid->xsize * sizeof (double));
+	    gridGenXvals(grid->xsize, grid->xfirst, grid->xlast, grid->xinc, xvals);
+	    grid->xvals = xvals;
+	    /*
+	    gridDefXinc(gridID, grid->xinc);
+	    */
 	  }
 
-	if ( grid->y.flag == 2 )
+	if ( grid->ydef == 2 )
 	  {
-            assert(gridtype != GRID_UNSTRUCTURED && gridtype != GRID_CURVILINEAR);
-	    double *yvals = (double *) Malloc((size_t)grid->y.size * sizeof (double));
-	    gridGenYvals(gridtype, grid->y.size, grid->y.first, grid->y.last, grid->y.inc, yvals);
-	    grid->y.vals = yvals;
-	    // gridDefYinc(gridID, grid->y.inc);
+            assert(gridtype != GRID_UNSTRUCTURED
+                   && gridtype != GRID_CURVILINEAR);
+	    double *yvals
+              = (double *) Malloc((size_t)grid->ysize * sizeof (double));
+	    gridGenYvals(gridtype, grid->ysize, grid->yfirst, grid->ylast, grid->yinc, yvals);
+	    grid->yvals = yvals;
+	    /*
+	    gridDefYinc(gridID, grid->yinc);
+	    */
 	  }
 
-	if ( grid->projtype == CDI_PROJ_RLL )
+	if ( grid->isRotated )
 	  {
-	    if ( grid->x.name[0] == 0 || grid->x.name[0] == 'x' ) strcpy(grid->x.name, "rlon");
-	    if ( grid->y.name[0] == 0 || grid->y.name[0] == 'y' ) strcpy(grid->y.name, "rlat");
-	    if ( grid->x.longname[0] == 0 ) strcpy(grid->x.longname, "longitude in rotated pole grid");
-	    if ( grid->y.longname[0] == 0 ) strcpy(grid->y.longname, "latitude in rotated pole grid");
-            grid->x.stdname = xystdname_tab[grid_xystdname_grid_latlon][0];
-            grid->y.stdname = xystdname_tab[grid_xystdname_grid_latlon][1];
-	    if ( grid->x.units[0] == 0 ) strcpy(grid->x.units, "degrees");
-	    if ( grid->y.units[0] == 0 ) strcpy(grid->y.units, "degrees");
+	    gridDefXname(gridID, "rlon");
+	    gridDefYname(gridID, "rlat");
+	    gridDefXlongname(gridID, "longitude in rotated pole grid");
+	    gridDefYlongname(gridID, "latitude in rotated pole grid");
+            grid->xstdname = xystdname_tab[grid_xystdname_grid_latlon][0];
+            grid->ystdname = xystdname_tab[grid_xystdname_grid_latlon][1];
+	    gridDefXunits(gridID, "degrees");
+	    gridDefYunits(gridID, "degrees");
+
+	    gridDefXpole(gridID, grid->xpole);
+	    gridDefYpole(gridID, grid->ypole);
+	    gridDefAngle(gridID, grid->angle);
 	  }
 
-        if ( gridtype == GRID_UNSTRUCTURED )
+        switch (gridtype)
           {
-            int number = grid->number;
-            int position = grid->position >= 0 ? grid->position : 0;
-            if ( number > 0 ) gridDefNumber(gridID, number);
-            gridDefPosition(gridID, position);
-          }
+          case GRID_LAEA:
+            gridDefLaea(gridID, grid->laea_a, grid->laea_lon_0, grid->laea_lat_0);
+            break;
+          case GRID_LCC2:
+            gridDefLcc2(gridID, grid->lcc2_a, grid->lcc2_lon_0, grid->lcc2_lat_0, grid->lcc2_lat_1, grid->lcc2_lat_2);
+            break;
+          case 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);
+            break;
+          case GRID_UNSTRUCTURED:
+            {
+              int number = grid->number;
+              int position = grid->position >= 0 ? grid->position : 0;
+              if ( number > 0 )
+                {
+                  gridDefNumber(gridID, number);
+                  gridDefPosition(gridID, position);
+                }
+            }
+            break;
+	  }
 
 	break;
       }
     case GRID_GAUSSIAN_REDUCED:
       {
 	gridDefNP(gridID, grid->np);
-	gridDefYsize(gridID, grid->y.size);
-        if ( grid->x.flag == 2 )
+	gridDefYsize(gridID, grid->ysize);
+        if ( grid->xdef == 2 )
           {
-            double xvals[2] = { grid->x.first, grid->x.last };
+            double xvals[2] = { grid->xfirst, grid->xlast };
             gridDefXvals(gridID, xvals);
           }
 
-        if ( grid->y.flag == 2 )
+        if ( grid->ydef == 2 )
 	  {
-	    double *yvals = (double *) Malloc((size_t)grid->y.size * sizeof (double));
-	    gridGenYvals(gridtype, grid->y.size, grid->y.first, grid->y.last, grid->y.inc, yvals);
-            grid->y.vals = yvals;
+	    double *yvals
+              = (double *) Malloc((size_t)grid->ysize * sizeof (double));
+	    gridGenYvals(gridtype, grid->ysize, grid->yfirst, grid->ylast, grid->yinc, yvals);
+            grid->yvals = yvals;
 	    /*
-	    gridDefYinc(gridID, grid->y.inc);
+	    gridDefYinc(gridID, grid->yinc);
 	    */
 	  }
 	break;
@@ -27794,18 +26923,21 @@ void gridComplete(grid_t *grid)
       }
     case GRID_GME:
       {
-        gridDefParamGME(gridID, grid->gme.nd, grid->gme.ni, grid->gme.ni2, grid->gme.ni3);
+        gridDefGMEnd(gridID, grid->nd);
+        gridDefGMEni(gridID, grid->ni);
+        gridDefGMEni2(gridID, grid->ni2);
+        gridDefGMEni3(gridID, grid->ni3);
         break;
       }
       /*
     case GRID_GENERIC:
       {
-        if ( grid->x.size > 0 && grid->y.size > 0 )
+        if ( grid->xsize > 0 && grid->ysize > 0 )
           {
-            gridDefXsize(gridID, grid->x.size);
-            gridDefYsize(gridID, grid->y.size);
-            if ( grid->x.vals ) gridDefXvals(gridID, grid->x.vals);
-            if ( grid->y.vals ) gridDefYvals(gridID, grid->y.vals);
+            gridDefXsize(gridID, grid->xsize);
+            gridDefYsize(gridID, grid->ysize);
+            if ( grid->xvals ) gridDefXvals(gridID, grid->xvals);
+            if ( grid->yvals ) gridDefYvals(gridID, grid->yvals);
           }
         break;
       }
@@ -27823,85 +26955,101 @@ void gridComplete(grid_t *grid)
       }
     }
 
-  grid->x.name[CDI_MAX_NAME - 1] = 0;
-  grid->x.longname[CDI_MAX_NAME - 1] = 0;
-  grid->x.units[CDI_MAX_NAME - 1] = 0;
-  grid->y.name[CDI_MAX_NAME - 1] = 0;
-  grid->y.longname[CDI_MAX_NAME - 1] = 0;
-  grid->y.units[CDI_MAX_NAME - 1] = 0;
+  grid->xname[CDI_MAX_NAME - 1] = 0;
+  grid->xlongname[CDI_MAX_NAME - 1] = 0;
+  grid->xunits[CDI_MAX_NAME - 1] = 0;
+  grid->yname[CDI_MAX_NAME - 1] = 0;
+  grid->ylongname[CDI_MAX_NAME - 1] = 0;
+  grid->yunits[CDI_MAX_NAME - 1] = 0;
 }
 
-#define GRID_STR_SERIALIZE(gridP) { gridP->x.dimname, gridP->y.dimname,  \
-    gridP->vdimname, gridP->x.name, gridP->y.name,  \
-    gridP->x.longname, gridP->y.longname, \
-    gridP->x.units, gridP->y.units }
+#define GRID_STR_SERIALIZE(gridP) { gridP->xdimname, gridP->ydimname,  \
+    gridP->vdimname, gridP->xname, gridP->yname,  \
+    gridP->xlongname, gridP->ylongname, \
+    gridP->xunits, gridP->yunits }
 
 int gridGenerate(const grid_t *grid)
 {
   int gridtype = grid->type;
   int gridID = gridCreate(gridtype, grid->size);
-  grid_t *restrict gridptr = grid_to_pointer(gridID);
+  grid_t *restrict gridptr = gridID2Ptr(gridID);
   gridptr->prec = grid->prec;
-  gridptr->x.size = grid->x.size;
-  gridptr->y.size = grid->y.size;
+  gridptr->xsize = grid->xsize;
+  gridptr->ysize = grid->ysize;
   gridptr->np = grid->np;
   gridptr->nvertex = grid->nvertex;
-  gridptr->x.flag = grid->x.flag;
+  gridptr->xdef = grid->xdef;
   int valdef_group1 = 0;
   static const int valdef_group1_tab[] = {
     GRID_LONLAT, GRID_GAUSSIAN, GRID_UNSTRUCTURED, GRID_CURVILINEAR,
-    GRID_GENERIC, GRID_PROJECTION
+    GRID_GENERIC, GRID_LCC, GRID_LCC2, GRID_SINUSOIDAL, GRID_LAEA,
+    GRID_PROJECTION
   };
   for ( size_t i = 0; i < sizeof (valdef_group1_tab) / sizeof (valdef_group1_tab[0]); ++i)
     valdef_group1 |= (gridtype == valdef_group1_tab[i]);
-  if ( valdef_group1 && grid->x.flag == 1 )
-    {
-      gridDefXvals(gridID, grid->x.vals);
-      if ( grid->x.bounds )
-        gridDefXbounds(gridID, grid->x.bounds);
-    }
-  gridptr->x.first = grid->x.first;
-  gridptr->x.last = grid->x.last;
-  gridptr->x.inc = grid->x.inc;
-  gridptr->y.flag = grid->y.flag;
-  if ( (valdef_group1 || gridtype == GRID_GAUSSIAN_REDUCED) && grid->y.flag == 1)
-    {
-      gridDefYvals(gridID, grid->y.vals);
-      if ( grid->y.bounds )
-        gridDefYbounds(gridID, grid->y.bounds);
-    }
-  gridptr->y.first = grid->y.first;
-  gridptr->y.last = grid->y.last;
-  gridptr->y.inc = grid->y.inc;
+  if ( valdef_group1 && grid->xdef == 1 )
+    {
+      gridDefXvals(gridID, grid->xvals);
+      if ( grid->xbounds )
+        gridDefXbounds(gridID, grid->xbounds);
+    }
+  gridptr->xfirst = grid->xfirst;
+  gridptr->xlast = grid->xlast;
+  gridptr->xinc = grid->xinc;
+  gridptr->ydef = grid->ydef;
+  if ( (valdef_group1 || gridtype == GRID_GAUSSIAN_REDUCED) && grid->ydef == 1)
+    {
+      gridDefYvals(gridID, grid->yvals);
+      if ( grid->ybounds )
+        gridDefYbounds(gridID, grid->ybounds);
+    }
+  gridptr->yfirst = grid->yfirst;
+  gridptr->ylast = grid->ylast;
+  gridptr->yinc = grid->yinc;
+  gridptr->isRotated = grid->isRotated;
+  gridptr->xpole = grid->xpole;
+  gridptr->ypole = grid->ypole;
+  gridptr->angle = grid->angle;
   if ( valdef_group1 && grid->area)
     gridDefArea(gridID, grid->area);
+  gridptr->laea_a = grid->laea_a;
+  gridptr->laea_lon_0 = grid->laea_lon_0;
+  gridptr->laea_lat_0 = grid->laea_lat_0;
+  gridptr->lcc2_a = grid->lcc2_a;
+  gridptr->lcc2_lon_0 = grid->lcc2_lon_0;
+  gridptr->lcc2_lat_0 = grid->lcc2_lat_0;
+  gridptr->lcc2_lat_1 = grid->lcc2_lat_1;
+  gridptr->lcc2_lat_2 = grid->lcc2_lat_2;
+  gridptr->lcc_originLon = grid->lcc_originLon;
+  gridptr->lcc_originLat = grid->lcc_originLat;
+  gridptr->lcc_lonParY = grid->lcc_lonParY;
+  gridptr->lcc_lat1 = grid->lcc_lat1;
+  gridptr->lcc_lat2 = grid->lcc_lat2;
+  gridptr->lcc_xinc = grid->lcc_xinc;
+  gridptr->lcc_yinc = grid->lcc_yinc;
+  gridptr->lcc_projflag = grid->lcc_projflag;
+  gridptr->lcc_scanflag = grid->lcc_scanflag;
   gridptr->number = grid->number;
   gridptr->position = grid->position;
-  gridptr->uvRelativeToGrid       = grid->uvRelativeToGrid;
-  gridptr->scanningMode           = grid->scanningMode;
-  gridptr->iScansNegatively       = grid->iScansNegatively;
-  gridptr->jScansPositively       = grid->jScansPositively;
-  gridptr->jPointsAreConsecutive  = grid->jPointsAreConsecutive;
   memcpy(gridptr->uuid, grid->uuid, CDI_UUID_SIZE);
   if ( gridtype == GRID_UNSTRUCTURED && grid->reference )
     gridDefReference(gridID, grid->reference);
   if ( gridtype == GRID_PROJECTION )
     gridptr->name = strdup(grid->name);
   if ( gridtype == GRID_GAUSSIAN_REDUCED )
-    gridDefRowlon(gridID, grid->y.size, grid->rowlon);
+    gridDefRowlon(gridID, grid->ysize, grid->rowlon);
   gridptr->trunc = grid->trunc;
   gridptr->lcomplex = grid->lcomplex;
-  gridptr->gme.nd = grid->gme.nd;
-  gridptr->gme.ni = grid->gme.ni;
-  gridptr->gme.ni2 = grid->gme.ni2;
-  gridptr->gme.ni3 = grid->gme.ni3;
+  gridptr->nd = grid->nd;
+  gridptr->ni = grid->ni;
+  gridptr->ni2 = grid->ni2;
+  gridptr->ni3 = grid->ni3;
   const char *grid_str_tab[] = GRID_STR_SERIALIZE(grid);
   char *gridptr_str_tab[] = GRID_STR_SERIALIZE(gridptr);
   for (size_t i = 0; i < sizeof (grid_str_tab) / sizeof (grid_str_tab[0]); ++i)
     if ( grid_str_tab[i][0] )
       memcpy(gridptr_str_tab[i], grid_str_tab[i], CDI_MAX_NAME);
   gridComplete(gridptr);
-
   return gridID;
 }
 
@@ -27918,38 +27066,38 @@ grid_copy_base_array_fields(grid_t *gridptrOrig, grid_t *gridptrDup)
       memcpy(gridptrDup->rowlon, gridptrOrig->rowlon, nrowlon * sizeof(int));
     }
 
-  if ( gridptrOrig->x.vals != NULL )
+  if ( gridptrOrig->xvals != NULL )
     {
-      size_t size  = irregular ? gridsize : (size_t)gridptrOrig->x.size;
+      size_t size  = irregular ? gridsize : (size_t)gridptrOrig->xsize;
 
-      gridptrDup->x.vals = (double *)Malloc(size * sizeof (double));
-      memcpy(gridptrDup->x.vals, gridptrOrig->x.vals, size * sizeof (double));
+      gridptrDup->xvals = (double *)Malloc(size * sizeof (double));
+      memcpy(gridptrDup->xvals, gridptrOrig->xvals, size * sizeof (double));
     }
 
-  if ( gridptrOrig->y.vals != NULL )
+  if ( gridptrOrig->yvals != NULL )
     {
-      size_t size  = irregular ? gridsize : (size_t)gridptrOrig->y.size;
+      size_t size  = irregular ? gridsize : (size_t)gridptrOrig->ysize;
 
-      gridptrDup->y.vals = (double *)Malloc(size * sizeof (double));
-      memcpy(gridptrDup->y.vals, gridptrOrig->y.vals, size * sizeof (double));
+      gridptrDup->yvals = (double *)Malloc(size * sizeof (double));
+      memcpy(gridptrDup->yvals, gridptrOrig->yvals, size * sizeof (double));
     }
 
-  if ( gridptrOrig->x.bounds != NULL )
+  if ( gridptrOrig->xbounds != NULL )
     {
-      size_t size  = (irregular ? gridsize : (size_t)gridptrOrig->x.size)
+      size_t size  = (irregular ? gridsize : (size_t)gridptrOrig->xsize)
         * (size_t)gridptrOrig->nvertex;
 
-      gridptrDup->x.bounds = (double *)Malloc(size * sizeof (double));
-      memcpy(gridptrDup->x.bounds, gridptrOrig->x.bounds, size * sizeof (double));
+      gridptrDup->xbounds = (double *)Malloc(size * sizeof (double));
+      memcpy(gridptrDup->xbounds, gridptrOrig->xbounds, size * sizeof (double));
     }
 
-  if ( gridptrOrig->y.bounds != NULL )
+  if ( gridptrOrig->ybounds != NULL )
     {
-      size_t size = (irregular ? gridsize : (size_t)gridptrOrig->y.size)
+      size_t size = (irregular ? gridsize : (size_t)gridptrOrig->ysize)
         * (size_t)gridptrOrig->nvertex;
 
-      gridptrDup->y.bounds = (double *)Malloc(size * sizeof (double));
-      memcpy(gridptrDup->y.bounds, gridptrOrig->y.bounds, size * sizeof (double));
+      gridptrDup->ybounds = (double *)Malloc(size * sizeof (double));
+      memcpy(gridptrDup->ybounds, gridptrOrig->ybounds, size * sizeof (double));
     }
 
   {
@@ -28000,7 +27148,7 @@ The function @func{gridDuplicate} duplicates a horizontal Grid.
 */
 int gridDuplicate(int gridID)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
   grid_t *gridptrnew = gridptr->vtable->copy(gridptr);
   int gridIDnew = reshPut(gridptrnew, &gridOps);
   gridptrnew->self = gridIDnew;
@@ -28010,7 +27158,7 @@ int gridDuplicate(int gridID)
 
 void gridCompress(int gridID)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
   int gridtype = gridInqType(gridID);
   if ( gridtype == GRID_UNSTRUCTURED )
@@ -28057,12 +27205,12 @@ void gridCompress(int gridID)
 	  /* fprintf(stderr, "grid compress %d %d %d\n", i, j, gridsize); */
 	  gridsize = nselect;
 	  gridptr->size  = (int)gridsize;
-	  gridptr->x.size = (int)gridsize;
-	  gridptr->y.size = (int)gridsize;
+	  gridptr->xsize = (int)gridsize;
+	  gridptr->ysize = (int)gridsize;
 
-          double **resizeP[] = { &gridptr->x.vals, &gridptr->y.vals,
+          double **resizeP[] = { &gridptr->xvals, &gridptr->yvals,
                                  &gridptr->area,
-                                 &gridptr->x.bounds, &gridptr->y.bounds };
+                                 &gridptr->xbounds, &gridptr->ybounds };
           size_t newSize[] = { gridsize, gridsize, gridsize, nv*gridsize,
                                nv*gridsize };
           for ( size_t i = 0; i < sizeof (resizeP) / sizeof (resizeP[0]); ++i)
@@ -28097,7 +27245,7 @@ gridDefAreaSerial(grid_t *gridptr, const double *area)
 
 void gridDefArea(int gridID, const double *area)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
   gridptr->vtable->defArea(gridptr, area);
   gridMark4Update(gridID);
 }
@@ -28112,7 +27260,7 @@ gridInqAreaSerial(grid_t *gridptr, double *area)
 
 void gridInqArea(int gridID, double *area)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
   gridptr->vtable->inqArea(gridptr, area);
 }
 
@@ -28124,7 +27272,7 @@ gridHasAreaBase(grid_t *gridptr)
 
 int gridHasArea(int gridID)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
   return gridptr->vtable->hasArea(gridptr);
 }
 
@@ -28136,14 +27284,14 @@ static const double *gridInqAreaPtrBase(grid_t *gridptr)
 
 const double *gridInqAreaPtr(int gridID)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
   return gridptr->vtable->inqAreaPtr(gridptr);
 }
 
 
 void gridDefNvertex(int gridID, int nvertex)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
   if (gridptr->nvertex != nvertex)
     {
@@ -28155,7 +27303,8 @@ void gridDefNvertex(int gridID, int nvertex)
 
 int gridInqNvertex(int gridID)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
+
   return gridptr->nvertex;
 }
 
@@ -28188,7 +27337,7 @@ gridDefBoundsGeneric(grid_t *gridptr, const double *bounds, int regularSize,
 static void
 gridDefXBoundsSerial(grid_t *gridptr, const double *xbounds)
 {
-  gridDefBoundsGeneric(gridptr, xbounds, gridptr->x.size, &gridptr->x.bounds);
+  gridDefBoundsGeneric(gridptr, xbounds, gridptr->xsize, &gridptr->xbounds);
 }
 
 /*
@@ -28207,7 +27356,7 @@ The function @func{gridDefXbounds} defines all bounds of the X-axis.
 */
 void gridDefXbounds(int gridID, const double *xbounds)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
   gridptr->vtable->defXBounds(gridptr, xbounds);
   gridMark4Update(gridID);
 }
@@ -28219,7 +27368,7 @@ gridInqXBoundsSerial(grid_t *gridptr, double *xbounds)
 
   int irregular = gridptr->type == GRID_CURVILINEAR
     || gridptr->type == GRID_UNSTRUCTURED;
-  size_t size = nvertex * (size_t)(irregular ? gridptr->size : gridptr->x.size);
+  size_t size = nvertex * (size_t)(irregular ? gridptr->size : gridptr->xsize);
 
   const double *gridptr_xbounds = gridptr->vtable->inqXBoundsPtr(gridptr);
   if ( gridptr_xbounds )
@@ -28255,27 +27404,27 @@ Otherwise, 0 is returned and @func{xbounds} is empty.
 */
 int gridInqXbounds(int gridID, double *xbounds)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
   return gridptr->vtable->inqXBounds(gridptr, xbounds);
 }
 
 static const double *
 gridInqXBoundsPtrSerial(grid_t *gridptr)
 {
-  return gridptr->x.bounds;
+  return gridptr->xbounds;
 }
 
 
 const double *gridInqXboundsPtr(int gridID)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
   return gridptr->vtable->inqXBoundsPtr(gridptr);
 }
 
 static void
 gridDefYBoundsSerial(grid_t *gridptr, const double *ybounds)
 {
-  gridDefBoundsGeneric(gridptr, ybounds, gridptr->y.size, &gridptr->y.bounds);
+  gridDefBoundsGeneric(gridptr, ybounds, gridptr->ysize, &gridptr->ybounds);
 }
 
 /*
@@ -28294,7 +27443,7 @@ The function @func{gridDefYbounds} defines all bounds of the Y-axis.
 */
 void gridDefYbounds(int gridID, const double *ybounds)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
   gridptr->vtable->defYBounds(gridptr, ybounds);
   gridMark4Update(gridID);
 }
@@ -28306,7 +27455,7 @@ gridInqYBoundsSerial(grid_t *gridptr, double *ybounds)
 
   int irregular = gridptr->type == GRID_CURVILINEAR
     || gridptr->type == GRID_UNSTRUCTURED;
-  size_t size = nvertex * (size_t)(irregular ? gridptr->size : gridptr->y.size);
+  size_t size = nvertex * (size_t)(irregular ? gridptr->size : gridptr->ysize);
 
   const double *gridptr_ybounds = gridptr->vtable->inqYBoundsPtr(gridptr);
   if ( gridptr_ybounds )
@@ -28343,20 +27492,20 @@ Otherwise, 0 is returned and @func{ybounds} is empty.
 */
 int gridInqYbounds(int gridID, double *ybounds)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
   return gridptr->vtable->inqYBounds(gridptr, ybounds);
 }
 
 static const double *
 gridInqYBoundsPtrSerial(grid_t *gridptr)
 {
-  return gridptr->y.bounds;
+  return gridptr->ybounds;
 }
 
 
 const double *gridInqYboundsPtr(int gridID)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
   return gridptr->vtable->inqYBoundsPtr(gridptr);
 }
 
@@ -28417,7 +27566,7 @@ printBounds(FILE *fp, int dig, const char prefix[], size_t nbyte0,
 
 static void
 printMask(FILE *fp, const char prefix[], size_t nbyte0,
-          size_t n, const int mask[])
+          size_t n, const mask_t mask[])
 {
   fputs(prefix, fp);
   size_t nbyte = nbyte0;
@@ -28428,146 +27577,51 @@ printMask(FILE *fp, const char prefix[], size_t nbyte0,
           fprintf(fp, "\n%*s", (int)nbyte0, "");
           nbyte = nbyte0;
         }
-      nbyte += (size_t)fprintf(fp, "%d ", mask[i]);
+      nbyte += (size_t)fprintf(fp, "%d ", (int)mask[i]);
     }
   fputs("\n", fp);
 }
 
-static inline
-void *resizeBuffer(void **buf, size_t *bufSize, size_t reqSize)
-{
-  if (reqSize > *bufSize)
-    {
-      *buf = Realloc(*buf, reqSize);
-      *bufSize = reqSize;
-    }
-  return *buf;
-}
-
-static
-void gridPrintAttributes(FILE *fp, int gridID)
-{
-  int cdiID = gridID;
-  int varID = CDI_GLOBAL;
-  int atttype, attlen;
-  char attname[CDI_MAX_NAME+1];
-  void *attBuf = NULL;
-  size_t attBufSize = 0;
-
-  int natts;
-  cdiInqNatts(cdiID, varID, &natts);
-
-  for ( int iatt = 0; iatt < natts; ++iatt )
-    {
-      cdiInqAtt(cdiID, varID, iatt, attname, &atttype, &attlen);
-
-      if ( attlen == 0 ) continue;
-
-      if ( atttype == CDI_DATATYPE_TXT )
-        {
-          size_t attSize = (size_t)(attlen+1)*sizeof(char);
-          char *atttxt = (char *)resizeBuffer(&attBuf, &attBufSize, attSize);
-          cdiInqAttTxt(cdiID, varID, attname, attlen, atttxt);
-          atttxt[attlen] = 0;
-          fprintf(fp, "ATTR_TXT: %s = \"%s\"\n", attname, atttxt);
-        }
-      else if ( atttype == CDI_DATATYPE_INT8  || atttype == CDI_DATATYPE_UINT8  ||
-                atttype == CDI_DATATYPE_INT16 || atttype == CDI_DATATYPE_UINT16 ||
-                atttype == CDI_DATATYPE_INT32 || atttype == CDI_DATATYPE_UINT32 )
-        {
-          size_t attSize = (size_t)attlen*sizeof(int);
-          int *attint = (int *)resizeBuffer(&attBuf, &attBufSize, attSize);
-          cdiInqAttInt(cdiID, varID, attname, attlen, &attint[0]);
-          if ( attlen == 1 )
-            fprintf(fp, "ATTR_INT: %s =", attname);
-          else
-            fprintf(fp, "ATTR_INT_%d: %s =", attlen, attname);
-          for ( int i = 0; i < attlen; ++i ) fprintf(fp, " %d", attint[i]);
-          fprintf(fp, "\n");
-        }
-      else if ( atttype == CDI_DATATYPE_FLT32 || atttype == CDI_DATATYPE_FLT64 )
-        {
-          size_t attSize = (size_t)attlen * sizeof(double);
-          double *attflt = (double *)resizeBuffer(&attBuf, &attBufSize, attSize);
-          int dig = (atttype == CDI_DATATYPE_FLT64) ? 15 : 7;
-          cdiInqAttFlt(cdiID, varID, attname, attlen, attflt);
-          if ( attlen == 1 )
-            fprintf(fp, "ATTR_FLT: %s =", attname);
-          else
-            fprintf(fp, "ATTR_FLT_%d: %s =", attlen, attname);
-          for ( int i = 0; i < attlen; ++i ) fprintf(fp, " %.*g", dig, attflt[i]);
-          fprintf(fp, "\n");
-        }
-    }
-
-  Free(attBuf);
-}
-
-static
-void gridPrintKernel(int gridID, int opt, FILE *fp)
+static void gridPrintKernel(grid_t * gridptr, int index, int opt, FILE *fp)
 {
-  size_t xdimLen, ydimLen;
-  char attstr[CDI_MAX_NAME];
-  char attstr2[CDI_MAX_NAME];
+  int xdim, ydim;
   unsigned char uuidOfHGrid[CDI_UUID_SIZE];
-  const char  **xcvals  = gridInqXCvalsPtr(gridID);
-  const char  **ycvals  = gridInqYCvalsPtr(gridID);
-  size_t nxvals = (size_t) gridInqXvals(gridID, NULL);
-  size_t nyvals = (size_t) gridInqYvals(gridID, NULL);
-  size_t nxbounds = (size_t) gridInqXbounds(gridID, NULL);
-  size_t nybounds = (size_t) gridInqYbounds(gridID, NULL);
+  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);
 
   int type     = gridInqType(gridID);
+  int trunc    = gridInqTrunc(gridID);
   int gridsize = gridInqSize(gridID);
   int xsize    = gridInqXsize(gridID);
   int ysize    = gridInqYsize(gridID);
-  int xstrlen  = gridInqXIsc(gridID);
-  int ystrlen  = gridInqYIsc(gridID);
   int nvertex  = gridInqNvertex(gridID);
   int prec     = gridInqPrec(gridID);
 
-  int dig = (prec == CDI_DATATYPE_FLT64) ? 15 : 7;
+  int dig = (prec == DATATYPE_FLT64) ? 15 : 7;
 
-  fprintf(fp, "gridtype  = %s\n" "gridsize  = %d\n", gridNamePtr(type), gridsize);
+  fprintf(fp, "#\n"
+          "# gridID %d\n"
+          "#\n"
+          "gridtype  = %s\n"
+          "gridsize  = %d\n", index, gridNamePtr(type), gridsize);
 
   if ( type != GRID_GME )
     {
-      if ( type != GRID_UNSTRUCTURED && type != GRID_SPECTRAL && type != GRID_FOURIER )
-        {
-          if ( xsize > 0 ) fprintf(fp, "xsize     = %d\n", xsize);
-          if ( ysize > 0 ) fprintf(fp, "ysize     = %d\n", ysize);
-        }
-
-      if ( nxvals > 0 || xcvals )
+      if ( xvals )
         {
-          if ( xstrlen )  fprintf(fp, "xstringlen= %d\n", xstrlen);
-          attstr[0] = 0; cdiGridInqKeyStr(gridID, CDI_KEY_XNAME, CDI_MAX_NAME, attstr);
-          if ( attstr[0] )  fprintf(fp, "xname     = %s\n", attstr);
-          attstr2[0] = 0; cdiGridInqKeyStr(gridID, CDI_KEY_XDIMNAME, CDI_MAX_NAME, attstr2);
-          if ( attstr2[0] && strcmp(attstr, attstr2) )  fprintf(fp, "xdimname  = %s\n", attstr2);
-          attstr[0] = 0; cdiGridInqKeyStr(gridID, CDI_KEY_XLONGNAME, CDI_MAX_NAME, attstr);
-          if ( attstr[0] )  fprintf(fp, "xlongname = %s\n", attstr);
-          attstr[0] = 0; cdiGridInqKeyStr(gridID, CDI_KEY_XUNITS, CDI_MAX_NAME, attstr);
-          if ( attstr[0] )  fprintf(fp, "xunits    = %s\n", attstr);
+          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 ( nyvals > 0 || ycvals )
-        {
-          if ( ystrlen )  fprintf(fp, "ystringlen= %d\n", ystrlen);
-          attstr[0] = 0; cdiGridInqKeyStr(gridID, CDI_KEY_YNAME, CDI_MAX_NAME, attstr);
-          if ( attstr[0] )  fprintf(fp, "yname     = %s\n", attstr);
-          attstr2[0] = 0; cdiGridInqKeyStr(gridID, CDI_KEY_YDIMNAME, CDI_MAX_NAME, attstr2);
-          if ( attstr2[0] && strcmp(attstr, attstr2) )  fprintf(fp, "ydimname  = %s\n", attstr2);
-          attstr[0] = 0; cdiGridInqKeyStr(gridID, CDI_KEY_YLONGNAME, CDI_MAX_NAME, attstr);
-          if ( attstr[0] )  fprintf(fp, "ylongname = %s\n", attstr);
-          attstr[0] = 0; cdiGridInqKeyStr(gridID, CDI_KEY_YUNITS, CDI_MAX_NAME, attstr);
-          if ( attstr[0] )  fprintf(fp, "yunits    = %s\n", attstr);
-        }
-
-      if ( type == GRID_UNSTRUCTURED || type == GRID_CURVILINEAR )
+      if ( yvals )
         {
-          attstr[0] = 0; cdiGridInqKeyStr(gridID, CDI_KEY_VDIMNAME, CDI_MAX_NAME, attstr);
-          if ( attstr[0] ) fprintf(fp, "vdimname  = %s\n", attstr);
+          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);
     }
@@ -28578,27 +27632,34 @@ void gridPrintKernel(int gridID, int opt, FILE *fp)
     case GRID_GAUSSIAN:
     case GRID_GAUSSIAN_REDUCED:
     case GRID_GENERIC:
-    case GRID_PROJECTION:
+    case GRID_LCC2:
+    case GRID_SINUSOIDAL:
+    case GRID_LAEA:
     case GRID_CURVILINEAR:
     case GRID_UNSTRUCTURED:
-    case GRID_CHARXY:
       {
-        if ( type == GRID_GAUSSIAN || type == GRID_GAUSSIAN_REDUCED ) fprintf(fp, "np        = %d\n", gridInqNP(gridID));
+        if ( type == GRID_GAUSSIAN || type == GRID_GAUSSIAN_REDUCED ) fprintf(fp, "np        = %d\n", gridptr->np);
 
 	if ( type == GRID_CURVILINEAR || type == GRID_UNSTRUCTURED )
 	  {
-	    xdimLen = (size_t)gridsize;
-	    ydimLen = (size_t)gridsize;
+	    xdim = gridsize;
+	    ydim = gridsize;
 	  }
         else if ( type == GRID_GAUSSIAN_REDUCED )
           {
-	    xdimLen = 2;
-	    ydimLen = (size_t)ysize;
+	    xdim = 2;
+	    ydim = ysize;
           }
 	else
 	  {
-	    xdimLen = (size_t)xsize;
-	    ydimLen = (size_t)ysize;
+	    xdim = xsize;
+	    ydim = ysize;
+	  }
+
+	if ( type != GRID_UNSTRUCTURED )
+	  {
+	    if ( xsize > 0 ) fprintf(fp, "xsize     = %d\n", xsize);
+	    if ( ysize > 0 ) fprintf(fp, "ysize     = %d\n", ysize);
 	  }
 
 	if ( type == GRID_UNSTRUCTURED )
@@ -28626,12 +27687,41 @@ void gridPrintKernel(int gridID, int opt, FILE *fp)
               }
           }
 
-	if ( nxvals > 0 )
+	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"
+                    "lon_0     = %.*g\n"
+                    "lat_0     = %.*g\n", dig, a, dig, lon_0, dig, lat_0);
+	  }
+
+	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"
+                    "lon_0     = %.*g\n"
+                    "lat_0     = %.*g\n"
+                    "lat_1     = %.*g\n"
+                    "lat_2     = %.*g\n",
+                    dig, a, dig, lon_0, dig, lat_0, dig, lat_1, dig, lat_2);
+	  }
+
+	if ( gridptr->isRotated )
+	  {
+	    if ( xsize > 0 ) fprintf(fp, "xnpole    = %.*g\n", dig, gridptr->xpole);
+	    if ( ysize > 0 ) fprintf(fp, "ynpole    = %.*g\n", dig, gridptr->ypole);
+	    if ( IS_NOT_EQUAL(gridptr->angle, 0) ) fprintf(fp, "angle     = %.*g\n", dig, gridptr->angle);
+ 	  }
+
+	if ( xvals )
 	  {
 	    double xfirst = 0.0, xinc = 0.0;
 
 	    if ( type == GRID_LONLAT     || type == GRID_GAUSSIAN ||
-		 type == GRID_PROJECTION || type == GRID_GENERIC )
+		 type == GRID_GENERIC    || type == GRID_LCC2     ||
+                 type == GRID_SINUSOIDAL || type == GRID_LAEA )
 	      {
 		xfirst = gridInqXval(gridID, 0);
 		xinc   = gridInqXinc(gridID);
@@ -28644,40 +27734,26 @@ void gridPrintKernel(int gridID, int opt, FILE *fp)
 	      }
 	    else
 	      {
-                double *xvals = (double*) Malloc(nxvals*sizeof(double));
-                gridInqXvals(gridID, xvals);
                 static const char prefix[] = "xvals     = ";
-                printDblsPrefixAutoBrk(fp, dig, prefix, sizeof(prefix)-1, nxvals, xvals);
-                Free(xvals);
+                printDblsPrefixAutoBrk(fp, dig, prefix, sizeof(prefix)-1,
+                                       (size_t)(xdim > 0 ? xdim : 0), xvals);
 	      }
 	  }
 
-        if ( xcvals )
-          {
-            attstr[0] = 0; cdiGridInqKeyStr(gridID, CDI_KEY_XNAME, CDI_MAX_NAME, attstr);
-            if ( attstr[0] )
-              fprintf(fp, "x%ss = %.*s\n", attstr, xstrlen, xcvals[0]);
-            else
-              fprintf(fp, "xstrings  = %.*s\n", xstrlen, xcvals[0]);
-            for ( int i = 1; i < xsize; i++ )
-              fprintf(fp, "          = %.*s\n", xstrlen, xcvals[i]);
-          }
-
-	if ( nxbounds )
+	if ( xbounds )
 	  {
-            double *xbounds = (double*) Malloc(nxbounds*sizeof(double));
-            gridInqXbounds(gridID, xbounds);
             static const char prefix[] = "xbounds   = ";
-            printBounds(fp, dig, prefix, sizeof(prefix)-1, xdimLen, (size_t)nvertex, xbounds);
-            Free(xbounds);
+            printBounds(fp, dig, prefix, sizeof(prefix)-1,
+                        (size_t)(xdim > 0 ? xdim : 0),
+                        (size_t)(nvertex > 0 ? nvertex : 0), xbounds);
 	  }
 
-	if ( nyvals > 0 )
+	if ( yvals )
 	  {
 	    double yfirst = 0.0, yinc = 0.0;
 
-	    if ( type == GRID_LONLAT || type == GRID_GENERIC ||
-                 type == GRID_PROJECTION || type == GRID_GENERIC )
+	    if ( type == GRID_LONLAT || type == GRID_GENERIC || type == GRID_LCC2 ||
+		 type == GRID_SINUSOIDAL || type == GRID_LAEA )
 	      {
 		yfirst = gridInqYval(gridID, 0);
 		yinc   = gridInqYinc(gridID);
@@ -28690,41 +27766,25 @@ void gridPrintKernel(int gridID, int opt, FILE *fp)
 	      }
 	    else
 	      {
-                double *yvals = (double*) Malloc(nyvals*sizeof(double));
-                gridInqYvals(gridID, yvals);
                 static const char prefix[] = "yvals     = ";
-                printDblsPrefixAutoBrk(fp, dig, prefix, sizeof(prefix)-1, nyvals, yvals);
-                Free(yvals);
+                printDblsPrefixAutoBrk(fp, dig, prefix, sizeof(prefix)-1,
+                                       (size_t)(ydim > 0 ? ydim : 0), yvals);
 	      }
 	  }
 
-        if ( ycvals )
-          {
-            attstr[0] = 0; cdiGridInqKeyStr(gridID, CDI_KEY_YNAME, CDI_MAX_NAME, attstr);
-            if ( attstr[0] )
-              fprintf(fp, "x%ss = %.*s\n", attstr, ystrlen, ycvals[0]);
-            else
-              fprintf(fp, "ystrings  = %.*s\n", ystrlen, ycvals[0]);
-            for ( int i = 1; i < ysize; i++ )
-              fprintf(fp, "          = %.*s\n", ystrlen, ycvals[i]);
-          }
-
-	if ( nybounds )
+	if ( ybounds )
 	  {
-            double *ybounds = (double*) Malloc(nybounds*sizeof(double));
-            gridInqYbounds(gridID, ybounds);
             static const char prefix[] = "ybounds   = ";
-            printBounds(fp, dig, prefix, sizeof(prefix)-1, ydimLen, (size_t)nvertex, ybounds);
-            Free(ybounds);
+            printBounds(fp, dig, prefix, sizeof(prefix)-1,
+                        (size_t)(ydim > 0 ? ydim : 0),
+                        (size_t)(nvertex > 0 ? nvertex : 0), ybounds);
 	  }
 
-	if ( gridHasArea(gridID) )
+	if ( area )
 	  {
-            double *area = (double*) Malloc((size_t)gridsize*sizeof(double));
-            gridInqArea(gridID, area);
             static const char prefix[] = "area      = ";
-            printDblsPrefixAutoBrk(fp, dig, prefix, sizeof(prefix)-1, (size_t)gridsize, area);
-            Free(area);
+            printDblsPrefixAutoBrk(fp, dig, prefix, sizeof(prefix)-1,
+                                   (size_t)(gridsize > 0 ? gridsize : 0), area);
 	  }
 
         if ( type == GRID_GAUSSIAN_REDUCED )
@@ -28737,26 +27797,45 @@ void gridPrintKernel(int gridID, int opt, FILE *fp)
             Free(rowlon);
           }
 
-        if ( type == GRID_PROJECTION ) gridPrintAttributes(fp, gridID);
-
+	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);
+
+	fprintf(fp,
+                "xsize     = %d\n"
+                "ysize     = %d\n"
+                "originLon = %.*g\n"
+                "originLat = %.*g\n"
+                "lonParY   = %.*g\n"
+                "lat1      = %.*g\n"
+                "lat2      = %.*g\n"
+                "xinc      = %.*g\n"
+                "yinc      = %.*g\n"
+                "projection = %s\n",
+                xsize, ysize, dig, originLon, dig, originLat, dig, lonParY,
+                dig, lat1, dig, lat2, dig, xincm, dig, yincm,
+                (projflag & 128) == 0 ? "northpole" : "southpole");
 	break;
       }
     case GRID_SPECTRAL:
       {
         fprintf(fp, "truncation = %d\n"
-                "complexpacking = %d\n", gridInqTrunc(gridID), gridInqComplexPacking(gridID) );
+                "complexpacking = %d\n", trunc, gridptr->lcomplex );
         break;
       }
     case GRID_FOURIER:
       {
-	fprintf(fp, "truncation = %d\n", gridInqTrunc(gridID));
+	fprintf(fp, "truncation = %d\n", trunc);
 	break;
       }
     case GRID_GME:
       {
-        int nd, ni, ni2, ni3;
-        gridInqParamGME(gridID, &nd, &ni, &ni2, &ni3);
-        fprintf(fp, "ni        = %d\n", ni );
+        fprintf(fp, "ni        = %d\n", gridptr->ni );
         break;
       }
    default:
@@ -28775,32 +27854,30 @@ void gridPrintKernel(int gridID, int opt, FILE *fp)
         fprintf(fp, "uuid      = %s\n", uuidOfHGridStr);
     }
 
-  if ( gridInqMask(gridID, NULL) )
+  if ( gridptr->mask )
     {
-      int *mask = (gridsize>0) ? (int*) Malloc((size_t)gridsize*sizeof(int)) : NULL;
-      gridInqMask(gridID, mask);
       static const char prefix[] = "mask      = ";
       printMask(fp, prefix, sizeof(prefix)-1,
-                (size_t)(gridsize > 0 ? gridsize : 0), mask);
-      if ( mask ) Free(mask);
+                (size_t)(gridsize > 0 ? gridsize : 0), gridptr->mask);
     }
 }
 
-
-void gridPrint(int gridID, int opt)
+void gridPrint ( int gridID, int index, int opt )
 {
-  gridPrintKernel(gridID, opt, stdout);
+  grid_t *gridptr = gridID2Ptr(gridID);
+
+  gridPrintKernel ( gridptr, index, opt, stdout );
 }
 
 
-void gridPrintP(void *voidptr, FILE *fp)
+
+void gridPrintP ( void * voidptr, FILE * fp )
 {
-  grid_t *gridptr = (grid_t *) voidptr;
-  int gridID = gridptr->self;
+  grid_t * gridptr = ( grid_t * ) voidptr;
 
-  xassert( gridptr );
+  xassert ( gridptr );
 
-  gridPrintKernel(gridID, 0, fp);
+  gridPrintKernel ( gridptr , gridptr->self, 0, fp );
 
   fprintf(fp,
           "precision = %d\n"
@@ -28813,8 +27890,8 @@ void gridPrintP(void *voidptr, FILE *fp)
           "trunc     = %d\n"
           "lcomplex  = %d\n"
           "nrowlon   = %d\n",
-          gridptr->prec, gridptr->gme.nd, gridptr->gme.ni, gridptr->gme.ni2,
-          gridptr->gme.ni3, gridptr->number, gridptr->position, gridptr->trunc,
+          gridptr->prec, gridptr->nd, gridptr->ni, gridptr->ni2,
+          gridptr->ni3, gridptr->number, gridptr->position, gridptr->trunc,
           gridptr->lcomplex, gridptr->nrowlon );
 
   if ( gridptr->rowlon )
@@ -28825,229 +27902,223 @@ void gridPrintP(void *voidptr, FILE *fp)
                                       ? gridptr->nrowlon : 0), gridptr->rowlon);
     }
 
-  if ( gridInqMaskGME(gridID, NULL) )
+  if ( gridptr->mask_gme )
     {
-      int gridsize = gridptr->size;
-      int *mask = (gridsize>0) ? (int*) Malloc((size_t)gridsize*sizeof(int)) : NULL;
-      gridInqMaskGME(gridID, mask);
       static const char prefix[] = "mask_gme  = ";
       printMask(fp, prefix, sizeof(prefix)-1,
-                (size_t)(gridptr->size > 0 ? gridptr->size : 0), mask);
-      if ( mask ) Free(mask);
+                (size_t)(gridptr->size > 0 ? gridptr->size : 0),
+                gridptr->mask_gme);
     }
 }
 
 static const double *gridInqXValsPtrSerial(grid_t *gridptr)
 {
-  return gridptr->x.vals;
+  return gridptr->xvals;
 }
 
-static const char **gridInqXCvalsPtrSerial(grid_t *gridptr)
-{
-  return (const char **) gridptr->x.cvals;
-}
-
-
 const double *gridInqXvalsPtr(int gridID)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
   return gridptr->vtable->inqXValsPtr(gridptr);
 }
 
 
-const char **gridInqXCvalsPtr(int gridID)
-{
-  grid_t *gridptr = grid_to_pointer(gridID);
-  return gridptr->vtable->inqXCvalsPtr(gridptr);
-}
-
 static const double *gridInqYValsPtrSerial(grid_t *gridptr)
 {
-  return gridptr->y.vals;
-}
-
-static const char **gridInqYCvalsPtrSerial(grid_t *gridptr)
-{
-  return (const char **) gridptr->y.cvals;
+  return gridptr->yvals;
 }
 
 const double *gridInqYvalsPtr(int gridID)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
   return gridptr->vtable->inqYValsPtr(gridptr);
 }
 
-const char **gridInqYCvalsPtr(int gridID)
-{
-  grid_t *gridptr = grid_to_pointer(gridID);
-  return gridptr->vtable->inqYCvalsPtr(gridptr);
-}
-
 /*
- at Function  gridDefParamLCC
+ at Function  gridDefLCC
 @Title     Define the parameter of a Lambert Conformal Conic grid
 
- at Prototype void gridDefParamLCC(int gridID, double missval, double lon_0, double lat_0, double lat_1, double lat_2, double a, double rf, double xval_0, double yval_0, double x_0, double y_0)
+ at Prototype void gridDefLCC(int gridID, double originLon, double originLat, double lonParY, double lat1, double lat2, double xinc, double yinc, int projflag, int scanflag)
 @Parameter
     @Item  gridID    Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  missval   Missing value
-    @Item  lon_0     The East longitude of the meridian which is parallel to the Y-axis.
-    @Item  lat_0     Latitude of the projection origin
-    @Item  lat_1     First latitude from the pole at which the secant cone cuts the sphere.
-    @Item  lat_2     Second latitude at which the secant cone cuts the sphere.
-    @Item  a         Earth radius in metres (optional).
-    @Item  rf        Inverse flattening (1/f) (optional).
-    @Item  xval_0    Longitude of the first grid point in degree (optional).
-    @Item  yval_0    Latitude of the first grid point in degree (optional).
-    @Item  x_0       False easting (optional).
-    @Item  y_0       False northing (optional).
+    @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.
 
 @Description
-The function @func{gridDefParamLCC} defines the parameter of a Lambert Conformal Conic grid.
+The function @func{gridDefLCC} defines the parameter of a Lambert Conformal Conic grid.
 
 @EndFunction
 */
-void gridDefParamLCC(int gridID, double missval, double lon_0, double lat_0, double lat_1, double lat_2,
-                     double a, double rf, double xval_0, double yval_0, double x_0, double y_0)
-{
-  (void)lat_0;
-  cdiGridDefKeyStr(gridID, CDI_KEY_MAPPING, CDI_MAX_NAME, "Lambert_Conformal");
-
-  const char *mapname = "lambert_conformal_conic";
-  cdiGridDefKeyStr(gridID, CDI_KEY_MAPNAME, CDI_MAX_NAME, mapname);
-  cdiDefAttTxt(gridID, CDI_GLOBAL, "grid_mapping_name", (int)(strlen(mapname)), mapname);
-  int nlats = 0;
-  double lats[2];
-  lats[nlats++] = lat_1;
-  if ( IS_NOT_EQUAL(lat_1, lat_2) ) lats[nlats++] = lat_2;
-  cdiDefAttFlt(gridID, CDI_GLOBAL, "standard_parallel", CDI_DATATYPE_FLT64, nlats, lats);
-  cdiDefAttFlt(gridID, CDI_GLOBAL, "longitude_of_central_meridian", CDI_DATATYPE_FLT64, 1, &lon_0);
-  cdiDefAttFlt(gridID, CDI_GLOBAL, "latitude_of_projection_origin", CDI_DATATYPE_FLT64, 1, &lat_2);
-  if ( a > 0 ) cdiDefAttFlt(gridID, CDI_GLOBAL, "earth_radius", CDI_DATATYPE_FLT64, 1, &a);
-  if ( rf > 0 ) cdiDefAttFlt(gridID, CDI_GLOBAL, "inverse_flattening", CDI_DATATYPE_FLT64, 1, &rf);
-  if ( IS_NOT_EQUAL(x_0, missval) ) cdiDefAttFlt(gridID, CDI_GLOBAL, "false_easting", CDI_DATATYPE_FLT64, 1, &x_0);
-  if ( IS_NOT_EQUAL(y_0, missval) ) cdiDefAttFlt(gridID, CDI_GLOBAL, "false_northing", CDI_DATATYPE_FLT64, 1, &y_0);
-  if ( IS_NOT_EQUAL(xval_0, missval) ) cdiDefAttFlt(gridID, CDI_GLOBAL, "longitudeOfFirstGridPointInDegrees", CDI_DATATYPE_FLT64, 1, &xval_0);
-  if ( IS_NOT_EQUAL(yval_0, missval) ) cdiDefAttFlt(gridID, CDI_GLOBAL, "latitudeOfFirstGridPointInDegrees", CDI_DATATYPE_FLT64, 1, &yval_0);
-
-  grid_t *gridptr = grid_to_pointer(gridID);
-  gridptr->projtype = CDI_PROJ_LCC;
-
-  gridVerifyProj(gridID);
+void gridDefLCC(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("Definition of LCC grid for %s grid not allowed!",
+	    gridNamePtr(gridptr->type));
+  else
+    {
+      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;
+      gridMark4Update(gridID);
+    }
 }
 
 /*
- at Function  gridInqParamLCC
+ at Function  gridInqLCC
 @Title     Get the parameter of a Lambert Conformal Conic grid
 
- at Prototype void gridInqParamLCC(int gridID, double missval, double *lon_0, double *lat_0, double *lat_1, double *lat_2, double *a, double *rf, double *xval_0, double *yval_0, double *x_0, double *y_0)
+ at Prototype void gridInqLCC(int gridID, double *originLon, double *originLat, double *lonParY, double *lat1, double *lat2, double *xinc, double *yinc, int *projflag, int *scanflag)
 @Parameter
     @Item  gridID    Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
-    @Item  missval   Missing value
-    @Item  lon_0     The East longitude of the meridian which is parallel to the Y-axis.
-    @Item  lat_0     Latitude of the projection origin
-    @Item  lat_1     First latitude from the pole at which the secant cone cuts the sphere.
-    @Item  lat_2     Second latitude at which the secant cone cuts the sphere.
-    @Item  a         Earth radius in metres (optional).
-    @Item  rf        Inverse flattening (1/f) (optional).
-    @Item  xval_0    Longitude of the first grid point in degree (optional).
-    @Item  yval_0    Latitude of the first grid point in degree (optional).
-    @Item  x_0       False easting (optional).
-    @Item  y_0       False northing (optional).
-
+    @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.
+ 
 @Description
-The function @func{gridInqParamLCC} returns the parameter of a Lambert Conformal Conic grid.
+The function @func{gridInqLCC} returns the parameter of a Lambert Conformal Conic grid.
 
 @EndFunction
 */
-int gridInqParamLCC(int gridID, double missval, double *lon_0, double *lat_0, double *lat_1, double *lat_2,
-                    double *a, double *rf, double *xval_0, double *yval_0, double *x_0, double *y_0)
+void gridInqLCC(int gridID, double *originLon, double *originLat, double *lonParY,
+                double *lat1, double *lat2, double *xinc, double *yinc,
+                int *projflag, int *scanflag)
 {
-  *a = 0; *rf = 0;
-  *lon_0 = missval; *lat_0 = missval, *lat_1 = missval, *lat_2 = missval;
-  *xval_0 = missval; *yval_0 = missval; *x_0 = missval, *y_0 = missval;
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  int status = -1;
-  if ( gridInqType(gridID) != GRID_PROJECTION ) return status;
+  if ( gridptr->type != GRID_LCC )
+    Warning("Inquire of LCC grid definition for %s grid not allowed!",
+	    gridNamePtr(gridptr->type));
+  else
+    {
+      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
+	Warning("Lambert Conformal grid undefined (gridID = %d)", gridID);
+    }
+}
+
+void gridDefLcc2(int gridID, double earth_radius, double lon_0, double lat_0, double lat_1, double lat_2)
+{
+  grid_t *gridptr = gridID2Ptr(gridID);
 
-  status = -2;
-  const char *projection = "lambert_conformal_conic";
-  char mapname[CDI_MAX_NAME]; mapname[0] = 0;
-  cdiGridInqKeyStr(gridID, CDI_KEY_MAPNAME, CDI_MAX_NAME, mapname);
-  if ( mapname[0] && strcmp(mapname, projection) == 0 )
+  if ( gridptr->type != GRID_LCC2 )
+    Warning("Definition of LCC2 grid for %s grid not allowed!",
+	    gridNamePtr(gridptr->type));
+  else
     {
-      int atttype, attlen;
-      char attname[CDI_MAX_NAME+1];
+      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;
+      gridMark4Update(gridID);
+    }
+}
 
-      int natts;
-      cdiInqNatts(gridID, CDI_GLOBAL, &natts);
 
-      if ( natts ) status = 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);
 
-      for ( int iatt = 0; iatt < natts; ++iatt )
+  if ( gridptr->type != GRID_LCC2 )
+    Warning("Inquire of LCC2 grid definition for %s grid not allowed!",
+	    gridNamePtr(gridptr->type));
+  else
+    {
+      if ( gridptr->lcc2_defined )
         {
-          cdiInqAtt(gridID, CDI_GLOBAL, iatt, attname, &atttype, &attlen);
-          if ( attlen > 2 ) continue;
-
-          double attflt[2];
-          if ( cdiInqAttConvertedToFloat(gridID, atttype, attname, attlen, attflt) )
-            {
-              if      ( strcmp(attname, "earth_radius") == 0 )                       *a      = attflt[0];
-              else if ( strcmp(attname, "inverse_flattening") == 0 )                 *rf     = attflt[0];
-              else if ( strcmp(attname, "longitude_of_central_meridian") == 0 )      *lon_0  = attflt[0];
-              else if ( strcmp(attname, "latitude_of_projection_origin") == 0 )      *lat_0  = attflt[0];
-              else if ( strcmp(attname, "false_easting")  == 0 )                     *x_0    = attflt[0];
-              else if ( strcmp(attname, "false_northing") == 0 )                     *y_0    = attflt[0];
-              else if ( strcmp(attname, "longitudeOfFirstGridPointInDegrees") == 0 ) *xval_0 = attflt[0];
-              else if ( strcmp(attname, "latitudeOfFirstGridPointInDegrees")  == 0 ) *yval_0 = attflt[0];
-              else if ( strcmp(attname, "standard_parallel") == 0 )
-                {
-                  *lat_1 = attflt[0];
-                  *lat_2 = (attlen == 2) ? attflt[1] : attflt[0];
-                }
-            }
+          *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);
     }
+}
 
-  return status;
+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
+    {
+      gridptr->laea_a       = earth_radius;
+      gridptr->laea_lon_0   = lon_0;
+      gridptr->laea_lat_0   = lat_0;
+      gridptr->laea_defined = TRUE;
+      gridMark4Update(gridID);
+    }
 }
 
 
-int gridVerifyGribParamLCC(double missval, double *lon_0, double *lat_0, double *lat_1, double *lat_2,
-                           double *a, double *rf, double *xval_0, double *yval_0, double *x_0, double *y_0)
+void gridInqLaea(int gridID, double *earth_radius, double *lon_0, double *lat_0)
 {
-  static bool lwarn = true;
+  grid_t* gridptr = gridID2Ptr(gridID);
 
-  if ( lwarn )
+  if ( gridptr->type != GRID_LAEA )
+    Warning("Inquire of LAEA grid definition for %s grid not allowed!",
+            gridNamePtr(gridptr->type));
+  else
     {
-      // lwarn = false;
-      const char *projection = "lambert_conformal_conic";
-      if ( IS_EQUAL(*lon_0, missval) ) { Warning("%s mapping parameter %s missing!", projection, "longitude_of_central_meridian"); }
-      if ( IS_EQUAL(*lat_0, missval) ) { Warning("%s mapping parameter %s missing!", projection, "latitude_of_central_meridian"); }
-      if ( IS_EQUAL(*lat_1, missval) ) { Warning("%s mapping parameter %s missing!", projection, "standard_parallel"); }
-      if ( IS_NOT_EQUAL(*x_0, missval) && IS_NOT_EQUAL(*y_0, grid_missval) && (IS_EQUAL(*xval_0, missval) || IS_EQUAL(*yval_0, missval)) )
+      if ( gridptr->laea_defined )
         {
-          if ( proj_lcc_to_lonlat_func )
-            {
-              *xval_0 = -(*x_0); *yval_0 = -(*y_0);
-              proj_lcc_to_lonlat_func(missval, *lon_0, *lat_0, *lat_1, *lat_2, *a, *rf, 0.0, 0.0, (size_t)1, xval_0, yval_0);
-            }
-          if ( IS_EQUAL(*xval_0, missval) || IS_EQUAL(*yval_0, missval) )
-            Warning("%s mapping parameter %s missing!", projection, "longitudeOfFirstGridPointInDegrees and latitudeOfFirstGridPointInDegrees");
+          *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);
     }
-
-  return 0;
 }
 
 
 void gridDefComplexPacking(int gridID, int lcomplex)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
   if (gridptr->lcomplex != lcomplex)
     {
-      gridptr->lcomplex = lcomplex != 0;
+      gridptr->lcomplex = (short)(lcomplex != 0);
       gridMark4Update(gridID);
     }
 }
@@ -29055,15 +28126,15 @@ void gridDefComplexPacking(int gridID, int lcomplex)
 
 int gridInqComplexPacking(int gridID)
 {
-  grid_t* gridptr = grid_to_pointer(gridID);
+  grid_t* gridptr = gridID2Ptr(gridID);
 
-  return (int)gridptr->lcomplex;
+  return gridptr->lcomplex;
 }
 
 
 void gridDefHasDims(int gridID, int hasdims)
 {
-  grid_t* gridptr = grid_to_pointer(gridID);
+  grid_t* gridptr = gridID2Ptr(gridID);
 
   if ( gridptr->hasdims != (hasdims != 0) )
     {
@@ -29075,9 +28146,9 @@ void gridDefHasDims(int gridID, int hasdims)
 
 int gridInqHasDims(int gridID)
 {
-  grid_t* gridptr = grid_to_pointer(gridID);
+  grid_t* gridptr = gridID2Ptr(gridID);
 
-  return (int)gridptr->hasdims;
+  return gridptr->hasdims;
 }
 
 /*
@@ -29096,7 +28167,7 @@ The function @func{gridDefNumber} defines the reference number for an unstructur
 */
 void gridDefNumber(int gridID, const int number)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
   if ( gridptr->number != number )
     {
@@ -29122,7 +28193,7 @@ The function @func{gridInqNumber} returns the reference number to an unstructure
 */
 int gridInqNumber(int gridID)
 {
-  grid_t* gridptr = grid_to_pointer(gridID);
+  grid_t* gridptr = gridID2Ptr(gridID);
   return gridptr->number;
 }
 
@@ -29142,7 +28213,7 @@ The function @func{gridDefPosition} defines the position of grid in the referenc
 */
 void gridDefPosition(int gridID, int position)
 {
-  grid_t* gridptr = grid_to_pointer(gridID);
+  grid_t* gridptr = gridID2Ptr(gridID);
 
   if ( gridptr->position != position )
     {
@@ -29168,7 +28239,8 @@ The function @func{gridInqPosition} returns the position of grid in the referenc
 */
 int gridInqPosition(int gridID)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
+
   return gridptr->position;
 }
 
@@ -29188,7 +28260,7 @@ The function @func{gridDefReference} defines the reference URI for an unstructur
 */
 void gridDefReference(int gridID, const char *reference)
 {
-  grid_t* gridptr = grid_to_pointer(gridID);
+  grid_t* gridptr = gridID2Ptr(gridID);
 
   if ( reference )
     {
@@ -29221,7 +28293,7 @@ The function @func{gridInqReference} returns the reference URI to an unstructure
 int gridInqReference(int gridID, char *reference)
 {
   size_t len = 0;
-  grid_t* gridptr = grid_to_pointer(gridID);
+  grid_t* gridptr = gridID2Ptr(gridID);
 
   if ( gridptr->reference )
     {
@@ -29235,7 +28307,7 @@ int gridInqReference(int gridID, char *reference)
 
 const char *gridInqReferencePtr(int gridID)
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
   return gridptr->reference;
 }
 
@@ -29255,7 +28327,7 @@ The function @func{gridDefUUID} defines the UUID for an unstructured grid.
 */
 void gridDefUUID(int gridID, const unsigned char uuid[CDI_UUID_SIZE])
 {
-  grid_t* gridptr = grid_to_pointer(gridID);
+  grid_t* gridptr = gridID2Ptr(gridID);
 
   memcpy(gridptr->uuid, uuid, CDI_UUID_SIZE);
   gridMark4Update(gridID);
@@ -29278,56 +28350,12 @@ The function @func{gridInqUUID} returns the UUID to an unstructured grid.
 */
 void gridInqUUID(int gridID, unsigned char uuid[CDI_UUID_SIZE])
 {
-  grid_t *gridptr = grid_to_pointer(gridID);
+  grid_t *gridptr = gridID2Ptr(gridID);
 
   memcpy(uuid, gridptr->uuid, CDI_UUID_SIZE);
 }
 
 
-void gridDefUvRelativeToGrid(int gridID, int uvRelativeToGrid)
-{
-  grid_t *gridptr = grid_to_pointer(gridID);
-
-  if ( gridptr->uvRelativeToGrid != uvRelativeToGrid )
-    {
-      gridMark4Update(gridID);
-      gridptr->uvRelativeToGrid = (bool)uvRelativeToGrid;
-    }
-}
-
-
-int gridInqUvRelativeToGrid(int gridID)
-{
-  grid_t *gridptr = grid_to_pointer(gridID);
-  return gridptr->uvRelativeToGrid;
-}
-
-
-void gridDefScanningMode(int gridID, int mode)
-{
-  grid_t *gridptr = grid_to_pointer(gridID);
-
-  if ( gridptr->scanningMode != mode )
-    {
-      gridMark4Update(gridID);
-      gridptr->scanningMode = mode;
-    }
-}
-
-
-int gridInqScanningMode(int gridID)
-{
-  grid_t *gridptr = grid_to_pointer(gridID);
-
-  int scanningModeTMP  = 128 * gridptr->iScansNegatively + 64 * gridptr->jScansPositively + 32 * gridptr->jPointsAreConsecutive;
-  if ( scanningModeTMP != gridptr->scanningMode )
-    Message("WARNING: scanningMode (%d) ! = (%d) 128 * iScansNegatively(%d) + 64 * jScansPositively(%d) + 32 * jPointsAreConsecutive(%d) ",
-            gridptr->scanningMode, scanningModeTMP, gridptr->iScansNegatively,gridptr->jScansPositively,gridptr->jPointsAreConsecutive );
-
-  return gridptr->scanningMode;
-}
-
-
 void cdiGridGetIndexList(unsigned ngrids, int * gridIndexList)
 {
   reshGetResHListOfType(ngrids, gridIndexList, &gridOps);
@@ -29340,48 +28368,8 @@ gridTxCode ()
   return GRID;
 }
 
-enum {
-  GRID_PACK_INT_IDX_SELF,
-  GRID_PACK_INT_IDX_TYPE,
-  GRID_PACK_INT_IDX_PREC,
-  GRID_PACK_INT_IDX_IS_CYCLIC,
-  GRID_PACK_INT_IDX_X_FLAG,
-  GRID_PACK_INT_IDX_Y_FLAG,
-  GRID_PACK_INT_IDX_GME_ND,
-  GRID_PACK_INT_IDX_GME_NI,
-  GRID_PACK_INT_IDX_GME_NI2,
-  GRID_PACK_INT_IDX_GME_NI3,
-  GRID_PACK_INT_IDX_NUMBER,
-  GRID_PACK_INT_IDX_POSITION,
-  GRID_PACK_INT_IDX_TRUNC,
-  GRID_PACK_INT_IDX_NVERTEX,
-  GRID_PACK_INT_IDX_NROWLON,
-  GRID_PACK_INT_IDX_SIZE,
-  GRID_PACK_INT_IDX_X_SIZE,
-  GRID_PACK_INT_IDX_Y_SIZE,
-  GRID_PACK_INT_IDX_LCOMPLEX,
-  GRID_PACK_INT_IDX_MEMBERMASK,
-  GRID_PACK_INT_IDX_XTSTDNNAME,
-  GRID_PACK_INT_IDX_YTSTDNNAME,
-  GRID_PACK_INT_IDX_UVRELATIVETOGRID,
-  GRID_PACK_INT_IDX_ISCANSNEGATIVELY,
-  GRID_PACK_INT_IDX_JSCANSPOSITIVELY,
-  GRID_PACK_INT_IDX_JPOINTSARECONSECUTIVE,
-  GRID_PACK_INT_IDX_SCANNINGMODE,
-  gridNint
-};
-
-enum {
-  GRID_PACK_DBL_IDX_X_FIRST,
-  GRID_PACK_DBL_IDX_Y_FIRST,
-  GRID_PACK_DBL_IDX_X_LAST,
-  GRID_PACK_DBL_IDX_Y_LAST,
-  GRID_PACK_DBL_IDX_X_INC,
-  GRID_PACK_DBL_IDX_Y_INC,
-  gridNdouble
-};
-
-enum {
+enum { gridNint    = 28,
+       gridNdouble = 24,
        gridHasMaskFlag = 1 << 0,
        gridHasGMEMaskFlag = 1 << 1,
        gridHasXValsFlag = 1 << 2,
@@ -29406,8 +28394,8 @@ static int gridGetComponentFlags(const grid_t * gridP)
     | (gridHasAreaFlag
        & (int)((unsigned)(gridP->vtable->inqAreaPtr((grid_t *)gridP) == NULL)
                - 1U))
-    | (gridHasXBoundsFlag & (int)((unsigned)(gridP->x.bounds == NULL) - 1U))
-    | (gridHasYBoundsFlag & (int)((unsigned)(gridP->y.bounds == 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));
@@ -29420,27 +28408,27 @@ gridGetPackSize(void * voidP, void *context)
   grid_t * gridP = ( grid_t * ) voidP;
   int packBuffSize = 0, count;
 
-  packBuffSize += serializeGetSize(gridNint, CDI_DATATYPE_INT, context)
-    + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
+  packBuffSize += serializeGetSize(gridNint, DATATYPE_INT, context)
+    + serializeGetSize(1, DATATYPE_UINT32, context);
 
   if (gridP->rowlon)
     {
       xassert(gridP->nrowlon);
-      packBuffSize += serializeGetSize(gridP->nrowlon, CDI_DATATYPE_INT, context)
-        + serializeGetSize( 1, CDI_DATATYPE_UINT32, context);
+      packBuffSize += serializeGetSize(gridP->nrowlon, DATATYPE_INT, context)
+        + serializeGetSize( 1, DATATYPE_UINT32, context);
     }
 
-  packBuffSize += serializeGetSize(gridNdouble, CDI_DATATYPE_FLT64, context);
+  packBuffSize += serializeGetSize(gridNdouble, DATATYPE_FLT64, context);
 
   if (gridP->vtable->inqXValsPtr(gridP))
     {
       if (gridP->type == GRID_UNSTRUCTURED || gridP->type == GRID_CURVILINEAR)
 	count = gridP->size;
       else
-	count = gridP->x.size;
+	count = gridP->xsize;
       xassert(count);
-      packBuffSize += serializeGetSize(count, CDI_DATATYPE_FLT64, context)
-        + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
+      packBuffSize += serializeGetSize(count, DATATYPE_FLT64, context)
+        + serializeGetSize(1, DATATYPE_UINT32, context);
     }
 
   if (gridP->vtable->inqYValsPtr(gridP))
@@ -29448,44 +28436,44 @@ gridGetPackSize(void * voidP, void *context)
       if (gridP->type == GRID_UNSTRUCTURED || gridP->type == GRID_CURVILINEAR)
 	count = gridP->size;
       else
-	count = gridP->y.size;
+	count = gridP->ysize;
       xassert(count);
-      packBuffSize += serializeGetSize(count, CDI_DATATYPE_FLT64, context)
-        + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
+      packBuffSize += serializeGetSize(count, DATATYPE_FLT64, context)
+        + serializeGetSize(1, DATATYPE_UINT32, context);
     }
 
   if (gridP->vtable->inqAreaPtr(gridP))
     {
       xassert(gridP->size);
       packBuffSize +=
-        serializeGetSize(gridP->size, CDI_DATATYPE_FLT64, context)
-        + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
+        serializeGetSize(gridP->size, DATATYPE_FLT64, context)
+        + serializeGetSize(1, DATATYPE_UINT32, context);
     }
 
-  if (gridP->x.bounds)
+  if (gridP->xbounds)
     {
       xassert(gridP->nvertex);
       if (gridP->type == GRID_CURVILINEAR || gridP->type == GRID_UNSTRUCTURED)
 	count = gridP->size;
       else
-	count = gridP->x.size;
+	count = gridP->xsize;
       xassert(count);
       packBuffSize
-        += (serializeGetSize(gridP->nvertex * count, CDI_DATATYPE_FLT64, context)
-            + serializeGetSize(1, CDI_DATATYPE_UINT32, context));
+        += (serializeGetSize(gridP->nvertex * count, DATATYPE_FLT64, context)
+            + serializeGetSize(1, DATATYPE_UINT32, context));
     }
 
-  if (gridP->y.bounds)
+  if (gridP->ybounds)
     {
       xassert(gridP->nvertex);
       if (gridP->type == GRID_CURVILINEAR || gridP->type == GRID_UNSTRUCTURED)
 	count = gridP->size;
       else
-	count = gridP->y.size;
+	count = gridP->ysize;
       xassert(count);
       packBuffSize
-        += (serializeGetSize(gridP->nvertex * count, CDI_DATATYPE_FLT64, context)
-            + serializeGetSize(1, CDI_DATATYPE_UINT32, context));
+        += (serializeGetSize(gridP->nvertex * count, DATATYPE_FLT64, context)
+            + serializeGetSize(1, DATATYPE_UINT32, context));
     }
 
   {
@@ -29498,28 +28486,28 @@ gridGetPackSize(void * voidP, void *context)
   if (gridP->reference)
     {
       size_t len = strlen(gridP->reference);
-      packBuffSize += serializeGetSize(1, CDI_DATATYPE_INT, context)
-        + serializeGetSize((int)len + 1, CDI_DATATYPE_TXT, context)
-        + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
+      packBuffSize += serializeGetSize(1, DATATYPE_INT, context)
+        + serializeGetSize((int)len + 1, DATATYPE_TXT, context)
+        + serializeGetSize(1, DATATYPE_UINT32, context);
     }
 
   if (gridP->mask)
     {
       xassert(gridP->size);
       packBuffSize
-        += serializeGetSize(gridP->size, CDI_DATATYPE_UCHAR, context)
-        + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
+        += serializeGetSize(gridP->size, DATATYPE_UCHAR, context)
+        + serializeGetSize(1, DATATYPE_UINT32, context);
     }
 
   if (gridP->mask_gme)
     {
       xassert(gridP->size);
-      packBuffSize += serializeGetSize(gridP->size, CDI_DATATYPE_UCHAR, context)
-        + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
+      packBuffSize += serializeGetSize(gridP->size, DATATYPE_UCHAR, context)
+        + serializeGetSize(1, DATATYPE_UINT32, context);
     }
 
   if (!cdiUUIDIsNull(gridP->uuid))
-    packBuffSize += serializeGetSize(CDI_UUID_SIZE, CDI_DATATYPE_UCHAR, context);
+    packBuffSize += serializeGetSize(CDI_UUID_SIZE, DATATYPE_UCHAR, context);
 
   return packBuffSize;
 }
@@ -29538,44 +28526,43 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
   {
     int intBuffer[gridNint];
     serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                    intBuffer, gridNint, CDI_DATATYPE_INT, context);
+                    intBuffer, gridNint, DATATYPE_INT, context);
     serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                    &d, 1, CDI_DATATYPE_UINT32, context);
+                    &d, 1, DATATYPE_UINT32, context);
 
-    xassert(cdiCheckSum(CDI_DATATYPE_INT, gridNint, intBuffer) == d);
+    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[GRID_PACK_INT_IDX_TYPE];
-    gridP->prec          =   intBuffer[GRID_PACK_INT_IDX_PREC];
-    gridP->isCyclic      =   (signed char)intBuffer[GRID_PACK_INT_IDX_IS_CYCLIC];
-    gridP->x.flag        =   (short)intBuffer[GRID_PACK_INT_IDX_X_FLAG];
-    gridP->y.flag        =   (short)intBuffer[GRID_PACK_INT_IDX_Y_FLAG];
-    gridP->gme.nd        =   intBuffer[GRID_PACK_INT_IDX_GME_ND];
-    gridP->gme.ni        =   intBuffer[GRID_PACK_INT_IDX_GME_NI];
-    gridP->gme.ni2       =   intBuffer[GRID_PACK_INT_IDX_GME_NI2];
-    gridP->gme.ni3       =   intBuffer[GRID_PACK_INT_IDX_GME_NI3];
-    gridP->number        =   intBuffer[GRID_PACK_INT_IDX_NUMBER];
-    gridP->position      =   intBuffer[GRID_PACK_INT_IDX_POSITION];
-    gridP->trunc         =   intBuffer[GRID_PACK_INT_IDX_TRUNC];
-    gridP->nvertex       =   intBuffer[GRID_PACK_INT_IDX_NVERTEX];
-    gridP->nrowlon       =   intBuffer[GRID_PACK_INT_IDX_NROWLON];
-    gridP->size          =   intBuffer[GRID_PACK_INT_IDX_SIZE];
-    gridP->x.size        =   intBuffer[GRID_PACK_INT_IDX_X_SIZE];
-    gridP->y.size        =   intBuffer[GRID_PACK_INT_IDX_Y_SIZE];
-    gridP->lcomplex      =   (bool)intBuffer[GRID_PACK_INT_IDX_LCOMPLEX];
-    memberMask           =   intBuffer[GRID_PACK_INT_IDX_MEMBERMASK];
-    gridP->x.stdname     =
-      xystdname_tab[intBuffer[GRID_PACK_INT_IDX_XTSTDNNAME]][0];
-    gridP->y.stdname     =
-      xystdname_tab[intBuffer[GRID_PACK_INT_IDX_YTSTDNNAME]][1];
-    gridP->uvRelativeToGrid         =   intBuffer[GRID_PACK_INT_IDX_UVRELATIVETOGRID];
-    gridP->iScansNegatively         =   (bool)intBuffer[GRID_PACK_INT_IDX_ISCANSNEGATIVELY];
-    gridP->jScansPositively         =   (bool)intBuffer[GRID_PACK_INT_IDX_JSCANSPOSITIVELY];
-    gridP->jPointsAreConsecutive    =   (bool)intBuffer[GRID_PACK_INT_IDX_JPOINTSARECONSECUTIVE];
-    gridP->scanningMode             =   intBuffer[GRID_PACK_INT_IDX_SCANNINGMODE];
+    gridP->type          =   intBuffer[1];
+    gridP->prec          =   intBuffer[2];
+    gridP->lcc_projflag  =   intBuffer[3];
+    gridP->lcc_scanflag  =   intBuffer[4];
+    gridP->lcc_defined   =   (short)intBuffer[5];
+    gridP->lcc2_defined  =   (short)intBuffer[6];
+    gridP->laea_defined  =   intBuffer[7];
+    gridP->isCyclic      =   (short)intBuffer[8];
+    gridP->isRotated     =   (short)intBuffer[9];
+    gridP->xdef          =   (short)intBuffer[10];
+    gridP->ydef          =   (short)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->lcomplex      =   (short)intBuffer[24];
+    memberMask           =   intBuffer[25];
+    gridP->xstdname      =   xystdname_tab[intBuffer[26]][0];
+    gridP->ystdname      =   xystdname_tab[intBuffer[27]][1];
   }
 
   if (memberMask & gridHasRowLonFlag)
@@ -29583,52 +28570,70 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
       xassert(gridP->nrowlon);
       gridP->rowlon = (int *) Malloc((size_t)gridP->nrowlon * sizeof (int));
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      gridP->rowlon, gridP->nrowlon , CDI_DATATYPE_INT, context);
+                      gridP->rowlon, gridP->nrowlon , DATATYPE_INT, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, CDI_DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(CDI_DATATYPE_INT, gridP->nrowlon, gridP->rowlon) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_INT, gridP->nrowlon, gridP->rowlon) == d);
     }
 
   {
     double doubleBuffer[gridNdouble];
     serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                    doubleBuffer, gridNdouble, CDI_DATATYPE_FLT64, context);
+                    doubleBuffer, gridNdouble, DATATYPE_FLT64, context);
     serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                    &d, 1, CDI_DATATYPE_UINT32, context);
-    xassert(d == cdiCheckSum(CDI_DATATYPE_FLT, gridNdouble, doubleBuffer));
-
-    gridP->x.first = doubleBuffer[GRID_PACK_DBL_IDX_X_FIRST];
-    gridP->y.first = doubleBuffer[GRID_PACK_DBL_IDX_Y_FIRST];
-    gridP->x.last = doubleBuffer[GRID_PACK_DBL_IDX_X_LAST];
-    gridP->y.last = doubleBuffer[GRID_PACK_DBL_IDX_Y_LAST];
-    gridP->x.inc = doubleBuffer[GRID_PACK_DBL_IDX_X_INC];
-    gridP->y.inc = doubleBuffer[GRID_PACK_DBL_IDX_Y_INC];
+                    &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 irregular = gridP->type == GRID_UNSTRUCTURED
     || gridP->type == GRID_CURVILINEAR;
   if (memberMask & gridHasXValsFlag)
     {
-      size = irregular ? gridP->size : gridP->x.size;
+      size = irregular ? gridP->size : gridP->xsize;
 
-      gridP->x.vals = (double *) Malloc((size_t)size * sizeof (double));
+      gridP->xvals = (double *) Malloc((size_t)size * sizeof (double));
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      gridP->x.vals, size, CDI_DATATYPE_FLT64, context);
+                      gridP->xvals, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, CDI_DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(CDI_DATATYPE_FLT, size, gridP->x.vals) == d );
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->xvals) == d );
     }
 
   if (memberMask & gridHasYValsFlag)
     {
-      size = irregular ? gridP->size : gridP->y.size;
+      size = irregular ? gridP->size : gridP->ysize;
 
-      gridP->y.vals = (double *) Malloc((size_t)size * sizeof (double));
+      gridP->yvals = (double *) Malloc((size_t)size * sizeof (double));
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      gridP->y.vals, size, CDI_DATATYPE_FLT64, context);
+                      gridP->yvals, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, CDI_DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(CDI_DATATYPE_FLT, size, gridP->y.vals) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->yvals) == d);
     }
 
   if (memberMask & gridHasAreaFlag)
@@ -29637,36 +28642,36 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
       xassert(size);
       gridP->area = (double *) Malloc((size_t)size * sizeof (double));
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      gridP->area, size, CDI_DATATYPE_FLT64, context);
+                      gridP->area, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, CDI_DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(CDI_DATATYPE_FLT, size, gridP->area) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->area) == d);
     }
 
   if (memberMask & gridHasXBoundsFlag)
     {
-      size = gridP->nvertex * (irregular ? gridP->size : gridP->x.size);
+      size = gridP->nvertex * (irregular ? gridP->size : gridP->xsize);
       xassert(size);
 
-      gridP->x.bounds = (double *) Malloc((size_t)size * sizeof (double));
+      gridP->xbounds = (double *) Malloc((size_t)size * sizeof (double));
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      gridP->x.bounds, size, CDI_DATATYPE_FLT64, context);
+                      gridP->xbounds, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, CDI_DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(CDI_DATATYPE_FLT, size, gridP->x.bounds) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->xbounds) == d);
     }
 
   if (memberMask & gridHasYBoundsFlag)
     {
-      size = gridP->nvertex * (irregular ? gridP->size : gridP->y.size);
+      size = gridP->nvertex * (irregular ? gridP->size : gridP->ysize);
       xassert(size);
 
-      gridP->y.bounds = (double *) Malloc((size_t)size * sizeof (double));
+      gridP->ybounds = (double *) Malloc((size_t)size * sizeof (double));
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-			  gridP->y.bounds, size, CDI_DATATYPE_FLT64, context);
+			  gridP->ybounds, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, CDI_DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(CDI_DATATYPE_FLT, size, gridP->y.bounds) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->ybounds) == d);
     }
 
   {
@@ -29680,13 +28685,13 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
     {
       int referenceSize;
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &referenceSize, 1, CDI_DATATYPE_INT, context);
+                      &referenceSize, 1, DATATYPE_INT, context);
       gridP->reference = (char *) Malloc((size_t)referenceSize);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      gridP->reference, referenceSize, CDI_DATATYPE_TXT, context);
+                      gridP->reference, referenceSize, DATATYPE_TXT, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, CDI_DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(CDI_DATATYPE_TXT, referenceSize, gridP->reference) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_TXT, referenceSize, gridP->reference) == d);
     }
 
   if (memberMask & gridHasMaskFlag)
@@ -29694,10 +28699,10 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
       xassert((size = gridP->size));
       gridP->mask = (mask_t *) Malloc((size_t)size * sizeof (mask_t));
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      gridP->mask, gridP->size, CDI_DATATYPE_UCHAR, context);
+                      gridP->mask, gridP->size, DATATYPE_UCHAR, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, CDI_DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(CDI_DATATYPE_UCHAR, gridP->size, gridP->mask) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_UCHAR, gridP->size, gridP->mask) == d);
     }
 
   if (memberMask & gridHasGMEMaskFlag)
@@ -29705,15 +28710,15 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
       xassert((size = gridP->size));
       gridP->mask_gme = (mask_t *) Malloc((size_t)size * sizeof (mask_t));
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      gridP->mask_gme, gridP->size, CDI_DATATYPE_UCHAR, context);
+                      gridP->mask_gme, gridP->size, DATATYPE_UCHAR, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, CDI_DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(CDI_DATATYPE_UCHAR, gridP->size, gridP->mask_gme) == d);
+                      &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, CDI_DATATYPE_UCHAR, context);
+                      gridP->uuid, CDI_UUID_SIZE, DATATYPE_UCHAR, context);
     }
 
   reshSetStatus(gridP->self, &gridOps,
@@ -29733,43 +28738,41 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
   {
     int intBuffer[gridNint];
 
-    intBuffer[GRID_PACK_INT_IDX_SELF]         = gridP->self;
-    intBuffer[GRID_PACK_INT_IDX_TYPE]         = gridP->type;
-    intBuffer[GRID_PACK_INT_IDX_PREC]         = gridP->prec;
-    intBuffer[GRID_PACK_INT_IDX_IS_CYCLIC]    = gridP->isCyclic;
-    intBuffer[GRID_PACK_INT_IDX_X_FLAG]       = gridP->x.flag;
-    intBuffer[GRID_PACK_INT_IDX_Y_FLAG]       = gridP->y.flag;
-    intBuffer[GRID_PACK_INT_IDX_GME_ND]       = gridP->gme.nd;
-    intBuffer[GRID_PACK_INT_IDX_GME_NI]       = gridP->gme.ni;
-    intBuffer[GRID_PACK_INT_IDX_GME_NI2]      = gridP->gme.ni2;
-    intBuffer[GRID_PACK_INT_IDX_GME_NI3]      = gridP->gme.ni3;
-    intBuffer[GRID_PACK_INT_IDX_NUMBER]       = gridP->number;
-    intBuffer[GRID_PACK_INT_IDX_POSITION]     = gridP->position;
-    intBuffer[GRID_PACK_INT_IDX_TRUNC]        = gridP->trunc;
-    intBuffer[GRID_PACK_INT_IDX_NVERTEX]      = gridP->nvertex;
-    intBuffer[GRID_PACK_INT_IDX_NROWLON]      = gridP->nrowlon;
-    intBuffer[GRID_PACK_INT_IDX_SIZE]         = gridP->size;
-    intBuffer[GRID_PACK_INT_IDX_X_SIZE]       = gridP->x.size;
-    intBuffer[GRID_PACK_INT_IDX_Y_SIZE]       = gridP->y.size;
-    intBuffer[GRID_PACK_INT_IDX_LCOMPLEX]     = gridP->lcomplex;
-    intBuffer[GRID_PACK_INT_IDX_MEMBERMASK]   = memberMask
-                                              = gridGetComponentFlags(gridP);
-    intBuffer[GRID_PACK_INT_IDX_XTSTDNNAME]   =
-      (int)((const char (*)[2][24])gridP->x.stdname - xystdname_tab);
-    intBuffer[GRID_PACK_INT_IDX_YTSTDNNAME]   =
-      (int)((const char (*)[2][24])gridP->y.stdname
-            - (const char (*)[2][24])xystdname_tab[0][1]);
-
-    intBuffer[GRID_PACK_INT_IDX_UVRELATIVETOGRID] = gridP->uvRelativeToGrid;
-    intBuffer[GRID_PACK_INT_IDX_ISCANSNEGATIVELY] = gridP->iScansNegatively;
-    intBuffer[GRID_PACK_INT_IDX_JSCANSPOSITIVELY] = gridP->jScansPositively;
-    intBuffer[GRID_PACK_INT_IDX_JPOINTSARECONSECUTIVE] = gridP->jPointsAreConsecutive;
-    intBuffer[GRID_PACK_INT_IDX_SCANNINGMODE] = gridP->scanningMode;
-
-    serializePack(intBuffer, gridNint, CDI_DATATYPE_INT,
+    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->lcomplex;
+    intBuffer[25] = memberMask = gridGetComponentFlags(gridP);
+    intBuffer[26] = (int)((const char (*)[2][24])gridP->xstdname
+                          - xystdname_tab);
+    intBuffer[27] = (int)((const char (*)[2][24])gridP->ystdname
+                          - (const char (*)[2][24])xystdname_tab[0][1]);
+
+    serializePack(intBuffer, gridNint, DATATYPE_INT,
                   packBuffer, packBufferSize, packBufferPos, context);
-    d = cdiCheckSum(CDI_DATATYPE_INT, gridNint, intBuffer);
-    serializePack(&d, 1, CDI_DATATYPE_UINT32,
+    d = cdiCheckSum(DATATYPE_INT, gridNint, intBuffer);
+    serializePack(&d, 1, DATATYPE_UINT32,
                   packBuffer, packBufferSize, packBufferPos, context);
   }
 
@@ -29777,27 +28780,45 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
     {
       size = gridP->nrowlon;
       xassert(size > 0);
-      serializePack(gridP->rowlon, size, CDI_DATATYPE_INT,
+      serializePack(gridP->rowlon, size, DATATYPE_INT,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(CDI_DATATYPE_INT , size, gridP->rowlon);
-      serializePack(&d, 1, CDI_DATATYPE_UINT32,
+      d = cdiCheckSum(DATATYPE_INT , size, gridP->rowlon);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
   {
     double doubleBuffer[gridNdouble];
 
-    doubleBuffer[GRID_PACK_DBL_IDX_X_FIRST]        = gridP->x.first;
-    doubleBuffer[GRID_PACK_DBL_IDX_Y_FIRST]        = gridP->y.first;
-    doubleBuffer[GRID_PACK_DBL_IDX_X_LAST]         = gridP->x.last;
-    doubleBuffer[GRID_PACK_DBL_IDX_Y_LAST]         = gridP->y.last;
-    doubleBuffer[GRID_PACK_DBL_IDX_X_INC]          = gridP->x.inc;
-    doubleBuffer[GRID_PACK_DBL_IDX_Y_INC]          = gridP->y.inc;
-
-    serializePack(doubleBuffer, gridNdouble, CDI_DATATYPE_FLT64,
+    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;
+
+    serializePack(doubleBuffer, gridNdouble, DATATYPE_FLT64,
                   packBuffer, packBufferSize, packBufferPos, context);
-    d = cdiCheckSum(CDI_DATATYPE_FLT, gridNdouble, doubleBuffer);
-    serializePack(&d, 1, CDI_DATATYPE_UINT32,
+    d = cdiCheckSum(DATATYPE_FLT, gridNdouble, doubleBuffer);
+    serializePack(&d, 1, DATATYPE_UINT32,
                   packBuffer, packBufferSize, packBufferPos, context);
   }
 
@@ -29806,14 +28827,14 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
       if (gridP->type == GRID_UNSTRUCTURED || gridP->type == GRID_CURVILINEAR)
 	size = gridP->size;
       else
-	size = gridP->x.size;
+	size = gridP->xsize;
       xassert(size);
 
       const double *gridP_xvals = gridP->vtable->inqXValsPtr(gridP);
-      serializePack(gridP_xvals, size, CDI_DATATYPE_FLT64,
+      serializePack(gridP_xvals, size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(CDI_DATATYPE_FLT, size, gridP_xvals);
-      serializePack(&d, 1, CDI_DATATYPE_UINT32,
+      d = cdiCheckSum(DATATYPE_FLT, size, gridP_xvals);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -29822,13 +28843,13 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
       if (gridP->type == GRID_UNSTRUCTURED || gridP->type == GRID_CURVILINEAR )
 	size = gridP->size;
       else
-	size = gridP->y.size;
+	size = gridP->ysize;
       xassert(size);
       const double *gridP_yvals = gridP->vtable->inqYValsPtr(gridP);
-      serializePack(gridP_yvals, size, CDI_DATATYPE_FLT64,
+      serializePack(gridP_yvals, size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(CDI_DATATYPE_FLT, size, gridP_yvals);
-      serializePack(&d, 1, CDI_DATATYPE_UINT32,
+      d = cdiCheckSum(DATATYPE_FLT, size, gridP_yvals);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -29836,10 +28857,10 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
     {
       xassert(gridP->size);
 
-      serializePack(gridP->area, gridP->size, CDI_DATATYPE_FLT64,
+      serializePack(gridP->area, gridP->size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(CDI_DATATYPE_FLT, gridP->size, gridP->area);
-      serializePack(&d, 1, CDI_DATATYPE_UINT32,
+      d = cdiCheckSum(DATATYPE_FLT, gridP->size, gridP->area);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -29849,13 +28870,13 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
       if (gridP->type == GRID_CURVILINEAR || gridP->type == GRID_UNSTRUCTURED)
 	size = gridP->nvertex * gridP->size;
       else
-	size = gridP->nvertex * gridP->x.size;
+	size = gridP->nvertex * gridP->xsize;
       xassert ( size );
 
-      serializePack(gridP->x.bounds, size, CDI_DATATYPE_FLT64,
+      serializePack(gridP->xbounds, size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(CDI_DATATYPE_FLT, size, gridP->x.bounds);
-      serializePack(&d, 1, CDI_DATATYPE_UINT32,
+      d = cdiCheckSum(DATATYPE_FLT, size, gridP->xbounds);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -29865,13 +28886,13 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
       if (gridP->type == GRID_CURVILINEAR || gridP->type == GRID_UNSTRUCTURED)
 	size = gridP->nvertex * gridP->size;
       else
-	size = gridP->nvertex * gridP->y.size;
+	size = gridP->nvertex * gridP->ysize;
       xassert ( size );
 
-      serializePack(gridP->y.bounds, size, CDI_DATATYPE_FLT64,
+      serializePack(gridP->ybounds, size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(CDI_DATATYPE_FLT, size, gridP->y.bounds);
-      serializePack(&d, 1, CDI_DATATYPE_UINT32,
+      d = cdiCheckSum(DATATYPE_FLT, size, gridP->ybounds);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -29885,22 +28906,22 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
   if (memberMask & gridHasReferenceFlag)
     {
       size = (int)strlen(gridP->reference) + 1;
-      serializePack(&size, 1, CDI_DATATYPE_INT,
+      serializePack(&size, 1, DATATYPE_INT,
                     packBuffer, packBufferSize, packBufferPos, context);
-      serializePack(gridP->reference, size, CDI_DATATYPE_TXT,
+      serializePack(gridP->reference, size, DATATYPE_TXT,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(CDI_DATATYPE_TXT, size, gridP->reference);
-      serializePack(&d, 1, CDI_DATATYPE_UINT32,
+      d = cdiCheckSum(DATATYPE_TXT, size, gridP->reference);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
   if (memberMask & gridHasMaskFlag)
     {
       xassert((size = gridP->size));
-      serializePack(gridP->mask, size, CDI_DATATYPE_UCHAR,
+      serializePack(gridP->mask, size, DATATYPE_UCHAR,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(CDI_DATATYPE_UCHAR, size, gridP->mask);
-      serializePack(&d, 1, CDI_DATATYPE_UINT32,
+      d = cdiCheckSum(DATATYPE_UCHAR, size, gridP->mask);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -29908,15 +28929,15 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
     {
       xassert((size = gridP->size));
 
-      serializePack(gridP->mask_gme, size, CDI_DATATYPE_UCHAR,
+      serializePack(gridP->mask_gme, size, DATATYPE_UCHAR,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(CDI_DATATYPE_UCHAR, size, gridP->mask_gme);
-      serializePack(&d, 1, CDI_DATATYPE_UINT32,
+      d = cdiCheckSum(DATATYPE_UCHAR, size, gridP->mask_gme);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
   if (memberMask & gridHasUUIDFlag)
-    serializePack(gridP->uuid, CDI_UUID_SIZE, CDI_DATATYPE_UCHAR,
+    serializePack(gridP->uuid, CDI_UUID_SIZE, DATATYPE_UCHAR,
                   packBuffer, packBufferSize, packBufferPos, context);
 }
 
@@ -29934,7 +28955,7 @@ gridCompareSearch(int id, void *res, void *data)
 {
   struct gridCompareSearchState *state = (struct gridCompareSearchState*)data;
   (void)res;
-  if ( gridCompare(id, state->queryKey, true) == false )
+  if ( gridCompare(id, state->queryKey) == false )
     {
       state->resIDValue = id;
       return CDI_APPLY_STOP;
@@ -29943,13 +28964,12 @@ gridCompareSearch(int id, void *res, void *data)
     return CDI_APPLY_GO_ON;
 }
 
-/* Add grid (which must be Malloc'ed to vlist if not already found) */
-struct addIfNewRes cdiVlistAddGridIfNew(int vlistID, grid_t *grid, int mode)
+/* Add grid (which must be Malloc'ed to vlist if not already found */
+struct addIffNewRes cdiVlistAddGridIfNew(int vlistID, grid_t *grid, int mode)
 {
   /*
     mode: 0 search in vlist and grid table
           1 search in grid table only
-          2 search in grid table only and don't store the grid in vlist
    */
   bool gridglobdefined = false;
   bool griddefined = false;
@@ -29961,9 +28981,9 @@ struct addIfNewRes cdiVlistAddGridIfNew(int vlistID, grid_t *grid, int mode)
   if ( mode == 0 )
     for ( unsigned index = 0; index < ngrids; index++ )
       {
-	if ( (gridID = vlistptr->gridIDs[index]) != CDI_UNDEFID )
+	if ( (gridID = vlistptr->gridIDs[index]) != UNDEFID )
           {
-            if ( gridCompare(gridID, grid, false) == false )
+            if ( gridCompare(gridID, grid) == false )
               {
                 griddefined = true;
                 break;
@@ -29972,18 +28992,20 @@ struct addIfNewRes cdiVlistAddGridIfNew(int vlistID, grid_t *grid, int mode)
         else
           Error("Internal problem: undefined gridID in vlist "
                 "%d, position %u!", vlistID, index);
+
       }
 
   if ( ! griddefined )
     {
       struct gridCompareSearchState query;
       query.queryKey = grid;// = { .queryKey = grid };
-      if ( (gridglobdefined = (cdiResHFilterApply(&gridOps, gridCompareSearch, &query)
-              == CDI_APPLY_STOP)) )
+      if ((gridglobdefined
+           = (cdiResHFilterApply(&gridOps, gridCompareSearch, &query)
+              == CDI_APPLY_STOP)))
         gridID = query.resIDValue;
 
       if ( mode == 1 && gridglobdefined )
-	for ( unsigned index = 0; index < ngrids; index++ )
+	for (unsigned index = 0; index < ngrids; index++ )
 	  if ( vlistptr->gridIDs[index] == gridID )
 	    {
 	      gridglobdefined = false;
@@ -29998,17 +29020,14 @@ struct addIfNewRes cdiVlistAddGridIfNew(int vlistID, grid_t *grid, int mode)
           grid->self = gridID = reshPut(grid, &gridOps);
           gridComplete(grid);
         }
-      if ( mode < 2 )
-        {
-          vlistptr->gridIDs[ngrids] = gridID;
-          vlistptr->ngrids++;
-        }
+      vlistptr->gridIDs[ngrids] = gridID;
+      vlistptr->ngrids++;
     }
 
-  return (struct addIfNewRes){ .Id = gridID, .isNew = !griddefined && !gridglobdefined };
+  return (struct addIffNewRes){ .Id = gridID,
+      .isNew = !griddefined && !gridglobdefined };
 }
 
-
 const struct gridVirtTable cdiGridVtable
   = {
   .destroy = gridDestroyKernel,
@@ -30025,15 +29044,9 @@ const struct gridVirtTable cdiGridVtable
   .inqXVal = gridInqXValSerial,
   .inqYVal = gridInqYValSerial,
   .inqXVals = gridInqXValsSerial,
-  .inqXCvals = gridInqXCvalsSerial,
-  .inqXIsc = gridInqXIscSerial,
   .inqYVals = gridInqYValsSerial,
-  .inqYCvals = gridInqYCvalsSerial,
-  .inqYIsc = gridInqYIscSerial,
   .inqXValsPtr = gridInqXValsPtrSerial,
   .inqYValsPtr = gridInqYValsPtrSerial,
-  .inqXCvalsPtr = gridInqXCvalsPtrSerial,
-  .inqYCvalsPtr = gridInqYCvalsPtrSerial,
   .compareXYFull = compareXYvals,
   .compareXYAO = compareXYvals2,
   .inqArea = gridInqAreaSerial,
@@ -30889,10 +29902,12 @@ void instituteDefaultEntries(void);
 #include <limits.h>
 
 
+#undef  UNDEFID
+#define UNDEFID  -1
 
-static int ECMWF  = CDI_UNDEFID,
-  MPIMET = CDI_UNDEFID,
-  MCH    = CDI_UNDEFID;
+static int ECMWF  = UNDEFID,
+  MPIMET = UNDEFID,
+  MCH    = UNDEFID;
 
 typedef struct
 {
@@ -30925,10 +29940,10 @@ static const resOps instituteOps = {
 static
 void instituteDefaultValue ( institute_t * instituteptr )
 {
-  instituteptr->self       = CDI_UNDEFID;
+  instituteptr->self       = UNDEFID;
   instituteptr->used       = 0;
-  instituteptr->center     = CDI_UNDEFID;
-  instituteptr->subcenter  = CDI_UNDEFID;
+  instituteptr->center     = UNDEFID;
+  instituteptr->subcenter  = UNDEFID;
   instituteptr->name       = NULL;
   instituteptr->longname   = NULL;
 }
@@ -31023,14 +30038,14 @@ findInstitute(int id, void *res, void *data)
 int institutInq(int center, int subcenter, const char *name, const char *longname)
 {
   institute_t * ip_ref = (institute_t *) Malloc(sizeof (*ip_ref));
-  ip_ref->self       = CDI_UNDEFID;
+  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;
 
-  struct instLoc state = { .ip = ip_ref, .id = CDI_UNDEFID };
+  struct instLoc state = { .ip = ip_ref, .id = UNDEFID };
   cdiResHFilterApply(&instituteOps, findInstitute, &state);
 
   Free(ip_ref);
@@ -31074,10 +30089,10 @@ int institutInqCenter(int instID)
 {
   institute_t * instituteptr = NULL;
 
-  if ( instID != CDI_UNDEFID )
+  if ( instID != UNDEFID )
     instituteptr = ( institute_t * ) reshGetVal ( instID, &instituteOps );
 
-  return  instituteptr ? instituteptr->center : CDI_UNDEFID;
+  return  instituteptr ? instituteptr->center : UNDEFID;
 }
 
 
@@ -31085,10 +30100,10 @@ int institutInqSubcenter(int instID)
 {
   institute_t * instituteptr = NULL;
 
-  if ( instID != CDI_UNDEFID )
+  if ( instID != UNDEFID )
     instituteptr = ( institute_t * ) reshGetVal ( instID, &instituteOps );
 
-  return instituteptr ? instituteptr->subcenter: CDI_UNDEFID;
+  return instituteptr ? instituteptr->subcenter: UNDEFID;
 }
 
 
@@ -31096,7 +30111,7 @@ const char *institutInqNamePtr(int instID)
 {
   institute_t * instituteptr = NULL;
 
-  if ( instID != CDI_UNDEFID )
+  if ( instID != UNDEFID )
     instituteptr = ( institute_t * ) reshGetVal ( instID, &instituteOps );
 
   return instituteptr ? instituteptr->name : NULL;
@@ -31107,7 +30122,7 @@ const char *institutInqLongnamePtr(int instID)
 {
   institute_t * instituteptr = NULL;
 
-  if ( instID != CDI_UNDEFID )
+  if ( instID != UNDEFID )
     instituteptr = ( institute_t * ) reshGetVal ( instID, &instituteOps );
 
   return instituteptr ? instituteptr->longname : NULL;
@@ -31176,9 +30191,9 @@ 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, CDI_DATATYPE_INT, context)
-    + (size_t)serializeGetSize((int)namelen + 1, CDI_DATATYPE_TXT, context)
-    + (size_t)serializeGetSize((int)longnamelen + 1, CDI_DATATYPE_TXT, context);
+  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;
 }
@@ -31192,9 +30207,9 @@ static void institutePackP(void * instituteptr, void *buf, int size, int *positi
   tempbuf[2] = p->subcenter;
   tempbuf[3] = (int)strlen(p->name) + 1;
   tempbuf[4] = (int)strlen(p->longname) + 1;
-  serializePack(tempbuf, institute_nints, CDI_DATATYPE_INT, buf, size, position, context);
-  serializePack(p->name, tempbuf[3], CDI_DATATYPE_TXT, buf, size, position, context);
-  serializePack(p->longname, tempbuf[4], CDI_DATATYPE_TXT, buf, size, position, context);
+  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 instituteUnpack(void *buf, int size, int *position, int originNamespace,
@@ -31203,11 +30218,11 @@ int instituteUnpack(void *buf, int size, int *position, int originNamespace,
   int tempbuf[institute_nints];
   int instituteID;
   char *name, *longname;
-  serializeUnpack(buf, size, position, tempbuf, institute_nints, CDI_DATATYPE_INT, context);
+  serializeUnpack(buf, size, position, tempbuf, institute_nints, DATATYPE_INT, context);
   name = (char *) Malloc((size_t)tempbuf[3] + (size_t)tempbuf[4]);
   longname = name + tempbuf[3];
-  serializeUnpack(buf, size, position, name, tempbuf[3], CDI_DATATYPE_TXT, context);
-  serializeUnpack(buf, size, position, longname, tempbuf[4], CDI_DATATYPE_TXT, context);
+  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);
@@ -31295,11 +30310,6 @@ void baseIterDestruct(CdiIterator *me);
 #ifndef INCLUDE_GUARD_CDI_ITERATOR_FALLBACK_H
 #define INCLUDE_GUARD_CDI_ITERATOR_FALLBACK_H
 
-#if defined (HAVE_CONFIG_H)
-#endif
-
-#include <stdlib.h>
-
 
 typedef struct CdiFallbackIterator CdiFallbackIterator;
 
@@ -31344,9 +30354,6 @@ void cdiFallbackIterator_delete(CdiIterator *super);
 #ifndef INCLUDE_GUARD_CDI_ITERATOR_GRIB_H
 #define INCLUDE_GUARD_CDI_ITERATOR_GRIB_H
 
-#if defined (HAVE_CONFIG_H)
-#endif
-
 
 #ifdef HAVE_LIBGRIB_API
 #include <grib_api.h>
@@ -31401,23 +30408,23 @@ static const char* fileType2String(int fileType)
   switch(fileType)
     {
 #ifdef HAVE_LIBGRIB_API
-        case CDI_FILETYPE_GRB: return "CDI::Iterator::GRIB1";
-        case CDI_FILETYPE_GRB2: return "CDI::Iterator::GRIB2";
+        case FILETYPE_GRB: return "CDI::Iterator::GRIB1";
+        case FILETYPE_GRB2: return "CDI::Iterator::GRIB2";
 #endif
 #ifdef HAVE_LIBNETCDF
-        case CDI_FILETYPE_NC: return "CDI::Iterator::NetCDF";
-        case CDI_FILETYPE_NC2: return "CDI::Iterator::NetCDF2";
-        case CDI_FILETYPE_NC4: return "CDI::Iterator::NetCDF4";
-        case CDI_FILETYPE_NC4C: return "CDI::Iterator::NetCDF4C";
+        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 CDI_FILETYPE_SRV: return "CDI::Iterator::SRV";
+        case FILETYPE_SRV: return "CDI::Iterator::SRV";
 #endif
 #ifdef HAVE_LIBEXTRA
-        case CDI_FILETYPE_EXT: return "CDI::Iterator::EXT";
+        case FILETYPE_EXT: return "CDI::Iterator::EXT";
 #endif
 #ifdef HAVE_LIBIEG
-        case CDI_FILETYPE_IEG: return "CDI::Iterator::IEG";
+        case FILETYPE_IEG: return "CDI::Iterator::IEG";
 #endif
 
       default: return NULL;
@@ -31434,24 +30441,24 @@ static int string2FileType(const char* fileType, const char **outRestString)
           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 CDI_FILETYPE_UNDEF; \
+          return FILETYPE_UNDEF; \
         } \
     } while(0)
-  check(fileType, "CDI::Iterator::GRIB1", CDI_FILETYPE_GRB);
-  check(fileType, "CDI::Iterator::GRIB2", CDI_FILETYPE_GRB2);
-  check(fileType, "CDI::Iterator::NetCDF", CDI_FILETYPE_NC);
-  check(fileType, "CDI::Iterator::NetCDF2", CDI_FILETYPE_NC2);
-  check(fileType, "CDI::Iterator::NetCDF4", CDI_FILETYPE_NC4);
-  check(fileType, "CDI::Iterator::NetCDF4C", CDI_FILETYPE_NC4C);
-  check(fileType, "CDI::Iterator::SRV", CDI_FILETYPE_SRV);
-  check(fileType, "CDI::Iterator::EXT", CDI_FILETYPE_EXT);
-  check(fileType, "CDI::Iterator::IEG", CDI_FILETYPE_IEG);
+  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 CDI_FILETYPE_UNDEF;
+  return FILETYPE_UNDEF;
 }
 
 /*
@@ -31479,30 +30486,30 @@ CdiIterator* cdiIterator_new(const char* path)
   int filetype = cdiGetFiletype(path, &trash);
   switch(filetype)
     {
-      case CDI_FILETYPE_UNDEF:
+      case FILETYPE_UNDEF:
         Warning("Can't open file \"%s\": unknown format\n", path);
         return NULL;
 
 #ifdef HAVE_LIBGRIB_API
-        case CDI_FILETYPE_GRB:
-        case CDI_FILETYPE_GRB2:
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
           return cdiGribIterator_new(path, filetype);
 #endif
 
 #ifdef HAVE_LIBNETCDF
-        case CDI_FILETYPE_NC:
-        case CDI_FILETYPE_NC2:
-        case CDI_FILETYPE_NC4:
-        case CDI_FILETYPE_NC4C:
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
 #endif
 #ifdef HAVE_LIBSERVICE
-        case CDI_FILETYPE_SRV:
+        case FILETYPE_SRV:
 #endif
 #ifdef HAVE_LIBEXTRA
-        case CDI_FILETYPE_EXT:
+        case FILETYPE_EXT:
 #endif
 #ifdef HAVE_LIBIEG
-        case CDI_FILETYPE_IEG:
+        case FILETYPE_IEG:
 #endif
           return cdiFallbackIterator_new(path, filetype);
 
@@ -31522,7 +30529,7 @@ const char* baseIter_constructFromString(CdiIterator* me, const char* descriptio
 {
   const char* result = description;
   me->filetype = string2FileType(result, &result);
-  assert(me->filetype != CDI_FILETYPE_UNDEF && "Please report this error.");        //This condition should have been checked for in a calling function.
+  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))
     {
@@ -31573,25 +30580,25 @@ CdiIterator* cdiIterator_clone(CdiIterator* me)
   switch(me->filetype)
     {
 #ifdef HAVE_LIBGRIB_API
-        case CDI_FILETYPE_GRB:
-        case CDI_FILETYPE_GRB2:
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
           return cdiGribIterator_getSuper(cdiGribIterator_clone(me));
 #endif
 
 #ifdef HAVE_LIBNETCDF
-        case CDI_FILETYPE_NC:
-        case CDI_FILETYPE_NC2:
-        case CDI_FILETYPE_NC4:
-        case CDI_FILETYPE_NC4C:
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
 #endif
 #ifdef HAVE_LIBSERVICE
-        case CDI_FILETYPE_SRV:
+        case FILETYPE_SRV:
 #endif
 #ifdef HAVE_LIBEXTRA
-        case CDI_FILETYPE_EXT:
+        case FILETYPE_EXT:
 #endif
 #ifdef HAVE_LIBIEG
-        case CDI_FILETYPE_IEG:
+        case FILETYPE_IEG:
 #endif
           return cdiFallbackIterator_getSuper(cdiFallbackIterator_clone(me));
 
@@ -31623,8 +30630,8 @@ CdiGribIterator* cdiGribIterator_clone(CdiIterator* me)
   switch(me->filetype)
     {
 #ifdef HAVE_LIBGRIB_API
-        case CDI_FILETYPE_GRB:
-        case CDI_FILETYPE_GRB2:
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
           return cdiGribIterator_makeClone(me);
 #endif
 
@@ -31653,26 +30660,26 @@ char* cdiIterator_serialize(CdiIterator* me)
   switch(me->filetype)
     {
 #ifdef HAVE_LIBGRIB_API
-        case CDI_FILETYPE_GRB:
-        case CDI_FILETYPE_GRB2:
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
           subclassDescription = cdiGribIterator_serialize(me);
           break;
 #endif
 
 #ifdef HAVE_LIBNETCDF
-        case CDI_FILETYPE_NC:
-        case CDI_FILETYPE_NC2:
-        case CDI_FILETYPE_NC4:
-        case CDI_FILETYPE_NC4C:
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
 #endif
 #ifdef HAVE_LIBSERVICE
-        case CDI_FILETYPE_SRV:
+        case FILETYPE_SRV:
 #endif
 #ifdef HAVE_LIBEXTRA
-        case CDI_FILETYPE_EXT:
+        case FILETYPE_EXT:
 #endif
 #ifdef HAVE_LIBIEG
-        case CDI_FILETYPE_IEG:
+        case FILETYPE_IEG:
 #endif
           subclassDescription = cdiFallbackIterator_serialize(me);
           break;
@@ -31713,25 +30720,25 @@ CdiIterator* cdiIterator_deserialize(const char* description)
   switch(string2FileType(description, NULL))
     {
 #ifdef HAVE_LIBGRIB_API
-        case CDI_FILETYPE_GRB:
-        case CDI_FILETYPE_GRB2:
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
           return cdiGribIterator_getSuper(cdiGribIterator_deserialize(description));
 #endif
 
 #ifdef HAVE_LIBNETCDF
-        case CDI_FILETYPE_NC:
-        case CDI_FILETYPE_NC2:
-        case CDI_FILETYPE_NC4:
-        case CDI_FILETYPE_NC4C:
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
 #endif
 #ifdef HAVE_LIBSERVICE
-        case CDI_FILETYPE_SRV:
+        case FILETYPE_SRV:
 #endif
 #ifdef HAVE_LIBEXTRA
-        case CDI_FILETYPE_EXT:
+        case FILETYPE_EXT:
 #endif
 #ifdef HAVE_LIBIEG
-        case CDI_FILETYPE_IEG:
+        case FILETYPE_IEG:
 #endif
           return cdiFallbackIterator_getSuper(cdiFallbackIterator_deserialize(description));
 
@@ -31785,25 +30792,25 @@ int cdiIterator_nextField(CdiIterator* me)
   switch(me->filetype)
     {
 #ifdef HAVE_LIBGRIB_API
-        case CDI_FILETYPE_GRB:
-        case CDI_FILETYPE_GRB2:
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
           return cdiGribIterator_nextField(me);
 #endif
 
 #ifdef HAVE_LIBNETCDF
-        case CDI_FILETYPE_NC:
-        case CDI_FILETYPE_NC2:
-        case CDI_FILETYPE_NC4:
-        case CDI_FILETYPE_NC4C:
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
 #endif
 #ifdef HAVE_LIBSERVICE
-        case CDI_FILETYPE_SRV:
+        case FILETYPE_SRV:
 #endif
 #ifdef HAVE_LIBEXTRA
-        case CDI_FILETYPE_EXT:
+        case FILETYPE_EXT:
 #endif
 #ifdef HAVE_LIBIEG
-        case CDI_FILETYPE_IEG:
+        case FILETYPE_IEG:
 #endif
           return cdiFallbackIterator_nextField(me);
 
@@ -31819,25 +30826,25 @@ static char* cdiIterator_inqTime(CdiIterator* me, CdiTimeType timeType)
   switch(me->filetype)
     {
 #ifdef HAVE_LIBGRIB_API
-        case CDI_FILETYPE_GRB:
-        case CDI_FILETYPE_GRB2:
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
           return cdiGribIterator_inqTime(me, timeType);
 #endif
 
 #ifdef HAVE_LIBNETCDF
-        case CDI_FILETYPE_NC:
-        case CDI_FILETYPE_NC2:
-        case CDI_FILETYPE_NC4:
-        case CDI_FILETYPE_NC4C:
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
 #endif
 #ifdef HAVE_LIBSERVICE
-        case CDI_FILETYPE_SRV:
+        case FILETYPE_SRV:
 #endif
 #ifdef HAVE_LIBEXTRA
-        case CDI_FILETYPE_EXT:
+        case FILETYPE_EXT:
 #endif
 #ifdef HAVE_LIBIEG
-        case CDI_FILETYPE_IEG:
+        case FILETYPE_IEG:
 #endif
           return cdiFallbackIterator_inqTime(me, timeType);
 
@@ -31979,25 +30986,25 @@ int cdiIterator_inqLevelType(CdiIterator* me, int levelSelector, char **outName,
   switch(me->filetype)
     {
 #ifdef HAVE_LIBGRIB_API
-        case CDI_FILETYPE_GRB:
-        case CDI_FILETYPE_GRB2:
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
           return cdiGribIterator_levelType(me, levelSelector, outName, outLongName, outStdName, outUnit);
 #endif
 
 #ifdef HAVE_LIBNETCDF
-        case CDI_FILETYPE_NC:
-        case CDI_FILETYPE_NC2:
-        case CDI_FILETYPE_NC4:
-        case CDI_FILETYPE_NC4C:
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
 #endif
 #ifdef HAVE_LIBSERVICE
-        case CDI_FILETYPE_SRV:
+        case FILETYPE_SRV:
 #endif
 #ifdef HAVE_LIBEXTRA
-        case CDI_FILETYPE_EXT:
+        case FILETYPE_EXT:
 #endif
 #ifdef HAVE_LIBIEG
-        case CDI_FILETYPE_IEG:
+        case FILETYPE_IEG:
 #endif
           return cdiFallbackIterator_levelType(me, levelSelector, outName, outLongName, outStdName, outUnit);
 
@@ -32029,25 +31036,25 @@ int cdiIterator_inqLevel(CdiIterator* me, int levelSelector, double* outValue1,
   switch(me->filetype)
     {
 #ifdef HAVE_LIBGRIB_API
-        case CDI_FILETYPE_GRB:
-        case CDI_FILETYPE_GRB2:
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
           return cdiGribIterator_level(me, levelSelector, outValue1, outValue2);
 #endif
 
 #ifdef HAVE_LIBNETCDF
-        case CDI_FILETYPE_NC:
-        case CDI_FILETYPE_NC2:
-        case CDI_FILETYPE_NC4:
-        case CDI_FILETYPE_NC4C:
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
 #endif
 #ifdef HAVE_LIBSERVICE
-        case CDI_FILETYPE_SRV:
+        case FILETYPE_SRV:
 #endif
 #ifdef HAVE_LIBEXTRA
-        case CDI_FILETYPE_EXT:
+        case FILETYPE_EXT:
 #endif
 #ifdef HAVE_LIBIEG
-        case CDI_FILETYPE_IEG:
+        case FILETYPE_IEG:
 #endif
           return cdiFallbackIterator_level(me, levelSelector, outValue1, outValue2);
 
@@ -32079,25 +31086,25 @@ int cdiIterator_inqLevelUuid(CdiIterator* me, int* outVgridNumber, int* outLevel
   switch(me->filetype)
     {
 #ifdef HAVE_LIBGRIB_API
-        case CDI_FILETYPE_GRB:
-        case CDI_FILETYPE_GRB2:
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
           return cdiGribIterator_zaxisUuid(me, outVgridNumber, outLevelCount, outUuid);
 #endif
 
 #ifdef HAVE_LIBNETCDF
-        case CDI_FILETYPE_NC:
-        case CDI_FILETYPE_NC2:
-        case CDI_FILETYPE_NC4:
-        case CDI_FILETYPE_NC4C:
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
 #endif
 #ifdef HAVE_LIBSERVICE
-        case CDI_FILETYPE_SRV:
+        case FILETYPE_SRV:
 #endif
 #ifdef HAVE_LIBEXTRA
-        case CDI_FILETYPE_EXT:
+        case FILETYPE_EXT:
 #endif
 #ifdef HAVE_LIBIEG
-        case CDI_FILETYPE_IEG:
+        case FILETYPE_IEG:
 #endif
           return cdiFallbackIterator_zaxisUuid(me, outVgridNumber, outLevelCount, outUuid);
 
@@ -32128,25 +31135,25 @@ int cdiIterator_inqTile(CdiIterator* me, int* outTileIndex, int* outTileAttribut
   switch(me->filetype)
     {
       #ifdef HAVE_LIBGRIB_API
-        case CDI_FILETYPE_GRB:
-        case CDI_FILETYPE_GRB2:
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
           return cdiGribIterator_inqTile(me, outTileIndex, outTileAttribute);
       #endif
 
       #ifdef HAVE_LIBNETCDF
-        case CDI_FILETYPE_NC:
-        case CDI_FILETYPE_NC2:
-        case CDI_FILETYPE_NC4:
-        case CDI_FILETYPE_NC4C:
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
       #endif
       #ifdef HAVE_LIBSERVICE
-        case CDI_FILETYPE_SRV:
+        case FILETYPE_SRV:
       #endif
       #ifdef HAVE_LIBEXTRA
-        case CDI_FILETYPE_EXT:
+        case FILETYPE_EXT:
       #endif
       #ifdef HAVE_LIBIEG
-        case CDI_FILETYPE_IEG:
+        case FILETYPE_IEG:
       #endif
           return cdiFallbackIterator_inqTile(me, outTileIndex, outTileAttribute);
 
@@ -32178,25 +31185,25 @@ int cdiIterator_inqTileCount(CdiIterator* me, int* outTileCount, int* outTileAtt
   switch(me->filetype)
     {
       #ifdef HAVE_LIBGRIB_API
-        case CDI_FILETYPE_GRB:
-        case CDI_FILETYPE_GRB2:
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
           return cdiGribIterator_inqTileCount(me, outTileCount, outTileAttributeCount);
       #endif
 
       #ifdef HAVE_LIBNETCDF
-        case CDI_FILETYPE_NC:
-        case CDI_FILETYPE_NC2:
-        case CDI_FILETYPE_NC4:
-        case CDI_FILETYPE_NC4C:
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
       #endif
       #ifdef HAVE_LIBSERVICE
-        case CDI_FILETYPE_SRV:
+        case FILETYPE_SRV:
       #endif
       #ifdef HAVE_LIBEXTRA
-        case CDI_FILETYPE_EXT:
+        case FILETYPE_EXT:
       #endif
       #ifdef HAVE_LIBIEG
-        case CDI_FILETYPE_IEG:
+        case FILETYPE_IEG:
       #endif
           return cdiFallbackIterator_inqTileCount(me, outTileCount, outTileAttributeCount);
 
@@ -32308,25 +31315,25 @@ char* cdiIterator_inqVariableName(CdiIterator* me)
   switch(me->filetype)
     {
 #ifdef HAVE_LIBGRIB_API
-        case CDI_FILETYPE_GRB:
-        case CDI_FILETYPE_GRB2:
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
           return cdiGribIterator_copyVariableName(me);
 #endif
 
 #ifdef HAVE_LIBNETCDF
-        case CDI_FILETYPE_NC:
-        case CDI_FILETYPE_NC2:
-        case CDI_FILETYPE_NC4:
-        case CDI_FILETYPE_NC4C:
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
 #endif
 #ifdef HAVE_LIBSERVICE
-        case CDI_FILETYPE_SRV:
+        case FILETYPE_SRV:
 #endif
 #ifdef HAVE_LIBEXTRA
-        case CDI_FILETYPE_EXT:
+        case FILETYPE_EXT:
 #endif
 #ifdef HAVE_LIBIEG
-        case CDI_FILETYPE_IEG:
+        case FILETYPE_IEG:
 #endif
           return cdiFallbackIterator_copyVariableName(me);
 
@@ -32377,26 +31384,26 @@ void cdiIterator_readField(CdiIterator* me, double* buffer, size_t* nmiss)
   switch(me->filetype)
     {
 #ifdef HAVE_LIBGRIB_API
-        case CDI_FILETYPE_GRB:
-        case CDI_FILETYPE_GRB2:
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
           cdiGribIterator_readField(me, buffer, nmiss);
 	  return;
 #endif
 
 #ifdef HAVE_LIBNETCDF
-        case CDI_FILETYPE_NC:
-        case CDI_FILETYPE_NC2:
-        case CDI_FILETYPE_NC4:
-        case CDI_FILETYPE_NC4C:
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
 #endif
 #ifdef HAVE_LIBSERVICE
-        case CDI_FILETYPE_SRV:
+        case FILETYPE_SRV:
 #endif
 #ifdef HAVE_LIBEXTRA
-        case CDI_FILETYPE_EXT:
+        case FILETYPE_EXT:
 #endif
 #ifdef HAVE_LIBIEG
-        case CDI_FILETYPE_IEG:
+        case FILETYPE_IEG:
 #endif
           cdiFallbackIterator_readField(me, buffer, nmiss);
           return;
@@ -32426,26 +31433,26 @@ void cdiIterator_readFieldF(CdiIterator* me, float* buffer, size_t* nmiss)
   switch(me->filetype)
     {
 #ifdef HAVE_LIBGRIB_API
-        case CDI_FILETYPE_GRB:
-        case CDI_FILETYPE_GRB2:
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
           cdiGribIterator_readFieldF(me, buffer, nmiss);
 	  return;
 #endif
 
 #ifdef HAVE_LIBNETCDF
-        case CDI_FILETYPE_NC:
-        case CDI_FILETYPE_NC2:
-        case CDI_FILETYPE_NC4:
-        case CDI_FILETYPE_NC4C:
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
 #endif
 #ifdef HAVE_LIBSERVICE
-        case CDI_FILETYPE_SRV:
+        case FILETYPE_SRV:
 #endif
 #ifdef HAVE_LIBEXTRA
-        case CDI_FILETYPE_EXT:
+        case FILETYPE_EXT:
 #endif
 #ifdef HAVE_LIBIEG
-        case CDI_FILETYPE_IEG:
+        case FILETYPE_IEG:
 #endif
           cdiFallbackIterator_readFieldF(me, buffer, nmiss);
           return; 
@@ -32471,26 +31478,26 @@ void cdiIterator_delete(CdiIterator* me)
   switch(me->filetype)
     {
 #ifdef HAVE_LIBGRIB_API
-        case CDI_FILETYPE_GRB:
-        case CDI_FILETYPE_GRB2:
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
           cdiGribIterator_delete((CdiGribIterator*)me);
           break;
 #endif
 
 #ifdef HAVE_LIBNETCDF
-        case CDI_FILETYPE_NC:
-        case CDI_FILETYPE_NC2:
-        case CDI_FILETYPE_NC4:
-        case CDI_FILETYPE_NC4C:
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
 #endif
 #ifdef HAVE_LIBSERVICE
-        case CDI_FILETYPE_SRV:
+        case FILETYPE_SRV:
 #endif
 #ifdef HAVE_LIBEXTRA
-        case CDI_FILETYPE_EXT:
+        case FILETYPE_EXT:
 #endif
 #ifdef HAVE_LIBIEG
-        case CDI_FILETYPE_IEG:
+        case FILETYPE_IEG:
 #endif
           cdiFallbackIterator_delete(me);
           break;
@@ -32515,9 +31522,6 @@ void baseIterDestruct(CdiIterator* me)
  * require-trailing-newline: t
  * End:
  */
-#if defined (HAVE_CONFIG_H)
-#endif
-
 
 
 #include <assert.h>
@@ -32920,10 +31924,6 @@ void cdiFallbackIterator_delete(CdiIterator *super)
 #ifndef _STREAM_GRB_H
 #define _STREAM_GRB_H
 
-static inline bool gribbyte_get_bit(int number, int bit) { return (bool)((number >> (8-bit)) & 1); }
-static inline void gribbyte_set_bit(int *number, int bit) { *number |= 1 << (8-bit); }
-static inline void gribbyte_clear_bit(int *number, int bit) { *number &= ~(1 << (8-bit)); }
-
 int   grbBitsPerValue(int datatype);
 
 int   grbInqContents(stream_t *streamptr);
@@ -32947,34 +31947,6 @@ int   grib2ltypeToZaxisType(int grib_ltype);
 int   zaxisTypeToGrib1ltype(int zaxistype);
 int   zaxisTypeToGrib2ltype(int zaxistype);
 
-struct cdiGribParamChange
-{
-  int code, ltype, lev;
-  bool active;
-};
-
-struct cdiGribModeChange
-{
-  bool mode;
-  bool active;
-};
-
-struct cdiGribScanModeChange
-{
-  int value;
-  bool active;
-};
-
-extern struct cdiGribParamChange cdiGribChangeParameterID;
-extern struct cdiGribModeChange cdiGribChangeModeUvRelativeToGrid;
-extern struct cdiGribScanModeChange cdiGribDataScanningMode;
-
-// Used in CDO
-void streamGrbChangeParameterIdentification(int code, int ltype, int lev);
-void streamGrbChangeModeUvRelativeToGrid(int mode);
-void streamGrbDefDataScanningMode(int scanmode);
-int  streamGrbInqDataScanningMode(void);
-
 #endif  /* _STREAM_GRB_H */
 /*
  * Local Variables:
@@ -32988,54 +31960,10 @@ int  streamGrbInqDataScanningMode(void);
 #ifndef _ZAXIS_H
 #define _ZAXIS_H
 
-
-typedef struct {
-  double value;
-  bool defined;
-}
-zkey_double_t;
-
-typedef struct {
-  char     dimname[CDI_MAX_NAME];
-  char     vdimname[CDI_MAX_NAME];
-  char     name[CDI_MAX_NAME];
-  char     longname[CDI_MAX_NAME];
-  char     stdname[CDI_MAX_NAME];
-  char     units[CDI_MAX_NAME];
-  char     psname[CDI_MAX_NAME];
-  char     p0name[CDI_MAX_NAME];
-  zkey_double_t p0value;
-  double  *vals;
-  char   **cvals;
-  int      clength;
-  double  *lbounds;
-  double  *ubounds;
-  double  *weights;
-  int      self;
-  int      prec;
-  int      scalar;
-  int      type;
-  int      ltype;    /* GRIB level type */
-  int      ltype2;
-  int      size;
-  int      direction;
-  int      vctsize;
-  unsigned positive;
-  double  *vct;
-  int      number;   /* Reference number to a generalized Z-axis */
-  int      nhlev;
-  unsigned char uuid[CDI_UUID_SIZE];
-  cdi_atts_t atts;
-}
-zaxis_t;
-
-
 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.
 
 unsigned cdiZaxisCount(void);
 
-zaxis_t *zaxis_to_pointer(int zaxisID);
-
 void cdiZaxisGetIndexList(unsigned numIDs, int *IDs);
 
 void
@@ -33049,11 +31977,6 @@ const resOps *getZaxisOps(void);
 
 const char *zaxisInqNamePtr(int zaxisID);
 
-const double *zaxisInqLevelsPtr(int zaxisID);
-char **zaxisInqCValsPtr(int zaxisID);
-
-void zaxisResize(int zaxisID, int size);
-
 #endif
 
 /*
@@ -33065,9 +31988,6 @@ void zaxisResize(int zaxisID, int size);
  * require-trailing-newline: t
  * End:
  */
-#if defined (HAVE_CONFIG_H)
-#endif
-
 
 
 #include <assert.h>
@@ -33085,7 +32005,11 @@ struct CdiGribIterator {
   off_t fileOffset;
   unsigned char *gribBuffer;
   size_t bufferSize, curRecordSize;
+#ifdef HAVE_LIBGRIB_API
   grib_handle *gribHandle;
+#else
+  void *gribHandle;
+#endif
 };
 
 CdiIterator *cdiGribIterator_getSuper(CdiGribIterator *me)
@@ -33141,7 +32065,7 @@ CdiIterator *cdiGribIterator_new(const char *path, int filetype)
 
 CdiGribIterator *cdiGribIterator_makeClone(CdiIterator *super)
 {
-  CdiGribIterator *me = (CdiGribIterator*)(void *)super;
+  CdiGribIterator *me = (CdiGribIterator*)super;
 
   //Allocate memory and copy data. (operations that may fail)
   CdiGribIterator *result = (struct CdiGribIterator *) Malloc(sizeof(*result));
@@ -33193,12 +32117,12 @@ fail:
 
 char *cdiGribIterator_serialize(CdiIterator *super)
 {
-  CdiGribIterator *me = (CdiGribIterator*)(void *)super;
+  CdiGribIterator *me = (CdiGribIterator*)super;
 
   const char *path = cdiInputFile_getPath(me->file);
   char *escapedPath = cdiEscapeSpaces(path);
   char *result = (char *) Malloc(strlen(escapedPath) + 3 * sizeof(int) * CHAR_BIT/8);
-  sprintf(result, "%s %zu", escapedPath, (size_t)me->fileOffset);
+  sprintf(result, "%s %zu", escapedPath, me->fileOffset);
   Free(escapedPath);
   return result;
 }
@@ -33222,9 +32146,7 @@ CdiGribIterator *cdiGribIterator_deserialize(const char *description)
 
   {
     const char *savedStart = description;
-    char *description_ = (char *)description;
-    long long decodedOffset = strtoll(description, &description_, 0);
-    description = 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;
@@ -33406,7 +32328,7 @@ fail:
 
 int cdiGribIterator_nextField(CdiIterator *super)
 {
-  CdiGribIterator *me = (CdiGribIterator*)(void *)super;
+  CdiGribIterator *me = (CdiGribIterator*)super;
 
   if(super->gridId != CDI_UNDEFID) gridDestroy(super->gridId), super->gridId = CDI_UNDEFID;
 
@@ -33427,13 +32349,13 @@ int cdiGribIterator_nextField(CdiIterator *super)
 
 char *cdiGribIterator_inqTime(CdiIterator *super, CdiTimeType timeType)
 {
-  CdiGribIterator *me = (CdiGribIterator*)(void *)super;
+  CdiGribIterator *me = (CdiGribIterator*)super;
   return gribMakeTimeString(me->gribHandle, timeType);
 }
 
 int cdiGribIterator_levelType(CdiIterator *super, int levelSelector, char **outName, char **outLongName, char **outStdName, char **outUnit)
 {
-  CdiGribIterator *me = (CdiGribIterator*)(void *)super;
+  CdiGribIterator *me = (CdiGribIterator*)super;
 
   //First determine the zaxis type corresponding to the given level.
   int zaxisType = ZAXIS_GENERIC;
@@ -33520,7 +32442,7 @@ static int readLevel2(grib_handle *gribHandle, const char *levelTypeKey, const c
 
 int cdiGribIterator_level(CdiIterator *super, int levelSelector, double *outValue1, double *outValue2)
 {
-  CdiGribIterator *me = (CdiGribIterator*)(void *)super;
+  CdiGribIterator *me = (CdiGribIterator*)super;
   double trash;
   if(!outValue1) outValue1 = &trash;
   if(!outValue2) outValue2 = &trash;
@@ -33544,15 +32466,15 @@ int cdiGribIterator_level(CdiIterator *super, int levelSelector, double *outValu
         {}
       else if(isGrib1DualLevel((int)levelType))
         {
-          *outValue1 = (double)(gribGetLongDefault(me->gribHandle, (levelSelector ? "bottomLevel" : "topLevel"), 0));
+          *outValue1 = (double)gribGetLongDefault(me->gribHandle, (levelSelector ? "bottomLevel" : "topLevel"), 0);
         }
       else if(levelType == 100)
         {
-          *outValue1 = 100 * (double)(gribGetLongDefault(me->gribHandle, "level", 0));        //2 bytes
+          *outValue1 = 100 * (double)gribGetLongDefault(me->gribHandle, "level", 0);        //2 bytes
         }
       else
         {
-          *outValue1 = (double)(gribGetLongDefault(me->gribHandle, "level", 0));        //2 bytes
+          *outValue1 = (double)gribGetLongDefault(me->gribHandle, "level", 0);        //2 bytes
         }
     }
   return CDI_NOERR;
@@ -33560,7 +32482,7 @@ int cdiGribIterator_level(CdiIterator *super, int levelSelector, double *outValu
 
 int cdiGribIterator_zaxisUuid(CdiIterator *super, int *outVgridNumber, int *outLevelCount, unsigned char outUuid[CDI_UUID_SIZE])
 {
-  CdiGribIterator *me = (CdiGribIterator*)(void *)super;
+  CdiGribIterator *me = (CdiGribIterator*)super;
 
   if(outVgridNumber)
     {
@@ -33586,7 +32508,7 @@ int cdiGribIterator_zaxisUuid(CdiIterator *super, int *outVgridNumber, int *outL
 
 int cdiGribIterator_inqTile(CdiIterator *super, int *outTileIndex, int *outTileAttribute)
 {
-  CdiGribIterator *me = (CdiGribIterator*)(void *)super;
+  CdiGribIterator *me = (CdiGribIterator*)super;
   int trash;
   if(!outTileIndex) outTileIndex = &trash;
   if(!outTileAttribute) outTileAttribute = &trash;
@@ -33606,7 +32528,7 @@ int cdiGribIterator_inqTile(CdiIterator *super, int *outTileIndex, int *outTileA
 
 int cdiGribIterator_inqTileCount(CdiIterator *super, int *outTileCount, int *outTileAttributeCount)
 {
-  CdiGribIterator *me = (CdiGribIterator*)(void *)super;
+  CdiGribIterator *me = (CdiGribIterator*)super;
   int trash;
   if(!outTileCount) outTileCount = &trash;
   if(!outTileAttributeCount) outTileAttributeCount = &trash;
@@ -33626,13 +32548,13 @@ int cdiGribIterator_inqTileCount(CdiIterator *super, int *outTileCount, int *out
 
 char *cdiGribIterator_copyVariableName(CdiIterator *super)
 {
-  CdiGribIterator *me = (CdiGribIterator*)(void *)super;
+  CdiGribIterator *me = (CdiGribIterator*)super;
   return gribCopyString(me->gribHandle, "shortName");
 }
 
 void cdiGribIterator_readField(CdiIterator *super, double *buffer, size_t *nmiss)
 {
-  CdiGribIterator *me = (CdiGribIterator*)(void *)super;
+  CdiGribIterator *me = (CdiGribIterator*)super;
 
   GRIB_CHECK(my_grib_set_double(me->gribHandle, "missingValue", cdiDefaultMissval), 0);
   gribGetDoubleArray(me->gribHandle, "values", buffer);
@@ -33645,7 +32567,7 @@ void cdiGribIterator_readField(CdiIterator *super, double *buffer, size_t *nmiss
 
 void cdiGribIterator_readFieldF(CdiIterator *super, float *buffer, size_t *nmiss)
 {
-  CdiGribIterator *me = (CdiGribIterator*)(void *)super;
+  CdiGribIterator *me = (CdiGribIterator*)super;
 
   size_t valueCount = gribGetArraySize(me->gribHandle, "values");
   double *temp = (double *) Malloc(valueCount*sizeof(*temp));
@@ -33701,7 +32623,6 @@ int cdiGribIterator_inqEdition(CdiGribIterator *me)
 #else
   (void)me;
   xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
-  return -4;
 #endif
 }
 
@@ -33728,7 +32649,6 @@ int cdiGribIterator_getLong(CdiGribIterator *me, const char *key, long *result)
   (void)key;
   (void)result;
   xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
-  return -4;
 #endif
 }
 
@@ -33761,7 +32681,6 @@ int cdiGribIterator_getLength(CdiGribIterator *me, const char *key, size_t *resu
   (void)key;
   (void)result;
   xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
-  return -4;
 #endif
 }
 
@@ -33789,7 +32708,6 @@ int cdiGribIterator_getString(CdiGribIterator *me, const char *key, char *result
   (void)result;
   (void)length;
   xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
-  return -4;
 #endif
 }
 
@@ -33816,7 +32734,6 @@ long cdiGribIterator_inqLongValue(CdiGribIterator *me, const char *key)
   (void)me;
   (void)key;
   xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
-  return -4;
 #endif
 }
 
@@ -33845,7 +32762,6 @@ long cdiGribIterator_inqLongDefaultValue(CdiGribIterator *me, const char *key, l
   (void)key;
   (void)defaultValue;
   xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
-  return -4;
 #endif
 }
 
@@ -33873,7 +32789,6 @@ char *cdiGribIterator_inqStringValue(CdiGribIterator *me, const char *key)
   (void)me;
   (void)key;
   xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
-  return NULL;
 #endif
 }
 
@@ -33900,7 +32815,6 @@ int cdiGribIterator_getDouble(CdiGribIterator *me, const char *key, double *resu
   (void)key;
   (void)result;
   xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
-  return -4;
 #endif
 }
 
@@ -33927,7 +32841,6 @@ int cdiGribIterator_getSize(CdiGribIterator *me, const char *key, size_t *result
   (void)key;
   (void)result;
   xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
-  return -4;
 #endif
 }
 
@@ -33955,7 +32868,6 @@ int cdiGribIterator_getLongArray(CdiGribIterator *me, const char *key, long *res
   (void)result;
   (void)size;
   xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
-  return -4;
 #endif
 }
 
@@ -33983,7 +32895,6 @@ int cdiGribIterator_getDoubleArray(CdiGribIterator *me, const char *key, double
   (void)result;
   (void)size;
   xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
-  return -4;
 #endif
 }
 
@@ -34010,7 +32921,6 @@ double cdiGribIterator_inqDoubleValue(CdiGribIterator *me, const char *key)
   (void)me;
   (void)key;
   xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
-  return -4;
 #endif
 }
 
@@ -34039,7 +32949,6 @@ double cdiGribIterator_inqDoubleDefaultValue(CdiGribIterator *me, const char *ke
   (void)key;
   (void)defaultValue;
   xabort("CDI was compiled without GribAPI support, so you can't possibly have a valid CdiGribIterator* to call this function with");
-  return -4;
 #endif
 }
 
@@ -34077,12 +32986,12 @@ void modelDefaultEntries(void);
 #include <limits.h>
 
 
-#undef  CDI_UNDEFID
-#define CDI_UNDEFID -1
+#undef  UNDEFID
+#define UNDEFID -1
 
-static int ECHAM4 = CDI_UNDEFID,
-  ECHAM5 = CDI_UNDEFID,
-  COSMO  = CDI_UNDEFID;
+static int ECHAM4 = UNDEFID,
+  ECHAM5 = UNDEFID,
+  COSMO  = UNDEFID;
 
 typedef struct
 {
@@ -34120,10 +33029,10 @@ static const resOps modelOps = {
 static
 void modelDefaultValue ( model_t *modelptr )
 {
-  modelptr->self        = CDI_UNDEFID;
+  modelptr->self        = UNDEFID;
   modelptr->used        = 0;
-  modelptr->instID      = CDI_UNDEFID;
-  modelptr->modelgribID = CDI_UNDEFID;
+  modelptr->instID      = UNDEFID;
+  modelptr->modelgribID = UNDEFID;
   modelptr->name        = NULL;
 }
 
@@ -34250,7 +33159,7 @@ int modelInq(int instID, int modelgribID, const char *name)
 
   struct modelLoc searchState = { .name = name, .instID = instID,
                                   .modelgribID = modelgribID,
-                                  .resID = CDI_UNDEFID };
+                                  .resID = UNDEFID };
   if (name && *name)
     cdiResHFilterApply(&modelOps, findModelByName, &searchState);
   else
@@ -34277,10 +33186,10 @@ int modelInqInstitut(int modelID)
 
   modelInit ();
 
-  if ( modelID != CDI_UNDEFID )
+  if ( modelID != UNDEFID )
     modelptr = ( model_t * ) reshGetVal ( modelID, &modelOps );
 
-  return modelptr ? modelptr->instID : CDI_UNDEFID;
+  return modelptr ? modelptr->instID : UNDEFID;
 }
 
 
@@ -34290,10 +33199,10 @@ int modelInqGribID(int modelID)
 
   modelInit ();
 
-  if ( modelID != CDI_UNDEFID )
+  if ( modelID != UNDEFID )
     modelptr = ( model_t * ) reshGetVal ( modelID, &modelOps );
 
-  return modelptr ? modelptr->modelgribID : CDI_UNDEFID;
+  return modelptr ? modelptr->modelgribID : UNDEFID;
 }
 
 
@@ -34303,7 +33212,7 @@ const char *modelInqNamePtr(int modelID)
 
   modelInit ();
 
-  if ( modelID != CDI_UNDEFID )
+  if ( modelID != UNDEFID )
     modelptr = ( model_t * ) reshGetVal ( modelID, &modelOps );
 
   return modelptr ? modelptr->name : NULL;
@@ -34362,8 +33271,8 @@ enum {
 static int modelGetSizeP(void * modelptr, void *context)
 {
   model_t *p = (model_t*)modelptr;
-  size_t txsize = (size_t)serializeGetSize(model_nints, CDI_DATATYPE_INT, context)
-    + (size_t)serializeGetSize(p->name?(int)strlen(p->name) + 1:0, CDI_DATATYPE_TXT, context);
+  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;
 }
@@ -34377,9 +33286,9 @@ static void modelPackP(void * modelptr, void * buf, int size, int *position, voi
   tempbuf[1] = p->instID;
   tempbuf[2] = p->modelgribID;
   tempbuf[3] = p->name ? (int)strlen(p->name) + 1 : 0;
-  serializePack(tempbuf, model_nints, CDI_DATATYPE_INT, buf, size, position, context);
+  serializePack(tempbuf, model_nints, DATATYPE_INT, buf, size, position, context);
   if (p->name)
-    serializePack(p->name, tempbuf[3], CDI_DATATYPE_TXT, buf, size, position, context);
+    serializePack(p->name, tempbuf[3], DATATYPE_TXT, buf, size, position, context);
 }
 
 int
@@ -34388,12 +33297,12 @@ modelUnpack(void *buf, int size, int *position, int originNamespace, void *conte
 {
   int tempbuf[model_nints];
   char *name;
-  serializeUnpack(buf, size, position, tempbuf, model_nints, CDI_DATATYPE_INT, context);
+  serializeUnpack(buf, size, position, tempbuf, model_nints, DATATYPE_INT, context);
   if (tempbuf[3] != 0)
     {
       name = (char *) Malloc((size_t)tempbuf[3]);
       serializeUnpack(buf, size, position,
-                      name, tempbuf[3], CDI_DATATYPE_TXT, context);
+                      name, tempbuf[3], DATATYPE_TXT, context);
     }
   else
     {
@@ -35132,15 +34041,17 @@ 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 );
 
   LIST_INIT(1);
 
   LIST_LOCK();
 
-  int nsp = namespaceGetActive ();
+  nsp = namespaceGetActive ();
 
-  namespaceTuple_t nspT = namespaceResHDecode ( resH );
+  nspT = namespaceResHDecode ( resH );
   assert(nspT.idx >= 0);
 
   if (nspT.nsp == nsp &&
@@ -35299,7 +34210,7 @@ static int getPackBufferSize(void *context)
   int nsp = namespaceGetActive ();
 
   /* pack start marker, namespace and sererator marker */
-  packBufferSize += resHPackHeaderNInt * (intpacksize = serializeGetSize(1, CDI_DATATYPE_INT, context));
+  packBufferSize += resHPackHeaderNInt * (intpacksize = serializeGetSize(1, DATATYPE_INT, context));
 
   /* pack resources, type marker and seperator marker */
   listElem_t *r = resHList[nsp].resources;
@@ -35334,35 +34245,9 @@ void reshPackBufferDestroy ( char ** buffer )
 
 /**************************************************************/
 
-int reshGetTxCode(cdiResH resH)
-{
-  int type = 0;
-
-  LIST_LOCK();
-
-  int nsp = namespaceGetActive ();
-
-  namespaceTuple_t nspT = namespaceResHDecode ( resH );
-  assert(nspT.idx >= 0);
-
-  if (nspT.nsp == nsp &&
-      nspT.idx < resHList[nsp].size)
-    {
-      listElem_t *listElem = resHList[nsp].resources + nspT.idx;
-      xassert ( listElem->res.v.ops );
-      type = listElem->res.v.ops->valTxCode();
-    }
-
-  LIST_UNLOCK();
-
-  return type;
-}
-
-/**************************************************************/
-
 int reshPackBufferCreate(char **packBuffer, int *packBufferSize, void *context)
 {
-  int packBufferPos = 0;
+  int i, packBufferPos = 0;
   int end = END;
 
   xassert ( packBuffer );
@@ -35376,18 +34261,18 @@ int reshPackBufferCreate(char **packBuffer, int *packBufferSize, void *context)
 
   {
     int header[resHPackHeaderNInt] = { START, nsp };
-    serializePack(header, resHPackHeaderNInt,  CDI_DATATYPE_INT, pB, pBSize, &packBufferPos, context);
+    serializePack(header, resHPackHeaderNInt,  DATATYPE_INT, pB, pBSize, &packBufferPos, context);
   }
 
   listElem_t *r = resHList[nsp].resources;
-  for ( int i = 0; i < resHList[nsp].size; i++ )
+  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, CDI_DATATYPE_INT,
+            serializePack(temp, resHDeleteNInt, DATATYPE_INT,
                           pB, pBSize, &packBufferPos, context);
           }
         else
@@ -35396,7 +34281,7 @@ int reshPackBufferCreate(char **packBuffer, int *packBufferSize, void *context)
             xassert ( curr->res.v.ops );
             int type = curr->res.v.ops->valTxCode();
             if ( ! type ) continue;
-            serializePack(&type, 1, CDI_DATATYPE_INT, pB,
+            serializePack(&type, 1, DATATYPE_INT, pB,
                           pBSize, &packBufferPos, context);
             curr->res.v.ops->valPack(curr->res.v.val,
                                      pB, pBSize, &packBufferPos, context);
@@ -35406,8 +34291,7 @@ int reshPackBufferCreate(char **packBuffer, int *packBufferSize, void *context)
 
   LIST_UNLOCK();
 
-  serializePack(&end, 1,  CDI_DATATYPE_INT, pB, pBSize, &packBufferPos, context);
-
+  serializePack(&end, 1,  DATATYPE_INT, pB, pBSize, &packBufferPos, context);
   return packBufferPos;
 }
 
@@ -35639,27 +34523,27 @@ serializeGetSizeInCore(int count, int datatype, void *context)
   (void)context;
   switch (datatype)
   {
-  case CDI_DATATYPE_INT8:
+  case DATATYPE_INT8:
     elemSize = sizeof (int8_t);
     break;
-  case CDI_DATATYPE_INT16:
+  case DATATYPE_INT16:
     elemSize = sizeof (int16_t);
     break;
-  case CDI_DATATYPE_UINT32:
+  case DATATYPE_UINT32:
     elemSize = sizeof (uint32_t);
     break;
-  case CDI_DATATYPE_INT:
+  case DATATYPE_INT:
     elemSize = sizeof (int);
     break;
-  case CDI_DATATYPE_FLT:
-  case CDI_DATATYPE_FLT64:
+  case DATATYPE_FLT:
+  case DATATYPE_FLT64:
     elemSize = sizeof (double);
     break;
-  case CDI_DATATYPE_TXT:
-  case CDI_DATATYPE_UCHAR:
+  case DATATYPE_TXT:
+  case DATATYPE_UCHAR:
     elemSize = 1;
     break;
-  case CDI_DATATYPE_LONG:
+  case DATATYPE_LONG:
     elemSize = sizeof (long);
     break;
   default:
@@ -36388,7 +35272,6 @@ void   iegWriteVarSliceDP(stream_t *streamptr, int varID, int levelID, const dou
 #define _XOPEN_SOURCE 600
 #endif
 
-#include <sys/stat.h> // struct stat
 #include <ctype.h>
 
 
@@ -36441,29 +35324,19 @@ int cdiGetFiletype(const char *filename, int *byteorder)
   int swap = 0;
   int version;
   long recpos;
+  char buffer[8];
 
   int fileID = fileOpen(filename, "r");
 
   if ( fileID == CDI_UNDEFID )
     {
       if ( strncmp(filename, "http:", 5) == 0 || strncmp(filename, "https:", 6) == 0 )
-	return CDI_FILETYPE_NC;
+	return FILETYPE_NC;
       else
 	return CDI_ESYSTEM;
     }
 
-  char buffer[8];
-  if ( fileRead(fileID, buffer, 8) != 8 )
-    {
-      struct stat buf;
-      if ( stat(filename, &buf) == 0 )
-        {
-          if ( buf.st_size == 0 ) return CDI_EISEMPTY;
-          if ( buf.st_mode&S_IFDIR ) return CDI_EISDIR;
-        }
-
-      return CDI_EUFTYPE;
-    }
+  if ( fileRead(fileID, buffer, 8) != 8 ) return CDI_EUFTYPE;
 
   fileRewind(fileID);
 
@@ -36472,58 +35345,66 @@ int cdiGetFiletype(const char *filename, int *byteorder)
       version = buffer[7];
       if ( version <= 1 )
 	{
-	  filetype = CDI_FILETYPE_GRB;
+	  filetype = FILETYPE_GRB;
 	  if ( CDI_Debug ) Message("found GRIB file = %s, version %d", filename, version);
 	}
       else if ( version == 2 )
 	{
-	  filetype = CDI_FILETYPE_GRB2;
+	  filetype = FILETYPE_GRB2;
 	  if ( CDI_Debug ) Message("found GRIB2 file = %s", filename);
 	}
     }
   else if ( memcmp(buffer, "CDF\001", 4) == 0 )
     {
-      filetype = CDI_FILETYPE_NC;
+      filetype = FILETYPE_NC;
       if ( CDI_Debug ) Message("found CDF1 file = %s", filename);
     }
   else if ( memcmp(buffer, "CDF\002", 4) == 0 )
     {
-      filetype = CDI_FILETYPE_NC2;
+      filetype = FILETYPE_NC2;
       if ( CDI_Debug ) Message("found CDF2 file = %s", filename);
     }
   else if ( memcmp(buffer+1, "HDF", 3) == 0 )
     {
-      filetype = CDI_FILETYPE_NC4;
+      filetype = FILETYPE_NC4;
       if ( CDI_Debug ) Message("found HDF file = %s", filename);
     }
+#if  defined  (HAVE_LIBSERVICE)
   else if ( srvCheckFiletype(fileID, &swap) )
     {
-      filetype = CDI_FILETYPE_SRV;
+      filetype = FILETYPE_SRV;
       if ( CDI_Debug ) Message("found SRV file = %s", filename);
     }
+#endif
+#if  defined  (HAVE_LIBEXTRA)
   else if ( extCheckFiletype(fileID, &swap) )
     {
-      filetype = CDI_FILETYPE_EXT;
+      filetype = FILETYPE_EXT;
       if ( CDI_Debug ) Message("found EXT file = %s", filename);
     }
+#endif
+#if  defined  (HAVE_LIBIEG)
   else if ( iegCheckFiletype(fileID, &swap) )
     {
-      filetype = CDI_FILETYPE_IEG;
+      filetype = FILETYPE_IEG;
       if ( CDI_Debug ) Message("found IEG file = %s", filename);
     }
+#endif
+#if  defined  (HAVE_LIBCGRIBEX)
   else if ( gribCheckSeek(fileID, &recpos, &version) == 0 )
     {
       if ( version <= 1 )
 	{
-	  filetype = CDI_FILETYPE_GRB;
+	  filetype = FILETYPE_GRB;
 	  if ( CDI_Debug ) Message("found seeked GRIB file = %s", filename);
 	}
       else if ( version == 2 )
 	{
-	  filetype = CDI_FILETYPE_GRB2;
+	  filetype = FILETYPE_GRB2;
 	  if ( CDI_Debug ) Message("found seeked GRIB2 file = %s", filename);
 	}
     }
+#endif
 
   fileClose(fileID);
 
@@ -36546,8 +35427,8 @@ The function @func{streamInqFiletype} returns the filetype of a stream.
 @Result
 @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{CDI_FILETYPE_GRB}, @func{CDI_FILETYPE_GRB2}, @func{CDI_FILETYPE_NC}, @func{CDI_FILETYPE_NC2},
- at func{CDI_FILETYPE_NC4}, @func{CDI_FILETYPE_NC4C}, @func{CDI_FILETYPE_SRV}, @func{CDI_FILETYPE_EXT} and @func{CDI_FILETYPE_IEG}.
+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}.
 
 @EndFunction
 */
@@ -36590,7 +35471,7 @@ int getByteswap(int byteorder)
 
 @Description
 The function @func{streamDefByteorder} defines the byte order of a binary dataset
-with the file format type @func{CDI_FILETYPE_SRV}, @func{CDI_FILETYPE_EXT} or @func{CDI_FILETYPE_IEG}.
+with the file format type @func{FILETYPE_SRV}, @func{FILETYPE_EXT} or @func{FILETYPE_IEG}.
 
 @EndFunction
 */
@@ -36603,7 +35484,7 @@ void streamDefByteorder(int streamID, int byteorder)
   switch (filetype)
     {
 #if  defined  (HAVE_LIBSERVICE)
-    case CDI_FILETYPE_SRV:
+    case FILETYPE_SRV:
       {
 	srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
 	srvp->byteswap = getByteswap(byteorder);
@@ -36612,7 +35493,7 @@ void streamDefByteorder(int streamID, int byteorder)
       }
 #endif
 #if  defined  (HAVE_LIBEXTRA)
-    case CDI_FILETYPE_EXT:
+    case FILETYPE_EXT:
       {
 	extrec_t *extp = (extrec_t*) streamptr->record->exsep;
 	extp->byteswap = getByteswap(byteorder);
@@ -36621,7 +35502,7 @@ void streamDefByteorder(int streamID, int byteorder)
       }
 #endif
 #if  defined  (HAVE_LIBIEG)
-    case CDI_FILETYPE_IEG:
+    case FILETYPE_IEG:
       {
 	iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
 	iegp->byteswap = getByteswap(byteorder);
@@ -36643,7 +35524,7 @@ void streamDefByteorder(int streamID, int byteorder)
 
 @Description
 The function @func{streamInqByteorder} returns the byte order of a binary dataset
-with the file format type @func{CDI_FILETYPE_SRV}, @func{CDI_FILETYPE_EXT} or @func{CDI_FILETYPE_IEG}.
+with the file format type @func{FILETYPE_SRV}, @func{FILETYPE_EXT} or @func{FILETYPE_IEG}.
 
 @Result
 @func{streamInqByteorder} returns the type of the byte order.
@@ -36695,47 +35576,48 @@ long cdiInqTimeSize(int streamID)
 }
 
 static
-int cdiInqContents(stream_t *streamptr)
+int cdiInqContents(stream_t * streamptr)
 {
   int status = 0;
+
   int filetype = streamptr->filetype;
 
   switch (filetype)
     {
 #if  defined  (HAVE_LIBGRIB)
-    case CDI_FILETYPE_GRB:
-    case CDI_FILETYPE_GRB2:
+    case FILETYPE_GRB:
+    case FILETYPE_GRB2:
       {
         status = grbInqContents(streamptr);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBSERVICE)
-    case CDI_FILETYPE_SRV:
+    case FILETYPE_SRV:
       {
         status = srvInqContents(streamptr);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBEXTRA)
-    case CDI_FILETYPE_EXT:
+    case FILETYPE_EXT:
       {
         status = extInqContents(streamptr);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBIEG)
-    case CDI_FILETYPE_IEG:
+    case FILETYPE_IEG:
       {
         status = iegInqContents(streamptr);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBNETCDF)
-    case CDI_FILETYPE_NC:
-    case CDI_FILETYPE_NC2:
-    case CDI_FILETYPE_NC4:
-    case CDI_FILETYPE_NC4C:
+    case FILETYPE_NC:
+    case FILETYPE_NC2:
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
       {
         status = cdfInqContents(streamptr);
 	break;
@@ -36774,10 +35656,8 @@ int cdiStreamOpenDefaultDelegate(const char *filename, char filemode,
   switch (filetype)
     {
 #if  defined  (HAVE_LIBGRIB)
-    case CDI_FILETYPE_GRB:
-#if  defined  (HAVE_LIBGRIB_API)
-    case CDI_FILETYPE_GRB2:
-#endif
+    case FILETYPE_GRB:
+    case FILETYPE_GRB2:
       {
 #ifndef __cplusplus
         fileID = gribOpen(filename, (char [2]){filemode, 0});
@@ -36795,7 +35675,7 @@ int cdiStreamOpenDefaultDelegate(const char *filename, char filemode,
       }
 #endif
 #if  defined  (HAVE_LIBSERVICE)
-    case CDI_FILETYPE_SRV:
+    case FILETYPE_SRV:
       {
 #ifndef __cplusplus
         fileID = fileOpen(filename, (char [2]){filemode, 0});
@@ -36814,7 +35694,7 @@ int cdiStreamOpenDefaultDelegate(const char *filename, char filemode,
       }
 #endif
 #if  defined  (HAVE_LIBEXTRA)
-    case CDI_FILETYPE_EXT:
+    case FILETYPE_EXT:
       {
 #ifndef __cplusplus
         fileID = fileOpen(filename, (char [2]){filemode, 0});
@@ -36834,7 +35714,7 @@ int cdiStreamOpenDefaultDelegate(const char *filename, char filemode,
       }
 #endif
 #if  defined  (HAVE_LIBIEG)
-    case CDI_FILETYPE_IEG:
+    case FILETYPE_IEG:
       {
 #ifndef __cplusplus
         fileID = fileOpen(filename, (char [2]){filemode, 0});
@@ -36847,13 +35727,13 @@ int cdiStreamOpenDefaultDelegate(const char *filename, char filemode,
           {
             streamptr->record = (Record *) Malloc(sizeof(Record));
             streamptr->record->buffer = NULL;
-            streamptr->record->exsep  = iegNew();
+            streamptr->record->exsep   = iegNew();
           }
         break;
       }
 #endif
 #if  defined  (HAVE_LIBNETCDF)
-    case CDI_FILETYPE_NC:
+    case FILETYPE_NC:
       {
 #ifndef __cplusplus
         fileID = cdfOpen(filename, (char [2]){filemode, 0});
@@ -36863,7 +35743,7 @@ int cdiStreamOpenDefaultDelegate(const char *filename, char filemode,
 #endif
         break;
       }
-    case CDI_FILETYPE_NC2:
+    case FILETYPE_NC2:
       {
 #ifndef __cplusplus
         fileID = cdfOpen64(filename, (char [2]){filemode, 0});
@@ -36873,8 +35753,8 @@ int cdiStreamOpenDefaultDelegate(const char *filename, char filemode,
 #endif
         break;
       }
-    case CDI_FILETYPE_NC4:
-    case CDI_FILETYPE_NC4C:
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
       {
 #ifndef __cplusplus
         fileID = cdf4Open(filename, (char [2]){filemode, 0}, &filetype);
@@ -36959,25 +35839,27 @@ int streamOpenID(const char *filename, char filemode, int filetype, int resH)
   return streamID;
 }
 
-static
-int streamOpen(const char *filename, const char *filemode, int filetype)
+static int streamOpen(const char *filename, const char *filemode, int filetype)
 {
-  if ( !filemode || strlen(filemode) != 1 ) return CDI_EINVAL;
-  return streamOpenID(filename, (char)tolower(filemode[0]), filetype, CDI_UNDEFID);
+  if (!filemode || strlen(filemode) != 1) return CDI_EINVAL;
+  return streamOpenID(filename, (char)tolower(filemode[0]),
+                      filetype, CDI_UNDEFID);
 }
 
-static
-int streamOpenA(const char *filename, const char *filemode, int filetype)
+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 ( 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;
 
-  stream_t *streamptr = stream_new_entry(CDI_UNDEFID);
-  int fileID = CDI_UNDEFID;
-
   {
     int (*streamOpenDelegate)(const char *filename, char filemode,
                               int filetype, stream_t *streamptr, int recordBufIsToBeCreated)
@@ -36989,7 +35871,7 @@ int streamOpenA(const char *filename, const char *filemode, int filetype)
 
   if ( fileID == CDI_UNDEFID || fileID == CDI_ELIBNAVAIL || fileID == CDI_ESYSTEM ) return fileID;
 
-  int streamID = streamptr->self;
+  streamID = streamptr->self;
 
   streamptr->filemode = tolower(*filemode);
   streamptr->filename = strdupx(filename);
@@ -36998,16 +35880,11 @@ int streamOpenA(const char *filename, const char *filemode, int filetype)
   streamptr->vlistID = vlistCreate();
   cdiVlistMakeInternal(streamptr->vlistID);
   /* cdiReadByteorder(streamID); */
-  int status = cdiInqContents(streamptr);
+  status = cdiInqContents(streamptr);
   if ( status < 0 ) return status;
-  vlist_t *vlistptr = vlist_to_pointer(streamptr->vlistID);
+  vlistptr = vlist_to_pointer(streamptr->vlistID);
   vlistptr->ntsteps = (int)cdiInqTimeSize(streamID);
-
-  // Needed for NetCDF4
-  for ( int varID = 0; varID < vlistptr->nvars; ++varID )
-    streamptr->vars[varID].defmiss = true;
-
-  if ( !strcmp(filemode, "r") ) cdiVlistMakeImmutable(streamptr->vlistID);
+  if(!strcmp(filemode, "r")) cdiVlistMakeImmutable(streamptr->vlistID);
 
   {
     void (*streamCloseDelegate)(stream_t *streamptr, int recordBufIsToBeDeleted)
@@ -37020,52 +35897,49 @@ int streamOpenA(const char *filename, const char *filemode, int filetype)
   switch (filetype)
     {
 #if  defined  (HAVE_LIBGRIB)
-    case CDI_FILETYPE_GRB:
-#if  defined  (HAVE_LIBGRIB_API)
-    case CDI_FILETYPE_GRB2:
-#endif
+    case FILETYPE_GRB:
+    case FILETYPE_GRB2:
       {
         fileID = gribOpen(filename, filemode);
-        if ( fileID != CDI_UNDEFID ) gribContainersNew(streamptr);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBSERVICE)
-    case CDI_FILETYPE_SRV:
+    case FILETYPE_SRV:
       {
         fileID = fileOpen(filename, filemode);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBEXTRA)
-    case CDI_FILETYPE_EXT:
+    case FILETYPE_EXT:
       {
         fileID = fileOpen(filename, filemode);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBIEG)
-    case CDI_FILETYPE_IEG:
+    case FILETYPE_IEG:
       {
         fileID = fileOpen(filename, filemode);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBNETCDF)
-    case CDI_FILETYPE_NC:
+    case FILETYPE_NC:
       {
 	fileID = cdfOpen(filename, filemode);
 	streamptr->ncmode = 2;
 	break;
       }
-    case CDI_FILETYPE_NC2:
+    case FILETYPE_NC2:
       {
 	fileID = cdfOpen64(filename, filemode);
 	streamptr->ncmode = 2;
 	break;
       }
-    case CDI_FILETYPE_NC4:
-    case CDI_FILETYPE_NC4C:
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
       {
 	fileID = cdf4Open(filename, filemode, &filetype);
 	streamptr->ncmode = 2;
@@ -37173,9 +36047,9 @@ int streamOpenAppend(const char *filename)
 @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{CDI_FILETYPE_GRB}, @func{CDI_FILETYPE_GRB2}, @func{CDI_FILETYPE_NC},
-                     @func{CDI_FILETYPE_NC2}, @func{CDI_FILETYPE_NC4}, @func{CDI_FILETYPE_NC4C}, @func{CDI_FILETYPE_SRV},
-                     @func{CDI_FILETYPE_EXT} and @func{CDI_FILETYPE_IEG}.
+                     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}.
 
 @Description
 The function @func{streamOpenWrite} creates a new datset.
@@ -37198,7 +36072,7 @@ Here is an example using @func{streamOpenWrite} to create a new NetCDF file name
    ...
 int streamID;
    ...
-streamID = streamOpenWrite("foo.nc", CDI_FILETYPE_NC);
+streamID = streamOpenWrite("foo.nc", FILETYPE_NC);
 if ( streamID < 0 ) handle_error(streamID);
    ...
 @EndSource
@@ -37217,7 +36091,7 @@ void streamDefaultValue ( stream_t * streamptr )
   streamptr->self              = CDI_UNDEFID;
   streamptr->accesstype        = CDI_UNDEFID;
   streamptr->accessmode        = 0;
-  streamptr->filetype          = CDI_FILETYPE_UNDEF;
+  streamptr->filetype          = FILETYPE_UNDEF;
   streamptr->byteorder         = CDI_UNDEFID;
   streamptr->fileID            = 0;
   streamptr->filemode          = 0;
@@ -37239,43 +36113,39 @@ void streamDefaultValue ( stream_t * streamptr )
   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 > 0;
-  streamptr->sortparam         = cdiSortParam > 0;
+  streamptr->sortname          = cdiSortName;
   streamptr->have_missval      = cdiHaveMissval;
-  streamptr->comptype          = CDI_COMPRESS_NONE;
+  streamptr->comptype          = COMPRESS_NONE;
   streamptr->complevel         = 0;
 
   basetimeInit(&streamptr->basetime);
 
-#ifdef HAVE_LIBNETCDF
-  for ( int i = 0; i < MAX_ZAXES_PS; i++ ) streamptr->zaxisID[i]  = CDI_UNDEFID;
-  for ( int i = 0; i < MAX_ZAXES_PS; i++ ) streamptr->nczvarID[i] = CDI_UNDEFID;
-
-  for ( int i = 0; i < MAX_GRIDS_PS; i++ )
-    {
-      streamptr->ncgrid[i].gridID = CDI_UNDEFID;
-      for (size_t j = 0; j < CDF_SIZE_ncIDs; ++j)
-        streamptr->ncgrid[i].ncIDs[j] = CDI_UNDEFID;
-    }
-
-  streamptr->vct.ilev          = 0;
-  streamptr->vct.mlev          = 0;
-  streamptr->vct.ilevID        = CDI_UNDEFID;
-  streamptr->vct.mlevID        = CDI_UNDEFID;
-#endif
+  int i;
+  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_ZAXES_PS; i++ ) streamptr->nczvarID[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;
 }
 
-static
-stream_t *stream_new_entry(int resH)
+
+static stream_t *stream_new_entry(int resH)
 {
+  stream_t *streamptr;
+
   cdiInitialize(); /* ***************** make MT version !!! */
 
-  stream_t *streamptr = (stream_t *) Malloc(sizeof(stream_t));
+  streamptr = (stream_t *) Malloc(sizeof(stream_t));
   streamDefaultValue ( streamptr );
-
   if (resH == CDI_UNDEFID)
     streamptr->self = reshPut(streamptr, &streamOps);
   else
@@ -37288,7 +36158,8 @@ stream_t *stream_new_entry(int resH)
 }
 
 
-void cdiStreamCloseDefaultDelegate(stream_t *streamptr, int recordBufIsToBeDeleted)
+void
+cdiStreamCloseDefaultDelegate(stream_t *streamptr, int recordBufIsToBeDeleted)
 {
   int fileID   = streamptr->fileID;
   int filetype = streamptr->filetype;
@@ -37298,50 +36169,49 @@ void cdiStreamCloseDefaultDelegate(stream_t *streamptr, int recordBufIsToBeDelet
     switch (filetype)
       {
 #if  defined  (HAVE_LIBGRIB)
-      case CDI_FILETYPE_GRB:
-      case CDI_FILETYPE_GRB2:
+      case FILETYPE_GRB:
+      case FILETYPE_GRB2:
         {
           gribClose(fileID);
-          if ( recordBufIsToBeDeleted ) gribContainersDelete(streamptr);
+          if (recordBufIsToBeDeleted)
+            gribContainersDelete(streamptr);
           break;
         }
 #endif
 #if  defined  (HAVE_LIBSERVICE)
-      case CDI_FILETYPE_SRV:
+      case FILETYPE_SRV:
         {
           fileClose(fileID);
-          if ( recordBufIsToBeDeleted ) srvDelete(streamptr->record->exsep);
+          if (recordBufIsToBeDeleted)
+            srvDelete(streamptr->record->exsep);
           break;
         }
 #endif
 #if  defined  (HAVE_LIBEXTRA)
-      case CDI_FILETYPE_EXT:
+      case FILETYPE_EXT:
         {
           fileClose(fileID);
-          if ( recordBufIsToBeDeleted ) extDelete(streamptr->record->exsep);
+          if (recordBufIsToBeDeleted)
+            extDelete(streamptr->record->exsep);
           break;
         }
 #endif
 #if  defined  (HAVE_LIBIEG)
-      case CDI_FILETYPE_IEG:
+      case FILETYPE_IEG:
         {
           fileClose(fileID);
-          if ( recordBufIsToBeDeleted ) iegDelete(streamptr->record->exsep);
+          if (recordBufIsToBeDeleted)
+            iegDelete(streamptr->record->exsep);
           break;
         }
 #endif
 #if  defined  (HAVE_LIBNETCDF)
-      case CDI_FILETYPE_NC:
-      case CDI_FILETYPE_NC2:
-      case CDI_FILETYPE_NC4:
-      case CDI_FILETYPE_NC4C:
+      case FILETYPE_NC:
+      case FILETYPE_NC2:
+      case FILETYPE_NC4:
+      case FILETYPE_NC4C:
         {
           cdfClose(fileID);
-          if (streamptr->ntsteps == 0)
-            {
-              Free(streamptr->tsteps[0].records);
-              Free(streamptr->tsteps[0].recIDs);
-            }
           break;
         }
 #endif
@@ -37354,8 +36224,7 @@ void cdiStreamCloseDefaultDelegate(stream_t *streamptr, int recordBufIsToBeDelet
 }
 
 
-static
-void deallocate_sleveltable_t(sleveltable_t *entry)
+static void deallocate_sleveltable_t(sleveltable_t *entry)
 {
   if (entry->recordID) Free(entry->recordID);
   if (entry->lindex)   Free(entry->lindex);
@@ -37379,6 +36248,7 @@ The function @func{streamClose} closes an open dataset.
 */
 void streamClose(int streamID)
 {
+  int index;
   stream_t *streamptr = stream_to_pointer(streamID);
 
   if ( CDI_Debug )
@@ -37403,7 +36273,7 @@ void streamClose(int streamID)
   streamptr->filetype = 0;
   if ( streamptr->filename ) Free(streamptr->filename);
 
-  for ( int index = 0; index < streamptr->nvars; index++ )
+  for ( index = 0; index < streamptr->nvars; index++ )
     {
       sleveltable_t *pslev = streamptr->vars[index].recordTable;
       unsigned nsub = streamptr->vars[index].subtypeSize >= 0
@@ -37417,10 +36287,12 @@ void streamClose(int streamID)
   Free(streamptr->vars);
   streamptr->vars = NULL;
 
-  for ( int index = 0; index < streamptr->ntsteps; ++index )
+  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);
+      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);
     }
 
@@ -37430,8 +36302,11 @@ void streamClose(int streamID)
 
   if ( vlistID != -1 )
     {
-      if ( streamptr->filemode != 'w' && vlistInqTaxis(vlistID) != -1 )
-        taxisDestroy(vlistInqTaxis(vlistID));
+      if ( streamptr->filemode != 'w' )
+	if ( vlistInqTaxis(vlistID) != -1 )
+	  {
+	    taxisDestroy(vlistInqTaxis(vlistID));
+	  }
 
       cdiVlistDestroy_(vlistID);
     }
@@ -37439,13 +36314,14 @@ void streamClose(int streamID)
   stream_delete_entry(streamptr);
 }
 
-static
-void stream_delete_entry(stream_t *streamptr)
+static void stream_delete_entry(stream_t *streamptr)
 {
+  int idx;
+
   xassert ( streamptr );
 
-  int idx = streamptr->self;
-  Free(streamptr);
+  idx = streamptr->self;
+  Free( streamptr );
   reshRemove ( idx, &streamOps );
 
   if ( CDI_Debug )
@@ -37460,9 +36336,12 @@ void cdiStreamSync_(stream_t *streamptr)
   int vlistID  = streamptr->vlistID;
   int nvars    = vlistNvars(vlistID);
 
-  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!");
+  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' )
@@ -37470,10 +36349,10 @@ void cdiStreamSync_(stream_t *streamptr)
 	  switch (filetype)
 	    {
 #if  defined  (HAVE_LIBNETCDF)
-	    case CDI_FILETYPE_NC:
-	    case CDI_FILETYPE_NC2:
-	    case CDI_FILETYPE_NC4:
-	    case CDI_FILETYPE_NC4C:
+	    case FILETYPE_NC:
+	    case FILETYPE_NC2:
+	    case FILETYPE_NC4:
+	    case FILETYPE_NC4C:
 	      {
 		void cdf_sync(int ncid);
 		if ( streamptr->ncmode == 2 ) cdf_sync(fileID);
@@ -37519,7 +36398,8 @@ int cdiStreamDefTimestep_(stream_t *streamptr, int tsID)
 
   stream_check_ptr(__func__, streamptr);
 
-  if ( CDI_Debug ) Message("streamID = %d  tsID = %d", streamptr->self, tsID);
+  if ( CDI_Debug )
+    Message("streamID = %d  tsID = %d", streamptr->self, tsID);
 
   int vlistID = streamptr->vlistID;
 
@@ -37553,10 +36433,10 @@ int cdiStreamDefTimestep_(stream_t *streamptr, int tsID)
   streamptr->ntsteps = tsID + 1;
 
 #ifdef HAVE_LIBNETCDF
-  if ((streamptr->filetype == CDI_FILETYPE_NC  ||
-       streamptr->filetype == CDI_FILETYPE_NC2 ||
-       streamptr->filetype == CDI_FILETYPE_NC4 ||
-       streamptr->filetype == CDI_FILETYPE_NC4C)
+  if ((streamptr->filetype == FILETYPE_NC  ||
+       streamptr->filetype == FILETYPE_NC2 ||
+       streamptr->filetype == FILETYPE_NC4 ||
+       streamptr->filetype == FILETYPE_NC4C)
       && time_is_varying)
     {
       void (*myCdfDefTimestep)(stream_t *streamptr, int tsID)
@@ -37597,13 +36477,13 @@ int streamDefTimestep(int streamID, int tsID)
   return myStreamDefTimestep_(streamptr, tsID);
 }
 
-
 int streamInqCurTimestepID(int streamID)
 {
   stream_t *streamptr = stream_to_pointer(streamID);
   return streamptr->curTsID;
 }
 
+
 /*
 @Function  streamInqTimestep
 @Title     Get time step
@@ -37654,39 +36534,39 @@ int streamInqTimestep(int streamID, int tsID)
   switch (filetype)
     {
 #if  defined  (HAVE_LIBGRIB)
-    case CDI_FILETYPE_GRB:
-    case CDI_FILETYPE_GRB2:
+    case FILETYPE_GRB:
+    case FILETYPE_GRB2:
       {
         nrecs = grbInqTimestep(streamptr, tsID);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBSERVICE)
-    case CDI_FILETYPE_SRV:
+    case FILETYPE_SRV:
       {
         nrecs = srvInqTimestep(streamptr, tsID);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBEXTRA)
-    case CDI_FILETYPE_EXT:
+    case FILETYPE_EXT:
       {
         nrecs = extInqTimestep(streamptr, tsID);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBIEG)
-    case CDI_FILETYPE_IEG:
+    case FILETYPE_IEG:
       {
         nrecs = iegInqTimestep(streamptr, tsID);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBNETCDF)
-    case CDI_FILETYPE_NC:
-    case CDI_FILETYPE_NC2:
-    case CDI_FILETYPE_NC4:
-    case CDI_FILETYPE_NC4C:
+    case FILETYPE_NC:
+    case FILETYPE_NC2:
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
       {
         nrecs = cdfInqTimestep(streamptr, tsID);
 	break;
@@ -37719,14 +36599,15 @@ void streamWriteContents(int streamID, char *cname)
 
   if ( cnp == NULL ) SysError(cname);
 
-  fprintf(cnp, "#CDI library version %s\n"
-          "#\n", cdiLibraryVersion());
+  fprintf(cnp, "#CDI library version %s\n", cdiLibraryVersion());
+  fprintf(cnp, "#\n");
 
+  fprintf(cnp, "filename: %s\n", streamptr->filename);
   int filetype = streamptr->filetype;
-  fprintf(cnp, "filename: %s\n"
-          "filetype: %s\n", streamptr->filename, strfiletype(filetype));
+  fprintf(cnp, "filetype: %s\n", strfiletype(filetype));
 
-  fputs("#\n#grids:\n", cnp);
+  fprintf(cnp, "#\n");
+  fprintf(cnp, "#grids:\n");
 
   int ngrids = vlistNgrids(vlistID);
   for ( int i = 0; i < ngrids; i++ )
@@ -37738,7 +36619,9 @@ void streamWriteContents(int streamID, char *cname)
       fprintf(cnp, "%4d:%4d:%4d:%4d\n", i+1, gridtype, xsize, ysize);
     }
 
-  fputs("#\nvarID:code:gridID:zaxisID:tsteptype:datatype\n", cnp);
+  fprintf(cnp, "#\n");
+
+  fprintf(cnp, "varID:code:gridID:zaxisID:tsteptype:datatype\n");
 
   int nvars = vlistNvars(vlistID);
   for ( int varID = 0; varID < nvars; varID++ )
@@ -37752,7 +36635,9 @@ void streamWriteContents(int streamID, char *cname)
 	      varID+1, code, gridID, zaxisID, tsteptype, datatype);
     }
 
-  fputs("#\ntsID:nrecs:date:time\n", cnp);
+  fprintf(cnp, "#\n");
+
+  fprintf(cnp, "tsID:nrecs:date:time\n");
 
   int tsID = 0;
   while (1)
@@ -37771,7 +36656,9 @@ void streamWriteContents(int streamID, char *cname)
 	break;
     }
 
-  fputs("#\ntsID:recID:varID:levID:size:pos\n", cnp);
+  fprintf(cnp, "#\n");
+
+  fprintf(cnp, "tsID:recID:varID:levID:size:pos\n");
 
   tsID = 0;
   while (1)
@@ -37801,6 +36688,7 @@ void streamWriteContents(int streamID, char *cname)
 off_t streamNvals(int streamID)
 {
   stream_t *streamptr = stream_to_pointer(streamID);
+
   return streamptr->numvals;
 }
 
@@ -37830,7 +36718,8 @@ void streamDefVlist(int streamID, int vlistID)
 }
 
 /* the single image implementation of streamDefVlist */
-void cdiStreamDefVlist_(int streamID, int vlistID)
+void
+cdiStreamDefVlist_(int streamID, int vlistID)
 {
   stream_t *streamptr = stream_to_pointer(streamID);
 
@@ -37936,49 +36825,50 @@ int streamTxCode(void)
   return STREAM;
 }
 
-void cdiStreamSetupVlist(stream_t *streamptr, int vlistID)
+void
+cdiStreamSetupVlist(stream_t *streamptr, int vlistID)
 {
   void (*myStreamSetupVlist)(stream_t *streamptr, int vlistID)
-    = (void (*)(stream_t *, int)) namespaceSwitchGet(NSSWITCH_STREAM_SETUP_VLIST).func;
+    = (void (*)(stream_t *, int))
+    namespaceSwitchGet(NSSWITCH_STREAM_SETUP_VLIST).func;
   myStreamSetupVlist(streamptr, vlistID);
 }
 
-
-void cdiStreamSetupVlist_(stream_t *streamptr, int vlistID)
+void
+cdiStreamSetupVlist_(stream_t *streamptr, int vlistID)
 {
-  streamptr->vlistID = vlistID;
   int nvars = vlistNvars(vlistID);
-  for ( int varID = 0; varID < nvars; varID++ )
+  streamptr->vlistID = vlistID;
+  for (int varID = 0; varID < nvars; varID++ )
     {
       int gridID    = vlistInqVarGrid(vlistID, varID);
       int zaxisID   = vlistInqVarZaxis(vlistID, varID);
       int tilesetID = vlistInqVarSubtype(vlistID, varID);
       stream_new_var(streamptr, gridID, zaxisID, tilesetID);
       if ( streamptr->have_missval )
-        vlistDefVarMissval(vlistID, varID, vlistInqVarMissval(vlistID, varID));
+        vlistDefVarMissval(vlistID, varID,
+                           vlistInqVarMissval(vlistID, varID));
     }
 
   if (streamptr->filemode == 'w')
     switch (streamptr->filetype)
       {
 #ifdef HAVE_LIBNETCDF
-      case CDI_FILETYPE_NC:
-      case CDI_FILETYPE_NC2:
-      case CDI_FILETYPE_NC4:
-      case CDI_FILETYPE_NC4C:
+      case FILETYPE_NC:
+      case FILETYPE_NC2:
+      case FILETYPE_NC4:
+      case FILETYPE_NC4C:
         {
-          /* calls cdfDefVars in serial mode but
-           * cdiPioClientStreamNOP (i.e. nothing) on client ranks
-           * and cdiPioServerCdfDefVars on server ranks in parallel mode*/
           void (*myCdfDefVars)(stream_t *streamptr)
-            = (void (*)(stream_t *)) namespaceSwitchGet(NSSWITCH_CDF_STREAM_SETUP).func;
+            = (void (*)(stream_t *))
+            namespaceSwitchGet(NSSWITCH_CDF_STREAM_SETUP).func;
           myCdfDefVars(streamptr);
         }
         break;
 #endif
 #ifdef HAVE_LIBGRIB
-      case CDI_FILETYPE_GRB:
-      case CDI_FILETYPE_GRB2:
+      case FILETYPE_GRB:
+      case FILETYPE_GRB2:
         gribContainersNew(streamptr);
         break;
 #endif
@@ -38031,7 +36921,7 @@ static int streamCompareP(void * streamptr1, void * streamptr2)
 
 void streamDestroyP ( void * streamptr )
 {
-  stream_t *sp = ( stream_t * ) streamptr;
+  stream_t * sp = ( stream_t * ) streamptr;
 
   xassert ( sp );
 
@@ -38093,11 +36983,11 @@ streamGetPackSize(void * voidP, void *context)
 {
   stream_t * streamP = ( stream_t * ) voidP;
   int packBufferSize
-    = serializeGetSize(streamNint, CDI_DATATYPE_INT, context)
-    + serializeGetSize(2, CDI_DATATYPE_UINT32, context)
+    = serializeGetSize(streamNint, DATATYPE_INT, context)
+    + serializeGetSize(2, DATATYPE_UINT32, context)
     + serializeGetSize((int)strlen(streamP->filename) + 1,
-                       CDI_DATATYPE_TXT, context)
-    + serializeGetSize(1, CDI_DATATYPE_FLT64, context);
+                       DATATYPE_TXT, context)
+    + serializeGetSize(1, DATATYPE_FLT64, context);
   return packBufferSize;
 }
 
@@ -38120,14 +37010,14 @@ streamPack(void * streamptr, void * packBuffer, int packBufferSize,
   intBuffer[8] = streamP->sortname;
   intBuffer[9] = streamP->have_missval;
 
-  serializePack(intBuffer, streamNint, CDI_DATATYPE_INT, packBuffer, packBufferSize, packBufferPos, context);
-  uint32_t d = cdiCheckSum(CDI_DATATYPE_INT, streamNint, intBuffer);
-  serializePack(&d, 1, CDI_DATATYPE_UINT32, packBuffer, packBufferSize, packBufferPos, context);
+  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);
 
-  serializePack(&cdiDefaultMissval, 1, CDI_DATATYPE_FLT64, packBuffer, packBufferSize, packBufferPos, context);
-  serializePack(streamP->filename, intBuffer[2], CDI_DATATYPE_TXT, packBuffer, packBufferSize, packBufferPos, context);
-  d = cdiCheckSum(CDI_DATATYPE_TXT, intBuffer[2], streamP->filename);
-  serializePack(&d, 1, CDI_DATATYPE_UINT32, packBuffer, packBufferSize, packBufferPos, context);
+  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);
 }
 
 struct streamAssoc
@@ -38139,18 +37029,18 @@ streamUnpack(char * unpackBuffer, int unpackBufferSize,
   char filename[CDI_MAX_NAME];
 
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  intBuffer, streamNint, CDI_DATATYPE_INT, context);
+                  intBuffer, streamNint, DATATYPE_INT, context);
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  &d, 1, CDI_DATATYPE_UINT32, context);
-  xassert(cdiCheckSum(CDI_DATATYPE_INT, streamNint, intBuffer) == d);
+                  &d, 1, DATATYPE_UINT32, context);
+  xassert(cdiCheckSum(DATATYPE_INT, streamNint, intBuffer) == d);
 
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  &cdiDefaultMissval, 1, CDI_DATATYPE_FLT64, context);
+                  &cdiDefaultMissval, 1, DATATYPE_FLT64, context);
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  &filename, intBuffer[2], CDI_DATATYPE_TXT, context);
+                  &filename, intBuffer[2], DATATYPE_TXT, context);
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  &d, 1, CDI_DATATYPE_UINT32, context);
-  xassert(d == cdiCheckSum(CDI_DATATYPE_TXT, intBuffer[2], filename));
+                  &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);
@@ -38202,15 +37092,15 @@ int cdiStreamWriteVar_(int streamID, int varID, int memtype, const void *data, i
   switch (filetype)
     {
 #if  defined  (HAVE_LIBGRIB)
-    case CDI_FILETYPE_GRB:
-    case CDI_FILETYPE_GRB2:
+    case FILETYPE_GRB:
+    case FILETYPE_GRB2:
       {
         grb_write_var(streamptr, varID, memtype, data, nmiss);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBSERVICE)
-    case CDI_FILETYPE_SRV:
+    case FILETYPE_SRV:
       {
         if ( memtype == MEMTYPE_FLOAT ) return 1;
         srvWriteVarDP(streamptr, varID, (double *)data);
@@ -38218,7 +37108,7 @@ int cdiStreamWriteVar_(int streamID, int varID, int memtype, const void *data, i
       }
 #endif
 #if  defined  (HAVE_LIBEXTRA)
-    case CDI_FILETYPE_EXT:
+    case FILETYPE_EXT:
       {
         if ( memtype == MEMTYPE_FLOAT ) return 1;
         extWriteVarDP(streamptr, varID, (double *)data);
@@ -38226,7 +37116,7 @@ int cdiStreamWriteVar_(int streamID, int varID, int memtype, const void *data, i
       }
 #endif
 #if  defined  (HAVE_LIBIEG)
-    case CDI_FILETYPE_IEG:
+    case FILETYPE_IEG:
       {
         if ( memtype == MEMTYPE_FLOAT ) return 1;
         iegWriteVarDP(streamptr, varID, (double *)data);
@@ -38234,10 +37124,10 @@ int cdiStreamWriteVar_(int streamID, int varID, int memtype, const void *data, i
       }
 #endif
 #if  defined  (HAVE_LIBNETCDF)
-    case CDI_FILETYPE_NC:
-    case CDI_FILETYPE_NC2:
-    case CDI_FILETYPE_NC4:
-    case CDI_FILETYPE_NC4C:
+    case FILETYPE_NC:
+    case FILETYPE_NC2:
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
       {
         cdf_write_var(streamptr, varID, memtype, data, nmiss);
 	break;
@@ -38271,7 +37161,8 @@ The values are converted to the external data type of the variable, if necessary
 */
 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 (*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;
 
@@ -38296,18 +37187,17 @@ The values are converted to the external data type of the variable, if necessary
 */
 void streamWriteVarF(int streamID, int varID, const float *data, int nmiss)
 {
-  int (*myCdiStreamWriteVar_)(int streamID, int varID, int memtype, const void *data, int nmiss)
+  int (*myCdiStreamWriteVar_)(int streamID, int varID, int memtype,
+                              const void *data, int nmiss)
     = (int (*)(int, int, int, const void *, int))
     namespaceSwitchGet(NSSWITCH_STREAM_WRITE_VAR_).func;
-
+  
   if ( myCdiStreamWriteVar_(streamID, varID, MEMTYPE_FLOAT, (const void *) data, nmiss) )
     {
       // In case the file format does not support single precision writing,
-      // we fall back to double precision writing, converting the data
-      // on the fly.
-      int vlistID = streamInqVlist(streamID);
-      size_t elementCount = (size_t) gridInqSize(vlistInqVarGrid(vlistID, varID));
-      elementCount *= (size_t) zaxisInqSize(vlistInqVarZaxis(vlistID, varID));
+      // we fall back to double precision writing, converting the data on the fly.
+      size_t elementCount = (size_t) gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
+      elementCount *= (size_t) zaxisInqSize(vlistInqVarZaxis(streamInqVlist(streamID), varID));
       double *conversionBuffer = (double *) Malloc(elementCount*sizeof(*conversionBuffer));
       for ( size_t i = elementCount; i--; ) conversionBuffer[i] = (double) data[i];
       myCdiStreamWriteVar_(streamID, varID, MEMTYPE_DOUBLE, (const void *) conversionBuffer, nmiss);
@@ -38338,15 +37228,15 @@ int cdiStreamWriteVarSlice(int streamID, int varID, int levelID, int memtype, co
   switch (filetype)
     {
 #if  defined  (HAVE_LIBGRIB)
-    case CDI_FILETYPE_GRB:
-    case CDI_FILETYPE_GRB2:
+    case FILETYPE_GRB:
+    case FILETYPE_GRB2:
       {
         grb_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBSERVICE)
-    case CDI_FILETYPE_SRV:
+    case FILETYPE_SRV:
       {
         if ( memtype == MEMTYPE_FLOAT ) return 1;
         srvWriteVarSliceDP(streamptr, varID, levelID, (double *)data);
@@ -38354,7 +37244,7 @@ int cdiStreamWriteVarSlice(int streamID, int varID, int levelID, int memtype, co
       }
 #endif
 #if  defined  (HAVE_LIBEXTRA)
-    case CDI_FILETYPE_EXT:
+    case FILETYPE_EXT:
       {
         if ( memtype == MEMTYPE_FLOAT ) return 1;
         extWriteVarSliceDP(streamptr, varID, levelID, (double *)data);
@@ -38362,7 +37252,7 @@ int cdiStreamWriteVarSlice(int streamID, int varID, int levelID, int memtype, co
       }
 #endif
 #if  defined  (HAVE_LIBIEG)
-    case CDI_FILETYPE_IEG:
+    case FILETYPE_IEG:
       {
         if ( memtype == MEMTYPE_FLOAT ) return 1;
         iegWriteVarSliceDP(streamptr, varID, levelID, (double *)data);
@@ -38370,10 +37260,10 @@ int cdiStreamWriteVarSlice(int streamID, int varID, int levelID, int memtype, co
       }
 #endif
 #if  defined  (HAVE_LIBNETCDF)
-    case CDI_FILETYPE_NC:
-    case CDI_FILETYPE_NC2:
-    case CDI_FILETYPE_NC4:
-    case CDI_FILETYPE_NC4C:
+    case FILETYPE_NC:
+    case FILETYPE_NC2:
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
       cdf_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
       break;
 #endif
@@ -38441,19 +37331,22 @@ void streamWriteVarSliceF(int streamID, int varID, int levelID, const float *dat
 }
 
 
-void streamWriteVarChunk(int streamID, int varID,
-                         const int rect[][2], const double *data, int nmiss)
+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)
+                                    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);
 }
 
 /* single image implementation */
-void cdiStreamWriteVarChunk_(int streamID, int varID, int memtype,
-                             const int rect[][2], const void *data, int nmiss)
+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);
 
@@ -38466,17 +37359,17 @@ void cdiStreamWriteVarChunk_(int streamID, int varID, int memtype,
   switch (filetype)
     {
 #if defined (HAVE_LIBGRIB)
-    case CDI_FILETYPE_GRB:
-    case CDI_FILETYPE_GRB2:
+    case FILETYPE_GRB:
+    case FILETYPE_GRB2:
 #endif
 #if defined (HAVE_LIBSERVICE)
-    case CDI_FILETYPE_SRV:
+    case FILETYPE_SRV:
 #endif
 #if defined (HAVE_LIBEXTRA)
-    case CDI_FILETYPE_EXT:
+    case FILETYPE_EXT:
 #endif
 #if defined (HAVE_LIBIEG)
-    case CDI_FILETYPE_IEG:
+    case FILETYPE_IEG:
 #endif
 #if  defined (HAVE_LIBGRIB) || defined (HAVE_LIBSERVICE)      \
   || defined (HAVE_LIBEXTRA) || defined (HAVE_LIBIEG)
@@ -38485,10 +37378,10 @@ void cdiStreamWriteVarChunk_(int streamID, int varID, int memtype,
       break;
 #endif
 #if  defined  (HAVE_LIBNETCDF)
-    case CDI_FILETYPE_NC:
-    case CDI_FILETYPE_NC2:
-    case CDI_FILETYPE_NC4:
-    case CDI_FILETYPE_NC4C:
+    case FILETYPE_NC:
+    case FILETYPE_NC2:
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
       cdf_write_var_chunk(streamptr, varID, memtype, rect, data, nmiss);
       break;
 #endif
@@ -38512,34 +37405,34 @@ int stream_write_record(int streamID, int memtype, const void *data, int nmiss)
   switch (streamptr->filetype)
     {
 #if  defined  (HAVE_LIBGRIB)
-    case CDI_FILETYPE_GRB:
-    case CDI_FILETYPE_GRB2:
+    case FILETYPE_GRB:
+    case FILETYPE_GRB2:
       grb_write_record(streamptr, memtype, data, nmiss);
       break;
 #endif
 #if  defined  (HAVE_LIBSERVICE)
-    case CDI_FILETYPE_SRV:
+    case FILETYPE_SRV:
       if ( memtype == MEMTYPE_FLOAT ) return 1;
       srvWriteRecord(streamptr, (const double *)data);
       break;
 #endif
 #if  defined  (HAVE_LIBEXTRA)
-    case CDI_FILETYPE_EXT:
+    case FILETYPE_EXT:
       if ( memtype == MEMTYPE_FLOAT ) return 1;
       extWriteRecord(streamptr, (const double *)data);
       break;
 #endif
 #if  defined  (HAVE_LIBIEG)
-    case CDI_FILETYPE_IEG:
+    case FILETYPE_IEG:
       if ( memtype == MEMTYPE_FLOAT ) return 1;
       iegWriteRecord(streamptr, (const double *)data);
       break;
 #endif
 #if  defined  (HAVE_LIBNETCDF)
-    case CDI_FILETYPE_NC:
-    case CDI_FILETYPE_NC2:
-    case CDI_FILETYPE_NC4:
-    case CDI_FILETYPE_NC4C:
+    case FILETYPE_NC:
+    case FILETYPE_NC2:
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
       {
 	cdf_write_record(streamptr, memtype, data, nmiss);
 	break;
@@ -38583,7 +37476,7 @@ void streamWriteRecordF(int streamID, const float *data, int nmiss)
       // In case the file format does not support single precision writing,
       // we fall back to double precision writing, converting the data on the fly.
       stream_t *streamptr = stream_to_pointer(streamID);
-      int varID = streamptr->record->varID;
+      int varID  = streamptr->record->varID;
       size_t elementCount = (size_t) gridInqSize(vlistInqVarGrid(streamInqVlist(streamID), varID));
       double *conversionBuffer = (double *) Malloc(elementCount*sizeof(*conversionBuffer));
       for ( size_t i = elementCount; i--; ) conversionBuffer[i] = (double) data[i];
@@ -38618,15 +37511,15 @@ int cdiStreamReadVar(int streamID, int varID, int memtype, void *data, int *nmis
   switch (filetype)
     {
 #if  defined  (HAVE_LIBGRIB)
-    case CDI_FILETYPE_GRB:
-    case CDI_FILETYPE_GRB2:
+    case FILETYPE_GRB:
+    case FILETYPE_GRB2:
       {
         grb_read_var(streamptr, varID, memtype, data, nmiss);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBSERVICE)
-    case CDI_FILETYPE_SRV:
+    case FILETYPE_SRV:
       {
         if ( memtype == MEMTYPE_FLOAT ) return 1;
         srvReadVarDP(streamptr, varID, (double *)data, nmiss);
@@ -38634,7 +37527,7 @@ int cdiStreamReadVar(int streamID, int varID, int memtype, void *data, int *nmis
       }
 #endif
 #if  defined  (HAVE_LIBEXTRA)
-    case CDI_FILETYPE_EXT:
+    case FILETYPE_EXT:
       {
         if ( memtype == MEMTYPE_FLOAT ) return 1;
         extReadVarDP(streamptr, varID, (double *)data, nmiss);
@@ -38642,7 +37535,7 @@ int cdiStreamReadVar(int streamID, int varID, int memtype, void *data, int *nmis
       }
 #endif
 #if  defined  (HAVE_LIBIEG)
-    case CDI_FILETYPE_IEG:
+    case FILETYPE_IEG:
       {
         if ( memtype == MEMTYPE_FLOAT ) return 1;
         iegReadVarDP(streamptr, varID, (double *)data, nmiss);
@@ -38650,10 +37543,10 @@ int cdiStreamReadVar(int streamID, int varID, int memtype, void *data, int *nmis
       }
 #endif
 #if  defined  (HAVE_LIBNETCDF)
-    case CDI_FILETYPE_NC:
-    case CDI_FILETYPE_NC2:
-    case CDI_FILETYPE_NC4:
-    case CDI_FILETYPE_NC4C:
+    case FILETYPE_NC:
+    case FILETYPE_NC2:
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
       {
         cdf_read_var(streamptr, varID, memtype, data, nmiss);
 	break;
@@ -38744,15 +37637,15 @@ int cdiStreamReadVarSlice(int streamID, int varID, int levelID, int memtype, voi
   switch (filetype)
     {
 #if  defined  (HAVE_LIBGRIB)
-    case CDI_FILETYPE_GRB:
-    case CDI_FILETYPE_GRB2:
+    case FILETYPE_GRB:
+    case FILETYPE_GRB2:
       {
         grb_read_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBSERVICE)
-    case CDI_FILETYPE_SRV:
+    case FILETYPE_SRV:
       {
         if ( memtype == MEMTYPE_FLOAT ) return 1;
         srvReadVarSliceDP(streamptr, varID, levelID, (double *)data, nmiss);
@@ -38760,7 +37653,7 @@ int cdiStreamReadVarSlice(int streamID, int varID, int levelID, int memtype, voi
       }
 #endif
 #if  defined  (HAVE_LIBEXTRA)
-    case CDI_FILETYPE_EXT:
+    case FILETYPE_EXT:
       {
         if ( memtype == MEMTYPE_FLOAT ) return 1;
         extReadVarSliceDP(streamptr, varID, levelID, (double *)data, nmiss);
@@ -38768,7 +37661,7 @@ int cdiStreamReadVarSlice(int streamID, int varID, int levelID, int memtype, voi
       }
 #endif
 #if  defined  (HAVE_LIBIEG)
-    case CDI_FILETYPE_IEG:
+    case FILETYPE_IEG:
       {
         if ( memtype == MEMTYPE_FLOAT ) return 1;
         iegReadVarSliceDP(streamptr, varID, levelID, (double *)data, nmiss);
@@ -38776,10 +37669,10 @@ int cdiStreamReadVarSlice(int streamID, int varID, int levelID, int memtype, voi
       }
 #endif
 #if  defined  (HAVE_LIBNETCDF)
-    case CDI_FILETYPE_NC:
-    case CDI_FILETYPE_NC2:
-    case CDI_FILETYPE_NC4:
-    case CDI_FILETYPE_NC4C:
+    case FILETYPE_NC:
+    case FILETYPE_NC2:
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
       {
         cdf_read_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
         break;
@@ -38873,34 +37766,34 @@ int stream_read_record(int streamID, int memtype, void *data, int *nmiss)
   switch (streamptr->filetype)
     {
 #if  defined  (HAVE_LIBGRIB)
-    case CDI_FILETYPE_GRB:
-    case CDI_FILETYPE_GRB2:
+    case FILETYPE_GRB:
+    case FILETYPE_GRB2:
       grb_read_record(streamptr, memtype, data, nmiss);
       break;
 #endif
 #if  defined  (HAVE_LIBSERVICE)
-    case CDI_FILETYPE_SRV:
+    case FILETYPE_SRV:
       if ( memtype == MEMTYPE_FLOAT ) return 1;
       srvReadRecord(streamptr, (double *)data, nmiss);
       break;
 #endif
 #if  defined  (HAVE_LIBEXTRA)
-    case CDI_FILETYPE_EXT:
+    case FILETYPE_EXT:
       if ( memtype == MEMTYPE_FLOAT ) return 1;
       extReadRecord(streamptr, (double *)data, nmiss);
       break;
 #endif
 #if  defined  (HAVE_LIBIEG)
-    case CDI_FILETYPE_IEG:
+    case FILETYPE_IEG:
       if ( memtype == MEMTYPE_FLOAT ) return 1;
       iegReadRecord(streamptr, (double *)data, nmiss);
       break;
 #endif
 #if  defined  (HAVE_LIBNETCDF)
-    case CDI_FILETYPE_NC:
-    case CDI_FILETYPE_NC2:
-    case CDI_FILETYPE_NC4:
-    case CDI_FILETYPE_NC4C:
+    case FILETYPE_NC:
+    case FILETYPE_NC2:
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
       cdf_read_record(streamptr, memtype, data, nmiss);
       break;
 #endif
@@ -38955,7 +37848,7 @@ void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
 void varDefVCT(size_t vctsize, double *vctptr);
 void varDefZAxisReference(int nlev, int nvgrid, unsigned char uuid[CDI_UUID_SIZE]);
 
-int  varDefZaxis(int vlistID, int zaxistype, int nlevels, const double *levels, const char **cvals, size_t clength, bool lbounds,
+int  varDefZaxis(int vlistID, int zaxistype, int nlevels, const double *levels, int lbounds,
 		 const double *levels1, const double *levels2, int vctsize, const double *vct, char *name,
 		 const char *longname, const char *units, int prec, int mode, int ltype);
 
@@ -38978,7 +37871,7 @@ void varDefOptGribInt(int varID, int tile_index, long lval, const char *keyword)
 void varDefOptGribDbl(int varID, int tile_index, double dval, const char *keyword);
 int varOptGribNentries(int varID);
 
-bool zaxisCompare(int zaxisID, int zaxistype, int nlevels, bool lbounds, const double *levels, const char *longname, const char *units, int ltype);
+int  zaxisCompare(int zaxisID, int zaxistype, int nlevels, int lbounds, const double *levels, const char *longname, const char *units, int ltype);
 
 #endif
 /*
@@ -38997,10 +37890,30 @@ bool zaxisCompare(int zaxisID, int zaxistype, int nlevels, bool lbounds, const d
 
 //#define TEST_GROUPS 1
 
-#include <ctype.h>
 #include <limits.h>
+#include <ctype.h>
+#include <math.h>
+#include <float.h>
+#ifdef HAVE_MMAP
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#endif
+#ifdef HAVE_LIBPTHREAD
+#include <pthread.h>
+#endif
+
+#include <netcdf.h>
+
 
+//#define PROJECTION_TEST
 
+#undef  UNDEFID
+#define UNDEFID  CDI_UNDEFID
+
+static const char bndsName[] = "bnds";
 
 #define  X_AXIS  1
 #define  Y_AXIS  2
@@ -39022,24 +37935,21 @@ ncdim_t;
 
 typedef struct {
   int      ncid;
-  int      isvar;
-  bool     ignore;
-  bool     isx;
-  bool     isy;
-  bool     isc;
-  bool     islon;
-  bool     islat;
-  bool     islev;
-  bool     istime;
-  bool     warn;
-  bool     calendar;
-  bool     climatology;
-  bool     lformulaterms;
+  int      ignore;
+  short    isvar;
+  short    islon;
+  int      islat;
+  int      islev;
+  int      istime;
+  int      warn;
   int      tsteptype;
   int      param;
   int      code;
   int      tabnum;
+  int      climatology;
   int      bounds;
+  int      lformula;
+  int      lformulaterms;
   int      gridID;
   int      zaxisID;
   int      gridtype;
@@ -39050,7 +37960,6 @@ typedef struct {
   int      xvarid;
   int      yvarid;
   int      zvarid;
-  int      cvarids[MAX_COORDVARS];
   int      tvarid;
   int      psvarid;
   int      p0varid;
@@ -39059,15 +37968,16 @@ typedef struct {
   int      nauxvars;
   int      auxvarids[MAX_AUXVARS];
   int      cellarea;
+  int      calendar;
   int      tableID;
   int      truncation;
   int      position;
-  bool     defmissval;
-  bool     deffillval;
+  int      defmissval;
+  int      deffillval;
   int      xtype;
+  int      ndims;
   int      gmapid;
   int      positive;
-  int      ndims;
   int      dimids[8];
   int      dimtype[8];
   int      chunks[8];
@@ -39075,8 +37985,8 @@ typedef struct {
   int      chunktype;
   int      natts;
   int      deflate;
-  bool     lunsigned;
-  bool     lvalidrange;
+  int      lunsigned;
+  int      lvalidrange;
   int     *atts;
   size_t   vctsize;
   double  *vct;
@@ -39094,6 +38004,80 @@ typedef struct {
 }
 ncvar_t;
 
+static
+void strtolower(char *str)
+{
+  if ( str )
+    for (size_t i = 0; str[i]; ++i)
+      str[i] = (char)tolower((int)str[i]);
+}
+
+static
+int get_timeunit(size_t len, const char *ptu)
+{
+  int timeunit = -1;
+
+  if ( len > 2 )
+    {
+      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 if ( len == 1 )
+    {
+      if ( ptu[0] == 's' ) timeunit = TUNIT_SECOND;
+    }
+
+  return timeunit;
+}
+
+static
+bool isTimeUnits(const char *timeunits)
+{
+  bool status = 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;
+  return status;
+}
+
+static
+bool isTimeAxisUnits(const char *timeunits)
+{
+  bool status = false;
+
+  size_t len = strlen(timeunits);
+  char *tu = (char *) Malloc((len+1)*sizeof(char));
+  memcpy(tu, timeunits, (len+1) * sizeof(char));
+  char *ptu = tu;
+
+  for (size_t i = 0; i < len; i++ ) ptu[i] = (char)tolower((int)ptu[i]);
+
+  int timeunit = get_timeunit(len, ptu);
+  if ( timeunit != -1 )
+    {
+
+      while ( ! isspace(*ptu) && *ptu != 0 ) ptu++;
+      if ( *ptu )
+        {
+          while ( isspace(*ptu) ) ptu++;
+
+          int timetype = memcmp(ptu, "as", 2) == 0 ? TAXIS_ABSOLUTE :
+            memcmp(ptu, "since", 5) == 0 ? TAXIS_RELATIVE : -1;
+
+          status = timetype != -1;
+        }
+    }
+
+  Free(tu);
+
+  return status;
+}
 
 static
 void scanTimeString(const char *ptu, int *rdate, int *rtime)
@@ -39166,11 +38150,17 @@ int scanTimeUnit(const char *unitstr)
 static
 void setForecastTime(const char *timestr, taxis_t *taxis)
 {
-  size_t len = strlen(timestr);
-  if ( len != 0 )
-    scanTimeString(timestr, &taxis->fdate, &taxis->ftime);
-  else
-    taxis->fdate = taxis->ftime = 0;
+  (*taxis).fdate = 0;
+  (*taxis).ftime = 0;
+
+  int len = (int) strlen(timestr);
+  if ( len == 0 ) return;
+
+  int fdate = 0, ftime = 0;
+  scanTimeString(timestr, &fdate, &ftime);
+
+  (*taxis).fdate = fdate;
+  (*taxis).ftime = ftime;
 }
 
 static
@@ -39180,57 +38170,53 @@ int setBaseTime(const char *timeunits, taxis_t *taxis)
   int rdate = -1, rtime = -1;
 
   size_t len = strlen(timeunits);
-  char *restrict tu = (char *)Malloc((len+1) * sizeof(char));
+  char *tu = (char *) Malloc((len+1) * sizeof (char));
+  memcpy(tu, timeunits, (len+1) * sizeof (char));
+  char *ptu = tu;
 
-  for ( size_t i = 0; i < len; i++ ) tu[i] = (char)tolower((int)timeunits[i]);
-  tu[len] = 0;
+  for ( size_t i = 0; i < len; i++ ) ptu[i] = (char)tolower((int) ptu[i]);
 
-  int timeunit = get_timeunit(len, tu);
+  int timeunit = get_timeunit(len, ptu);
   if ( timeunit == -1 )
     {
       Message("Unsupported TIMEUNIT: %s!", timeunits);
-      return 1;
+      return (1);
     }
 
-  size_t pos = 0;
-  while ( pos < len && !isspace(tu[pos]) ) ++pos;
-  if ( tu[pos] )
+  while ( ! isspace(*ptu) && *ptu != 0 ) ptu++;
+  if ( *ptu )
     {
-      while ( isspace(tu[pos]) ) ++pos;
+      while ( isspace(*ptu) ) ptu++;
 
-      if ( str_is_equal(tu+pos, "since") )
+      if ( memcmp(ptu, "as", 2) == 0 )
+        timetype = TAXIS_ABSOLUTE;
+      else if ( memcmp(ptu, "since", 5) == 0 )
         timetype = TAXIS_RELATIVE;
 
-      while ( pos < len && !isspace(tu[pos]) ) ++pos;
-      if ( tu[pos] )
+      while ( ! isspace(*ptu) && *ptu != 0 ) ptu++;
+      if ( *ptu )
         {
-          while ( isspace(tu[pos]) ) ++pos;
+          while ( isspace(*ptu) ) ptu++;
 
           if ( timetype == TAXIS_ABSOLUTE )
             {
-              if ( timeunit == TUNIT_DAY )
+              if ( memcmp(ptu, "%y%m%d.%f", 9) != 0 && timeunit == TUNIT_DAY )
                 {
-                  if ( !str_is_equal(tu+pos, "%y%m%d.%f") )
-                    {
-                      Message("Unsupported format %s for TIMEUNIT day!", tu+pos);
-                      timeunit = -1;
-                    }
+                  Message("Unsupported format %s for TIMEUNIT day!", ptu);
+                  timeunit = -1;
                 }
-              else if ( timeunit == TUNIT_MONTH )
+              else if ( memcmp(ptu, "%y%m.%f", 7) != 0 && timeunit == TUNIT_MONTH )
                 {
-                  if ( !str_is_equal(tu+pos, "%y%m.%f") )
-                    {
-                      Message("Unsupported format %s for TIMEUNIT month!", tu+pos);
-                      timeunit = -1;
-                    }
+                  Message("Unsupported format %s for TIMEUNIT month!", ptu);
+                  timeunit = -1;
                 }
             }
           else if ( timetype == TAXIS_RELATIVE )
             {
-              scanTimeString(tu+pos, &rdate, &rtime);
+              scanTimeString(ptu, &rdate, &rtime);
 
-              taxis->rdate = rdate;
-              taxis->rtime = rtime;
+              (*taxis).rdate = rdate;
+              (*taxis).rtime = rtime;
 
               if ( CDI_Debug )
                 Message("rdate = %d  rtime = %d", rdate, rtime);
@@ -39238,8 +38224,8 @@ int setBaseTime(const char *timeunits, taxis_t *taxis)
         }
     }
 
-  taxis->type = timetype;
-  taxis->unit = timeunit;
+  (*taxis).type = timetype;
+  (*taxis).unit = timeunit;
 
   Free(tu);
 
@@ -39250,134 +38236,63 @@ int setBaseTime(const char *timeunits, taxis_t *taxis)
 }
 
 static
-bool xtypeIsText(int xtype)
+void cdfGetAttInt(int fileID, int ncvarid, const char *attname, int attlen, int *attint)
 {
-  bool isText = ( xtype == NC_CHAR )
-#if  defined  (HAVE_NETCDF4)
-    || ( xtype == NC_STRING )
-#endif
-    ;
-  return isText;
-}
-
-static
-bool xtypeIsFloat(nc_type xtype)
-{
-  bool isFloat = xtype == NC_FLOAT || xtype == NC_DOUBLE;
-
-  return isFloat;
-}
-
-static
-bool xtypeIsInt(nc_type xtype)
-{
-  bool isInt = xtype == NC_SHORT || xtype == NC_INT
-            || xtype == NC_BYTE
-#if  defined  (HAVE_NETCDF4)
-            || xtype == NC_USHORT || xtype == NC_UINT
-            || xtype == NC_UBYTE
-#endif
-             ;
-
-  return isInt;
-}
-
-static
-int cdfInqDatatype(int xtype, bool lunsigned)
-{
-  int datatype = -1;
-
-#if  defined  (HAVE_NETCDF4)
-  if ( xtype == NC_BYTE && lunsigned ) xtype = NC_UBYTE;
-#endif
-
-  if      ( xtype == NC_BYTE   )  datatype = CDI_DATATYPE_INT8;
-  else if ( xtype == NC_CHAR   )  datatype = CDI_DATATYPE_UINT8;
-  else if ( xtype == NC_SHORT  )  datatype = CDI_DATATYPE_INT16;
-  else if ( xtype == NC_INT    )  datatype = CDI_DATATYPE_INT32;
-  else if ( xtype == NC_FLOAT  )  datatype = CDI_DATATYPE_FLT32;
-  else if ( xtype == NC_DOUBLE )  datatype = CDI_DATATYPE_FLT64;
-#if  defined  (HAVE_NETCDF4)
-  else if ( xtype == NC_UBYTE  )  datatype = CDI_DATATYPE_UINT8;
-  else if ( xtype == NC_LONG   )  datatype = CDI_DATATYPE_INT32;
-  else if ( xtype == NC_USHORT )  datatype = CDI_DATATYPE_UINT16;
-  else if ( xtype == NC_UINT   )  datatype = CDI_DATATYPE_UINT32;
-  else if ( xtype == NC_INT64  )  datatype = CDI_DATATYPE_FLT64;
-  else if ( xtype == NC_UINT64 )  datatype = CDI_DATATYPE_FLT64;
-#endif
-
-  return datatype;
-}
+  nc_type atttype;
+  size_t nc_attlen;
 
-static
-void cdfGetAttInt(int fileID, int ncvarid, const char *attname, size_t attlen, int *attint)
-{
   *attint = 0;
 
-  nc_type atttype;
-  size_t nc_attlen;
   cdf_inq_atttype(fileID, ncvarid, attname, &atttype);
   cdf_inq_attlen(fileID, ncvarid, attname, &nc_attlen);
 
-  if ( xtypeIsFloat(atttype) || xtypeIsInt(atttype) )
+  if ( atttype != NC_CHAR )
     {
-      bool lalloc = nc_attlen > attlen;
-      int *pintatt = lalloc ? (int *)(Malloc(nc_attlen*sizeof(int))) : attint;
+      int *pintatt = (int)nc_attlen > attlen
+        ? (int *)(Malloc(nc_attlen * sizeof (int))) : attint;
+
       cdf_get_att_int(fileID, ncvarid, attname, pintatt);
-      if ( lalloc )
+
+      if ( (int)nc_attlen > attlen )
         {
-          memcpy(attint, pintatt, attlen*sizeof(int));
+          memcpy(attint, pintatt, (size_t)attlen * sizeof (int));
           Free(pintatt);
         }
     }
 }
 
 static
-void cdfGetAttDouble(int fileID, int ncvarid, char *attname, size_t attlen, double *attdouble)
+void cdfGetAttDouble(int fileID, int ncvarid, char *attname, int attlen, double *attdouble)
 {
-  *attdouble = 0;
-
   nc_type atttype;
   size_t nc_attlen;
+
+  *attdouble = 0;
+
   cdf_inq_atttype(fileID, ncvarid, attname, &atttype);
   cdf_inq_attlen(fileID, ncvarid, attname, &nc_attlen);
 
-  if ( xtypeIsFloat(atttype) || xtypeIsInt(atttype) )
+  if ( atttype != NC_CHAR )
     {
-      bool lalloc = nc_attlen > attlen;
-      double *pdoubleatt = lalloc ? (double*)Malloc(nc_attlen*sizeof(double)) : attdouble;
+      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 ( lalloc )
+
+      if ( (int)nc_attlen > attlen )
         {
-          memcpy(attdouble, pdoubleatt, attlen*sizeof(double));
+          memcpy(attdouble, pdoubleatt, (size_t)attlen * sizeof (double));
           Free(pdoubleatt);
         }
     }
 }
 
 static
-bool cdfCheckAttText(int fileID, int ncvarid, const char *attname)
-{
-  bool status = false;
-  nc_type atttype;
-
-  int status_nc = nc_inq_atttype(fileID, ncvarid, attname, &atttype);
-
-  if ( status_nc == NC_NOERR
-       && (atttype == NC_CHAR
-#if  defined  (HAVE_NETCDF4)
-           || atttype == NC_STRING
-#endif
-           ) )
-    {
-      status = true;
-    }
-
-  return status;
-}
-
-static
-void cdfGetAttText(int fileID, int ncvarid, const char *attname, size_t attlen, char *atttext)
+void cdfGetAttText(int fileID, int ncvarid,const char *attname, int attlen, char *atttext)
 {
   nc_type atttype;
   size_t nc_attlen;
@@ -39392,7 +38307,7 @@ void cdfGetAttText(int fileID, int ncvarid, const char *attname, size_t attlen,
         {
           cdf_get_att_text(fileID, ncvarid, attname, attbuf);
 
-          if ( nc_attlen > (attlen-1) ) nc_attlen = (attlen-1);
+          if ( (int) nc_attlen > (attlen-1) ) nc_attlen = (size_t)(attlen-1);
 
           attbuf[nc_attlen++] = 0;
           memcpy(atttext, attbuf, nc_attlen);
@@ -39412,7 +38327,7 @@ void cdfGetAttText(int fileID, int ncvarid, const char *attname, size_t attlen,
 
           size_t ssize = strlen(attbuf) + 1;
 
-          if ( ssize > attlen ) ssize = attlen;
+          if ( ssize > (size_t)attlen ) ssize = (size_t)attlen;
           memcpy(atttext, attbuf, ssize);
           atttext[ssize - 1] = 0;
           Free(attbuf);
@@ -39425,6029 +38340,6706 @@ void cdfGetAttText(int fileID, int ncvarid, const char *attname, size_t attlen,
 #endif
 }
 
-
-void cdf_scale_add(size_t size, double *data, double addoffset, double scalefactor)
+static
+int xtypeIsText(int xtype)
 {
-  bool laddoffset   = IS_NOT_EQUAL(addoffset, 0);
-  bool lscalefactor = IS_NOT_EQUAL(scalefactor, 1);
+  int isText = FALSE;
 
-  if ( laddoffset && lscalefactor )
-    {
-      for (size_t i = 0; i < size; ++i )
-        data[i] = data[i] * scalefactor + addoffset;
-    }
-  else if (lscalefactor)
-    {
-      for (size_t i = 0; i < size; ++i )
-        data[i] *= scalefactor;
-    }
-  else if (laddoffset)
-    {
-      for (size_t i = 0; i < size; ++i )
-        data[i] += addoffset;
-    }
+  if ( xtype == NC_CHAR )
+    isText = TRUE;
+#if  defined  (HAVE_NETCDF4)
+  else if ( xtype == NC_STRING )
+    isText = TRUE;
+#endif
+
+  return isText;
 }
 
 static
-void cdfCreateRecords(stream_t *streamptr, int tsID)
+int xtypeIsFloat(int xtype)
 {
-  if ( tsID < 0 || (tsID >= streamptr->ntsteps && tsID > 0) ) return;
+  int isFloat = xtype == NC_FLOAT || xtype == NC_DOUBLE;
+  return isFloat;
+}
 
-  if ( streamptr->tsteps[tsID].nallrecs > 0 ) return;
+static
+int cdfInqDatatype(int xtype, int lunsigned)
+{
+  int datatype = -1;
 
-  int vlistID  = streamptr->vlistID;
+#if  defined  (HAVE_NETCDF4)
+  if ( xtype == NC_BYTE && lunsigned ) xtype = NC_UBYTE;
+#endif
 
-  tsteps_t* sourceTstep = streamptr->tsteps;
-  tsteps_t* destTstep = sourceTstep + tsID;
+  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
 
-  int nvars = vlistNvars(vlistID);
-  int nrecs = vlistNrecs(vlistID);
+  return datatype;
+}
 
-  if ( nrecs <= 0 ) return;
 
-  if ( tsID == 0 )
-    {
-      int nvrecs = nrecs; /* use all records at first timestep */
+void cdfCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
+{
+  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);
+  int datatype = vlistInqVarDatatype(vlistID1, ivarID);
+  int memtype  = datatype != DATATYPE_FLT32 ? MEMTYPE_DOUBLE : MEMTYPE_FLOAT;
 
-      streamptr->nrecs += nrecs;
+  void *data
+    = Malloc((size_t)datasize
+             * (memtype == MEMTYPE_DOUBLE ? sizeof(double) : sizeof(float)));
 
-      destTstep->records    = (record_t *) Malloc((size_t)nrecs*sizeof(record_t));
-      destTstep->nrecs      = nrecs;
-      destTstep->nallrecs   = nrecs;
-      destTstep->recordSize = nrecs;
-      destTstep->curRecID   = CDI_UNDEFID;
-      destTstep->recIDs     = (int *) Malloc((size_t)nvrecs*sizeof (int));;
-      for ( int recID = 0; recID < nvrecs; recID++ ) destTstep->recIDs[recID] = recID;
+  int nmiss;
+  cdf_read_record(streamptr1, memtype, data, &nmiss);
+  cdf_write_record(streamptr2, memtype, data, nmiss);
 
-      record_t *records = destTstep->records;
+  Free(data);
+}
 
-      for ( int varID = 0, recID = 0; varID < nvars; varID++ )
-        {
-          int zaxisID = vlistInqVarZaxis(vlistID, varID);
-          int nlev    = zaxisInqSize(zaxisID);
-          for ( int levelID = 0; levelID < nlev; levelID++ )
-            {
-              recordInitEntry(&records[recID]);
-              records[recID].varID   = (short)varID;
-              records[recID].levelID = (short)levelID;
-              recID++;
-            }
-        }
-    }
-  else if ( tsID == 1 )
+/* 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 )
     {
-      int nvrecs = 0;
-      for ( int varID = 0; varID < nvars; varID++ )
-        {
-          if ( vlistInqVarTsteptype(vlistID, varID) != TSTEP_CONSTANT )
-            {
-              int zaxisID = vlistInqVarZaxis(vlistID, varID);
-              nvrecs += zaxisInqSize(zaxisID);
-            }
-        }
+      streamptr->tsteps[0].curRecID = 0;
+    }
 
-      streamptr->nrecs += nvrecs;
+  *varID   = streamptr->tsteps[0].records[recID].varID;
+  *levelID = streamptr->tsteps[0].records[recID].levelID;
 
-      destTstep->records    = (record_t *) Malloc((size_t)nrecs*sizeof(record_t));
-      destTstep->nrecs      = nvrecs;
-      destTstep->nallrecs   = nrecs;
-      destTstep->recordSize = nrecs;
-      destTstep->curRecID   = CDI_UNDEFID;
+  streamptr->record->varID   = *varID;
+  streamptr->record->levelID = *levelID;
 
-      memcpy(destTstep->records, sourceTstep->records, (size_t)nrecs*sizeof(record_t));
+  if ( CDI_Debug )
+    Message("recID = %d  varID = %d  levelID = %d", recID, *varID, *levelID);
 
-      if ( nvrecs )
+  return (recID+1);
+}
+*/
+
+
+void cdfDefRecord(stream_t *streamptr)
+{
+  (void)streamptr;
+}
+
+#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 ((retval = nc_def_var_szip(ncid, ncvarid, options_mask, bits_per_pixel)))
+    {
+      if ( retval == NC_EINVAL )
         {
-          destTstep->recIDs = (int *) Malloc((size_t)nvrecs * sizeof (int));
-          for ( int recID = 0, vrecID = 0; recID < nrecs; recID++ )
+          static int lwarn = TRUE;
+
+          if ( lwarn )
             {
-              int varID = destTstep->records[recID].varID;
-              if ( vlistInqVarTsteptype(vlistID, varID) != TSTEP_CONSTANT )
-                {
-                  destTstep->recIDs[vrecID++] = recID;
-                }
+              lwarn = FALSE;
+              Warning("NetCDF4/Szip compression not compiled in!");
             }
         }
+      else
+        Error("nc_def_var_szip failed, status = %d", retval);
     }
-  else
-    {
-      if ( streamptr->tsteps[1].records == 0 ) cdfCreateRecords(streamptr, 1);
+}
+#endif
 
-      int nvrecs = streamptr->tsteps[1].nrecs;
+static
+void cdfDefTimeValue(stream_t *streamptr, int tsID)
+{
+  int fileID = streamptr->fileID;
 
-      streamptr->nrecs += nvrecs;
+  if ( CDI_Debug )
+    Message("streamID = %d, fileID = %d", streamptr->self, fileID);
 
-      destTstep->records    = (record_t *) Malloc((size_t)nrecs*sizeof(record_t));
-      destTstep->nrecs      = nvrecs;
-      destTstep->nallrecs   = nrecs;
-      destTstep->recordSize = nrecs;
-      destTstep->curRecID   = CDI_UNDEFID;
+  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
 
-      memcpy(destTstep->records, sourceTstep->records, (size_t)nrecs*sizeof(record_t));
+  if ( streamptr->ncmode == 1 )
+    {
+      cdf_enddef(fileID);
+      streamptr->ncmode = 2;
+    }
 
-      destTstep->recIDs     = (int *) Malloc((size_t)nvrecs * sizeof(int));
+  size_t index = (size_t)tsID;
 
-      memcpy(destTstep->recIDs, streamptr->tsteps[1].recIDs, (size_t)nvrecs*sizeof(int));
-    }
-}
+  double timevalue = cdiEncodeTimeval(taxis->vdate, taxis->vtime, &streamptr->tsteps[0].taxis);
+  if ( CDI_Debug ) Message("tsID = %d  timevalue = %f", tsID, timevalue);
 
-static
-int cdf_time_dimid(int fileID, int ndims, int nvars)
-{
-  char dimname[80];
-  for ( int dimid = 0; dimid < ndims; ++dimid )
+  int ncvarid = streamptr->basetime.ncvarid;
+  cdf_put_var1_double(fileID, ncvarid, &index, &timevalue);
+
+  if ( taxis->has_bounds )
     {
-      dimname[0] = 0;
-      cdf_inq_dimname(fileID, dimid, dimname);
-      if ( str_is_equal(dimname, "time") || str_is_equal(dimname, "Time") ) return dimid;
+      size_t start[2], count[2];
+
+      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);
     }
 
-  for ( int varid = 0; varid < nvars; ++varid )
+  ncvarid = streamptr->basetime.leadtimeid;
+  if ( taxis->type == TAXIS_FORECAST && ncvarid != UNDEFID )
     {
-      nc_type xtype;
-      int nvdims, nvatts, dimids[9];
-      cdf_inq_var(fileID, varid, NULL, &xtype, &nvdims, dimids, &nvatts);
-      if ( nvdims == 1 )
-        {
-          char sbuf[CDI_MAX_NAME];
-          for ( int iatt = 0; iatt < nvatts; ++iatt )
-            {
-              sbuf[0] = 0;
-              cdf_inq_attname(fileID, varid, iatt, sbuf);
-              if ( strncmp(sbuf, "units", 5) == 0 )
-                {
-                  cdfGetAttText(fileID, varid, "units", sizeof(sbuf), sbuf);
-                  str_tolower(sbuf);
-
-                  if ( is_time_units(sbuf) ) return dimids[0];
-                }
-            }
-        }
+      timevalue = taxis->fc_period;
+      cdf_put_var1_double(fileID, ncvarid, &index, &timevalue);
     }
 
-  return CDI_UNDEFID;
+  /*
+printf("fileID = %d %d %d %f\n", fileID, time_varid, index, timevalue);
+  */
 }
 
 static
-void init_ncdims(long ndims, ncdim_t *ncdims)
+int cdfDefTimeBounds(int fileID, int nctimevarid, int nctimedimid, const char *taxis_name, taxis_t* taxis)
 {
-  for ( long ncdimid = 0; ncdimid < ndims; ncdimid++ )
+  int time_bndsid = -1;
+  int dims[2];
+
+  dims[0] = nctimedimid;
+
+  /* fprintf(stderr, "time has bounds\n"); */
+
+  if ( nc_inq_dimid(fileID, bndsName, &dims[1]) != NC_NOERR )
+    cdf_def_dim(fileID, bndsName, 2, &dims[1]);
+
+  const char *bndsAttName, *bndsAttVal;
+  size_t bndsAttValLen;
+  char tmpstr[CDI_MAX_NAME];
+  if ( taxis->climatology )
     {
-      ncdims[ncdimid].ncvarid      = CDI_UNDEFID;
-      ncdims[ncdimid].dimtype      = CDI_UNDEFID;
-      ncdims[ncdimid].len          = 0;
-      ncdims[ncdimid].name[0]      = 0;
+      static const char climatology_bndsName[] = "climatology_bnds",
+        climatology_bndsAttName[] = "climatology";
+      bndsAttName = climatology_bndsAttName;
+      bndsAttValLen = sizeof (climatology_bndsName) - 1;
+      bndsAttVal = climatology_bndsName;
+    }
+  else
+    {
+      size_t taxisnameLen = strlen(taxis_name);
+      memcpy(tmpstr, taxis_name, taxisnameLen);
+      tmpstr[taxisnameLen] = '_';
+      memcpy(tmpstr + taxisnameLen + 1, bndsName, sizeof (bndsName));
+      size_t tmpstrLen = taxisnameLen + sizeof (bndsName);
+      static const char generic_bndsAttName[] = "bounds";
+      bndsAttName = generic_bndsAttName;
+      bndsAttValLen = tmpstrLen;
+      bndsAttVal = tmpstr;
     }
+  cdf_def_var(fileID, bndsAttVal, NC_DOUBLE, 2, dims, &time_bndsid);
+  cdf_put_att_text(fileID, nctimevarid, bndsAttName, bndsAttValLen, bndsAttVal);
+
+  return (time_bndsid);
 }
 
 static
-void init_ncvars(long nvars, ncvar_t *ncvars)
+void cdfDefTimeUnits(char *unitstr, taxis_t* taxis0, taxis_t* taxis)
 {
-  for ( long ncvarid = 0; ncvarid < nvars; ++ncvarid )
+  unitstr[0] = 0;
+
+  if ( taxis0->type == TAXIS_ABSOLUTE )
     {
-      ncvars[ncvarid].ncid            = CDI_UNDEFID;
-      ncvars[ncvarid].isvar           = CDI_UNDEFID;
-      ncvars[ncvarid].ignore          = false;
-      ncvars[ncvarid].isx             = false;
-      ncvars[ncvarid].isy             = false;
-      ncvars[ncvarid].isc             = false;
-      ncvars[ncvarid].islon           = false;
-      ncvars[ncvarid].islat           = false;
-      ncvars[ncvarid].islev           = false;
-      ncvars[ncvarid].istime          = false;
-      ncvars[ncvarid].warn            = false;
-      ncvars[ncvarid].calendar        = false;
-      ncvars[ncvarid].climatology     = false;
-      ncvars[ncvarid].lformulaterms   = false;
-      ncvars[ncvarid].tsteptype       = TSTEP_CONSTANT;
-      ncvars[ncvarid].param           = CDI_UNDEFID;
-      ncvars[ncvarid].code            = CDI_UNDEFID;
-      ncvars[ncvarid].tabnum          = 0;
-      ncvars[ncvarid].bounds          = CDI_UNDEFID;
-      ncvars[ncvarid].gridID          = CDI_UNDEFID;
-      ncvars[ncvarid].zaxisID         = CDI_UNDEFID;
-      ncvars[ncvarid].gridtype        = CDI_UNDEFID;
-      ncvars[ncvarid].zaxistype       = CDI_UNDEFID;
-      ncvars[ncvarid].xdim            = CDI_UNDEFID;
-      ncvars[ncvarid].ydim            = CDI_UNDEFID;
-      ncvars[ncvarid].zdim            = CDI_UNDEFID;
-      ncvars[ncvarid].xvarid          = CDI_UNDEFID;
-      ncvars[ncvarid].yvarid          = CDI_UNDEFID;
-      ncvars[ncvarid].zvarid          = CDI_UNDEFID;
-      ncvars[ncvarid].tvarid          = CDI_UNDEFID;
-      ncvars[ncvarid].psvarid         = CDI_UNDEFID;
-      ncvars[ncvarid].p0varid         = CDI_UNDEFID;
-      ncvars[ncvarid].ncoordvars      = 0;
-      for ( int i = 0; i < MAX_COORDVARS; ++i )
+      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 timeunit = taxis->unit != -1 ? taxis->unit : TUNIT_HOUR;
+      int rdate    = taxis->rdate;
+      int rtime    = taxis->rtime;
+      if ( rdate == -1 )
         {
-          ncvars[ncvarid].coordvarids[i]  = CDI_UNDEFID;
-          ncvars[ncvarid].cvarids[i]      = CDI_UNDEFID;
+          rdate  = taxis->vdate;
+          rtime  = taxis->vtime;
         }
-      ncvars[ncvarid].nauxvars      = 0;
-      for ( int i = 0; i < MAX_AUXVARS; ++i )
-        ncvars[ncvarid].auxvarids[i]  = CDI_UNDEFID;
-      ncvars[ncvarid].cellarea        = CDI_UNDEFID;
-      ncvars[ncvarid].tableID         = CDI_UNDEFID;
-      ncvars[ncvarid].xtype           = 0;
-      ncvars[ncvarid].ndims           = 0;
-      ncvars[ncvarid].gmapid          = CDI_UNDEFID;
-      ncvars[ncvarid].vctsize         = 0;
-      ncvars[ncvarid].vct             = NULL;
-      ncvars[ncvarid].truncation      = 0;
-      ncvars[ncvarid].position        = 0;
-      ncvars[ncvarid].positive        = 0;
-      ncvars[ncvarid].chunked         = 0;
-      ncvars[ncvarid].chunktype       = CDI_UNDEFID;
-      ncvars[ncvarid].defmissval      = false;
-      ncvars[ncvarid].deffillval      = false;
-      ncvars[ncvarid].missval         = 0;
-      ncvars[ncvarid].fillval         = 0;
-      ncvars[ncvarid].addoffset       = 0;
-      ncvars[ncvarid].scalefactor     = 1;
-      ncvars[ncvarid].natts           = 0;
-      ncvars[ncvarid].atts            = NULL;
-      ncvars[ncvarid].deflate         = 0;
-      ncvars[ncvarid].lunsigned       = false;
-      ncvars[ncvarid].lvalidrange     = false;
-      ncvars[ncvarid].validrange[0]   = VALIDMISS;
-      ncvars[ncvarid].validrange[1]   = VALIDMISS;
-      ncvars[ncvarid].ensdata         = NULL;
-      memset(ncvars[ncvarid].name, 0, CDI_MAX_NAME);
-      memset(ncvars[ncvarid].longname, 0, CDI_MAX_NAME);
-      memset(ncvars[ncvarid].stdname, 0, CDI_MAX_NAME);
-      memset(ncvars[ncvarid].units, 0, CDI_MAX_NAME);
-      memset(ncvars[ncvarid].extra, 0, CDI_MAX_NAME);
+
+      int year, month, day, hour, minute, second;
+      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-%d-%d %02d:%02d:%02d",
+              tunitNamePtr(timeunit), year, month, day, hour, minute, second);
     }
 }
 
 static
-void cdf_set_var(ncvar_t *ncvars, int ncvarid, short isvar)
+void cdfDefForecastTimeUnits(char *unitstr, int timeunit)
 {
-  if ( ncvars[ncvarid].isvar != CDI_UNDEFID &&
-       ncvars[ncvarid].isvar != isvar   &&
-       ncvars[ncvarid].warn  == false )
-    {
-      if ( ! ncvars[ncvarid].ignore )
-        Warning("Inconsistent variable definition for %s!", ncvars[ncvarid].name);
+  unitstr[0] = 0;
 
-      ncvars[ncvarid].warn = true;
-      isvar = FALSE;
-    }
+  if ( timeunit == -1 ) timeunit = TUNIT_HOUR;
 
-  ncvars[ncvarid].isvar = isvar;
+  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;
+
+  strcpy(unitstr, tunitNamePtr(timeunit));
 }
 
 static
-void cdf_set_dim(ncvar_t *ncvars, int ncvarid, int dimid, int dimtype)
+void cdfDefCalendar(int fileID, int ncvarid, int calendar)
 {
-  if ( ncvars[ncvarid].dimtype[dimid] != CDI_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);
-    }
+  static const struct { int calCode; const char *calStr; } calTab[] = {
+    { CALENDAR_STANDARD, "standard" },
+    { CALENDAR_PROLEPTIC, "proleptic_gregorian" },
+    { CALENDAR_NONE, "none" },
+    { CALENDAR_360DAYS, "360_day" },
+    { CALENDAR_365DAYS, "365_day" },
+    { CALENDAR_366DAYS, "366_day" },
+  };
+  enum { calTabSize = sizeof calTab / sizeof calTab[0] };
 
-  ncvars[ncvarid].dimtype[dimid] = dimtype;
+  for (size_t i = 0; i < calTabSize; ++i)
+    if (calTab[i].calCode == calendar)
+      {
+        const char *calstr = calTab[i].calStr;
+        size_t len = strlen(calstr);
+        cdf_put_att_text(fileID, ncvarid, "calendar", len, calstr);
+        break;
+      }
 }
 
-static
-void scan_hybrid_formulaterms(int ncid, int ncfvarid, int *avarid, int *bvarid, int *psvarid, int *p0varid)
+
+void cdfDefTime(stream_t* streamptr)
 {
-  *avarid  = -1;
-  *bvarid  = -1;
-  *psvarid = -1;
-  *p0varid = -1;
+  int time_varid;
+  int time_dimid;
+  int time_bndsid = -1;
+  static const char default_name[] = "time";
+
+  if ( streamptr->basetime.ncvarid != UNDEFID ) return;
+
+  int fileID = streamptr->fileID;
+
+  if ( streamptr->ncmode == 0 ) streamptr->ncmode = 1;
+  if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+
+  taxis_t *taxis = &streamptr->tsteps[0].taxis;
 
-  char attstring[1024];
-  cdfGetAttText(ncid, ncfvarid, "formula_terms", sizeof(attstring), attstring);
-  char *pstring = attstring;
+  const char *taxis_name = (taxis->name && taxis->name[0]) ? taxis->name : default_name ;
 
-  bool lstop = false;
-  for ( int i = 0; i < 4; i++ )
-    {
-      while ( isspace((int) *pstring) ) pstring++;
-      if ( *pstring == 0 ) break;
-      char *tagname = pstring;
-      while ( !isspace((int) *pstring) && *pstring != 0 ) pstring++;
-      if ( *pstring == 0 ) lstop = true;
-      *pstring++ = 0;
+  cdf_def_dim(fileID, taxis_name, NC_UNLIMITED, &time_dimid);
+  streamptr->basetime.ncdimid = time_dimid;
 
-      while ( isspace((int) *pstring) ) pstring++;
-      if ( *pstring == 0 ) break;
-      char *varname = pstring;
-      while ( !isspace((int) *pstring) && *pstring != 0 ) pstring++;
-      if ( *pstring == 0 ) lstop = true;
-      *pstring++ = 0;
+  cdf_def_var(fileID, taxis_name, NC_DOUBLE, 1, &time_dimid, &time_varid);
 
-      int dimvarid;
-      int status_nc = nc_inq_varid(ncid, varname, &dimvarid);
-      if ( status_nc == NC_NOERR )
-        {
-          if      ( strcmp(tagname, "ap:") == 0 ) *avarid  = dimvarid;
-          else if ( strcmp(tagname, "a:")  == 0 ) *avarid  = dimvarid;
-          else if ( strcmp(tagname, "b:")  == 0 ) *bvarid  = dimvarid;
-          else if ( strcmp(tagname, "ps:") == 0 ) *psvarid = dimvarid;
-          else if ( strcmp(tagname, "p0:") == 0 ) *p0varid = dimvarid;
-        }
-      else if ( strcmp(tagname, "ps:") != 0 )
-        {
-          Warning("%s - %s", nc_strerror(status_nc), varname);
-        }
+  streamptr->basetime.ncvarid = time_varid;
 
-      if ( lstop ) break;
-    }
-}
+  {
+    static const char timeStr[] = "time";
+    cdf_put_att_text(fileID, time_varid, "standard_name", sizeof(timeStr) - 1, timeStr);
+  }
 
-static
-bool isHybridSigmaPressureCoordinate(int ncid, int ncvarid, ncvar_t *ncvars, const ncdim_t *ncdims)
-{
-  bool status = false;
-  ncvar_t *ncvar = &ncvars[ncvarid];
+  if ( taxis->longname && taxis->longname[0] )
+    cdf_put_att_text(fileID, time_varid, "long_name", strlen(taxis->longname), taxis->longname);
 
-  if ( strcmp(ncvar->stdname, "atmosphere_hybrid_sigma_pressure_coordinate") == 0 )
+  if ( taxis->has_bounds )
     {
-      cdiConvention = CDI_CONVENTION_CF;
+      time_bndsid = cdfDefTimeBounds(fileID, time_varid, time_dimid, taxis_name, taxis);
+      streamptr->basetime.ncvarboundsid = time_bndsid;
+    }
 
-      status = true;
-      ncvar->zaxistype = ZAXIS_HYBRID;
-      //int ndims = ncvar->ndims;
-      int dimid = ncvar->dimids[0];
-      size_t dimlen = ncdims[dimid].len;
-      int avarid1 = -1, bvarid1 = -1, psvarid1 = -1, p0varid1 = -1;
-      int ncfvarid = ncvarid;
-      if ( ncvars[ncfvarid].lformulaterms )
-        scan_hybrid_formulaterms(ncid, ncfvarid, &avarid1, &bvarid1, &psvarid1, &p0varid1);
-      // printf("avarid1, bvarid1, psvarid1, p0varid1 %d %d %d %d\n", avarid1, bvarid1, psvarid1, p0varid1);
-      if ( avarid1  != -1 ) ncvars[avarid1].isvar = FALSE;
-      if ( bvarid1  != -1 ) ncvars[bvarid1].isvar = FALSE;
-      if ( psvarid1 != -1 ) ncvar->psvarid = psvarid1;
-      if ( p0varid1 != -1 ) ncvar->p0varid = p0varid1;
+  {
+    char unitstr[CDI_MAX_NAME];
+    cdfDefTimeUnits(unitstr, &streamptr->tsteps[0].taxis, taxis);
+    size_t len = strlen(unitstr);
+    if ( len )
+      {
+        cdf_put_att_text(fileID, time_varid, "units", len, unitstr);
+        /*
+          if ( taxis->has_bounds )
+          cdf_put_att_text(fileID, time_bndsid, "units", len, unitstr);
+        */
+      }
+  }
 
-      if ( ncvar->bounds != CDI_UNDEFID && ncvars[ncvar->bounds].lformulaterms )
-        {
-          ncfvarid = ncvar->bounds;
-          int avarid2 = -1, bvarid2 = -1, psvarid2 = -1, p0varid2 = -1;
-          if ( ncvars[ncfvarid].lformulaterms )
-            scan_hybrid_formulaterms(ncid, ncfvarid, &avarid2, &bvarid2, &psvarid2, &p0varid2);
-          // printf("avarid2, bvarid2, psvarid2, p0varid2 %d %d %d %d\n", avarid2, bvarid2, psvarid2, p0varid2);
-          if ( avarid2 != -1 && bvarid2 != -1 )
-            {
-              ncvars[avarid2].isvar = FALSE;
-              ncvars[bvarid2].isvar = FALSE;
+  if ( taxis->calendar != -1 )
+    {
+      cdfDefCalendar(fileID, time_varid, taxis->calendar);
+      /*
+      if ( taxis->has_bounds )
+        cdfDefCalendar(fileID, time_bndsid, taxis->calendar);
+      */
+    }
 
-              int ndims2 = ncvars[avarid2].ndims;
-              int dimid2 = ncvars[avarid2].dimids[0];
-              size_t dimlen2 = ncdims[dimid2].len;
+  if ( taxis->type == TAXIS_FORECAST )
+    {
+      int leadtimeid;
 
-              if ( (ndims2 == 2 && dimid == ncvars[avarid2].dimids[0] ) ||
-                   (ndims2 == 1 && dimlen == dimlen2-1 ) )
-                {
-                  double px = 1;
-                  if ( p0varid1 != -1 && p0varid1 == p0varid2 )
-                    cdf_get_var_double(ncid, p0varid2, &px);
+      cdf_def_var(fileID, "leadtime", NC_DOUBLE, 1, &time_dimid, &leadtimeid);
 
-                  double abuf[dimlen*2], bbuf[dimlen*2];
-                  cdf_get_var_double(ncid, avarid2, abuf);
-                  cdf_get_var_double(ncid, bvarid2, bbuf);
+      streamptr->basetime.leadtimeid = leadtimeid;
 
-                  size_t vctsize = (dimlen+1)*2;
-                  double *vct = (double *) Malloc(vctsize*sizeof(double));
-                  if ( ndims2 == 2 )
-                    {
-                      for ( size_t i = 0; i < dimlen; ++i )
-                        {
-                          vct[i] = abuf[i*2];
-                          vct[i+dimlen+1] = bbuf[i*2];
-                        }
-                      vct[dimlen]     = abuf[dimlen*2-1];
-                      vct[dimlen*2+1] = bbuf[dimlen*2-1];
-                    }
-                  else
-                    {
-                       for ( size_t i = 0; i < dimlen2; ++i )
-                        {
-                          vct[i] = abuf[i];
-                          vct[i+dimlen+1] = bbuf[i];
-                        }
-                    }
+      {
+        static const char stdname[] = "forecast_period";
+        cdf_put_att_text(fileID, leadtimeid, "standard_name", sizeof(stdname) - 1, stdname);
+      }
 
-                  if ( p0varid1 != -1 && IS_NOT_EQUAL(px, 1) )
-                    for ( size_t i = 0; i < dimlen+1; ++i ) vct[i] *= px;
+      {
+        static const char lname[] = "Time elapsed since the start of the forecast";
+        cdf_put_att_text(fileID, leadtimeid, "long_name", sizeof(lname) - 1, lname);
+      }
 
-                  ncvar->vct = vct;
-                  ncvar->vctsize = vctsize;
-                }
-            }
-        }
+      {
+          char unitstr[CDI_MAX_NAME];
+          cdfDefForecastTimeUnits(unitstr, taxis->fc_unit);
+          size_t len = strlen(unitstr);
+          if ( len )
+            cdf_put_att_text(fileID, leadtimeid, "units", len, unitstr);
+      }
     }
 
-  return status;
+  cdf_put_att_text(fileID, time_varid, "axis", 1, "T");
+
+  if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
 }
 
-static
-void cdf_set_cdi_attr(int ncid, int ncvarid, int attnum, int cdiID, int varID)
+
+void cdfDefTimestep(stream_t *streamptr, int tsID)
 {
-  nc_type atttype;
-  size_t attlen;
-  char attname[CDI_MAX_NAME];
+  int vlistID = streamptr->vlistID;
 
-  cdf_inq_attname(ncid, ncvarid, attnum, attname);
-  cdf_inq_attlen(ncid, ncvarid, attname, &attlen);
-  cdf_inq_atttype(ncid, ncvarid, attname, &atttype);
-  if ( xtypeIsInt(atttype) )
-    {
-      int attint[attlen];
-      cdfGetAttInt(ncid, ncvarid, attname, attlen, attint);
-      int datatype = (atttype == NC_SHORT)  ? CDI_DATATYPE_INT16 :
-                     (atttype == NC_BYTE)   ? CDI_DATATYPE_INT8 :
-#if  defined  (HAVE_NETCDF4)
-                     (atttype == NC_UBYTE)  ? CDI_DATATYPE_UINT8 :
-                     (atttype == NC_USHORT) ? CDI_DATATYPE_UINT16 :
-                     (atttype == NC_UINT)   ? CDI_DATATYPE_UINT32 :
-#endif
-                     CDI_DATATYPE_INT32;
-      cdiDefAttInt(cdiID, varID, attname, datatype, (int)attlen, attint);
-    }
-  else if ( xtypeIsFloat(atttype) )
-    {
-      double attflt[attlen];
-      cdfGetAttDouble(ncid, ncvarid, attname, attlen, attflt);
-      int datatype = (atttype == NC_FLOAT) ? CDI_DATATYPE_FLT32 : CDI_DATATYPE_FLT64;
-      cdiDefAttFlt(cdiID, varID, attname, datatype, (int)attlen, attflt);
-    }
-  else if ( xtypeIsText(atttype) )
-    {
-      char attstring[8192];
-      cdfGetAttText(ncid, ncvarid, attname, sizeof(attstring), attstring);
-      cdiDefAttTxt(cdiID, varID, attname, (int)attlen, attstring);
-    }
+  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
+
+  cdfDefTimeValue(streamptr, tsID);
 }
 
 static
-void cdf_print_vars(const ncvar_t *ncvars, int nvars, const char *oname)
+void cdfDefComplex(stream_t *streamptr, int gridID)
 {
-  char axis[7];
-  static const char iaxis[] = {'t', 'z', 'y', 'x'};
+  static const char axisname[] = "nc2";
+  int dimID = UNDEFID;
+  int vlistID = streamptr->vlistID;
+  int fileID  = streamptr->fileID;
 
-  fprintf(stderr, "%s:\n", oname);
+  int ngrids = vlistNgrids(vlistID);
 
-  for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
+  for ( int index = 0; index < ngrids; index++ )
     {
-      int ndim = 0;
-      if ( ncvars[ncvarid].isvar )
+      if ( streamptr->xdimID[index] != UNDEFID )
         {
-          axis[ndim++] = 'v';
-          axis[ndim++] = ':';
-          for ( int 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++] = '?';
+          int gridID0 = vlistGrid(vlistID, index);
+          int gridtype0 = gridInqType(gridID0);
+          if ( gridtype0 == GRID_SPECTRAL || gridtype0 == GRID_FOURIER )
+            {
+              dimID = streamptr->xdimID[index];
+              break;
             }
         }
-      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].isy    ) axis[ndim++] = iaxis[2];
-          else if ( ncvars[ncvarid].islon  ) axis[ndim++] = iaxis[3];
-          else if ( ncvars[ncvarid].isx    ) axis[ndim++] = iaxis[3];
-          else                               axis[ndim++] = '?';
-        }
+    }
 
-      axis[ndim++] = 0;
+  if ( dimID == UNDEFID )
+    {
+      size_t dimlen = 2;
 
-      fprintf(stderr, "%3d %3d  %-6s %s\n", ncvarid, ndim-3, axis, ncvars[ncvarid].name);
+      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;
 }
 
-static
-void cdf_scan_attr_axis(ncvar_t *ncvars, ncdim_t *ncdims, int ncvarid, const char *attstring, size_t attlen,
-                        int nvdims, int *dimidsp, const char *name)
+static void
+cdfDefSPorFC(stream_t *streamptr, int gridID,
+             char *restrict axisname, int gridRefType)
 {
-  int i;
-  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;
-        }
-    }
+  int index, iz = 0;
+  int dimID = UNDEFID;
 
-  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");
-              cdf_set_dim(ncvars, ncvarid, (int)attlen, T_AXIS);
-            }
-          else if ( (int) attstring[attlen] == 'z' )
-            {
-              ncvars[ncvarid].zdim = dimidsp[attlen];
-              cdf_set_dim(ncvars, ncvarid, (int)attlen, Z_AXIS);
+  int vlistID = streamptr->vlistID;
 
-              if ( ncvars[ncvarid].ndims == 1 )
-                {
-                  cdf_set_var(ncvars, ncvarid, FALSE);
-                  ncdims[ncvars[ncvarid].dimids[0]].dimtype = Z_AXIS;
-                }
-            }
-          else if ( (int) attstring[attlen] == 'y' )
-            {
-              ncvars[ncvarid].ydim = dimidsp[attlen];
-              cdf_set_dim(ncvars, ncvarid, (int)attlen, Y_AXIS);
+  int ngrids = vlistNgrids(vlistID);
 
-              if ( ncvars[ncvarid].ndims == 1 )
-                {
-                  cdf_set_var(ncvars, ncvarid, FALSE);
-                  ncdims[ncvars[ncvarid].dimids[0]].dimtype = Y_AXIS;
-                }
-            }
-          else if ( (int) attstring[attlen] == 'x' )
-            {
-              ncvars[ncvarid].xdim = dimidsp[attlen];
-              cdf_set_dim(ncvars, ncvarid, (int)attlen, X_AXIS);
+  size_t dimlen = (size_t)gridInqSize(gridID)/2;
 
-              if ( ncvars[ncvarid].ndims == 1 )
+  for ( index = 0; index < ngrids; index++ )
+    {
+      if ( streamptr->ydimID[index] != UNDEFID )
+        {
+          int gridID0 = vlistGrid(vlistID, index);
+          int gridtype0 = gridInqType(gridID0);
+          if ( gridtype0 == gridRefType )
+            {
+              size_t dimlen0 = (size_t)gridInqSize(gridID0)/2;
+              if ( dimlen == dimlen0 )
                 {
-                  cdf_set_var(ncvars, ncvarid, FALSE);
-                  ncdims[ncvars[ncvarid].dimids[0]].dimtype = X_AXIS;
+                  dimID = streamptr->ydimID[index];
+                  break;
                 }
+              else
+                iz++;
             }
         }
     }
-}
 
-static
-int cdf_get_cell_varid(char *attstring, int ncid)
-{
-  int nc_cell_id = CDI_UNDEFID;
-
-  char *pstring = attstring;
-  while ( isspace((int) *pstring) ) pstring++;
-  char *cell_measures = pstring;
-  while ( isalnum((int) *pstring) ) pstring++;
-  *pstring++ = 0;
-  while ( isspace((int) *pstring) ) pstring++;
-  char *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 ( str_is_equal(cell_measures, "area") )
+  if ( dimID == UNDEFID )
     {
-      int nc_var_id;
-      int status = nc_inq_varid(ncid, cell_var, &nc_var_id);
-      if ( status == NC_NOERR )
-        nc_cell_id = nc_var_id;
-      /*
-      else
-        Warning("%s - %s", nc_strerror(status), cell_var);
-      */
+      int fileID  = streamptr->fileID;
+      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;
     }
 
-  return nc_cell_id;
+  int gridindex = vlistGridIndex(vlistID, gridID);
+  streamptr->ydimID[gridindex] = dimID;
 }
 
 static
-void cdf_scan_var_attr(int nvars, ncvar_t *ncvars, ncdim_t *ncdims, int timedimid, int modelID, int format)
+void cdfDefSP(stream_t *streamptr, int gridID)
 {
-  int ncdimid;
-  int nvdims, nvatts;
-  int iatt;
-  nc_type xtype, atttype;
-  size_t attlen;
-  char name[CDI_MAX_NAME];
-  char attname[CDI_MAX_NAME];
-  char attstring[8192];
-
-  int nchecked_vars = 0;
-  enum { max_check_vars = 9 };
-  char *checked_vars[max_check_vars];
-  for ( int i = 0; i < max_check_vars; ++i ) checked_vars[i] = NULL;
+  /*
+  char longname[] = "Spherical harmonic coefficient";
+  */
+  char axisname[5] = "nspX";
+  cdfDefSPorFC(streamptr, gridID, axisname, GRID_SPECTRAL);
+}
 
-  for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
-    {
-      int ncid    = ncvars[ncvarid].ncid;
-      int *dimidsp = ncvars[ncvarid].dimids;
 
-      cdf_inq_var(ncid, ncvarid, name, &xtype, &nvdims, dimidsp, &nvatts);
-      strcpy(ncvars[ncvarid].name, name);
+static
+void cdfDefFC(stream_t *streamptr, int gridID)
+{
+  char axisname[5] = "nfcX";
+  cdfDefSPorFC(streamptr, gridID, axisname, GRID_FOURIER);
+}
 
-      for ( ncdimid = 0; ncdimid < nvdims; ncdimid++ )
-        ncvars[ncvarid].dimtype[ncdimid] = -1;
+static const struct cdfDefGridAxisInqs {
+  int (*axisSize)(int gridID);
+  void (*axisName)(int gridID, char *dimname);
+  const char *(*axisNamePtr)(int gridID);
+  void (*axisStdname)(int gridID, char *dimstdname);
+  void (*axisLongname)(int gridID, char *dimlongname);
+  void (*axisUnits)(int gridID, char *dimunits);
+  double (*axisVal)(int gridID, int index);
+  const double *(*axisValsPtr)(int gridID);
+  const double *(*axisBoundsPtr)(int gridID);
+} gridInqsX = {
+  .axisSize = gridInqXsize,
+  .axisName = gridInqXname,
+  .axisNamePtr = gridInqXnamePtr,
+  .axisStdname = gridInqXstdname,
+  .axisLongname = gridInqXlongname,
+  .axisUnits = gridInqXunits,
+  .axisVal = gridInqXval,
+  .axisValsPtr = gridInqXvalsPtr,
+  .axisBoundsPtr = gridInqXboundsPtr,
+}, gridInqsY = {
+  .axisSize = gridInqYsize,
+  .axisName = gridInqYname,
+  .axisNamePtr = gridInqYnamePtr,
+  .axisStdname = gridInqYstdname,
+  .axisLongname = gridInqYlongname,
+  .axisUnits = gridInqYunits,
+  .axisVal = gridInqYval,
+  .axisValsPtr = gridInqYvalsPtr,
+  .axisBoundsPtr = gridInqYboundsPtr,
+}, gridInqsZ = {
+  .axisStdname = zaxisInqStdname,
+  .axisLongname = zaxisInqLongname,
+  .axisUnits = zaxisInqUnits,
+};
 
-      ncvars[ncvarid].xtype = xtype;
-      ncvars[ncvarid].ndims = nvdims;
+static void
+cdfPutGridStdAtts(int fileID, int ncvarid,
+                  int gridID, const struct cdfDefGridAxisInqs *inqs)
+{
+  size_t len;
+  {
+    char stdname[CDI_MAX_NAME];
+    inqs->axisStdname(gridID, stdname);
+    if ( (len = strlen(stdname)) )
+      cdf_put_att_text(fileID, ncvarid, "standard_name", len, stdname);
+  }
+  {
+    char longname[CDI_MAX_NAME];
+    inqs->axisLongname(gridID, longname);
+    if ( (len = strlen(longname)) )
+      cdf_put_att_text(fileID, ncvarid, "long_name", len, longname);
+  }
+  {
+    char units[CDI_MAX_NAME];
+    inqs->axisUnits(gridID, units);
+    if ( (len = strlen(units)) )
+      cdf_put_att_text(fileID, ncvarid, "units", len, units);
+  }
+}
 
-#if  defined  (HAVE_NETCDF4)
-      if ( format == NC_FORMAT_NETCDF4_CLASSIC || format == NC_FORMAT_NETCDF4 )
-        {
-          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;
-          /*
-          size_t cache_size, nelems;
-          float preemption;
-          nc_get_chunk_cache(&cache_size, &nelems, &preemption);
-          printf("cache_size %lu nelems %lu preemption %g\n", cache_size, nelems, preemption);
-          nc_get_var_chunk_cache(ncid, ncvarid, &cache_size, &nelems, &preemption);
-          printf("varid %d cache_size %lu nelems %lu preemption %g\n", ncvarid, cache_size, nelems, preemption);
-          */
-          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, "%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");
-                    }
-                  {
-                    char *buf = ncvars[ncvarid].extra;
-                    size_t pos = strlen(buf);
-                    static const char prefix[] = "chunks=";
-                    memcpy(buf + pos, prefix, sizeof (prefix));
-                    pos += sizeof (prefix) - 1;
-                    for ( int i = nvdims-1; i >= 0; --i )
-                      {
-                        pos += (size_t)(sprintf(buf + pos, "%zu%s", chunks[i],
-                                                i > 0 ? "x" : ""));
-                      }
-                    buf[pos] = ' '; buf[pos + 1] = 0;
-                  }
-                }
-            }
-        }
-#endif
+static void
+cdfDefTrajLatLon(stream_t *streamptr, int gridID,
+                 const struct cdfDefGridAxisInqs *inqs,
+                 int *dimID, const char *sizeName)
+{
+  nc_type xtype = gridInqPrec(gridID) == DATATYPE_FLT32 ? NC_FLOAT : NC_DOUBLE;
 
-      if ( nvdims > 0 )
-        {
-          if ( timedimid == dimidsp[0] )
-            {
-              ncvars[ncvarid].tsteptype = TSTEP_INSTANT;
-              cdf_set_dim(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;
-                    }
-                }
-            }
-        }
+  int vlistID = streamptr->vlistID;
+  int dimlen = inqs->axisSize(gridID);
+  if ( dimlen != 1 )
+    Error("%s isn't 1 for %s grid!", sizeName, gridNamePtr(gridInqType(gridID)));
 
-      for ( iatt = 0; iatt < nvatts; iatt++ )
-        {
-          int nc_cell_id = CDI_UNDEFID;
+  int gridindex = vlistGridIndex(vlistID, gridID);
+  int ncvarid = dimID[gridindex];
 
-          cdf_inq_attname(ncid, ncvarid, iatt, attname);
-          cdf_inq_atttype(ncid, ncvarid, attname, &atttype);
-          cdf_inq_attlen(ncid, ncvarid, attname, &attlen);
+  if ( ncvarid == UNDEFID )
+    {
+      int dimNcID = streamptr->basetime.ncvarid;
+      int fileID  = streamptr->fileID;
+      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-          size_t attstringsize = sizeof(attstring);
-          bool isText = xtypeIsText(atttype);
-          bool isNumber = xtypeIsFloat(atttype) || xtypeIsInt(atttype);
-          if ( isText )
-            {
-              cdfGetAttText(ncid, ncvarid, attname, sizeof(attstring), attstring);
-              attstringsize = strlen(attstring) + 1;
-              if ( attstringsize > CDI_MAX_NAME ) attstringsize = CDI_MAX_NAME;
-            }
+      const char *axisname = inqs->axisNamePtr(gridID);
+      cdf_def_var(fileID, axisname, xtype, 1, &dimNcID, &ncvarid);
+      cdfPutGridStdAtts(fileID, ncvarid, gridID, inqs);
+      cdf_enddef(fileID);
+      streamptr->ncmode = 2;
+    }
 
-          if ( isText && strcmp(attname, "long_name") == 0 )
-            {
-              memcpy(ncvars[ncvarid].longname, attstring, attstringsize);
-            }
-          else if ( isText && strcmp(attname, "standard_name") == 0 )
-            {
-              memcpy(ncvars[ncvarid].stdname, attstring, attstringsize);
-            }
-          else if ( isText && strcmp(attname, "units") == 0 )
-            {
-              memcpy(ncvars[ncvarid].units, attstring, attstringsize);
-            }
-          else if ( strcmp(attname, "calendar") == 0 )
-            {
-              ncvars[ncvarid].calendar = true;
-            }
-          else if ( isText && strcmp(attname, "param") == 0 )
-            {
-	      int pnum = 0, pcat = 255, pdis = 255;
-	      sscanf(attstring, "%d.%d.%d", &pnum, &pcat, &pdis);
-	      ncvars[ncvarid].param = cdiEncodeParam(pnum, pcat, pdis);
-              cdf_set_var(ncvars, ncvarid, TRUE);
-            }
-          else if ( isNumber && strcmp(attname, "code") == 0 )
-            {
-              cdfGetAttInt(ncid, ncvarid, attname, 1, &ncvars[ncvarid].code);
-              cdf_set_var(ncvars, ncvarid, TRUE);
-            }
-          else if ( isNumber && strcmp(attname, "table") == 0 )
-            {
-              int tablenum;
-              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);
-                }
-              cdf_set_var(ncvars, ncvarid, TRUE);
-            }
-          else if ( isText && strcmp(attname, "trunc_type") == 0 )
-            {
-              if ( str_is_equal(attstring, "Triangular") )
-                ncvars[ncvarid].gridtype = GRID_SPECTRAL;
-            }
-          else if ( isText && (strcmp(attname, "grid_type") == 0 || strcmp(attname, "CDI_grid_type") == 0) )
-            {
-              str_tolower(attstring);
-              set_gridtype(attstring, &ncvars[ncvarid].gridtype);
-              cdf_set_var(ncvars, ncvarid, TRUE);
-            }
-          else if ( isText && strcmp(attname, "level_type") == 0 )
-            {
-              str_tolower(attstring);
-              set_zaxistype(attstring, &ncvars[ncvarid].zaxistype);
-              cdf_set_var(ncvars, ncvarid, TRUE);
-            }
-          else if ( isNumber && strcmp(attname, "trunc_count") == 0 )
-            {
-              cdfGetAttInt(ncid, ncvarid, attname, 1, &ncvars[ncvarid].truncation);
-            }
-          else if ( isNumber && strcmp(attname, "truncation") == 0 )
-            {
-              cdfGetAttInt(ncid, ncvarid, attname, 1, &ncvars[ncvarid].truncation);
-            }
-          else if ( isNumber && strcmp(attname, "number_of_grid_in_reference") == 0 )
-            {
-              cdfGetAttInt(ncid, ncvarid, attname, 1, &ncvars[ncvarid].position);
-            }
-          else if ( isNumber && strcmp(attname, "add_offset") == 0 )
-            {
-	      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) cdf_set_var(ncvars, ncvarid, TRUE); */
-            }
-          else if ( isNumber && strcmp(attname, "scale_factor") == 0 )
-            {
-	      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) cdf_set_var(ncvars, ncvarid, TRUE); */
-            }
-          else if ( isText && strcmp(attname, "climatology") == 0 )
-            {
-              int ncboundsid;
-              int status = nc_inq_varid(ncid, attstring, &ncboundsid);
-              if ( status == NC_NOERR )
-                {
-                  ncvars[ncvarid].climatology = true;
-                  ncvars[ncvarid].bounds = ncboundsid;
-                  cdf_set_var(ncvars, ncvars[ncvarid].bounds, FALSE);
-                  cdf_set_var(ncvars, ncvarid, FALSE);
-                }
-              else
-                Warning("%s - %s", nc_strerror(status), attstring);
-            }
-          else if ( isText && strcmp(attname, "bounds") == 0 )
-            {
-              int ncboundsid;
-              int status = nc_inq_varid(ncid, attstring, &ncboundsid);
-              if ( status == NC_NOERR )
-                {
-                  ncvars[ncvarid].bounds = ncboundsid;
-                  cdf_set_var(ncvars, ncvars[ncvarid].bounds, FALSE);
-                  cdf_set_var(ncvars, ncvarid, FALSE);
-                }
-              else
-                Warning("%s - %s", nc_strerror(status), attstring);
-            }
-          else if ( isText &&  strcmp(attname, "formula_terms") == 0 )
-            {
-              ncvars[ncvarid].lformulaterms = true;
-            }
-          else if ( isText && strcmp(attname, "cell_measures") == 0 && (nc_cell_id=cdf_get_cell_varid(attstring, ncid)) != CDI_UNDEFID )
-            {
-              ncvars[ncvarid].cellarea = nc_cell_id;
-              ncvars[nc_cell_id].isvar = FALSE;
-              cdf_set_var(ncvars, ncvarid, TRUE);
-            }
-          /*
-          else if ( strcmp(attname, "coordinates") == 0 )
-            {
-              char *pstring, *xvarname = NULL, *yvarname = NULL;
-              pstring = attstring;
+  dimID[gridindex] = ncvarid; /* var ID for trajectory !!! */
+}
 
-              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;
+static
+void cdfDefTrajLon(stream_t *streamptr, int gridID)
+{
+  cdfDefTrajLatLon(streamptr, gridID, &gridInqsX, streamptr->xdimID, "Xsize");
+}
 
-              cdf_inq_varid(ncid, xvarname, &ncvars[ncvarid].xvarid);
-              cdf_inq_varid(ncid, yvarname, &ncvars[ncvarid].yvarid);
 
-              cdf_set_var(ncvars, ncvars[ncvarid].xvarid, FALSE);
-              cdf_set_var(ncvars, ncvars[ncvarid].yvarid, FALSE);
-              cdf_set_var(ncvars, ncvarid, TRUE);
-            }
-          */
-          else if ( isText && (strcmp(attname, "associate")  == 0 || strcmp(attname, "coordinates") == 0) )
-            {
-              bool lstop = false;
-              char *pstring = attstring;
+static
+void cdfDefTrajLat(stream_t *streamptr, int gridID)
+{
+  cdfDefTrajLatLon(streamptr, gridID, &gridInqsY, streamptr->ydimID, "Ysize");
+}
 
-              for ( int i = 0; i < MAX_COORDVARS; i++ )
-                {
-                  while ( isspace((int) *pstring) ) pstring++;
-                  if ( *pstring == 0 ) break;
-                  char *varname = pstring;
-                  while ( !isspace((int) *pstring) && *pstring != 0 ) pstring++;
-                  if ( *pstring == 0 ) lstop = true;
-                  *pstring++ = 0;
+static
+int checkDimName(int fileID, size_t dimlen, char *dimname)
+{
+  /* check whether the dimenion name is already defined with the same length */
+  unsigned iz = 0;
+  int dimid = UNDEFID;
+  char name[CDI_MAX_NAME];
 
-                  int dimvarid;
-                  int status = nc_inq_varid(ncid, varname, &dimvarid);
-                  if ( status == NC_NOERR )
-                    {
-                      cdf_set_var(ncvars, dimvarid, FALSE);
-                      if ( !cdiIgnoreAttCoordinates )
-                        {
-                          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;
+  size_t len = strlen(dimname);
+  memcpy(name, dimname, len + 1);
 
-                      if ( k == nchecked_vars )
-                        {
-                          if ( nchecked_vars < max_check_vars ) checked_vars[nchecked_vars++] = strdup(varname);
-                          Warning("%s - %s", nc_strerror(status), varname);
-                        }
-                    }
+  do
+    {
+      if ( iz ) sprintf(name + len, "_%u", iz+1);
 
-                  if ( lstop ) break;
-                }
+      int dimid0, status = nc_inq_dimid(fileID, name, &dimid0);
+      if ( status != NC_NOERR )
+        break;
+      size_t dimlen0;
+      cdf_inq_dimlen(fileID, dimid0, &dimlen0);
+      if ( dimlen0 == dimlen )
+        {
+          dimid = dimid0;
+          break;
+        }
+      iz++;
+    }
+  while ( iz <= 99 );
 
-              cdf_set_var(ncvars, ncvarid, TRUE);
-            }
-          else if ( isText && strcmp(attname, "auxiliary_variable") == 0 )
-            {
-              bool lstop = false;
-              char *pstring = attstring;
 
-              for ( int i = 0; i < MAX_AUXVARS; i++ )
-                {
-                  while ( isspace((int) *pstring) ) pstring++;
-                  if ( *pstring == 0 ) break;
-                  char *varname = pstring;
-                  while ( !isspace((int) *pstring) && *pstring != 0 ) pstring++;
-                  if ( *pstring == 0 ) lstop = true;
-                  *pstring++ = 0;
+  if ( iz ) sprintf(dimname + len, "_%u", iz+1);
 
-                  int dimvarid;
-                  int status = nc_inq_varid(ncid, varname, &dimvarid);
-                  if ( status == NC_NOERR )
-                    {
-                      cdf_set_var(ncvars, dimvarid, FALSE);
-                      //  if ( !cdiIgnoreAttCoordinates )
-                        {
-                          ncvars[ncvarid].auxvarids[i] = dimvarid;
-                          ncvars[ncvarid].nauxvars++;
-                        }
-                    }
-                  else
-                    Warning("%s - %s", nc_strerror(status), varname);
+  return dimid;
+}
 
-                  if ( lstop ) break;
-                }
+static
+void checkGridName(char *axisname, int fileID, int vlistID, int gridID, int ngrids, int mode)
+{
+  int ncdimid;
+  char axisname2[CDI_MAX_NAME];
 
-              cdf_set_var(ncvars, ncvarid, TRUE);
-            }
-          else if ( isText && strcmp(attname, "grid_mapping") == 0 )
-            {
-              int nc_gmap_id;
-              int status = nc_inq_varid(ncid, attstring, &nc_gmap_id);
-              if ( status == NC_NOERR )
-                {
-                  ncvars[ncvarid].gmapid = nc_gmap_id;
-                  cdf_set_var(ncvars, ncvars[ncvarid].gmapid, FALSE);
-                }
-              else
-                Warning("%s - %s", nc_strerror(status), attstring);
+  /* check that the name is not already defined */
+  unsigned iz = 0;
 
-              cdf_set_var(ncvars, ncvarid, TRUE);
-            }
-          else if ( isText && strcmp(attname, "positive") == 0 )
-            {
-              str_tolower(attstring);
+  size_t axisnameLen = strlen(axisname);
+  memcpy(axisname2, axisname, axisnameLen + 1);
+  do
+    {
+      if ( iz ) sprintf(axisname2 + axisnameLen, "_%u", iz+1);
 
-              if      ( str_is_equal(attstring, "down") ) ncvars[ncvarid].positive = POSITIVE_DOWN;
-              else if ( str_is_equal(attstring, "up")   ) ncvars[ncvarid].positive = POSITIVE_UP;
+      int status = nc_inq_varid(fileID, axisname2, &ncdimid);
 
-              if ( ncvars[ncvarid].ndims == 1 )
-                {
-                  cdf_set_var(ncvars, ncvarid, FALSE);
-                  cdf_set_dim(ncvars, ncvarid, 0, Z_AXIS);
-                  ncdims[ncvars[ncvarid].dimids[0]].dimtype = Z_AXIS;
-                }
-            }
-          else if ( isNumber && strcmp(attname, "_FillValue") == 0 )
-            {
-	      cdfGetAttDouble(ncid, ncvarid, attname, 1, &ncvars[ncvarid].fillval);
-	      ncvars[ncvarid].deffillval = true;
-	      /* cdf_set_var(ncvars, ncvarid, TRUE); */
-            }
-          else if ( isNumber && strcmp(attname, "missing_value") == 0 )
-            {
-	      cdfGetAttDouble(ncid, ncvarid, attname, 1, &ncvars[ncvarid].missval);
-	      ncvars[ncvarid].defmissval = true;
-	      /* cdf_set_var(ncvars, ncvarid, TRUE); */
-            }
-          else if ( isNumber && strcmp(attname, "valid_range") == 0 && attlen == 2 )
-            {
-              if ( ncvars[ncvarid].lvalidrange == false )
-                {
-                  bool lignore = xtypeIsFloat(atttype) != xtypeIsFloat(xtype);
-                  if ( !cdiIgnoreValidRange && 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;
-                      /* cdf_set_var(ncvars, ncvarid, TRUE); */
-                    }
-                  else if ( lignore )
-                    {
-                      Warning("Inconsistent data type for attribute %s:valid_range, ignored!", name);
-                    }
-                }
-            }
-          else if ( isNumber && strcmp(attname, "valid_min") == 0 && attlen == 1 )
-            {
-              if ( ncvars[ncvarid].lvalidrange == false )
-                {
-                  bool lignore = xtypeIsFloat(atttype) != xtypeIsFloat(xtype);
-                  if ( !cdiIgnoreValidRange && 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 ( isNumber && strcmp(attname, "valid_max") == 0 && attlen == 1 )
+      if ( status != NC_NOERR )
+        {
+          if ( iz )
             {
-              if ( ncvars[ncvarid].lvalidrange == false )
+              /* check that the name does not exist for other grids */
+              for ( int index = 0; index < ngrids; index++ )
                 {
-                  bool lignore = xtypeIsFloat(atttype) != xtypeIsFloat(xtype);
-                  if ( !cdiIgnoreValidRange && lignore == false )
-                    {
-                      cdfGetAttDouble(ncid, ncvarid, attname, 1, &(ncvars[ncvarid].validrange)[1]);
-                      ncvars[ncvarid].lvalidrange = true;
-                    }
-                  else if ( lignore )
+                  int gridID0 = vlistGrid(vlistID, index);
+                  if ( gridID != gridID0 )
                     {
-                      Warning("Inconsistent data type for attribute %s:valid_max, ignored!", name);
+                       /* mode X or Y */
+                      const char *(*query)(int)
+                        = mode == 'X' ? gridInqXnamePtr : gridInqYnamePtr;
+                      const char *axisname0 = query(gridID0);
+                      if ( strcmp(axisname0, axisname2) == 0 ) goto nextSuffix;
                     }
                 }
             }
-          else if ( isText && strcmp(attname, "_Unsigned") == 0 )
-            {
-              str_tolower(attstring);
+          break;
+        }
+      nextSuffix:
+      ++iz;
+    }
+  while ( iz <= 99 );
 
-              if ( str_is_equal(attstring, "true") )
-                {
-                  ncvars[ncvarid].lunsigned = true;
-                  /*
-                  ncvars[ncvarid].lvalidrange = true;
-                  ncvars[ncvarid].validrange[0] = 0;
-                  ncvars[ncvarid].validrange[1] = 255;
-                  */
-                }
-	      /* cdf_set_var(ncvars, ncvarid, TRUE); */
-            }
-          else if ( isText && strcmp(attname, "cdi") == 0 )
-            {
-	      str_tolower(attstring);
 
-	      if ( str_is_equal(attstring, "ignore") )
-		{
-		  ncvars[ncvarid].ignore = true;
-		  cdf_set_var(ncvars, ncvarid, FALSE);
-		}
-            }
-          else if ( isText && strcmp(attname, "axis") == 0 )
-            {
-	      attlen = strlen(attstring);
+  if ( iz ) sprintf(axisname + axisnameLen, "_%u", iz+1);
+}
 
-	      if ( (int) attlen > nvdims && nvdims > 0 && attlen > 1 )
-		{
-		    Warning("Unexpected axis attribute length for %s, ignored!", name);
-		}
-              else if ( nvdims == 0 && attlen == 1 )
+static
+int checkZaxisName(char *axisname, int fileID, int vlistID, int zaxisID, int nzaxis)
+{
+  char axisname2[CDI_MAX_NAME];
+
+  /* check that the name is not already defined */
+  unsigned iz = 0;
+
+  size_t axisnameLen = strlen(axisname);
+  memcpy(axisname2, axisname, axisnameLen + 1);
+  do
+    {
+      if ( iz ) sprintf(axisname2 + axisnameLen, "_%u", iz+1);
+
+      int ncdimid, status = nc_inq_varid(fileID, axisname2, &ncdimid);
+
+      if ( status != NC_NOERR )
+        {
+          if ( iz )
+            {
+              /* check that the name does not exist for other zaxes */
+              for ( int index = 0; index < nzaxis; index++ )
                 {
-                  if ( attstring[0] == 'z' || attstring[0] == 'Z' )
+                  int zaxisID0 = vlistZaxis(vlistID, index);
+                  if ( zaxisID != zaxisID0 )
                     {
-                      cdf_set_var(ncvars, ncvarid, FALSE);
-                      ncvars[ncvarid].islev = true;
+                      const char *axisname0 = zaxisInqNamePtr(zaxisID0);
+                      if ( strcmp(axisname0, axisname2) == 0 ) goto nextSuffix;
                     }
                 }
-	      else
-		{
-		  str_tolower(attstring);
-                  cdf_scan_attr_axis(ncvars, ncdims, ncvarid, attstring, attlen, nvdims, dimidsp, name);
-		}
-	    }
-	  else if ( isNumber &&
-                    (strcmp(attname, "realization") == 0       ||
-                     strcmp(attname, "ensemble_members") == 0  ||
-                     strcmp(attname, "forecast_init_type") == 0) )
-	    {
-	      int temp;
-
-	      if( ncvars[ncvarid].ensdata == NULL )
-		ncvars[ncvarid].ensdata = (ensinfo_t *) Malloc( sizeof( ensinfo_t ) );
-
-	      cdfGetAttInt(ncid, ncvarid, attname, 1, &temp);
-
-	      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;
+            }
+          break;
+        }
+      nextSuffix:
+      ++iz;
+    }
+  while (iz <= 99);
 
-	      cdf_set_var(ncvars, ncvarid, TRUE);
-	    }
-	  else
-	    {
-	      if ( ncvars[ncvarid].natts == 0 )
-		ncvars[ncvarid].atts = (int*) Malloc((size_t)nvatts*sizeof(int));
 
-	      ncvars[ncvarid].atts[ncvars[ncvarid].natts++] = iatt;
-	      /*
-	      int attrint;
-	      double attrflt;
-	      nc_type atttype;
-	      cdf_inq_attlen(ncid, ncvarid, attname, &attlen);
-	      cdf_inq_atttype(ncid, ncvarid, attname, &atttype);
-	      if ( attlen == 1 && (atttype == NC_INT || atttype == NC_SHORT) )
-		{
-		  cdfGetAttInt(ncid, ncvarid, attname, 1, &attrint);
-		  printf("int: %s.%s = %d\n", ncvars[ncvarid].name, attname, attrint);
-		}
-	      else if ( attlen == 1 && (atttype == NC_FLOAT || atttype == NC_DOUBLE) )
-		{
-		  cdfGetAttDouble(ncid, ncvarid, attname, 1, &attrflt);
-		  printf("flt: %s.%s = %g\n", ncvars[ncvarid].name, attname, attrflt);
-		}
-	      else if ( atttype == NC_CHAR )
-		{
-		  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);
-              */
-	    }
-	}
-    }
+  if ( iz ) sprintf(axisname + axisnameLen, "_%u", iz+1);
 
-  for ( int i = 0; i < max_check_vars; ++i ) if ( checked_vars[i] ) Free(checked_vars[i]);
+  return (int)iz;
 }
 
-static
-void cdf_set_dimtype(int nvars, ncvar_t *ncvars, ncdim_t *ncdims)
-{
-  for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
-    {
-      if ( ncvars[ncvarid].isvar == TRUE )
-	{
-	  int ndims = ncvars[ncvarid].ndims;
-	  for ( int i = 0; i < ndims; i++ )
-	    {
-	      int ncdimid = ncvars[ncvarid].dimids[i];
-              int dimtype = ncdims[ncdimid].dimtype;
-	      if ( dimtype >= X_AXIS && dimtype <= T_AXIS )
-                cdf_set_dim(ncvars, ncvarid, i, dimtype);
-	    }
-
-	  if ( CDI_Debug )
-	    {
-	      Message("var %d %s", ncvarid, ncvars[ncvarid].name);
-	      for ( int i = 0; i < ndims; i++ )
-		printf("  dim%d type=%d  ", i, ncvars[ncvarid].dimtype[i]);
-	      printf("\n");
-	    }
-          }
-      }
+static void
+cdfDefAxisCommon(stream_t *streamptr, int gridID, int ndims,
+                 const struct cdfDefGridAxisInqs *gridAxisInq,
+                 int *axisDimIDs, int dimKey, char axisLetter,
+                 void (*finishCyclicBounds)(double *pbounds, size_t dimlen,
+                                            const double *pvals),
+                 int *ncAxisVarIDs)
+{
+  int dimID = UNDEFID;
+  int ngrids = 0;
+  int ncvarid = UNDEFID, ncbvarid = UNDEFID;
+  int nvdimID = UNDEFID;
+  nc_type xtype = gridInqPrec(gridID) == DATATYPE_FLT32 ? NC_FLOAT : NC_DOUBLE;
 
-  for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
-    {
-      if ( ncvars[ncvarid].isvar == TRUE )
-	{
-	  bool lxdim = false, lydim = false, lzdim = false/* , ltdim = false */;
-          int lcdim = 0;
-	  int ndims = ncvars[ncvarid].ndims;
-	  for ( int i = 0; i < ndims; i++ )
-	    {
-              int dimtype = ncvars[ncvarid].dimtype[i];
-              lxdim = lxdim | (dimtype == X_AXIS);
-	      lydim = lydim | (dimtype == Y_AXIS);
-	      lzdim = lzdim | (dimtype == Z_AXIS);
-              if ( ncvars[ncvarid].cvarids[i] != CDI_UNDEFID ) lcdim++;
-	      /* else if ( ncvars[ncvarid].dimtype[i] == T_AXIS ) ltdim = true; */
-	    }
+  int vlistID = streamptr->vlistID;
+  int fileID  = streamptr->fileID;
 
-          int allcdims = lcdim;
+  if ( ndims ) ngrids = vlistNgrids(vlistID);
 
-          if ( !lxdim && ncvars[ncvarid].xvarid != CDI_UNDEFID )
-            {
-              if ( ncvars[ncvars[ncvarid].xvarid].ndims == 0 ) lxdim = true;
-            }
+  size_t dimlen = (size_t)gridAxisInq->axisSize(gridID);
+  int gridindex = vlistGridIndex(vlistID, gridID);
 
-          if ( !lydim && ncvars[ncvarid].yvarid != CDI_UNDEFID )
-            {
-              if ( ncvars[ncvars[ncvarid].yvarid].ndims == 0 ) lydim = true;
-            }
+  const char *axisname = gridAxisInq->axisNamePtr(gridID);
+  size_t axisnameLen = strlen(axisname);
 
-          if ( lxdim && (lydim || ncvars[ncvarid].gridtype == GRID_UNSTRUCTURED) )
-            for ( int i = ndims-1; i >= 0; i-- )
-              {
-                if ( ncvars[ncvarid].dimtype[i] == -1 )
-                  {
-                    if ( !lzdim )
-                      {
-                        if ( lcdim )
-                          {
-                            int cdimvar = ncvars[ncvarid].cvarids[allcdims-lcdim];
-                            ncvars[ncvarid].zvarid = cdimvar;
-                            lcdim--;
-		            ncvars[cdimvar].zaxistype = ZAXIS_CHAR;
-                          }
-                        cdf_set_dim(ncvars, ncvarid, i, Z_AXIS);
-                        lzdim = true;
-                        int ncdimid = ncvars[ncvarid].dimids[i];
-                        if ( ncdims[ncdimid].dimtype == CDI_UNDEFID )
-                          ncdims[ncdimid].dimtype = Z_AXIS;
-                      }
-                  }
-              }
-	}
-    }
+  if ( axisname[0] == 0 ) Error("axis name undefined!");
 
-  for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
+  for ( int index = 0; index < ngrids; index++ )
     {
-      int ndims = ncvars[ncvarid].ndims;
-      for ( int i = 0; i < ndims; i++ )
+      if ( axisDimIDs[index] != UNDEFID )
         {
-          if ( ncvars[ncvarid].dimtype[i] == CDI_UNDEFID )
+          int gridID0 = vlistGrid(vlistID, index);
+          int gridtype0 = gridInqType(gridID0);
+          if ( gridtype0 == GRID_GAUSSIAN    ||
+               gridtype0 == GRID_LONLAT      ||
+               gridtype0 == GRID_CURVILINEAR ||
+               gridtype0 == GRID_GENERIC )
             {
-              int ncdimid = ncvars[ncvarid].dimids[i];
-              if ( ncdims[ncdimid].dimtype == Z_AXIS )
+              size_t dimlen0 = (size_t)gridAxisInq->axisSize(gridID0);
+              if ( dimlen == dimlen0 )
                 {
-                  ncvars[ncvarid].islev = true;
-                  cdf_set_dim(ncvars, ncvarid, i, Z_AXIS);
+                  double (*inqVal)(int gridID, int index)
+                    = gridAxisInq->axisVal;
+                  if ( IS_EQUAL(inqVal(gridID0, 0), inqVal(gridID, 0)) &&
+                       IS_EQUAL(inqVal(gridID0, (int)dimlen-1), inqVal(gridID, (int)dimlen-1)) )
+                  {
+                    dimID = axisDimIDs[index];
+                    break;
+                  }
                 }
             }
         }
     }
 
-  for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
+  if ( dimID == UNDEFID )
     {
-      if ( ncvars[ncvarid].isvar == TRUE )
-	{
-	  bool lxdim = false, lydim = false, lzdim = false/* , ltdim = false */;
-          int lcdim = 0;
-	  int ndims = ncvars[ncvarid].ndims;
-	  for ( int 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].cvarids[i] != CDI_UNDEFID ) lcdim++;
-	      /* else if ( ncvars[ncvarid].dimtype[i] == T_AXIS ) ltdim = true; */
-	    }
+      const double *pvals = gridAxisInq->axisValsPtr(gridID);
 
-          int allcdims = lcdim;
+      /* enough to append _ plus up to 100 decimal and trailing \0 */
+      char extendedAxisname[axisnameLen + 4 + 1];
+      memcpy(extendedAxisname, axisname, axisnameLen + 1);
+      checkGridName(extendedAxisname, fileID, vlistID, gridID, ngrids, axisLetter);
+      size_t extendedAxisnameLen
+        = axisnameLen + strlen(extendedAxisname + axisnameLen);
 
-          if ( !lxdim && ncvars[ncvarid].xvarid != CDI_UNDEFID )
-            {
-              if ( ncvars[ncvars[ncvarid].xvarid].ndims == 0 ) lxdim = true;
-            }
+      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-          if ( !lydim && ncvars[ncvarid].yvarid != CDI_UNDEFID )
-            {
-              if ( ncvars[ncvars[ncvarid].yvarid].ndims == 0 ) lydim = true;
-            }
+      if ( ndims )
+        {
+          char dimname[CDI_MAX_NAME+3];
+          dimname[0] = 0;
 
-          //   if ( ndims > 1 )
-            for ( int i = ndims-1; i >= 0; i-- )
-              {
-                if ( ncvars[ncvarid].dimtype[i] == -1 )
-                  {
-                    if ( !lxdim )
-                      {
-                        if ( lcdim && ncvars[ncvarid].xvarid == CDI_UNDEFID )
-                          {
-                            int cdimvar = ncvars[ncvarid].cvarids[allcdims-lcdim];
-                            ncvars[ncvarid].xvarid = cdimvar;
-                            lcdim--;
-                          }
-                        cdf_set_dim(ncvars, ncvarid, i, X_AXIS);
-                        lxdim = true;
-                      }
-                    else if ( !lydim && ncvars[ncvarid].gridtype != GRID_UNSTRUCTURED )
-                      {
-                        if ( lcdim && ncvars[ncvarid].yvarid == CDI_UNDEFID )
-                          {
-                            int cdimvar = ncvars[ncvarid].cvarids[allcdims-lcdim];
-                            ncvars[ncvarid].yvarid = cdimvar;
-                            lcdim--;
-                          }
-                        cdf_set_dim(ncvars, ncvarid, i, Y_AXIS);
-                        lydim = true;
-                      }
-                    else if ( !lzdim )
-                      {
-                        if ( lcdim > 0 )
-                          {
-                            int cdimvar = ncvars[ncvarid].cvarids[allcdims-lcdim];
-                            ncvars[ncvarid].zvarid = cdimvar;
-                            lcdim--;
-		            ncvars[cdimvar].zaxistype = ZAXIS_CHAR;
-                          }
-                        cdf_set_dim(ncvars, ncvarid, i, Z_AXIS);
-                        lzdim = true;
-                      }
-                  }
-              }
-	}
-    }
-}
+          if ( pvals == NULL )
+            cdiGridInqString(gridID, dimKey, CDI_MAX_NAME, dimname);
 
-/* verify coordinate vars - first scan (dimname == varname) */
-static
-void verify_coordinate_vars_1(int ncid, int ndims, ncdim_t *ncdims, ncvar_t *ncvars, int timedimid, bool *lhybrid_cf)
-{
-  for ( int ncdimid = 0; ncdimid < ndims; ncdimid++ )
-    {
-      int ncvarid = ncdims[ncdimid].ncvarid;
-      if ( ncvarid != -1 )
-	{
-	  if ( ncvars[ncvarid].dimids[0] == timedimid )
-	    {
-              ncvars[ncvarid].istime = true;
-	      ncdims[ncdimid].dimtype = T_AXIS;
-	      continue;
-	    }
+          if ( dimname[0] == 0 ) strcpy(dimname, extendedAxisname);
+          dimID = checkDimName(fileID, dimlen, dimname);
 
-          if ( isHybridSigmaPressureCoordinate(ncid, ncvarid, ncvars, ncdims) )
-            {
-              *lhybrid_cf = true;
-              continue;
-            }
+          if ( dimID == UNDEFID ) cdf_def_dim(fileID, dimname, dimlen, &dimID);
+        }
 
-	  if ( ncvars[ncvarid].units[0] != 0 )
-	    {
-	      if ( is_lon_axis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
-		{
-		  ncvars[ncvarid].islon = true;
-		  cdf_set_var(ncvars, ncvarid, FALSE);
-		  cdf_set_dim(ncvars, ncvarid, 0, X_AXIS);
-		  ncdims[ncdimid].dimtype = X_AXIS;
-		}
-	      else if ( is_lat_axis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
-		{
-		  ncvars[ncvarid].islat = true;
-		  cdf_set_var(ncvars, ncvarid, FALSE);
-		  cdf_set_dim(ncvars, ncvarid, 0, Y_AXIS);
-		  ncdims[ncdimid].dimtype = Y_AXIS;
-		}
-	      else if ( is_x_axis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
-		{
-		  ncvars[ncvarid].isx = true;
-		  cdf_set_var(ncvars, ncvarid, FALSE);
-		  cdf_set_dim(ncvars, ncvarid, 0, X_AXIS);
-		  ncdims[ncdimid].dimtype = X_AXIS;
-		}
-	      else if ( is_y_axis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
-		{
-		  ncvars[ncvarid].isy = true;
-		  cdf_set_var(ncvars, ncvarid, FALSE);
-		  cdf_set_dim(ncvars, ncvarid, 0, Y_AXIS);
-		  ncdims[ncdimid].dimtype = Y_AXIS;
-		}
-	      else if ( is_pressure_units(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 ( is_DBL_axis(ncvars[ncvarid].longname) )
-                {
-                  ncvars[ncvarid].zaxistype = ZAXIS_DEPTH_BELOW_LAND;
-		}
-	      else if ( is_height_units(ncvars[ncvarid].units) )
-		{
-		  if ( is_depth_axis(ncvars[ncvarid].stdname, ncvars[ncvarid].longname) )
-		    ncvars[ncvarid].zaxistype = ZAXIS_DEPTH_BELOW_SEA;
-		  else if ( is_height_axis(ncvars[ncvarid].stdname, ncvars[ncvarid].longname) )
-		    ncvars[ncvarid].zaxistype = ZAXIS_HEIGHT;
-		}
-	    }
-          else
-            {
-              if ( (strcmp(ncvars[ncvarid].longname, "generalized_height") == 0 ||
-                    strcmp(ncvars[ncvarid].longname, "generalized height") == 0) &&
-                   strcmp(ncvars[ncvarid].stdname, "height") == 0 )
-                  ncvars[ncvarid].zaxistype = ZAXIS_REFERENCE;
-            }
+      bool gen_bounds = false;
+      int grid_is_cyclic = gridIsCircular(gridID);
+      double *pbounds = NULL;
+      if ( pvals )
+        {
+          cdf_def_var(fileID, extendedAxisname, xtype, ndims, &dimID, &ncvarid);
 
-	  if ( !ncvars[ncvarid].islon && ncvars[ncvarid].longname[0] != 0 &&
-               !ncvars[ncvarid].islat && ncvars[ncvarid].longname[1] != 0 )
-	    {
-	      if ( str_is_equal(ncvars[ncvarid].longname+1, "ongitude") )
-		{
-		  ncvars[ncvarid].islon = true;
-		  cdf_set_var(ncvars, ncvarid, FALSE);
-		  cdf_set_dim(ncvars, ncvarid, 0, X_AXIS);
-		  ncdims[ncdimid].dimtype = X_AXIS;
-		  continue;
-		}
-	      else if ( str_is_equal(ncvars[ncvarid].longname+1, "atitude") )
-		{
-		  ncvars[ncvarid].islat = true;
-		  cdf_set_var(ncvars, ncvarid, FALSE);
-		  cdf_set_dim(ncvars, ncvarid, 0, Y_AXIS);
-		  ncdims[ncdimid].dimtype = Y_AXIS;
-		  continue;
-		}
-	    }
+          cdfPutGridStdAtts(fileID, ncvarid, gridID, gridAxisInq);
+          {
+            char axisStr[2] = { axisLetter, '\0' };
+            cdf_put_att_text(fileID, ncvarid, "axis", 1, axisStr);
+          }
 
-	  if ( ncvars[ncvarid].zaxistype != CDI_UNDEFID )
-	    {
-              ncvars[ncvarid].islev = true;
-	      cdf_set_var(ncvars, ncvarid, FALSE);
-	      cdf_set_dim(ncvars, ncvarid, 0, Z_AXIS);
-	      ncdims[ncdimid].dimtype = Z_AXIS;
-	    }
-	}
-    }
-}
+          pbounds = (double *)gridAxisInq->axisBoundsPtr(gridID);
 
-/* verify coordinate vars - second scan (all other variables) */
-static
-void verify_coordinate_vars_2(int nvars, ncvar_t *ncvars)
-{
-  for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
-    {
-      if ( ncvars[ncvarid].isvar == 0 )
-	{
-	  if ( ncvars[ncvarid].units[0] != 0 )
-	    {
-	      if ( is_lon_axis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
-		{
-		  ncvars[ncvarid].islon = true;
-		  continue;
-		}
-	      else if ( is_lat_axis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
-		{
-		  ncvars[ncvarid].islat = true;
-		  continue;
-		}
-	      else if ( is_x_axis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
-		{
-		  ncvars[ncvarid].isx = true;
-		  continue;
-		}
-	      else if ( is_y_axis(ncvars[ncvarid].units, ncvars[ncvarid].stdname) )
-		{
-		  ncvars[ncvarid].isy = true;
-		  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 ( ncvars[ncvarid].zaxistype == CDI_UNDEFID && is_pressure_units(ncvars[ncvarid].units) )
-		{
-		  ncvars[ncvarid].zaxistype = ZAXIS_PRESSURE;
-		  continue;
-		}
-	      else if ( is_DBL_axis(ncvars[ncvarid].longname) )
-		{
-                  ncvars[ncvarid].zaxistype = ZAXIS_DEPTH_BELOW_LAND;
-		  continue;
-		}
-	      else if ( is_height_units(ncvars[ncvarid].units) )
-		{
-		  if ( is_depth_axis(ncvars[ncvarid].stdname, ncvars[ncvarid].longname) )
-		    ncvars[ncvarid].zaxistype = ZAXIS_DEPTH_BELOW_SEA;
-		  else if ( is_height_axis(ncvars[ncvarid].stdname, ncvars[ncvarid].longname) )
-		    ncvars[ncvarid].zaxistype = ZAXIS_HEIGHT;
-		  continue;
-		}
+          if ( CDI_cmor_mode && grid_is_cyclic && !pbounds )
+            {
+              gen_bounds = true;
+              pbounds = (double*) Malloc(2*dimlen*sizeof(double));
+              for ( size_t i = 0; i < dimlen-1; ++i )
+                {
+                  pbounds[i*2+1]   = (pvals[i] + pvals[i+1])/2;
+                  pbounds[(i+1)*2] = (pvals[i] + pvals[i+1])/2;
+                }
+              finishCyclicBounds(pbounds, dimlen, pvals);
+            }
+          if ( pbounds )
+            {
+              size_t nvertex = 2;
+              if ( nc_inq_dimid(fileID, bndsName, &nvdimID) != NC_NOERR )
+                cdf_def_dim(fileID, bndsName, nvertex, &nvdimID);
             }
-          else if ( strcmp(ncvars[ncvarid].stdname, "region") == 0  ||
-                    strcmp(ncvars[ncvarid].stdname, "area_type") == 0 ||
-                    cdfInqDatatype(ncvars[ncvarid].xtype, ncvars[ncvarid].lunsigned) == CDI_DATATYPE_UINT8 )
+          if ( pbounds && nvdimID != UNDEFID )
             {
-              ncvars[ncvarid].isc = true;
+              char boundsname[extendedAxisnameLen + 1 + sizeof (bndsName)];
+              memcpy(boundsname, axisname, extendedAxisnameLen);
+              boundsname[extendedAxisnameLen] = '_';
+              memcpy(boundsname + extendedAxisnameLen + 1, bndsName, sizeof bndsName);
+              int dimIDs[2] = { dimID, nvdimID };
+              cdf_def_var(fileID, boundsname, xtype, 2, dimIDs, &ncbvarid);
+              cdf_put_att_text(fileID, ncvarid, "bounds", extendedAxisnameLen + sizeof (bndsName), boundsname);
             }
+        }
 
-	  /* not needed anymore for rotated grids */
-	  if ( !ncvars[ncvarid].islon && ncvars[ncvarid].longname[0] != 0 &&
-               !ncvars[ncvarid].islat && ncvars[ncvarid].longname[1] != 0 )
-	    {
-	      if ( str_is_equal(ncvars[ncvarid].longname+1, "ongitude") )
-		{
-		  ncvars[ncvarid].islon = true;
-		  continue;
-		}
-	      else if ( str_is_equal(ncvars[ncvarid].longname+1, "atitude") )
-		{
-		  ncvars[ncvarid].islat = true;
-		  continue;
-		}
-	    }
-	}
+      cdf_enddef(fileID);
+      streamptr->ncmode = 2;
+
+      if ( ncvarid  != UNDEFID ) cdf_put_var_double(fileID, ncvarid, pvals);
+      if ( ncbvarid != UNDEFID ) cdf_put_var_double(fileID, ncbvarid, pbounds);
+      if ( gen_bounds ) Free(pbounds);
+
+      if ( ndims == 0 ) ncAxisVarIDs[gridindex] = ncvarid;
     }
+
+  axisDimIDs[gridindex] = dimID;
 }
 
-static
-void grid_set_chunktype(grid_t *grid, ncvar_t *ncvar)
+static void
+finishCyclicXBounds(double *pbounds, size_t dimlen, const double *pvals)
 {
-  if ( ncvar->chunked )
-    {
-      int ndims = ncvar->ndims;
-
-      if ( grid->type == GRID_UNSTRUCTURED )
-        {
-          ncvar->chunktype = ncvar->chunks[ndims-1] == grid->size
-            ? CDI_CHUNK_GRID : CDI_CHUNK_AUTO;
-        }
-      else
-        {
-          if ( grid->x.size > 1 && grid->y.size > 1 && ndims > 1 &&
-               grid->x.size == ncvar->chunks[ndims-1] &&
-               grid->y.size == ncvar->chunks[ndims-2] )
-            ncvar->chunktype = CDI_CHUNK_GRID;
-          else if ( grid->x.size > 1 && grid->x.size == ncvar->chunks[ndims-1] )
-            ncvar->chunktype = CDI_CHUNK_LINES;
-          else
-            ncvar->chunktype = CDI_CHUNK_AUTO;
-        }
-    }
+  pbounds[0] = (pvals[0] + pvals[dimlen-1]-360)*0.5;
+  pbounds[2*dimlen-1] = (pvals[dimlen-1] + pvals[0]+360)*0.5;
 }
 
-/* define all input grids */
 static
-void cdf_load_vals(size_t size, int ndims, int varid, ncvar_t *ncvar, double **gridvals, struct xyValGet *valsGet,
-                   int ntdims, size_t *start, size_t *count)
-{
-  if ( CDI_netcdf_lazy_grid_load )
-    {
-      *valsGet = (struct xyValGet){
-        .scalefactor = ncvar->scalefactor,
-        .addoffset = ncvar->addoffset,
-        .start = { start[0], start[1], start[2] },
-        .count = { count[0], count[1], count[2] },
-        .size = size,
-        .datasetNCId = ncvar->ncid,
-        .varNCId = varid,
-        .ndims = (short)ndims,
-      };
-      *gridvals = cdfPendingLoad;
-    }
-  else
-    {
-      *gridvals = (double*) Malloc(size*sizeof(double));
-      if ( ntdims == 1 )
-        cdf_get_vara_double(ncvar->ncid, varid, start, count, *gridvals);
-      else
-        cdf_get_var_double(ncvar->ncid, varid, *gridvals);
-      cdf_scale_add(size, *gridvals, ncvar->addoffset, ncvar->scalefactor);
-    }
+void cdfDefXaxis(stream_t *streamptr, int gridID, int ndims)
+{
+  cdfDefAxisCommon(streamptr, gridID, ndims, &gridInqsX, streamptr->xdimID,
+                   CDI_GRID_XDIMNAME, 'X', finishCyclicXBounds,
+                   streamptr->ncxvarID);
 }
 
-static
-void cdf_load_cvals(size_t size, int varid, ncvar_t *ncvar, char ***gridvals, size_t dimlength)
+static void
+finishCyclicYBounds(double *pbounds, size_t dimlen, const double *pvals)
 {
-  size_t startc[] = {0, 0};
-  size_t countc[] = {1, size/dimlength};
-  *gridvals = (char **) Malloc(dimlength * sizeof(char *));
-  for ( size_t i = 0; i < dimlength; i++ )
-    {
-      (*gridvals)[i] = (char*) Malloc((size/dimlength) * sizeof(char));
-      cdf_get_vara_text(ncvar->ncid, varid, startc, countc, (*gridvals)[i]);
-      startc[0] = i+1;
-    }
+  pbounds[0] = copysign(90.0, pvals[0]);
+  pbounds[2*dimlen-1] = copysign(90.0, pvals[dimlen-1]);
 }
 
 static
-void cdf_load_bounds(size_t size, ncvar_t *ncvar, double **gridbounds, struct cdfLazyGridIds *cellBoundsGet)
+void cdfDefYaxis(stream_t *streamptr, int gridID, int ndims)
 {
-  if ( CDI_netcdf_lazy_grid_load )
-    {
-      cellBoundsGet->datasetNCId = ncvar->ncid;
-      cellBoundsGet->varNCId  = ncvar->bounds;
-      *gridbounds = cdfPendingLoad;
-    }
-  else
-    {
-      *gridbounds = (double*) Malloc(size*sizeof(double));
-      cdf_get_var_double(ncvar->ncid, ncvar->bounds, *gridbounds);
-    }
+  cdfDefAxisCommon(streamptr, gridID, ndims, &gridInqsY, streamptr->ydimID,
+                   CDI_GRID_YDIMNAME, 'Y', finishCyclicYBounds,
+                   streamptr->ncyvarID);
 }
 
 static
-void cdf_load_cellarea(size_t size, ncvar_t *ncvar, double **gridarea, struct cdfLazyGridIds *cellAreaGet)
+void cdfGridCompress(int fileID, int ncvarid, int gridsize, int filetype, int comptype)
 {
-  if ( CDI_netcdf_lazy_grid_load )
-    {
-      cellAreaGet->datasetNCId = ncvar->ncid;
-      cellAreaGet->varNCId = ncvar->cellarea;
-      *gridarea = cdfPendingLoad;
-    }
-  else
+#if  defined  (HAVE_NETCDF4)
+  if ( gridsize > 1 && comptype == COMPRESS_ZIP && (filetype == FILETYPE_NC4 || filetype == FILETYPE_NC4C) )
     {
-      *gridarea = (double*) Malloc(size*sizeof(double));
-      cdf_get_var_double(ncvar->ncid, ncvar->cellarea, *gridarea);
+      nc_def_var_chunking(fileID, ncvarid, NC_CHUNKED, NULL);
+      cdfDefVarDeflate(fileID, ncvarid, 1);
     }
+#endif
 }
 
 static
-void cdf_copy_axis_attr(ncvar_t *ncvar, struct gridaxis_t *gridaxis)
+void cdfDefCurvilinear(stream_t *streamptr, int gridID)
 {
-  strcpy(gridaxis->name, ncvar->name);
-  strcpy(gridaxis->longname, ncvar->longname);
-  strcpy(gridaxis->units, ncvar->units);
-  if ( gridaxis->cvals )
-    gridaxis->stdname = ncvar->stdname;
-}
+  int xdimID = UNDEFID;
+  int ydimID = UNDEFID;
+  int ncxvarid = UNDEFID, ncyvarid = UNDEFID;
+  int ncbxvarid = UNDEFID, ncbyvarid = UNDEFID, ncavarid = UNDEFID;
+  nc_type xtype = gridInqPrec(gridID) == DATATYPE_FLT32 ? NC_FLOAT : NC_DOUBLE;
 
-static
-int cdf_get_xydimid(int ndims, int *dimids, int *dimtype, int *xdimid, int *ydimid)
-{
-  int nxdims = 0, nydims = 0;
-  int xdimids[2] = {-1,-1}, ydimids[2] = {-1,-1};
+  int vlistID = streamptr->vlistID;
+  int fileID  = streamptr->fileID;
+
+  int ngrids = vlistNgrids(vlistID);
+
+  size_t dimlen = (size_t)gridInqSize(gridID);
+  size_t xdimlen = (size_t)gridInqXsize(gridID);
+  size_t ydimlen = (size_t)gridInqYsize(gridID);
+  int gridindex = vlistGridIndex(vlistID, gridID);
 
-  for ( int i = 0; i < ndims; i++ )
+  for ( int index = 0; index < ngrids; index++ )
     {
-      if ( dimtype[i] == X_AXIS && nxdims < 2 )
-        {
-          xdimids[nxdims] = dimids[i];
-          nxdims++;
-        }
-      else if ( dimtype[i] == Y_AXIS && nydims < 2 )
+      if ( streamptr->xdimID[index] != UNDEFID )
         {
-          ydimids[nydims] = dimids[i];
-          nydims++;
+          int gridID0 = vlistGrid(vlistID, index);
+          int gridtype0 = gridInqType(gridID0);
+          if ( gridtype0 == GRID_CURVILINEAR )
+            {
+              size_t dimlen0 = (size_t)gridInqSize(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)) &&
+                     IS_EQUAL(gridInqYval(gridID0, 0), gridInqYval(gridID, 0)) &&
+                     IS_EQUAL(gridInqYval(gridID0, (int)dimlen-1), gridInqYval(gridID, (int)dimlen-1)) )
+                  {
+                    xdimID = streamptr->xdimID[index];
+                    ydimID = streamptr->ydimID[index];
+                    ncxvarid = streamptr->ncxvarID[index];
+                    ncyvarid = streamptr->ncyvarID[index];
+                    break;
+                  }
+            }
         }
     }
 
-  if ( nxdims == 2 )
-    {
-      *xdimid = xdimids[1];
-      *ydimid = xdimids[0];
-    }
-  else if ( nydims == 2 )
-    {
-      *xdimid = ydimids[1];
-      *ydimid = ydimids[0];
-    }
-  else
+  if ( xdimID == UNDEFID || ydimID == UNDEFID )
     {
-      *xdimid = xdimids[0];
-      *ydimid = ydimids[0];
-    }
-
-  return nydims;
-}
+      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+      {
+        char xdimname[CDI_MAX_NAME+3];
+        xdimname[0] = 0;
+        cdiGridInqString(gridID, CDI_GRID_XDIMNAME, CDI_MAX_NAME, xdimname);
+        if ( xdimname[0] == 0 ) { xdimname[0] = 'x'; xdimname[1] = 0; }
+        xdimID = checkDimName(fileID, xdimlen, xdimname);
+        if ( xdimID == UNDEFID ) cdf_def_dim(fileID, xdimname, xdimlen, &xdimID);
+      }
+      {
+        char ydimname[CDI_MAX_NAME+3];
+        ydimname[0] = 0;
+        cdiGridInqString(gridID, CDI_GRID_YDIMNAME, CDI_MAX_NAME, ydimname);
+        if ( ydimname[0] == 0 ) { ydimname[0] = 'y'; ydimname[1] = 0; }
+        ydimID = checkDimName(fileID, ydimlen, ydimname);
+        if ( ydimID == UNDEFID ) cdf_def_dim(fileID, ydimname, ydimlen, &ydimID);
+      }
 
-static
-void cdf_check_gridtype(int *gridtype, bool islon, bool islat, size_t xsize, size_t ysize, grid_t *grid)
-{
-  if ( islat && (islon || xsize == 0) )
-    {
-      double yinc = 0;
-      if ( islon && (int) ysize > 1 )
+      int nvdimID = UNDEFID;
+      int dimIDs[3];
+      if ( gridInqXboundsPtr(gridID) || gridInqYboundsPtr(gridID) )
         {
-          yinc = fabs(grid->y.vals[0] - grid->y.vals[1]);
-          for ( size_t i = 2; i < ysize; i++ )
-            if ( (fabs(grid->y.vals[i-1] - grid->y.vals[i]) - yinc) > (yinc/1000) )
-              {
-                yinc = 0;
-                break;
-              }
+          char vdimname[CDI_MAX_NAME+3];
+          vdimname[0] = 0;
+          cdiGridInqString(gridID, CDI_GRID_VDIMNAME, CDI_MAX_NAME, vdimname);
+          if ( vdimname[0] == 0 ) strcpy(vdimname, "nv4");
+          size_t nvertex = 4;
+          nvdimID = checkDimName(fileID, nvertex, vdimname);
+          if ( nvdimID == UNDEFID ) cdf_def_dim(fileID, vdimname, nvertex, &nvdimID);
         }
-      if ( ysize < 10000 && isGaussGrid(ysize, yinc, grid->y.vals) )
+
+      dimIDs[0] = ydimID;
+      dimIDs[1] = xdimID;
+      dimIDs[2] = nvdimID;
+
+      if ( gridInqXvalsPtr(gridID) )
         {
-          *gridtype = GRID_GAUSSIAN;
-          grid->np = (int)(ysize/2);
-        }
-      else
-        *gridtype = GRID_LONLAT;
-    }
-  else if ( islon && !islat && ysize == 0 )
-    {
-      *gridtype = GRID_LONLAT;
-    }
-  else
-    *gridtype = GRID_GENERIC;
-}
+          char xaxisname[CDI_MAX_NAME];
+          gridInqXname(gridID, xaxisname);
+          checkGridName(xaxisname, fileID, vlistID, gridID, ngrids, 'X');
 
-static
-bool cdf_read_xcoord(struct cdfLazyGrid *restrict lazyGrid, ncdim_t *ncdims, ncvar_t *ncvar, int xvarid, ncvar_t *axisvar,
-                     size_t *xsize, size_t ysize, int ntdims, size_t *start, size_t *count, bool *islon)
-{
-  grid_t *grid = &lazyGrid->base;
-  bool skipvar = true;
-  *islon = axisvar->islon;
-  int ndims = axisvar->ndims;
-  size_t size = 0;
-  int prec = cdfInqDatatype(axisvar->xtype, axisvar->lunsigned);
+          cdf_def_var(fileID, xaxisname, xtype, 2, dimIDs, &ncxvarid);
+          cdfGridCompress(fileID, ncxvarid, (int)(xdimlen*ydimlen), streamptr->filetype, streamptr->comptype);
 
-  if ( (ndims - ntdims) == 2 )
-    {
-      /* Check size of 2 dimensional coordinate variables */
-      int dimid = axisvar->dimids[ndims-2];
-      size_t dimsize1 = ncdims[dimid].len;
-      dimid = axisvar->dimids[ndims-1];
-      size_t dimsize2 = ncdims[dimid].len;
+          cdfPutGridStdAtts(fileID, ncxvarid, gridID, &gridInqsX);
 
-      if ( prec == CDI_DATATYPE_UINT8 )
-        {
-          ncvar->gridtype = GRID_CHARXY;
-          size = dimsize1*dimsize2;
-          skipvar = dimsize1 != *xsize;
-        }
-      else
-        {
-          ncvar->gridtype = GRID_CURVILINEAR;
-          size = (*xsize)*ysize;
-          skipvar = dimsize1*dimsize2 != size;
-        }
-    }
-  else if ( (ndims - ntdims) == 1 )
-    {
-      size = *xsize;
-      /* Check size of 1 dimensional coordinate variables */
-      int dimid = axisvar->dimids[ndims-1];
-      size_t dimsize = ncdims[dimid].len;
-      skipvar = dimsize != size;
-    }
-  else if ( ndims == 0 && *xsize == 0 )
-    {
-      size = *xsize = 1;
-      skipvar = false;
-    }
+          /* attribute for Panoply */
+          cdf_put_att_text(fileID, ncxvarid, "_CoordinateAxisType", 3, "Lon");
 
-  if ( skipvar )
-    {
-      Warning("Unsupported array structure, skipped variable %s!", ncvar->name);
-      ncvar->isvar = -1;
-      return true;
-    }
+          if ( gridInqXboundsPtr(gridID) && nvdimID != UNDEFID )
+            {
+              size_t xaxisnameLen = strlen(xaxisname);
+              xaxisname[xaxisnameLen] = '_';
+              memcpy(xaxisname + xaxisnameLen + 1, bndsName, sizeof (bndsName));
+              cdf_def_var(fileID, xaxisname, xtype, 3, dimIDs, &ncbxvarid);
+              cdfGridCompress(fileID, ncbxvarid, (int)(xdimlen*ydimlen), streamptr->filetype, streamptr->comptype);
 
-  if ( prec != -1 )  grid->prec = prec;
+              cdf_put_att_text(fileID, ncxvarid, "bounds", xaxisnameLen + sizeof (bndsName), xaxisname);
+            }
+        }
 
-  if ( prec == CDI_DATATYPE_UINT8 && !CDI_netcdf_lazy_grid_load )
-    {
-      cdf_load_cvals(size, xvarid, axisvar, &grid->x.cvals, *xsize);
-      grid->x.clength = size / (*xsize) ;
-    }
-  else
-    cdf_load_vals(size, ndims, xvarid, axisvar, &grid->x.vals, &lazyGrid->xValsGet, ntdims, start, count);
+      if ( gridInqYvalsPtr(gridID) )
+        {
+          char yaxisname[CDI_MAX_NAME];
+          gridInqYname(gridID, yaxisname);
+          checkGridName(yaxisname, fileID, vlistID, gridID, ngrids, 'Y');
 
-  cdf_copy_axis_attr(axisvar, &grid->x);
+          cdf_def_var(fileID, yaxisname, xtype, 2, dimIDs, &ncyvarid);
+          cdfGridCompress(fileID, ncyvarid, (int)(xdimlen*ydimlen), streamptr->filetype, streamptr->comptype);
 
-  return false;
-}
+          cdfPutGridStdAtts(fileID, ncyvarid, gridID, &gridInqsY);
 
-static
-bool cdf_read_ycoord(struct cdfLazyGrid *restrict lazyGrid, ncdim_t *ncdims, ncvar_t *ncvar, int yvarid, ncvar_t *axisvar,
-                     size_t xsize, size_t *ysize, int ntdims, size_t *start, size_t *count, bool *islat)
-{
-  grid_t *grid = &lazyGrid->base;
-  bool skipvar = true;
-  *islat = axisvar->islat;
-  int ndims = axisvar->ndims;
-  size_t size = 0;
-  int prec = cdfInqDatatype(axisvar->xtype, axisvar->lunsigned);
+          /* attribute for Panoply */
+          cdf_put_att_text(fileID, ncyvarid, "_CoordinateAxisType", 3, "Lat");
 
-  if ( (ndims - ntdims) == 2 )
-    {
-      /* Check size of 2 dimensional coordinate variables */
-      int dimid = axisvar->dimids[ndims-2];
-      size_t dimsize1 = ncdims[dimid].len;
-      dimid = axisvar->dimids[ndims-1];
-      size_t dimsize2 = ncdims[dimid].len;
+          if ( gridInqYboundsPtr(gridID) && nvdimID != UNDEFID )
+            {
+              size_t yaxisnameLen = strlen(yaxisname);
+              yaxisname[yaxisnameLen] = '_';
+              memcpy(yaxisname + yaxisnameLen + 1, bndsName, sizeof (bndsName));
+              cdf_def_var(fileID, yaxisname, xtype, 3, dimIDs, &ncbyvarid);
+              cdfGridCompress(fileID, ncbyvarid, (int)(xdimlen*ydimlen), streamptr->filetype, streamptr->comptype);
 
-      if ( prec == CDI_DATATYPE_UINT8 )
-        {
-          ncvar->gridtype = GRID_CHARXY;
-          size = dimsize1*dimsize2;
-          skipvar = dimsize1 != *ysize;
+              cdf_put_att_text(fileID, ncyvarid, "bounds", yaxisnameLen + sizeof (bndsName), yaxisname);
+            }
         }
-      else
+
+      if ( gridInqAreaPtr(gridID) )
         {
-          ncvar->gridtype = GRID_CURVILINEAR;
-          size = xsize*(*ysize);
-          skipvar = dimsize1*dimsize2 != size;
-        }
-    }
-  else if ( (ndims - ntdims) == 1 )
-    {
-      if ( (int) *ysize == 0 ) size = xsize;
-      else                    size = *ysize;
+          static const char yaxisname_[] = "cell_area";
+          static const char units[] = "m2";
+          static const char longname[] = "area of grid cell";
+          static const char stdname[] = "cell_area";
 
-      int dimid = axisvar->dimids[ndims-1];
-      size_t dimsize = ncdims[dimid].len;
-      skipvar = dimsize != size;
-    }
-  else if ( ndims == 0 && *ysize == 0 )
-    {
-      size = *ysize = 1;
-      skipvar = false;
-    }
+          cdf_def_var(fileID, yaxisname_, xtype, 2, dimIDs, &ncavarid);
 
-  if ( skipvar )
-    {
-      Warning("Unsupported array structure, skipped variable %s!", ncvar->name);
-      ncvar->isvar = -1;
-      return true;
-    }
+          cdf_put_att_text(fileID, ncavarid, "standard_name", sizeof (stdname) - 1, stdname);
+          cdf_put_att_text(fileID, ncavarid, "long_name", sizeof (longname) - 1, longname);
+          cdf_put_att_text(fileID, ncavarid, "units", sizeof (units) - 1, units);
+        }
 
-  if ( prec != -1 )  grid->prec = prec;
+      cdf_enddef(fileID);
+      streamptr->ncmode = 2;
 
-  if ( prec == CDI_DATATYPE_UINT8 && !CDI_netcdf_lazy_grid_load )
-    {
-      cdf_load_cvals(size, yvarid, axisvar, &grid->y.cvals, *ysize);
-      grid->y.clength = size / (*ysize) ;
+      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));
     }
-  else
-    cdf_load_vals(size, ndims, yvarid, axisvar, &grid->y.vals, &lazyGrid->yValsGet, ntdims, start, count);
 
-  cdf_copy_axis_attr(axisvar, &grid->y);
-
-  return false;
+  streamptr->xdimID[gridindex] = xdimID;
+  streamptr->ydimID[gridindex] = ydimID;
+  streamptr->ncxvarID[gridindex] = ncxvarid;
+  streamptr->ncyvarID[gridindex] = ncyvarid;
+  streamptr->ncavarID[gridindex] = ncavarid;
 }
 
 static
-bool cdf_read_coordinates(struct cdfLazyGrid *restrict lazyGrid, ncvar_t *ncvar, ncvar_t *ncvars, ncdim_t *ncdims,
-                          int timedimid, int xvarid, int yvarid, size_t xsize, size_t ysize, int *vdimid)
+void cdfDefRgrid(stream_t *streamptr, int gridID)
 {
-  grid_t *grid = &lazyGrid->base;
-  size_t size = 0;
+  int dimID = UNDEFID;
 
-  grid->prec = CDI_DATATYPE_FLT64;
+  int vlistID = streamptr->vlistID;
+  int ngrids = vlistNgrids(vlistID);
 
-  if ( ncvar->gridtype == GRID_TRAJECTORY )
-    {
-      if ( ncvar->xvarid == CDI_UNDEFID ) Error("Longitude coordinate undefined for %s!", ncvar->name);
-      if ( ncvar->yvarid == CDI_UNDEFID ) Error("Latitude coordinate undefined for %s!", ncvar->name);
-    }
-  else
-    {
-      static bool ltwarn = true;
-      size_t start[3], count[3];
-      int ntdims = 0;
+  size_t dimlen = (size_t)gridInqSize(gridID);
 
-      if ( xvarid != CDI_UNDEFID && yvarid != CDI_UNDEFID )
+  int iz = 0;
+  for ( int index = 0; index < ngrids; index++ )
+    {
+      if ( streamptr->xdimID[index] != UNDEFID )
         {
-          int ndims = ncvars[xvarid].ndims;
-          if ( ndims != ncvars[yvarid].ndims && !ncvars[xvarid].isc && !ncvars[yvarid].isc )
-            {
-              Warning("Inconsistent grid structure for variable %s!", ncvar->name);
-              ncvar->xvarid = xvarid = CDI_UNDEFID;
-              ncvar->yvarid = yvarid = CDI_UNDEFID;
-            }
-          if ( ndims > 1 )
+          int gridID0 = vlistGrid(vlistID, index);
+          int gridtype0 = gridInqType(gridID0);
+          if ( gridtype0 == GRID_GAUSSIAN_REDUCED )
             {
-              if ( ndims <= 3 )
-                {
-                  if ( ncvars[xvarid].dimids[0] == timedimid && ncvars[yvarid].dimids[0] == timedimid )
-                    {
-                      size_t ntsteps = 0;
-                      cdf_inq_dimlen(ncvar->ncid, timedimid, &ntsteps);
-                      if ( ltwarn && ntsteps > 1 ) Warning("Time varying grids unsupported, using grid at time step 1!");
-                      ltwarn = false;
-                      ntdims = 1;
-                      start[0] = start[1] = start[2] = 0;
-                      count[0] = 1; count[1] = ysize; count[ndims-1] = xsize;
-                    }
-                }
-              else
+              size_t dimlen0 = (size_t)gridInqSize(gridID0);
+
+              if ( dimlen == dimlen0 )
                 {
-                  Warning("Unsupported grid structure for variable %s (grid dims > 2)!", ncvar->name);
-                  ncvar->xvarid = xvarid = CDI_UNDEFID;
-                  ncvar->yvarid = yvarid = CDI_UNDEFID;
+                  dimID = streamptr->xdimID[index];
+                  break;
                 }
+              iz++;
             }
         }
+    }
 
-      if ( xvarid != CDI_UNDEFID )
+  if ( dimID == UNDEFID )
+    {
+      int fileID  = streamptr->fileID;
+      static bool lwarn = true;
+      if ( lwarn )
         {
-          if ( (ncvars[xvarid].ndims - ntdims) > 2 )
-            {
-              Warning("Coordinate variable %s has to many dimensions (%d), skipped!", ncvars[xvarid].name, ncvars[xvarid].ndims);
-              //ncvar->xvarid = CDI_UNDEFID;
-              xvarid = CDI_UNDEFID;
-            }
+          Warning("Creating a NetCDF file with data on a gaussian reduced grid.");
+          Warning("The further processing of the resulting file is unsupported!");
+          lwarn = false;
         }
 
-      if ( yvarid != CDI_UNDEFID )
-        {
-          if ( (ncvars[yvarid].ndims - ntdims) > 2 )
-            {
-              Warning("Coordinate variable %s has to many dimensions (%d), skipped!", ncvars[yvarid].name, ncvars[yvarid].ndims);
-              //ncvar->yvarid = CDI_UNDEFID;
-              yvarid = CDI_UNDEFID;
-            }
-        }
+      char axisname[7] = "rgridX";
+      if ( iz == 0 ) axisname[5] = '\0';
+      else           sprintf(&axisname[5], "%1d", iz+1);
 
-      bool islon = false, islat = false;
+      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-      if ( xvarid != CDI_UNDEFID )
-        if ( cdf_read_xcoord(lazyGrid, ncdims, ncvar, xvarid, &ncvars[xvarid],
-                             &xsize, ysize, ntdims, start, count, &islon) )
-          return true;
+      cdf_def_dim(fileID, axisname, dimlen, &dimID);
 
-      if ( yvarid != CDI_UNDEFID )
-        if ( cdf_read_ycoord(lazyGrid, ncdims, ncvar, yvarid, &ncvars[yvarid],
-                             xsize, &ysize, ntdims, start, count, &islat) )
-          return true;
+      cdf_enddef(fileID);
+      streamptr->ncmode = 2;
+    }
 
-      if      ( (int) ysize == 0 ) size = xsize;
-      else if ( (int) xsize == 0 ) size = ysize;
-      else if ( ncvar->gridtype == GRID_UNSTRUCTURED ) size = xsize;
-      else                         size = xsize*ysize;
+  int gridindex = vlistGridIndex(vlistID, gridID);
+  streamptr->xdimID[gridindex] = dimID;
+}
 
-      if ( ncvar->gridtype == CDI_UNDEFID || ncvar->gridtype == GRID_GENERIC )
-        cdf_check_gridtype(&ncvar->gridtype, islon, islat, xsize, ysize, grid);
-    }
+static
+void cdfDefGdim(stream_t *streamptr, int gridID)
+{
+  int iz = 0;
+  int dimID = UNDEFID;
 
-  int gridtype = grid->type;
-  if ( gridtype != GRID_PROJECTION ) gridtype = ncvar->gridtype;
-  else if ( gridtype == GRID_PROJECTION && ncvar->gridtype == GRID_LONLAT )
-    {
-      int gmapvarid = ncvar->gmapid;
-      if ( gmapvarid != CDI_UNDEFID && cdfCheckAttText(ncvar->ncid, gmapvarid, "grid_mapping_name") )
-        {
-          char attstring[CDI_MAX_NAME];
-          cdfGetAttText(ncvar->ncid, gmapvarid, "grid_mapping_name", CDI_MAX_NAME, attstring);
-          if ( strcmp(attstring, "latitude_longitude") == 0 ) gridtype = ncvar->gridtype;
-        }
-    }
+  int vlistID = streamptr->vlistID;
+  int ngrids = vlistNgrids(vlistID);
 
-  switch (gridtype)
-    {
-    case GRID_GENERIC:
-    case GRID_LONLAT:
-    case GRID_GAUSSIAN:
-    case GRID_UNSTRUCTURED:
-    case GRID_CURVILINEAR:
-    case GRID_PROJECTION:
+  size_t dimlen = (size_t)gridInqSize(gridID);
+
+  if ( gridInqYsize(gridID) == 0 )
+    for ( int index = 0; index < ngrids; index++ )
       {
-        grid->size  = (int)size;
-        grid->x.size = (int)xsize;
-        grid->y.size = (int)ysize;
-        if ( xvarid != CDI_UNDEFID )
+        if ( streamptr->xdimID[index] != UNDEFID )
           {
-            grid->x.flag = 1;
-            int bvarid = ncvars[xvarid].bounds;
-            if ( bvarid != CDI_UNDEFID )
+            int gridID0 = vlistGrid(vlistID, index);
+            int gridtype0 = gridInqType(gridID0);
+            if ( gridtype0 == GRID_GENERIC )
               {
-                int nbdims = ncvars[bvarid].ndims;
-                if ( nbdims == 2 || nbdims == 3 )
+                size_t dimlen0 = (size_t)gridInqSize(gridID0);
+                if ( dimlen == dimlen0 )
                   {
-                    *vdimid = ncvars[bvarid].dimids[nbdims-1];
-                    grid->nvertex = (int)ncdims[*vdimid].len;
-                    cdf_load_bounds(size*(size_t)grid->nvertex, &ncvars[xvarid], &grid->x.bounds, &lazyGrid->xBoundsGet);
+                    dimID = streamptr->xdimID[index];
+                    break;
                   }
+                else
+                  iz++;
               }
           }
-        if ( yvarid != CDI_UNDEFID )
+      }
+
+  if ( gridInqXsize(gridID) == 0 )
+    for ( int index = 0; index < ngrids; index++ )
+      {
+        if ( streamptr->ydimID[index] != UNDEFID )
           {
-            grid->y.flag = 1;
-            int bvarid = ncvars[yvarid].bounds;
-            if ( bvarid != CDI_UNDEFID )
+            int gridID0 = vlistGrid(vlistID, index);
+            int gridtype0 = gridInqType(gridID0);
+            if ( gridtype0 == GRID_GENERIC )
               {
-                int nbdims = ncvars[bvarid].ndims;
-                if ( nbdims == 2 || nbdims == 3 )
+                size_t dimlen0 = (size_t)gridInqSize(gridID0);
+                if ( dimlen == dimlen0 )
                   {
-                    if ( *vdimid == CDI_UNDEFID )
-                      {
-                        *vdimid = ncvars[bvarid].dimids[nbdims-1];
-                        grid->nvertex = (int)ncdims[*vdimid].len;
-                      }
-                    cdf_load_bounds(size*(size_t)grid->nvertex, &ncvars[yvarid], &grid->y.bounds, &lazyGrid->yBoundsGet);
+                    dimID = streamptr->ydimID[index];
+                    break;
                   }
+                else
+                  iz++;
               }
           }
-
-        if ( ncvar->cellarea != CDI_UNDEFID )
-          cdf_load_cellarea(size, ncvar, &grid->area, &lazyGrid->cellAreaGet);
-
-        break;
-      }
-    case GRID_SPECTRAL:
-      {
-        grid->size = (int)size;
-        grid->lcomplex = 1;
-        grid->trunc = ncvar->truncation;
-        break;
       }
-    case GRID_FOURIER:
-      {
-        grid->size = (int)size;
-        grid->trunc = ncvar->truncation;
-        break;
-      }
-    case GRID_TRAJECTORY:
-      {
-        grid->size = 1;
-        break;
-      }
-    case GRID_CHARXY:
-      {
-        grid->size = (int)size;
-        grid->x.size = (int)xsize;
-        grid->y.size = (int)ysize;
-        break;
-      }
-    }
 
-  // if ( grid->type != GRID_PROJECTION && grid->type != ncvar->gridtype )
-  if ( grid->type != gridtype )
+  if ( dimID == UNDEFID )
     {
-      // int gridtype = ncvar->gridtype;
-      grid->type = gridtype;
-      cdiGridTypeInit(grid, gridtype, grid->size);
-    }
+      int fileID  = streamptr->fileID;
+      char dimname[CDI_MAX_NAME];
+      strcpy(dimname, "gsize");
 
-  if ( grid->size == 0 )
-    {
-      int ndims = ncvar->ndims;
-      int *dimtype = ncvar->dimtype;
-      if ( (ndims == 1 && dimtype[0] == T_AXIS) ||
-           (ndims == 1 && dimtype[0] == Z_AXIS) ||
-           (ndims == 2 && dimtype[0] == T_AXIS && dimtype[1] == Z_AXIS) )
-        {
-          grid->type  = GRID_GENERIC;
-          grid->size  = 1;
-          grid->x.size = 0;
-          grid->y.size = 0;
-        }
-      else
-        {
-          Warning("Unsupported grid, skipped variable %s!", ncvar->name);
-          ncvar->isvar = -1;
-          return true;
-        }
+      dimID = checkDimName(fileID, dimlen, dimname);
+
+      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+
+      if ( dimID == UNDEFID ) cdf_def_dim(fileID, dimname, dimlen, &dimID);
+
+      cdf_enddef(fileID);
+      streamptr->ncmode = 2;
     }
 
-  return false;
+  int gridindex = vlistGridIndex(vlistID, gridID);
+  streamptr->xdimID[gridindex] = dimID;
 }
 
 static
-bool cdf_set_unstructured_par(ncvar_t *ncvar, grid_t *grid, int *xdimid, int *ydimid, int number_of_grid_used, unsigned char *uuidOfHGrid)
+void cdfDefGridReference(stream_t *streamptr, int gridID)
 {
-  int ndims = ncvar->ndims;
-  int *dimtype = ncvar->dimtype;
-
-  int zdimid = CDI_UNDEFID;
-  int xdimidx = CDI_UNDEFID, ydimidx = CDI_UNDEFID;
+  int fileID  = streamptr->fileID;
+  int number = gridInqNumber(gridID);
 
-  for ( int i = 0; i < ndims; i++ )
+  if ( number > 0 )
     {
-      if      ( dimtype[i] == X_AXIS ) xdimidx = i;
-      else if ( dimtype[i] == Y_AXIS ) ydimidx = i;
-      else if ( dimtype[i] == Z_AXIS ) zdimid = ncvar->dimids[i];
+      cdf_put_att_int(fileID, NC_GLOBAL, "number_of_grid_used", NC_INT, 1, &number);
     }
 
-  if ( *xdimid != CDI_UNDEFID && *ydimid != CDI_UNDEFID && zdimid == CDI_UNDEFID )
+  const char *gridfile = gridInqReferencePtr(gridID);
+  if ( gridfile && gridfile[0] != 0 )
+    cdf_put_att_text(fileID, NC_GLOBAL, "grid_file_uri", strlen(gridfile), gridfile);
+}
+
+static
+void cdfDefGridUUID(stream_t *streamptr, int gridID)
+{
+  unsigned char uuidOfHGrid[CDI_UUID_SIZE];
+
+  gridInqUUID(gridID, uuidOfHGrid);
+  if ( !cdiUUIDIsNull(uuidOfHGrid) )
     {
-      if ( grid->x.size > grid->y.size && grid->y.size < 1000 )
-        {
-          dimtype[ydimidx] = Z_AXIS;
-          *ydimid = CDI_UNDEFID;
-          grid->size  = grid->x.size;
-          grid->y.size = 0;
-        }
-      else if ( grid->y.size > grid->x.size && grid->x.size < 1000 )
+      char uuidOfHGridStr[37];
+      cdiUUID2Str(uuidOfHGrid, uuidOfHGridStr);
+      if ( uuidOfHGridStr[0] != 0 && strlen(uuidOfHGridStr) == 36 )
         {
-          dimtype[xdimidx] = Z_AXIS;
-          *xdimid = *ydimid;
-          *ydimid = CDI_UNDEFID;
-          grid->size  = grid->y.size;
-          grid->x.size = grid->y.size;
-          grid->y.size = 0;
+          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 ( grid->size != grid->x.size )
-    {
-      Warning("Unsupported array structure, skipped variable %s!", ncvar->name);
-      ncvar->isvar = -1;
-      return true;
-    }
-
-  if ( number_of_grid_used != CDI_UNDEFID ) grid->number = number_of_grid_used;
-  if ( ncvar->position > 0 ) grid->position = ncvar->position;
-  if ( uuidOfHGrid[0] != 0 ) memcpy(grid->uuid, uuidOfHGrid, 16);
-
-  return false;
 }
 
 static
-void cdf_read_mapping_atts(int ncid, int gmapvarid, int projID, const char *varname)
+void cdfDefZaxisUUID(stream_t *streamptr, int zaxisID)
 {
-  if ( cdfCheckAttText(ncid, gmapvarid, "grid_mapping_name") )
-    {
-      char attstring[CDI_MAX_NAME];
-      cdfGetAttText(ncid, gmapvarid, "grid_mapping_name", CDI_MAX_NAME, attstring);
-      cdiGridDefKeyStr(projID, CDI_KEY_MAPNAME, (int)(strlen(attstring)+1), attstring);
-    }
-  else
+  unsigned char uuidOfVGrid[CDI_UUID_SIZE];
+  zaxisInqUUID(zaxisID, uuidOfVGrid);
+
+  if ( uuidOfVGrid[0] != 0 )
     {
-      Warning("Text attribute %s:grid_mapping_name missing!", varname);
+      char uuidOfVGridStr[37];
+      cdiUUID2Str(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);
+        }
     }
-
-  int nvatts;
-  cdf_inq_varnatts(ncid, gmapvarid, &nvatts);
-  for ( int attnum = 0; attnum < nvatts; ++attnum )
-    cdf_set_cdi_attr(ncid, gmapvarid, attnum, projID, CDI_GLOBAL);
 }
 
 static
-void cdf_set_grid_to_similar_vars(ncvar_t *ncvar1, ncvar_t *ncvar2, int gridtype, int xdimid, int ydimid)
+void cdfDefUnstructured(stream_t *streamptr, int gridID)
 {
-  if ( ncvar2->isvar == TRUE && ncvar2->gridID == CDI_UNDEFID )
-    {
-      int xdimid2 = CDI_UNDEFID, ydimid2 = CDI_UNDEFID, zdimid2 = CDI_UNDEFID;
-      int xdimidx = CDI_UNDEFID, ydimidx = CDI_UNDEFID;
-      int ndims2 = ncvar2->ndims;
-
-      int *dimtype2 = ncvar2->dimtype;
-      int *dimids2 = ncvar2->dimids;
-      for ( int i = 0; i < ndims2; i++ )
-        {
-          if      ( dimtype2[i] == X_AXIS ) { xdimid2 = dimids2[i]; xdimidx = i; }
-          else if ( dimtype2[i] == Y_AXIS ) { ydimid2 = dimids2[i]; ydimidx = i; }
-          else if ( dimtype2[i] == Z_AXIS ) { zdimid2 = dimids2[i]; }
-        }
+  int dimID = UNDEFID;
+  int ncxvarid = UNDEFID, ncyvarid = UNDEFID;
+  int ncbxvarid = UNDEFID, ncbyvarid = UNDEFID, ncavarid = UNDEFID;
+  int nvdimID = UNDEFID;
+  nc_type xtype = NC_DOUBLE;
 
-      if ( ncvar2->gridtype == CDI_UNDEFID && gridtype == GRID_UNSTRUCTURED )
-        {
-          if ( xdimid == xdimid2 && ydimid2 != CDI_UNDEFID && zdimid2 == CDI_UNDEFID )
-            {
-              ncvar2->dimtype[ydimidx] = Z_AXIS;
-              ydimid2 = CDI_UNDEFID;
-            }
+  if ( gridInqPrec(gridID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
 
-          if ( xdimid == ydimid2 && xdimid2 != CDI_UNDEFID && zdimid2 == CDI_UNDEFID )
-            {
-              ncvar2->dimtype[xdimidx] = Z_AXIS;
-              xdimid2 = ydimid2;
-              ydimid2 = CDI_UNDEFID;
-            }
-        }
+  int vlistID = streamptr->vlistID;
+  int fileID  = streamptr->fileID;
 
-      if ( xdimid == xdimid2 && (ydimid == ydimid2 || (xdimid == ydimid && ydimid2 == CDI_UNDEFID)) )
-        {
-          bool same_grid = ncvar1->xvarid == ncvar2->xvarid
-                        && ncvar1->yvarid == ncvar2->yvarid
-                        && ncvar1->position == ncvar2->position;
-          /*
-            if ( xvarid != -1 && ncvar2->xvarid != CDI_UNDEFID &&
-            xvarid != ncvar2->xvarid ) same_grid = false;
+  int ngrids = vlistNgrids(vlistID);
 
-            if ( yvarid != -1 && ncvar2->yvarid != CDI_UNDEFID &&
-            yvarid != ncvar2->yvarid ) same_grid = false;
-          */
+  size_t dimlen = (size_t)gridInqSize(gridID);
+  int gridindex = vlistGridIndex(vlistID, gridID);
 
-          if ( same_grid )
+  for ( int index = 0; index < ngrids; index++ )
+    {
+      if ( streamptr->xdimID[index] != UNDEFID )
+        {
+          int gridID0 = vlistGrid(vlistID, index);
+          int gridtype0 = gridInqType(gridID0);
+          if ( gridtype0 == GRID_UNSTRUCTURED )
             {
-              if ( CDI_Debug ) Message("Same gridID %d %s", ncvar1->gridID, ncvar2->name);
-              ncvar2->gridID = ncvar1->gridID;
-              ncvar2->chunktype = ncvar1->chunktype;
+              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)) &&
+		     IS_EQUAL(gridInqYval(gridID0, 0), gridInqYval(gridID, 0)) &&
+                     IS_EQUAL(gridInqYval(gridID0, (int)dimlen-1), gridInqYval(gridID, (int)dimlen-1)) )
+		  {
+		    dimID = streamptr->xdimID[index];
+                    ncxvarid = streamptr->ncxvarID[index];
+                    ncyvarid = streamptr->ncyvarID[index];
+                    ncavarid = streamptr->ncavarID[index];
+		    break;
+		  }
             }
         }
     }
-}
 
-static
-int cdf_define_all_grids(ncgrid_t *ncgrid, int vlistID, ncdim_t *ncdims, int nvars, ncvar_t *ncvars,
-                         int timedimid, unsigned char *uuidOfHGrid, char *gridfile, int number_of_grid_used)
-{
-  for ( int ncvarid = 0; ncvarid < nvars; ++ncvarid )
+  if ( dimID == UNDEFID )
     {
-      ncvar_t *ncvar = &ncvars[ncvarid];
-      if ( ncvar->isvar && ncvar->gridID == CDI_UNDEFID )
-	{
-          int ndims = ncvar->ndims;
-          int *dimtype = ncvar->dimtype;
-          int vdimid = CDI_UNDEFID;
-          struct addIfNewRes projAdded = { .Id = CDI_UNDEFID, .isNew = 0 },
-                             gridAdded = { .Id = CDI_UNDEFID, .isNew = 0 };
-	  int xdimid = CDI_UNDEFID, ydimid = CDI_UNDEFID;
-          int nydims = cdf_get_xydimid(ndims, ncvar->dimids, dimtype, &xdimid, &ydimid);
-
-          int xaxisid = (xdimid != CDI_UNDEFID) ? ncdims[xdimid].ncvarid : CDI_UNDEFID;
-          int yaxisid = (ydimid != CDI_UNDEFID) ? ncdims[ydimid].ncvarid : CDI_UNDEFID;
-          int xvarid = (ncvar->xvarid != CDI_UNDEFID) ? ncvar->xvarid : xaxisid;
-          int yvarid = (ncvar->yvarid != CDI_UNDEFID) ? ncvar->yvarid : yaxisid;
-
-	  size_t xsize = (xdimid != CDI_UNDEFID) ? ncdims[xdimid].len : 0;
-	  size_t ysize = (ydimid != CDI_UNDEFID) ? ncdims[ydimid].len : 0;
-
-	  if ( ydimid == CDI_UNDEFID && yvarid != CDI_UNDEFID )
-	    {
-	      if ( ncvars[yvarid].ndims == 1 )
-		{
-		  ydimid = ncvars[yvarid].dimids[0];
-		  ysize  = ncdims[ydimid].len;
-		}
-	    }
-
-          if ( xsize > INT_MAX )
-            {
-              Warning("Size limit exceeded for x-axis dimension (limit=%d)!", INT_MAX);
-              return CDI_EDIMSIZE;
-            }
-          if ( ysize > INT_MAX )
-            {
-              Warning("Size limit exceeded for y-axis dimension (limit=%d)!", INT_MAX);
-              return CDI_EDIMSIZE;
-            }
-
-          int gmapvarid = ncvar->gmapid;
-          bool lproj = gmapvarid != CDI_UNDEFID;
-
-          if ( !lproj && xaxisid != CDI_UNDEFID && xaxisid != xvarid && yaxisid != CDI_UNDEFID && yaxisid != yvarid )
-            {
-              lproj = true;
-            }
-
-          bool lgrid = !(lproj && ncvar->xvarid == CDI_UNDEFID);
-
-          bool lunstructured = xdimid != CDI_UNDEFID && xdimid == ydimid && nydims == 0;
-	  if ( (ncvar->gridtype == CDI_UNDEFID || ncvar->gridtype == GRID_GENERIC) && lunstructured )
-            ncvar->gridtype = GRID_UNSTRUCTURED;
-
-          struct cdfLazyGrid *restrict lazyGrid = NULL, *restrict lazyProj = NULL;
-
-          {
-            int gridtype = !lgrid ? GRID_PROJECTION : ncvar->gridtype;
-            if ( CDI_netcdf_lazy_grid_load )
-              {
-                cdfLazyGridRenew(&lazyGrid, gridtype);
-                if ( lgrid && lproj ) cdfLazyGridRenew(&lazyProj, GRID_PROJECTION);
-              }
-            else
-              {
-                cdfBaseGridRenew(&lazyGrid, gridtype);
-                if ( lgrid && lproj ) cdfBaseGridRenew(&lazyProj, GRID_PROJECTION);
-              }
-          }
-          grid_t *grid = &lazyGrid->base;
-          grid_t *proj = ( lgrid && lproj ) ? &lazyProj->base : NULL;
+      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+      {
+        char xdimname[CDI_MAX_NAME+3];
+        xdimname[0] = 0;
+        cdiGridInqString(gridID, CDI_GRID_XDIMNAME, CDI_MAX_NAME, xdimname);
+        if ( xdimname[0] == 0 ) strcpy(xdimname, "ncells");
+        dimID = checkDimName(fileID, dimlen, xdimname);
+        if ( dimID == UNDEFID ) cdf_def_dim(fileID, xdimname, dimlen, &dimID);
+      }
 
-          xaxisid = (xdimid != CDI_UNDEFID) ? ncdims[xdimid].ncvarid : CDI_UNDEFID;
-          yaxisid = (ydimid != CDI_UNDEFID) ? ncdims[ydimid].ncvarid : CDI_UNDEFID;
+      size_t nvertex = (size_t)gridInqNvertex(gridID);
+      if ( nvertex > 0 )
+        {
+          char vdimname[CDI_MAX_NAME+3];
+          vdimname[0] = 0;
+          cdiGridInqString(gridID, CDI_GRID_VDIMNAME, CDI_MAX_NAME, vdimname);
+          if ( vdimname[0] == 0 ) strcpy(vdimname, "vertices");
+          nvdimID = checkDimName(fileID, nvertex, vdimname);
+          if ( nvdimID == UNDEFID ) cdf_def_dim(fileID, vdimname, nvertex, &nvdimID);
+        }
 
+      cdfDefGridReference(streamptr, gridID);
 
-          if ( cdf_read_coordinates(lazyGrid, ncvar, ncvars, ncdims,
-                                    timedimid, xvarid, yvarid, xsize, ysize, &vdimid) )
-            continue;
+      cdfDefGridUUID(streamptr, gridID);
 
-	  if ( number_of_grid_used != CDI_UNDEFID &&
-               (grid->type == CDI_UNDEFID || grid->type == GRID_GENERIC) &&
-               xdimid != CDI_UNDEFID && xsize > 9999 )
-            grid->type = GRID_UNSTRUCTURED;
+      if ( gridInqXvalsPtr(gridID) )
+        {
+          char xaxisname[CDI_MAX_NAME];
+          gridInqXname(gridID, xaxisname);
+          checkGridName(xaxisname, fileID, vlistID, gridID, ngrids, 'X');
+          cdf_def_var(fileID, xaxisname, xtype, 1, &dimID, &ncxvarid);
+          cdfGridCompress(fileID, ncxvarid, (int)dimlen, streamptr->filetype, streamptr->comptype);
 
-          if ( grid->type == GRID_UNSTRUCTURED )
-            if ( cdf_set_unstructured_par(ncvar, grid, &xdimid, &ydimid, number_of_grid_used, uuidOfHGrid) )
-              continue;
+          cdfPutGridStdAtts(fileID, ncxvarid, gridID, &gridInqsX);
 
-          if ( lproj && lgrid )
+          if ( gridInqXboundsPtr(gridID) && nvdimID != UNDEFID )
             {
-              int dumid;
-              cdf_read_coordinates(lazyProj, ncvar, ncvars, ncdims, timedimid,
-                                   xaxisid, yaxisid, xsize, ysize, &dumid);
-	    }
-
-	  if ( CDI_Debug )
-	    {
-	      Message("grid: type = %d, size = %d, nx = %d, ny %d",
-		      grid->type, grid->size, grid->x.size, grid->y.size);
-              if ( proj )
-                Message("proj: type = %d, size = %d, nx = %d, ny %d",
-                        proj->type, proj->size, proj->x.size, proj->y.size);
-	    }
-
+              int dimIDs[2] = { dimID, nvdimID };
+              size_t xaxisnameLen = strlen(xaxisname);
+              xaxisname[xaxisnameLen] = '_';
+              memcpy(xaxisname + xaxisnameLen + 1, bndsName, sizeof (bndsName));
+              cdf_def_var(fileID, xaxisname, xtype, 2, dimIDs, &ncbxvarid);
+              cdfGridCompress(fileID, ncbxvarid, (int)dimlen, streamptr->filetype, streamptr->comptype);
 
-          if ( lgrid && lproj )
-            {
-              projAdded = cdiVlistAddGridIfNew(vlistID, proj, 2);
-              grid->proj = projAdded.Id;
+              cdf_put_att_text(fileID, ncxvarid, "bounds", xaxisnameLen + sizeof (bndsName), xaxisname);
             }
+        }
 
-          gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 1);
-          ncvar->gridID = gridAdded.Id;
+      if ( gridInqYvalsPtr(gridID) )
+        {
+          char yaxisname[CDI_MAX_NAME];
+          gridInqYname(gridID, yaxisname);
+          checkGridName(yaxisname, fileID, vlistID, gridID, ngrids, 'Y');
+          cdf_def_var(fileID, yaxisname, xtype, 1, &dimID, &ncyvarid);
+          cdfGridCompress(fileID, ncyvarid, (int)dimlen, streamptr->filetype, streamptr->comptype);
 
-          int gridID = ncvar->gridID;
+          cdfPutGridStdAtts(fileID, ncyvarid, gridID, &gridInqsY);
 
-          if ( lproj && gmapvarid != CDI_UNDEFID )
+          if ( gridInqYboundsPtr(gridID) && nvdimID != UNDEFID )
             {
-              int projID = lgrid ? grid->proj : gridID;
-              int ncid = ncvars[gmapvarid].ncid;
-              const char *gmapname = ncvars[gmapvarid].name;
-              cdf_read_mapping_atts(ncid, gmapvarid, projID, gmapname);
-              cdiGridDefKeyStr(projID, CDI_KEY_MAPPING, (int)(strlen(gmapname)+1), gmapname);
-              gridVerifyProj(projID);
-            }
-
-          if ( grid->type == GRID_UNSTRUCTURED && gridfile[0] != 0 )
-            gridDefReference(gridID, gridfile);
-
-          if ( ncvar->chunked ) grid_set_chunktype(grid, ncvar);
-
-	  int gridindex = vlistGridIndex(vlistID, gridID);
-          ncgrid[gridindex].gridID = gridID;
-          ncgrid[gridindex].ncIDs[CDF_DIMID_X] = xdimid;
-          ncgrid[gridindex].ncIDs[CDF_DIMID_Y] = ydimid;
-
-          if ( xdimid == CDI_UNDEFID && ydimid == CDI_UNDEFID && grid->size == 1 )
-            gridDefHasDims(gridID, FALSE);
+              int dimIDs[2] = { dimID, nvdimID };
+              size_t yaxisnameLen = strlen(yaxisname);
+              yaxisname[yaxisnameLen] = '_';
+              memcpy(yaxisname + yaxisnameLen + 1, bndsName, sizeof (bndsName));
+              cdf_def_var(fileID, yaxisname, xtype, 2, dimIDs, &ncbyvarid);
+              cdfGridCompress(fileID, ncbyvarid, (int)dimlen, streamptr->filetype, streamptr->comptype);
 
-          if ( xdimid != CDI_UNDEFID ) cdiGridDefKeyStr(gridID, CDI_KEY_XDIMNAME, (int)(strlen(ncdims[xdimid].name)+1), ncdims[xdimid].name);
-          if ( ydimid != CDI_UNDEFID ) cdiGridDefKeyStr(gridID, CDI_KEY_YDIMNAME, (int)(strlen(ncdims[ydimid].name)+1), ncdims[ydimid].name);
-          if ( vdimid != CDI_UNDEFID ) cdiGridDefKeyStr(gridID, CDI_KEY_VDIMNAME, (int)(strlen(ncdims[vdimid].name)+1), ncdims[vdimid].name);
+              cdf_put_att_text(fileID, ncyvarid, "bounds", yaxisnameLen + sizeof (bndsName), yaxisname);
+            }
+        }
 
-	  if ( CDI_Debug ) Message("gridID %d %d %s", gridID, ncvarid, ncvar->name);
+      if ( gridInqAreaPtr(gridID) )
+        {
+          static const char yaxisname_[] = "cell_area";
+          static const char units[] = "m2";
+          static const char longname[] = "area of grid cell";
+          static const char stdname[] = "cell_area";
 
-	  for ( int ncvarid2 = ncvarid+1; ncvarid2 < nvars; ncvarid2++ )
-            cdf_set_grid_to_similar_vars(ncvar, &ncvars[ncvarid2], grid->type, xdimid, ydimid);
+          cdf_def_var(fileID, yaxisname_, xtype, 1, &dimID, &ncavarid);
 
-          if ( gridAdded.isNew ) lazyGrid = NULL;
-          if ( projAdded.isNew ) lazyProj = NULL;
+          cdf_put_att_text(fileID, ncavarid, "standard_name", sizeof (stdname) - 1, stdname);
+          cdf_put_att_text(fileID, ncavarid, "long_name", sizeof (longname) - 1, longname);
+          cdf_put_att_text(fileID, ncavarid, "units", sizeof (units) - 1, units);
+        }
 
-          if ( lazyGrid )
-            {
-              if ( CDI_netcdf_lazy_grid_load ) cdfLazyGridDestroy(lazyGrid);
-              if ( grid ) { grid_free(grid); Free(grid); }
-            }
+      cdf_enddef(fileID);
+      streamptr->ncmode = 2;
 
-          if ( lazyProj )
-            {
-              if ( CDI_netcdf_lazy_grid_load ) cdfLazyGridDestroy(lazyProj);
-              if ( proj ) { grid_free(proj); Free(proj); }
-            }
-	}
+      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));
     }
 
-  return 0;
+  streamptr->xdimID[gridindex] = dimID;
+  streamptr->ncxvarID[gridindex] = ncxvarid;
+  streamptr->ncyvarID[gridindex] = ncyvarid;
+  streamptr->ncavarID[gridindex] = ncavarid;
 }
 
-/* define all input zaxes */
+struct attTxtTab2
+{
+  const char *attName, *attVal;
+  size_t valLen;
+};
+
 static
-int cdf_define_all_zaxes(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nvars, ncvar_t *ncvars,
-                         size_t vctsize_echam, double *vct_echam, unsigned char *uuidOfVGrid)
+void cdf_def_vct_echam(stream_t *streamptr, int zaxisID)
 {
-  char *pname, *plongname, *punits;
-  size_t vctsize = vctsize_echam;
-  double *vct = vct_echam;
+  int type = zaxisInqType(zaxisID);
 
-  for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
+  if ( type == ZAXIS_HYBRID || type == ZAXIS_HYBRID_HALF )
     {
-      ncvar_t *ncvar = &ncvars[ncvarid];
-      if ( ncvar->isvar == TRUE && ncvar->zaxisID == CDI_UNDEFID )
-	{
-          bool is_scalar = false;
-	  bool with_bounds = false;
-	  int zdimid = CDI_UNDEFID;
-	  int zvarid = CDI_UNDEFID;
-	  size_t zsize = 1;
-          int psvarid = -1;
-          int p0varid = -1;
+      int ilev = zaxisInqVctSize(zaxisID)/2;
+      if ( ilev == 0 ) return;
 
-          int positive = 0;
-	  int ndims = ncvar->ndims;
+      int mlev = ilev - 1;
+      size_t start;
+      size_t count = 1;
+      int ncdimid, ncdimid2;
+      int hyaiid, hybiid, hyamid, hybmid;
+      double mval;
 
-          if ( ncvar->zvarid != -1 && ncvars[ncvar->zvarid].ndims == 0 )
-            {
-              zvarid = ncvar->zvarid;
-              is_scalar = true;
-            }
-          else
-            {
-              for ( int i = 0; i < ndims; i++ )
-                {
-                  if ( ncvar->dimtype[i] == Z_AXIS )
-                    zdimid = ncvar->dimids[i];
-                }
+      if ( streamptr->vct.ilev > 0 )
+        {
+          if ( streamptr->vct.ilev != ilev )
+            Error("more than one VCT for each file unsupported!");
+          return;
+        }
 
-              if ( zdimid != CDI_UNDEFID )
-                {
-                  // zvarid = ncdims[zdimid].ncvarid;
-                  zvarid = (ncvar->zvarid != CDI_UNDEFID) ? ncvar->zvarid : ncdims[zdimid].ncvarid;
-                  zsize  = ncdims[zdimid].len;
-                }
-            }
+      int fileID = streamptr->fileID;
 
-	  if ( CDI_Debug ) Message("nlevs = %zu", zsize);
+      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-	  double *zvar = NULL;
-          char **zcvals = NULL;
-          size_t zclength = 0;
+      cdf_def_dim(fileID, "nhym", (size_t)mlev, &ncdimid);
+      cdf_def_dim(fileID, "nhyi", (size_t)ilev, &ncdimid2);
 
-	  int zaxisType = CDI_UNDEFID;
-	  if ( zvarid != CDI_UNDEFID ) zaxisType = ncvars[zvarid].zaxistype;
-	  if ( zaxisType == CDI_UNDEFID ) zaxisType = ZAXIS_GENERIC;
+      streamptr->vct.mlev   = mlev;
+      streamptr->vct.ilev   = ilev;
+      streamptr->vct.mlevID = ncdimid;
+      streamptr->vct.ilevID = ncdimid2;
 
-	  int zprec = CDI_DATATYPE_FLT64;
-	  double *restrict lbounds = NULL;
-	  double *restrict ubounds = NULL;
+      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 ( zvarid != CDI_UNDEFID )
-	    {
-	      positive  = ncvars[zvarid].positive;
-	      pname     = ncvars[zvarid].name;
-	      plongname = ncvars[zvarid].longname;
-	      punits    = ncvars[zvarid].units;
-	      if ( ncvars[zvarid].xtype == NC_FLOAT ) zprec = CDI_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;
-	      */
-              if ( zaxisType == ZAXIS_CHAR )
-                {
-                  if ( ncvars[zvarid].ndims == 2 )
-                    {
-                      zprec = CDI_DATATYPE_UINT8;
-                      zclength = ncdims[ncvars[zvarid].dimids[1]].len;
-                      cdf_load_cvals(zsize*zclength, zvarid, ncvar, &zcvals, zsize);
-                    }
-                }
+      {
+        static const char lname_n[] = "long_name",
+          lname_v_ai[] = "hybrid A coefficient at layer interfaces",
+          units_n[] = "units",
+          units_v_ai[] = "Pa",
+          lname_v_bi[] = "hybrid B coefficient at layer interfaces",
+          units_v_bi[] = "1",
+          lname_v_am[] = "hybrid A coefficient at layer midpoints",
+          units_v_am[] = "Pa",
+          lname_v_bm[] = "hybrid B coefficient at layer midpoints",
+          units_v_bm[] = "1";
+        static const struct attTxtTab2 tab[]
+          = {
+          { lname_n, lname_v_ai, sizeof (lname_v_ai) - 1 },
+          { units_n, units_v_ai, sizeof (units_v_ai) - 1 },
+          { lname_n, lname_v_bi, sizeof (lname_v_bi) - 1 },
+          { units_n, units_v_bi, sizeof (units_v_bi) - 1 },
+          { lname_n, lname_v_am, sizeof (lname_v_am) - 1 },
+          { units_n, units_v_am, sizeof (units_v_am) - 1 },
+          { lname_n, lname_v_bm, sizeof (lname_v_bm) - 1 },
+          { units_n, units_v_bm, sizeof (units_v_bm) - 1 },
+        };
+        enum { tabLen = sizeof (tab) / sizeof (tab[0]) };
+        int ids[tabLen] = { hyaiid, hyaiid, hybiid, hybiid,
+                            hyamid, hyamid, hybmid, hybmid };
+        for ( size_t i = 0; i < tabLen; ++i )
+          cdf_put_att_text(fileID, ids[i], tab[i].attName, tab[i].valLen, tab[i].attVal);
+      }
 
-              if ( zaxisType == ZAXIS_HYBRID && ncvars[zvarid].vct )
-                {
-                  vct = ncvars[zvarid].vct;
-                  vctsize = ncvars[zvarid].vctsize;
+      cdf_enddef(fileID);
+      streamptr->ncmode = 2;
 
-                  if ( ncvars[zvarid].psvarid != -1 ) psvarid = ncvars[zvarid].psvarid;
-                  if ( ncvars[zvarid].p0varid != -1 ) p0varid = ncvars[zvarid].p0varid;
-                }
+      const double *vctptr = zaxisInqVctPtr(zaxisID);
 
-              if ( zaxisType != ZAXIS_CHAR )
-                {
-                  zvar = (double*) Malloc(zsize*sizeof(double));
-                  cdf_get_var_double(ncvars[zvarid].ncid, zvarid, zvar);
-                }
+      cdf_put_var_double(fileID, hyaiid, vctptr);
+      cdf_put_var_double(fileID, hybiid, vctptr+ilev);
 
-	      if ( ncvars[zvarid].bounds != CDI_UNDEFID )
-		{
-		  int nbdims = ncvars[ncvars[zvarid].bounds].ndims;
-		  if ( nbdims == 2 || is_scalar )
-		    {
-		      size_t nlevel  = is_scalar ? 1 : (int)ncdims[ncvars[ncvars[zvarid].bounds].dimids[0]].len;
-		      int nvertex = (int)ncdims[ncvars[ncvars[zvarid].bounds].dimids[1-is_scalar]].len;
-		      if ( nlevel == zsize && nvertex == 2 )
-			{
-			  with_bounds = true;
-			  lbounds = (double *) Malloc(4 * nlevel*sizeof(double));
-			  ubounds = lbounds + nlevel;
-			  double *restrict zbounds = lbounds + 2 * nlevel;
-			  cdf_get_var_double(ncvars[zvarid].ncid, ncvars[zvarid].bounds, zbounds);
-			  for ( size_t i = 0; i < nlevel; ++i )
-			    {
-			      lbounds[i] = zbounds[i*2];
-			      ubounds[i] = zbounds[i*2+1];
-			    }
-			}
-		    }
-		}
-	    }
-	  else
-	    {
-              pname     = (zdimid != CDI_UNDEFID) ? ncdims[zdimid].name : NULL;
-	      plongname = NULL;
-	      punits    = NULL;
+      for ( int 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);
+        }
+    }
+}
+
+static
+void cdf_def_vct_cf(stream_t *streamptr, int zaxisID, int nclevID, int ncbndsID)
+{
+  int type = zaxisInqType(zaxisID);
+
+  if ( type == ZAXIS_HYBRID || type == ZAXIS_HYBRID_HALF )
+    {
+      int ilev = zaxisInqVctSize(zaxisID)/2;
+      if ( ilev == 0 ) return;
+
+      int mlev = ilev - 1;
+      int hyaiid = 0, hybiid = 0, hyamid, hybmid;
+
+      if ( streamptr->vct.ilev > 0 )
+        {
+          if ( streamptr->vct.ilev != ilev )
+            Error("more than one VCT for each file unsupported!");
+          return;
+        }
 
-	      if ( zsize == 1 && zdimid == CDI_UNDEFID )
-		{
-                  zaxisType = (ncvar->zaxistype != CDI_UNDEFID) ? ncvar->zaxistype : ZAXIS_SURFACE;
-                  // if ( pname )
-                    {
-                      zvar = (double*) Malloc(sizeof(double));
-                      zvar[0] = 0;
-                    }
-                }
-	    }
+      int fileID = streamptr->fileID;
 
-          if ( zsize > INT_MAX )
-            {
-              Warning("Size limit exceeded for z-axis dimension (limit=%d)!", INT_MAX);
-              return CDI_EDIMSIZE;
-            }
+      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-      	  ncvar->zaxisID = varDefZaxis(vlistID, zaxisType, (int) zsize, zvar, (const char **)zcvals, zclength, with_bounds, lbounds, ubounds,
-                                       (int)vctsize, vct, pname, plongname, punits, zprec, 1, 0);
+      int dimIDs[2];
+      dimIDs[0] = nclevID;
+      dimIDs[1] = ncbndsID;
 
-          int zaxisID = ncvar->zaxisID;
+      streamptr->vct.mlev   = mlev;
+      streamptr->vct.ilev   = ilev;
+      streamptr->vct.mlevID = nclevID;
+      streamptr->vct.ilevID = nclevID;
 
-          if ( CDI_cmor_mode && zsize == 1 && zaxisType != ZAXIS_HYBRID ) zaxisDefScalar(zaxisID);
+      cdf_def_var(fileID, "ap", NC_DOUBLE, 1, dimIDs,  &hyamid);
+      cdf_def_var(fileID, "b",  NC_DOUBLE, 1, dimIDs,  &hybmid);
 
-          if ( uuidOfVGrid[0] != 0 )
-            zaxisDefUUID(zaxisID, uuidOfVGrid);
+      {
+        static const char lname[] = "vertical coordinate formula term: ap(k)";
+        cdf_put_att_text(fileID, hyamid, "long_name", sizeof (lname) - 1, lname);
+      }
+      {
+        static const char units[] = "Pa";
+        cdf_put_att_text(fileID, hyamid, "units", sizeof (units) - 1, units);
+      }
+      {
+        static const char lname[] = "vertical coordinate formula term: b(k)";
+        cdf_put_att_text(fileID, hybmid, "long_name", sizeof (lname) - 1, lname);
+      }
+      {
+        static const char units[] = "1";
+        cdf_put_att_text(fileID, hybmid, "units", sizeof (units) - 1, units);
+      }
 
-          if ( zaxisType == ZAXIS_HYBRID )
-            {
-              if ( psvarid != -1 )
-                cdiZaxisDefKeyStr(zaxisID, CDI_KEY_PSNAME, (int)(strlen(ncvars[psvarid].name)+1), ncvars[psvarid].name);
-              if ( p0varid != -1 )
-                {
-                  double px = 1;
-                  cdf_get_var_double(ncvars[p0varid].ncid, p0varid, &px);
-                  cdiZaxisDefKeyFlt(zaxisID, CDI_KEY_P0VALUE, px);
-                  cdiZaxisDefKeyStr(zaxisID, CDI_KEY_P0NAME, (int)(strlen(ncvars[p0varid].name)+1), ncvars[p0varid].name);
-                }
-            }
+      if ( ncbndsID != -1 )
+        {
+          cdf_def_var(fileID, "ap_bnds", NC_DOUBLE, 2, dimIDs, &hyaiid);
+          cdf_def_var(fileID, "b_bnds",  NC_DOUBLE, 2, dimIDs, &hybiid);
+          {
+            static const char lname[] = "vertical coordinate formula term: ap(k+1/2)";
+            cdf_put_att_text(fileID, hyaiid, "long_name", sizeof (lname) - 1, lname);
+          }
+          {
+            static const char units[] = "Pa";
+            cdf_put_att_text(fileID, hyaiid, "units", sizeof (units) - 1, units);
+          }
+          {
+            static const char lname[] = "vertical coordinate formula term: b(k+1/2)";
+            cdf_put_att_text(fileID, hybiid, "long_name", sizeof (lname) - 1, lname);
+          }
+          {
+            static const char units[] = "1";
+            cdf_put_att_text(fileID, hybiid, "units", sizeof (units) - 1, units);
+          }
+        }
 
-          if ( positive > 0 ) zaxisDefPositive(zaxisID, positive);
-          if ( is_scalar ) zaxisDefScalar(zaxisID);
+      cdf_enddef(fileID);
+      streamptr->ncmode = 2;
 
-          if ( zdimid != CDI_UNDEFID )
-            cdiZaxisDefKeyStr(zaxisID, CDI_KEY_DIMNAME, (int)(strlen(ncdims[zdimid].name)+1), ncdims[zdimid].name);
-          /*
-          if ( vdimid != -1 )
-            cdiZaxisDefKeyStr(zaxisID, CDI_KEY_VDIMNAME, strlen(ncdims[vdimid].name)+1, ncdims[vdimid].name);
-          */
-	  if ( zvar    ) Free(zvar);
-	  if ( zcvals  )
+      const double *vctptr = zaxisInqVctPtr(zaxisID);
+      double tarray[ilev*2];
+
+      if ( ncbndsID != -1 )
+        {
+          for ( int i = 0; i < mlev; ++i )
             {
-              for ( size_t i = 0; i < zsize; i++ )
-                Free(zcvals[i]);
-              Free(zcvals);
+              tarray[2*i  ] = vctptr[i];
+              tarray[2*i+1] = vctptr[i+1];
             }
-	  if ( lbounds ) Free(lbounds);
+          cdf_put_var_double(fileID, hyaiid, tarray);
 
-          if ( zvarid != CDI_UNDEFID )
+          for ( int i = 0; i < mlev; ++i )
             {
-              int ncid = ncvars[zvarid].ncid;
-              int nvatts = ncvars[zvarid].natts;
-              for ( int iatt = 0; iatt < nvatts; ++iatt )
-                {
-                  int attnum = ncvars[zvarid].atts[iatt];
-                  cdf_set_cdi_attr(ncid, zvarid, attnum, zaxisID, CDI_GLOBAL);
-                }
+              tarray[2*i  ] = vctptr[ilev+i];
+              tarray[2*i+1] = vctptr[ilev+i+1];
             }
+          cdf_put_var_double(fileID, hybiid, tarray);
+        }
 
-          int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
-	  streamptr->zaxisID[zaxisindex] = zdimid;
-
-	  if ( CDI_Debug )
-	    Message("zaxisID %d %d %s", zaxisID, ncvarid, ncvar->name);
-
-	  for ( int ncvarid2 = ncvarid+1; ncvarid2 < nvars; ncvarid2++ )
-	    if ( ncvars[ncvarid2].isvar == TRUE && ncvars[ncvarid2].zaxisID == CDI_UNDEFID /*&& ncvars[ncvarid2].zaxistype == CDI_UNDEFID*/ )
-	      {
-                int zvarid2 = CDI_UNDEFID;
-                if ( ncvars[ncvarid2].zvarid != CDI_UNDEFID && ncvars[ncvars[ncvarid2].zvarid].ndims == 0 )
-                  zvarid2 = ncvars[ncvarid2].zvarid;
-
-		int zdimid2 = CDI_UNDEFID;
-		ndims = ncvars[ncvarid2].ndims;
-		for ( int i = 0; i < ndims; i++ )
-		  {
-		    if ( ncvars[ncvarid2].dimtype[i] == Z_AXIS )
-		      zdimid2 = ncvars[ncvarid2].dimids[i];
-		  }
+      for ( int i = 0; i < mlev; ++i )
+        tarray[i] = (vctptr[i] + vctptr[i+1]) * 0.5;
+      cdf_put_var_double(fileID, hyamid, tarray);
 
-		if ( zdimid == zdimid2 /* && zvarid == zvarid2 */)
-		  {
-                    if ( (zdimid != CDI_UNDEFID && ncvars[ncvarid2].zaxistype == CDI_UNDEFID) ||
-                         (zdimid == CDI_UNDEFID && zvarid != CDI_UNDEFID && zvarid == zvarid2) ||
-                         (zdimid == CDI_UNDEFID && zaxisType == ncvars[ncvarid2].zaxistype) ||
-                         (zdimid == CDI_UNDEFID && zvarid2 == CDI_UNDEFID && ncvars[ncvarid2].zaxistype == CDI_UNDEFID) )
-                      {
-                        if ( CDI_Debug )
-                          Message("zaxisID %d %d %s", zaxisID, ncvarid2, ncvars[ncvarid2].name);
-                        ncvars[ncvarid2].zaxisID = zaxisID;
-                      }
-                  }
-	      }
-	}
+      for ( int i = 0; i < mlev; ++i )
+        tarray[i] = (vctptr[ilev+i] + vctptr[ilev+i+1]) * 0.5;
+      cdf_put_var_double(fileID, hybmid, tarray);
     }
-
-  return 0;
 }
 
+struct attTxtTab { const char *txt; size_t txtLen; };
 
-struct cdf_varinfo
-{
-  int        varid;
-  const char *name;
-};
-
-static
-int cdf_cmp_varname(const void *s1, const void *s2)
-{
-  const struct cdf_varinfo *x = (const struct cdf_varinfo *)s1,
-                           *y = (const struct cdf_varinfo *)s2;
-  return strcmp(x->name, y->name);
-}
-
-/* define all input data variables */
 static
-void cdf_define_all_vars(stream_t *streamptr, int vlistID, int instID, int modelID, int *varids, int nvars, int num_ncvars, ncvar_t *ncvars)
+void cdf_def_zaxis_hybrid_echam(stream_t *streamptr, int type, int ncvarid, int zaxisID, int zaxisindex, int xtype, size_t dimlen, int *dimID, char *axisname)
 {
-  if ( CDI_Debug )
-    for ( int i = 0; i < nvars; i++ ) Message("varids[%d] = %d", i, varids[i]);
-
-  if ( streamptr->sortname )
-    {
-      struct cdf_varinfo *varInfo
-        = (struct cdf_varinfo *) Malloc((size_t)nvars * sizeof(struct cdf_varinfo));
+  int fileID  = streamptr->fileID;
 
-      for ( int varID = 0; varID < nvars; varID++ )
-	{
-	  int ncvarid = varids[varID];
-	  varInfo[varID].varid = ncvarid;
-	  varInfo[varID].name = ncvars[ncvarid].name;
-	}
-      qsort(varInfo, (size_t)nvars, sizeof(varInfo[0]), cdf_cmp_varname);
-      for ( int varID = 0; varID < nvars; varID++ )
-	{
-	  varids[varID] = varInfo[varID].varid;
-	}
-      Free(varInfo);
-      if ( CDI_Debug )
-        for ( int i = 0; i < nvars; i++ ) Message("sorted varids[%d] = %d", i, varids[i]);
-    }
+  if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-  for ( int varID1 = 0; varID1 < nvars; varID1++ )
-    {
-      int ncvarid = varids[varID1];
-      int gridID  = ncvars[ncvarid].gridID;
-      int zaxisID = ncvars[ncvarid].zaxisID;
+  cdf_def_dim(fileID, axisname, dimlen, dimID);
+  cdf_def_var(fileID, axisname, (nc_type) xtype, 1, dimID,  &ncvarid);
 
-      stream_new_var(streamptr, gridID, zaxisID, CDI_UNDEFID);
-      int varID = vlistDefVar(vlistID, gridID, zaxisID, ncvars[ncvarid].tsteptype);
+  {
+    static const char sname[] = "hybrid_sigma_pressure";
+    cdf_put_att_text(fileID, ncvarid, "standard_name", sizeof (sname) - 1, sname);
+  }
+  {
+    static const char *attName[] = {
+      "long_name",
+      "formula",
+      "formula_terms"
+    };
+    enum { nAtt = sizeof (attName) / sizeof (attName[0]) };
+    static const char lname_m[] = "hybrid level at layer midpoints",
+      formula_m[] = "hyam hybm (mlev=hyam+hybm*aps)",
+      fterms_m[] = "ap: hyam b: hybm ps: aps",
+      lname_i[] = "hybrid level at layer interfaces",
+      formula_i[] = "hyai hybi (ilev=hyai+hybi*aps)",
+      fterms_i[] = "ap: hyai b: hybi ps: aps";
+    static const struct attTxtTab tab[2][nAtt] = {
+      {
+        { lname_i, sizeof (lname_i) - 1 },
+        { formula_i, sizeof (formula_i) - 1 },
+        { fterms_i, sizeof (fterms_i) - 1 }
+      },
+      {
+        { lname_m, sizeof (lname_m) - 1 },
+        { formula_m, sizeof (formula_m) - 1 },
+        { fterms_m, sizeof (fterms_m) - 1 }
+      }
+    };
 
-#if  defined  (HAVE_NETCDF4)
-      if ( ncvars[ncvarid].deflate )
-	vlistDefVarCompType(vlistID, varID, CDI_COMPRESS_ZIP);
+    size_t tabSelect = type == ZAXIS_HYBRID;
+    for (size_t i = 0; i < nAtt; ++i)
+      cdf_put_att_text(fileID, ncvarid, attName[i],
+                       tab[tabSelect][i].txtLen, tab[tabSelect][i].txt);
+  }
 
-      if ( ncvars[ncvarid].chunked && ncvars[ncvarid].chunktype != CDI_UNDEFID )
-        vlistDefVarChunkType(vlistID, varID, ncvars[ncvarid].chunktype);
-#endif
+  {
+    static const char units[] = "level";
+    cdf_put_att_text(fileID, ncvarid, "units", sizeof (units) - 1, units);
+  }
+  {
+    static const char direction[] = "down";
+    cdf_put_att_text(fileID, ncvarid, "positive", sizeof (direction) - 1, direction);
+  }
 
-      streamptr->vars[varID1].defmiss = false;
-      streamptr->vars[varID1].ncvarid = ncvarid;
+  cdf_enddef(fileID);
+  streamptr->ncmode = 2;
 
-      vlistDefVarName(vlistID, varID, ncvars[ncvarid].name);
-      if ( ncvars[ncvarid].param != CDI_UNDEFID ) vlistDefVarParam(vlistID, varID, ncvars[ncvarid].param);
-      if ( ncvars[ncvarid].code != CDI_UNDEFID )  vlistDefVarCode(vlistID, varID, ncvars[ncvarid].code);
-      if ( ncvars[ncvarid].code != CDI_UNDEFID )
-	{
-	  int 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);
+  cdf_put_var_double(fileID, ncvarid, zaxisInqLevelsPtr(zaxisID));
 
-      if ( ncvars[ncvarid].lvalidrange )
-        vlistDefVarValidrange(vlistID, varID, ncvars[ncvarid].validrange);
+  cdf_def_vct_echam(streamptr, zaxisID);
 
-      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 ( *dimID == UNDEFID )
+    {
+      if ( type == ZAXIS_HYBRID )
+        streamptr->zaxisID[zaxisindex] = streamptr->vct.mlevID;
+      else
+        streamptr->zaxisID[zaxisindex] = streamptr->vct.ilevID;
+    }
+}
 
-      vlistDefVarDatatype(vlistID, varID, cdfInqDatatype(ncvars[ncvarid].xtype, ncvars[ncvarid].lunsigned));
+static
+void cdf_def_zaxis_hybrid_cf(stream_t *streamptr, int type, int ncvarid, int zaxisID, int zaxisindex, int xtype, size_t dimlen, int *dimID, char *axisname)
+{
+  char psname[CDI_MAX_NAME];
+  psname[0] = 0;
+  zaxisInqPsName(zaxisID, psname);
+  if ( psname[0] == 0 ) strcpy(psname, "ps");
 
-      vlistDefVarInstitut(vlistID, varID, instID);
-      vlistDefVarModel(vlistID, varID, modelID);
-      if ( ncvars[ncvarid].tableID != CDI_UNDEFID )
-	vlistDefVarTable(vlistID, varID, ncvars[ncvarid].tableID);
+  int fileID = streamptr->fileID;
+  if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-      if ( ncvars[ncvarid].deffillval == false && ncvars[ncvarid].defmissval )
-        {
-          ncvars[ncvarid].deffillval = true;
-          ncvars[ncvarid].fillval    = ncvars[ncvarid].missval;
-        }
+  strcpy(axisname, "lev");
 
-      if ( ncvars[ncvarid].deffillval )
-        vlistDefVarMissval(vlistID, varID, ncvars[ncvarid].fillval);
+  cdf_def_dim(fileID, axisname, dimlen, dimID);
+  cdf_def_var(fileID, axisname, (nc_type) xtype, 1, dimID,  &ncvarid);
 
-      if ( CDI_Debug )
-	Message("varID = %d  gridID = %d  zaxisID = %d", varID,
-		vlistInqVarGrid(vlistID, varID), vlistInqVarZaxis(vlistID, varID));
+  {
+    static const char sname[] = "standard_name",
+      sname_v[] = "atmosphere_hybrid_sigma_pressure_coordinate",
+      lname[] = "long_name",
+      lname_v[] = "hybrid sigma pressure coordinate",
+      formula[] = "formula",
+      formula_v[] = "p = ap + b*ps",
+      fterms[] = "formula_terms",
+      fterms_v[] = "ap: ap b: b ps: ",
+      units[] = "units",
+      units_v[] = "1",
+      axis[] = "axis",
+      axis_v[] = "Z",
+      direction[] = "positive",
+      direction_v[] = "down";
+    struct attTxtTab2 tab[] = {
+      { sname, sname_v, sizeof (sname_v) - 1 },
+      { lname, lname_v, sizeof (lname_v) - 1 },
+      { formula, formula_v, sizeof (formula_v) - 1 },
+      { fterms, fterms_v, sizeof (fterms_v) - 1 },
+      { units, units_v, sizeof (units_v) - 1 },
+      { axis, axis_v, sizeof (axis_v) - 1 },
+      { direction, direction_v, sizeof (direction_v) - 1 },
+    };
+    enum { nAtt = sizeof (tab) / sizeof (tab[0]) };
+    for (size_t i = 0; i < nAtt; ++i)
+      cdf_put_att_text(fileID, ncvarid, tab[i].attName, tab[i].valLen, tab[i].attVal);
+  }
 
-      int gridindex = vlistGridIndex(vlistID, gridID);
-      int xdimid = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X];
-      int ydimid = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_Y];
+  int ncbvarid = UNDEFID;
+  int nvdimID = UNDEFID;
 
-      int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
-      int zdimid = streamptr->zaxisID[zaxisindex];
+  double lbounds[dimlen], ubounds[dimlen], levels[dimlen];
 
-      int ndims = ncvars[ncvarid].ndims;
-      int iodim = 0;
-      int ixyz = 0;
-      static const int ipow10[4] = {1, 10, 100, 1000};
+  zaxisInqLevels(zaxisID, levels);
 
-      if ( ncvars[ncvarid].tsteptype != TSTEP_CONSTANT ) iodim++;
+  if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
+    {
+      zaxisInqLbounds(zaxisID, lbounds);
+      zaxisInqUbounds(zaxisID, ubounds);
+    }
+  else
+    {
+      for ( size_t i = 0; i < dimlen; ++i ) lbounds[i] = levels[i];
+      for ( size_t i = 0; i < dimlen-1; ++i ) ubounds[i] = levels[i+1];
+      ubounds[dimlen-1] = levels[dimlen-1] + 1;
+    }
 
-      const int *dimids = ncvars[ncvarid].dimids;
+  //if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
+    {
+      size_t nvertex = 2;
+      if ( nc_inq_dimid(fileID, bndsName, &nvdimID) != NC_NOERR )
+        cdf_def_dim(fileID, bndsName, nvertex, &nvdimID);
 
-      if ( gridInqType(gridID) == GRID_UNSTRUCTURED && ndims-iodim <= 2 && ydimid == xdimid )
-        {
-          ixyz = (xdimid == dimids[ndims-1]) ? 321 : 213;
-        }
-      else
+      if ( nvdimID != UNDEFID )
         {
-          for ( int idim = iodim; idim < ndims; idim++ )
-            {
-              if      ( xdimid == dimids[idim] ) ixyz += 1*ipow10[ndims-idim-1];
-              else if ( ydimid == dimids[idim] ) ixyz += 2*ipow10[ndims-idim-1];
-              else if ( zdimid == dimids[idim] ) ixyz += 3*ipow10[ndims-idim-1];
-            }
+          size_t axisnameLen = strlen(axisname);
+          axisname[axisnameLen] = '_';
+          memcpy(axisname + axisnameLen + 1, bndsName, sizeof (bndsName));
+          axisnameLen += sizeof (bndsName);
+          int dimIDs[2] = { *dimID, nvdimID };
+          cdf_def_var(fileID, axisname, (nc_type) xtype, 2, dimIDs, &ncbvarid);
+          cdf_put_att_text(fileID, ncvarid, "bounds", axisnameLen, axisname);
+          {
+            static const char sname[] = "standard_name",
+              sname_v[] = "atmosphere_hybrid_sigma_pressure_coordinate",
+              formula[] = "formula",
+              formula_v[] = "p = ap + b*ps";
+            struct attTxtTab2 tab[] = {
+              { sname, sname_v, sizeof (sname_v) - 1 },
+              { formula, formula_v, sizeof (formula_v) - 1 },
+            };
+            enum { nAtt = sizeof (tab) / sizeof (tab[0]) };
+            for (size_t i = 0; i < nAtt; ++i)
+              cdf_put_att_text(fileID, ncbvarid, tab[i].attName, tab[i].valLen, tab[i].attVal);
+          }
+          {
+            char txt[CDI_MAX_NAME];
+            size_t len = (size_t)(sprintf(txt, "%s%s", "ap: ap_bnds b: b_bnds ps: ", psname));
+            cdf_put_att_text(fileID, ncbvarid, "formula_terms", len, txt);
+          }
+          {
+            static const char units[] = "1";
+            cdf_put_att_text(fileID, ncbvarid, "units", sizeof (units) - 1, units);
+          }
         }
+    }
 
-      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, dimids[i]);
-      printf("xdimid, ydimid %d %d\n", xdimid, ydimid);
-      */
-      if ( ncvars[ncvarid].ensdata != NULL )
-        {
-          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;
-        }
+  cdf_enddef(fileID);
+  streamptr->ncmode = 2;
 
-      if ( ncvars[ncvarid].extra[0] != 0 )
+  cdf_put_var_double(fileID, ncvarid, levels);
+
+  if ( ncbvarid != UNDEFID )
+    {
+      double zbounds[2*dimlen];
+      for ( size_t i = 0; i < dimlen; ++i )
         {
-          vlistDefVarExtra(vlistID, varID, ncvars[ncvarid].extra);
+          zbounds[2*i  ] = lbounds[i];
+          zbounds[2*i+1] = ubounds[i];
         }
+      cdf_put_var_double(fileID, ncbvarid, zbounds);
     }
 
-  for ( int varID = 0; varID < nvars; varID++ )
+  cdf_def_vct_cf(streamptr, zaxisID, *dimID, nvdimID);
+
+  if ( *dimID == UNDEFID )
     {
-      int ncvarid = varids[varID];
-      int ncid = ncvars[ncvarid].ncid;
+      if ( type == ZAXIS_HYBRID )
+        streamptr->zaxisID[zaxisindex] = streamptr->vct.mlevID;
+      else
+        streamptr->zaxisID[zaxisindex] = streamptr->vct.ilevID;
+    }
+}
 
-      int nvatts = ncvars[ncvarid].natts;
-      for ( int iatt = 0; iatt < nvatts; ++iatt )
-        {
-          int attnum = ncvars[ncvarid].atts[iatt];
-          cdf_set_cdi_attr(ncid, ncvarid, attnum, vlistID, varID);
-        }
+static
+void cdf_def_zaxis_hybrid(stream_t *streamptr, int type, int ncvarid, int zaxisID, int zaxisindex, int xtype, size_t dimlen, int *dimID, char *axisname)
+{
+  if ( (!CDI_cmor_mode && cdiConvention == CDI_CONVENTION_ECHAM) || type == ZAXIS_HYBRID_HALF )
+    cdf_def_zaxis_hybrid_echam(streamptr, type, ncvarid, zaxisID, zaxisindex, xtype, dimlen, dimID, axisname);
+  else
+    cdf_def_zaxis_hybrid_cf(streamptr, type, ncvarid, zaxisID, zaxisindex, xtype, dimlen, dimID, axisname);
+}
 
-      if ( ncvars[ncvarid].atts )
-        {
-          Free(ncvars[ncvarid].atts);
-          ncvars[ncvarid].atts = NULL;
-        }
+static
+void cdfDefZaxis(stream_t *streamptr, int zaxisID)
+{
+  /*  char zaxisname0[CDI_MAX_NAME]; */
+  char axisname[CDI_MAX_NAME];
+  int dimID = UNDEFID;
+  int dimIDs[2];
+  int ncvarid = UNDEFID, ncbvarid = UNDEFID;
+  int nvdimID = UNDEFID;
+  int xtype = NC_DOUBLE;
+
+  if ( zaxisInqPrec(zaxisID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
+
+  int vlistID = streamptr->vlistID;
+  int fileID  = streamptr->fileID;
+
+  int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
+
+  int nzaxis = vlistNzaxis(vlistID);
+
+  size_t dimlen = (size_t)zaxisInqSize(zaxisID);
+  int type   = zaxisInqType(zaxisID);
 
-      if ( ncvars[ncvarid].vct )
+  int is_scalar = FALSE;
+  if ( dimlen == 1 )
+    {
+      is_scalar = zaxisInqScalar(zaxisID);
+      if ( !is_scalar && CDI_cmor_mode )
         {
-          Free(ncvars[ncvarid].vct);
-          ncvars[ncvarid].vct = NULL;
+          is_scalar = TRUE;
+          zaxisDefScalar(zaxisID);
         }
     }
 
-  /* release mem of not freed attributes */
-  for ( int ncvarid = 0; ncvarid < num_ncvars; ncvarid++ )
-    if ( ncvars[ncvarid].atts ) Free(ncvars[ncvarid].atts);
+  int ndims = 1;
+  if ( is_scalar ) ndims = 0;
 
-  if ( varids ) Free(varids);
+  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;
+      }
 
-  for ( int varID = 0; varID < nvars; varID++ )
-    {
-      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 ( str_is_equal(pname, "var") )
-		{
-		  vlistDefVarCode(vlistID, varID, atoi(pname+3));
-                  // vlistDestroyVarName(vlistID, varID);
-		}
-	    }
-	  else if ( len > 4 && isdigit((int) pname[4]) )
-	    {
-	      if ( str_is_equal(pname, "code") )
-		{
-		  vlistDefVarCode(vlistID, varID, atoi(pname+4));
-		  // vlistDestroyVarName(vlistID, varID);
-		}
-	    }
-	  else if ( len > 5 && isdigit((int) pname[5]) )
-	    {
-	      if ( str_is_equal(pname, "param") )
-		{
-		  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);
-		}
-	    }
-	}
-    }
+  zaxisInqName(zaxisID, axisname);
 
-  for ( int varID = 0; varID < nvars; varID++ )
+  if ( dimID == UNDEFID )
     {
-      int varInstID  = vlistInqVarInstitut(vlistID, varID);
-      int varModelID = vlistInqVarModel(vlistID, varID);
-      int varTableID = vlistInqVarTable(vlistID, varID);
-      int code = vlistInqVarCode(vlistID, varID);
-      if ( cdiDefaultTableID != CDI_UNDEFID )
-	{
-	  if ( tableInqParNamePtr(cdiDefaultTableID, code) )
-	    {
-	      vlistDestroyVarName(vlistID, varID);
-	      vlistDestroyVarLongname(vlistID, varID);
-	      vlistDestroyVarUnits(vlistID, varID);
+      checkZaxisName(axisname, fileID, vlistID, zaxisID, nzaxis);
 
-	      if ( varTableID != CDI_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
-		{
-		  varTableID = cdiDefaultTableID;
-		}
-	    }
+      char dimname[CDI_MAX_NAME+3];
+      dimname[0] = 0;
+      //cdiZaxisInqString(zaxisID, CDI_ZAXIS_DIMNAME, CDI_MAX_NAME, dimname);
+      if ( dimname[0] == 0 ) strcpy(dimname, axisname);
 
-	  if ( cdiDefaultModelID != CDI_UNDEFID ) varModelID = cdiDefaultModelID;
-	  if ( cdiDefaultInstID  != CDI_UNDEFID ) varInstID  = cdiDefaultInstID;
-	}
-      if ( varInstID  != CDI_UNDEFID ) vlistDefVarInstitut(vlistID, varID, varInstID);
-      if ( varModelID != CDI_UNDEFID ) vlistDefVarModel(vlistID, varID, varModelID);
-      if ( varTableID != CDI_UNDEFID ) vlistDefVarTable(vlistID, varID, varTableID);
-    }
-}
+      if ( type == ZAXIS_REFERENCE ) cdfDefZaxisUUID(streamptr, zaxisID);
 
-static
-void cdf_scan_global_attr(int fileID, int vlistID, stream_t *streamptr, int ngatts, int *instID, int *modelID, bool *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];
-  char attstring[65636];
+      if ( type == ZAXIS_HYBRID || type == ZAXIS_HYBRID_HALF )
+        {
+          cdf_def_zaxis_hybrid(streamptr, type, ncvarid, zaxisID, zaxisindex, xtype, dimlen, &dimID, axisname);
+        }
+      else
+        {
+          dimID = checkDimName(fileID, dimlen, dimname);
 
-  for ( int 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 ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-      if ( xtypeIsText(xtype) )
-	{
-	  cdfGetAttText(fileID, NC_GLOBAL, attname, sizeof(attstring), attstring);
+          if ( ndims && dimID == UNDEFID ) cdf_def_dim(fileID, dimname, dimlen, &dimID);
 
-          size_t attstrlen = strlen(attstring);
+          cdf_def_var(fileID, axisname, (nc_type) xtype, ndims, &dimID, &ncvarid);
 
-	  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 == CDI_UNDEFID )
-		    *instID = institutDef(0, 0, NULL, attstring);
-		}
-	      else if ( strcmp(attname, "source") == 0 )
-		{
-		  *modelID = modelInq(-1, 0, attstring);
-		  if ( *modelID == CDI_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 )
+          cdfPutGridStdAtts(fileID, ncvarid, zaxisID, &gridInqsZ);
+
+          {
+            int positive = zaxisInqPositive(zaxisID);
+            static const char positive_up[] = "up",
+              positive_down[] = "down";
+            static const struct attTxtTab tab[2] = {
+              { positive_up, sizeof (positive_up) - 1 },
+              { positive_down, sizeof (positive_down) - 1 },
+            };
+            if ( positive == POSITIVE_UP || positive == POSITIVE_DOWN )
+              {
+                size_t select = positive == POSITIVE_DOWN;
+                cdf_put_att_text(fileID, ncvarid, "positive",
+                                 tab[select].txtLen, tab[select].txt);
+              }
+          }
+          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, bndsName, &nvdimID) != NC_NOERR )
+		cdf_def_dim(fileID, bndsName, nvertex, &nvdimID);
+
+	      if ( nvdimID != UNDEFID )
 		{
-                  attstring[36] = 0;
-                  cdiStr2UUID(attstring, uuidOfHGrid);
-                  //   printf("uuid: %d %s\n", attlen, attstring);
+                  size_t axisnameLen = strlen(axisname);
+                  axisname[axisnameLen] = '_';
+                  memcpy(axisname + axisnameLen + 1, bndsName, sizeof (bndsName));
+		  dimIDs[0] = dimID;
+		  dimIDs[ndims] = nvdimID;
+		  cdf_def_var(fileID, axisname, (nc_type) xtype, ndims+1, dimIDs, &ncbvarid);
+		  cdf_put_att_text(fileID, ncvarid, "bounds", strlen(axisname), axisname);
 		}
-	      else if ( strcmp(attname, "uuidOfVGrid") == 0 && attstrlen == 36 )
+	    }
+
+          cdf_enddef(fileID);
+          streamptr->ncmode = 2;
+
+          cdf_put_var_double(fileID, ncvarid, zaxisInqLevelsPtr(zaxisID));
+
+          if ( ncbvarid != UNDEFID )
+	    {
+              double lbounds[dimlen], ubounds[dimlen], zbounds[2*dimlen];
+	      zaxisInqLbounds(zaxisID, lbounds);
+	      zaxisInqUbounds(zaxisID, ubounds);
+	      for ( size_t i = 0; i < dimlen; ++i )
 		{
-                  attstring[36] = 0;
-                  cdiStr2UUID(attstring, uuidOfVGrid);
+		  zbounds[2*i  ] = lbounds[i];
+		  zbounds[2*i+1] = ubounds[i];
 		}
-	      else
-		{
-                  if ( strcmp(attname, "ICON_grid_file_uri") == 0 && gridfile[0] == 0 )
-                    memcpy(gridfile, attstring, attstrlen+1);
 
-		  cdiDefAttTxt(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) = CDI_UNDEFID;
-	      cdfGetAttInt(fileID, NC_GLOBAL, attname, 1, number_of_grid_used);
+	      cdf_put_var_double(fileID, ncbvarid, zbounds);
 	    }
- 	  else
-            {
-              int attint[attlen];
-              cdfGetAttInt(fileID, NC_GLOBAL, attname, attlen, attint);
-              int datatype = (xtype == NC_SHORT) ? CDI_DATATYPE_INT16 : CDI_DATATYPE_INT32;
-              cdiDefAttInt(vlistID, CDI_GLOBAL, attname, datatype, (int)attlen, attint);
-            }
+
+          if ( ndims == 0 ) streamptr->nczvarID[zaxisindex] = ncvarid;
         }
-      else if ( xtype == NC_FLOAT || xtype == NC_DOUBLE )
-	{
-	  double attflt[attlen];
-	  cdfGetAttDouble(fileID, NC_GLOBAL, attname, attlen, attflt);
-          int datatype = (xtype == NC_FLOAT) ? CDI_DATATYPE_FLT32 : CDI_DATATYPE_FLT64;
-          cdiDefAttFlt(vlistID, CDI_GLOBAL, attname, datatype, (int)attlen, attflt);
-	}
     }
+
+  if ( dimID != UNDEFID )
+    streamptr->zaxisID[zaxisindex] = dimID;
 }
 
 static
-int find_leadtime(int nvars, ncvar_t *ncvars)
+void cdfDefPole(stream_t *streamptr, int gridID)
 {
-  int leadtime_id = CDI_UNDEFID;
+  int ncvarid = UNDEFID;
+  static const char varname[] = "rotated_pole";
+  static const char mapname[] = "rotated_latitude_longitude";
 
-  for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
+  int fileID  = streamptr->fileID;
+
+  double ypole = gridInqYpole(gridID);
+  double xpole = gridInqXpole(gridID);
+  double angle = gridInqAngle(gridID);
+
+  cdf_redef(fileID);
+
+  int ncerrcode = nc_def_var(fileID, varname, (nc_type) NC_CHAR, 0, NULL, &ncvarid);
+  if ( ncerrcode == NC_NOERR )
+    {
+      cdf_put_att_text(fileID, ncvarid, "grid_mapping_name", sizeof (mapname) - 1, 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);
+    }
+
+  cdf_enddef(fileID);
+}
+
+
+static
+void cdfDefMapping(stream_t *streamptr, int gridID)
+{
+  int ncvarid = UNDEFID;
+  int fileID  = streamptr->fileID;
+
+  if ( gridInqType(gridID) == GRID_SINUSOIDAL )
     {
-      if ( ncvars[ncvarid].stdname[0] && strcmp(ncvars[ncvarid].stdname, "forecast_period") == 0 )
+      static const char varname[] = "sinusoidal";
+      static const char mapname[] = "sinusoidal";
+
+      cdf_redef(fileID);
+
+      int ncerrcode = nc_def_var(fileID, varname, (nc_type) NC_CHAR, 0, NULL, &ncvarid);
+      if ( ncerrcode == NC_NOERR )
         {
-          leadtime_id = ncvarid;
-          break;
+          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);
+          */
+        }
+
+      cdf_enddef(fileID);
+    }
+  else if ( gridInqType(gridID) == GRID_LAEA )
+    {
+      static const char varname[] = "laea";
+      static const char mapname[] = "lambert_azimuthal_equal_area";
+
+      cdf_redef(fileID);
+
+      int ncerrcode = nc_def_var(fileID, varname, (nc_type) NC_CHAR, 0, NULL, &ncvarid);
+      if ( ncerrcode == NC_NOERR )
+        {
+          double a, lon_0, lat_0;
+
+          gridInqLaea(gridID, &a, &lon_0, &lat_0);
+
+          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);
         }
+
+      cdf_enddef(fileID);
     }
+  else if ( gridInqType(gridID) == GRID_LCC2 )
+    {
+      static const char varname[] = "Lambert_Conformal";
+      static const char mapname[] = "lambert_conformal_conic";
+
+      cdf_redef(fileID);
+
+      int ncerrcode = nc_def_var(fileID, varname, (nc_type) NC_CHAR, 0, NULL, &ncvarid);
+      if ( ncerrcode == NC_NOERR )
+        {
+          double radius, lon_0, lat_0, lat_1, lat_2;
+
+          gridInqLcc2(gridID, &radius, &lon_0, &lat_0, &lat_1, &lat_2);
+
+          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);
+            }
+        }
 
-  return leadtime_id;
+      cdf_enddef(fileID);
+    }
 }
 
+
 static
-void find_time_vars(int nvars, ncvar_t *ncvars, ncdim_t *ncdims, int timedimid, stream_t *streamptr,
-                    bool *time_has_units, bool *time_has_bounds, bool *time_climatology)
+void cdfDefGrid(stream_t *streamptr, int gridID)
 {
-  int ncvarid;
+  int vlistID = streamptr->vlistID;
+  int gridindex = vlistGridIndex(vlistID, gridID);
+  if ( streamptr->xdimID[gridindex] != UNDEFID ) return;
 
-  if ( timedimid == CDI_UNDEFID )
-    {
-      char timeunits[CDI_MAX_NAME];
+  int gridtype = gridInqType(gridID);
+  int size     = gridInqSize(gridID);
 
-      for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
+  if ( CDI_Debug )
+    Message("gridtype = %d  size = %d", gridtype, size);
+
+  if ( gridtype == GRID_GAUSSIAN ||
+       gridtype == GRID_LONLAT   ||
+       gridtype == GRID_GENERIC )
+    {
+      if ( gridtype == GRID_GENERIC )
         {
-          if ( ncvars[ncvarid].ndims == 0 && strcmp(ncvars[ncvarid].name, "time") == 0 )
+          if ( size == 1 && gridInqXsize(gridID) == 0 && gridInqYsize(gridID) == 0 )
             {
-              if ( ncvars[ncvarid].units[0] )
+              /* no grid information */
+            }
+          else
+            {
+              int lx = 0, ly = 0;
+              if ( gridInqXsize(gridID) > 0 /*&& gridInqXvals(gridID, NULL) > 0*/ )
                 {
-                  strcpy(timeunits, ncvars[ncvarid].units);
-                  str_tolower(timeunits);
+                  cdfDefXaxis(streamptr, gridID, 1);
+                  lx = 1;
+                }
 
-                  if ( is_time_units(timeunits) )
-                    {
-                      streamptr->basetime.ncvarid = ncvarid;
-                      break;
-                    }
+              if ( gridInqYsize(gridID) > 0 /*&& gridInqYvals(gridID, NULL) > 0*/ )
+                {
+                  cdfDefYaxis(streamptr, gridID, 1);
+                  ly = 1;
                 }
+
+              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);
+
+      cdfDefMapping(streamptr, gridID);
+    }
+  /*
+  else if ( gridtype == GRID_LCC )
+    {
+      cdfDefLcc(streamptr, gridID);
+    }
+  */
   else
     {
-      bool ltimevar = false;
+      Error("Unsupported grid type: %s", gridNamePtr(gridtype));
+    }
+}
+
+static
+void scale_add(size_t size, double *data, double addoffset, double scalefactor)
+{
+  int laddoffset;
+  int lscalefactor;
+
+  laddoffset   = IS_NOT_EQUAL(addoffset, 0);
+  lscalefactor = IS_NOT_EQUAL(scalefactor, 1);
 
-      if ( ncdims[timedimid].ncvarid != CDI_UNDEFID )
+  if ( laddoffset || lscalefactor )
+    {
+      for (size_t i = 0; i < size; ++i )
         {
-          streamptr->basetime.ncvarid = ncdims[timedimid].ncvarid;
-          ltimevar = true;
+          if ( lscalefactor ) data[i] *= scalefactor;
+          if ( laddoffset )   data[i] += addoffset;
         }
+    }
+}
 
-      for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
-        if ( ncvarid != streamptr->basetime.ncvarid &&
-             ncvars[ncvarid].ndims == 1 &&
-             timedimid == ncvars[ncvarid].dimids[0] &&
-             !xtypeIsText(ncvars[ncvarid].xtype) &&
-             is_timeaxis_units(ncvars[ncvarid].units) )
-          {
-            ncvars[ncvarid].isvar = FALSE;
+static
+void cdfCreateRecords(stream_t *streamptr, int tsID)
+{
+  if ( tsID < 0 || (tsID >= streamptr->ntsteps && tsID > 0) ) return;
 
-            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);
-              }
-          }
+  if ( streamptr->tsteps[tsID].nallrecs > 0 ) return;
 
-      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;
-              }
-        }
+  int vlistID  = streamptr->vlistID;
 
-      /* time varID */
-      ncvarid = streamptr->basetime.ncvarid;
+  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 )
+    {
+      int nvrecs = nrecs; /* use all records at first timestep */
 
-      if ( ncvarid == CDI_UNDEFID )
+      streamptr->nrecs += nrecs;
+
+      destTstep->records    = (record_t *) Malloc((size_t)nrecs*sizeof(record_t));
+      destTstep->nrecs      = nrecs;
+      destTstep->nallrecs   = nrecs;
+      destTstep->recordSize = nrecs;
+      destTstep->curRecID   = UNDEFID;
+      destTstep->recIDs     = (int *) Malloc((size_t)nvrecs*sizeof (int));;
+      for ( int recID = 0; recID < nvrecs; recID++ ) destTstep->recIDs[recID] = recID;
+
+      record_t *records = destTstep->records;
+
+      for ( int varID = 0, recID = 0; varID < nvars; varID++ )
         {
-          Warning("Time variable >%s< not found!", ncdims[timedimid].name);
+          int zaxisID = vlistInqVarZaxis(vlistID, varID);
+          int nlev    = zaxisInqSize(zaxisID);
+          for ( int levelID = 0; levelID < nlev; levelID++ )
+            {
+              recordInitEntry(&records[recID]);
+              records[recID].varID   = (short)varID;
+              records[recID].levelID = (short)levelID;
+              recID++;
+            }
         }
     }
+  else if ( tsID == 1 )
+    {
+      int nvrecs = 0;
+      for ( int varID = 0; varID < nvars; varID++ )
+        {
+          if ( vlistInqVarTsteptype(vlistID, varID) != TSTEP_CONSTANT )
+            {
+              int zaxisID = vlistInqVarZaxis(vlistID, varID);
+              nvrecs += zaxisInqSize(zaxisID);
+            }
+        }
 
-  /* time varID */
-  ncvarid = streamptr->basetime.ncvarid;
+      streamptr->nrecs += nvrecs;
 
-  if ( ncvarid != CDI_UNDEFID && streamptr->basetime.lwrf == false )
-    {
-      if ( ncvars[ncvarid].units[0] != 0 ) *time_has_units = true;
+      destTstep->records    = (record_t *) Malloc((size_t)nrecs*sizeof(record_t));
+      destTstep->nrecs      = nvrecs;
+      destTstep->nallrecs   = nrecs;
+      destTstep->recordSize = nrecs;
+      destTstep->curRecID   = UNDEFID;
+
+      memcpy(destTstep->records, sourceTstep->records, (size_t)nrecs*sizeof(record_t));
 
-      if ( ncvars[ncvarid].bounds != CDI_UNDEFID )
+      if ( nvrecs )
         {
-          int nbdims = ncvars[ncvars[ncvarid].bounds].ndims;
-          if ( nbdims == 2 )
+          destTstep->recIDs = (int *) Malloc((size_t)nvrecs * sizeof (int));
+          for ( int recID = 0, vrecID = 0; recID < nrecs; recID++ )
             {
-              int len = (int) ncdims[ncvars[ncvars[ncvarid].bounds].dimids[nbdims-1]].len;
-              if ( len == 2 && timedimid == ncvars[ncvars[ncvarid].bounds].dimids[0] )
+              int varID = destTstep->records[recID].varID;
+              if ( vlistInqVarTsteptype(vlistID, varID) != TSTEP_CONSTANT )
                 {
-                  *time_has_bounds = true;
-                  streamptr->basetime.ncvarboundsid = ncvars[ncvarid].bounds;
-                  if ( ncvars[ncvarid].climatology ) *time_climatology = true;
+                  destTstep->recIDs[vrecID++] = recID;
                 }
             }
         }
     }
+  else
+    {
+      if ( streamptr->tsteps[1].records == 0 ) cdfCreateRecords(streamptr, 1);
+
+      int nvrecs = streamptr->tsteps[1].nrecs;
+
+      streamptr->nrecs += nvrecs;
+
+      destTstep->records    = (record_t *) Malloc((size_t)nrecs*sizeof(record_t));
+      destTstep->nrecs      = nvrecs;
+      destTstep->nallrecs   = nrecs;
+      destTstep->recordSize = nrecs;
+      destTstep->curRecID   = UNDEFID;
+
+      memcpy(destTstep->records, sourceTstep->records, (size_t)nrecs*sizeof(record_t));
+
+      destTstep->recIDs     = (int *) Malloc((size_t)nvrecs * sizeof(int));
+
+      memcpy(destTstep->recIDs, streamptr->tsteps[1].recIDs, (size_t)nvrecs*sizeof(int));
+    }
 }
 
+
 static
-void read_vct_echam(int fileID, int nvars, ncvar_t *ncvars, ncdim_t *ncdims, double **vct, size_t *pvctsize)
+int cdfTimeDimID(int fileID, int ndims, int nvars)
 {
-  /* find ECHAM VCT */
-  int nvcth_id = CDI_UNDEFID, vcta_id = CDI_UNDEFID, vctb_id = CDI_UNDEFID;
+  for ( int dimid = 0; dimid < ndims; dimid++ )
+    {
+      char dimname[80];
+      cdf_inq_dimname(fileID, dimid, dimname);
+      if ( memcmp(dimname, "time", 4) == 0 )
+        return dimid;
+    }
 
-  for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
+
+  for ( int varid = 0; varid < nvars; varid++ )
     {
-      if ( ncvars[ncvarid].ndims == 1 )
+      int nvdims, nvatts, dimids[9];
+      cdf_inq_var(fileID, varid, NULL, NULL, &nvdims, dimids, &nvatts);
+      if ( nvdims == 1 )
         {
-          size_t len = strlen(ncvars[ncvarid].name);
-          if ( len == 4 && ncvars[ncvarid].name[0] == 'h' && ncvars[ncvarid].name[1] == 'y' )
+          for ( int iatt = 0; iatt < nvatts; iatt++ )
             {
-              if ( ncvars[ncvarid].name[2] == 'a' && ncvars[ncvarid].name[3] == 'i' ) // hyai
-                {
-                  vcta_id = ncvarid;
-                  nvcth_id = ncvars[ncvarid].dimids[0];
-                  ncvars[ncvarid].isvar = FALSE;
-                }
-              else if ( ncvars[ncvarid].name[2] == 'b' && ncvars[ncvarid].name[3] == 'i' ) //hybi
-                {
-                  vctb_id = ncvarid;
-                  nvcth_id = ncvars[ncvarid].dimids[0];
-                  ncvars[ncvarid].isvar = FALSE;
-                }
-              else if ( (ncvars[ncvarid].name[2] == 'a' || ncvars[ncvarid].name[2] == 'b') && ncvars[ncvarid].name[3] == 'm' )
+              char sbuf[CDI_MAX_NAME];
+              cdf_inq_attname(fileID, varid, iatt, sbuf);
+              if ( strncmp(sbuf, "units", 5) == 0 )
                 {
-                  ncvars[ncvarid].isvar = FALSE; // hyam or hybm
+                  cdfGetAttText(fileID, varid, "units", sizeof(sbuf), sbuf);
+                  strtolower(sbuf);
+
+                  if ( isTimeUnits(sbuf) )
+                    return dimids[0];
                 }
             }
-	}
+        }
     }
 
-  /* read VCT */
-  if ( nvcth_id != CDI_UNDEFID && vcta_id != CDI_UNDEFID && vctb_id != CDI_UNDEFID )
+  return UNDEFID;
+}
+
+static
+void init_ncdims(long ndims, ncdim_t *ncdims)
+{
+  for ( long ncdimid = 0; ncdimid < ndims; ncdimid++ )
     {
-      size_t 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);
-      *pvctsize = vctsize;
+      ncdims[ncdimid].ncvarid      = UNDEFID;
+      ncdims[ncdimid].dimtype      = UNDEFID;
+      ncdims[ncdimid].len          = 0;
+      ncdims[ncdimid].name[0]      = 0;
     }
 }
 
 static
-void cdf_set_ucla_dimtype(int ndims, ncdim_t *ncdims, ncvar_t *ncvars)
+void init_ncvars(long nvars, ncvar_t *ncvars)
 {
-  for ( int ncdimid = 0; ncdimid < ndims; ncdimid++ )
+  for ( long ncvarid = 0; ncvarid < nvars; ++ncvarid )
     {
-      int ncvarid = ncdims[ncdimid].ncvarid;
-      if ( ncvarid != -1 )
-        {
-          if ( ncdims[ncdimid].dimtype == CDI_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;
-            }
-        }
+      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].lformula        = FALSE;
+      ncvars[ncvarid].lformulaterms   = FALSE;
+      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].psvarid         = UNDEFID;
+      ncvars[ncvarid].p0varid         = 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].vctsize         = 0;
+      ncvars[ncvarid].vct             = 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;
     }
 }
 
 static
-int cdf_check_vars(int nvars, ncvar_t *ncvars, size_t ntsteps, int timedimid)
+void cdfSetVar(ncvar_t *ncvars, int ncvarid, short isvar)
 {
-  for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
+  if ( ncvars[ncvarid].isvar != UNDEFID &&
+       ncvars[ncvarid].isvar != isvar   &&
+       ncvars[ncvarid].warn  == FALSE )
     {
-      if ( timedimid != CDI_UNDEFID )
-	if ( ncvars[ncvarid].isvar == -1 &&
-	     ncvars[ncvarid].ndims > 1   &&
-	     timedimid == ncvars[ncvarid].dimids[0] )
-	  cdf_set_var(ncvars, ncvarid, TRUE);
+      if ( ! ncvars[ncvarid].ignore )
+        Warning("Inconsistent variable definition for %s!", ncvars[ncvarid].name);
 
-      if ( ncvars[ncvarid].isvar == -1 && ncvars[ncvarid].ndims == 0 )
-	cdf_set_var(ncvars, ncvarid, FALSE);
+      ncvars[ncvarid].warn = TRUE;
+      isvar = FALSE;
+    }
 
-      //if ( ncvars[ncvarid].isvar == -1 && ncvars[ncvarid].ndims > 1 )
-      if ( ncvars[ncvarid].isvar == -1 && ncvars[ncvarid].ndims >= 1 )
-	cdf_set_var(ncvars, ncvarid, TRUE);
+  ncvars[ncvarid].isvar = isvar;
+}
 
-      if ( ncvars[ncvarid].isvar == -1 )
-	{
-	  ncvars[ncvarid].isvar = 0;
-	  Warning("Variable %s has an unknown type, skipped!", ncvars[ncvarid].name);
-	  continue;
-	}
+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);
+    }
 
-      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;
-	}
+  ncvars[ncvarid].dimtype[dimid] = dimtype;
+}
 
-      if ( ncvars[ncvarid].ndims == 4 && timedimid == CDI_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;
-	}
+static
+bool isLonAxis(const char *units, const char *stdname)
+{
+  bool status = false;
+  char lc_units[16];
 
-      if ( xtypeIsText(ncvars[ncvarid].xtype) )
-	{
-	  ncvars[ncvarid].isvar = 0;
-	  continue;
-	}
+  memcpy(lc_units, units, 15);
+  lc_units[15] = 0;
+  strtolower(lc_units);
 
-      if ( cdfInqDatatype(ncvars[ncvarid].xtype, ncvars[ncvarid].lunsigned) == -1 )
-	{
-	  ncvars[ncvarid].isvar = 0;
-	  Warning("Unsupported data type, skipped variable %s!", ncvars[ncvarid].name);
-	  continue;
-	}
+  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;
+    }
 
-      if ( timedimid != CDI_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;
-	    }
-	}
+  if ( status == false &&
+       memcmp(stdname, "grid_latitude", 13) && memcmp(stdname, "latitude", 8) &&
+       memcmp(lc_units, "degree", 6) == 0 )
+    {
+      int ioff = 6;
+      if ( lc_units[ioff] == 's' ) ioff++;
+      if ( lc_units[ioff] == '_' ) ioff++;
+      if ( lc_units[ioff] == 'e' ) status = true;
     }
 
-  return timedimid;
+  return status;
 }
 
+static
+bool isLatAxis(const char *units, const char *stdname)
+{
+  bool status = false;
+  char lc_units[16];
 
-int cdfInqContents(stream_t *streamptr)
+  memcpy(lc_units, units, 15);
+  lc_units[15] = 0;
+  strtolower(lc_units);
+
+  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;
+    }
+
+  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' || lc_units[ioff] == 's' ) status = true;
+    }
+
+  return status;
+}
+
+static
+bool isDBLAxis(/*const char *units,*/ const char *longname)
 {
-  int ndims, nvars, ngatts, unlimdimid;
-  int ncvarid;
-  int ncdimid;
-  int *varids;
-  int nvarids;
-  bool time_has_units = false;
-  bool time_has_bounds = false;
-  bool time_climatology = false;
-  int leadtime_id = CDI_UNDEFID;
-  int nvars_data;
-  int instID  = CDI_UNDEFID;
-  int modelID = CDI_UNDEFID;
-  int calendar = CDI_UNDEFID;
-  int format = 0;
-  bool ucla_les = false;
-  char gridfile[8912];
-  char fcreftime[CDI_MAX_NAME];
-  int number_of_grid_used = CDI_UNDEFID;
+  bool status = false;
 
-  unsigned char uuidOfHGrid[CDI_UUID_SIZE];
-  unsigned char uuidOfVGrid[CDI_UUID_SIZE];
-  memset(uuidOfHGrid, 0, CDI_UUID_SIZE);
-  memset(uuidOfVGrid, 0, CDI_UUID_SIZE);
-  gridfile[0] = 0;
-  fcreftime[0] = 0;
+  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;
+    }
+
+  return status;
+}
+
+static
+bool unitsIsHeight(const char *units)
+{
+  bool status = false;
+  int u0 = units[0];
+
+  if ( (u0=='m' && (!units[1] || strncmp(units, "meter", 5) == 0)) ||
+       (!units[2] && units[1]=='m' && (u0=='c' || u0=='d' || u0=='k')) )
+    {
+      status = true;
+    }
+
+  return status;
+}
+
+static
+bool isDepthAxis(const char *stdname, const char *longname)
+{
+  bool status = false;
+
+  if ( strcmp(stdname, "depth") == 0 )
+    status = true;
+  else
+    if ( strcmp(longname, "depth_below_sea") == 0 ||
+         strcmp(longname, "depth below sea") == 0 )
+      {
+        status = true;
+      }
 
-  int vlistID = streamptr->vlistID;
-  int fileID  = streamptr->fileID;
+  return status;
+}
 
-  if ( CDI_Debug ) Message("streamID = %d, fileID = %d", streamptr->self, fileID);
+static
+bool isHeightAxis(const char *stdname, const char *longname)
+{
+  bool status = false;
 
-#if  defined  (HAVE_NETCDF4)
-  nc_inq_format(fileID, &format);
-#endif
+  if ( strcmp(stdname, "height") == 0 )
+    status = true;
+  else
+    if ( strcmp(longname, "height") == 0 ||
+         strcmp(longname, "height above the surface") == 0 )
+      {
+        status = true;
+      }
 
-  cdf_inq(fileID, &ndims , &nvars, &ngatts, &unlimdimid);
+  return status;
+}
 
-  if ( CDI_Debug )
-    Message("root: ndims %d, nvars %d, ngatts %d", ndims, nvars, ngatts);
+static
+bool unitsIsPressure(const char *units)
+{
+  bool status = false;
 
-  if ( ndims == 0 )
+  if ( strncmp(units, "millibar", 8) == 0 ||
+       strncmp(units, "mb", 2)       == 0 ||
+       strncmp(units, "hectopas", 8) == 0 ||
+       strncmp(units, "hPa", 3)      == 0 ||
+       strncmp(units, "Pa", 2)       == 0 )
     {
-      Warning("No dimensions found!");
-      return CDI_EUFSTRUCT;
+      status = true;
     }
 
-  /* alloc ncdims */
-  ncdim_t *ncdims = (ncdim_t *) Malloc((size_t)ndims * sizeof (ncdim_t));
-  init_ncdims(ndims, ncdims);
+  return status;
+}
 
-#if  defined  (TEST_GROUPS)
-#if  defined  (HAVE_NETCDF4)
-  if ( format == NC_FORMAT_NETCDF4 )
+static
+int scan_hybrid_formula(int ncid, int ncfvarid, int *apvarid, int *bvarid, int *psvarid, int *avarid, int *p0varid)
+{
+  int status = 0;
+  *apvarid = -1;
+  *bvarid  = -1;
+  *psvarid = -1;
+  *avarid  = -1;
+  *p0varid = -1;
+  enum { attstringlen = 8192 }; char attstring[attstringlen];
+  cdfGetAttText(ncid, ncfvarid, "formula", attstringlen, attstring);
+  if ( strcmp(attstring, "p = ap + b*ps") == 0 )
     {
-      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 )
+      status = 1;
+      int lstop = FALSE;
+      int dimvarid;
+      cdfGetAttText(ncid, ncfvarid, "formula_terms", attstringlen, attstring);
+      char *pstring = attstring;
+
+      for ( int i = 0; i < 3; i++ )
         {
-          ncid = ncids[i];
-          nc_inq_grpname(ncid, name1);
-          cdf_inq(ncid, &gndims , &gnvars, &gngatts, &gunlimdimid);
+          while ( isspace((int) *pstring) ) pstring++;
+          if ( *pstring == 0 ) break;
+          char *tagname = pstring;
+          while ( !isspace((int) *pstring) && *pstring != 0 ) pstring++;
+          if ( *pstring == 0 ) lstop = TRUE;
+          *pstring++ = 0;
+
+          while ( isspace((int) *pstring) ) pstring++;
+          if ( *pstring == 0 ) break;
+          char *varname = pstring;
+          while ( !isspace((int) *pstring) && *pstring != 0 ) pstring++;
+          if ( *pstring == 0 ) lstop = TRUE;
+          *pstring++ = 0;
+
+          int status_nc = nc_inq_varid(ncid, varname, &dimvarid);
+          if ( status_nc == NC_NOERR )
+            {
+              if      ( strcmp(tagname, "ap:") == 0 ) *apvarid = dimvarid;
+              else if ( strcmp(tagname, "b:")  == 0 ) *bvarid  = dimvarid;
+              else if ( strcmp(tagname, "ps:") == 0 ) *psvarid = dimvarid;
+            }
+          else if ( strcmp(tagname, "ps:") != 0 )
+            {
+              Warning("%s - %s", nc_strerror(status_nc), varname);
+            }
 
-          if ( CDI_Debug )
-            Message("%s: ndims %d, nvars %d, ngatts %d", name1, gndims, gnvars, gngatts);
+          if ( lstop ) break;
+        }
+    }
+  else if ( strcmp(attstring, "xxxp = a*p0 + b*ps") == 0 )
+    {
+      status = 2;
+      int lstop = FALSE;
+      int dimvarid;
+      cdfGetAttText(ncid, ncfvarid, "formula_terms", attstringlen, attstring);
+      char *pstring = attstring;
 
-          if ( gndims == 0 )
+      for ( int i = 0; i < 4; i++ )
+        {
+          while ( isspace((int) *pstring) ) pstring++;
+          if ( *pstring == 0 ) break;
+          char *tagname = pstring;
+          while ( !isspace((int) *pstring) && *pstring != 0 ) pstring++;
+          if ( *pstring == 0 ) lstop = TRUE;
+          *pstring++ = 0;
+
+          while ( isspace((int) *pstring) ) pstring++;
+          if ( *pstring == 0 ) break;
+          char *varname = pstring;
+          while ( !isspace((int) *pstring) && *pstring != 0 ) pstring++;
+          if ( *pstring == 0 ) lstop = TRUE;
+          *pstring++ = 0;
+
+          int status_nc = nc_inq_varid(ncid, varname, &dimvarid);
+          if ( status_nc == NC_NOERR )
+            {
+              if      ( strcmp(tagname, "a:")  == 0 ) *avarid  = dimvarid;
+              else if ( strcmp(tagname, "b:")  == 0 ) *bvarid  = dimvarid;
+              else if ( strcmp(tagname, "ps:") == 0 ) *psvarid = dimvarid;
+              else if ( strcmp(tagname, "p0:") == 0 ) *p0varid = dimvarid;
+            }
+          else if ( strcmp(tagname, "ps:") != 0 )
             {
+              Warning("%s - %s", nc_strerror(status_nc), varname);
             }
+
+          if ( lstop ) break;
         }
     }
-#endif
-#endif
 
-  if ( nvars == 0 )
+  return status;
+}
+
+static
+bool isHybridSigmaPressureCoordinate(int ncid, int ncvarid, ncvar_t *ncvars, const ncdim_t *ncdims)
+{
+  bool status = false;
+  int ncfvarid = ncvarid;
+  ncvar_t *ncvar = &ncvars[ncvarid];
+
+  if ( strcmp(ncvar->stdname, "atmosphere_hybrid_sigma_pressure_coordinate") == 0 )
     {
-      Warning("No arrays found!");
-      return CDI_EUFSTRUCT;
-    }
+      cdiConvention = CDI_CONVENTION_CF;
 
-  /* alloc ncvars */
-  ncvar_t *ncvars = (ncvar_t *) Malloc((size_t)nvars * sizeof (ncvar_t));
-  init_ncvars(nvars, ncvars);
+      status = true;
+      ncvar->zaxistype = ZAXIS_HYBRID;
+      int dimid = ncvar->dimids[0];
+      size_t dimlen = ncdims[dimid].len;
 
-  for ( ncvarid = 0; ncvarid < nvars; ++ncvarid ) ncvars[ncvarid].ncid = fileID;
+      int ret;
+      int apvarid1 = -1, bvarid1 = -1, psvarid1 = -1, avarid1 = -1, p0varid1 = -1;
+      if ( ncvars[ncfvarid].lformula && ncvars[ncfvarid].lformulaterms )
+        ret = scan_hybrid_formula(ncid, ncfvarid, &apvarid1, &bvarid1, &psvarid1, &avarid1, &p0varid1);
+      if ( apvarid1 != -1 ) ncvars[apvarid1].isvar = FALSE;
+      if ( bvarid1  != -1 ) ncvars[bvarid1].isvar  = FALSE;
+      if ( psvarid1 != -1 ) ncvar->psvarid = psvarid1;
+      if ( avarid1  != -1 ) ncvars[avarid1].isvar = FALSE;
+      if ( p0varid1 != -1 ) ncvar->p0varid = p0varid1;
 
+      if ( ncvar->bounds != UNDEFID && ncvars[ncvar->bounds].lformula && ncvars[ncvar->bounds].lformulaterms )
+        {
+          ncfvarid = ncvar->bounds;
+          int apvarid2 = -1, bvarid2 = -1, psvarid2 = -1, avarid2 = -1, p0varid2 = -1;
+          ret = 0;
+          if ( ncvars[ncfvarid].lformula && ncvars[ncfvarid].lformulaterms )
+            ret = scan_hybrid_formula(ncid, ncfvarid, &apvarid2, &bvarid2, &psvarid2, &avarid2, &p0varid2);
+          if ( ret == 1 ) avarid2 = apvarid2;
+          if ( avarid2 != -1 && bvarid2 != -1 )
+            {
+              ncvars[avarid2].isvar = FALSE;
+              ncvars[bvarid2].isvar  = FALSE;
 
-  /* scan global attributes */
-  cdf_scan_global_attr(fileID, vlistID, streamptr, ngatts, &instID, &modelID, &ucla_les,
-                       uuidOfHGrid, uuidOfVGrid, gridfile, &number_of_grid_used);
+              if ( dimid == ncvars[avarid2].dimids[0] && ncdims[ncvars[avarid2].dimids[1]].len == 2 )
+                {
+                  double px = 1;
+                  if ( ret == 2 && p0varid1 == p0varid2 )
+                    cdf_get_var_double(ncid, p0varid2, &px);
 
-  /* find time dim */
-  int timedimid = (unlimdimid >= 0) ? unlimdimid : cdf_time_dimid(fileID, ndims, nvars);
+                  double abuf[dimlen*2], bbuf[dimlen*2];
+                  cdf_get_var_double(ncid, avarid2, abuf);
+                  cdf_get_var_double(ncid, bvarid2, bbuf);
+                  /*
+                  for ( int i = 0; i < dimlen; ++i )
+                    printf("%d  %g %g    %g %g\n", i, abuf[i*2], abuf[i*2+1], bbuf[i*2], bbuf[i*2+1]);
+                  */
+                  size_t vctsize = (dimlen+1)*2;
+                  double *vct = (double *) Malloc(vctsize * sizeof(double));
+                  for ( size_t i = 0; i < dimlen; ++i )
+                    {
+                      vct[i] = abuf[i*2];
+                      vct[i+dimlen+1] = bbuf[i*2];
+                    }
+                  vct[dimlen]     = abuf[dimlen*2-1];
+                  vct[dimlen*2+1] = bbuf[dimlen*2-1];
 
-  streamptr->basetime.ncdimid = timedimid;
+                  if ( ret == 2 && IS_NOT_EQUAL(px, 1) )
+                    for ( size_t i = 0; i < dimlen+1; ++i ) vct[i] *= px;
 
-  size_t ntsteps = 0;
-  if ( timedimid != CDI_UNDEFID ) cdf_inq_dimlen(fileID, timedimid, &ntsteps);
-  if ( ntsteps > INT_MAX )
-    {
-      Warning("Size limit exceeded for time dimension (limit=%d)!", INT_MAX);
-      return CDI_EDIMSIZE;
+                  ncvar->vct = vct;
+                  ncvar->vctsize = vctsize;
+                }
+            }
+        }
     }
 
-  if ( CDI_Debug ) Message("Number of timesteps = %zu", ntsteps);
-  if ( CDI_Debug ) Message("Time dimid = %d", streamptr->basetime.ncdimid);
+  return status;
+}
 
-  /* read ncdims */
-  for ( ncdimid = 0; ncdimid < ndims; ncdimid++ )
+
+static
+int isGaussGrid(size_t ysize, double yinc, const double *yvals)
+{
+  int lgauss = FALSE;
+  double *yv, *yw;
+
+  if ( IS_EQUAL(yinc, 0) && ysize > 2 ) /* check if gaussian */
     {
-      cdf_inq_dimlen(fileID, ncdimid, &ncdims[ncdimid].len);
-      cdf_inq_dimname(fileID, ncdimid, ncdims[ncdimid].name);
-      if ( timedimid == ncdimid )
-	ncdims[ncdimid].dimtype = T_AXIS;
-    }
+      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;
 
-  if ( CDI_Debug ) cdf_print_vars(ncvars, nvars, "cdf_scan_var_attr");
+      if ( i == ysize ) lgauss = TRUE;
 
-  /* scan attributes of all variables */
-  cdf_scan_var_attr(nvars, ncvars, ncdims, timedimid, modelID, format);
+      /* 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;
+        }
 
-  if ( CDI_Debug ) cdf_print_vars(ncvars, nvars, "find coordinate vars");
+      Free(yv);
+    }
 
-  /* find coordinate vars */
-  for ( ncdimid = 0; ncdimid < ndims; ncdimid++ )
+  return (lgauss);
+}
+
+static
+void printNCvars(const ncvar_t *ncvars, int nvars, const char *oname)
+{
+  char axis[7];
+  int ncvarid, i;
+  int ndim;
+  static const char iaxis[] = {'t', 'z', 'y', 'x'};
+
+  fprintf(stderr, "%s:\n", oname);
+
+  for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
     {
-      for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
-	{
-	  if ( ncvars[ncvarid].ndims == 1 )
-	    {
-	      if ( timedimid != CDI_UNDEFID && timedimid == ncvars[ncvarid].dimids[0] )
-		{
-		  if ( ncvars[ncvarid].isvar != FALSE ) cdf_set_var(ncvars, ncvarid, TRUE);
-		}
-	      else
-		{
-                  //  if ( ncvars[ncvarid].isvar != TRUE ) cdf_set_var(ncvars, ncvarid, FALSE);
-		}
-	      // if ( ncvars[ncvarid].isvar != TRUE ) cdf_set_var(ncvars, ncvarid, FALSE);
+      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++] = '?';
+        }
 
-	      if ( ncdimid == ncvars[ncvarid].dimids[0] && ncdims[ncdimid].ncvarid == CDI_UNDEFID )
-		if ( strcmp(ncvars[ncvarid].name, ncdims[ncdimid].name) == 0 )
-		  {
-		    ncdims[ncdimid].ncvarid = ncvarid;
-		    ncvars[ncvarid].isvar = FALSE;
-		  }
-	    }
-	}
+      axis[ndim++] = 0;
+
+      fprintf(stderr, "%3d %3d  %-6s %s\n", ncvarid, ndim-3, axis, ncvars[ncvarid].name);
     }
+}
 
-  /* find time vars */
-  find_time_vars(nvars, ncvars, ncdims, timedimid, streamptr, &time_has_units, &time_has_bounds, &time_climatology);
+static
+void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
+                          int timedimid, int modelID, int format)
+{
+  int ncid;
+  int ncdimid;
+  int nvdims, nvatts;
+  int *dimidsp;
+  int iatt;
+  nc_type xtype, atttype;
+  size_t attlen;
+  char name[CDI_MAX_NAME];
+  char attname[CDI_MAX_NAME];
+  const int attstringlen = 8192; char attstring[8192];
 
-  leadtime_id = find_leadtime(nvars, ncvars);
-  if ( leadtime_id != CDI_UNDEFID ) ncvars[leadtime_id].isvar = FALSE;
+  int nchecked_vars = 0;
+  enum { max_check_vars = 9 };
+  char *checked_vars[max_check_vars];
+  for ( int i = 0; i < max_check_vars; ++i ) checked_vars[i] = NULL;
 
-  /* check ncvars */
-  timedimid = cdf_check_vars(nvars, ncvars, ntsteps, timedimid);
+  for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
+    {
+      ncid    = ncvars[ncvarid].ncid;
+      dimidsp = ncvars[ncvarid].dimids;
 
-  /* verify coordinate vars - first scan (dimname == varname) */
-  bool lhybrid_cf = false;
-  verify_coordinate_vars_1(fileID, ndims, ncdims, ncvars, timedimid, &lhybrid_cf);
+      cdf_inq_var(ncid, ncvarid, name, &xtype, &nvdims, dimidsp, &nvatts);
+      strcpy(ncvars[ncvarid].name, name);
 
-  /* verify coordinate vars - second scan (all other variables) */
-  verify_coordinate_vars_2(nvars, ncvars);
+      for ( ncdimid = 0; ncdimid < nvdims; ncdimid++ )
+        ncvars[ncvarid].dimtype[ncdimid] = -1;
 
-  if ( CDI_Debug ) cdf_print_vars(ncvars, nvars, "verify_coordinate_vars");
+      ncvars[ncvarid].xtype = xtype;
+      ncvars[ncvarid].ndims = nvdims;
 
-  if ( ucla_les ) cdf_set_ucla_dimtype(ndims, ncdims, ncvars);
+#if  defined  (HAVE_NETCDF4)
+      if ( format == NC_FORMAT_NETCDF4_CLASSIC || format == NC_FORMAT_NETCDF4 )
+        {
+          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;
 
-  /*
-  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 ( 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, "%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");
+                    }
+                  {
+                    char *buf = ncvars[ncvarid].extra;
+                    size_t pos = strlen(buf);
+                    static const char prefix[] = "chunks=";
+                    memcpy(buf + pos, prefix, sizeof (prefix));
+                    pos += sizeof (prefix) - 1;
+                    for ( int i = nvdims-1; i >= 0; --i )
+                      {
+                        pos += (size_t)(sprintf(buf + pos, "%zu%s", chunks[i],
+                                                i > 0 ? "x" : ""));
+                      }
+                    buf[pos] = ' '; buf[pos + 1] = 0;
+                  }
+                }
+            }
+        }
+#endif
 
-	  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 ( 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;
+                    }
+                }
+            }
+        }
 
-  /* Set coordinate varids (att: associate)  */
-  for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
-    {
-      ncvar_t *ncvar = &ncvars[ncvarid];
-      if ( ncvar->isvar == TRUE && ncvar->ncoordvars )
-	{
-	  int ncoordvars = ncvar->ncoordvars;
-	  for ( int i = 0; i < ncoordvars; i++ )
-	    {
-	      if      ( ncvars[ncvar->coordvarids[i]].islon ||
-                        ncvars[ncvar->coordvarids[i]].isx )   ncvar->xvarid = ncvar->coordvarids[i];
-	      else if ( ncvars[ncvar->coordvarids[i]].islat ||
-                        ncvars[ncvar->coordvarids[i]].isy )   ncvar->yvarid = ncvar->coordvarids[i];
-	      else if ( ncvars[ncvar->coordvarids[i]].islev ) ncvar->zvarid = ncvar->coordvarids[i];
-	      else if ( ncvars[ncvar->coordvarids[i]].isc )   ncvar->cvarids[i] = ncvar->coordvarids[i];
-	    }
-	}
-    }
+      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);
 
-  /* set dim type */
-  cdf_set_dimtype(nvars, ncvars, ncdims);
+          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) )
+            {
+              int tablenum;
+              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);
+
+              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);
+                    }
+                }
 
-  /* read ECHAM VCT if present */
-  size_t vctsize = 0;
-  double *vct = NULL;
-  if ( !lhybrid_cf ) read_vct_echam(fileID, nvars, ncvars, ncdims, &vct, &vctsize);
+              cdfSetVar(ncvars, ncvarid, TRUE);
+            }
+          else if ( strcmp(attname, "level_type") == 0 && xtypeIsText(atttype) )
+            {
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
+              strtolower(attstring);
+
+              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);
+                    }
+                }
+
+              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) )
+            {
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
+              int ncboundsid;
+              int status = nc_inq_varid(ncid, attstring, &ncboundsid);
+              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 ( xtypeIsText(atttype) && strcmp(attname, "bounds") == 0 )
+            {
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
+              int ncboundsid;
+              int 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 ( xtypeIsText(atttype) && strcmp(attname, "formula_terms") == 0 )
+            {
+              ncvars[ncvarid].lformulaterms = TRUE;
+            }
+          else if ( xtypeIsText(atttype) && strcmp(attname, "formula") == 0 )
+            {
+              ncvars[ncvarid].lformula = TRUE;
+            }
+          else if ( strcmp(attname, "cell_measures") == 0 && xtypeIsText(atttype) )
+            {
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
+              char *pstring = attstring;
 
+              while ( isspace((int) *pstring) ) pstring++;
+              char *cell_measures = pstring;
+              while ( isalnum((int) *pstring) ) pstring++;
+              *pstring++ = 0;
+              while ( isspace((int) *pstring) ) pstring++;
+              char *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 nc_cell_id;
+                  int 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;
 
-  if ( CDI_Debug ) cdf_print_vars(ncvars, nvars, "cdf_define_all_grids");
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
+              pstring = attstring;
 
-  /* define all grids */
-  int status;
-  status = cdf_define_all_grids(streamptr->ncgrid, vlistID, ncdims, nvars, ncvars, timedimid, uuidOfHGrid, gridfile, number_of_grid_used);
-  if ( status < 0 ) return status;
+              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;
 
-  /* define all zaxes */
-  status = cdf_define_all_zaxes(streamptr, vlistID, ncdims, nvars, ncvars, vctsize, vct, uuidOfVGrid);
-  if ( vct ) Free(vct);
-  if ( status < 0 ) return status;
+              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 lstop = FALSE;
+              int dimvarid;
 
-  /* select vars */
-  varids = (int *) Malloc((size_t)nvars * sizeof (int));
-  nvarids = 0;
-  for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
-    if ( ncvars[ncvarid].isvar == TRUE ) varids[nvarids++] = ncvarid;
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
+              char *pstring = attstring;
 
-  nvars_data = nvarids;
+              for ( int i = 0; i < MAX_COORDVARS; i++ )
+                {
+                  while ( isspace((int) *pstring) ) pstring++;
+                  if ( *pstring == 0 ) break;
+                  char *varname = pstring;
+                  while ( !isspace((int) *pstring) && *pstring != 0 ) pstring++;
+                  if ( *pstring == 0 ) lstop = TRUE;
+                  *pstring++ = 0;
 
-  if ( CDI_Debug ) Message("time varid = %d", streamptr->basetime.ncvarid);
-  if ( CDI_Debug ) Message("ntsteps = %zu", ntsteps);
-  if ( CDI_Debug ) Message("nvars_data = %d", nvars_data);
+                  int 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;
 
+                      if ( k == nchecked_vars )
+                        {
+                          if ( nchecked_vars < max_check_vars ) checked_vars[nchecked_vars++] = strdup(varname);
+                          Warning("%s - %s", nc_strerror(status), varname);
+                        }
+                    }
 
-  if ( nvars_data == 0 )
-    {
-      streamptr->ntsteps = 0;
-      return CDI_EUFSTRUCT;
-    }
+                  if ( lstop ) break;
+                }
 
-  if ( ntsteps == 0 && streamptr->basetime.ncdimid == CDI_UNDEFID && streamptr->basetime.ncvarid != CDI_UNDEFID )
-    ntsteps = 1;
+              cdfSetVar(ncvars, ncvarid, TRUE);
+            }
+          else if ( (strcmp(attname, "auxiliary_variable") == 0) && xtypeIsText(atttype) )
+            {
+              int lstop = FALSE;
+              int dimvarid;
 
-  streamptr->ntsteps = (long)ntsteps;
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
+              char *pstring = attstring;
 
-  /* define all data variables */
-  cdf_define_all_vars(streamptr, vlistID, instID, modelID, varids, nvars_data, nvars, ncvars);
+              for ( int i = 0; i < MAX_AUXVARS; i++ )
+                {
+                  while ( isspace((int) *pstring) ) pstring++;
+                  if ( *pstring == 0 ) break;
+                  char *varname = pstring;
+                  while ( !isspace((int) *pstring) && *pstring != 0 ) pstring++;
+                  if ( *pstring == 0 ) lstop = TRUE;
+                  *pstring++ = 0;
 
+                  int 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);
 
-  cdiCreateTimesteps(streamptr);
+                  if ( lstop ) break;
+                }
 
-  /* time varID */
-  int nctimevarid = streamptr->basetime.ncvarid;
+              cdfSetVar(ncvars, ncvarid, TRUE);
+            }
+          else if ( strcmp(attname, "grid_mapping") == 0 && xtypeIsText(atttype) )
+            {
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
+              int nc_gmap_id;
+              int 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 ( time_has_units )
-    {
-      taxis_t *taxis = &streamptr->tsteps[0].taxis;
+              cdfSetVar(ncvars, ncvarid, TRUE);
+            }
+          else if ( strcmp(attname, "positive") == 0 && xtypeIsText(atttype) )
+            {
+              cdfGetAttText(ncid, ncvarid, attname, attstringlen, attstring);
+              strtolower(attstring);
 
-      if ( setBaseTime(ncvars[nctimevarid].units, taxis) == 1 )
-        {
-          nctimevarid = CDI_UNDEFID;
-          streamptr->basetime.ncvarid = CDI_UNDEFID;
-        }
+              if    ( memcmp(attstring, "down", 4) == 0 ) ncvars[ncvarid].positive = POSITIVE_DOWN;
+              else if ( memcmp(attstring, "up", 2) == 0 ) ncvars[ncvarid].positive = POSITIVE_UP;
 
-      if ( leadtime_id != CDI_UNDEFID && taxis->type == TAXIS_RELATIVE )
-        {
-          streamptr->basetime.leadtimeid = leadtime_id;
-          taxis->type = TAXIS_FORECAST;
+              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 = xtypeIsFloat(atttype) != xtypeIsFloat(xtype);
+                  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 = xtypeIsFloat(atttype) != xtypeIsFloat(xtype);
+                  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 = xtypeIsFloat(atttype) != xtypeIsFloat(xtype);
+                  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);
 
-          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;
+              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);
 
-          setForecastTime(fcreftime, taxis);
-        }
-    }
+	      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);
 
-  if ( time_has_bounds )
-    {
-      streamptr->tsteps[0].taxis.has_bounds = true;
-      if ( time_climatology ) streamptr->tsteps[0].taxis.climatology = true;
-    }
+	      if ( (int) attlen > nvdims && nvdims > 0 && attlen > 1 )
+		{
+		    Warning("Unexpected axis attribute length for %s, ignored!", name);
+		}
+              else if ( nvdims == 0 && attlen == 1 )
+                {
+                  if ( attstring[0] == 'z' || attstring[0] == 'Z' )
+                    {
+                      cdfSetVar(ncvars, ncvarid, FALSE);
+                      ncvars[ncvarid].islev = TRUE;
+                    }
+                }
+	      else
+		{
+		  strtolower(attstring);
+                  int i;
+		  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 ( nctimevarid != CDI_UNDEFID )
-    {
-      taxis_t *taxis = &streamptr->tsteps[0].taxis;
-      ptaxisDefName(taxis, ncvars[nctimevarid].name);
+		  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);
+
+                              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 ( 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;
 
-      if ( ncvars[nctimevarid].longname[0] )
-        ptaxisDefLongname(taxis, ncvars[nctimevarid].longname);
+	      if( ncvars[ncvarid].ensdata == NULL )
+		ncvars[ncvarid].ensdata = (ensinfo_t *) Malloc( sizeof( ensinfo_t ) );
 
-      if ( ncvars[nctimevarid].units[0] )
-        ptaxisDefUnits(taxis, ncvars[nctimevarid].units);
+	      cdfGetAttInt(ncid, ncvarid, attname, 1, &temp);
 
-      int datatype = (ncvars[nctimevarid].xtype == NC_FLOAT) ? CDI_DATATYPE_FLT32 : CDI_DATATYPE_FLT64;
-      ptaxisDefDatatype(taxis, datatype);
-    }
+	      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;
 
-  if ( nctimevarid != CDI_UNDEFID )
-    if ( ncvars[nctimevarid].calendar == true )
-      {
-        char attstring[1024];
-	cdfGetAttText(fileID, nctimevarid, "calendar", sizeof(attstring), attstring);
-	str_tolower(attstring);
-        set_calendar(attstring, &calendar);
-      }
+	      cdfSetVar(ncvars, ncvarid, TRUE);
+	    }
+	  else
+	    {
+	      if ( ncvars[ncvarid].natts == 0 )
+		ncvars[ncvarid].atts
+                  = (int *) Malloc((size_t)nvatts * sizeof (int));
 
-  int taxisID;
-  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);
-    }
-  else
-    {
-      taxisID = taxisCreate(TAXIS_ABSOLUTE);
-      if ( !time_has_units )
-	{
-	  taxisDefTunit(taxisID, TUNIT_DAY);
-	  streamptr->tsteps[0].taxis.unit = TUNIT_DAY;
+	      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);
+	      */
+	    }
 	}
     }
 
+  for ( int i = 0; i < max_check_vars; ++i ) if ( checked_vars[i] ) Free(checked_vars[i]);
+}
 
-  if ( calendar == CDI_UNDEFID && streamptr->tsteps[0].taxis.type != TAXIS_ABSOLUTE )
-    {
-      calendar = CALENDAR_STANDARD;
-    }
+static
+void setDimType(int nvars, ncvar_t *ncvars, ncdim_t *ncdims)
+{
+  int ndims;
+  int ncvarid, ncdimid;
+  int i;
 
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic warning "-Wstrict-overflow"
-#endif
-  if ( calendar != CDI_UNDEFID )
+  for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
     {
-      taxis_t *taxis = &streamptr->tsteps[0].taxis;
-      taxis->calendar = calendar;
-      taxisDefCalendar(taxisID, calendar);
-    }
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5)
-#pragma GCC diagnostic pop
-#endif
-
-  vlistDefTaxis(vlistID, taxisID);
-
-  streamptr->curTsID = 0;
-  streamptr->rtsteps = 1;
-
-  (void) cdfInqTimestep(streamptr, 0);
-
-  cdfCreateRecords(streamptr, 0);
-
-  /* free ncdims */
-  Free(ncdims);
-
-  /* free ncvars */
-  Free(ncvars);
+      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);
+	    }
 
-  return 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");
+	    }
 
-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;
-  }
-}
+	  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; */
+	    }
 
-static
-double get_timevalue(int fileID, int nctimevarid, int tsID, timecache_t *tcache)
-{
-  double timevalue = 0;
+          if ( lxdim == FALSE && ncvars[ncvarid].xvarid != UNDEFID )
+            {
+              if (  ncvars[ncvars[ncvarid].xvarid].ndims == 0 ) lxdim = TRUE;
+            }
 
-  if ( tcache )
-    {
-      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;
-          size_t 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 )
+          if ( lydim == FALSE && ncvars[ncvarid].yvarid != UNDEFID )
             {
-              cdf_get_var1_double(fileID, nctimevarid, &index, &timevalue);
-              if ( timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE ) timevalue = 0;
-              tcache->cache[ival] = timevalue;
-              index++;
+              if (  ncvars[ncvars[ncvarid].yvarid].ndims == 0 ) lydim = TRUE;
             }
-        }
 
-      timevalue = tcache->cache[tsID%MAX_TIMECACHE_SIZE];
-    }
-  else
-    {
-      size_t index = (size_t) tsID;
-      cdf_get_var1_double(fileID, nctimevarid, &index, &timevalue);
-      if ( timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE ) timevalue = 0;
+          //   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;
+                      }
+                  }
+              }
+	}
     }
-
-  return timevalue;
 }
 
-
-int cdfInqTimestep(stream_t * streamptr, int tsID)
+/* verify coordinate vars - first scan (dimname == varname) */
+static
+void verify_coordinate_vars_1(int ncid, int ndims, ncdim_t *ncdims, ncvar_t *ncvars, int timedimid)
 {
-  if ( CDI_Debug ) Message("streamID = %d  tsID = %d", streamptr->self, tsID);
+  int ncdimid, ncvarid;
 
-  if ( tsID < 0 ) Error("unexpected tsID = %d", tsID);
-
-  if ( tsID < streamptr->ntsteps && streamptr->ntsteps > 0 )
+  for ( ncdimid = 0; ncdimid < ndims; ncdimid++ )
     {
-      cdfCreateRecords(streamptr, tsID);
-
-      taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
-      if ( tsID > 0 )
-	ptaxisCopy(taxis, &streamptr->tsteps[0].taxis);
-
-      double timevalue = tsID;
-
-      int nctimevarid = streamptr->basetime.ncvarid;
-      if ( nctimevarid != CDI_UNDEFID )
+      ncvarid = ncdims[ncdimid].ncvarid;
+      if ( ncvarid != -1 )
 	{
-	  int fileID = streamptr->fileID;
-	  size_t index  = (size_t)tsID;
-
-	  if ( streamptr->basetime.lwrf )
+	  if ( ncvars[ncvarid].dimids[0] == timedimid )
 	    {
-              wrf_read_timestep(fileID, nctimevarid, tsID, taxis);
+              ncvars[ncvarid].istime = TRUE;
+	      ncdims[ncdimid].dimtype = T_AXIS;
+	      continue;
 	    }
-	  else
+
+          if ( isHybridSigmaPressureCoordinate(ncid, ncvarid, ncvars, ncdims) ) continue;
+
+	  if ( ncvars[ncvarid].units[0] != 0 )
 	    {
-#if defined (USE_TIMECACHE)
-              if ( streamptr->basetime.timevar_cache == NULL )
+	      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) )
                 {
-                  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);
+                  ncvars[ncvarid].zaxistype = ZAXIS_DEPTH_BELOW_LAND;
+		}
+	      else if ( unitsIsHeight(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;
+		}
 	    }
+          else
+            {
+              if ( (strcmp(ncvars[ncvarid].longname, "generalized_height") == 0 ||
+                    strcmp(ncvars[ncvarid].longname, "generalized height") == 0) &&
+                   strcmp(ncvars[ncvarid].stdname, "height") == 0 )
+                  ncvars[ncvarid].zaxistype = ZAXIS_REFERENCE;
+            }
 
-	  int nctimeboundsid = streamptr->basetime.ncvarboundsid;
-	  if ( nctimeboundsid != CDI_UNDEFID )
+	  if ( ncvars[ncvarid].islon == FALSE && ncvars[ncvarid].longname[0] != 0 &&
+               ncvars[ncvarid].islat == FALSE && ncvars[ncvarid].longname[1] != 0 )
 	    {
-	      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;
-
-	      cdiDecodeTimeval(timevalue, taxis, &taxis->vdate_lb, &taxis->vtime_lb);
-
-              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;
+	      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;
+		}
+	    }
 
-	      cdiDecodeTimeval(timevalue, taxis, &taxis->vdate_ub, &taxis->vtime_ub);
+	  if ( ncvars[ncvarid].zaxistype != UNDEFID )
+	    {
+              ncvars[ncvarid].islev = TRUE;
+	      cdfSetVar(ncvars, ncvarid, FALSE);
+	      cdfSetDim(ncvars, ncvarid, 0, Z_AXIS);
+	      ncdims[ncdimid].dimtype = Z_AXIS;
 	    }
+	}
+    }
+}
 
-          int leadtimeid = streamptr->basetime.leadtimeid;
-          if ( leadtimeid != CDI_UNDEFID )
-            {
-              timevalue = get_timevalue(fileID, leadtimeid, tsID, NULL);
-              cdiSetForecastPeriod(timevalue, taxis);
+/* verify coordinate vars - second scan (all other variables) */
+static
+void verify_coordinate_vars_2(int nvars, ncvar_t *ncvars)
+{
+  int ncvarid;
+
+  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 ( unitsIsHeight(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;
+		}
             }
+
+	  /* 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;
+		}
+	    }
 	}
     }
+}
 
-  streamptr->curTsID = tsID;
-  long nrecs = streamptr->tsteps[tsID].nrecs;
+#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;
 
-  return (int) nrecs;
-}
+  cdf_inq_varnatts(ncfileID, ncvarID, &nvatts);
 
+  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);
 
-int cdfInqHistorySize(stream_t *streamptr)
-{
-  size_t size = 0;
-  int ncid = streamptr->fileID;
-  if ( streamptr->historyID != CDI_UNDEFID )
-    cdf_inq_attlen(ncid, NC_GLOBAL, "history", &size);
+      //  printf("%s %d\n", attname, (int)attlen);
+    }
 
-  return (int) size;
 }
+#endif
 
-
-void cdfInqHistoryString(stream_t *streamptr, char *history)
+static
+void grid_set_chunktype(grid_t *grid, ncvar_t *ncvar)
 {
-  int ncid = streamptr->fileID;
-  if ( streamptr->historyID != CDI_UNDEFID )
+  if ( ncvar->chunked )
     {
-      nc_type atttype;
-      cdf_inq_atttype(ncid, NC_GLOBAL, "history", &atttype);
+      int ndims = ncvar->ndims;
 
-      if ( atttype == NC_CHAR )
+      if ( grid->type == GRID_UNSTRUCTURED )
         {
-          cdf_get_att_text(ncid, NC_GLOBAL, "history", history);
+          if ( ncvar->chunks[ndims-1] == grid->size )
+            ncvar->chunktype = CHUNK_GRID;
+          else
+            ncvar->chunktype = CHUNK_AUTO;
         }
-#if  defined  (HAVE_NETCDF4)
-      else if ( atttype == NC_STRING )
+      else
         {
-          // ToDo
-          Warning("History attribute with type NC_STRING unsupported!");
+          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;
         }
-#endif
     }
 }
 
+static struct gridVirtTable cdfLazyGridVtable;
+static double *cdfPendingLoad;
+#ifdef HAVE_LIBPTHREAD
+static pthread_once_t cdfLazyInitialized = PTHREAD_ONCE_INIT;
+#else
+static bool cdfLazyInitialized;
 #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
-
-#ifdef HAVE_LIBNETCDF
-
 
+struct cdfLazyGrid
+{
+  grid_t base;
+  const struct gridVirtTable *baseVtable;
+  struct {
+    int datasetNCId, varNCId;
+  } cellAreaGet, xBoundsGet, yBoundsGet;
+  struct xyValGet {
+    double scalefactor, addoffset;
+    size_t start[3], count[3], size, dimsize;
+    int datasetNCId, varNCId;
+    short ndims;
+  } xValsGet, yValsGet;
+#ifdef HAVE_LIBPTHREAD
+  pthread_mutex_t loadSerialize;
+#endif
+};
 
-#define  POSITIVE_UP    1
-#define  POSITIVE_DOWN  2
+#ifdef HAVE_LIBPTHREAD
+#define lock_lazy_load(plGrid) pthread_mutex_lock(&((plGrid)->loadSerialize))
+#define unlock_lazy_load(plGrid) pthread_mutex_unlock(&((plGrid)->loadSerialize))
+#define destroy_lazy_load_lock(plGrid) pthread_mutex_destroy(&((plGrid)->loadSerialize))
+#define init_lazy_load_lock(plGrid) pthread_mutex_init(&((plGrid)->loadSerialize), NULL)
+#else
+#define lock_lazy_load(plGrid)
+#define unlock_lazy_load(plGrid)
+#define destroy_lazy_load_lock(plGrid)
+#define init_lazy_load_lock(plGrid)
+#endif
 
+static void cdfLazyGridDestroy(struct cdfLazyGrid *lazyGrid)
+{
+  lazyGrid->base.extraData = NULL;
+  if (lazyGrid->base.area == cdfPendingLoad)
+    lazyGrid->base.area = NULL;
+  if (lazyGrid->base.xvals == cdfPendingLoad)
+    lazyGrid->base.xvals = NULL;
+  if (lazyGrid->base.yvals == cdfPendingLoad)
+    lazyGrid->base.yvals = NULL;
+  if (lazyGrid->base.xbounds == cdfPendingLoad)
+    lazyGrid->base.xbounds = NULL;
+  if (lazyGrid->base.ybounds == cdfPendingLoad)
+    lazyGrid->base.ybounds = NULL;
+  destroy_lazy_load_lock(lazyGrid);
+}
 
-static const char bndsName[] = "bnds";
+static void cdfLazyGridDelete(grid_t *grid)
+{
+  struct cdfLazyGrid *cdfGrid = (struct cdfLazyGrid *)grid;
+  void (*baseDestroy)(grid_t *grid) = cdfGrid->baseVtable->destroy;
+  cdfLazyGridDestroy(cdfGrid);
+  baseDestroy(grid);
+}
 
+static void cdfLazyGridDestroyOnce(void)
+{
+  /*
+#ifdef HAVE_MMAP
+  size_t pgSize = cdiGetPageSize(false);
+  munmap(cdfPendingLoad, pgSize);
+#endif
+  */
+}
 
-void cdfCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
+static void
+cdfLazyGridDefArea(grid_t *grid, const double *area)
 {
-  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);
-  int datatype = vlistInqVarDatatype(vlistID1, ivarID);
-  int memtype  = datatype != CDI_DATATYPE_FLT32 ? MEMTYPE_DOUBLE : MEMTYPE_FLOAT;
+  struct cdfLazyGrid *cdfGrid = (struct cdfLazyGrid *)grid;
+  lock_lazy_load(cdfGrid);
+  if (grid->area == cdfPendingLoad)
+    grid->area = NULL;
+  cdfGrid->cellAreaGet.datasetNCId = -1;
+  cdfGrid->cellAreaGet.varNCId = -1;
+  cdfGrid->baseVtable->defArea(grid, area);
+  unlock_lazy_load(cdfGrid);
+}
 
-  void *data = Malloc((size_t)datasize
-             * (memtype == MEMTYPE_DOUBLE ? sizeof(double) : sizeof(float)));
 
-  int nmiss;
-  cdf_read_record(streamptr1, memtype, data, &nmiss);
-  cdf_write_record(streamptr2, memtype, data, nmiss);
+static const double *
+cdfLazyGridInqAreaPtr(grid_t *grid)
+{
+  struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
+  lock_lazy_load(lazyGrid);
+  if (grid->area == cdfPendingLoad)
+    {
+      grid->area = (double *)Malloc((size_t)grid->size * sizeof(double));
+      cdf_get_var_double(lazyGrid->cellAreaGet.datasetNCId,
+                         lazyGrid->cellAreaGet.varNCId, grid->area);
+    }
+  unlock_lazy_load(lazyGrid);
+  return lazyGrid->baseVtable->inqAreaPtr(grid);
+}
 
-  Free(data);
+static void
+cdfLazyGridInqArea(grid_t *grid, double *area)
+{
+  grid->vtable->inqAreaPtr(grid);
+  struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
+  lazyGrid->baseVtable->inqArea(grid, area);
 }
 
 
-void cdfDefRecord(stream_t *streamptr)
+static void
+cdfLazyLoadXYVals(struct xyValGet *valsGet, double **valsp)
 {
-  (void)streamptr;
+  double *grid_vals
+    = (double *)Malloc(valsGet->size * sizeof (double));
+  *valsp = grid_vals;
+  if ( valsGet->ndims == 3 )
+    cdf_get_vara_double(valsGet->datasetNCId, valsGet->varNCId,
+                        valsGet->start, valsGet->count, grid_vals);
+  else
+    cdf_get_var_double(valsGet->datasetNCId, valsGet->varNCId, grid_vals);
+  scale_add(valsGet->size, grid_vals, valsGet->addoffset, valsGet->scalefactor);
 }
 
-static
-void cdfDefTimeValue(stream_t *streamptr, int tsID)
+static const double *
+cdfLazyGridInqXValsPtr(grid_t *grid)
 {
-  int fileID = streamptr->fileID;
-
-  if ( CDI_Debug )
-    Message("streamID = %d, fileID = %d", streamptr->self, fileID);
+  struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
+  lock_lazy_load(lazyGrid);
+  if (grid->xvals == cdfPendingLoad)
+    cdfLazyLoadXYVals(&lazyGrid->xValsGet, &grid->xvals);
+  unlock_lazy_load(lazyGrid);
+  return lazyGrid->baseVtable->inqXValsPtr(grid);
+}
 
-  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
+static const double *
+cdfLazyGridInqYValsPtr(grid_t *grid)
+{
+  struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
+  lock_lazy_load(lazyGrid);
+  if (grid->yvals == cdfPendingLoad)
+    cdfLazyLoadXYVals(&lazyGrid->yValsGet, &grid->yvals);
+  unlock_lazy_load(lazyGrid);
+  return lazyGrid->baseVtable->inqYValsPtr(grid);
+}
 
-  if ( streamptr->ncmode == 1 )
+static double
+cdfLazyGridInqXYVal(grid_t *grid, size_t index,
+                    const struct xyValGet *valsGet, double *vals,
+                    const double *(*inqValsPtr)(grid_t *gridptr))
+{
+  size_t size = valsGet->size;
+  double v;
+  if ( vals == cdfPendingLoad )
     {
-      cdf_enddef(fileID);
-      streamptr->ncmode = 2;
+      /* prevent full load if only first/last values get inspected */
+      if ( index == 0 || index == size - 1 )
+        {
+          size_t indexND[3];
+          if ( valsGet->ndims == 3 )
+            {
+              indexND[0] = 0;
+              indexND[1] = index / valsGet->count[2];
+              indexND[2] = index % valsGet->count[2];
+            }
+          else if ( valsGet->ndims == 2)
+            {
+              indexND[0] = index / (size_t)grid->xsize;
+              indexND[1] = index % (size_t)grid->xsize;
+            }
+          else
+            indexND[0] = index;
+          cdf_get_var1_double(valsGet->datasetNCId, valsGet->varNCId,
+                              indexND, &v);
+        }
+      else
+        {
+          const double *grid_vals = inqValsPtr(grid);
+          v = grid_vals[index];
+        }
     }
+  else if ( vals )
+    v = vals[index];
+  else
+    v = 0.0;
+  return v;
+}
 
-  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;
-  size_t index = (size_t)tsID;
-  cdf_put_var1_double(fileID, ncvarid, &index, &timevalue);
-
-  if ( taxis->has_bounds )
-    {
-      size_t start[2], count[2];
-
-      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);
+static void
+cdfLazyGridDefXVals(grid_t *grid, const double *vals)
+{
+  struct cdfLazyGrid *cdfGrid = (struct cdfLazyGrid *)grid;
+  lock_lazy_load(cdfGrid);
+  if (grid->xvals == cdfPendingLoad)
+    grid->xvals = NULL;
+  cdfGrid->xValsGet.datasetNCId = -1;
+  cdfGrid->xValsGet.varNCId = -1;
+  cdfGrid->baseVtable->defXVals(grid, vals);
+  unlock_lazy_load(cdfGrid);
+}
 
-      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);
-    }
+static void
+cdfLazyGridDefYVals(grid_t *grid, const double *vals)
+{
+  struct cdfLazyGrid *cdfGrid = (struct cdfLazyGrid *)grid;
+  lock_lazy_load(cdfGrid);
+  if (grid->yvals == cdfPendingLoad)
+    grid->yvals = NULL;
+  cdfGrid->yValsGet.datasetNCId = -1;
+  cdfGrid->yValsGet.varNCId = -1;
+  cdfGrid->baseVtable->defYVals(grid, vals);
+  unlock_lazy_load(cdfGrid);
+}
 
-  ncvarid = streamptr->basetime.leadtimeid;
-  if ( taxis->type == TAXIS_FORECAST && ncvarid != CDI_UNDEFID )
-    {
-      timevalue = taxis->fc_period;
-      cdf_put_var1_double(fileID, ncvarid, &index, &timevalue);
-    }
+static double
+cdfLazyGridInqXVal(grid_t *grid, int index)
+{
+  struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
+  lock_lazy_load(lazyGrid);
+  double rv = cdfLazyGridInqXYVal(grid, (size_t)index, &lazyGrid->xValsGet,
+                                  grid->xvals, grid->vtable->inqXValsPtr);
+  unlock_lazy_load(lazyGrid);
+  return rv;
 }
 
-void cdfDefTimestep(stream_t *streamptr, int tsID)
+static double
+cdfLazyGridInqYVal(grid_t *grid, int index)
 {
-  int vlistID = streamptr->vlistID;
+  struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
+  lock_lazy_load(lazyGrid);
+  double rv = cdfLazyGridInqXYVal(grid, (size_t)index, &lazyGrid->yValsGet,
+                                  grid->yvals, grid->vtable->inqYValsPtr);
+  unlock_lazy_load(lazyGrid);
+  return rv;
+}
 
-  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
+static bool
+cdfLazyXYValGetCompare(struct cdfLazyGrid *lazyGridRef,
+                       struct cdfLazyGrid *lazyGridTest)
+{
+  struct xyValGet *valsGetXRef = &lazyGridRef->xValsGet,
+    *valsGetYRef = &lazyGridRef->yValsGet,
+    *valsGetXTest = &lazyGridTest->xValsGet,
+    *valsGetYTest = &lazyGridTest->yValsGet;
+  if (valsGetXRef->datasetNCId == -1
+      || valsGetXTest->datasetNCId == -1
+      || valsGetYRef->datasetNCId == -1
+      || valsGetYTest->datasetNCId == -1)
+    return lazyGridRef->baseVtable->compareXYFull(&lazyGridRef->base,
+                                                  &lazyGridTest->base);
+  return valsGetXRef->datasetNCId != valsGetXTest->datasetNCId
+    ||   valsGetXRef->varNCId     != valsGetXTest->varNCId
+    ||   valsGetYRef->datasetNCId != valsGetYTest->datasetNCId
+    ||   valsGetYRef->varNCId     != valsGetYTest->varNCId;
+}
 
-  cdfDefTimeValue(streamptr, tsID);
+static bool
+cdfLazyCompareXYFull(grid_t *gridRef, grid_t *gridTest)
+{
+  bool diff;
+  struct cdfLazyGrid *lazyGridRef = (struct cdfLazyGrid *)gridRef;
+  if (gridTest->vtable == &cdfLazyGridVtable)
+    diff = cdfLazyXYValGetCompare(lazyGridRef, (struct cdfLazyGrid *)gridTest);
+  else
+    diff = lazyGridRef->baseVtable->compareXYFull(gridRef, gridTest);
+  return diff;
 }
 
-static
-void cdfDefComplex(stream_t *streamptr, int gridID, int gridindex)
+static bool
+cdfLazyCompareXYAO(grid_t *gridRef, grid_t *gridTest)
 {
-  int dimID;
-  ncgrid_t *ncgrid = streamptr->ncgrid;
+  bool diff;
+  struct cdfLazyGrid *lazyGridRef = (struct cdfLazyGrid *)gridRef;
+  if (gridTest->vtable == &cdfLazyGridVtable)
+    diff = cdfLazyXYValGetCompare(lazyGridRef, (struct cdfLazyGrid *)gridTest);
+  else
+    diff = lazyGridRef->baseVtable->compareXYAO(gridRef, gridTest);
+  return diff;
+}
 
-  for ( int index = 0; index < gridindex; ++index )
+
+static const double *
+cdfLazyGridInqXBoundsPtr(grid_t *grid)
+{
+  struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
+  lock_lazy_load(lazyGrid);
+  if (grid->xbounds == cdfPendingLoad)
     {
-      if ( ncgrid[index].ncIDs[CDF_DIMID_X] != CDI_UNDEFID )
-        {
-          int gridID0 = ncgrid[index].gridID;
-          int gridtype0 = gridInqType(gridID0);
-          if ( gridtype0 == GRID_SPECTRAL || gridtype0 == GRID_FOURIER )
-            {
-              dimID = ncgrid[index].ncIDs[CDF_DIMID_X];
-              goto dimIDEstablished;
-            }
-        }
+      grid->xbounds = (double *)Malloc((size_t)grid->nvertex
+                                       * (size_t)grid->size * sizeof(double));
+      cdf_get_var_double(lazyGrid->xBoundsGet.datasetNCId,
+                         lazyGrid->xBoundsGet.varNCId, grid->xbounds);
     }
+  unlock_lazy_load(lazyGrid);
+  return lazyGrid->baseVtable->inqXBoundsPtr(grid);
+}
 
-  {
-    static const char axisname[] = "nc2";
-    size_t dimlen = 2;
-    int fileID  = streamptr->fileID;
-
-    if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
-    cdf_def_dim(fileID, axisname, dimlen, &dimID);
-    cdf_enddef(fileID);
-    streamptr->ncmode = 2;
-  }
-  dimIDEstablished:
-  ncgrid[gridindex].gridID = gridID;
-  ncgrid[gridindex].ncIDs[CDF_DIMID_X] = dimID;
+static void
+cdfLazyGridDefXBounds(grid_t *grid, const double *xbounds)
+{
+  struct cdfLazyGrid *cdfGrid = (struct cdfLazyGrid *)grid;
+  lock_lazy_load(cdfGrid);
+  if (grid->xbounds == cdfPendingLoad)
+    grid->xbounds = NULL;
+  cdfGrid->xBoundsGet.datasetNCId = -1;
+  cdfGrid->xBoundsGet.varNCId = -1;
+  cdfGrid->baseVtable->defXBounds(grid, xbounds);
+  unlock_lazy_load(cdfGrid);
 }
 
-struct idSearch
+static void
+cdfLazyGridDefYBounds(grid_t *grid, const double *ybounds)
 {
-  int numNonMatching, foundID;
-  size_t foundIdx;
-};
+  struct cdfLazyGrid *cdfGrid = (struct cdfLazyGrid *)grid;
+  lock_lazy_load(cdfGrid);
+  if (grid->ybounds == cdfPendingLoad)
+    grid->ybounds = NULL;
+  cdfGrid->yBoundsGet.datasetNCId = -1;
+  cdfGrid->yBoundsGet.varNCId = -1;
+  cdfGrid->baseVtable->defYBounds(grid, ybounds);
+  unlock_lazy_load(cdfGrid);
+}
 
-static inline struct idSearch
-cdfSearchIDBySize(size_t startIdx, size_t numIDs, const ncgrid_t ncgrid[numIDs],
-                  int ncIDType, int searchType, int searchSize,
-                  int (*typeInq)(int id), int (*sizeInq)(int id))
+static const double *
+cdfLazyGridInqYBoundsPtr(grid_t *grid)
 {
-  int numNonMatching = 0,
-    foundID = CDI_UNDEFID;
-  size_t foundIdx = SIZE_MAX;
-  for ( size_t index = startIdx; index < numIDs; index++ )
+  struct cdfLazyGrid *lazyGrid = (struct cdfLazyGrid *)grid;
+  lock_lazy_load(lazyGrid);
+  if (grid->ybounds == cdfPendingLoad)
     {
-      if ( ncgrid[index].ncIDs[ncIDType] != CDI_UNDEFID )
-        {
-          int id0 = ncgrid[index].gridID,
-            id0Type = typeInq(id0);
-          if ( id0Type == searchType )
-            {
-              int size0 = sizeInq(id0);
-              if ( searchSize == size0 )
-                {
-                  foundID = ncgrid[index].ncIDs[ncIDType];
-                  foundIdx = index;
-                  break;
-                }
-              numNonMatching++;
-            }
-        }
+      grid->ybounds = (double *)Malloc((size_t)grid->nvertex
+                                       * (size_t)grid->size * sizeof(double));
+      cdf_get_var_double(lazyGrid->yBoundsGet.datasetNCId,
+                         lazyGrid->yBoundsGet.varNCId, grid->ybounds);
     }
-  return (struct idSearch){ .numNonMatching = numNonMatching,
-      .foundID = foundID, .foundIdx = foundIdx };
+  unlock_lazy_load(lazyGrid);
+  return lazyGrid->baseVtable->inqYBoundsPtr(grid);
 }
 
-static int
-cdfGridInqHalfSize(int gridID)
+static void
+cdfLazyGridCopyScalarFields(grid_t *gridptrOrig, grid_t *gridptrDup)
 {
-  return gridInqSize(gridID)/2;
+  struct cdfLazyGrid *lazyGridDup = (struct cdfLazyGrid *)gridptrDup,
+    *lazyGridOrig = (struct cdfLazyGrid *)gridptrOrig;
+  lazyGridOrig->baseVtable->copyScalarFields(gridptrOrig, &lazyGridDup->base);
+  lazyGridDup->baseVtable = lazyGridOrig->baseVtable;
+  lazyGridDup->cellAreaGet = lazyGridOrig->cellAreaGet;
+  lazyGridDup->xBoundsGet = lazyGridOrig->xBoundsGet;
+  lazyGridDup->yBoundsGet = lazyGridOrig->yBoundsGet;
+  lazyGridDup->xValsGet = lazyGridOrig->xValsGet;
+  lazyGridDup->yValsGet = lazyGridOrig->yValsGet;
+  init_lazy_load_lock(lazyGridDup);
 }
 
-
 static void
-cdfDefSPorFC(stream_t *streamptr, int gridID, int gridindex,
-             char *restrict axisname, int gridRefType)
+cdfLazyGridCopyArrayFields(grid_t *gridptrOrig, grid_t *gridptrDup)
 {
-  ncgrid_t *ncgrid = streamptr->ncgrid;
+  size_t nrowlon = (size_t)gridptrOrig->nrowlon;
+  size_t gridsize = (size_t)gridptrOrig->size;
+  int gridtype = gridptrOrig->type;
+  int irregular = gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED;
+  if ( nrowlon )
+    {
+      gridptrDup->rowlon = (int *)Malloc(nrowlon * sizeof (int));
+      memcpy(gridptrDup->rowlon, gridptrOrig->rowlon, nrowlon * sizeof(int));
+    }
 
-  size_t dimlen = (size_t)(gridInqSize(gridID))/2;
+  if ( gridptrOrig->xvals != NULL && gridptrOrig->xvals != cdfPendingLoad )
+    {
+      size_t size  = irregular ? gridsize : (size_t)gridptrOrig->xsize;
 
-  int iz;
-  int dimID;
-  {
-    struct idSearch search
-      = cdfSearchIDBySize(0, (size_t)gridindex, ncgrid, CDF_DIMID_Y,
-                          gridRefType, (int)dimlen,
-                          gridInqType, cdfGridInqHalfSize);
-    dimID = search.foundID;
-    iz = search.numNonMatching;
-  }
+      gridptrDup->xvals = (double *)Malloc(size * sizeof (double));
+      memcpy(gridptrDup->xvals, gridptrOrig->xvals, size * sizeof (double));
+    }
 
-  if ( dimID == CDI_UNDEFID )
+  if ( gridptrOrig->yvals != NULL && gridptrOrig->yvals != cdfPendingLoad )
     {
-      int fileID  = streamptr->fileID;
-      if ( iz == 0 ) axisname[3] = '\0';
-      else           sprintf(&axisname[3], "%1d", iz+1);
+      size_t size  = irregular ? gridsize : (size_t)gridptrOrig->ysize;
 
-      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+      gridptrDup->yvals = (double *)Malloc(size * sizeof (double));
+      memcpy(gridptrDup->yvals, gridptrOrig->yvals, size * sizeof (double));
+    }
 
-      cdf_def_dim(fileID, axisname, dimlen, &dimID);
+  if ( gridptrOrig->xbounds != NULL && gridptrOrig->xbounds != cdfPendingLoad )
+    {
+      size_t size  = (irregular ? gridsize : (size_t)gridptrOrig->xsize)
+        * (size_t)gridptrOrig->nvertex;
 
-      cdf_enddef(fileID);
-      streamptr->ncmode = 2;
+      gridptrDup->xbounds = (double *)Malloc(size * sizeof (double));
+      memcpy(gridptrDup->xbounds, gridptrOrig->xbounds, size * sizeof (double));
     }
 
-  ncgrid[gridindex].gridID = gridID;
-  ncgrid[gridindex].ncIDs[CDF_DIMID_Y] = dimID;
-}
+  if ( gridptrOrig->ybounds != NULL && gridptrOrig->ybounds != cdfPendingLoad )
+    {
+      size_t size = (irregular ? gridsize : (size_t)gridptrOrig->ysize)
+        * (size_t)gridptrOrig->nvertex;
 
-static
-void cdfDefSP(stream_t *streamptr, int gridID, int gridindex)
-{
-  /*
-  char longname[] = "Spherical harmonic coefficient";
-  */
-  char axisname[5] = "nspX";
-  cdfDefSPorFC(streamptr, gridID, gridindex, axisname, GRID_SPECTRAL);
-}
+      gridptrDup->ybounds = (double *)Malloc(size * sizeof (double));
+      memcpy(gridptrDup->ybounds, gridptrOrig->ybounds, size * sizeof (double));
+    }
 
+  {
+    if ( gridptrOrig->area != NULL && gridptrOrig->area != cdfPendingLoad )
+      {
+        size_t size = gridsize;
 
-static
-void cdfDefFC(stream_t *streamptr, int gridID, int gridindex)
-{
-  char axisname[5] = "nfcX";
-  cdfDefSPorFC(streamptr, gridID, gridindex, axisname, GRID_FOURIER);
-}
+        gridptrDup->area = (double *)Malloc(size * sizeof (double));
+        memcpy(gridptrDup->area, gridptrOrig->area, size * sizeof (double));
+      }
+  }
 
-static const struct cdfDefGridAxisInqs {
-  int (*axisSize)(int gridID);
-  int (*axisDimname)(int cdiID, int key, int size, char *mesg);
-  int (*axisName)(int cdiID, int key, int size, char *mesg);
-  int (*axisLongname)(int cdiID, int key, int size, char *mesg);
-  int (*axisUnits)(int cdiID, int key, int size, char *mesg);
-  void (*axisStdname)(int cdiID, char *dimstdname);
-  double (*axisVal)(int gridID, int index);
-  const double *(*axisValsPtr)(int gridID);
-  const double *(*axisBoundsPtr)(int gridID);
-} gridInqsX = {
-  .axisSize = gridInqXsize,
-  .axisDimname = cdiGridInqKeyStr,
-  .axisName = cdiGridInqKeyStr,
-  .axisLongname = cdiGridInqKeyStr,
-  .axisUnits = cdiGridInqKeyStr,
-  .axisStdname = gridInqXstdname,
-  .axisVal = gridInqXval,
-  .axisValsPtr = gridInqXvalsPtr,
-  .axisBoundsPtr = gridInqXboundsPtr,
-}, gridInqsY = {
-  .axisSize = gridInqYsize,
-  .axisDimname = cdiGridInqKeyStr,
-  .axisName = cdiGridInqKeyStr,
-  .axisLongname = cdiGridInqKeyStr,
-  .axisUnits = cdiGridInqKeyStr,
-  .axisStdname = gridInqYstdname,
-  .axisVal = gridInqYval,
-  .axisValsPtr = gridInqYvalsPtr,
-  .axisBoundsPtr = gridInqYboundsPtr,
-}, gridInqsZ = {
-  .axisLongname = cdiZaxisInqKeyStr,
-  .axisUnits = cdiZaxisInqKeyStr,
-  .axisStdname = zaxisInqStdname,
-};
+  if ( gridptrOrig->mask != NULL )
+    {
+      size_t size = gridsize;
 
-static
-void cdfPutGridStdAtts(int fileID, int ncvarid, int gridID, int dimtype, const struct cdfDefGridAxisInqs *inqs)
-{
-  size_t len;
+      gridptrDup->mask = (mask_t *)Malloc(size * sizeof(mask_t));
+      memcpy(gridptrDup->mask, gridptrOrig->mask, size * sizeof (mask_t));
+    }
 
-  char stdname[CDI_MAX_NAME];
-  inqs->axisStdname(gridID, stdname);
-  if ( (len = strlen(stdname)) )
-    cdf_put_att_text(fileID, ncvarid, "standard_name", len, stdname);
+  if ( gridptrOrig->mask_gme != NULL )
+    {
+      size_t size = gridsize;
 
-  char longname[CDI_MAX_NAME]; longname[0] = 0;
-  int keyname = (dimtype == 'Z') ? CDI_KEY_LONGNAME : (dimtype == 'X') ? CDI_KEY_XLONGNAME : CDI_KEY_YLONGNAME;
-  inqs->axisLongname(gridID, keyname, CDI_MAX_NAME, longname);
-  if ( longname[0] && (len = strlen(longname)) )
-    cdf_put_att_text(fileID, ncvarid, "long_name", len, longname);
+      gridptrDup->mask_gme = (mask_t *)Malloc(size * sizeof (mask_t));
+      memcpy(gridptrDup->mask_gme, gridptrOrig->mask_gme, size * sizeof(mask_t));
+    }
+}
 
-  char units[CDI_MAX_NAME]; units[0] = 0;
-  keyname = (dimtype == 'Z') ? CDI_KEY_UNITS : (dimtype == 'X') ? CDI_KEY_XUNITS : CDI_KEY_YUNITS;
-  inqs->axisUnits(gridID, keyname, CDI_MAX_NAME, units);
-  if ( units[0] && (len = strlen(units)) )
-    cdf_put_att_text(fileID, ncvarid, "units", len, units);
+static grid_t *
+cdfLazyGridCopy(grid_t *gridptrOrig)
+{
+  struct cdfLazyGrid *lazyGridDup
+    = (struct cdfLazyGrid *)Malloc(sizeof (*lazyGridDup));
+  gridptrOrig->vtable->copyScalarFields(gridptrOrig, &lazyGridDup->base);
+  gridptrOrig->vtable->copyArrayFields(gridptrOrig, &lazyGridDup->base);
+  return &lazyGridDup->base;
 }
 
 static void
-cdfDefTrajLatLon(stream_t *streamptr, int gridID, int gridindex,
-                 const struct cdfDefGridAxisInqs *inqs, int dimtype)
+cdfLazyGridInitOnce(void)
 {
-  nc_type xtype = (gridInqPrec(gridID) == CDI_DATATYPE_FLT32) ? NC_FLOAT : NC_DOUBLE;
-  ncgrid_t *ncgrid = streamptr->ncgrid;
-
-  int dimlen = inqs->axisSize(gridID);
-  if ( dimlen != 1 )
-    Error("%c size isn't 1 for %s grid!", dimtype, gridNamePtr(gridInqType(gridID)));
-
-  int ncvarid
-    = ncgrid[gridindex].ncIDs[dimtype == 'X' ? CDF_DIMID_X : CDF_DIMID_Y];
-
-  if ( ncvarid == CDI_UNDEFID )
-    {
-      int dimNcID = streamptr->basetime.ncvarid;
-      int fileID  = streamptr->fileID;
-      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
-
-      char axisname[CDI_MAX_NAME]; axisname[0] = 0;
-      int keyname = (dimtype == 'X') ? CDI_KEY_XNAME : CDI_KEY_YNAME;
-      inqs->axisName(gridID, keyname, CDI_MAX_NAME, axisname);
-      cdf_def_var(fileID, axisname, xtype, 1, &dimNcID, &ncvarid);
-      cdfPutGridStdAtts(fileID, ncvarid, gridID, dimtype, inqs);
-      cdf_enddef(fileID);
-      streamptr->ncmode = 2;
-    }
+  cdfLazyGridVtable = cdiGridVtable;
+  cdfLazyGridVtable.destroy = cdfLazyGridDelete;
+  cdfLazyGridVtable.copy = cdfLazyGridCopy;
+  cdfLazyGridVtable.copyScalarFields = cdfLazyGridCopyScalarFields;
+  cdfLazyGridVtable.copyArrayFields = cdfLazyGridCopyArrayFields;
+  cdfLazyGridVtable.defArea = cdfLazyGridDefArea;
+  cdfLazyGridVtable.inqAreaPtr = cdfLazyGridInqAreaPtr;
+  cdfLazyGridVtable.inqArea = cdfLazyGridInqArea;
+  cdfLazyGridVtable.inqXValsPtr = cdfLazyGridInqXValsPtr;
+  cdfLazyGridVtable.inqYValsPtr = cdfLazyGridInqYValsPtr;
+  cdfLazyGridVtable.inqXVal = cdfLazyGridInqXVal;
+  cdfLazyGridVtable.inqYVal = cdfLazyGridInqYVal;
+  cdfLazyGridVtable.defXVals = cdfLazyGridDefXVals;
+  cdfLazyGridVtable.defYVals = cdfLazyGridDefYVals;
+  cdfLazyGridVtable.compareXYFull = cdfLazyCompareXYFull;
+  cdfLazyGridVtable.compareXYAO = cdfLazyCompareXYAO;
+  cdfLazyGridVtable.defXBounds = cdfLazyGridDefXBounds;
+  cdfLazyGridVtable.defYBounds = cdfLazyGridDefYBounds;
+  cdfLazyGridVtable.inqXBoundsPtr = cdfLazyGridInqXBoundsPtr;
+  cdfLazyGridVtable.inqYBoundsPtr = cdfLazyGridInqYBoundsPtr;
+  /* create inaccessible memory area, if possible, this serves as
+   * dummy value for pointers to data not yet loaded */
+  /*
+#ifdef HAVE_MMAP
+  {
+    size_t pgSize = cdiGetPageSize(false);
+    static const char devZero[] = "/dev/zero";
+    int fd = open(devZero, O_RDWR);
+    if (fd == -1)
+      SysError("Could not open %s to map anonymous memory", devZero);
+    void *cdfInvalid = mmap(NULL, pgSize, PROT_NONE, MAP_PRIVATE, fd, 0);
+    if (cdfInvalid == MAP_FAILED)
+      SysError("Could not mmap anonymous memory");
+    cdfPendingLoad = cdfInvalid;
+    int rc = close(fd);
+    if (rc == -1)
+      SysError("Could not close %s file handle %d after mapping anonymous"
+               " memory", devZero, fd);
+  }
+#else
+  */
+  cdfPendingLoad = (double *)&cdfPendingLoad;
+  //#endif
+  atexit(cdfLazyGridDestroyOnce);
+#ifndef HAVE_LIBPTHREAD
+  cdfLazyInitialized = true;
+#endif
+}
 
-  ncgrid[gridindex].gridID = gridID;
-  /* var ID for trajectory !!! */
-  ncgrid[gridindex].ncIDs[dimtype == 'X' ? CDF_DIMID_X : CDF_DIMID_Y] = ncvarid;
+static void
+cdfBaseGridInit(grid_t *grid, int gridtype)
+{
+  grid_init(grid);
+  cdiGridTypeInit(grid, gridtype, 0);
 }
 
-static
-void cdfDefTrajLon(stream_t *streamptr, int gridID, int gridindex)
+static void
+cdfLazyGridInit(struct cdfLazyGrid *grid, int gridtype)
 {
-  cdfDefTrajLatLon(streamptr, gridID, gridindex, &gridInqsX, 'X');
+#ifdef HAVE_LIBPTHREAD
+  pthread_once(&cdfLazyInitialized, cdfLazyGridInitOnce);
+#else
+  if (cdfLazyInitialized) ; else cdfLazyGridInitOnce();
+#endif
+  cdfBaseGridInit(&grid->base, gridtype);
+  grid->baseVtable = grid->base.vtable;
+  grid->cellAreaGet.datasetNCId = -1;
+  grid->cellAreaGet.varNCId = -1;
+  grid->xValsGet.datasetNCId = -1;
+  grid->xValsGet.varNCId = -1;
+  grid->yValsGet.datasetNCId = -1;
+  grid->yValsGet.varNCId = -1;
+  grid->xBoundsGet.datasetNCId = -1;
+  grid->xBoundsGet.varNCId = -1;
+  grid->yBoundsGet.datasetNCId = -1;
+  grid->yBoundsGet.varNCId = -1;
+  grid->base.vtable = &cdfLazyGridVtable;
+  init_lazy_load_lock(grid);
 }
 
+static void
+cdfLazyGridRenew(struct cdfLazyGrid *restrict *restrict gridpptr, int gridtype)
+{
+  struct cdfLazyGrid *restrict grid = *gridpptr;
+  if (!grid)
+    *gridpptr = grid = (struct cdfLazyGrid *)Malloc(sizeof (*grid));
+  cdfLazyGridInit(grid, gridtype);
+}
 
-static
-void cdfDefTrajLat(stream_t *streamptr, int gridID, int gridindex)
+static void
+cdfBaseGridRenew(struct cdfLazyGrid *restrict *restrict gridpptr, int gridtype)
 {
-  cdfDefTrajLatLon(streamptr, gridID, gridindex, &gridInqsY, 'Y');
+  struct cdfLazyGrid *restrict grid = *gridpptr;
+  if (!grid)
+    *gridpptr = grid = (struct cdfLazyGrid *)Malloc(sizeof (grid_t));
+  cdfBaseGridInit((grid_t*)grid, gridtype);
 }
 
+
+/* define all input grids */
 static
-int checkDimName(int fileID, size_t dimlen, char *dimname)
+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)
 {
-  /* check whether the dimenion name is already defined with the same length */
-  unsigned iz = 0;
-  int dimid = CDI_UNDEFID;
-  char name[CDI_MAX_NAME];
+  int ltwarn = TRUE;
+  struct cdfLazyGrid *restrict lazyGrid = NULL, *restrict lazyProj = NULL;
+#define grid (&lazyGrid->base)
+#define proj (&lazyProj->base)
 
-  size_t len = strlen(dimname);
-  memcpy(name, dimname, len + 1);
-
-  do
+  for ( int ncvarid = 0; ncvarid < nvars; ++ncvarid )
     {
-      if ( iz ) sprintf(name + len, "_%u", iz+1);
-
-      int dimid0, status = nc_inq_dimid(fileID, name, &dimid0);
-      if ( status != NC_NOERR )
-        break;
-      size_t dimlen0;
-      cdf_inq_dimlen(fileID, dimid0, &dimlen0);
-      if ( dimlen0 == dimlen )
-        {
-          dimid = dimid0;
-          break;
-        }
-      iz++;
-    }
-  while ( iz <= 99 );
+      if ( ncvars[ncvarid].isvar && ncvars[ncvarid].gridID == UNDEFID )
+	{
+          int xdimids[2] = {-1,-1}, ydimids[2] = {-1,-1};
+	  int xdimid = -1, ydimid = -1;
+          int vdimid = -1;
+	  int islon = 0, islat = 0;
+	  int nxdims = 0, nydims = 0;
+          size_t size = 0;
+          size_t xsize = 0, ysize = 0;
+	  double yinc = 0;
+          struct addIffNewRes projAdded = { .Id = CDI_UNDEFID, .isNew = 0 },
+            gridAdded  = { .Id = CDI_UNDEFID, .isNew = 0 };
 
+	  int ndims = ncvars[ncvarid].ndims;
+	  for ( int 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 ( iz ) sprintf(dimname + len, "_%u", iz+1);
+	  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];
+	    }
 
-  return dimid;
-}
+	  int xvarid = ncvars[ncvarid].xvarid != UNDEFID
+	    ? ncvars[ncvarid].xvarid
+            : (xdimid != UNDEFID ? ncdims[xdimid].ncvarid : -1);
+          int yvarid = ncvars[ncvarid].yvarid != UNDEFID
+            ? ncvars[ncvarid].yvarid
+            : (ydimid != UNDEFID ? ncdims[ydimid].ncvarid : -1);
 
-static
-void checkGridName(char *axisname, int fileID)
-{
-  int ncdimid;
-  char axisname2[CDI_MAX_NAME];
+	  /*
+	  if ( xdimid != UNDEFID )
+	    xvarid = ncdims[xdimid].ncvarid;
+	  if ( xvarid == UNDEFID && ncvars[ncvarid].xvarid != UNDEFID )
+	    xvarid = ncvars[ncvarid].xvarid;
+
+	  if ( ydimid != UNDEFID )
+	    yvarid = ncdims[ydimid].ncvarid;
+	  if ( yvarid == UNDEFID && ncvars[ncvarid].yvarid != UNDEFID )
+	    yvarid = ncvars[ncvarid].yvarid;
+	  */
 
-  /* check that the name is not already defined */
-  unsigned iz = 0;
+	  if ( xdimid != UNDEFID ) xsize = ncdims[xdimid].len;
+	  if ( ydimid != UNDEFID ) ysize = ncdims[ydimid].len;
 
-  size_t axisnameLen = strlen(axisname);
-  memcpy(axisname2, axisname, axisnameLen + 1);
-  do
-    {
-      if ( iz ) sprintf(axisname2 + axisnameLen, "_%u", iz+1);
+	  if ( ydimid == UNDEFID && yvarid != UNDEFID )
+	    {
+	      if ( ncvars[yvarid].ndims == 1 )
+		{
+		  ydimid = ncvars[yvarid].dimids[0];
+		  ysize  = ncdims[ydimid].len;
+		}
+	    }
 
-      int status = nc_inq_varid(fileID, axisname2, &ncdimid);
-      if ( status != NC_NOERR ) break;
+	  if ( ncvars[ncvarid].gridtype == UNDEFID || ncvars[ncvarid].gridtype == GRID_GENERIC )
+	    if ( xdimid != UNDEFID && xdimid == ydimid && nydims == 0 ) ncvars[ncvarid].gridtype = GRID_UNSTRUCTURED;
 
-      ++iz;
-    }
-  while ( iz <= 99 );
+          if (CDI_netcdf_lazy_grid_load)
+            {
+              cdfLazyGridRenew(&lazyGrid, ncvars[ncvarid].gridtype);
+              cdfLazyGridRenew(&lazyProj, GRID_PROJECTION);
+            }
+          else
+            {
+              cdfBaseGridRenew(&lazyGrid, ncvars[ncvarid].gridtype);
+              cdfBaseGridRenew(&lazyProj, GRID_PROJECTION);
+            }
 
-  if ( iz ) sprintf(axisname + axisnameLen, "_%u", iz+1);
-}
+	  grid->prec  = DATATYPE_FLT64;
+	  grid->trunc = ncvars[ncvarid].truncation;
 
-static
-int checkZaxisName(char *axisname, int fileID, int vlistID, int zaxisID, int nzaxis)
-{
-  char axisname2[CDI_MAX_NAME];
+	  if ( ncvars[ncvarid].gridtype == GRID_TRAJECTORY )
+	    {
+	      if ( ncvars[ncvarid].xvarid == UNDEFID )
+		Error("Longitude coordinate undefined for %s!", ncvars[ncvarid].name);
+	      if ( ncvars[ncvarid].yvarid == UNDEFID )
+		Error("Latitude coordinate undefined for %s!", ncvars[ncvarid].name);
+	    }
+	  else
+	    {
+	      size_t start[3], count[3];
+	      int ltgrid = FALSE;
 
-  /* check that the name is not already defined */
-  unsigned iz = 0;
+	      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;
+		    }
 
-  size_t axisnameLen = strlen(axisname);
-  memcpy(axisname2, axisname, axisnameLen + 1);
-  do
-    {
-      if ( iz ) sprintf(axisname2 + axisnameLen, "_%u", iz+1);
+		  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;
+			}
+		    }
+		}
 
-      int ncdimid, status = nc_inq_varid(fileID, axisname2, &ncdimid);
+              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;
+                    }
+                }
 
-      if ( status != NC_NOERR )
-        {
-          if ( iz )
-            {
-              /* check that the name does not exist for other zaxes */
-              for ( int index = 0; index < nzaxis; index++ )
+              if ( yvarid != UNDEFID )
                 {
-                  int zaxisID0 = vlistZaxis(vlistID, index);
-                  if ( zaxisID != zaxisID0 )
+                  if ( ncvars[yvarid].ndims > 3 || (ncvars[yvarid].ndims == 3 && ltgrid == FALSE) )
                     {
-                      const char *axisname0 = zaxisInqNamePtr(zaxisID0);
-                      if ( strcmp(axisname0, axisname2) == 0 ) goto nextSuffix;
+                      Warning("Coordinate variable %s has to many dimensions (%d), skipped!", ncvars[yvarid].name, ncvars[yvarid].ndims);
+                      //ncvars[ncvarid].yvarid = UNDEFID;
+                      yvarid = UNDEFID;
                     }
                 }
-            }
-          break;
-        }
-      nextSuffix:
-      ++iz;
-    }
-  while (iz <= 99);
 
+              if ( xvarid != UNDEFID )
+		{
+                  bool 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 = ncvars[xvarid].dimids[ndims-2];
+                      size_t dimsize1 = ncdims[dimid].len;
+                      dimid = ncvars[xvarid].dimids[ndims-1];
+                      size_t dimsize2 = ncdims[dimid].len;
+                      skipvar = dimsize1*dimsize2 != size;
+		    }
+		  else if ( ndims == 1 )
+		    {
+		      size = xsize;
+		      /* Check size of 1 dimensional coordinate variables */
+                      int dimid = ncvars[xvarid].dimids[0];
+                      size_t dimsize = ncdims[dimid].len;
+                      skipvar = dimsize != size;
+		    }
+		  else if ( ndims == 0 && xsize == 0 )
+		    {
+                      size = xsize = 1;
+                      skipvar = false;
+		    }
 
-  if ( iz ) sprintf(axisname + axisnameLen, "_%u", iz+1);
+                  if ( skipvar )
+                    {
+                      Warning("Unsupported array structure, skipped variable %s!", ncvars[ncvarid].name);
+                      ncvars[ncvarid].isvar = -1;
+                      continue;
+                    }
 
-  return (int)iz;
-}
+		  if ( ncvars[xvarid].xtype == NC_FLOAT ) grid->prec = DATATYPE_FLT32;
+                  if (CDI_netcdf_lazy_grid_load)
+                    {
+                      lazyGrid->xValsGet = (struct xyValGet){
+                        .scalefactor = ncvars[xvarid].scalefactor,
+                        .addoffset = ncvars[xvarid].addoffset,
+                        .start = { start[0], start[1], start[2] },
+                        .count = { count[0], count[1], count[2] },
+                        .size = size,
+                        .datasetNCId = ncvars[xvarid].ncid,
+                        .varNCId = xvarid,
+                        .ndims = (short)ndims,
+                      };
+                      grid->xvals = cdfPendingLoad;
+                    }
+                  else
+                    {
+                      grid->xvals = (double *) Malloc(size*sizeof(double));
+                      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);
+                      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;
+		  */
+		}
 
-static void
-cdfDefAxisCommon(stream_t *streamptr, int gridID, int gridindex, int ndims,
-                 const struct cdfDefGridAxisInqs *gridAxisInq, int dimKey, char axisLetter,
-                 void (*finishCyclicBounds)(double *pbounds, size_t dimlen, const double *pvals))
-{
-  int dimID = CDI_UNDEFID;
-  int ncvarid = CDI_UNDEFID, ncbvarid = CDI_UNDEFID;
-  int nvdimID = CDI_UNDEFID;
-  int fileID  = streamptr->fileID;
-  size_t dimlen = (size_t)gridAxisInq->axisSize(gridID);
-  nc_type xtype = (nc_type)cdfDefDatatype(gridInqPrec(gridID), streamptr->filetype);
+	      if ( yvarid != UNDEFID )
+		{
+                  bool 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;
+			skipvar = dimsize1*dimsize2 != size;
+		      }
+		    }
+		  else if ( ndims == 1 )
+		    {
+		      if ( (int) ysize == 0 ) size = xsize;
+		      else                    size = ysize;
+
+		      /* Check size of 1 dimensional coordinate variables */
+		      {
+			int dimid;
+			size_t dimsize;
+			dimid = ncvars[yvarid].dimids[0];
+			dimsize = ncdims[dimid].len;
+			skipvar = dimsize != size;
+		      }
+		    }
+		  else if ( ndims == 0 && ysize == 0 )
+		    {
+                      size = ysize = 1;
+                      skipvar = false;
+		    }
 
-  ncgrid_t *ncgrid = streamptr->ncgrid;
+                  if ( skipvar )
+                    {
+                      Warning("Unsupported array structure, skipped variable %s!", ncvars[ncvarid].name);
+                      ncvars[ncvarid].isvar = -1;
+                      continue;
+                    }
 
-  const double *pvals = gridAxisInq->axisValsPtr(gridID);
-  char dimname[CDI_MAX_NAME+3]; dimname[0] = 0;
-  if ( ndims && pvals == NULL ) cdiGridInqKeyStr(gridID, dimKey, CDI_MAX_NAME, dimname);
+		  if ( ncvars[yvarid].xtype == NC_FLOAT ) grid->prec = DATATYPE_FLT32;
+                  /* see below for when it's impossible to operate
+                   * without y values */
+                  if ( !CDI_netcdf_lazy_grid_load
+                       || ((ncvars[ncvarid].gridtype == UNDEFID ||
+                            ncvars[ncvarid].gridtype == GRID_GENERIC)
+                           && islat && (islon || xsize == 0)) )
+                    {
+                      grid->yvals = (double *) Malloc(size*sizeof(double));
+
+                      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);
+
+                      scale_add(size, grid->yvals, ncvars[yvarid].addoffset, ncvars[yvarid].scalefactor);
+
+                      /* 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 ( size_t i = 2; i < ysize; i++ )
+                            if ( (fabs(grid->yvals[i-1] - grid->yvals[i]) - yinc) > (yinc/1000) )
+                              {
+                                yinc = 0;
+                                break;
+                              }
+                        }
+                    }
+                  else
+                    {
+                      lazyGrid->yValsGet = (struct xyValGet){
+                        .scalefactor = ncvars[yvarid].scalefactor,
+                        .addoffset = ncvars[yvarid].addoffset,
+                        .start = { start[0], start[1], start[2] },
+                        .count = { count[0], count[1], count[2] },
+                        .size = size,
+                        .datasetNCId = ncvars[yvarid].ncid,
+                        .varNCId = yvarid,
+                        .ndims = (short)ndims,
+                      };
+                      grid->yvals = cdfPendingLoad;
+                    }
+                  strcpy(grid->yname, ncvars[yvarid].name);
+                  strcpy(grid->ylongname, ncvars[yvarid].longname);
+                  strcpy(grid->yunits, ncvars[yvarid].units);
+		}
 
-  for ( int index = 0; index < gridindex; ++index )
-    {
-      int gridID0 = ncgrid[index].gridID;
-      assert(gridID0 != CDI_UNDEFID);
-      int gridtype0 = gridInqType(gridID0);
-      if ( gridtype0 == GRID_GAUSSIAN    ||
-           gridtype0 == GRID_LONLAT      ||
-           gridtype0 == GRID_PROJECTION  ||
-           gridtype0 == GRID_CURVILINEAR ||
-           gridtype0 == GRID_GENERIC )
-        {
-          size_t dimlen0 = (size_t)gridAxisInq->axisSize(gridID0);
-          char dimname0[CDI_MAX_NAME]; dimname0[0] = 0;
-          if ( dimname[0] ) cdiGridInqKeyStr(gridID0, dimKey, CDI_MAX_NAME, dimname0);
-          bool lname = dimname0[0] ? strcmp(dimname, dimname0) == 0 : true;
-          if ( dimlen == dimlen0 && lname )
-            {
-              double (*inqVal)(int gridID, int index) = gridAxisInq->axisVal;
-              if ( IS_EQUAL(inqVal(gridID0, 0), inqVal(gridID, 0)) &&
-                   IS_EQUAL(inqVal(gridID0, (int)dimlen-1), inqVal(gridID, (int)dimlen-1)) )
-                {
-                  dimID = ncgrid[index].ncIDs[dimKey == CDI_KEY_XDIMNAME
-                                              ? CDF_DIMID_X : CDF_DIMID_Y];
-                  break;
-                }
-            }
-        }
-    }
+	      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;
+	    }
 
-  if ( dimID == CDI_UNDEFID )
-    {
-      char axisname[CDI_MAX_NAME]; axisname[0] = 0;
-      int keyname = (axisLetter == 'X') ? CDI_KEY_XNAME : CDI_KEY_YNAME;
-      gridAxisInq->axisName(gridID, keyname, CDI_MAX_NAME, axisname);
-      if ( axisname[0] == 0 ) Error("axis name undefined!");
-      size_t axisnameLen = strlen(axisname);
+	  if ( ncvars[ncvarid].gridtype == UNDEFID ||
+	       ncvars[ncvarid].gridtype == GRID_GENERIC )
+	    {
+	      if ( islat && (islon || xsize == 0) )
+		{
+		  if ( isGaussGrid(ysize, yinc, grid->yvals) )
+                    {
+                      ncvars[ncvarid].gridtype = GRID_GAUSSIAN;
+                      grid->np = (int)(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;
+	    }
 
-      /* enough to append _ plus up to 100 decimal and trailing \0 */
-      char extendedAxisname[axisnameLen + 4 + 1];
-      memcpy(extendedAxisname, axisname, axisnameLen + 1);
-      checkGridName(extendedAxisname, fileID);
-      size_t extendedAxisnameLen = axisnameLen + strlen(extendedAxisname + axisnameLen);
+	  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;
+		if ( xvarid != UNDEFID )
+		  {
+		    grid->xdef  = 1;
+		    if ( ncvars[xvarid].bounds != UNDEFID )
+		      {
+			int nbdims = ncvars[ncvars[xvarid].bounds].ndims;
+			if ( nbdims == 2 || nbdims == 3 )
+			  {
+                            vdimid = ncvars[ncvars[xvarid].bounds].dimids[nbdims-1];
+			    size_t nvertex = ncdims[vdimid].len;
+			    grid->nvertex = (int)nvertex;
+                            if (CDI_netcdf_lazy_grid_load)
+                              {
+                                lazyGrid->xBoundsGet.datasetNCId
+                                  = ncvars[xvarid].ncid;
+                                lazyGrid->xBoundsGet.varNCId
+                                  = ncvars[xvarid].bounds;
+                                grid->xbounds = cdfPendingLoad;
+                              }
+                            else
+                              {
+                                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 )
+		      {
+			int nbdims = ncvars[ncvars[yvarid].bounds].ndims;
+			if ( nbdims == 2 || nbdims == 3 )
+			  {
+			    /* size_t 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);
+			    */
+                            if (CDI_netcdf_lazy_grid_load)
+                              {
+                                lazyGrid->yBoundsGet.datasetNCId
+                                  = ncvars[yvarid].ncid;
+                                lazyGrid->yBoundsGet.varNCId
+                                  = ncvars[yvarid].bounds;
+                                grid->ybounds = cdfPendingLoad;
+                              }
+                            else
+                              {
+                                vdimid = ncvars[ncvars[yvarid].bounds].dimids[nbdims-1];
+                                size_t nvertex = ncdims[vdimid].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 ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+		if ( ncvars[ncvarid].cellarea != UNDEFID )
+                  {
+                    if (CDI_netcdf_lazy_grid_load)
+                      {
+                        grid->area = cdfPendingLoad;
+                        lazyGrid->cellAreaGet.datasetNCId
+                          = ncvars[ncvarid].ncid;
+                        lazyGrid->cellAreaGet.varNCId
+                          = ncvars[ncvarid].cellarea;
+                      }
+                    else
+                      {
+                        grid->area = (double *) Malloc(size*sizeof(double));
+                        cdf_get_var_double(ncvars[ncvarid].ncid,
+                                           ncvars[ncvarid].cellarea,
+                                           grid->area);
+                      }
+                  }
 
-      if ( ndims )
-        {
-          if ( dimname[0] == 0 ) strcpy(dimname, extendedAxisname);
-          dimID = checkDimName(fileID, dimlen, dimname);
+		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 ( dimID == CDI_UNDEFID ) cdf_def_dim(fileID, dimname, dimlen, &dimID);
-        }
+          if ( grid->type != ncvars[ncvarid].gridtype )
+            {
+              int gridtype = ncvars[ncvarid].gridtype;
+              grid->type = gridtype;
+              cdiGridTypeInit(grid, gridtype, grid->size);
+            }
 
-      bool gen_bounds = false;
-      bool grid_is_cyclic = gridIsCircular(gridID) > 0;
-      double *pbounds = NULL;
-      if ( pvals )
-        {
-          cdf_def_var(fileID, extendedAxisname, xtype, ndims, &dimID, &ncvarid);
+	  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;
+		}
+	    }
 
-          cdfPutGridStdAtts(fileID, ncvarid, gridID, axisLetter, gridAxisInq);
-          {
-            char axisStr[2] = { axisLetter, '\0' };
-            cdf_put_att_text(fileID, ncvarid, "axis", 1, axisStr);
-          }
+	  if ( number_of_grid_used != UNDEFID && (grid->type == UNDEFID || grid->type == GRID_GENERIC) )
+            grid->type   = GRID_UNSTRUCTURED;
 
-          pbounds = (double *)gridAxisInq->axisBoundsPtr(gridID);
+	  if ( number_of_grid_used != UNDEFID && grid->type == GRID_UNSTRUCTURED )
+            grid->number = number_of_grid_used;
 
-          if ( CDI_cmor_mode && grid_is_cyclic && !pbounds )
+	  if ( ncvars[ncvarid].gmapid >= 0 && ncvars[ncvarid].gridtype != GRID_CURVILINEAR )
+	    {
+              int nvatts;
+	      cdf_inq_varnatts(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, &nvatts);
+
+	      for ( int iatt = 0; iatt < nvatts; iatt++ )
+		{
+                  size_t attlen;
+                  char attname[CDI_MAX_NAME];
+		  cdf_inq_attname(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, iatt, attname);
+		  cdf_inq_attlen(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, &attlen);
+
+		  if ( strcmp(attname, "grid_mapping_name") == 0 )
+		    {
+                      enum {
+                        attstringlen = 8192,
+                      };
+                      char attstring[attstringlen];
+
+		      cdfGetAttText(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, attname, attstringlen, attstring);
+		      strtolower(attstring);
+
+		      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 )
+		    {
+                      double datt;
+		      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 )
+		    {
+                      double datt;
+		      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 )
+			{
+                          double datt;
+			  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 ( grid->type == GRID_UNSTRUCTURED )
             {
-              gen_bounds = true;
-              pbounds = (double*) Malloc(2*dimlen*sizeof(double));
-              for ( size_t i = 0; i < dimlen-1; ++i )
+              int zdimid = UNDEFID;
+              int xdimidx = -1, ydimidx = -1;
+
+              for ( int i = 0; i < ndims; i++ )
                 {
-                  pbounds[i*2+1]   = (pvals[i] + pvals[i+1])/2;
-                  pbounds[(i+1)*2] = (pvals[i] + pvals[i+1])/2;
+                  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];
                 }
-              finishCyclicBounds(pbounds, dimlen, pvals);
-            }
-          if ( pbounds )
-            {
-              size_t nvertex = gridInqNvertex(gridID);
-              if ( nc_inq_dimid(fileID, bndsName, &nvdimID) != NC_NOERR )
-                cdf_def_dim(fileID, bndsName, nvertex, &nvdimID);
-            }
-          if ( pbounds && nvdimID != CDI_UNDEFID )
-            {
-              char boundsname[extendedAxisnameLen + 1 + sizeof (bndsName)];
-              memcpy(boundsname, axisname, extendedAxisnameLen);
-              boundsname[extendedAxisnameLen] = '_';
-              memcpy(boundsname + extendedAxisnameLen + 1, bndsName, sizeof bndsName);
-              int dimIDs[2] = { dimID, nvdimID };
-              cdf_def_var(fileID, boundsname, xtype, 2, dimIDs, &ncbvarid);
-              cdf_put_att_text(fileID, ncvarid, "bounds", extendedAxisnameLen + sizeof (bndsName), boundsname);
-            }
-        }
-
-      cdf_enddef(fileID);
-      streamptr->ncmode = 2;
 
-      if ( ncvarid  != CDI_UNDEFID ) cdf_put_var_double(fileID, ncvarid, pvals);
-      if ( ncbvarid != CDI_UNDEFID ) cdf_put_var_double(fileID, ncbvarid, pbounds);
-      if ( gen_bounds ) Free(pbounds);
+              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;
+                    }
+                }
 
-      if ( ndims == 0 )
-        ncgrid[gridindex].ncIDs[dimKey == CDI_KEY_XDIMNAME
-                                ? CDF_VARID_X : CDF_VARID_Y] = ncvarid;
-    }
+              if ( grid->size != grid->xsize )
+                {
+                  Warning("Unsupported array structure, skipped variable %s!", ncvars[ncvarid].name);
+                  ncvars[ncvarid].isvar = -1;
+                  continue;
+                }
 
-  ncgrid[gridindex].gridID = gridID;
-  ncgrid[gridindex].ncIDs[dimKey == CDI_KEY_XDIMNAME
-                          ? CDF_DIMID_X : CDF_DIMID_Y] = dimID;
-}
+              if ( ncvars[ncvarid].position > 0 ) grid->position = ncvars[ncvarid].position;
+              if ( uuidOfHGrid[0] != 0 ) memcpy(grid->uuid, uuidOfHGrid, 16);
+            }
 
-static
-void finishCyclicXBounds(double *pbounds, size_t dimlen, const double *pvals)
-{
-  pbounds[0] = (pvals[0] + pvals[dimlen-1]-360)*0.5;
-  pbounds[2*dimlen-1] = (pvals[dimlen-1] + pvals[0]+360)*0.5;
-}
+#if defined (PROJECTION_TEST)
+	  if ( proj->type == GRID_PROJECTION )
+	    {
+	      if ( grid->type == GRID_GENERIC )
+		{
+		  grid->type = GRID_CURVILINEAR;
+		}
 
-static
-void cdfDefXaxis(stream_t *streamptr, int gridID, int gridindex, int ndims)
-{
-  cdfDefAxisCommon(streamptr, gridID, gridindex, ndims, &gridInqsX,
-                   CDI_KEY_XDIMNAME, 'X', finishCyclicXBounds);
-}
+	      if ( grid->type == GRID_CURVILINEAR )
+		{
+                  proj->size  = grid->size;
+                  proj->xsize = grid->xsize;
+                  proj->ysize = grid->ysize;
+		}
 
-static
-void finishCyclicYBounds(double *pbounds, size_t dimlen, const double *pvals)
-{
-  pbounds[0] = copysign(90.0, pvals[0]);
-  pbounds[2*dimlen-1] = copysign(90.0, pvals[dimlen-1]);
-}
+	      //  grid->proj = gridGenerate(proj);
+	    }
+#endif
 
-static
-void cdfDefYaxis(stream_t *streamptr, int gridID, int gridindex, int ndims)
-{
-  cdfDefAxisCommon(streamptr, gridID, gridindex, ndims, &gridInqsY,
-                   CDI_KEY_YDIMNAME, 'Y', finishCyclicYBounds);
-}
+	  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);
+	    }
 
-static
-void cdfGridCompress(int fileID, int ncvarid, int gridsize, int filetype, int comptype)
-{
-#if  defined  (HAVE_NETCDF4)
-  if ( gridsize > 1 && comptype == CDI_COMPRESS_ZIP && (filetype == CDI_FILETYPE_NC4 || filetype == CDI_FILETYPE_NC4C) )
-    {
-      cdf_def_var_chunking(fileID, ncvarid, NC_CHUNKED, NULL);
-      cdfDefVarDeflate(fileID, ncvarid, 1);
-    }
+#if defined (PROJECTION_TEST)
+	  if ( proj->type == GRID_PROJECTION )
+	    {
+              projAdded = cdiVlistAddGridIfNew(vlistID, proj, 1);
+              ncvars[ncvarid].gridID = projAdded.Id;
+	      copy_numeric_projatts(ncvars[ncvarid].gridID, ncvars[ncvarid].gmapid, ncvars[ncvarid].ncid);
+	    }
+	  else
 #endif
-}
+            {
+              gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 1);
+              ncvars[ncvarid].gridID = gridAdded.Id;
+            }
 
-static
-void cdfDefGridReference(stream_t *streamptr, int gridID)
-{
-  int fileID  = streamptr->fileID;
-  int number = gridInqNumber(gridID);
+          if ( grid->type == GRID_UNSTRUCTURED )
+            {
+              if ( gridfile[0] != 0 ) gridDefReference(ncvars[ncvarid].gridID, gridfile);
+            }
 
-  if ( number > 0 )
-    {
-      cdf_put_att_int(fileID, NC_GLOBAL, "number_of_grid_used", NC_INT, 1, &number);
-    }
+          if ( ncvars[ncvarid].chunked ) grid_set_chunktype(grid, &ncvars[ncvarid]);
 
-  const char *gridfile = gridInqReferencePtr(gridID);
-  if ( gridfile && gridfile[0] != 0 )
-    cdf_put_att_text(fileID, NC_GLOBAL, "grid_file_uri", strlen(gridfile), gridfile);
-}
+	  int 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);
 
-static
-void cdfDefGridUUID(stream_t *streamptr, int gridID)
-{
-  unsigned char uuidOfHGrid[CDI_UUID_SIZE];
+          if ( xdimid != -1 )
+            cdiGridDefString(ncvars[ncvarid].gridID, CDI_GRID_XDIMNAME, (int)(strlen(ncdims[xdimid].name)+1), ncdims[xdimid].name);
+          if ( ydimid != -1 )
+            cdiGridDefString(ncvars[ncvarid].gridID, CDI_GRID_YDIMNAME, (int)(strlen(ncdims[ydimid].name)+1), ncdims[ydimid].name);
+          if ( vdimid != -1 )
+            cdiGridDefString(ncvars[ncvarid].gridID, CDI_GRID_VDIMNAME, (int)(strlen(ncdims[vdimid].name)+1), ncdims[vdimid].name);
 
-  gridInqUUID(gridID, uuidOfHGrid);
-  if ( !cdiUUIDIsNull(uuidOfHGrid) )
-    {
-      char uuidOfHGridStr[37];
-      cdiUUID2Str(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 ( CDI_Debug )
+	    Message("gridID %d %d %s", ncvars[ncvarid].gridID, ncvarid, ncvars[ncvarid].name);
 
-struct cdfDefIrregularGridCommonIDs
-{
-  int xdimID, ydimID, ncxvarid, ncyvarid, ncavarid;
-};
+	  for ( int 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;
 
-static struct cdfDefIrregularGridCommonIDs
-cdfDefIrregularGridCommon(stream_t *streamptr, int gridID,
-                          size_t xdimlen, size_t ydimlen,
-                          int ndims, const char *xdimname_default,
-                          size_t nvertex, const char *vdimname_default,
-                          bool setVdimname)
-{
-  nc_type xtype = (nc_type)cdfDefDatatype(gridInqPrec(gridID), streamptr->filetype);
-  int xdimID = CDI_UNDEFID;
-  int ydimID = CDI_UNDEFID;
-  int ncxvarid = CDI_UNDEFID, ncyvarid = CDI_UNDEFID, ncavarid = CDI_UNDEFID;
-  int ncbxvarid = CDI_UNDEFID, ncbyvarid = CDI_UNDEFID;
-  int fileID  = streamptr->fileID;
-  if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+		for ( int 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]; }
+		  }
 
-  {
-    char xdimname[CDI_MAX_NAME+3];
-    xdimname[0] = 0;
-    cdiGridInqKeyStr(gridID, CDI_KEY_XDIMNAME, CDI_MAX_NAME, xdimname);
-    if ( xdimname[0] == 0 ) strcpy(xdimname, xdimname_default);
-    xdimID = checkDimName(fileID, xdimlen, xdimname);
-    if ( xdimID == CDI_UNDEFID ) cdf_def_dim(fileID, xdimname, xdimlen, &xdimID);
-  }
+                if ( ncvars[ncvarid2].gridtype == UNDEFID && grid->type == GRID_UNSTRUCTURED )
+                  {
+                    if ( xdimid == xdimid2 && ydimid2 != UNDEFID && zdimid2 == UNDEFID )
+                      {
+                        ncvars[ncvarid2].dimtype[ydimidx] = Z_AXIS;
+                        ydimid2 = UNDEFID;
+                      }
 
-  if ( ndims == 3 )
-    {
-      char ydimname[CDI_MAX_NAME+3];
-      ydimname[0] = 0;
-      cdiGridInqKeyStr(gridID, CDI_KEY_YDIMNAME, CDI_MAX_NAME, ydimname);
-      if ( ydimname[0] == 0 ) { ydimname[0] = 'y'; ydimname[1] = 0; }
-      ydimID = checkDimName(fileID, ydimlen, ydimname);
-      if ( ydimID == CDI_UNDEFID ) cdf_def_dim(fileID, ydimname, ydimlen, &ydimID);
-    }
+                    if ( xdimid == ydimid2 && xdimid2 != UNDEFID && zdimid2 == UNDEFID )
+                      {
+                        ncvars[ncvarid2].dimtype[xdimidx] = Z_AXIS;
+                        xdimid2 = ydimid2;
+                        ydimid2 = UNDEFID;
+                      }
+                  }
 
-  int nvdimID = CDI_UNDEFID;
-  int dimIDs[3];
-  dimIDs[ndims-1] = CDI_UNDEFID;
-  if ( setVdimname )
-    {
-      char vdimname[CDI_MAX_NAME+3]; vdimname[0] = 0;
-      cdiGridInqKeyStr(gridID, CDI_KEY_VDIMNAME, CDI_MAX_NAME, vdimname);
-      if ( vdimname[0] == 0 ) strcpy(vdimname, vdimname_default);
-      nvdimID = dimIDs[ndims-1] = checkDimName(fileID, nvertex, vdimname);
-      if ( nvdimID == CDI_UNDEFID )
-        {
-          cdf_def_dim(fileID, vdimname, nvertex, dimIDs+ndims-1);
-          nvdimID = dimIDs[ndims-1];
-        }
-    }
+                if ( xdimid == xdimid2 &&
+		    (ydimid == ydimid2 || (xdimid == ydimid && ydimid2 == UNDEFID)) )
+		  {
+		    int same_grid = ncvars[ncvarid].xvarid == ncvars[ncvarid2].xvarid
+                      && ncvars[ncvarid].yvarid == ncvars[ncvarid2].yvarid
+                      && ncvars[ncvarid].position == ncvars[ncvarid2].position;
+                    /*
+		    if ( xvarid != -1 && ncvars[ncvarid2].xvarid != UNDEFID &&
+			 xvarid != ncvars[ncvarid2].xvarid ) same_grid = FALSE;
+
+		    if ( yvarid != -1 && ncvars[ncvarid2].yvarid != UNDEFID &&
+			 yvarid != ncvars[ncvarid2].yvarid ) same_grid = FALSE;
+                    */
+
+		    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;
+		      }
+		  }
+	      }
 
-  if ( ndims == 3 )
-    {
-      dimIDs[0] = ydimID;
-      dimIDs[1] = xdimID;
+          if (gridAdded.isNew)
+            lazyGrid = NULL;
+          if (projAdded.isNew)
+            lazyProj = NULL;
+	}
     }
-  else /* ndims == 2 */
+  if (lazyGrid)
     {
-      dimIDs[0] = xdimID;
-      cdfDefGridReference(streamptr, gridID);
-      cdfDefGridUUID(streamptr, gridID);
+      if (CDI_netcdf_lazy_grid_load) cdfLazyGridDestroy(lazyGrid);
+      grid_free(grid);
+      Free(grid);
     }
-
-  const double *xvalsPtr = gridInqXvalsPtr(gridID),
-    *xboundsPtr = NULL;
-  if ( xvalsPtr )
+  if (lazyProj)
     {
-      char xaxisname[CDI_MAX_NAME]; xaxisname[0] = 0;
-      cdiGridInqKeyStr(gridID, CDI_KEY_XNAME, CDI_MAX_NAME, xaxisname);
-      checkGridName(xaxisname, fileID);
-      cdf_def_var(fileID, xaxisname, xtype, ndims-1, dimIDs, &ncxvarid);
-      cdfGridCompress(fileID, ncxvarid, (int)(xdimlen*ydimlen), streamptr->filetype, streamptr->comptype);
-
-      cdfPutGridStdAtts(fileID, ncxvarid, gridID, 'X', &gridInqsX);
-
-      /* attribute for Panoply */
-      if ( ndims == 3 )
-        cdf_put_att_text(fileID, ncxvarid, "_CoordinateAxisType", 3, "Lon");
-
-      if ( (xboundsPtr = gridInqXboundsPtr(gridID)) && nvdimID != CDI_UNDEFID )
-        {
-          size_t xaxisnameLen = strlen(xaxisname);
-          xaxisname[xaxisnameLen] = '_';
-          memcpy(xaxisname + xaxisnameLen + 1, bndsName, sizeof (bndsName));
-          cdf_def_var(fileID, xaxisname, xtype, ndims, dimIDs, &ncbxvarid);
-          cdfGridCompress(fileID, ncbxvarid, (int)(xdimlen*ydimlen), streamptr->filetype, streamptr->comptype);
-
-          cdf_put_att_text(fileID, ncxvarid, "bounds", xaxisnameLen + sizeof (bndsName), xaxisname);
-        }
+      if (CDI_netcdf_lazy_grid_load) cdfLazyGridDestroy(lazyProj);
+      grid_free(proj);
+      Free(proj);
     }
+#undef proj
+#undef grid
+}
+
+/* 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_echam, double *vct_echam, unsigned char *uuidOfVGrid)
+{
+  int ncvarid, ncvarid2;
+  int i, ilev;
+  int zaxisindex;
+  int nbdims, nvertex, nlevel;
+  int psvarid = -1;
+  char *pname, *plongname, *punits;
+  size_t vctsize = vctsize_echam;
+  double *vct = vct_echam;
 
-  const double *yvalsPtr = gridInqYvalsPtr(gridID),
-    *yboundsPtr = NULL;
-  if ( yvalsPtr )
+  for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
     {
-      char yaxisname[CDI_MAX_NAME];
-      gridInqYname(gridID, yaxisname);
-      checkGridName(yaxisname, fileID);
+      if ( ncvars[ncvarid].isvar == TRUE && ncvars[ncvarid].zaxisID == UNDEFID )
+	{
+          int is_scalar = FALSE;
+	  int with_bounds = FALSE;
+	  int zdimid = UNDEFID;
+	  int zvarid = UNDEFID;
+	  int zsize = 1;
+	  double *lbounds = NULL;
+	  double *ubounds = NULL;
 
-      cdf_def_var(fileID, yaxisname, xtype, ndims - 1, dimIDs, &ncyvarid);
-      cdfGridCompress(fileID, ncyvarid, (int)(xdimlen*ydimlen), streamptr->filetype, streamptr->comptype);
+          int positive = 0;
+	  int ndims = ncvars[ncvarid].ndims;
 
-      cdfPutGridStdAtts(fileID, ncyvarid, gridID, 'Y', &gridInqsY);
+          if ( ncvars[ncvarid].zvarid != -1 && ncvars[ncvars[ncvarid].zvarid].ndims == 0 )
+            {
+              zvarid = ncvars[ncvarid].zvarid;
+              is_scalar = TRUE;
+            }
+          else
+            {
+              for ( i = 0; i < ndims; i++ )
+                {
+                  if ( ncvars[ncvarid].dimtype[i] == Z_AXIS )
+                    zdimid = ncvars[ncvarid].dimids[i];
+                }
 
-      /* attribute for Panoply */
-      if ( ndims == 3 )
-        cdf_put_att_text(fileID, ncyvarid, "_CoordinateAxisType", 3, "Lat");
+              if ( zdimid != UNDEFID )
+                {
+                  zvarid = ncdims[zdimid].ncvarid;
+                  zsize  = (int)ncdims[zdimid].len;
+                }
+            }
 
-      if ( (yboundsPtr = gridInqYboundsPtr(gridID)) && nvdimID != CDI_UNDEFID )
-        {
-          size_t yaxisnameLen = strlen(yaxisname);
-          yaxisname[yaxisnameLen] = '_';
-          memcpy(yaxisname + yaxisnameLen + 1, bndsName, sizeof (bndsName));
-          cdf_def_var(fileID, yaxisname, xtype, ndims, dimIDs, &ncbyvarid);
-          cdfGridCompress(fileID, ncbyvarid, (int)(xdimlen*ydimlen), streamptr->filetype, streamptr->comptype);
+	  if ( CDI_Debug ) Message("nlevs = %d", zsize);
 
-          cdf_put_att_text(fileID, ncyvarid, "bounds", yaxisnameLen + sizeof (bndsName), yaxisname);
-        }
-    }
+	  double *zvar = (double *) Malloc((size_t)zsize * sizeof (double));
 
-  const double *areaPtr = gridInqAreaPtr(gridID);
-  if ( areaPtr )
-    {
-      static const char yaxisname_[] = "cell_area";
-      static const char units[] = "m2";
-      static const char longname[] = "area of grid cell";
-      static const char stdname[] = "cell_area";
+	  int zaxisType = UNDEFID;
+	  if ( zvarid != UNDEFID ) zaxisType = ncvars[zvarid].zaxistype;
+	  if ( zaxisType == UNDEFID )  zaxisType = ZAXIS_GENERIC;
 
-      cdf_def_var(fileID, yaxisname_, xtype, ndims-1, dimIDs, &ncavarid);
+	  int zprec = DATATYPE_FLT64;
+
+	  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;
+	      */
+              psvarid = -1;
+              if ( zaxisType == ZAXIS_HYBRID && ncvars[zvarid].vct )
+                {
+                  vct = ncvars[zvarid].vct;
+                  vctsize = ncvars[zvarid].vctsize;
 
-      cdf_put_att_text(fileID, ncavarid, "standard_name", sizeof (stdname) - 1, stdname);
-      cdf_put_att_text(fileID, ncavarid, "long_name", sizeof (longname) - 1, longname);
-      cdf_put_att_text(fileID, ncavarid, "units", sizeof (units) - 1, units);
-    }
+                  if ( ncvars[zvarid].psvarid != -1 ) psvarid = ncvars[zvarid].psvarid;
+                }
 
-  cdf_enddef(fileID);
-  streamptr->ncmode = 2;
+	      cdf_get_var_double(ncvars[zvarid].ncid, zvarid, zvar);
 
-  if ( ncxvarid  != CDI_UNDEFID ) cdf_put_var_double(fileID, ncxvarid,  xvalsPtr);
-  if ( ncbxvarid != CDI_UNDEFID ) cdf_put_var_double(fileID, ncbxvarid, xboundsPtr);
-  if ( ncyvarid  != CDI_UNDEFID ) cdf_put_var_double(fileID, ncyvarid,  yvalsPtr);
-  if ( ncbyvarid != CDI_UNDEFID ) cdf_put_var_double(fileID, ncbyvarid, yboundsPtr);
-  if ( ncavarid  != CDI_UNDEFID ) cdf_put_var_double(fileID, ncavarid,  areaPtr);
+	      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 )
+			{
+			  with_bounds = TRUE;
+			  lbounds = (double *) Malloc((size_t)nlevel*sizeof(double));
+			  ubounds = (double *) Malloc((size_t)nlevel*sizeof(double));
+			  double zbounds[2*nlevel];
+			  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];
+			    }
+			}
+		    }
+		}
+	    }
+	  else
+	    {
+	      pname     = NULL;
+	      plongname = NULL;
+	      punits    = NULL;
 
-  return (struct cdfDefIrregularGridCommonIDs) {
-    .xdimID=xdimID, .ydimID = ydimID,
-    .ncxvarid=ncxvarid, .ncyvarid=ncyvarid, .ncavarid=ncavarid
-  };
-}
+	      if ( zsize == 1 )
+		{
+                  if ( ncvars[ncvarid].zaxistype != UNDEFID )
+                    zaxisType = ncvars[ncvarid].zaxistype;
+                  else
+                    zaxisType = ZAXIS_SURFACE;
 
-static
-void cdfDefCurvilinear(stream_t *streamptr, int gridID, int gridindex)
-{
-  ncgrid_t *ncgrid = streamptr->ncgrid;
+		  zvar[0] = 0;
+		  /*
+		  if ( zdimid == UNDEFID )
+		    zvar[0] = 9999;
+		  else
+		    zvar[0] = 0;
+		  */
+		}
+	      else
+		{
+		  for ( ilev = 0; ilev < zsize; ilev++ ) zvar[ilev] = ilev + 1;
+		}
+	    }
 
-  size_t dimlen = (size_t)gridInqSize(gridID);
-  size_t xdimlen = (size_t)gridInqXsize(gridID);
-  size_t ydimlen = (size_t)gridInqYsize(gridID);
+      	  ncvars[ncvarid].zaxisID = varDefZaxis(vlistID, zaxisType, (int) zsize, zvar, with_bounds, lbounds, ubounds,
+						(int)vctsize, vct, pname, plongname, punits, zprec, 1, 0);
 
-  int xdimID = CDI_UNDEFID, ydimID = CDI_UNDEFID;
-  int ncxvarid = CDI_UNDEFID, ncyvarid = CDI_UNDEFID, ncavarid = CDI_UNDEFID;
-  {
-    size_t ofs = 0;
-    do {
-      struct idSearch search
-        = cdfSearchIDBySize(ofs, (size_t)gridindex, ncgrid, CDF_DIMID_X,
-                            GRID_CURVILINEAR, (int)dimlen,
-                            gridInqType, gridInqSize);
-      size_t index = search.foundIdx;
-      if ( index != SIZE_MAX )
-        {
-          int gridID0 = ncgrid[index].gridID;
-          if (    IS_EQUAL(gridInqXval(gridID0, 0), gridInqXval(gridID, 0))
-               && IS_EQUAL(gridInqXval(gridID0, (int)dimlen-1),
-                           gridInqXval(gridID, (int)dimlen-1))
-               && IS_EQUAL(gridInqYval(gridID0, 0), gridInqYval(gridID, 0))
-               && IS_EQUAL(gridInqYval(gridID0, (int)dimlen-1),
-                           gridInqYval(gridID, (int)dimlen-1)) )
+	  if ( uuidOfVGrid[0] != 0 )
             {
-              xdimID = ncgrid[index].ncIDs[CDF_DIMID_X];
-              ydimID = ncgrid[index].ncIDs[CDF_DIMID_Y];
-              ncxvarid = ncgrid[index].ncIDs[CDF_VARID_X];
-              ncyvarid = ncgrid[index].ncIDs[CDF_VARID_Y];
-              break;
+              // printf("uuidOfVGrid: defined\n");
+              zaxisDefUUID(ncvars[ncvarid].zaxisID, uuidOfVGrid);
             }
-          ofs = search.foundIdx;
-          if ( ofs < (size_t)gridindex )
-            continue;
-        }
-    } while (false);
-  }
 
-  if ( xdimID == CDI_UNDEFID || ydimID == CDI_UNDEFID )
-    {
-      struct cdfDefIrregularGridCommonIDs createdIDs
-        = cdfDefIrregularGridCommon(streamptr, gridID,
-                                    xdimlen, ydimlen, 3, "x", 4, "nv4",
-                                    gridInqXboundsPtr(gridID)
-                                    || gridInqYboundsPtr(gridID));
-      xdimID = createdIDs.xdimID;
-      ydimID = createdIDs.ydimID;
-      ncxvarid = createdIDs.ncxvarid;
-      ncyvarid = createdIDs.ncyvarid;
-      ncavarid = createdIDs.ncavarid;
-    }
+          if ( zaxisType == ZAXIS_HYBRID && psvarid != -1 ) zaxisDefPsName(ncvars[ncvarid].zaxisID, ncvars[psvarid].name);
 
-  ncgrid[gridindex].gridID = gridID;
-  ncgrid[gridindex].ncIDs[CDF_DIMID_X] = xdimID;
-  ncgrid[gridindex].ncIDs[CDF_DIMID_Y] = ydimID;
-  ncgrid[gridindex].ncIDs[CDF_VARID_X] = ncxvarid;
-  ncgrid[gridindex].ncIDs[CDF_VARID_Y] = ncyvarid;
-  ncgrid[gridindex].ncIDs[CDF_VARID_A] = ncavarid;
-}
+          if ( positive > 0 ) zaxisDefPositive(ncvars[ncvarid].zaxisID, positive);
+          if ( is_scalar ) zaxisDefScalar(ncvars[ncvarid].zaxisID);
 
+          if ( zdimid != -1 )
+            cdiZaxisDefString(ncvars[ncvarid].zaxisID, CDI_ZAXIS_DIMNAME, (int)(strlen(ncdims[zdimid].name)+1), ncdims[zdimid].name);
+          /*
+          if ( vdimid != -1 )
+            cdiZaxisDefString(ncvars[ncvarid].zaxisID, CDI_ZAXIS_VDIMNAME, strlen(ncdims[vdimid].name)+1, ncdims[vdimid].name);
+          */
+	  Free(zvar);
+	  Free(lbounds);
+	  Free(ubounds);
 
-static
-void cdfDefUnstructured(stream_t *streamptr, int gridID, int gridindex)
-{
-  ncgrid_t *ncgrid = streamptr->ncgrid;
+	  zaxisindex = vlistZaxisIndex(vlistID, ncvars[ncvarid].zaxisID);
+	  streamptr->zaxisID[zaxisindex]  = zdimid;
 
-  size_t dimlen = (size_t)gridInqSize(gridID);
+	  if ( CDI_Debug )
+	    Message("zaxisID %d %d %s", ncvars[ncvarid].zaxisID, ncvarid, ncvars[ncvarid].name);
 
-  int dimID = CDI_UNDEFID;
-  int ncxvarid = CDI_UNDEFID, ncyvarid = CDI_UNDEFID, ncavarid = CDI_UNDEFID;
-  {
-    size_t ofs = 0;
-    do {
-      struct idSearch search
-        = cdfSearchIDBySize(ofs, (size_t)gridindex, ncgrid, CDF_DIMID_X,
-                            GRID_UNSTRUCTURED, (int)dimlen,
-                            gridInqType, gridInqSize);
-      size_t index = search.foundIdx;
-      if ( index != SIZE_MAX )
-        {
-          int gridID0 = ncgrid[index].gridID;
-          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)) &&
-               IS_EQUAL(gridInqYval(gridID0, 0), gridInqYval(gridID, 0)) &&
-               IS_EQUAL(gridInqYval(gridID0, (int)dimlen-1),
-                        gridInqYval(gridID, (int)dimlen-1)) )
-            {
-              dimID = ncgrid[index].ncIDs[CDF_DIMID_X];
-              ncxvarid = ncgrid[index].ncIDs[CDF_VARID_X];
-              ncyvarid = ncgrid[index].ncIDs[CDF_VARID_Y];
-              ncavarid = ncgrid[index].ncIDs[CDF_VARID_A];
-              break;
-            }
-          ofs = search.foundIdx;
-          if ( ofs < (size_t)gridindex )
-            continue;
-        }
-    } while (false);
-  }
+	  for ( ncvarid2 = ncvarid+1; ncvarid2 < nvars; ncvarid2++ )
+	    if ( ncvars[ncvarid2].isvar == TRUE && ncvars[ncvarid2].zaxisID == UNDEFID /*&& ncvars[ncvarid2].zaxistype == UNDEFID*/ )
+	      {
+                int zvarid2 = UNDEFID;
+                if ( ncvars[ncvarid2].zvarid != UNDEFID && ncvars[ncvars[ncvarid2].zvarid].ndims == 0 )
+                  zvarid2 = ncvars[ncvarid2].zvarid;
 
-  if ( dimID == CDI_UNDEFID )
-    {
-      size_t nvertex = (size_t)gridInqNvertex(gridID);
-      struct cdfDefIrregularGridCommonIDs createdIDs
-        = cdfDefIrregularGridCommon(streamptr, gridID,
-                                    dimlen, 1, 2, "ncells",
-                                    nvertex, "vertices", nvertex > 0);
-      dimID = createdIDs.xdimID;
-      ncxvarid = createdIDs.ncxvarid;
-      ncyvarid = createdIDs.ncyvarid;
-      ncavarid = createdIDs.ncavarid;
-    }
+		int zdimid2 = UNDEFID;
+		ndims = ncvars[ncvarid2].ndims;
+		for ( i = 0; i < ndims; i++ )
+		  {
+		    if ( ncvars[ncvarid2].dimtype[i] == Z_AXIS )
+		      zdimid2 = ncvars[ncvarid2].dimids[i];
+		  }
 
-  ncgrid[gridindex].gridID = gridID;
-  ncgrid[gridindex].ncIDs[CDF_DIMID_X] = dimID;
-  ncgrid[gridindex].ncIDs[CDF_VARID_X] = ncxvarid;
-  ncgrid[gridindex].ncIDs[CDF_VARID_Y] = ncyvarid;
-  ncgrid[gridindex].ncIDs[CDF_VARID_A] = ncavarid;
+		if ( zdimid == zdimid2 /* && zvarid == zvarid2 */)
+		  {
+                    if ( (zdimid != UNDEFID && ncvars[ncvarid2].zaxistype == UNDEFID) ||
+                         (zdimid == UNDEFID && zvarid != UNDEFID && zvarid == zvarid2) ||
+                         (zdimid == UNDEFID && zaxisType == ncvars[ncvarid2].zaxistype) ||
+                         (zdimid == UNDEFID && zvarid2 == UNDEFID && ncvars[ncvarid2].zaxistype == UNDEFID) )
+                      {
+                        if ( CDI_Debug )
+                          Message("zaxisID %d %d %s", ncvars[ncvarid].zaxisID, ncvarid2, ncvars[ncvarid2].name);
+                        ncvars[ncvarid2].zaxisID = ncvars[ncvarid].zaxisID;
+                      }
+                  }
+	      }
+	}
+    }
 }
 
-struct attTxtTab2
+struct varinfo
 {
-  const char *attName, *attVal;
-  size_t valLen;
+  int      ncvarid;
+  const char *name;
 };
 
 static
-void cdf_def_vct_echam(stream_t *streamptr, int zaxisID)
+int cmpvarname(const void *s1, const void *s2)
 {
-  int type = zaxisInqType(zaxisID);
+  const struct varinfo *x = (const struct varinfo *)s1,
+    *y = (const struct varinfo *)s2;
+  return (strcmp(x->name, y->name));
+}
 
-  if ( type == ZAXIS_HYBRID || type == ZAXIS_HYBRID_HALF )
+/* 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 ( CDI_Debug )
     {
-      int ilev = zaxisInqVctSize(zaxisID)/2;
-      if ( ilev == 0 ) return;
-
-      int mlev = ilev - 1;
+      for(int i = 0; i < nvars; i++) Message("varids[%d] = %d", i, varids[i]);
+    }
+  if ( streamptr->sortname )
+    {
+      struct varinfo *varInfo
+        = (struct varinfo *) Malloc((size_t)nvars * sizeof (struct varinfo));
 
-      if ( streamptr->vct.ilev > 0 )
+      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 ( CDI_Debug )
         {
-          if ( streamptr->vct.ilev != ilev )
-            Error("More than one VCT for each file unsupported!");
-          return;
+          for(int i = 0; i < nvars; i++) Message("sorted varids[%d] = %d", i, varids[i]);
         }
+    }
 
-      int fileID = streamptr->fileID;
+  for ( int varID1 = 0; varID1 < nvars; varID1++ )
+    {
+      int ncvarid = varids[varID1];
+      int gridID  = ncvars[ncvarid].gridID;
+      int zaxisID = ncvars[ncvarid].zaxisID;
 
-      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+      stream_new_var(streamptr, gridID, zaxisID, CDI_UNDEFID);
+      int varID = vlistDefVar(vlistID, gridID, zaxisID, ncvars[ncvarid].tsteptype);
 
-      int ncdimid = -1, ncdimid2 = -1;
-      int hyaiid, hybiid, hyamid = -1, hybmid = -1;
+#if  defined  (HAVE_NETCDF4)
+      if ( ncvars[ncvarid].deflate )
+	vlistDefVarCompType(vlistID, varID, COMPRESS_ZIP);
 
-      cdf_def_dim(fileID, "nhyi", (size_t)ilev, &ncdimid2);
-      cdf_def_var(fileID, "hyai", NC_DOUBLE, 1, &ncdimid2, &hyaiid);
-      cdf_def_var(fileID, "hybi", NC_DOUBLE, 1, &ncdimid2, &hybiid);
-      if ( mlev > 0 )
-        {
-          cdf_def_dim(fileID, "nhym", (size_t)mlev, &ncdimid);
-          cdf_def_var(fileID, "hyam", NC_DOUBLE, 1, &ncdimid,  &hyamid);
-          cdf_def_var(fileID, "hybm", NC_DOUBLE, 1, &ncdimid,  &hybmid);
-        }
+      if ( ncvars[ncvarid].chunked && ncvars[ncvarid].chunktype != UNDEFID )
+        vlistDefVarChunkType(vlistID, varID, ncvars[ncvarid].chunktype);
+#endif
 
-      streamptr->vct.ilev   = ilev;
-      streamptr->vct.mlev   = mlev;
-      streamptr->vct.mlevID = ncdimid;
-      streamptr->vct.ilevID = ncdimid2;
+      streamptr->vars[varID1].defmiss = 0;
+      streamptr->vars[varID1].ncvarid = ncvarid;
 
-      {
-        static const char lname_n[] = "long_name",
-          units_n[] = "units",
-          lname_v_ai[] = "hybrid A coefficient at layer interfaces",
-          units_v_ai[] = "Pa",
-          lname_v_bi[] = "hybrid B coefficient at layer interfaces",
-          units_v_bi[] = "1";
-        static const struct attTxtTab2 tab[]
-          = {
-          { lname_n, lname_v_ai, sizeof (lname_v_ai) - 1 },
-          { units_n, units_v_ai, sizeof (units_v_ai) - 1 },
-          { lname_n, lname_v_bi, sizeof (lname_v_bi) - 1 },
-          { units_n, units_v_bi, sizeof (units_v_bi) - 1 },
-        };
-        enum { tabLen = sizeof (tab) / sizeof (tab[0]) };
-        int ids[tabLen] = { hyaiid, hyaiid, hybiid, hybiid };
-        for ( size_t i = 0; i < tabLen; ++i )
-          cdf_put_att_text(fileID, ids[i], tab[i].attName, tab[i].valLen, tab[i].attVal);
-      }
+      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 = 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);
 
-      {
-        static const char lname_n[] = "long_name",
-          units_n[] = "units",
-          lname_v_am[] = "hybrid A coefficient at layer midpoints",
-          units_v_am[] = "Pa",
-          lname_v_bm[] = "hybrid B coefficient at layer midpoints",
-          units_v_bm[] = "1";
-        static const struct attTxtTab2 tab[]
-          = {
-          { lname_n, lname_v_am, sizeof (lname_v_am) - 1 },
-          { units_n, units_v_am, sizeof (units_v_am) - 1 },
-          { lname_n, lname_v_bm, sizeof (lname_v_bm) - 1 },
-          { units_n, units_v_bm, sizeof (units_v_bm) - 1 },
-        };
-        enum { tabLen = sizeof (tab) / sizeof (tab[0]) };
-        int ids[tabLen] = { hyamid, hyamid, hybmid, hybmid };
-        for ( size_t i = 0; i < tabLen; ++i )
-          cdf_put_att_text(fileID, ids[i], tab[i].attName, tab[i].valLen, tab[i].attVal);
-      }
+      if ( ncvars[ncvarid].lvalidrange )
+        vlistDefVarValidrange(vlistID, varID, ncvars[ncvarid].validrange);
 
-      cdf_enddef(fileID);
-      streamptr->ncmode = 2;
+      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);
 
-      const double *vctptr = zaxisInqVctPtr(zaxisID);
+      vlistDefVarDatatype(vlistID, varID, cdfInqDatatype(ncvars[ncvarid].xtype, ncvars[ncvarid].lunsigned));
 
-      cdf_put_var_double(fileID, hyaiid, vctptr);
-      cdf_put_var_double(fileID, hybiid, vctptr+ilev);
+      vlistDefVarInstitut(vlistID, varID, instID);
+      vlistDefVarModel(vlistID, varID, modelID);
+      if ( ncvars[ncvarid].tableID != UNDEFID )
+	vlistDefVarTable(vlistID, varID, ncvars[ncvarid].tableID);
 
-      size_t start;
-      size_t count = 1;
-      double mval;
-      for ( int i = 0; i < mlev; i++ )
+      if ( ncvars[ncvarid].deffillval == FALSE && ncvars[ncvarid].defmissval == TRUE )
         {
-          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);
+          ncvars[ncvarid].deffillval = TRUE;
+          ncvars[ncvarid].fillval    = ncvars[ncvarid].missval;
         }
-    }
-}
-
-static
-void cdf_def_vct_cf(stream_t *streamptr, int zaxisID, int nclevID, int ncbndsID, int p0status, double p0value)
-{
-  int type = zaxisInqType(zaxisID);
-
-  if ( type == ZAXIS_HYBRID || type == ZAXIS_HYBRID_HALF )
-    {
-      int ilev = zaxisInqVctSize(zaxisID)/2;
-      if ( ilev == 0 ) return;
 
-      int mlev = ilev - 1;
-      int hyaiid = 0, hybiid = 0, hyamid, hybmid;
+      if ( ncvars[ncvarid].deffillval == TRUE )
+        vlistDefVarMissval(vlistID, varID, ncvars[ncvarid].fillval);
 
-      if ( streamptr->vct.ilev > 0 )
-        {
-          if ( streamptr->vct.ilev != ilev )
-            Error("more than one VCT for each file unsupported!");
-          return;
-        }
+      if ( CDI_Debug )
+	Message("varID = %d  gridID = %d  zaxisID = %d", varID,
+		vlistInqVarGrid(vlistID, varID), vlistInqVarZaxis(vlistID, varID));
 
-      int fileID = streamptr->fileID;
+      int gridindex = vlistGridIndex(vlistID, gridID);
+      int xdimid = streamptr->xdimID[gridindex];
+      int ydimid = streamptr->ydimID[gridindex];
 
-      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+      int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
+      int zdimid = streamptr->zaxisID[zaxisindex];
 
-      int dimIDs[2];
-      dimIDs[0] = nclevID;
-      dimIDs[1] = ncbndsID;
+      int ndims = ncvars[ncvarid].ndims;
+      int iodim = 0;
+      int ixyz = 0;
+      int ipow10[4] = {1, 10, 100, 1000};
 
-      streamptr->vct.mlev   = mlev;
-      streamptr->vct.ilev   = ilev;
-      streamptr->vct.mlevID = nclevID;
-      streamptr->vct.ilevID = nclevID;
+      if ( ncvars[ncvarid].tsteptype != TSTEP_CONSTANT ) iodim++;
 
-      if ( p0status == 0 )
-        cdf_def_var(fileID, "a", NC_DOUBLE, 1, dimIDs,  &hyamid);
+      if ( gridInqType(gridID) == GRID_UNSTRUCTURED && ndims-iodim <= 2 && ydimid == xdimid )
+        {
+          if ( xdimid == ncvars[ncvarid].dimids[ndims-1] )
+            {
+              ixyz = 321;
+            }
+          else
+            {
+              ixyz = 213;
+            }
+        }
       else
-        cdf_def_var(fileID, "ap", NC_DOUBLE, 1, dimIDs,  &hyamid);
-      cdf_def_var(fileID, "b",  NC_DOUBLE, 1, dimIDs,  &hybmid);
+        {
+          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];
+            }
+        }
 
-      {
-        static const char lname[] = "vertical coordinate formula term: ap(k)";
-        cdf_put_att_text(fileID, hyamid, "long_name", sizeof (lname) - 1, lname);
-      }
-      {
-        static const char units[] = "Pa";
-        cdf_put_att_text(fileID, hyamid, "units", sizeof (units) - 1, units);
-      }
-      {
-        static const char lname[] = "vertical coordinate formula term: b(k)";
-        cdf_put_att_text(fileID, hybmid, "long_name", sizeof (lname) - 1, lname);
-      }
-      {
-        static const char units[] = "1";
-        cdf_put_att_text(fileID, hybmid, "units", sizeof (units) - 1, units);
-      }
+      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 )
+        {
+          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 ( ncbndsID != -1 )
+      if ( ncvars[ncvarid].extra[0] != 0 )
         {
-          if ( p0status == 0 )
-            cdf_def_var(fileID, "a_bnds", NC_DOUBLE, 2, dimIDs, &hyaiid);
-          else
-            cdf_def_var(fileID, "ap_bnds", NC_DOUBLE, 2, dimIDs, &hyaiid);
-          cdf_def_var(fileID, "b_bnds",  NC_DOUBLE, 2, dimIDs, &hybiid);
-          {
-            static const char lname[] = "vertical coordinate formula term: ap(k+1/2)";
-            cdf_put_att_text(fileID, hyaiid, "long_name", sizeof (lname) - 1, lname);
-          }
-          {
-            static const char units[] = "Pa";
-            cdf_put_att_text(fileID, hyaiid, "units", sizeof (units) - 1, units);
-          }
-          {
-            static const char lname[] = "vertical coordinate formula term: b(k+1/2)";
-            cdf_put_att_text(fileID, hybiid, "long_name", sizeof (lname) - 1, lname);
-          }
-          {
-            static const char units[] = "1";
-            cdf_put_att_text(fileID, hybiid, "units", sizeof (units) - 1, units);
-          }
+          vlistDefVarExtra(vlistID, varID, ncvars[ncvarid].extra);
         }
+    }
 
-      cdf_enddef(fileID);
-      streamptr->ncmode = 2;
+  for ( int varID = 0; varID < nvars; varID++ )
+    {
+      int ncvarid = varids[varID];
+      int ncid = ncvars[ncvarid].ncid;
 
-      int vctsize = zaxisInqVctSize(zaxisID);
-      double vct[vctsize];
-      zaxisInqVct(zaxisID, vct);
+      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 ( p0status == 0 && IS_NOT_EQUAL(p0value,0) )
-        for ( int i = 0; i < vctsize/2; ++i ) vct[i] /= p0value;
+	      if ( attrtype == NC_SHORT || attrtype == NC_INT )
+		{
+		  int attint[attlen];
+		  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);
+		}
+	      else if ( attrtype == NC_FLOAT || attrtype == NC_DOUBLE )
+		{
+		  double attflt[attlen];
+		  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);
+		}
+	      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);
+		}
+	    }
 
-      double tarray[ilev*2];
+	  if (ncvars[ncvarid].vct) Free(ncvars[ncvarid].vct);
+	  if (ncvars[ncvarid].atts) Free(ncvars[ncvarid].atts);
+          ncvars[ncvarid].vct = NULL;
+          ncvars[ncvarid].atts = NULL;
+	}
+    }
 
-      if ( ncbndsID != -1 )
-        {
-          for ( int i = 0; i < mlev; ++i )
-            {
-              tarray[2*i  ] = vct[i];
-              tarray[2*i+1] = vct[i+1];
-            }
-          cdf_put_var_double(fileID, hyaiid, tarray);
+  /* release mem of not freed attributes */
+  for ( int ncvarid = 0; ncvarid < num_ncvars; ncvarid++ )
+    if ( ncvars[ncvarid].atts ) Free(ncvars[ncvarid].atts);
 
-          for ( int i = 0; i < mlev; ++i )
-            {
-              tarray[2*i  ] = vct[ilev+i];
-              tarray[2*i+1] = vct[ilev+i+1];
-            }
-          cdf_put_var_double(fileID, hybiid, tarray);
-        }
+  if ( varids ) Free(varids);
 
-      for ( int i = 0; i < mlev; ++i )
-        tarray[i] = (vct[i] + vct[i+1]) * 0.5;
-      cdf_put_var_double(fileID, hyamid, tarray);
+  for ( int varID = 0; varID < nvars; varID++ )
+    {
+      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);
+		}
+	    }
+	}
+    }
 
-      for ( int i = 0; i < mlev; ++i )
-        tarray[i] = (vct[ilev+i] + vct[ilev+i+1]) * 0.5;
-      cdf_put_var_double(fileID, hybmid, tarray);
+  for ( int varID = 0; varID < nvars; varID++ )
+    {
+      int varInstID  = vlistInqVarInstitut(vlistID, varID);
+      int varModelID = vlistInqVarModel(vlistID, varID);
+      int varTableID = 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 ( varTableID != 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
+		{
+		  varTableID = cdiDefaultTableID;
+		}
+	    }
+
+	  if ( cdiDefaultModelID != UNDEFID ) varModelID = cdiDefaultModelID;
+	  if ( cdiDefaultInstID  != UNDEFID ) varInstID  = cdiDefaultInstID;
+	}
+      if ( varInstID  != UNDEFID ) vlistDefVarInstitut(vlistID, varID, varInstID);
+      if ( varModelID != UNDEFID ) vlistDefVarModel(vlistID, varID, varModelID);
+      if ( varTableID != UNDEFID ) vlistDefVarTable(vlistID, varID, varTableID);
     }
 }
 
-struct attTxtTab { const char *txt; size_t txtLen; };
-
 static
-void cdf_def_zaxis_hybrid_echam(stream_t *streamptr, int type, int *ncvaridp, int zaxisID, int zaxisindex, int xtype, size_t dimlen, int *dimID, char *axisname)
+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)
 {
-  int fileID = streamptr->fileID;
-
-  if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
-
-  cdf_def_dim(fileID, axisname, dimlen, dimID);
-  cdf_def_var(fileID, axisname, (nc_type) xtype, 1, dimID,  ncvaridp);
-  int ncvarid = *ncvaridp;
-
-  {
-    static const char sname[] = "hybrid_sigma_pressure";
-    cdf_put_att_text(fileID, ncvarid, "standard_name", sizeof (sname) - 1, sname);
-  }
-  {
-    static const char *attName[] = {
-      "long_name",
-      "formula",
-      "formula_terms"
-    };
-    enum { nAtt = sizeof (attName) / sizeof (attName[0]) };
-    static const char lname_m[] = "hybrid level at layer midpoints",
-      formula_m[] = "hyam hybm (mlev=hyam+hybm*aps)",
-      fterms_m[] = "ap: hyam b: hybm ps: aps",
-      lname_i[] = "hybrid level at layer interfaces",
-      formula_i[] = "hyai hybi (ilev=hyai+hybi*aps)",
-      fterms_i[] = "ap: hyai b: hybi ps: aps";
-    static const struct attTxtTab tab[2][nAtt] = {
-      {
-        { lname_i, sizeof (lname_i) - 1 },
-        { formula_i, sizeof (formula_i) - 1 },
-        { fterms_i, sizeof (fterms_i) - 1 }
-      },
-      {
-        { lname_m, sizeof (lname_m) - 1 },
-        { formula_m, sizeof (formula_m) - 1 },
-        { fterms_m, sizeof (fterms_m) - 1 }
-      }
-    };
-
-    size_t tabSelect = type == ZAXIS_HYBRID;
-    for (size_t i = 0; i < nAtt; ++i)
-      cdf_put_att_text(fileID, ncvarid, attName[i],
-                       tab[tabSelect][i].txtLen, tab[tabSelect][i].txt);
-  }
+  nc_type xtype;
+  size_t attlen;
+  char attname[CDI_MAX_NAME];
+  enum { attstringlen = 65636 };
+  char attstring[attstringlen];
+  int iatt;
 
-  {
-    static const char units[] = "level";
-    cdf_put_att_text(fileID, ncvarid, "units", sizeof (units) - 1, units);
-  }
-  {
-    static const char direction[] = "down";
-    cdf_put_att_text(fileID, ncvarid, "positive", sizeof (direction) - 1, direction);
-  }
+  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);
 
-  cdf_enddef(fileID);
-  streamptr->ncmode = 2;
+      if ( xtypeIsText(xtype) )
+	{
+	  cdfGetAttText(fileID, NC_GLOBAL, attname, attstringlen, attstring);
 
-  cdf_put_var_double(fileID, ncvarid, zaxisInqLevelsPtr(zaxisID));
+          size_t attstrlen = strlen(attstring);
 
-  cdf_def_vct_echam(streamptr, zaxisID);
+	  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;
+                  cdiStr2UUID(attstring, uuidOfHGrid);
+                  //   printf("uuid: %d %s\n", attlen, attstring);
+		}
+	      else if ( strcmp(attname, "uuidOfVGrid") == 0 && attstrlen == 36 )
+		{
+                  attstring[36] = 0;
+                  cdiStr2UUID(attstring, uuidOfVGrid);
+		}
+	      else
+		{
+                  if ( strcmp(attname, "ICON_grid_file_uri") == 0 && gridfile[0] == 0 )
+                    {
+                      memcpy(gridfile, attstring, attstrlen+1);
+                    }
 
-  if ( *dimID == CDI_UNDEFID )
-    streamptr->zaxisID[zaxisindex] = type == ZAXIS_HYBRID
-      ? streamptr->vct.mlevID : streamptr->vct.ilevID;
+		  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[attlen];
+              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);
+            }
+        }
+      else if ( xtype == NC_FLOAT || xtype == NC_DOUBLE )
+	{
+	  double attflt[attlen];
+	  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);
+	}
+    }
 }
 
 static
-void cdf_def_zaxis_hybrid_cf(stream_t *streamptr, int type, int *ncvaridp, int zaxisID, int zaxisindex, int xtype, size_t dimlen, int *dimID, char *axisname)
+int find_leadtime(int nvars, ncvar_t *ncvars)
 {
-  int fileID = streamptr->fileID;
-  if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
-
-  char psname[CDI_MAX_NAME]; psname[0] = 0;
-  cdiZaxisInqKeyStr(zaxisID, CDI_KEY_PSNAME, CDI_MAX_NAME, psname);
-  if ( psname[0] == 0 ) strcpy(psname, "ps");
-
-  char p0name[CDI_MAX_NAME]; p0name[0] = 0;
-  double p0value = 1;
-  int p0varid = CDI_UNDEFID;
-  int p0status = cdiZaxisInqKeyFlt(zaxisID, CDI_KEY_P0VALUE, &p0value);
-  if ( p0status == 0 )
-    {
-      cdiZaxisInqKeyStr(zaxisID, CDI_KEY_P0NAME, CDI_MAX_NAME, p0name);
-      if ( p0name[0] == 0 ) strcpy(p0name, "p0");
-      cdf_def_var(fileID, p0name, NC_DOUBLE, 0, 0,  &p0varid);
-      static const char longname[] = "reference pressure";
-      cdf_put_att_text(fileID, p0varid, "long_name", strlen(longname), longname);
-      static const char units[] = "Pa";
-      cdf_put_att_text(fileID, p0varid, "units", strlen(units), units);
-    }
-
-  char zname[CDI_MAX_NAME]; zname[0] = 0;
-  char zlongname[CDI_MAX_NAME]; zlongname[0] = 0;
-  char zunits[CDI_MAX_NAME]; zunits[0] = 0;
-  cdiZaxisInqKeyStr(zaxisID, CDI_KEY_NAME, CDI_MAX_NAME, zname);
-  //cdiZaxisInqKeyStr(zaxisID, CDI_KEY_LONGNAME, CDI_MAX_NAME, zlongname);
-  cdiZaxisInqKeyStr(zaxisID, CDI_KEY_UNITS, CDI_MAX_NAME, zunits);
-  if ( zname[0] ) strcpy(axisname, zname);
-  if ( zlongname[0] == 0 ) strcpy(zlongname, "hybrid sigma pressure coordinate");
-  if ( zunits[0] == 0 ) strcpy(zunits, "1");
-
-  cdf_def_dim(fileID, axisname, dimlen, dimID);
-  cdf_def_var(fileID, axisname, (nc_type) xtype, 1, dimID, ncvaridp);
-  int ncvarid = *ncvaridp;
-
-  {
-    static const char sname[] = "standard_name",
-      sname_v[] = "atmosphere_hybrid_sigma_pressure_coordinate",
-      axis[] = "axis",
-      axis_v[] = "Z",
-      direction[] = "positive",
-      direction_v[] = "down";
-    struct attTxtTab2 tab[] = {
-      { sname, sname_v, sizeof (sname_v) - 1 },
-      { axis, axis_v, sizeof (axis_v) - 1 },
-      { direction, direction_v, sizeof (direction_v) - 1 },
-    };
-    enum { nAtt = sizeof (tab) / sizeof (tab[0]) };
-    for ( size_t i = 0; i < nAtt; ++i )
-      cdf_put_att_text(fileID, ncvarid, tab[i].attName, tab[i].valLen, tab[i].attVal);
+  int leadtime_id = UNDEFID;
 
-    cdf_put_att_text(fileID, ncvarid, "long_name", strlen(zlongname), zlongname);
-    cdf_put_att_text(fileID, ncvarid, "units", strlen(zunits), zunits);
-  }
+  for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
+    {
+      if ( ncvars[ncvarid].stdname[0] )
+        {
+          if ( strcmp(ncvars[ncvarid].stdname, "forecast_period") == 0 )
+            {
+              leadtime_id = ncvarid;
+              break;
+            }
+        }
+    }
 
-  size_t len = 0;
-  char txt[CDI_MAX_NAME];
-  if ( p0status == 0 )
-    len = (size_t)(sprintf(txt, "%s%s %s%s", "a: a b: b p0: ", p0name, "ps: ", psname));
-  else
-    len = (size_t)(sprintf(txt, "%s%s", "ap: ap b: b ps: ", psname));
-  cdf_put_att_text(fileID, ncvarid, "formula_terms", len, txt);
+  return (leadtime_id);
+}
 
-  int ncbvarid = CDI_UNDEFID;
-  int nvdimID = CDI_UNDEFID;
+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)
+{
+  int ncvarid;
 
-  double lbounds[dimlen], ubounds[dimlen], levels[dimlen];
+  if ( timedimid == UNDEFID )
+    {
+      char timeunits[CDI_MAX_NAME];
 
-  if ( zaxisInqLevels(zaxisID, NULL) )
-    zaxisInqLevels(zaxisID, levels);
-  else
-    for ( size_t i = 0; i < dimlen; ++i ) levels[i] = i+1;
+      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 ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
-    {
-      zaxisInqLbounds(zaxisID, lbounds);
-      zaxisInqUbounds(zaxisID, ubounds);
+                  if ( isTimeUnits(timeunits) )
+                    {
+                      streamptr->basetime.ncvarid = ncvarid;
+                      break;
+                    }
+                }
+            }
+        }
     }
   else
     {
-      for ( size_t i = 0; i < dimlen; ++i ) lbounds[i] = levels[i];
-      for ( size_t i = 0; i < dimlen-1; ++i ) ubounds[i] = levels[i+1];
-      ubounds[dimlen-1] = levels[dimlen-1] + 1;
-    }
-
-  //if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
-    {
-      size_t nvertex = 2;
-      if ( dimlen > 1 && nc_inq_dimid(fileID, bndsName, &nvdimID) != NC_NOERR )
-        cdf_def_dim(fileID, bndsName, nvertex, &nvdimID);
+      int ltimevar = FALSE;
 
-      if ( nvdimID != CDI_UNDEFID )
+      if ( ncdims[timedimid].ncvarid != UNDEFID )
         {
-          size_t axisnameLen = strlen(axisname);
-          axisname[axisnameLen] = '_';
-          memcpy(axisname + axisnameLen + 1, bndsName, sizeof (bndsName));
-          axisnameLen += sizeof (bndsName);
-          int dimIDs[2] = { *dimID, nvdimID };
-          cdf_def_var(fileID, axisname, (nc_type) xtype, 2, dimIDs, &ncbvarid);
-          cdf_put_att_text(fileID, ncvarid, "bounds", axisnameLen, axisname);
+          streamptr->basetime.ncvarid = ncdims[timedimid].ncvarid;
+          ltimevar = TRUE;
+        }
+
+      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) )
           {
-            static const char sname[] = "standard_name",
-              sname_v[] = "atmosphere_hybrid_sigma_pressure_coordinate";
-            struct attTxtTab2 tab[] = {
-              { sname, sname_v, sizeof (sname_v) - 1 },
-            };
-            enum { nAtt = sizeof (tab) / sizeof (tab[0]) };
-            for ( size_t i = 0; i < nAtt; ++i )
-              cdf_put_att_text(fileID, ncbvarid, tab[i].attName, tab[i].valLen, tab[i].attVal);
-            cdf_put_att_text(fileID, ncbvarid, "units", strlen(zunits), zunits);
+            ncvars[ncvarid].isvar = FALSE;
+
+            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);
+              }
           }
 
-          if ( p0status == 0 )
-            len = (size_t)(sprintf(txt, "%s%s %s%s", "a: a_bnds b: b_bnds p0: ", p0name, "ps: ", psname));
-          else
-            len = (size_t)(sprintf(txt, "%s%s", "ap: ap_bnds b: b_bnds ps: ", psname));
-          cdf_put_att_text(fileID, ncbvarid, "formula_terms", len, txt);
+      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;
+              }
         }
-    }
-
-  cdf_enddef(fileID);
-  streamptr->ncmode = 2;
 
-  cdf_put_var_double(fileID, ncvarid, levels);
-
-  if ( p0varid != CDI_UNDEFID ) cdf_put_var_double(fileID, p0varid, &p0value);
+      /* time varID */
+      ncvarid = streamptr->basetime.ncvarid;
 
-  if ( ncbvarid != CDI_UNDEFID )
-    {
-      double zbounds[2*dimlen];
-      for ( size_t i = 0; i < dimlen; ++i )
+      if ( ncvarid == UNDEFID )
         {
-          zbounds[2*i  ] = lbounds[i];
-          zbounds[2*i+1] = ubounds[i];
+          Warning("Time variable >%s< not found!", ncdims[timedimid].name);
         }
-      cdf_put_var_double(fileID, ncbvarid, zbounds);
     }
 
-  cdf_def_vct_cf(streamptr, zaxisID, *dimID, nvdimID, p0status, p0value);
-
-  if ( *dimID == CDI_UNDEFID )
-    streamptr->zaxisID[zaxisindex] = type == ZAXIS_HYBRID
-      ? streamptr->vct.mlevID : streamptr->vct.ilevID;
-}
-
-static
-void cdf_def_zaxis_hybrid(stream_t *streamptr, int type, int *ncvarid, int zaxisID, int zaxisindex, int xtype, size_t dimlen, int *dimID, char *axisname)
-{
-  void (*def_zaxis_hybrid_delegate)(stream_t *streamptr, int type, int *ncvarid, int zaxisID, int zaxisindex, int xtype, size_t dimlen, int *dimID, char *axisname)
-    = ( (!CDI_cmor_mode && cdiConvention == CDI_CONVENTION_ECHAM)
-        || type == ZAXIS_HYBRID_HALF )
-    ? cdf_def_zaxis_hybrid_echam : cdf_def_zaxis_hybrid_cf;
-  def_zaxis_hybrid_delegate(streamptr, type, ncvarid, zaxisID, zaxisindex, xtype, dimlen, dimID, axisname);
-}
-
-static
-void cdfDefZaxisUUID(stream_t *streamptr, int zaxisID)
-{
-  unsigned char uuidOfVGrid[CDI_UUID_SIZE];
-  zaxisInqUUID(zaxisID, uuidOfVGrid);
+  /* time varID */
+  ncvarid = streamptr->basetime.ncvarid;
 
-  if ( uuidOfVGrid[0] != 0 )
+  if ( ncvarid != UNDEFID && streamptr->basetime.lwrf == FALSE )
     {
-      char uuidOfVGridStr[37];
-      cdiUUID2Str(uuidOfVGrid, uuidOfVGridStr);
-      if ( uuidOfVGridStr[0] != 0 && strlen(uuidOfVGridStr) == 36 )
+      if ( ncvars[ncvarid].units[0] != 0 ) *time_has_units = TRUE;
+
+      if ( ncvars[ncvarid].bounds != UNDEFID )
         {
-          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);
+          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;
+                }
+            }
         }
     }
 }
 
 static
-void cdfDefZaxisChar(stream_t *streamptr, int zaxisID, char *axisname, int *dimID, size_t dimlen, int zaxisindex)
+void read_vct_echam(int fileID, int nvars, ncvar_t *ncvars, ncdim_t *ncdims, double **vct, size_t *pvctsize)
 {
-  int fileID  = streamptr->fileID;
-  int ncvarID = CDI_UNDEFID;
-  if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
-
-  /* Check StrlenID */
-  char strlen[7] = "strlen\0";
-  size_t clen = (size_t) zaxisInqCLen(zaxisID);
-  if ( clen == 0 )
-    Error("Maximal string length value is 0.\nA given character axis requires a dimension to save the maximal string length.");
-  int strlenID = CDI_UNDEFID;
-  strlenID = checkDimName(fileID, clen, strlen);
-
-  if ( strlenID == CDI_UNDEFID ) cdf_def_dim(fileID, strlen, clen, &strlenID);
-
-  /* Check 'areatype'dimID */
-  char dimname[CDI_MAX_NAME+3]; dimname[0] = 0;
-  cdiZaxisInqKeyStr(zaxisID, CDI_KEY_DIMNAME, CDI_MAX_NAME, dimname);
-  *dimID = checkDimName(fileID, dimlen, dimname);
-  if ( !(dimlen > 0) )
-    Error("No strings delivered for a character axis.");
-  if ( dimname[0] == 0 ) { memcpy(dimname, "area_type", 10); dimname[10] = 0; }
-
-  if ( *dimID == CDI_UNDEFID ) cdf_def_dim(fileID, dimname, dimlen, dimID);
-
-  int dimIDs[2];
-  dimIDs[0] = *dimID;
-  dimIDs[1] = strlenID;
-
-  /* Get Stringvalues */
-  char **cvals = zaxisInqCValsPtr(zaxisID);
+  /* find ECHAM VCT */
+  int nvcth_id = UNDEFID, vcta_id = UNDEFID, vctb_id = UNDEFID;
 
-  if ( cvals )
+  for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
     {
-      /* Define variable and its attributes */
-      cdf_def_var(fileID, axisname, NC_CHAR, 2, dimIDs, &ncvarID);
-
-      cdfPutGridStdAtts(fileID, ncvarID, zaxisID, 'Z', &gridInqsZ);
-      cdf_put_att_text(fileID, ncvarID, "axis", 1, "Z");
-      cdfDefineAttributes(zaxisID, CDI_GLOBAL, fileID, ncvarID);
-
-      streamptr->nczvarID[zaxisindex] = ncvarID;
-      cdf_enddef(fileID);
-
-      /* Write Stringvalues */
-      size_t start[2], count[2];
-      start[1] = 0;
-      count[0] = 1;
-      count[1] = clen;
-      for ( size_t i = 0; i < dimlen; i++ )
+      if ( ncvars[ncvarid].ndims == 1 )
         {
-          start[0] = i;
-          nc_put_vara_text(fileID, ncvarID, start, count, cvals[i]);
-        }
+          size_t len = strlen(ncvars[ncvarid].name);
+          if ( len == 4 && ncvars[ncvarid].name[0] == 'h' && ncvars[ncvarid].name[1] == 'y' )
+            {
+              if ( ncvars[ncvarid].name[2] == 'a' && ncvars[ncvarid].name[3] == 'i' ) // hyai
+                {
+                  vcta_id = ncvarid;
+                  nvcth_id = ncvars[ncvarid].dimids[0];
+                  ncvars[ncvarid].isvar = FALSE;
+                }
+              else if ( ncvars[ncvarid].name[2] == 'b' && ncvars[ncvarid].name[3] == 'i' ) //hybi
+                {
+                  vctb_id = ncvarid;
+                  nvcth_id = ncvars[ncvarid].dimids[0];
+                  ncvars[ncvarid].isvar = FALSE;
+                }
+              else if ( (ncvars[ncvarid].name[2] == 'a' || ncvars[ncvarid].name[2] == 'b') && ncvars[ncvarid].name[3] == 'm' )
+                {
+                  ncvars[ncvarid].isvar = FALSE; // hyam or hybm
+                }
+            }
+	}
     }
 
-  streamptr->ncmode = 2;
+  /* read VCT */
+  if ( nvcth_id != UNDEFID && vcta_id != UNDEFID && vctb_id != UNDEFID )
+    {
+      size_t 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);
+      *pvctsize = vctsize;
+    }
 }
 
-static
-void cdfDefZaxis(stream_t *streamptr, int zaxisID)
+
+int cdfInqContents(stream_t *streamptr)
 {
-  /*  char zaxisname0[CDI_MAX_NAME]; */
-  char axisname[CDI_MAX_NAME];
-  int dimID = CDI_UNDEFID;
-  int ncvarid = CDI_UNDEFID, ncbvarid = CDI_UNDEFID;
-  int xtype = zaxisInqPrec(zaxisID) == CDI_DATATYPE_FLT32 ? NC_FLOAT : NC_DOUBLE;
+  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 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;
+
+  memset(uuidOfHGrid, 0, CDI_UUID_SIZE);
+  memset(uuidOfVGrid, 0, CDI_UUID_SIZE);
+  gridfile[0] = 0;
+  fcreftime[0] = 0;
 
   int vlistID = streamptr->vlistID;
   int fileID  = streamptr->fileID;
 
-  int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
+  if ( CDI_Debug ) Message("streamID = %d, fileID = %d", streamptr->self, fileID);
 
-  int nzaxis = vlistNzaxis(vlistID);
+#if  defined  (HAVE_NETCDF4)
+  nc_inq_format(fileID, &format);
+#endif
 
-  size_t dimlen = (size_t)zaxisInqSize(zaxisID);
-  int type   = zaxisInqType(zaxisID);
+  cdf_inq(fileID, &ndims , &nvars, &ngatts, &unlimdimid);
 
-  bool is_scalar = false;
-  if ( dimlen == 1 )
+  if ( CDI_Debug )
+    Message("root: ndims %d, nvars %d, ngatts %d", ndims, nvars, ngatts);
+
+  if ( ndims == 0 )
     {
-      is_scalar = zaxisInqScalar(zaxisID) > 0;
-      if ( !is_scalar && CDI_cmor_mode )
-        {
-          is_scalar = true;
-          zaxisDefScalar(zaxisID);
-        }
+      Warning("ndims = %d", ndims);
+      return (CDI_EUFSTRUCT);
     }
 
-  int ndims = is_scalar ? 0 : 1;
-
-  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;
-      }
-
-  zaxisInqName(zaxisID, axisname);
+  /* alloc ncdims */
+  ncdims = (ncdim_t *) Malloc((size_t)ndims * sizeof (ncdim_t));
+  init_ncdims(ndims, ncdims);
 
-  if ( dimID == CDI_UNDEFID )
+  if ( nvars > 0 )
     {
-      checkZaxisName(axisname, fileID, vlistID, zaxisID, nzaxis);
-
-      char dimname[CDI_MAX_NAME+3]; dimname[0] = 0;
-      //cdiZaxisInqKeyStr(zaxisID, CDI_KEY_DIMNAME, CDI_MAX_NAME, dimname);
-      if ( dimname[0] == 0 ) strcpy(dimname, axisname);
-
-      if ( type == ZAXIS_REFERENCE ) cdfDefZaxisUUID(streamptr, zaxisID);
+      /* alloc ncvars */
+      ncvars = (ncvar_t *) Malloc((size_t)nvars * sizeof (ncvar_t));
+      init_ncvars(nvars, ncvars);
 
-      if ( type == ZAXIS_HYBRID || type == ZAXIS_HYBRID_HALF )
-        {
-          cdf_def_zaxis_hybrid(streamptr, type, &ncvarid, zaxisID, zaxisindex, xtype, dimlen, &dimID, axisname);
+      for ( ncvarid = 0; ncvarid < nvars; ++ncvarid )
+        ncvars[ncvarid].ncid = fileID;
+    }
 
-          int natts;
-          cdiInqNatts(zaxisID, CDI_GLOBAL, &natts);
-          if ( natts > 0 && streamptr->ncmode == 2 ) cdf_redef(fileID);
-          cdfDefineAttributes(zaxisID, CDI_GLOBAL, fileID, ncvarid);
-          if ( natts > 0 && streamptr->ncmode == 2 ) cdf_enddef(fileID);
-        }
-      else if ( type == ZAXIS_CHAR )
-        cdfDefZaxisChar(streamptr, zaxisID, axisname, &dimID, dimlen, zaxisindex);
-      else
+#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 )
         {
-          dimID = checkDimName(fileID, dimlen, dimname);
-
-          if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+          ncid = ncids[i];
+          nc_inq_grpname (ncid, name1);
+          cdf_inq(ncid, &gndims , &gnvars, &gngatts, &gunlimdimid);
 
-          if ( ndims && dimID == CDI_UNDEFID ) cdf_def_dim(fileID, dimname, dimlen, &dimID);
+          if ( CDI_Debug )
+            Message("%s: ndims %d, nvars %d, ngatts %d", name1, gndims, gnvars, gngatts);
 
-          if ( zaxisInqLevels(zaxisID, NULL) )
+          if ( gndims == 0 )
             {
-              cdf_def_var(fileID, axisname, (nc_type) xtype, ndims, &dimID, &ncvarid);
-
-              cdfPutGridStdAtts(fileID, ncvarid, zaxisID, 'Z', &gridInqsZ);
-
-              {
-                int positive = zaxisInqPositive(zaxisID);
-                static const char positive_up[] = "up",
-                                  positive_down[] = "down";
-                static const struct attTxtTab tab[2] = {
-                  { positive_up, sizeof (positive_up) - 1 },
-                  { positive_down, sizeof (positive_down) - 1 },
-                };
-                if ( positive == POSITIVE_UP || positive == POSITIVE_DOWN )
-                  {
-                    size_t select = positive == POSITIVE_DOWN;
-                    cdf_put_att_text(fileID, ncvarid, "positive", tab[select].txtLen, tab[select].txt);
-                  }
-              }
-              cdf_put_att_text(fileID, ncvarid, "axis", 1, "Z");
-
-              if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
-                {
-                  int nvdimID = CDI_UNDEFID;
-                  size_t nvertex = 2;
-                  if ( nc_inq_dimid(fileID, bndsName, &nvdimID) != NC_NOERR )
-                    cdf_def_dim(fileID, bndsName, nvertex, &nvdimID);
+            }
+        }
+    }
+#endif
+#endif
 
-                  if ( nvdimID != CDI_UNDEFID )
-                    {
-                      size_t axisnameLen = strlen(axisname);
-                      axisname[axisnameLen] = '_';
-                      memcpy(axisname + axisnameLen + 1, bndsName, sizeof (bndsName));
-                      int dimIDs[2];
-                      dimIDs[0] = dimID;
-                      dimIDs[ndims] = nvdimID;
-                      cdf_def_var(fileID, axisname, (nc_type) xtype, ndims+1, dimIDs, &ncbvarid);
-                      cdf_put_att_text(fileID, ncvarid, "bounds", strlen(axisname), axisname);
-                    }
-                }
+  if ( nvars == 0 )
+    {
+      Warning("nvars = %d", nvars);
+      return (CDI_EUFSTRUCT);
+    }
 
-              cdfDefineAttributes(zaxisID, CDI_GLOBAL, fileID, ncvarid);
-            }
+  /* scan global attributes */
+  scan_global_attributes(fileID, vlistID, streamptr, ngatts, &instID, &modelID, &ucla_les,
+                         uuidOfHGrid, uuidOfVGrid, gridfile, &number_of_grid_used);
 
-          cdf_enddef(fileID);
-          streamptr->ncmode = 2;
+  /* find time dim */
+  if ( unlimdimid >= 0 )
+    timedimid = unlimdimid;
+  else
+    timedimid = cdfTimeDimID(fileID, ndims, nvars);
 
-          if ( zaxisInqLevels(zaxisID, NULL) )
-            {
-              cdf_put_var_double(fileID, ncvarid, zaxisInqLevelsPtr(zaxisID));
+  streamptr->basetime.ncdimid = timedimid;
 
-              if ( ncbvarid != CDI_UNDEFID )
-                {
-                  double lbounds[dimlen], ubounds[dimlen], zbounds[2*dimlen];
-                  zaxisInqLbounds(zaxisID, lbounds);
-                  zaxisInqUbounds(zaxisID, ubounds);
-                  for ( size_t i = 0; i < dimlen; ++i )
-                    {
-                      zbounds[2*i  ] = lbounds[i];
-                      zbounds[2*i+1] = ubounds[i];
-                    }
+  if ( timedimid != UNDEFID )
+    cdf_inq_dimlen(fileID, timedimid, &ntsteps);
+  else
+    ntsteps = 0;
 
-                  cdf_put_var_double(fileID, ncbvarid, zbounds);
-                }
+  if ( CDI_Debug ) Message("Number of timesteps = %d", ntsteps);
+  if ( CDI_Debug ) Message("Time dimid = %d", streamptr->basetime.ncdimid);
 
-              if ( ndims == 0 ) streamptr->nczvarID[zaxisindex] = ncvarid;
-            }
-        }
+  /* 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;
     }
 
-  if ( dimID != CDI_UNDEFID )
-    streamptr->zaxisID[zaxisindex] = dimID;
-}
+  if ( CDI_Debug ) printNCvars(ncvars, nvars, "cdfScanVarAttributes");
 
-static
-void cdf_def_mapping(stream_t *streamptr, int gridID)
-{
-  char mapping[CDI_MAX_NAME]; mapping[0] = 0;
-  cdiGridInqKeyStr(gridID, CDI_KEY_MAPNAME, CDI_MAX_NAME, mapping);
-  if ( mapping[0] )
-    {
-      char gmapvarname[CDI_MAX_NAME]; gmapvarname[0] = 0;
-      cdiGridInqKeyStr(gridID, CDI_KEY_MAPPING, CDI_MAX_NAME, gmapvarname);
+  /* scan attributes of all variables */
+  cdfScanVarAttributes(nvars, ncvars, ncdims, timedimid, modelID, format);
 
-      int fileID = streamptr->fileID;
-      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-      int ncvarid;
-      int ncerrcode = nc_def_var(fileID, gmapvarname, (nc_type) NC_INT, 0, NULL, &ncvarid);
-      if ( ncerrcode == NC_NOERR )
-        cdfDefineAttributes(gridID, CDI_GLOBAL, fileID, ncvarid);
+  if ( CDI_Debug ) printNCvars(ncvars, nvars, "find coordinate vars");
 
-      cdf_enddef(fileID);
+  /* 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);
 
-      if ( ncerrcode == NC_NOERR )
-        {
-          int dummy = 1;
-          cdf_put_var_int(fileID, ncvarid, &dummy);
-        }
+	      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;
+		  }
+	    }
+	}
     }
-}
 
-static
-void cdfDefCharacter(stream_t *streamptr, int gridID, int gridindex, int xory, int strlen)
-{
-  if ( streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X] != CDI_UNDEFID ) return;
-
-  int dimlen = ( xory == 0 ) ? gridInqXsize(gridID) : gridInqYsize(gridID);
-  int dimID, strlenID;
-  ncgrid_t *ncgrid = streamptr->ncgrid;
+  /* find time vars */
+  find_time_vars(nvars, ncvars, ncdims, timedimid, streamptr, &time_has_units, &time_has_bounds, &time_climatology);
 
-  /* Check for all grids up to gridindex whether it already is defined */
+  leadtime_id = find_leadtime(nvars, ncvars);
+  if ( leadtime_id != UNDEFID ) ncvars[leadtime_id].isvar = FALSE;
 
-  for ( int index = 0; index < gridindex; index++ )
+  /* check ncvars */
+  for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
     {
-      int gridID0 = ncgrid[index].gridID;
-      int gridtype0 = gridInqType(gridID0);
-      if ( gridtype0 == GRID_CHARXY )
-        {
-          if ( gridInqXIsc(gridID0) == strlen &&
-               gridInqXsize(gridID0) == dimlen )
-            return;
-          else if ( gridInqYIsc(gridID0) == strlen &&
-               gridInqYsize(gridID0) == dimlen )
-            return;
-        }
-    }
-
-  int fileID  = streamptr->fileID;
+      if ( timedimid != UNDEFID )
+	if ( ncvars[ncvarid].isvar == -1 &&
+	     ncvars[ncvarid].ndims > 1   &&
+	     timedimid == ncvars[ncvarid].dimids[0] )
+	  cdfSetVar(ncvars, ncvarid, TRUE);
 
-  if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+      if ( ncvars[ncvarid].isvar == -1 && ncvars[ncvarid].ndims == 0 )
+	cdfSetVar(ncvars, ncvarid, FALSE);
 
-/* Define Dims */
+      //if ( ncvars[ncvarid].isvar == -1 && ncvars[ncvarid].ndims > 1 )
+      if ( ncvars[ncvarid].isvar == -1 && ncvars[ncvarid].ndims >= 1 )
+	cdfSetVar(ncvars, ncvarid, TRUE);
 
-  char dimname[CDI_MAX_NAME+3];
-  dimname[0] = 0;
-  if ( xory == 0 )
-    cdiGridInqKeyStr(gridID, CDI_KEY_XDIMNAME, CDI_MAX_NAME, dimname);
-  else
-    cdiGridInqKeyStr(gridID, CDI_KEY_YDIMNAME, CDI_MAX_NAME, dimname);
-  if ( dimname[0] == 0 ) { memcpy(dimname, "region", 7); dimname[6] = 0; }
-  dimID = checkDimName(fileID, dimlen, dimname);
-  if ( dimID == CDI_UNDEFID ) cdf_def_dim(fileID, dimname, dimlen, &dimID);
+      if ( ncvars[ncvarid].isvar == -1 )
+	{
+	  ncvars[ncvarid].isvar = 0;
+	  Warning("Variable %s has an unknown type, skipped!", ncvars[ncvarid].name);
+	  continue;
+	}
 
-/* Define strlength dim */
+      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;
+	}
 
-  strcpy(dimname, "strlen");
-  strlenID = checkDimName(fileID, strlen, dimname);
-  if ( strlenID == CDI_UNDEFID ) cdf_def_dim(fileID, dimname, strlen, &strlenID);
+      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;
+	}
 
-/* Define Variable */
+      if ( xtypeIsText(ncvars[ncvarid].xtype) )
+	{
+	  ncvars[ncvarid].isvar = 0;
+	  continue;
+	}
 
-  int dimIDs[2];
-  dimIDs[0] = dimID;
-  dimIDs[1] = strlenID;
+      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;
+	}
 
-  char axisname[CDI_MAX_NAME]; axisname[0] = 0;
-  char **cvals = (char **) Malloc(dimlen * sizeof(char *));
-  for ( int i = 0; i < dimlen; i++ )
-    cvals[i] = Malloc(strlen * sizeof(char) );
-  int ncaxisid;
-  if ( xory == 0 )
-    {
-      cdiGridInqKeyStr(gridID, CDI_KEY_XNAME, CDI_MAX_NAME, axisname);
-      gridInqXCvals(gridID, cvals);
-    }
-  else
-    {
-      cdiGridInqKeyStr(gridID, CDI_KEY_YNAME, CDI_MAX_NAME, axisname);
-      gridInqXCvals(gridID, cvals);
-    }
-  int status = nc_inq_varid(fileID, axisname, &ncaxisid);
-  if ( status != NC_NOERR )
-    {
-      cdf_def_var(fileID, axisname, NC_CHAR, 2, dimIDs, &ncaxisid);
-      if ( xory == 0 )
-        cdfPutGridStdAtts(fileID, ncaxisid, gridID, 'X', &gridInqsX);
-      else
-        cdfPutGridStdAtts(fileID, ncaxisid, gridID, 'Y', &gridInqsY);
+      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;
+	    }
+	}
     }
-  else
-    return;
-  cdf_enddef(fileID);
 
-/* Write Var */
+  /* verify coordinate vars - first scan (dimname == varname) */
+  verify_coordinate_vars_1(fileID, ndims, ncdims, ncvars, timedimid);
 
-  size_t start[2], count[2];
-  start[1] = 0;
-  count[0] = 1;
-  count[1] = strlen;
-  for (int i = 0; i < dimlen; i++)
+  /* 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[0] = i;
-      status = nc_put_vara_text(fileID, ncaxisid, start, count, cvals[i]);
+      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;
+		}
+	    }
+	}
     }
-
-  ncgrid[gridindex].gridID = gridID;
-  if ( xory == 0 )
+  /*
+  for ( ncdimid = 0; ncdimid < ndims; ncdimid++ )
     {
-      ncgrid[gridindex].ncIDs[CDF_DIMID_X] = dimID;
-      ncgrid[gridindex].ncIDs[CDF_VARID_X] = ncaxisid;
+      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);
+	}
     }
-  else
+  */
+
+  /* Set coordinate varids (att: associate)  */
+  for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
     {
-      ncgrid[gridindex].ncIDs[CDF_DIMID_Y] = dimID;
-      ncgrid[gridindex].ncIDs[CDF_VARID_Y] = ncaxisid;
+      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];
+	    }
+	}
     }
-  streamptr->ncmode = 2;
-}
 
-static
-void cdfDefRgrid(stream_t *streamptr, int gridID, int gridindex)
-{
-  ncgrid_t *ncgrid = streamptr->ncgrid;
+  /* set dim type */
+  setDimType(nvars, ncvars, ncdims);
 
-  size_t dimlen = (size_t)gridInqSize(gridID);
+  /* read ECHAM VCT if present */
+  size_t vctsize = 0;
+  double *vct = NULL;
+  read_vct_echam(fileID, nvars, ncvars, ncdims, &vct, &vctsize);
 
-  int iz;
-  int dimID;
-  {
-    struct idSearch search
-      = cdfSearchIDBySize(0, (size_t)gridindex, ncgrid, CDF_DIMID_X,
-                          GRID_GAUSSIAN_REDUCED, (int)dimlen,
-                          gridInqType, gridInqSize);
-    iz = search.numNonMatching;
-    dimID = search.foundID;
-  }
 
-  if ( dimID == CDI_UNDEFID )
-    {
-      int fileID  = streamptr->fileID;
-      static bool lwarn = true;
-      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;
-        }
+  if ( CDI_Debug ) printNCvars(ncvars, nvars, "define_all_grids");
 
-      char axisname[7] = "rgridX";
-      if ( iz == 0 ) axisname[5] = '\0';
-      else           sprintf(&axisname[5], "%1d", iz+1);
+  /* define all grids */
+  define_all_grids(streamptr, vlistID, ncdims, nvars, ncvars, timedimid, uuidOfHGrid, gridfile, number_of_grid_used);
 
-      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
-      cdf_def_dim(fileID, axisname, dimlen, &dimID);
+  /* define all zaxes */
+  define_all_zaxes(streamptr, vlistID, ncdims, nvars, ncvars, vctsize, vct, uuidOfVGrid);
+  if ( vct ) Free(vct);
 
-      cdf_enddef(fileID);
-      streamptr->ncmode = 2;
-    }
 
-  ncgrid[gridindex].gridID = gridID;
-  ncgrid[gridindex].ncIDs[CDF_DIMID_X] = dimID;
-}
+  /* select vars */
+  varids = (int *) Malloc((size_t)nvars * sizeof (int));
+  nvarids = 0;
+  for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
+    if ( ncvars[ncvarid].isvar == TRUE ) varids[nvarids++] = ncvarid;
 
-static
-void cdfDefGdim(stream_t *streamptr, int gridID, int gridindex)
-{
-  ncgrid_t *ncgrid = streamptr->ncgrid;
-  int iz = 0;
-  int dimID = CDI_UNDEFID;
+  nvars_data = nvarids;
 
-  size_t dimlen = (size_t)gridInqSize(gridID);
+  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 ( gridInqYsize(gridID) == 0 )
-    {
-      struct idSearch search
-        = cdfSearchIDBySize(0, (size_t)gridindex, ncgrid, CDF_DIMID_X,
-                            GRID_GENERIC, (int)dimlen,
-                            gridInqType, gridInqSize);
-      iz = search.numNonMatching;
-      dimID = search.foundID;
-    }
 
-  if ( gridInqXsize(gridID) == 0 )
+  if ( nvars_data == 0 )
     {
-      struct idSearch search
-        = cdfSearchIDBySize(0, (size_t)gridindex, ncgrid, CDF_DIMID_Y,
-                            GRID_GENERIC, (int)dimlen,
-                            gridInqType, gridInqSize);
-      iz += search.numNonMatching;
-      dimID = search.foundID;
+      streamptr->ntsteps = 0;
+      return (CDI_EUFSTRUCT);
     }
 
-  if ( dimID == CDI_UNDEFID )
-    {
-      int fileID  = streamptr->fileID;
-      char dimname[CDI_MAX_NAME];
-      strcpy(dimname, "gsize");
-
-      dimID = checkDimName(fileID, dimlen, dimname);
-
-      if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
-
-      if ( dimID == CDI_UNDEFID ) cdf_def_dim(fileID, dimname, dimlen, &dimID);
+  if ( ntsteps == 0 && streamptr->basetime.ncdimid == UNDEFID && streamptr->basetime.ncvarid != UNDEFID )
+    ntsteps = 1;
 
-      cdf_enddef(fileID);
-      streamptr->ncmode = 2;
-    }
+  streamptr->ntsteps = (long)ntsteps;
 
-  ncgrid[gridindex].gridID = gridID;
-  ncgrid[gridindex].ncIDs[CDF_DIMID_X] = dimID;
-}
+  /* define all data variables */
+  define_all_vars(streamptr, vlistID, instID, modelID, varids, nvars_data, nvars, ncvars);
 
-static
-void cdfDefGrid(stream_t *streamptr, int gridID, int gridindex)
-{
-  if ( streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X] != CDI_UNDEFID ) return;
 
-  int gridtype = gridInqType(gridID);
-  int size     = gridInqSize(gridID);
+  cdiCreateTimesteps(streamptr);
 
-  if ( CDI_Debug )
-    Message("gridtype = %d  size = %d", gridtype, size);
+  /* time varID */
+  int nctimevarid = streamptr->basetime.ncvarid;
 
-  if ( gridtype == GRID_GAUSSIAN    ||
-       gridtype == GRID_LONLAT      ||
-       gridtype == GRID_PROJECTION  ||
-       gridtype == GRID_GENERIC )
+  if ( time_has_units )
     {
-      if ( gridtype == GRID_GENERIC )
-        {
-          if ( size == 1 && gridInqXsize(gridID) == 0 && gridInqYsize(gridID) == 0 )
-            {
-              /* no grid information */
-              streamptr->ncgrid[gridindex].gridID = gridID;
-            }
-          else
-            {
-              bool lx = false, ly = false;
-              if ( gridInqXsize(gridID) > 0 /*&& gridInqXvals(gridID, NULL) > 0*/ )
-                {
-                  cdfDefXaxis(streamptr, gridID, gridindex, 1);
-                  lx = true;
-                }
-
-              if ( gridInqYsize(gridID) > 0 /*&& gridInqYvals(gridID, NULL) > 0*/ )
-                {
-                  cdfDefYaxis(streamptr, gridID, gridindex, 1);
-                  ly = true;
-                }
+      taxis_t *taxis = &streamptr->tsteps[0].taxis;
 
-              if ( !lx && !ly ) cdfDefGdim(streamptr, gridID, gridindex);
-            }
+      if ( setBaseTime(ncvars[nctimevarid].units, taxis) == 1 )
+        {
+          nctimevarid = UNDEFID;
+          streamptr->basetime.ncvarid = UNDEFID;
         }
-      else
+
+      if ( leadtime_id != UNDEFID && taxis->type == TAXIS_RELATIVE )
         {
-          int ndims = !(gridtype == GRID_LONLAT && size == 1 && !gridInqHasDims(gridID));
+          streamptr->basetime.leadtimeid = leadtime_id;
+          taxis->type = TAXIS_FORECAST;
 
-          if ( gridInqXsize(gridID) > 0 ) cdfDefXaxis(streamptr, gridID, gridindex, ndims);
-          if ( gridInqYsize(gridID) > 0 ) cdfDefYaxis(streamptr, gridID, gridindex, ndims);
+          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;
 
-          cdf_def_mapping(streamptr, gridID);
+          setForecastTime(fcreftime, taxis);
         }
     }
-  else if ( gridtype == GRID_CURVILINEAR )
-    {
-      cdfDefCurvilinear(streamptr, gridID, gridindex);
-    }
-  else if ( gridtype == GRID_UNSTRUCTURED )
-    {
-      cdfDefUnstructured(streamptr, gridID, gridindex);
-    }
-  else if ( gridtype == GRID_GAUSSIAN_REDUCED )
-    {
-      cdfDefRgrid(streamptr, gridID, gridindex);
-    }
-  else if ( gridtype == GRID_SPECTRAL )
+
+  if ( time_has_bounds )
     {
-      cdfDefComplex(streamptr, gridID, gridindex);
-      cdfDefSP(streamptr, gridID, gridindex);
+      streamptr->tsteps[0].taxis.has_bounds = TRUE;
+      if ( time_climatology ) streamptr->tsteps[0].taxis.climatology = TRUE;
     }
-  else if ( gridtype == GRID_FOURIER )
+
+  if ( nctimevarid != UNDEFID )
     {
-      cdfDefComplex(streamptr, gridID, gridindex);
-      cdfDefFC(streamptr, gridID, gridindex);
+      taxis_t *taxis = &streamptr->tsteps[0].taxis;
+      ptaxisDefName(taxis, ncvars[nctimevarid].name);
+      if ( ncvars[nctimevarid].longname[0] )
+        ptaxisDefLongname(taxis, ncvars[nctimevarid].longname);
     }
-  else if ( gridtype == GRID_TRAJECTORY )
+
+  if ( nctimevarid != UNDEFID )
+    if ( ncvars[nctimevarid].calendar == TRUE )
+      {
+        enum {attstringlen = 8192};
+        char attstring[attstringlen];
+
+	cdfGetAttText(fileID, nctimevarid, "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 )
     {
-      cdfDefTrajLon(streamptr, gridID, gridindex);
-      cdfDefTrajLat(streamptr, gridID, gridindex);
+      taxisID = taxisCreate(TAXIS_FORECAST);
     }
-  else if ( gridtype == GRID_CHARXY )
+  else if ( streamptr->tsteps[0].taxis.type == TAXIS_RELATIVE )
     {
-      int strlen = 0;
-      if ( (strlen = gridInqXIsc(gridID)) )
-        cdfDefCharacter(streamptr, gridID, gridindex, 0, strlen);
-      else
-        if ( gridInqXsize(gridID) > 0 ) cdfDefXaxis(streamptr, gridID, gridindex, 1);
-      if ( (strlen = gridInqYIsc(gridID)) )
-        cdfDefCharacter(streamptr, gridID, gridindex, 1, strlen);
-      else
-        if ( gridInqYsize(gridID) > 0 ) cdfDefYaxis(streamptr, gridID, gridindex, 1);
+      taxisID = taxisCreate(TAXIS_RELATIVE);
     }
   else
     {
-      Error("Unsupported grid type: %s", gridNamePtr(gridtype));
+      taxisID = taxisCreate(TAXIS_ABSOLUTE);
+      if ( !time_has_units )
+	{
+	  taxisDefTunit(taxisID, TUNIT_DAY);
+	  streamptr->tsteps[0].taxis.unit = TUNIT_DAY;
+	}
     }
-}
-
 
-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);
-}
-
-
-void cdfDefVars(stream_t *streamptr)
-{
-  int vlistID = streamptr->vlistID;
-  if ( vlistID == CDI_UNDEFID )
-    Error("Internal problem! vlist undefined for streamptr %p", streamptr);
 
-  int ngrids = vlistNgrids(vlistID);
-  if ( 2*ngrids > MAX_GRIDS_PS ) Error("Internal problem! Too many grids per stream (max=%d)\n", MAX_GRIDS_PS);
-  for ( int index = 0; index < 2*ngrids; ++index )
+  if ( calendar == UNDEFID && streamptr->tsteps[0].taxis.type != TAXIS_ABSOLUTE )
     {
-      streamptr->ncgrid[index].gridID = CDI_UNDEFID;
-      for (size_t i = 0; i < CDF_SIZE_ncIDs; ++i)
-        streamptr->ncgrid[index].ncIDs[i] = CDI_UNDEFID;
+      calendar = CALENDAR_STANDARD;
     }
 
-  for ( int index = 0; index < ngrids; ++index )
-    {
-      int gridID = vlistGrid(vlistID, index);
-      cdfDefGrid(streamptr, gridID, index);
-    }
-  {
-    int index = ngrids-1;
-    for ( int i = 0; i < ngrids; ++i )
-      {
-        int gridID = vlistGrid(vlistID, i);
-        int projID = gridInqProj(gridID);
-        if ( projID != CDI_UNDEFID ) cdfDefGrid(streamptr, projID, ++index);
-      }
-  }
-  int nzaxis = vlistNzaxis(vlistID);
-  for ( int index = 0; index < nzaxis; ++index )
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic warning "-Wstrict-overflow"
+#endif
+  if ( calendar != UNDEFID )
     {
-      int zaxisID = vlistZaxis(vlistID, index);
-      if ( streamptr->zaxisID[index] == CDI_UNDEFID ) cdfDefZaxis(streamptr, zaxisID);
+      taxis_t *taxis = &streamptr->tsteps[0].taxis;
+      taxis->calendar = calendar;
+      taxisDefCalendar(taxisID, calendar);
     }
-}
-
-#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)
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5)
+#pragma GCC diagnostic pop
 #endif
 
-#ifdef HAVE_LIBNETCDF
-
-#  include <stdio.h>
-#  include <string.h>
+  vlistDefTaxis(vlistID, taxisID);
 
-#  include <netcdf.h>
+  streamptr->curTsID = 0;
+  streamptr->rtsteps = 1;
 
+  (void) cdfInqTimestep(streamptr, 0);
 
-static
-int cdfDefTimeBounds(int fileID, int nctimevarid, int nctimedimid, const char *taxis_name, taxis_t* taxis)
-{
-  int time_bndsid = -1;
-  int dims[2];
+  cdfCreateRecords(streamptr, 0);
 
-  dims[0] = nctimedimid;
+  /* free ncdims */
+  Free(ncdims);
 
-  /* fprintf(stderr, "time has bounds\n"); */
-  static const char bndsName[] = "bnds";
-  if ( nc_inq_dimid(fileID, bndsName, &dims[1]) != NC_NOERR )
-    cdf_def_dim(fileID, bndsName, 2, &dims[1]);
+  /* free ncvars */
+  Free(ncvars);
 
-  const char *bndsAttName, *bndsAttVal;
-  size_t bndsAttValLen;
-  char tmpstr[CDI_MAX_NAME];
-  if ( taxis->climatology )
-    {
-      static const char climatology_bndsName[] = "climatology_bnds",
-        climatology_bndsAttName[] = "climatology";
-      bndsAttName = climatology_bndsAttName;
-      bndsAttValLen = sizeof (climatology_bndsName) - 1;
-      bndsAttVal = climatology_bndsName;
-    }
-  else
-    {
-      size_t taxisnameLen = strlen(taxis_name);
-      memcpy(tmpstr, taxis_name, taxisnameLen);
-      tmpstr[taxisnameLen] = '_';
-      memcpy(tmpstr + taxisnameLen + 1, bndsName, sizeof (bndsName));
-      size_t tmpstrLen = taxisnameLen + sizeof (bndsName);
-      static const char generic_bndsAttName[] = "bounds";
-      bndsAttName = generic_bndsAttName;
-      bndsAttValLen = tmpstrLen;
-      bndsAttVal = tmpstr;
-    }
-  cdf_def_var(fileID, bndsAttVal, NC_DOUBLE, 2, dims, &time_bndsid);
-  cdf_put_att_text(fileID, nctimevarid, bndsAttName, bndsAttValLen, bndsAttVal);
+  return (0);
+}
 
-  return time_bndsid;
+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;
+  }
 }
 
 static
-void cdfDefTimeUnits(char *unitstr, taxis_t* taxis0, taxis_t* taxis)
+double get_timevalue(int fileID, int nctimevarid, int tsID, timecache_t *tcache)
 {
-  if ( taxis->units && taxis->units[0] )
+  double timevalue = 0;
+  size_t index = (size_t) tsID;
+
+  if ( tcache )
     {
-      strcpy(unitstr, taxis->units);
+      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];
     }
   else
     {
-      unitstr[0] = 0;
-
-      if ( taxis0->type == TAXIS_ABSOLUTE )
-        {
-          static const char *const unitstrfmt[3]
-            = { "year as %Y.%f",
-                "month as %Y%m.%f",
-                "day as %Y%m%d.%f" };
-          size_t fmtidx = (taxis0->unit == TUNIT_YEAR ? 0
-                           : (taxis0->unit == TUNIT_MONTH ? 1
-                              : 2));
-          strcpy(unitstr, unitstrfmt[fmtidx]);
-        }
-      else
-        {
-          int timeunit = taxis->unit != -1 ? taxis->unit : TUNIT_HOUR;
-          int rdate    = taxis->rdate != -1 ? taxis->rdate : taxis->vdate;
-          int rtime    = taxis->rdate != -1 ? taxis->rtime : taxis->vtime;
-          int year, month, day, hour, minute, second;
-          cdiDecodeDate(rdate, &year, &month, &day);
-          cdiDecodeTime(rtime, &hour, &minute, &second);
-
-          if ( timeunit == TUNIT_QUARTER   ) timeunit = TUNIT_MINUTE;
-          else if ( timeunit == TUNIT_30MINUTES ) timeunit = TUNIT_MINUTE;
-          else if (    timeunit == TUNIT_3HOURS
-                    || timeunit == TUNIT_6HOURS
-                    || timeunit == TUNIT_12HOURS ) timeunit = TUNIT_HOUR;
-
-          sprintf(unitstr, "%s since %d-%d-%d %02d:%02d:%02d",
-                  tunitNamePtr(timeunit), year, month, day, hour, minute, second);
-        }
+      cdf_get_var1_double(fileID, nctimevarid, &index, &timevalue);
+      if ( timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE ) timevalue = 0;
     }
+
+  return timevalue;
 }
 
-static
-void cdfDefForecastTimeUnits(char *unitstr, int timeunit)
+
+int cdfInqTimestep(stream_t * streamptr, int tsID)
 {
-  unitstr[0] = 0;
+  long nrecs = 0;
+  double timevalue;
+  int fileID;
+  taxis_t *taxis;
 
-  if ( timeunit == -1 ) timeunit = TUNIT_HOUR;
-  else if ( timeunit == TUNIT_QUARTER   ) timeunit = TUNIT_MINUTE;
-  else if ( timeunit == TUNIT_30MINUTES ) timeunit = TUNIT_MINUTE;
-  else if (    timeunit == TUNIT_3HOURS
-            || timeunit == TUNIT_6HOURS
-            || timeunit == TUNIT_12HOURS ) timeunit = TUNIT_HOUR;
+  if ( CDI_Debug ) Message("streamID = %d  tsID = %d", streamptr->self, tsID);
 
-  strcpy(unitstr, tunitNamePtr(timeunit));
-}
+  if ( tsID < 0 ) Error("unexpected tsID = %d", tsID);
 
-static
-void cdfDefCalendar(int fileID, int ncvarid, int calendar)
-{
-  static const struct { int calCode; const char *calStr; } calTab[] = {
-    { CALENDAR_STANDARD, "standard" },
-    { CALENDAR_PROLEPTIC, "proleptic_gregorian" },
-    { CALENDAR_NONE, "none" },
-    { CALENDAR_360DAYS, "360_day" },
-    { CALENDAR_365DAYS, "365_day" },
-    { CALENDAR_366DAYS, "366_day" },
-  };
-  enum { calTabSize = sizeof calTab / sizeof calTab[0] };
+  if ( tsID < streamptr->ntsteps && streamptr->ntsteps > 0 )
+    {
+      cdfCreateRecords(streamptr, tsID);
 
-  for ( size_t i = 0; i < calTabSize; ++i )
-    if ( calTab[i].calCode == calendar )
-      {
-        const char *calstr = calTab[i].calStr;
-        size_t len = strlen(calstr);
-        cdf_put_att_text(fileID, ncvarid, "calendar", len, calstr);
-        break;
-      }
-}
+      taxis = &streamptr->tsteps[tsID].taxis;
+      if ( tsID > 0 )
+	ptaxisCopy(taxis, &streamptr->tsteps[0].taxis);
 
+      timevalue = tsID;
 
-void cdfDefTime(stream_t* streamptr)
-{
-  int time_varid;
-  int time_dimid;
-  int time_bndsid = -1;
-  static const char default_name[] = "time";
+      int nctimevarid = streamptr->basetime.ncvarid;
+      if ( nctimevarid != UNDEFID )
+	{
+	  fileID = streamptr->fileID;
+	  size_t index  = (size_t)tsID;
 
-  if ( streamptr->basetime.ncvarid != CDI_UNDEFID ) return;
+	  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);
+	    }
 
-  int fileID = streamptr->fileID;
+	  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;
 
-  if ( streamptr->ncmode == 0 ) streamptr->ncmode = 1;
-  if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+	      cdiDecodeTimeval(timevalue, taxis, &taxis->vdate_lb, &taxis->vtime_lb);
 
-  taxis_t *taxis = &streamptr->tsteps[0].taxis;
+              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;
 
-  const char *taxis_name = (taxis->name && taxis->name[0]) ? taxis->name : default_name ;
+	      cdiDecodeTimeval(timevalue, taxis, &taxis->vdate_ub, &taxis->vtime_ub);
+	    }
 
-  cdf_def_dim(fileID, taxis_name, NC_UNLIMITED, &time_dimid);
-  streamptr->basetime.ncdimid = time_dimid;
+          int leadtimeid = streamptr->basetime.leadtimeid;
+          if ( leadtimeid != UNDEFID )
+            {
+              timevalue = get_timevalue(fileID, leadtimeid, tsID, NULL);
+              cdiSetForecastPeriod(timevalue, taxis);
+            }
+	}
+    }
 
-  nc_type xtype = (taxis->datatype == CDI_DATATYPE_FLT32) ? NC_FLOAT : NC_DOUBLE;
+  streamptr->curTsID = tsID;
+  nrecs = streamptr->tsteps[tsID].nrecs;
 
-  cdf_def_var(fileID, taxis_name, xtype, 1, &time_dimid, &time_varid);
+  return ((int) nrecs);
+}
 
-  streamptr->basetime.ncvarid = time_varid;
 
-#if  defined  (HAVE_NETCDF4)
-  if ( streamptr->filetype == CDI_FILETYPE_NC4 || streamptr->filetype == CDI_FILETYPE_NC4C )
-    {
-      size_t chunk = 512;
-      cdf_def_var_chunking(fileID, time_varid, NC_CHUNKED, &chunk);
-    }
-#endif
+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);
+}
 
-  {
-    static const char timeStr[] = "time";
-    cdf_put_att_text(fileID, time_varid, "standard_name", sizeof(timeStr) - 1, timeStr);
-  }
 
-  if ( taxis->longname && taxis->longname[0] )
-    cdf_put_att_text(fileID, time_varid, "long_name", strlen(taxis->longname), taxis->longname);
+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);
 
-  if ( taxis->has_bounds )
-    {
-      time_bndsid = cdfDefTimeBounds(fileID, time_varid, time_dimid, taxis_name, taxis);
-      streamptr->basetime.ncvarboundsid = time_bndsid;
-    }
+  return ((int) size);
+}
 
-  {
-    char unitstr[CDI_MAX_NAME];
-    cdfDefTimeUnits(unitstr, &streamptr->tsteps[0].taxis, taxis);
-    size_t len = strlen(unitstr);
-    if ( len )
-      {
-        cdf_put_att_text(fileID, time_varid, "units", len, unitstr);
-        /*
-          if ( taxis->has_bounds )
-          cdf_put_att_text(fileID, time_bndsid, "units", len, unitstr);
-        */
-      }
-  }
 
-  if ( taxis->calendar != -1 )
+void cdfInqHistoryString(stream_t *streamptr, char *history)
+{
+  int ncid = streamptr->fileID;
+  if ( streamptr->historyID != UNDEFID )
     {
-      cdfDefCalendar(fileID, time_varid, taxis->calendar);
-      /*
-      if ( taxis->has_bounds )
-        cdfDefCalendar(fileID, time_bndsid, taxis->calendar);
-      */
+      nc_type atttype;
+      cdf_inq_atttype(ncid, NC_GLOBAL, "history", &atttype);
+
+      if ( atttype == NC_CHAR )
+        {
+          cdf_get_att_text(ncid, NC_GLOBAL, "history", history);
+        }
+#if  defined  (HAVE_NETCDF4)
+      else if ( atttype == NC_STRING )
+        {
+          // ToDo
+          Warning("History attribute with type NC_STRING unsupported!");
+        }
+#endif
     }
+}
 
-  if ( taxis->type == TAXIS_FORECAST )
-    {
-      int leadtimeid;
-      cdf_def_var(fileID, "leadtime", xtype, 1, &time_dimid, &leadtimeid);
-      streamptr->basetime.leadtimeid = leadtimeid;
 
-      {
-        static const char stdname[] = "forecast_period";
-        cdf_put_att_text(fileID, leadtimeid, "standard_name", sizeof(stdname) - 1, stdname);
-      }
+void cdfDefVars(stream_t *streamptr)
+{
+  int vlistID = streamptr->vlistID;
+  if ( vlistID == UNDEFID )
+    Error("Internal problem! vlist undefined for streamptr %p", streamptr);
 
+  int ngrids = vlistNgrids(vlistID);
+  int nzaxis = vlistNzaxis(vlistID);
+  /*
+  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
+  */
+  if ( ngrids > 0 )
+    for ( int index = 0; index < ngrids; index++ )
       {
-        static const char lname[] = "Time elapsed since the start of the forecast";
-        cdf_put_att_text(fileID, leadtimeid, "long_name", sizeof(lname) - 1, lname);
+        int gridID = vlistGrid(vlistID, index);
+        cdfDefGrid(streamptr, gridID);
       }
 
+  if ( nzaxis > 0 )
+    for ( int index = 0; index < nzaxis; index++ )
       {
-          char unitstr[CDI_MAX_NAME];
-          cdfDefForecastTimeUnits(unitstr, taxis->fc_unit);
-          size_t len = strlen(unitstr);
-          if ( len )
-            cdf_put_att_text(fileID, leadtimeid, "units", len, unitstr);
+        int zaxisID = vlistZaxis(vlistID, index);
+        if ( streamptr->zaxisID[index] == UNDEFID ) cdfDefZaxis(streamptr, zaxisID);
       }
-    }
-
-  cdf_put_att_text(fileID, time_varid, "axis", 1, "T");
 
-  if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
+  /* define time first!!!
+    int nvars  = vlistNvars(vlistID);
+  for ( int varID = 0; varID < nvars; varID++ )
+    {
+      int ncvarid = cdfDefVar(streamptr, varID);
+    }
+  */
 }
-
-
 #endif
 /*
  * Local Variables:
@@ -45500,11 +45092,6 @@ size_t cgribexEncode(int memtype, int varID, int levelID, int vlistID, int gridI
 		     int vdate, int vtime, int tsteptype, int numavg,
 		     long datasize, const void *data, int nmiss, void *gribbuffer, size_t gribbuffersize);
 
-void *cgribex_handle_new_from_meassage(void *gribbuffer, size_t recsize);
-void cgribex_handle_delete(void *gh);
-
-void cgribexChangeParameterIdentification(void *gh, int code, int ltype, int lev);
-
 #endif  /* _STREAM_CGRIBEX_H */
 /*
  * Local Variables:
@@ -45542,12 +45129,17 @@ int cgribexGetGridType(int *isec2)
 
   switch (ISEC2_GridType)
     {
-    case  GRIB1_GTYPE_LATLON:     { gridtype = GRID_LONLAT;     break; }
-    case  GRIB1_GTYPE_LATLON_ROT: { gridtype = GRID_PROJECTION; break; }
-    case  GRIB1_GTYPE_LCC:        { gridtype = GRID_LCC;        break; }
-    case  GRIB1_GTYPE_GAUSSIAN:   { gridtype = ISEC2_Reduced ? GRID_GAUSSIAN_REDUCED : GRID_GAUSSIAN; break; }
-    case  GRIB1_GTYPE_SPECTRAL:   { gridtype = GRID_SPECTRAL;   break; }
-    case  GRIB1_GTYPE_GME:        { gridtype = GRID_GME;        break; }
+    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; }
     }
 
   return gridtype;
@@ -45556,7 +45148,9 @@ int cgribexGetGridType(int *isec2)
 static
 bool cgribexGetIsRotated(int *isec2)
 {
-  return (ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT);
+  bool isRotated = (ISEC2_GridType == GRIB1_GTYPE_LATLON_ROT) ? true : false;
+
+  return isRotated;
 }
 
 static
@@ -45617,9 +45211,9 @@ bool cgribexTimeIsFC(int *isec1)
 static
 int cgribexGetTsteptype(int timerange)
 {
+  int tsteptype = TSTEP_INSTANT;
   static bool lprint = true;
 
-  int tsteptype = TSTEP_INSTANT;
   switch ( timerange )
     {
     case  0:  tsteptype = TSTEP_INSTANT;  break;
@@ -45642,21 +45236,15 @@ 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)
 {
   bool compyinc = true;
   int gridtype = cgribexGetGridType(isec2);
-  int projtype = (gridtype == GRID_PROJECTION && cgribexGetIsRotated(isec2)) ? CDI_PROJ_RLL : CDI_UNDEFID;
-  if ( gridtype == GRID_LCC )
-    {
-      gridtype = GRID_PROJECTION;
-      projtype = CDI_PROJ_LCC;
-    }
 
   if ( streamptr->unreduced && gridtype == GRID_GAUSSIAN_REDUCED && iret != -801 )
     {
-      int nlon = 0;
-      for ( int ilat = 0; ilat < ISEC2_NumLat; ++ilat )
+      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;
@@ -45666,190 +45254,197 @@ void cgribexGetGrid(stream_t *streamptr, int *isec2, int *isec4, grid_t *grid, i
 
   grid_init(grid);
   cdiGridTypeInit(grid, gridtype, 0);
-
-  if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN || projtype == CDI_PROJ_RLL )
+  switch (gridtype)
     {
-      bool ijDirectionIncrementGiven = gribbyte_get_bit(ISEC2_ResFlag, 1);
-      bool uvRelativeToGrid = gribbyte_get_bit(ISEC2_ResFlag, 5);
-
-      if ( uvRelativeToGrid ) grid->uvRelativeToGrid = 1;
-      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->x.size = ISEC2_NumLon;
-      grid->y.size = ISEC2_NumLat;
-      if ( gridtype == GRID_GAUSSIAN ) grid->np = ISEC2_NumPar;
-      grid->x.inc  = 0;
-      grid->y.inc  = 0;
-      grid->x.flag = 0;
-      /* if ( ISEC2_FirstLon != 0 || ISEC2_LastLon != 0 ) */
+    case GRID_LONLAT:
+    case GRID_GAUSSIAN:
       {
-        if ( grid->x.size > 1 )
-          {
-            bool recompinc = true;
+	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 )
+	      {
+                bool recompinc = true;
 
-            if ( ISEC2_LastLon < ISEC2_FirstLon && ISEC2_LastLon < 0 ) ISEC2_LastLon += 360000;
+                if ( ISEC2_LastLon < ISEC2_FirstLon && ISEC2_LastLon < 0 ) ISEC2_LastLon += 360000;
 
-            if ( ijDirectionIncrementGiven && ISEC2_LonIncr > 0 )
-              {
-                if ( abs(ISEC2_LastLon - (ISEC2_FirstLon+ISEC2_LonIncr*(grid->x.size-1))) <= 2 )
+		if ( ISEC2_ResFlag && ISEC2_LonIncr > 0 )
                   {
-                    recompinc = false;
-                    grid->x.inc = ISEC2_LonIncr * 0.001;
+                    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->x.inc = (ISEC2_LastLon - ISEC2_FirstLon) * 0.001 / (grid->x.size-1);
+		/* 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->x.size;
-                if ( fabs(grid->x.inc-xinc) > 0.0 )
+		/* 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 )
+	      {
+                bool recompinc = true;
+		if ( ISEC2_ResFlag && ISEC2_LatIncr > 0 )
                   {
-                    grid->x.inc = xinc;
-                    if ( CDI_Debug ) Message("set xinc to %g", grid->x.inc);
+                    if ( abs(ISEC2_LastLat - (ISEC2_FirstLat+ISEC2_LatIncr*(grid->ysize-1))) <= 2 )
+                      {
+                        recompinc = false;
+                        grid->yinc = ISEC2_LatIncr * 0.001;
+                      }
                   }
-              }
-          }
-        grid->x.first = ISEC2_FirstLon * 0.001;
-        grid->x.last  = ISEC2_LastLon  * 0.001;
-        grid->x.flag  = 2;
+
+		/* 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;
       }
-      grid->y.flag = 0;
-      /* if ( ISEC2_FirstLat != 0 || ISEC2_LastLat != 0 ) */
+    case GRID_GAUSSIAN_REDUCED:
       {
-        if ( grid->y.size > 1 && compyinc )
-          {
-            bool recompinc = true;
-            if ( ijDirectionIncrementGiven && ISEC2_LatIncr > 0 )
-              {
-                if ( abs(ISEC2_LastLat - (ISEC2_FirstLat+ISEC2_LatIncr*(grid->y.size-1))) <= 2 )
-                  {
-                    recompinc = false;
-                    grid->y.inc = ISEC2_LatIncr * 0.001;
-                  }
-              }
+        grid->np      = ISEC2_NumPar;
+	grid->size    = ISEC4_NumValues;
+        grid->rowlon  = ISEC2_RowLonPtr;
+	grid->nrowlon = ISEC2_NumLat;
+	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;
 
-            /* recompute yinc if necessary */
-            if ( recompinc ) grid->y.inc = (ISEC2_LastLat - ISEC2_FirstLat) * 0.001 / (grid->y.size - 1);
-          }
-        grid->y.first = ISEC2_FirstLat * 0.001;
-        grid->y.last  = ISEC2_LastLat  * 0.001;
-        grid->y.flag  = 2;
+		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;
       }
-    }
-  else if ( gridtype == GRID_GAUSSIAN_REDUCED )
-    {
-      bool ijDirectionIncrementGiven = gribbyte_get_bit(ISEC2_ResFlag, 1);
-      bool uvRelativeToGrid = gribbyte_get_bit(ISEC2_ResFlag, 5);
-      if ( uvRelativeToGrid ) grid->uvRelativeToGrid = 1;
-      grid->np      = ISEC2_NumPar;
-      grid->size    = ISEC4_NumValues;
-      grid->rowlon  = ISEC2_RowLonPtr;
-      grid->nrowlon = ISEC2_NumLat;
-      grid->y.size  = ISEC2_NumLat;
-      grid->x.inc   = 0;
-      grid->y.inc   = 0;
-      grid->x.flag  = 0;
-      /* if ( ISEC2_FirstLon != 0 || ISEC2_LastLon != 0 ) */
+    case GRID_LCC:
       {
-        if ( grid->x.size > 1 )
-          {
-            if ( ISEC2_LastLon < ISEC2_FirstLon && ISEC2_LastLon < 0 ) ISEC2_LastLon += 360000;
+	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;
 
-            if ( ijDirectionIncrementGiven && ISEC2_LonIncr > 0 )
-              grid->x.inc = ISEC2_LonIncr * 0.001;
-            else
-              grid->x.inc = (ISEC2_LastLon - ISEC2_FirstLon) * 0.001 / (grid->x.size - 1);
-          }
-        grid->x.first = ISEC2_FirstLon * 0.001;
-        grid->x.last  = ISEC2_LastLon  * 0.001;
-        grid->x.flag  = 2;
+	break;
       }
-      grid->y.flag = 0;
-      /* if ( ISEC2_FirstLat != 0 || ISEC2_LastLat != 0 ) */
+    case GRID_SPECTRAL:
       {
-        if ( grid->y.size > 1 )
-          {
-            if ( ijDirectionIncrementGiven && ISEC2_LatIncr > 0 )
-              grid->y.inc = ISEC2_LatIncr * 0.001;
-            else
-              grid->y.inc = (ISEC2_LastLat - ISEC2_FirstLat) * 0.001 / (grid->y.size - 1);
-          }
-        grid->y.first = ISEC2_FirstLat * 0.001;
-        grid->y.last  = ISEC2_LastLat  * 0.001;
-        grid->y.flag  = 2;
+	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;
       }
     }
-  else if ( projtype == CDI_PROJ_LCC )
-    {
-      bool uvRelativeToGrid = gribbyte_get_bit(ISEC2_ResFlag, 5);
-      if ( uvRelativeToGrid ) grid->uvRelativeToGrid = 1;
-
-      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->x.size = ISEC2_NumLon;
-      grid->y.size = ISEC2_NumLat;
 
-      grid->x.first = 0;
-      grid->x.last  = 0;
-      grid->x.inc   = ISEC2_Lambert_dx;
-      grid->y.first = 0;
-      grid->y.last  = 0;
-      grid->y.inc   = ISEC2_Lambert_dy;
-      grid->x.flag  = 2;
-      grid->y.flag  = 2;
-    }
-  else if ( gridtype == GRID_SPECTRAL )
-    {
-      grid->size  = ISEC4_NumValues;
-      grid->trunc = ISEC2_PentaJ;
-      if ( ISEC2_RepMode == 2 )
-        grid->lcomplex = 1;
-      else
-        grid->lcomplex = 0;
-    }
-  else if ( gridtype == GRID_GME )
-    {
-      grid->size  = ISEC4_NumValues;
-      grid->gme.nd  = ISEC2_GME_ND;
-      grid->gme.ni  = ISEC2_GME_NI;
-      grid->gme.ni2 = ISEC2_GME_NI2;
-      grid->gme.ni3 = ISEC2_GME_NI3;
-    }
-  else if ( gridtype == GRID_GENERIC )
+  grid->isRotated = FALSE;
+  if ( cgribexGetIsRotated(isec2) )
     {
-      grid->size  = ISEC4_NumValues;
-      grid->x.size = 0;
-      grid->y.size = 0;
+      grid->isRotated = TRUE;
+      grid->ypole     = - ISEC2_LatSP*0.001;
+      grid->xpole     =   ISEC2_LonSP*0.001 - 180;
+      grid->angle     = - FSEC2_RotAngle;
     }
-  else
-    {
-      Error("Unsupported grid type: %s", gridNamePtr(gridtype));
-    }
-
-  grid->type = gridtype;
-  grid->projtype = projtype;
-}
 
-static
-void cgribexGetLevel(int *isec1, int *leveltype, int *level1, int *level2)
-{
-  *leveltype = ISEC1_LevelType;
-  *level1 = ISEC1_Level1;
-  *level2 = ISEC1_Level2;
-  if ( *leveltype == GRIB1_LTYPE_ISOBARIC ) *level1 *= 100;
-  else if ( *leveltype == GRIB1_LTYPE_99 || *leveltype == GRIB1_LTYPE_ISOBARIC_PA ) *leveltype = GRIB1_LTYPE_ISOBARIC;
+  grid->xvals = NULL;
+  grid->yvals = NULL;
+  grid->type  = gridtype;
 }
 
 static
 void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, double *fsec2, double *fsec3,
-		      int *isec4, size_t recsize, off_t position, int datatype, int comptype, int lmv, int iret)
+		      int *isec4, long recsize, off_t position, int datatype, int comptype, int lmv, int iret)
 {
   int varID;
   int levelID = 0;
@@ -45862,23 +45457,23 @@ void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, d
   int tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);
   int numavg    = ISEC1_AvgNum;
 
-  int leveltype, level1, level2;
-  cgribexGetLevel(isec1, &leveltype, &level1, &level2);
+  int level1  = ISEC1_Level1;
+  int level2  = ISEC1_Level2;
 
-  /* fprintf(stderr, "param %d %d %d %d\n", param, level1, level2, leveltype); */
+  /* fprintf(stderr, "param %d %d %d %d\n", param, level1, level2, ISEC1_LevelType); */
 
-  record->size      = recsize;
+  record->size      = (size_t)recsize;
   record->position  = position;
   record->param     = param;
   record->ilevel    = level1;
   record->ilevel2   = level2;
-  record->ltype     = leveltype;
+  record->ltype     = ISEC1_LevelType;
   record->tsteptype = (short)tsteptype;
 
   grid_t *gridptr = (grid_t*) Malloc(sizeof(*gridptr));
-  cgribexGetGrid(streamptr, isec2, isec4, gridptr, iret);
+  cgribexGetGrid(streamptr, isec2, fsec2, isec4, gridptr, iret);
 
-  struct addIfNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, gridptr, 0);
+  struct addIffNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, gridptr, 0);
   int gridID = gridAdded.Id;
   if ( gridAdded.isNew )
     {
@@ -45889,44 +45484,11 @@ void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, d
           gridptr->rowlon = (int*) Malloc(nrowlon * sizeof(int));
           memcpy(gridptr->rowlon, rowlon, nrowlon * sizeof(int));
         }
-      else if ( gridptr->projtype == CDI_PROJ_RLL )
-        {
-          double xpole =   ISEC2_LonSP*0.001 - 180;
-          double ypole = - ISEC2_LatSP*0.001;
-          double angle = - FSEC2_RotAngle;
-          gridDefParamRLL(gridID, xpole, ypole, angle);
-        }
-      else if ( gridptr->projtype == CDI_PROJ_LCC )
-        {
-          double a = 6367470., rf = 0;
-          bool earthIsOblate = gribbyte_get_bit(ISEC2_ResFlag, 2);
-          if ( earthIsOblate ) { a = 6378160.; rf = 297.0; }
-          double xval_0 = ISEC2_FirstLon * 0.001;
-          double yval_0 = ISEC2_FirstLat * 0.001;
-          double lon_0  = ISEC2_Lambert_Lov * 0.001;
-          double lat_1  = ISEC2_Lambert_LatS1 * 0.001;
-          double lat_2  = ISEC2_Lambert_LatS2 * 0.001;
-          bool lsouth = gribbyte_get_bit(ISEC2_Lambert_ProjFlag, 1);
-          if ( lsouth ) { lat_1 = -lat_1; lat_2 = -lat_2; }
-
-          double lat_0 = lat_2;
-          double x_0 = grid_missval;
-          double y_0 = grid_missval;
-
-          if ( proj_lonlat_to_lcc_func )
-            {
-              x_0 = xval_0; y_0 = yval_0;
-              proj_lonlat_to_lcc_func(grid_missval, lon_0, lat_0, lat_1, lat_2, a, rf, (size_t)1, &x_0, &y_0);
-              if ( IS_NOT_EQUAL(x_0, grid_missval) && IS_NOT_EQUAL(y_0, grid_missval) )
-                { x_0 = -x_0; y_0 = -y_0; }
-            }
-          gridDefParamLCC(gridID, grid_missval, lon_0, lat_0, lat_1, lat_2, a, rf, xval_0, yval_0, x_0, y_0);
-        }
     }
   else
     Free(gridptr);
 
-  int zaxistype = grib1ltypeToZaxisType(leveltype);
+  int zaxistype = grib1ltypeToZaxisType(ISEC1_LevelType);
 
   if ( zaxistype == ZAXIS_HYBRID || zaxistype == ZAXIS_HYBRID_HALF )
     {
@@ -45936,13 +45498,13 @@ void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, d
       varDefVCT(vctsize, vctptr);
     }
 
-  int lbounds = cgribexGetZaxisHasBounds(leveltype);
+  int lbounds = cgribexGetZaxisHasBounds(ISEC1_LevelType);
 
-  if ( datatype > 32 ) datatype = CDI_DATATYPE_PACK32;
-  if ( datatype <  0 ) datatype = CDI_DATATYPE_PACK;
+  if ( datatype > 32 ) datatype = DATATYPE_PACK32;
+  if ( datatype <  0 ) datatype = DATATYPE_PACK;
 
   varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, 0, 0,
-	       datatype, &varID, &levelID, tsteptype, numavg, leveltype, -1,
+	       datatype, &varID, &levelID, tsteptype, numavg, ISEC1_LevelType, -1,
                NULL, NULL, NULL, NULL, NULL, NULL);
 
   record->varID   = (short)varID;
@@ -45962,9 +45524,10 @@ void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, d
 
   if ( varInqInst(varID) == CDI_UNDEFID )
     {
-      int center    = ISEC1_CenterID;
-      int subcenter = ISEC1_SubCenterID;
-      int instID    = institutInq(center, subcenter, NULL, NULL);
+      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);
@@ -45972,7 +45535,8 @@ void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, d
 
   if ( varInqModel(varID) == CDI_UNDEFID )
     {
-      int modelID = modelInq(varInqInst(varID), ISEC1_ModelID, NULL);
+      int modelID;
+      modelID = modelInq(varInqInst(varID), ISEC1_ModelID, NULL);
       if ( modelID == CDI_UNDEFID )
 	modelID = modelDef(varInqInst(varID), ISEC1_ModelID, NULL);
       varDefModel(varID, modelID);
@@ -45980,7 +45544,10 @@ void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, d
 
   if ( varInqTable(varID) == CDI_UNDEFID )
     {
-      int tableID = tableInq(varInqModel(varID), ISEC1_CodeTable, NULL);
+      int tableID;
+
+      tableID = tableInq(varInqModel(varID), ISEC1_CodeTable, NULL);
+
       if ( tableID == CDI_UNDEFID )
 	tableID = tableDef(varInqModel(varID), ISEC1_CodeTable, NULL);
       varDefTable(varID, tableID);
@@ -46032,6 +45599,7 @@ void cgribexDecodeHeader(int *isec0, int *isec1, int *isec2, double *fsec2,
   if ( ISEC1_CenterID == 215 && (isec1[34] != 0 && isec1[34] != 255) )
     {
       double undef_pds, undef_eps;
+
       MCH_get_undef(isec1, &undef_pds, &undef_eps);
       FSEC3_MissVal = undef_pds;
       *lmv = 1;
@@ -46041,9 +45609,9 @@ void cgribexDecodeHeader(int *isec0, int *isec1, int *isec2, double *fsec2,
 static
 compvar_t cgribexVarSet(int param, int level1, int level2, int leveltype, int trange)
 {
+  compvar_t compVar;
   int tsteptype = cgribexGetTsteptype(trange);
 
-  compvar_t compVar;
   compVar.param     = param;
   compVar.level1    = level1;
   compVar.level2    = level2;
@@ -46056,10 +45624,11 @@ compvar_t cgribexVarSet(int param, int level1, int level2, int leveltype, int tr
 static inline int
 cgribexVarCompare(compvar_t compVar, record_t record, int flag)
 {
-  bool vinst = compVar.tsteptype == TSTEP_INSTANT || compVar.tsteptype == TSTEP_INSTANT2 || compVar.tsteptype == TSTEP_INSTANT3;
-  bool rinst = record.tsteptype == TSTEP_INSTANT || record.tsteptype == TSTEP_INSTANT2 || record.tsteptype == TSTEP_INSTANT3;
-  int tstepDiff = (!((flag == 0) & (vinst && rinst)))
-                & (compVar.tsteptype != record.tsteptype);
+  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)
@@ -46083,7 +45652,7 @@ cgribexScanTsFixNtsteps(stream_t *streamptr, off_t recpos)
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
-      streamptr->tsteps[tsID-1].next   = true;
+      streamptr->tsteps[tsID-1].next   = TRUE;
       streamptr->tsteps[tsID].position = recpos;
     }
 }
@@ -46097,14 +45666,16 @@ cgribexScanTsConstAdjust(stream_t *streamptr, taxis_t *taxis)
       if ( taxis->vdate == 0 && taxis->vtime == 0 )
 	{
 	  streamptr->ntsteps = 0;
-	  for ( int varID = 0; varID < streamptr->nvars; varID++ )
-            vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
+	  for (int varID = 0; varID < streamptr->nvars; varID++ )
+	    {
+	      vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
+	    }
 	}
     }
 }
 
 
-int cgribexScanTimestep1(stream_t *streamptr)
+int cgribexScanTimestep1(stream_t * streamptr)
 {
   double fsec2[512], fsec3[2], *fsec4 = NULL;
   int lmv = 0, iret = 0;
@@ -46113,13 +45684,13 @@ int cgribexScanTimestep1(stream_t *streamptr)
   size_t buffersize = 0;
   int rstatus;
   int param = 0;
-  int leveltype = 0, level1 = 0, level2 = 0, vdate = 0, vtime = 0;
+  int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
   DateTime datetime, datetime0 = { LONG_MIN, LONG_MIN };
   size_t readsize;
   unsigned nrecords, recID;
   int nrecs_scanned = 0;
   int datatype;
-  size_t recsize = 0;
+  long recsize = 0;
   bool warn_time = true;
   bool warn_numavg = true;
   int taxisID = -1;
@@ -46127,7 +45698,7 @@ int cgribexScanTimestep1(stream_t *streamptr)
   bool fcast = false;
   int vlistID;
   int comptype;
-  size_t unzipsize;
+  long unzipsize;
   char paramstr[32];
   int nskip = cdiSkipRecords;
 
@@ -46158,7 +45729,7 @@ int cgribexScanTimestep1(stream_t *streamptr)
     }
 
   unsigned nrecs = 0;
-  while ( true )
+  while ( TRUE )
     {
       recsize = gribGetSize(fileID);
       recpos  = fileGetPos(fileID);
@@ -46171,24 +45742,24 @@ int cgribexScanTimestep1(stream_t *streamptr)
 	  streamptr->ntsteps = 1;
 	  break;
 	}
-      if ( recsize > buffersize )
+      if ( (size_t)recsize > buffersize )
 	{
-	  buffersize = recsize;
+	  buffersize = (size_t)recsize;
 	  gribbuffer = Realloc(gribbuffer, buffersize);
 	}
 
-      readsize = recsize;
+      readsize = (size_t)recsize;
       rstatus = gribRead(fileID, (unsigned char *)gribbuffer, &readsize);
       if ( rstatus ) break;
 
-      comptype = CDI_COMPRESS_NONE;
+      comptype = COMPRESS_NONE;
       if ( gribGetZip(recsize, (unsigned char *)gribbuffer, &unzipsize) > 0 )
 	{
-	  comptype = CDI_COMPRESS_SZIP;
+	  comptype = COMPRESS_SZIP;
 	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
-	  if ( buffersize < unzipsize )
+	  if ( buffersize < (size_t)unzipsize )
 	    {
-	      buffersize = unzipsize;
+	      buffersize = (size_t)unzipsize;
 	      gribbuffer = Realloc(gribbuffer, buffersize);
 	    }
 	}
@@ -46200,11 +45771,17 @@ int cgribexScanTimestep1(stream_t *streamptr)
       param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
       cdiParamToString(param, paramstr, sizeof(paramstr));
 
-      cgribexGetLevel(isec1, &leveltype, &level1, &level2);
+      if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
+      if ( ISEC1_LevelType ==  99 ) ISEC1_LevelType = 100;
+      level1   = ISEC1_Level1;
+      level2   = ISEC1_Level2;
 
       gribDateTime(isec1, &vdate, &vtime);
 
-      datatype = (ISEC4_NumBits > 0 && ISEC4_NumBits <= 32) ? ISEC4_NumBits : CDI_DATATYPE_PACK;
+      if ( ISEC4_NumBits > 0 && ISEC4_NumBits <= 32 )
+	datatype = ISEC4_NumBits;
+      else
+        datatype = DATATYPE_PACK;
 
       if ( nrecs == 0 )
 	{
@@ -46217,9 +45794,9 @@ int cgribexScanTimestep1(stream_t *streamptr)
 	}
       else
 	{
-	  datetime.date = vdate;
-	  datetime.time = vtime;
-	  compvar_t compVar = cgribexVarSet(param, level1, level2, leveltype, ISEC1_TimeRange);
+	  datetime.date  = vdate;
+	  datetime.time  = vtime;
+	  compvar_t compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType, ISEC1_TimeRange);
 	  for ( recID = 0; recID < nrecs; recID++ )
 	    {
 	      if ( cgribexVarCompare(compVar, streamptr->tsteps[0].records[recID], 0) == 0 ) break;
@@ -46310,7 +45887,7 @@ int cgribexScanTimestep1(stream_t *streamptr)
     streamptr->tsteps[0].recIDs[recID] = (int)recID;
 
   streamptr->record->buffer     = gribbuffer;
-  streamptr->record->buffersize = buffersize;
+  streamptr->record->buffersize = (size_t)buffersize;
 
   cgribexScanTsFixNtsteps(streamptr, recpos);
   cgribexScanTsConstAdjust(streamptr, taxis);
@@ -46326,15 +45903,15 @@ int cgribexScanTimestep2(stream_t * streamptr)
   int lmv = 0, iret = 0;
   off_t recpos = 0;
   int param = 0;
-  int leveltype = 0, level1 = 0, level2 = 0, vdate = 0, vtime = 0;
+  int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
   DateTime datetime, datetime0 = { LONG_MIN, LONG_MIN };
   int varID, gridID;
   size_t readsize;
   int nrecs, recID;
-  size_t recsize = 0;
+  long recsize = 0;
   bool warn_numavg = true;
   int tsteptype;
-  size_t unzipsize;
+  long unzipsize;
   char paramstr[32];
 
   streamptr->curTsID = 1;
@@ -46377,7 +45954,7 @@ int cgribexScanTimestep2(stream_t * streamptr)
 
   int nrecs_scanned = nrecords;
   int rindex = 0;
-  while ( true )
+  while ( TRUE )
     {
       if ( rindex > nrecords ) break;
 
@@ -46388,22 +45965,22 @@ int cgribexScanTimestep2(stream_t * streamptr)
 	  streamptr->ntsteps = 2;
 	  break;
 	}
-      if ( recsize > buffersize )
+      if ( (size_t)recsize > buffersize )
 	{
-	  buffersize = recsize;
+	  buffersize = (size_t)recsize;
 	  gribbuffer = Realloc(gribbuffer, buffersize);
 	}
 
-      readsize = recsize;
+      readsize = (size_t)recsize;
       rstatus = gribRead(fileID, (unsigned char *)gribbuffer, &readsize);
       if ( rstatus ) break;
 
       if ( gribGetZip(recsize, (unsigned char *)gribbuffer, &unzipsize) > 0 )
 	{
 	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
-	  if ( buffersize < unzipsize )
+	  if ( buffersize < (size_t)unzipsize )
 	    {
-	      buffersize = unzipsize;
+	      buffersize = (size_t)unzipsize;
 	      gribbuffer = Realloc(gribbuffer, buffersize);
 	    }
 	}
@@ -46416,7 +45993,10 @@ int cgribexScanTimestep2(stream_t * streamptr)
       param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
       cdiParamToString(param, paramstr, sizeof(paramstr));
 
-      cgribexGetLevel(isec1, &leveltype, &level1, &level2);
+      if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
+      if ( ISEC1_LevelType ==  99 ) ISEC1_LevelType = 100;
+      level1    = ISEC1_Level1;
+      level2    = ISEC1_Level2;
 
       gribDateTime(isec1, &vdate, &vtime);
 
@@ -46461,7 +46041,7 @@ int cgribexScanTimestep2(stream_t * streamptr)
       datetime.date  = vdate;
       datetime.time  = vtime;
 
-      compvar_t compVar = cgribexVarSet(param, level1, level2, leveltype, ISEC1_TimeRange);
+      compvar_t compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType, ISEC1_TimeRange);
 
       for ( recID = 0; recID < nrecords; recID++ )
 	{
@@ -46482,7 +46062,7 @@ int cgribexScanTimestep2(stream_t * streamptr)
 	    }
 	  else
 	    {
-	      streamptr->tsteps[tsID].records[recID].used = true;
+	      streamptr->tsteps[tsID].records[recID].used = TRUE;
 	      streamptr->tsteps[tsID].recIDs[rindex] = recID;
 	    }
 	}
@@ -46497,7 +46077,7 @@ int cgribexScanTimestep2(stream_t * streamptr)
 	    }
 	  else
 	    {
-	      streamptr->tsteps[tsID].records[recID].used = true;
+	      streamptr->tsteps[tsID].records[recID].used = TRUE;
 	      streamptr->tsteps[tsID].recIDs[rindex] = recID;
 	    }
 	}
@@ -46505,7 +46085,7 @@ int cgribexScanTimestep2(stream_t * streamptr)
       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 = recsize;
+      streamptr->tsteps[tsID].records[recID].size = (size_t)recsize;
 
       if ( cgribexVarCompare(compVar, streamptr->tsteps[tsID].records[recID], 0) != 0 )
 	{
@@ -46565,13 +46145,13 @@ int cgribexScanTimestep(stream_t * streamptr)
   int rstatus = 0;
   double fsec2[512], fsec3[2], *fsec4 = NULL;
   int lmv = 0, iret = 0;
-  size_t recsize = 0;
+  long recsize = 0;
   off_t recpos = 0;
   void *gribbuffer;
   size_t buffersize = 0;
   int fileID;
   int param = 0;
-  int leveltype = 0, level1 = 0, level2 = 0, vdate = 0, vtime = 0;
+  int level1 = 0, level2 = 0, vdate = 0, vtime = 0;
   DateTime datetime, datetime0 = { LONG_MIN, LONG_MIN };
   int vrecID, recID;
   bool warn_numavg = true;
@@ -46579,7 +46159,7 @@ int cgribexScanTimestep(stream_t * streamptr)
   int taxisID = -1;
   int rindex, nrecs = 0;
   int nrecs_scanned;
-  size_t unzipsize;
+  long unzipsize;
   char paramstr[32];
 
   /*
@@ -46620,7 +46200,7 @@ int cgribexScanTimestep(stream_t * streamptr)
 
       nrecs_scanned = streamptr->tsteps[0].nallrecs + streamptr->tsteps[1].nrecs*(tsID-1);
       rindex = 0;
-      while ( true )
+      while ( TRUE )
 	{
 	  if ( rindex > nrecs ) break;
 
@@ -46631,15 +46211,15 @@ int cgribexScanTimestep(stream_t * streamptr)
 	      streamptr->ntsteps = streamptr->rtsteps + 1;
 	      break;
 	    }
-	  if ( recsize > 0 && recsize > buffersize )
+	  if ( recsize > 0 && (size_t)recsize > buffersize )
 	    {
-	      buffersize = recsize;
+	      buffersize = (size_t)recsize;
 	      gribbuffer = Realloc(gribbuffer, buffersize);
 	    }
 
 	  if ( rindex >= nrecs ) break;
 
-	  readsize = recsize;
+	  readsize = (size_t)recsize;
 	  rstatus = gribRead(fileID, (unsigned char *)gribbuffer, &readsize);
 	  if ( rstatus )
 	    {
@@ -46651,9 +46231,9 @@ int cgribexScanTimestep(stream_t * streamptr)
 	  if ( gribGetZip(recsize, (unsigned char *)gribbuffer, &unzipsize) > 0 )
 	    {
 	      unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
-	      if ( buffersize < unzipsize )
+	      if ( buffersize < (size_t)unzipsize )
 		{
-		  buffersize = unzipsize;
+		  buffersize = (size_t)unzipsize;
 		  gribbuffer = Realloc(gribbuffer, buffersize);
 		}
 	    }
@@ -46666,7 +46246,10 @@ int cgribexScanTimestep(stream_t * streamptr)
 	  param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255);
           cdiParamToString(param, paramstr, sizeof(paramstr));
 
-          cgribexGetLevel(isec1, &leveltype, &level1, &level2);
+	  if ( ISEC1_LevelType == 100 ) ISEC1_Level1 *= 100;
+	  if ( ISEC1_LevelType ==  99 ) ISEC1_LevelType = 100;
+	  level1   = ISEC1_Level1;
+	  level2   = ISEC1_Level2;
 
 	  gribDateTime(isec1, &vdate, &vtime);
 
@@ -46713,7 +46296,7 @@ int cgribexScanTimestep(stream_t * streamptr)
 	  datetime.date  = vdate;
 	  datetime.time  = vtime;
 
-	  compvar_t compVar = cgribexVarSet(param, level1, level2, leveltype, ISEC1_TimeRange);
+	  compvar_t compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType, ISEC1_TimeRange);
 
 	  for ( vrecID = 0; vrecID < nrecs; vrecID++ )
 	    {
@@ -46733,7 +46316,7 @@ int cgribexScanTimestep(stream_t * streamptr)
 
 	  if ( cdiInventoryMode == 1 )
 	    {
-	      streamptr->tsteps[tsID].records[recID].used = true;
+	      streamptr->tsteps[tsID].records[recID].used = TRUE;
 	      streamptr->tsteps[tsID].recIDs[rindex] = recID;
 	    }
 	  else
@@ -46752,7 +46335,7 @@ int cgribexScanTimestep(stream_t * streamptr)
 		}
 	      else
 		{
-		  streamptr->tsteps[tsID].records[recID].used = true;
+		  streamptr->tsteps[tsID].records[recID].used = TRUE;
 		  streamptr->tsteps[tsID].recIDs[rindex] = recID;
 		}
 	    }
@@ -46770,7 +46353,7 @@ int cgribexScanTimestep(stream_t * streamptr)
 	    }
 
 	  streamptr->tsteps[tsID].records[recID].position = recpos;
-	  streamptr->tsteps[tsID].records[recID].size = recsize;
+	  streamptr->tsteps[tsID].records[recID].size = (size_t)recsize;
 
 	  rindex++;
 	}
@@ -46797,7 +46380,7 @@ int cgribexScanTimestep(stream_t * streamptr)
 	  if ( tsID != streamptr->rtsteps )
 	    Error("Internal error. tsID = %d", tsID);
 
-	  streamptr->tsteps[tsID-1].next   = true;
+	  streamptr->tsteps[tsID-1].next   = 1;
 	  streamptr->tsteps[tsID].position = recpos;
 	}
 
@@ -46887,18 +46470,33 @@ int cgribexDecode(int memtype, void *gribbuffer, int gribsize, void *data, long
 static
 void cgribexDefInstitut(int *isec1, int vlistID, int varID)
 {
-  int instID = (vlistInqInstitut(vlistID) != CDI_UNDEFID) ? vlistInqInstitut(vlistID) : vlistInqVarInstitut(vlistID, varID);
+  int instID;
+
+  if ( vlistInqInstitut(vlistID) != CDI_UNDEFID )
+    instID = vlistInqInstitut(vlistID);
+  else
+    instID = vlistInqVarInstitut(vlistID, varID);
+
   if ( instID != CDI_UNDEFID )
     {
-      ISEC1_CenterID    = institutInqCenter(instID);
-      ISEC1_SubCenterID = institutInqSubcenter(instID);
+      int center, subcenter;
+      center    = institutInqCenter(instID);
+      subcenter = institutInqSubcenter(instID);
+      ISEC1_CenterID    = center;
+      ISEC1_SubCenterID = subcenter;
     }
 }
 
 static
 void cgribexDefModel(int *isec1, int vlistID, int varID)
 {
-  int modelID = (vlistInqModel(vlistID) != CDI_UNDEFID) ? vlistInqModel(vlistID) : vlistInqVarModel(vlistID, varID);
+  int modelID;
+
+  if ( vlistInqModel(vlistID) != CDI_UNDEFID )
+    modelID = vlistInqModel(vlistID);
+  else
+    modelID = vlistInqVarModel(vlistID, varID);
+
   if ( modelID != CDI_UNDEFID )
     ISEC1_ModelID = modelInqGribID(modelID);
 }
@@ -46907,7 +46505,9 @@ static
 void cgribexDefParam(int *isec1, int param)
 {
   int pdis, pcat, pnum;
+
   cdiDecodeParam(param, &pnum, &pcat, &pdis);
+
   if ( pnum < 0 ) pnum = -pnum;
 
   static bool lwarn_pdis = true;
@@ -46935,8 +46535,10 @@ 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 ip1 = 0, ip2 = 0;
 
   cdiDecodeDate(rdate, &year, &month, &day);
   cdiDecodeTime(rtime, &hour, &minute, &second);
@@ -46948,8 +46550,6 @@ int cgribexDefTimerange(int tsteptype, int factor, int calendar,
 
   (void) julday_sub(julday1, secofday1, julday2, secofday2, &days, &secs);
 
-  int timerange = -1;
-  int ip1 = 0, ip2 = 0;
   if ( !(int)(fmod(days*86400.0 + secs, factor)) )
     {
       int ip = (int) ((days*86400.0 + secs)/factor);
@@ -46979,10 +46579,13 @@ static
 int cgribexDefDateTime(int *isec1, int timeunit, int date, int time)
 {
   int year, month, day, hour, minute, second;
+  int century = 0;
+  int factor = 1;
+
   cdiDecodeDate(date, &year, &month, &day);
   cdiDecodeTime(time, &hour, &minute, &second);
 
-  int century =  year / 100;
+  century =  year / 100;
 
   ISEC1_Year = year - century*100;
 
@@ -47008,7 +46611,6 @@ int cgribexDefDateTime(int *isec1, int timeunit, int date, int time)
 
   ISEC1_Century = century;
 
-  int factor = 1;
   switch (timeunit)
     {
     case TUNIT_MINUTE:    factor =    60; ISEC1_TimeUnit = ISEC1_TABLE4_MINUTE;    break;
@@ -47107,8 +46709,8 @@ void cgribexDefTime(int *isec1, int vdate, int vtime, int tsteptype, int numavg,
 static
 void cgribexDefGrid(int *isec1, int *isec2, double *fsec2, int *isec4, int gridID)
 {
-  bool lrotated = false;
   bool lcurvi = false;
+  static bool lwarning = true;
 
   memset(isec2, 0, 16*sizeof(int));
 
@@ -47146,39 +46748,16 @@ void cgribexDefGrid(int *isec1, int *isec2, double *fsec2, int *isec4, int gridI
     }
   else if ( gridtype == GRID_CURVILINEAR )
     {
-      int projID = gridInqProj(gridID);
-      if ( projID != CDI_UNDEFID && gridInqType(projID) == GRID_PROJECTION )
-        {
-          gridID = projID;
-          gridtype = GRID_PROJECTION;
-        }
-      else
-        {
-          static bool lwarning = true;
-          if ( lwarning && gridInqSize(gridID) > 1 )
-            {
-              lwarning = false;
-              Warning("Curvilinear grid is unsupported in GRIB1! Created wrong Grid Description Section!");
-            }
-          lcurvi = true;
-          gridtype = GRID_LONLAT;
-        }
-    }
-
-  if ( gridtype == GRID_PROJECTION )
-    {
-      if ( gridInqProjType(gridID) == CDI_PROJ_RLL )
-        {
-          gridtype = GRID_LONLAT;
-          lrotated = true;
-        }
-      else if ( gridInqProjType(gridID) == CDI_PROJ_LCC )
-        {
-          gridtype = GRID_LCC;
-        }
+      if ( lwarning && gridInqSize(gridID) > 1 )
+	{
+	  lwarning = false;
+	  Warning("Curvilinear grids are unsupported in GRIB1! Created wrong Grid Description Section!");
+	}
+      gridtype = GRID_LONLAT;
+      lcurvi = true;
     }
 
-  ISEC2_Reduced  = false;
+  ISEC2_Reduced  = FALSE;
   ISEC2_ScanFlag = 0;
 
   switch (gridtype)
@@ -47190,10 +46769,11 @@ void cgribexDefGrid(int *isec1, int *isec2, double *fsec2, int *isec4, int gridI
       {
 	double xfirst = 0, xlast = 0, xinc = 0;
 	double yfirst = 0, ylast = 0, yinc = 0;
+        bool isRotated = gridIsRotated(gridID);
 
 	if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_GAUSSIAN_REDUCED )
           ISEC2_GridType = GRIB1_GTYPE_GAUSSIAN;
-        else if ( gridtype == GRID_LONLAT && lrotated )
+        else if ( gridtype == GRID_LONLAT && isRotated )
 	  ISEC2_GridType = GRIB1_GTYPE_LATLON_ROT;
 	else
 	  ISEC2_GridType = GRIB1_GTYPE_LATLON;
@@ -47203,25 +46783,31 @@ void cgribexDefGrid(int *isec1, int *isec2, double *fsec2, int *isec4, int gridI
 
 	if ( gridtype == GRID_GAUSSIAN_REDUCED )
 	  {
-	    ISEC2_Reduced = true;
+	    ISEC2_Reduced = TRUE;
 	    nlon = 0;
 	    gridInqRowlon(gridID, ISEC2_RowLonPtr);
 	  }
 	else
 	  {
-	    if ( nlon == 0 ) nlon = 1;
+	    if ( nlon == 0 )
+	      {
+		nlon = 1;
+	      }
 	    else
 	      {
-		xfirst = gridInqXval(gridID, 0);
+		xfirst = gridInqXval(gridID,      0);
                 xlast  = gridInqXval(gridID, (lcurvi ? nlon*nlat : nlon) - 1);
-		xinc   = fabs(gridInqXinc(gridID));
+		xinc   = gridInqXinc(gridID);
 	      }
 	  }
 
-	if ( nlat == 0 ) nlat = 1;
+	if ( nlat == 0 )
+	  {
+	    nlat = 1;
+	  }
 	else
 	  {
-	    yfirst = gridInqYval(gridID, 0);
+	    yfirst = gridInqYval(gridID,      0);
             ylast  = gridInqYval(gridID, (lcurvi ? nlon*nlat : nlat) - 1);
 	    yinc   = fabs(gridInqYinc(gridID));
 	  }
@@ -47252,6 +46838,7 @@ void cgribexDefGrid(int *isec1, int *isec2, double *fsec2, int *isec4, int gridI
 	else
 	  {
 	    ISEC2_LatIncr = (int)lround(yinc*1000);
+	    if ( ISEC2_LatIncr < 0 ) ISEC2_LatIncr = -ISEC2_LatIncr;
 	  }
 
 	if ( ISEC2_NumLon > 1 && ISEC2_NumLat == 1 )
@@ -47260,64 +46847,51 @@ void cgribexDefGrid(int *isec1, int *isec2, double *fsec2, int *isec4, int gridI
 	if ( ISEC2_NumLon == 1 && ISEC2_NumLat > 1 )
 	  if ( ISEC2_LonIncr == 0 && ISEC2_LatIncr != 0 ) ISEC2_LonIncr = ISEC2_LatIncr;
 
-        ISEC2_ResFlag = 0;
-        if ( ISEC2_LatIncr && ISEC2_LonIncr )   gribbyte_set_bit(&ISEC2_ResFlag, 1);
-        if ( gridInqUvRelativeToGrid(gridID) )  gribbyte_set_bit(&ISEC2_ResFlag, 5);
-
-	if ( lrotated )
-          {
-            double xpole = 0, ypole = 0, angle = 0;
-            gridInqParamRLL(gridID, &xpole, &ypole, &angle);
+        ISEC2_ResFlag = ( ISEC2_LatIncr == 0 || ISEC2_LonIncr == 0 ) ? 0 : 128;
 
-	    ISEC2_LatSP = - (int)lround(ypole * 1000);
-	    ISEC2_LonSP =   (int)lround((xpole + 180) * 1000);
+	if ( isRotated )
+	  {
+	    ISEC2_LatSP = - (int)lround(gridInqYpole(gridID) * 1000);
+	    ISEC2_LonSP =   (int)lround((gridInqXpole(gridID) + 180) * 1000);
+            double angle = gridInqAngle(gridID);
             if ( fabs(angle) > 0 ) angle = -angle;
             FSEC2_RotAngle = angle;
-          }
+	  }
+
+	/* East -> West */
+	if ( ISEC2_LastLon < ISEC2_FirstLon ) ISEC2_ScanFlag += 128;
 
-        ISEC2_ScanFlag = 0;
-	if ( ISEC2_LastLon < ISEC2_FirstLon ) gribbyte_set_bit(&ISEC2_ScanFlag, 1); // East -> West
-	if ( ISEC2_LastLat > ISEC2_FirstLat ) gribbyte_set_bit(&ISEC2_ScanFlag, 2); // South -> North
+	/* South -> North */
+	if ( ISEC2_LastLat > ISEC2_FirstLat ) ISEC2_ScanFlag += 64;
 
 	break;
       }
     case GRID_LCC:
       {
-	int xsize = gridInqXsize(gridID);
-        int ysize = gridInqYsize(gridID);
+	double originLon = 0.0, originLat = 0.0, lonParY = 0.0,
+          lat1 = 0.0, lat2 = 0.0, xincm = 0.0, yincm = 0.0;
+	int projflag = 0, scanflag = 0;
 
-        double lon_0, lat_0, lat_1, lat_2, a, rf, xval_0, yval_0, x_0, y_0;
-	gridInqParamLCC(gridID, grid_missval, &lon_0, &lat_0, &lat_1, &lat_2, &a, &rf, &xval_0, &yval_0, &x_0, &y_0);
-	gridVerifyGribParamLCC(grid_missval, &lon_0, &lat_0, &lat_1, &lat_2, &a, &rf, &xval_0, &yval_0, &x_0, &y_0);
-        bool lsouth = (lat_1 < 0);
-        if ( lsouth ) { lat_1 = -lat_2; lat_2 = -lat_2; }
+	int xsize = gridInqXsize(gridID),
+          ysize = gridInqYsize(gridID);
 
-        double xinc = gridInqXinc(gridID);
-        double yinc = gridInqYinc(gridID);
+	gridInqLCC(gridID, &originLon, &originLat, &lonParY, &lat1, &lat2, &xincm, &yincm,
+		   &projflag, &scanflag);
 
 	ISEC2_GridType = GRIB1_GTYPE_LCC;
 	ISEC2_NumLon   = xsize;
 	ISEC2_NumLat   = ysize;
-	ISEC2_FirstLon       = (int)lround(xval_0 * 1000);
-	ISEC2_FirstLat       = (int)lround(yval_0 * 1000);
-	ISEC2_Lambert_Lov    = (int)lround(lon_0 * 1000);
-	ISEC2_Lambert_LatS1  = (int)lround(lat_1 * 1000);
-	ISEC2_Lambert_LatS2  = (int)lround(lat_2 * 1000);
-	ISEC2_Lambert_dx     = (int)lround(xinc);
-	ISEC2_Lambert_dy     = (int)lround(yinc);
+	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_LonSP  = 0;
-	ISEC2_Lambert_ProjFlag = 0;
-        if ( lsouth ) gribbyte_set_bit(&ISEC2_Lambert_ProjFlag, 1);
-
-        bool earthIsOblate = (IS_EQUAL(a, 6378160.) && IS_EQUAL(rf, 297.));
-        ISEC2_ResFlag = 0;
-        if ( ISEC2_Lambert_dx && ISEC2_Lambert_dy ) gribbyte_set_bit(&ISEC2_ResFlag, 1);
-        if ( earthIsOblate )                        gribbyte_set_bit(&ISEC2_ResFlag, 2);
-        if ( gridInqUvRelativeToGrid(gridID) )      gribbyte_set_bit(&ISEC2_ResFlag, 5);
-
-	ISEC2_ScanFlag = 0;
-        gribbyte_set_bit(&ISEC2_ScanFlag, 2); // South -> North
+	ISEC2_Lambert_ProjFlag = projflag;
+	ISEC2_ScanFlag = scanflag;
 
 	break;
       }
@@ -47348,12 +46922,10 @@ void cgribexDefGrid(int *isec1, int *isec2, double *fsec2, int *isec4, int gridI
     case GRID_GME:
       {
 	ISEC2_GridType   = GRIB1_GTYPE_GME;
-        int nd = 0, ni = 0, ni2 = 0, ni3 = 0;
-        gridInqParamGME(gridID, &nd, &ni, &ni2, &ni3);
-	ISEC2_GME_ND     = nd;
-	ISEC2_GME_NI     = ni;
-	ISEC2_GME_NI2    = ni2;
-	ISEC2_GME_NI3    = ni3;
+	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;
@@ -47368,33 +46940,13 @@ void cgribexDefGrid(int *isec1, int *isec2, double *fsec2, int *isec4, int gridI
 	break;
       }
     }
-
-
-  if ( cdiGribChangeModeUvRelativeToGrid.active )
-    {
-      // this will overrule/change the UvRelativeToGrid flag;
-      // typically when the wind is rotated with respect to north pole
-      bool uvRelativeToGrid = gribbyte_get_bit(ISEC2_ResFlag, 5);
-      if      ( uvRelativeToGrid && !cdiGribChangeModeUvRelativeToGrid.mode )
-        gribbyte_clear_bit(&ISEC2_ResFlag, 5);
-      else if ( !uvRelativeToGrid && cdiGribChangeModeUvRelativeToGrid.mode )
-        gribbyte_set_bit(&ISEC2_ResFlag, 5);
-    }
-}
-
-static
-void isec1DefLevel(int *isec1, int leveltype, int level1, int level2)
-{
-  ISEC1_LevelType = leveltype;
-  ISEC1_Level1    = level1;
-  ISEC1_Level2    = level2;
 }
 
 static
 void cgribexDefLevel(int *isec1, int *isec2, double *fsec2, int zaxisID, int levelID)
 {
-  char units[CDI_MAX_NAME];
   static bool lwarning_vct = true;
+  double level;
 
   int zaxistype = zaxisInqType(zaxisID);
   int ltype = zaxisInqLtype(zaxisID);
@@ -47402,7 +46954,8 @@ void cgribexDefLevel(int *isec1, int *isec2, double *fsec2, int zaxisID, int lev
   if ( zaxistype == ZAXIS_GENERIC && ltype == 0 )
     {
       Message("Changed zaxis type from %s to %s",
-	      zaxisNamePtr(zaxistype), zaxisNamePtr(ZAXIS_PRESSURE));
+	      zaxisNamePtr(zaxistype),
+	      zaxisNamePtr(ZAXIS_PRESSURE));
       zaxistype = ZAXIS_PRESSURE;
       zaxisChangeType(zaxisID, zaxistype);
       zaxisDefUnits(zaxisID, "Pa");
@@ -47420,7 +46973,9 @@ void cgribexDefLevel(int *isec1, int *isec2, double *fsec2, int zaxisID, int lev
     case ZAXIS_DEPTH_BELOW_SEA:
     case ZAXIS_ISENTROPIC:
       {
-        isec1DefLevel(isec1, grib_ltype, (int)(zaxisInqLevel(zaxisID, levelID)), 0);
+        ISEC1_LevelType = grib_ltype;
+	ISEC1_Level1    = (int) (zaxisInqLevel(zaxisID, levelID));
+	ISEC1_Level2    = 0;
 	break;
       }
     case ZAXIS_CLOUD_BASE:
@@ -47430,17 +46985,26 @@ void cgribexDefLevel(int *isec1, int *isec2, double *fsec2, int zaxisID, int lev
     case ZAXIS_SEA_BOTTOM:
     case ZAXIS_ATMOSPHERE:
       {
-        isec1DefLevel(isec1, grib_ltype, 0, 0);
+        ISEC1_LevelType = grib_ltype;
+	ISEC1_Level1    = 0;
+	ISEC1_Level2    = 0;
 	break;
       }
     case ZAXIS_HYBRID:
     case ZAXIS_HYBRID_HALF:
       {
 	if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
-          isec1DefLevel(isec1, GRIB1_LTYPE_HYBRID_LAYER, (int)(zaxisInqLbound(zaxisID, levelID)),
-                        (int)(zaxisInqUbound(zaxisID, levelID)));
+	  {
+	    ISEC1_LevelType = GRIB1_LTYPE_HYBRID_LAYER;
+	    ISEC1_Level1    = (int) (zaxisInqLbound(zaxisID, levelID));
+	    ISEC1_Level2    = (int) (zaxisInqUbound(zaxisID, levelID));
+	  }
 	else
-          isec1DefLevel(isec1, GRIB1_LTYPE_HYBRID, (int)(zaxisInqLevel(zaxisID, levelID)), 0);
+	  {
+	    ISEC1_LevelType = GRIB1_LTYPE_HYBRID;
+	    ISEC1_Level1    = (int) (zaxisInqLevel(zaxisID, levelID));
+	    ISEC1_Level2    = 0;
+	  }
 
 	int vctsize = zaxisInqVctSize(zaxisID);
 	if ( vctsize > 255 )
@@ -47461,25 +47025,33 @@ void cgribexDefLevel(int *isec1, int *isec2, double *fsec2, int zaxisID, int lev
       }
     case ZAXIS_PRESSURE:
       {
-	double level = zaxisInqLevel(zaxisID, levelID);
-	if ( level < 0 ) Warning("Pressure level of %f Pa is below zero!", level);
+	level = zaxisInqLevel(zaxisID, levelID);
+	if ( level < 0 )
+	  Warning("Pressure level of %f Pa is below zero!", level);
 
+	char units[128];
 	zaxisInqUnits(zaxisID, units);
 	if ( (units[0] != 'P') | (units[1] != 'a') ) level *= 100;
 
 	double dum;
 	if ( level < 32768 && (level < 100 || modf(level/100, &dum) > 0) )
-          grib_ltype = GRIB1_LTYPE_ISOBARIC_PA;
+	  {
+	    grib_ltype = GRIB1_LTYPE_99;
+	  }
 	else
-          level = level/100;
-
-        isec1DefLevel(isec1, grib_ltype, (int) level, 0);
+	  {
+	    level = level/100;
+	  }
+        ISEC1_LevelType = grib_ltype;
+        ISEC1_Level1    = (int) level;
+        ISEC1_Level2    = 0;
 	break;
       }
     case ZAXIS_HEIGHT:
       {
-	double level = zaxisInqLevel(zaxisID, levelID);
+	level = zaxisInqLevel(zaxisID, levelID);
 
+	char units[128];
 	zaxisInqUnits(zaxisID, units);
         if ( units[1] == 'm' && !units[2] )
           {
@@ -47488,39 +47060,61 @@ void cgribexDefLevel(int *isec1, int *isec2, double *fsec2, int zaxisID, int lev
             else if ( units[0] == 'k' ) level *= 1000;
           }
 
-        isec1DefLevel(isec1, grib_ltype, (int) level, 0);
+	ISEC1_LevelType = grib_ltype;
+	ISEC1_Level1    = (int) level;
+	ISEC1_Level2    = 0;
+
 	break;
       }
     case ZAXIS_SIGMA:
       {
 	if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
-          isec1DefLevel(isec1, GRIB1_LTYPE_SIGMA_LAYER, (int)(zaxisInqLbound(zaxisID, levelID)),
-                        (int)(zaxisInqUbound(zaxisID, levelID)));
+	  {
+	    ISEC1_LevelType = GRIB1_LTYPE_SIGMA_LAYER;
+	    ISEC1_Level1    = (int) zaxisInqLbound(zaxisID, levelID);
+	    ISEC1_Level2    = (int) zaxisInqUbound(zaxisID, levelID);
+	  }
 	else
-          isec1DefLevel(isec1, GRIB1_LTYPE_SIGMA, (int)(zaxisInqLevel(zaxisID, levelID)), 0);
+	  {
+            ISEC1_LevelType = GRIB1_LTYPE_SIGMA;
+            ISEC1_Level1    = (int) zaxisInqLevel(zaxisID, levelID);
+            ISEC1_Level2    = 0;
+          }
 
 	break;
       }
     case ZAXIS_DEPTH_BELOW_LAND:
       {
+	char units[128];
 	zaxisInqUnits(zaxisID, units);
 
-	double factor = 100; // default: meter
+	double factor;
         if      ( units[0] == 'm' && units[1] == 'm' ) factor =   0.1;
         else if ( units[0] == 'c' && units[1] == 'm' ) factor =   1;
         else if ( units[0] == 'd' && units[1] == 'm' ) factor =  10;
+        else                                           factor = 100; // meter
 
 	if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
-          isec1DefLevel(isec1, GRIB1_LTYPE_LANDDEPTH_LAYER, (int) (factor*zaxisInqLbound(zaxisID, levelID)),
-                        (int) (factor*zaxisInqUbound(zaxisID, levelID)));
+	  {
+	    ISEC1_LevelType = GRIB1_LTYPE_LANDDEPTH_LAYER;
+	    ISEC1_Level1    = (int) (factor*zaxisInqLbound(zaxisID, levelID));
+	    ISEC1_Level2    = (int) (factor*zaxisInqUbound(zaxisID, levelID));
+	  }
 	else
-          isec1DefLevel(isec1, GRIB1_LTYPE_LANDDEPTH, (int) (factor*zaxisInqLevel(zaxisID, levelID)), 0);
+	  {
+	    ISEC1_LevelType = GRIB1_LTYPE_LANDDEPTH;
+	    ISEC1_Level1    = (int) (factor*zaxisInqLevel(zaxisID, levelID));
+	    ISEC1_Level2    = 0;
+	  }
 
 	break;
       }
     case ZAXIS_GENERIC:
       {
-        isec1DefLevel(isec1, ltype, (int)(zaxisInqLevel(zaxisID, levelID)), 0);
+	ISEC1_LevelType = ltype;
+	ISEC1_Level1    = (int) zaxisInqLevel(zaxisID, levelID);
+	ISEC1_Level2    = 0;
+
 	break;
       }
     default:
@@ -47586,17 +47180,21 @@ size_t cgribexEncode(int memtype, int varID, int levelID, int vlistID, int gridI
 		     int vdate, int vtime, int tsteptype, int numavg,
 		     long datasize, const void *data, int nmiss, void *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;
 
   memset(isec1, 0, 256*sizeof(int));
   fsec2[0] = 0; fsec2[1] = 0;
   fsec2f[0] = 0; fsec2f[1] = 0;
 
-  int gribsize = (int)(gribbuffersize / sizeof(int));
-  int param    = vlistInqVarParam(vlistID, varID);
+  gribsize = (int)(gribbuffersize / sizeof(int));
+  param    = vlistInqVarParam(vlistID, varID);
 
   cgribexDefaultSec0(isec0);
   cgribexDefaultSec1(isec1);
@@ -47605,7 +47203,7 @@ size_t cgribexEncode(int memtype, int varID, int levelID, int vlistID, int gridI
   cgribexDefInstitut(isec1, vlistID, varID);
   cgribexDefModel(isec1, vlistID, varID);
 
-  int datatype = vlistInqVarDatatype(vlistID, varID);
+  datatype = vlistInqVarDatatype(vlistID, varID);
 
   cgribexDefParam(isec1, param);
   cgribexDefTime(isec1, vdate, vtime, tsteptype, numavg, vlistInqTaxis(vlistID));
@@ -47650,69 +47248,27 @@ size_t cgribexEncode(int memtype, int varID, int levelID, int vlistID, int gridI
 
   if ( iret ) Error("Problem during GRIB encode (errno = %d)!", iret);
 
-  size_t nbytes = (size_t)iword * sizeof(int);
+  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:
+ */
+#ifndef STREAM_FCOMMON_H
+#define STREAM_FCOMMON_H
 
+#ifndef  _CDI_INT_H
+#endif
 
-typedef struct
-{
-  void *gribbuffer;
-  size_t gribbuffersize;
-  unsigned char *pds;
-  unsigned char *gds;
-  unsigned char *bms;
-  unsigned char *bds;
-} cgribex_handle;
-
-
-int grib1Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **pdsp,
-		  unsigned char **gdsp, unsigned char **bmsp, unsigned char **bdsp, long *gribrecsize);
-
-void *cgribex_handle_new_from_meassage(void *gribbuffer, size_t gribbuffersize)
-{
-  cgribex_handle *gh = (cgribex_handle*) Malloc(sizeof(cgribex_handle));
-  gh->gribbuffer = NULL;
-  gh->gribbuffersize = 0;
-  gh->pds = NULL;
-
-  if ( gribbuffersize && gribbuffer )
-    {
-      unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
-      long gribrecsize;
-      int status = grib1Sections((unsigned char *)gribbuffer, (long)gribbuffersize, &pds, &gds, &bms, &bds, &gribrecsize);
-      if ( status >= 0 )
-        {
-          gh->gribbuffer = gribbuffer;
-          gh->gribbuffersize = gribbuffersize;
-          gh->pds = pds;
-          gh->gds = gds;
-          gh->bms = bms;
-          gh->bds = bds;
-        }
-    }
-
-  return (void*)gh;
-}
-
-
-void cgribex_handle_delete(void *gh)
-{
-  if ( gh ) Free(gh);
-}
-
-
-void cgribexChangeParameterIdentification(void *gh, int code, int ltype, int lev)
-{
-  if ( !gh ) return;
-
-  unsigned char *pds = ((cgribex_handle*)gh)->pds;
-  if ( !pds ) return;
-
-  pds[8]  = (unsigned char) code;
-  pds[9]  = (unsigned char) ltype;
-  pds[10] = (unsigned char) lev;
-}
+void streamFCopyRecord(stream_t *streamptr2, stream_t *streamptr1,
+                       const char *container_name);
 
 #endif
 /*
@@ -47734,8 +47290,15 @@ void cgribexChangeParameterIdentification(void *gh, int code, int ltype, int lev
 
 
 
+#undef  UNDEFID
+#define UNDEFID  CDI_UNDEFID
+
+#define SINGLE_PRECISION  4
+#define DOUBLE_PRECISION  8
+
 #if defined (HAVE_LIBEXTRA)
 
+
 typedef struct {
   int param;
   int level;
@@ -47747,24 +47310,36 @@ int extInqDatatype(int prec, int number)
   int datatype;
 
   if ( number == 2 )
-    datatype = (prec == EXSE_DOUBLE_PRECISION) ? CDI_DATATYPE_CPX64 : CDI_DATATYPE_CPX32;
+    {
+      if ( prec == DOUBLE_PRECISION ) datatype = DATATYPE_CPX64;
+      else                            datatype = DATATYPE_CPX32;
+    }
   else
-    datatype = (prec == EXSE_DOUBLE_PRECISION) ? CDI_DATATYPE_FLT64 : CDI_DATATYPE_FLT32;
+    {
+      if ( prec == DOUBLE_PRECISION ) datatype = DATATYPE_FLT64;
+      else                            datatype = DATATYPE_FLT32;
+    }
 
-  return datatype;
+  return (datatype);
 }
 
 static
 void extDefDatatype(int datatype, int *prec, int *number)
 {
 
-  if ( datatype != CDI_DATATYPE_FLT32 && datatype != CDI_DATATYPE_FLT64 &&
-       datatype != CDI_DATATYPE_CPX32 && datatype != CDI_DATATYPE_CPX64 )
-    datatype = CDI_DATATYPE_FLT32;
+  if ( datatype != DATATYPE_FLT32 && datatype != DATATYPE_FLT64 &&
+       datatype != DATATYPE_CPX32 && datatype != DATATYPE_CPX64 )
+    datatype = DATATYPE_FLT32;
 
-  *number = (datatype == CDI_DATATYPE_CPX32 || datatype == CDI_DATATYPE_CPX64) ? 2 : 1;
+  if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
+    *number = 2;
+  else
+    *number = 1;
 
-  *prec = (datatype == CDI_DATATYPE_FLT64 || datatype == CDI_DATATYPE_CPX64) ? EXSE_DOUBLE_PRECISION : EXSE_SINGLE_PRECISION;
+  if ( datatype == DATATYPE_FLT64 || datatype == DATATYPE_CPX64 )
+    *prec = DOUBLE_PRECISION;
+  else 
+    *prec = SINGLE_PRECISION;
 }
 
 /* not used
@@ -47785,7 +47360,7 @@ int extInqRecord(stream_t *streamptr, int *varID, int *levelID)
   *levelID = -1;
 
   status = extRead(fileID, extp);
-  if ( status != 0 ) return 0;
+  if ( status != 0 ) return (0);
 
   extInqHeader(extp, header);
 
@@ -47794,46 +47369,55 @@ int extInqRecord(stream_t *streamptr, int *varID, int *levelID)
 
   *varID = vlistInqVarID(vlistID, icode);
 
-  if ( *varID == CDI_UNDEFID ) Error("Code %d undefined", icode);
+  if ( *varID == UNDEFID ) Error("Code %d undefined", icode);
 
   zaxisID = vlistInqVarZaxis(vlistID, *varID);
 
   *levelID = zaxisInqLevelID(zaxisID, (double) ilevel);
 
-  return 1;
+  return (1);
 }
 */
 
 void extReadRecord(stream_t *streamptr, double *data, int *nmiss)
 {
-  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];
-  int varID   = streamptr->tsteps[tsID].records[recID].varID;
-  off_t recpos = streamptr->tsteps[tsID].records[recID].position;
+  int vlistID, fileID;
+  int status;
+  int recID, vrecID, tsID;
+  off_t recpos;
+  int header[4];
+  int varID, gridID;
+  int i, size;
+  double missval;
+  void *extp = 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);
 
-  void *extp = streamptr->record->exsep;
-  int status = extRead(fileID, extp);
-  if ( status != 0 ) Error("Failed to read EXTRA record");
+  status = extRead(fileID, extp);
+  if ( status != 0 )
+    Error("Failed to read EXTRA record");
 
-  int header[4];
   extInqHeader(extp, header);
   extInqDataDP(extp, data);
 
-  double missval = vlistInqVarMissval(vlistID, varID);
-  int gridID  = vlistInqVarGrid(vlistID, varID);
-  int size    = gridInqSize(gridID);
+  missval = vlistInqVarMissval(vlistID, varID);
+  gridID  = vlistInqVarGrid(vlistID, varID);
+  size    = gridInqSize(gridID);
 
   streamptr->numvals += size;
 
   *nmiss = 0;
   if ( vlistInqVarNumber(vlistID, varID) == CDI_REAL )
     {
-      for ( int i = 0; i < size; i++ )
+      for ( i = 0; i < size; i++ )
 	if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
 	  {
 	    data[i] = missval;
@@ -47842,7 +47426,7 @@ void extReadRecord(stream_t *streamptr, double *data, int *nmiss)
     }
   else
     {
-      for ( int i = 0; i < 2*size; i+=2 )
+      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;
@@ -47860,18 +47444,21 @@ void extCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
 
 void extDefRecord(stream_t *streamptr)
 {
+  int gridID;
+  int header[4];
   int pdis, pcat, pnum;
-  cdiDecodeParam(streamptr->record->param, &pnum, &pcat, &pdis);
+  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
 
-  int header[4];
+  gridID   = streamptr->record->gridID;
+
+  cdiDecodeParam(streamptr->record->param, &pnum, &pcat, &pdis);
   header[0] = streamptr->record->date;
   header[1] = pnum;
   header[2] = streamptr->record->level;
-  int gridID = streamptr->record->gridID;
   header[3] = gridInqSize(gridID);
 
-  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
   extDefDatatype(streamptr->record->prec, &extp->prec, &extp->number);
+
   extDefHeader(extp, header);
 }
 
@@ -47902,9 +47489,11 @@ void extAddRecord(stream_t *streamptr, int param, int level, int xysize,
   grid_t *grid = (grid_t *)Malloc(sizeof (*grid));
   grid_init(grid);
   cdiGridTypeInit(grid, GRID_GENERIC, xysize);
-  grid->x.size = xysize;
-  grid->y.size = 0;
-  struct addIfNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 0);
+  grid->xsize = xysize;
+  grid->ysize = 0;
+  grid->xvals = NULL;
+  grid->yvals = NULL;
+  struct addIffNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 0);
   int gridID = gridAdded.Id;
   if (!gridAdded.isNew) Free(grid);
   /*
@@ -47924,36 +47513,46 @@ void extAddRecord(stream_t *streamptr, int param, int level, int xysize,
   streamptr->nrecs++;
 
   if ( CDI_Debug )
-    Message("varID = %d gridID = %d levelID = %d", varID, gridID, levelID);
+    Message("varID = %d gridID = %d levelID = %d",
+	    varID, gridID, levelID);
 }
 
 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 datetime0 = { LONG_MIN, LONG_MIN };
+  int tsID;
   int varID;
-  off_t recpos = 0;
   long recsize;
-  int recID;
+  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 tsID  = tstepsNewEntry(streamptr);
-  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
+  tsID  = tstepsNewEntry(streamptr);
+  taxis = &streamptr->tsteps[tsID].taxis;
 
   if ( tsID != 0 )
     Error("Internal problem! tstepsNewEntry returns %d", tsID);
 
-  int fileID = streamptr->fileID;
+  fileID = streamptr->fileID;
 
-  int nrecs = 0;
-  while ( true )
+  nrecs = 0;
+  while ( TRUE )
     {
       recpos = fileGetPos(fileID);
-      int status = extRead(fileID, extp);
+      status = extRead(fileID, extp);
       if ( status != 0 )
 	{
 	  streamptr->ntsteps = 1;
@@ -47963,13 +47562,13 @@ void extScanTimestep1(stream_t *streamptr)
 
       extInqHeader(extp, header);
 
-      int vdate   = header[0];
-      int vtime   = 0;
-      int rcode   = header[1];
-      int rlevel  = header[2];
-      int rxysize = header[3];
+      vdate   = header[0];
+      vtime   = 0;
+      rcode   = header[1];
+      rlevel  = header[2];
+      rxysize = header[3];
 
-      int param = cdiEncodeParam(rcode, 255, 255);
+      param = cdiEncodeParam(rcode, 255, 255);
 
       if ( nrecs == 0 )
 	{
@@ -48005,17 +47604,17 @@ void extScanTimestep1(stream_t *streamptr)
 
   cdi_generate_vars(streamptr);
 
-  int taxisID = taxisCreate(TAXIS_ABSOLUTE);
+  taxisID = taxisCreate(TAXIS_ABSOLUTE);
   taxis->type  = TAXIS_ABSOLUTE;
   taxis->vdate = (int)datetime0.date;
   taxis->vtime = (int)datetime0.time;
 
-  int vlistID = streamptr->vlistID;
+  vlistID = streamptr->vlistID;
   vlistDefTaxis(vlistID, taxisID);
 
   vlist_check_contents(vlistID);
 
-  int nrecords = streamptr->tsteps[0].nallrecs;
+  nrecords = streamptr->tsteps[0].nallrecs;
   if ( nrecords < streamptr->tsteps[0].recordSize )
     {
       streamptr->tsteps[0].recordSize = nrecords;
@@ -48034,7 +47633,7 @@ void extScanTimestep1(stream_t *streamptr)
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
-      streamptr->tsteps[tsID-1].next   = true;
+      streamptr->tsteps[tsID-1].next   = TRUE;
       streamptr->tsteps[tsID].position = recpos;
     }
 
@@ -48055,33 +47654,43 @@ 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;
   void *extp = streamptr->record->exsep;
 
   streamptr->curTsID = 1;
 
-  int fileID  = streamptr->fileID;
-  int vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
+  vlistID = streamptr->vlistID;
 
-  int tsID = streamptr->rtsteps;
+  tsID = streamptr->rtsteps;
   if ( tsID != 1 )
     Error("Internal problem! unexpected timestep %d", tsID+1);
 
-  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
+  taxis = &streamptr->tsteps[tsID].taxis;
 
   fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
   cdi_create_records(streamptr, tsID);
 
-  int nrecords = streamptr->tsteps[0].nallrecs;
+  nrecords = streamptr->tsteps[0].nallrecs;
   streamptr->tsteps[1].recIDs = (int *) Malloc((size_t)nrecords * sizeof (int));
   streamptr->tsteps[1].nrecs = 0;
-  for ( int recID = 0; recID < nrecords; recID++ )
+  for ( recID = 0; recID < nrecords; recID++ )
     streamptr->tsteps[1].recIDs[recID] = -1;
 
-  for ( int recID = 0; recID < nrecords; recID++ )
+  for ( recID = 0; recID < nrecords; recID++ )
     {
       varID = streamptr->tsteps[0].records[recID].varID;
       streamptr->tsteps[tsID].records[recID].position =
@@ -48090,10 +47699,10 @@ int extScanTimestep2(stream_t *streamptr)
 	streamptr->tsteps[0].records[recID].size;
     }
 
-  for ( int rindex = 0; rindex <= nrecords; rindex++ )
+  for ( rindex = 0; rindex <= nrecords; rindex++ )
     {
       recpos = fileGetPos(fileID);
-      int status = extRead(fileID, extp);
+      status = extRead(fileID, extp);
       if ( status != 0 )
 	{
 	  streamptr->ntsteps = 2;
@@ -48103,13 +47712,13 @@ int extScanTimestep2(stream_t *streamptr)
 
       extInqHeader(extp, header);
 
-      int vdate  = header[0];
-      int vtime  = 0;
-      int rcode  = header[1];
-      int rlevel = header[2];
+      vdate  = header[0];
+      vtime  = 0;
+      rcode  = header[1];
+      rlevel = header[2];
       // rxysize = header[3];
 
-      int param = cdiEncodeParam(rcode, 255, 255);
+      param = cdiEncodeParam(rcode, 255, 255);
 
       if ( rindex == 0 )
 	{
@@ -48120,8 +47729,7 @@ int extScanTimestep2(stream_t *streamptr)
 
       compVar.param = param;
       compVar.level = rlevel;
-      bool nextstep = false;
-      int recID;
+      nextstep = FALSE;
       for ( recID = 0; recID < nrecords; recID++ )
 	{
 	  compVar0.param = streamptr->tsteps[tsID].records[recID].param;
@@ -48131,11 +47739,11 @@ int extScanTimestep2(stream_t *streamptr)
 	    {
 	      if ( streamptr->tsteps[tsID].records[recID].used )
 		{
-		  nextstep = true;
+		  nextstep = TRUE;
 		}
 	      else
 		{
-		  streamptr->tsteps[tsID].records[recID].used = true;
+		  streamptr->tsteps[tsID].records[recID].used = TRUE;
 		  streamptr->tsteps[tsID].recIDs[rindex] = recID;
 		}
 	      break;
@@ -48144,7 +47752,7 @@ int extScanTimestep2(stream_t *streamptr)
       if ( recID == nrecords )
 	{
 	  Warning("Code %d level %d not found at timestep %d", rcode, rlevel, tsID+1);
-	  return CDI_EUFSTRUCT;
+	  return (CDI_EUFSTRUCT);
 	}
 
       if ( nextstep ) break;
@@ -48163,14 +47771,14 @@ int extScanTimestep2(stream_t *streamptr)
 		  tsID, recID,
 		  streamptr->tsteps[tsID].records[recID].param, param,
 		  streamptr->tsteps[tsID].records[recID].ilevel, rlevel);
-	  return CDI_EUFSTRUCT;
+	  return (CDI_EUFSTRUCT);
 	}
 
       streamptr->tsteps[1].records[recID].position = recpos;
     }
 
-  int nrecs = 0;
-  for ( int recID = 0; recID < nrecords; recID++ )
+  nrecs = 0;
+  for ( recID = 0; recID < nrecords; recID++ )
     {
       if ( ! streamptr->tsteps[tsID].records[recID].used )
 	{
@@ -48192,36 +47800,44 @@ int extScanTimestep2(stream_t *streamptr)
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
-      streamptr->tsteps[tsID-1].next   = true;
+      streamptr->tsteps[tsID-1].next   = TRUE;
       streamptr->tsteps[tsID].position = recpos;
     }
 
-  return 0;
+  return (0);
 }
 
 
 int extInqContents(stream_t *streamptr)
 {
+  int fileID;
+  int status = 0;
+
+  fileID = streamptr->fileID;
+
   streamptr->curTsID = 0;
 
   extScanTimestep1(streamptr);
 
-  int status = 0;
   if ( streamptr->ntsteps == -1 ) status = extScanTimestep2(streamptr);
 
-  int fileID = streamptr->fileID;
   fileSetPos(fileID, 0, SEEK_SET);
 
-  return status;
+  return (status);
 }
 
 static
 long extScanTimestep(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;
   off_t recpos = 0;
   int recID;
-  int nrecs = 0;
+  int rindex, nrecs = 0;
   extcompvar_t compVar, compVar0;
   void *extp = streamptr->record->exsep;
   /*
@@ -48248,14 +47864,14 @@ long extScanTimestep(stream_t *streamptr)
       for ( recID = 0; recID < nrecs; recID++ )
 	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
 
-      int fileID = streamptr->fileID;
+      fileID = streamptr->fileID;
 
       fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-      for ( int rindex = 0; rindex <= nrecs; rindex++ )
+      for ( rindex = 0; rindex <= nrecs; rindex++ )
 	{
 	  recpos = fileGetPos(fileID);
-	  int status = extRead(fileID, extp);
+	  status = extRead(fileID, extp);
 	  if ( status != 0 )
 	    {
 	      streamptr->ntsteps = streamptr->rtsteps + 1;
@@ -48265,13 +47881,13 @@ long extScanTimestep(stream_t *streamptr)
 
 	  extInqHeader(extp, header);
 
-	  int vdate  = header[0];
-	  int vtime  = 0;
-	  int rcode  = header[1];
-	  int rlevel = header[2];
+	  vdate  = header[0];
+	  vtime  = 0;
+	  rcode  = header[1];
+	  rlevel = header[2];
 	  // rxysize = header[3];
 
-	  int param = cdiEncodeParam(rcode, 255, 255);
+	  param = cdiEncodeParam(rcode, 255, 255);
 
 	  // if ( rindex == nrecs ) break; gcc-4.5 internal compiler error
 	  if ( rindex == nrecs ) continue;
@@ -48313,7 +47929,7 @@ long extScanTimestep(stream_t *streamptr)
 	  if ( tsID != streamptr->rtsteps )
 	    Error("Internal error. tsID = %d", tsID);
 
-	  streamptr->tsteps[tsID-1].next   = true;
+	  streamptr->tsteps[tsID-1].next   = 1;
 	  streamptr->tsteps[tsID].position = recpos;
 	}
 
@@ -48327,54 +47943,131 @@ long extScanTimestep(stream_t *streamptr)
       streamptr->ntsteps = tsID;
     }
 
-  return streamptr->ntsteps;
+  return (streamptr->ntsteps);
 }
 
 
 int extInqTimestep(stream_t *streamptr, int tsID)
 {
+  int nrecs;
+  long ntsteps;
+
   if ( tsID == 0 && streamptr->rtsteps == 0 )
     Error("Call to cdiInqContents missing!");
 
   if ( CDI_Debug )
     Message("tsID = %d rtsteps = %d", tsID, streamptr->rtsteps);
 
-  long ntsteps = CDI_UNDEFID;
-  while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == CDI_UNDEFID )
+  ntsteps = UNDEFID;
+  while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == UNDEFID )
     ntsteps = extScanTimestep(streamptr);
 
-  int nrecs = 0;
-  if ( !(tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID) )
+  if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID )
+    {
+      nrecs = 0;
+    }
+  else
     {
       streamptr->curTsID = tsID;
       nrecs = streamptr->tsteps[tsID].nrecs;
     }
 
-  return nrecs;
+  return (nrecs);
 }
 
 
-void extReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, int *nmiss)
+void extReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
 {
-  if ( CDI_Debug ) Message("streamID = %d  varID = %d  levID = %d", streamptr->self, varID, levID);
+  int vlistID, fileID;
+  int levID, nlevs, gridID, gridsize;
+  off_t recpos, currentfilepos;
+  int header[4];
+  int tsid;
+  int recID;
+  int i;
+  double missval;
+  void *extp = streamptr->record->exsep;
+
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
+  /* NOTE: tiles are not supported here! */
+  nlevs    = streamptr->vars[varID].recordTable[0].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);
+
+  for (levID = 0; levID < nlevs; levID++)
+    {
+      /* NOTE: tiles are not supported here! */
+      recID = streamptr->vars[varID].recordTable[0].recordID[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);
+
+  *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)++;
+	  }
+    }
+}
+
+
+void extReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, int *nmiss)
+{
+  int vlistID, fileID;
+  int nlevs, gridID, gridsize;
+  off_t recpos, currentfilepos;
+  int header[4];
+  int tsid;
+  int recID;
+  int i;
+  double missval;
   void *extp = streamptr->record->exsep;
 
-  int vlistID  = streamptr->vlistID;
-  int fileID   = streamptr->fileID;
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   /* NOTE: tiles are not supported here! */
-  double missval = vlistInqVarMissval(vlistID, varID);
-  int gridsize = gridInqSize(vlistInqVarGrid(vlistID, varID));
-  int tsid     = streamptr->curTsID;
+  nlevs    = streamptr->vars[varID].recordTable[0].nlevs;
+  missval  = vlistInqVarMissval(vlistID, varID);
+  gridID   = vlistInqVarGrid(vlistID, varID);
+  gridsize = gridInqSize(gridID);
+  tsid     = streamptr->curTsID;
 
-  off_t currentfilepos = fileGetPos(fileID);
+  if ( CDI_Debug )
+    Message("nlevs = %d gridID = %d gridsize = %d",
+	     nlevs, gridID, gridsize);
+
+  currentfilepos = fileGetPos(fileID);
 
   /* NOTE: tiles are not supported here! */
-  int recID = streamptr->vars[varID].recordTable[0].recordID[levID];
-  off_t recpos = streamptr->tsteps[tsid].records[recID].position;
+  recID = streamptr->vars[varID].recordTable[0].recordID[levID];
+  recpos = streamptr->tsteps[tsid].records[recID].position;
   fileSetPos(fileID, recpos, SEEK_SET);
   extRead(fileID, extp);
-  int header[4];
   extInqHeader(extp, header);
   extInqDataDP(extp, data);
 
@@ -48383,7 +48076,7 @@ void extReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data,
   *nmiss = 0;
   if ( vlistInqVarNumber(vlistID, varID) == CDI_REAL )
     {
-      for ( int i = 0; i < gridsize; i++ )
+      for ( i = 0; i < gridsize; i++ )
 	if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
 	  {
 	    data[i] = missval;
@@ -48392,7 +48085,7 @@ void extReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data,
     }
   else
     {
-      for ( int i = 0; i < 2*gridsize; i+=2 )
+      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;
@@ -48402,58 +48095,125 @@ void extReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data,
 }
 
 
-void extReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
+void extWriteVarDP(stream_t *streamptr, int varID, const double *data)
 {
+  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);
 
-  int vlistID = streamptr->vlistID;
-  size_t gridsize = (size_t) gridInqSize(vlistInqVarGrid(vlistID, varID));
-  size_t nlevs    = (size_t) streamptr->vars[varID].recordTable[0].nlevs;
+  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);
+
+  cdiDecodeParam(vlistInqVarParam(vlistID, varID), &pnum, &pcat, &pdis);
+
+  header[0] = streamptr->tsteps[tsID].taxis.vdate;
+  header[1] = pnum;
+  header[3] = gridInqSize(gridID);
+
+  extDefDatatype(vlistInqVarDatatype(vlistID, varID), &extp->prec, &extp->number);
+
+  for ( levID = 0;  levID < nlevs; levID++ )
+    {
+      level = zaxisInqLevel(zaxisID, levID);
 
-  for ( size_t levID = 0; levID < nlevs; levID++)
-    extReadVarSliceDP(streamptr, varID, (int)levID, &data[levID*gridsize], nmiss);
+      header[2] = (int) level;
+      extDefHeader(extp, header);
+      extDefDataDP(extp, &data[levID*gridsize]);
+      extWrite(fileID, extp);
+    }
 }
 
 
 void extWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double *data)
 {
-  if ( CDI_Debug ) Message("streamID = %d  varID = %d  levID = %d", streamptr->self, varID, levID);
+  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;
 
-  int vlistID  = streamptr->vlistID;
-  int fileID   = streamptr->fileID;
-  int tsID     = streamptr->curTsID;
+  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);
 
-  int pdis, pcat, pnum;
   cdiDecodeParam(vlistInqVarParam(vlistID, varID), &pnum, &pcat, &pdis);
 
-  int header[4];
   header[0] = streamptr->tsteps[tsID].taxis.vdate;
   header[1] = pnum;
-  header[2] = (int)(zaxisInqLevel(vlistInqVarZaxis(vlistID, varID), levID));
-  header[3] = gridInqSize(vlistInqVarGrid(vlistID, varID));
+  header[2] = (int) level;
+  header[3] = gridInqSize(gridID);
 
-  extrec_t *extp = (extrec_t*) streamptr->record->exsep;
   extDefDatatype(vlistInqVarDatatype(vlistID, varID), &extp->prec, &extp->number);
-  extDefHeader(extp, header);
 
+  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:
+ */
+#include <stdlib.h>
 
-void extWriteVarDP(stream_t *streamptr, int varID, const double *data)
+
+
+void streamFCopyRecord(stream_t *streamptr2, stream_t *streamptr1, const char *container_name)
 {
-  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
+  int fileID1 = streamptr1->fileID;
+  int fileID2 = streamptr2->fileID;
 
-  int vlistID = streamptr->vlistID;
-  size_t gridsize = (size_t) gridInqSize(vlistInqVarGrid(vlistID, varID));
-  size_t nlevs    = (size_t) zaxisInqSize(vlistInqVarZaxis(vlistID, varID));
+  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 ( size_t levID = 0;  levID < nlevs; levID++ )
-    extWriteVarSliceDP(streamptr, varID, (int)levID, &data[levID*gridsize]);
-}
+  if (fileSetPos(fileID1, recpos, SEEK_SET) != 0)
+    Error("Cannot seek input file for %s record copy!", container_name);
 
-#endif /* HAVE_LIBEXTRA */
+  char *buffer = (char *) Malloc(recsize);
+
+  if (fileRead(fileID1, buffer, recsize) != recsize)
+    Error("Failed to read record from %s file for copying!", container_name);
+
+  if (fileWrite(fileID2, buffer, recsize) != recsize)
+    Error("Failed to write record to %s file when copying!", container_name);
+
+  Free(buffer);
+}
 
 /*
  * Local Variables:
@@ -48467,9 +48227,6 @@ void extWriteVarDP(stream_t *streamptr, int varID, const double *data)
 #ifndef _STREAM_GRIBAPI_H
 #define _STREAM_GRIBAPI_H
 
-#ifdef HAVE_LIBGRIB_API
-
-
 int gribapiScanTimestep1(stream_t * streamptr);
 int gribapiScanTimestep2(stream_t * streamptr);
 int gribapiScanTimestep(stream_t * streamptr);
@@ -48482,13 +48239,6 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
 		     long datasize, const double *data, int nmiss, void **gribbuffer, size_t *gribbuffersize,
 		     int ljpeg, void *gribContainer);
 
-int gribapiGetScanningMode(grib_handle *gh);
-void gribapiSetScanningMode(grib_handle *gh, int scanningMode);
-
-void gribapiChangeParameterIdentification(grib_handle *gh, int code, int ltype, int lev);
-
-#endif
-
 #endif  /* _STREAM_GRIBAPI_H */
 /*
  * Local Variables:
@@ -48503,55 +48253,6 @@ void gribapiChangeParameterIdentification(grib_handle *gh, int code, int ltype,
 #endif
 
 
-int cdiDebugExt                        =  0;      //  Debug level for the KNMI extensions
-#ifdef HIRLAM_EXTENSIONS
-// *** RELATED to GRIB only ***
-int cdiGribUseTimeRangeIndicator        = 0;       // normaly cdo looks in grib for attribute called "stepType"
-                                                   // but NWP models such as Harmonie 37h1.2, use "timeRangeIndicator"
-                                                   // where:  0: for instanteneous fields; 4: for accumulated fields
-#endif // HIRLAM_EXTENSIONS
-
-
-// Regarding operation to change parameter identification:
-// change if cdiGribChangeParameterID.active
-struct cdiGribParamChange cdiGribChangeParameterID;
-
-// Used only for CDO module Selmulti
-void streamGrbChangeParameterIdentification(int code, int ltype, int lev)
-{
-  // NOTE this is a "PROXY" function for gribapiChangeParameterIdentification();
-  // This just sets the globals. There are probably better solutions to this.
-  // The parameter change is done by function  gribapiChangeParameterIdentification() in stream_gribapi.c
-  // Setting this control variable to true will cause calling fnc. gribapiChangeParameterIdentification later.
-  // After grib attributes have been changed this variable goes to false.
-  cdiGribChangeParameterID.active = true;
-  cdiGribChangeParameterID.code = code;
-  cdiGribChangeParameterID.ltype = ltype;
-  cdiGribChangeParameterID.lev = lev;
-}
-
-struct cdiGribModeChange cdiGribChangeModeUvRelativeToGrid;
-
-// Used only for CDO module WindTrans
-void streamGrbChangeModeUvRelativeToGrid(int mode)
-{
-  cdiGribChangeModeUvRelativeToGrid.active = true;
-  cdiGribChangeModeUvRelativeToGrid.mode = (mode > 0);
-}
-
-struct cdiGribScanModeChange cdiGribDataScanningMode;
-
-void streamGrbDefDataScanningMode(int scanmode)
-{
-  cdiGribDataScanningMode.active = true;
-  cdiGribDataScanningMode.value = scanmode;
-}
-
-int  streamGrbInqDataScanningMode(void)
-{
-  return cdiGribDataScanningMode.value;
-}
-
 
 int grib1ltypeToZaxisType(int grib_ltype)
 {
@@ -48568,7 +48269,6 @@ int grib1ltypeToZaxisType(int grib_ltype)
     case GRIB1_LTYPE_ATMOSPHERE:         zaxistype = ZAXIS_ATMOSPHERE;             break;
     case GRIB1_LTYPE_MEANSEA:            zaxistype = ZAXIS_MEANSEA;                break;
     case GRIB1_LTYPE_99:
-    case GRIB1_LTYPE_ISOBARIC_PA:
     case GRIB1_LTYPE_ISOBARIC:           zaxistype = ZAXIS_PRESSURE;               break;
     case GRIB1_LTYPE_HEIGHT:             zaxistype = ZAXIS_HEIGHT;                 break;
     case GRIB1_LTYPE_ALTITUDE:           zaxistype = ZAXIS_ALTITUDE;	           break;
@@ -48708,14 +48408,14 @@ int grbBitsPerValue(int datatype)
 {
   int bitsPerValue = 16;
 
-  if ( datatype == CDI_DATATYPE_CPX32 || datatype == CDI_DATATYPE_CPX64 )
+  if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
     Error("CDI/GRIB library does not support complex numbers!");
 
   if ( datatype != CDI_UNDEFID )
     {
       if ( datatype > 0 && datatype <= 32 )
 	bitsPerValue = datatype;
-      else if ( datatype == CDI_DATATYPE_FLT64 )
+      else if ( datatype == DATATYPE_FLT64 )
 	bitsPerValue = 24;
       else
 	bitsPerValue = 16;
@@ -48749,7 +48449,7 @@ int grbScanTimestep1(stream_t * streamptr)
 #if  defined  (HAVE_LIBCGRIBEX)
   int filetype  = streamptr->filetype;
 
-  if ( filetype == CDI_FILETYPE_GRB )
+  if ( filetype == FILETYPE_GRB )
     status = cgribexScanTimestep1(streamptr);
 #endif
 #if defined(HAVE_LIBCGRIBEX) && defined (HAVE_LIBGRIB_API)
@@ -48770,7 +48470,7 @@ int grbScanTimestep2(stream_t * streamptr)
 #if  defined  (HAVE_LIBCGRIBEX)
   int filetype = streamptr->filetype;
 
-  if ( filetype == CDI_FILETYPE_GRB )
+  if ( filetype == FILETYPE_GRB )
     {
       status = cgribexScanTimestep2(streamptr);
     }
@@ -48789,11 +48489,15 @@ static
 int grbScanTimestep(stream_t * streamptr)
 {
   int status = CDI_EUFTYPE;
-  int filetype  = streamptr->filetype;
+  int filetype;
+
+  filetype  = streamptr->filetype;
 
 #if  defined  (HAVE_LIBCGRIBEX)
-  if ( filetype == CDI_FILETYPE_GRB )
-    status = cgribexScanTimestep(streamptr);
+  if ( filetype == FILETYPE_GRB )
+    {
+      status = cgribexScanTimestep(streamptr);
+    }
   else
 #endif
 #ifdef HAVE_LIBGRIB_API
@@ -48809,12 +48513,17 @@ int grbScanTimestep(stream_t * streamptr)
 #if  defined  (HAVE_LIBGRIB)
 int grbInqContents(stream_t * streamptr)
 {
+  int fileID;
+  int status = 0;
+
+  fileID = streamptr->fileID;
+
   streamptr->curTsID = 0;
 
-  int status = grbScanTimestep1(streamptr);
+  status = grbScanTimestep1(streamptr);
+
   if ( status == 0 && streamptr->ntsteps == -1 ) status = grbScanTimestep2(streamptr);
 
-  int fileID = streamptr->fileID;
   fileSetPos(fileID, 0, SEEK_SET);
 
   return status;
@@ -48823,13 +48532,15 @@ int grbInqContents(stream_t * streamptr)
 
 int grbInqTimestep(stream_t * streamptr, int tsID)
 {
+  int ntsteps, nrecs;
+
   if ( tsID == 0 && streamptr->rtsteps == 0 )
     Error("Call to cdiInqContents missing!");
 
   if ( CDI_Debug )
     Message("tsid = %d rtsteps = %d", tsID, streamptr->rtsteps);
 
-  int ntsteps = CDI_UNDEFID;
+  ntsteps = CDI_UNDEFID;
   while ( (tsID + 1) > streamptr->rtsteps && ntsteps == CDI_UNDEFID )
     {
       ntsteps = grbScanTimestep(streamptr);
@@ -48840,8 +48551,6 @@ int grbInqTimestep(stream_t * streamptr, int tsID)
 	}
     }
 
-  int nrecs;
-
   if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID )
     {
       nrecs = 0;
@@ -48862,7 +48571,7 @@ void streamInqGRIBinfo(int streamID, int *intnum, float *fltnum, off_t *bignum)
 
   int filetype = streamptr->filetype;
 
-  if ( filetype == CDI_FILETYPE_GRB )
+  if ( filetype == FILETYPE_GRB )
     {
       int tsID     = streamptr->curTsID;
       int vrecID   = streamptr->tsteps[tsID].curRecID;
@@ -48996,14 +48705,14 @@ int vlistInsertTrivialTileSubtype(int vlistID);
 #if defined (HAVE_CONFIG_H)
 #endif
 
-#ifdef HAVE_LIBGRIB_API
+#if  defined  (HAVE_LIBGRIB_API)
 #include <limits.h>
 #include <stdio.h>
 
 
 
 
-#include <grib_api.h>
+#  include <grib_api.h>
 
 extern int cdiInventoryMode;
 
@@ -49015,14 +48724,6 @@ typedef struct {
   int level2;
   int ltype;
   int tsteptype;
-#ifdef HIRLAM_EXTENSIONS
-    // NOTE: tsteptype MUST be part of attributes used to compare variables!
-    // Modern NWP models (HARMONIE, HIRLAM) use timeRangeIndicator to specify
-    // if the field is instantanous or accumulated.
-    // Both types are typically in the same GRIB-file.
-    // (181; 105, 0, timeRangeIndicator=0) .. instantanous rain
-    // (181; 105, 0, timeRangeIndicator=4) .. accumulated rain  .. both can be in the same grib file
-#endif // HIRLAM_EXTENSIONS
   char name[32];
 
   var_tile_t tiles;
@@ -49186,7 +48887,7 @@ int gribapiGetValidityDateTime(grib_handle *gh, int *vdate, int *vtime)
 	}
 
       {
-	static bool lprint = true;
+	static int lprint = TRUE;
 	extern int grib_calendar;
 	int ryear, rmonth, rday, rhour, rminute, rsecond;
 	int julday, secofday;
@@ -49214,7 +48915,7 @@ int gribapiGetValidityDateTime(grib_handle *gh, int *vdate, int *vtime)
                 if ( lprint )
                   {
                     Warning("Time unit %d unsupported", timeUnits);
-                    lprint = false;
+                    lprint = FALSE;
                   }
                 break;
               }
@@ -49264,9 +48965,9 @@ void grib1GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, i
 	{
           double dlevel;
 	  GRIB_CHECK(grib_get_double(gh, "level", &dlevel), 0); //2 byte
-	  if ( *leveltype == GRIB1_LTYPE_ISOBARIC ) dlevel *= 100;
+	  if ( *leveltype == 100 ) dlevel *= 100;
 	  if ( dlevel < -2.e9 || dlevel > 2.e9 ) dlevel = 0;
-	  if ( *leveltype == GRIB1_LTYPE_99 || *leveltype == GRIB1_LTYPE_ISOBARIC_PA ) *leveltype = GRIB1_LTYPE_ISOBARIC;
+	  if ( *leveltype == GRIB1_LTYPE_99 ) *leveltype = 100;
 
 	  *level1 = (int) dlevel;
 	  *level2 = 0;
@@ -49418,11 +49119,11 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
   int vlistID = streamptr->vlistID;
   int tsID    = streamptr->curTsID;
   int recID   = recordNewEntry(streamptr, tsID);
-  record_t *record = &streamptr->tsteps[tsID].records[recID];
+  record_t *record  = &streamptr->tsteps[tsID].records[recID];
 
   int tsteptype = gribapiGetTsteptype(gh);
   // numavg  = ISEC1_AvgNum;
-  int numavg = 0;
+  int numavg  = 0;
 
   // fprintf(stderr, "param %d %d %d %d\n", param, level1, level2, leveltype1);
 
@@ -49447,54 +49148,12 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
   //       I. e. kick the fixed size array and allocate enough space, whatever that may be.
   strncpy(record->varname, varname, sizeof(record->varname));
 
-  grid_t *grid = (grid_t *)Malloc(sizeof(*grid));
+  grid_t *grid = (grid_t *)Malloc(sizeof (*grid));
   gribapiGetGrid(gh, grid);
 
-  struct addIfNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 0);
+  struct addIffNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 0);
   int gridID = gridAdded.Id;
-  if ( !gridAdded.isNew ) Free(grid);
-  else if ( grid->projtype == CDI_PROJ_RLL )
-    {
-      double xpole = 0, ypole = 0, angle = 0;
-      grib_get_double(gh, "latitudeOfSouthernPoleInDegrees",  &ypole);
-      grib_get_double(gh, "longitudeOfSouthernPoleInDegrees", &xpole);
-      grib_get_double(gh, "angleOfRotation", &angle);
-      xpole -= 180;
-      if ( fabs(ypole) > 0 ) ypole = -ypole; // change from south to north pole
-      if ( fabs(angle) > 0 ) angle = -angle;
-
-      gridDefParamRLL(gridID, xpole, ypole, angle);
-    }
-  else if ( grid->projtype == CDI_PROJ_LCC )
-    {
-      double a = 6367470., rf = 0;
-      long earthIsOblate;
-      grib_get_long(gh, "earthIsOblate", &earthIsOblate);
-      if ( earthIsOblate ) { a = 6378160.; rf = 297.0; }
-      double lon_0, lat_1, lat_2, xval_0, yval_0;
-      long projflag = 0;
-      grib_get_double(gh, "longitudeOfFirstGridPointInDegrees", &xval_0);
-      grib_get_double(gh, "latitudeOfFirstGridPointInDegrees", &yval_0);
-      grib_get_double(gh, "LoVInDegrees", &lon_0);
-      grib_get_double(gh, "Latin1InDegrees", &lat_1);
-      grib_get_double(gh, "Latin2InDegrees", &lat_2);
-      grib_get_long(gh, "projectionCentreFlag", &projflag);
-      bool lsouth = gribbyte_get_bit((int)projflag, 1);
-      if ( lsouth ) { lat_1 = -lat_1; lat_2 = -lat_2; }
-
-      double lat_0 = lat_2;
-      double x_0 = grid_missval;
-      double y_0 = grid_missval;
-
-      if ( proj_lonlat_to_lcc_func )
-        {
-          x_0 = xval_0; y_0 = yval_0;
-          proj_lonlat_to_lcc_func(grid_missval, lon_0, lat_0, lat_1, lat_2, a, rf, (size_t)1, &x_0, &y_0);
-          if ( IS_NOT_EQUAL(x_0, grid_missval) && IS_NOT_EQUAL(y_0, grid_missval) )
-            { x_0 = -x_0; y_0 = -y_0; }
-        }
-      gridDefParamLCC(gridID, grid_missval, lon_0, lat_0, lat_1, lat_2, a, rf, xval_0, yval_0, x_0, y_0);
-    }
+  if (!gridAdded.isNew) Free(grid);
 
   int zaxistype = gribapiGetZaxisType(gribEditionNumber(gh), leveltype1);
 
@@ -49522,7 +49181,10 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
         unsigned char uuid[CDI_UUID_SIZE];
         long lpar;
         GRIB_CHECK(grib_get_long(gh, "NV", &lpar), 0);
-        if ( lpar != 6 ) fprintf(stderr, "Warning ...\n");
+        if ( lpar != 6 )
+          {
+            fprintf(stderr, "Warning ...\n");
+          }
         GRIB_CHECK(grib_get_long(gh, "nlev", &lpar), 0);
         int nhlev = (int)lpar;
         GRIB_CHECK(grib_get_long(gh, "numberOfVGridUsed", &lpar), 0);
@@ -49535,8 +49197,8 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
       }
     }
 
-  // if ( datatype > 32 ) datatype = CDI_DATATYPE_PACK32;
-  if ( datatype <  0 ) datatype = CDI_DATATYPE_PACK;
+  // if ( datatype > 32 ) datatype = DATATYPE_PACK32;
+  if ( datatype <  0 ) datatype = DATATYPE_PACK;
 
   stdname[0] = 0;
   longname[0] = 0;
@@ -49587,11 +49249,12 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
   if ( grib_get_long(gh, "productDefinitionTemplateNumber", &productDefinitionTemplate) == 0 )
     varDefProductDefinitionTemplate(varID, (int) productDefinitionTemplate);
 
+  int    i;
   long   lval;
   double dval;
 
   if (lread_additional_keys)
-    for ( int i = 0; i < cdiNAdditionalGRIBKeys; i++ )
+    for ( i = 0; i < cdiNAdditionalGRIBKeys; i++ )
       {
         /* note: if the key is not defined, we do not throw an error! */
         if ( grib_get_long(gh, cdiAdditionalGRIBKeys[i], &lval) == 0 )
@@ -49603,9 +49266,10 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
   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);
-      int instID = institutInq((int)center, (int)subcenter, NULL, NULL);
+      instID    = institutInq((int)center, (int)subcenter, NULL, NULL);
       if ( instID == CDI_UNDEFID )
 	instID = institutDef((int)center, (int)subcenter, NULL, NULL);
       varDefInst(varID, instID);
@@ -49613,11 +49277,12 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
 
   if ( varInqModel(varID) == CDI_UNDEFID )
     {
+      int modelID;
       long processID;
       if ( grib_get_long(gh, "generatingProcessIdentifier", &processID) == 0 )
 	{
           /* FIXME: assert(processID >= INT_MIN && processID <= INT_MAX) */
-	  int modelID = modelInq(varInqInst(varID), (int)processID, NULL);
+	  modelID = modelInq(varInqInst(varID), (int)processID, NULL);
 	  if ( modelID == CDI_UNDEFID )
 	    modelID = modelDef(varInqInst(varID), (int)processID, NULL);
 	  varDefModel(varID, modelID);
@@ -49627,12 +49292,16 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
   if ( varInqTable(varID) == CDI_UNDEFID )
     {
       int pdis, pcat, pnum;
+
       cdiDecodeParam(param, &pnum, &pcat, &pdis);
 
       if ( pdis == 255 )
 	{
+	  int tableID;
 	  int tabnum = pcat;
-	  int tableID = tableInq(varInqModel(varID), tabnum, NULL);
+
+	  tableID = tableInq(varInqModel(varID), tabnum, NULL);
+
 	  if ( tableID == CDI_UNDEFID )
 	    tableID = tableDef(varInqModel(varID), tabnum, NULL);
 	  varDefTable(varID, tableID);
@@ -49647,7 +49316,7 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
 	    varID, param, zaxistype, gridID, levelID);
 }
 
-static compvar2_t gribapiVarSet(int param, int level1, int level2, int leveltype,
+static compvar2_t gribapiVarSet(int param, int level1, int level2, int leveltype, 
                                 int tsteptype, char *name, var_tile_t tiles_data)
 {
   compvar2_t compVar;
@@ -49700,28 +49369,12 @@ void ensureBufferSize(size_t requiredSize, size_t *curSize, void **buffer)
 }
 
 static
-grib_handle *gribapiGetDiskRepresentation(size_t recsize, size_t *buffersize, void **gribbuffer, int *outDatatype, int *outCompressionType, size_t *outUnzipsize)
+grib_handle *gribapiGetDiskRepresentation(size_t recsize, size_t *buffersize, void **gribbuffer, int *outDatatype, int *outCompressionType, long *outUnzipsize)
 {
-  int gribversion = (int)((char*)*gribbuffer)[7];
-
-  if ( gribversion <= 1 )
-    {
-      if ( gribGetZip(recsize, *gribbuffer, outUnzipsize) > 0 )
-        {
-          *outCompressionType = CDI_COMPRESS_SZIP;
-          ensureBufferSize(*outUnzipsize + 100, buffersize, gribbuffer);
-        }
-      else
-        {
-          *outCompressionType = CDI_COMPRESS_NONE;
-        }
-    }
-
-  grib_handle *gh = grib_handle_new_from_message(NULL, *gribbuffer, recsize);
-
   bool lieee = false;
 
-  if ( gribversion > 1 )
+  grib_handle *gh = grib_handle_new_from_message(NULL, *gribbuffer, recsize);
+  if(gribEditionNumber(gh) > 1)
     {
       size_t len = 256;
       char typeOfPacking[256];
@@ -49729,29 +49382,40 @@ grib_handle *gribapiGetDiskRepresentation(size_t recsize, size_t *buffersize, vo
       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 = CDI_COMPRESS_JPEG;
-          else if ( strncmp(typeOfPacking, "grid_ccsds", len) == 0 ) *outCompressionType = CDI_COMPRESS_SZIP;
+          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((long)recsize, *gribbuffer, outUnzipsize) > 0 )
+        {
+          *outCompressionType = COMPRESS_SZIP;
+          ensureBufferSize((size_t)*outUnzipsize + 100, buffersize, gribbuffer);
+        }
+      else
+        {
+          *outCompressionType = COMPRESS_NONE;
+        }
+    }
 
   if ( lieee )
     {
-      *outDatatype = CDI_DATATYPE_FLT64;
+      *outDatatype = DATATYPE_FLT64;
       long precision;
       int status = grib_get_long(gh, "precision", &precision);
-      if ( status == 0 && precision == 1 ) *outDatatype = CDI_DATATYPE_FLT32;
+      if ( status == 0 && precision == 1 ) *outDatatype = DATATYPE_FLT32;
     }
   else
     {
-      *outDatatype = CDI_DATATYPE_PACK;
+      *outDatatype = DATATYPE_PACK;
       long bitsPerValue;
       if ( grib_get_long(gh, "bitsPerValue", &bitsPerValue) == 0 )
         {
           if ( bitsPerValue > 0 && bitsPerValue <= 32 ) *outDatatype = (int)bitsPerValue;
         }
     }
-
   return gh;
 }
 
@@ -49798,8 +49462,8 @@ int gribapiScanTimestep1(stream_t * streamptr)
   size_t buffersize = 0;
   DateTime datetime0 = { .date = 10101, .time = 0 };
   int nrecs_scanned = 0;        //Only used for debug output.
-  bool warn_time = true;
-  // bool warn_numavg = true;
+  int warn_time = TRUE;
+  // int warn_numavg = TRUE;
   int rdate = 0, rtime = 0, tunit = 0, fcast = 0;
   grib_handle *gh = NULL;
 
@@ -49814,11 +49478,11 @@ int gribapiScanTimestep1(stream_t * streamptr)
   int fileID = streamptr->fileID;
 
   unsigned nrecs = 0;
-  while ( true )
+  while ( TRUE )
     {
       int level1 = 0, level2 = 0;
-      size_t recsize = gribGetSize(fileID);
-      recpos = fileGetPos(fileID);
+      size_t recsize = (size_t)gribGetSize(fileID);
+      recpos  = fileGetPos(fileID);
 
       if ( recsize == 0 )
         {
@@ -49832,7 +49496,7 @@ int gribapiScanTimestep1(stream_t * streamptr)
       if ( rstatus ) break;
 
       int datatype, comptype = 0;
-      size_t unzipsize;
+      long unzipsize;
       gh = gribapiGetDiskRepresentation(recsize, &buffersize, &gribbuffer, &datatype, &comptype, &unzipsize);
 
       nrecs_scanned++;
@@ -49884,7 +49548,7 @@ int gribapiScanTimestep1(stream_t * streamptr)
           else if ( result == CHECKTIME_INCONSISTENT && warn_time )
             {
               gribWarning("Inconsistent verification time!", nrecs_scanned, tsID+1, varname, param, level1, level2);
-              warn_time = false;
+              warn_time = FALSE;
             }
           assert(result == CHECKTIME_OK || result == CHECKTIME_INCONSISTENT);
         }
@@ -49895,7 +49559,7 @@ int gribapiScanTimestep1(stream_t * streamptr)
             {
               Message("Change numavg from %d to %d not allowed!",
                       taxis->numavg, ISEC1_AvgNum);
-              warn_numavg = false;
+              warn_numavg = FALSE;
             }
           else
             {
@@ -49973,7 +49637,7 @@ int gribapiScanTimestep1(stream_t * streamptr)
       if ( tsID != streamptr->rtsteps )
         Error("Internal error. tsID = %d", tsID);
 
-      streamptr->tsteps[tsID-1].next   = true;
+      streamptr->tsteps[tsID-1].next   = TRUE;
       streamptr->tsteps[tsID].position = recpos;
     }
 
@@ -50000,7 +49664,7 @@ int gribapiScanTimestep2(stream_t * streamptr)
   DateTime datetime0 = { LONG_MIN, LONG_MIN };
   // int gridID;
   int recID;
-  //  bool warn_numavg = true;
+  //  int warn_numavg = TRUE;
   grib_handle *gh = NULL;
 
   streamptr->curTsID = 1;
@@ -50036,12 +49700,12 @@ int gribapiScanTimestep2(stream_t * streamptr)
 
   int nrecs_scanned = nrecords; //Only used for debug output
   int rindex = 0;
-  while ( true )
+  while ( TRUE )
     {
       if ( rindex > nrecords ) break;
 
-      size_t recsize = gribGetSize(fileID);
-      recpos = fileGetPos(fileID);
+      size_t recsize = (size_t)gribGetSize(fileID);
+      recpos  = fileGetPos(fileID);
       if ( recsize == 0 )
 	{
 	  streamptr->ntsteps = 2;
@@ -50053,9 +49717,9 @@ int gribapiScanTimestep2(stream_t * streamptr)
       rstatus = gribRead(fileID, gribbuffer, &readsize);
       if ( rstatus ) break;
 
-      size_t unzipsize;
-      if ( gribGetZip(recsize, gribbuffer, &unzipsize) > 0 )
-        ensureBufferSize(unzipsize + 100, &buffersize, &gribbuffer);
+      long unzipsize;
+      if ( gribGetZip((long)recsize, gribbuffer, &unzipsize) > 0 )
+        ensureBufferSize((size_t)unzipsize + 100, &buffersize, &gribbuffer);
 
       nrecs_scanned++;
       gh = grib_handle_new_from_message(NULL, gribbuffer, recsize);
@@ -50101,7 +49765,7 @@ int gribapiScanTimestep2(stream_t * streamptr)
 	  if (  taxis->numavg && warn_numavg &&
 		(taxis->numavg != ISEC1_AvgNum) )
 	    {
-	      warn_numavg = false;
+	      warn_numavg = FALSE;
 	    }
 	  else
 	    {
@@ -50137,7 +49801,7 @@ int gribapiScanTimestep2(stream_t * streamptr)
 	    }
 	}
 
-      streamptr->tsteps[tsID].records[recID].used = true;
+      streamptr->tsteps[tsID].records[recID].used = TRUE;
       streamptr->tsteps[tsID].recIDs[rindex] = recID;
 
       if ( CDI_Debug )
@@ -50204,7 +49868,7 @@ int gribapiScanTimestep2(stream_t * streamptr)
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
-      streamptr->tsteps[tsID-1].next   = true;
+      streamptr->tsteps[tsID-1].next   = TRUE;
       streamptr->tsteps[tsID].position = recpos;
     }
 
@@ -50218,7 +49882,7 @@ int gribapiScanTimestep2(stream_t * streamptr)
 int gribapiScanTimestep(stream_t * streamptr)
 {
   int vrecID, recID;
-  //bool warn_numavg = true;
+  //int warn_numavg = TRUE;
   int nrecs = 0;
   int vlistID = streamptr->vlistID;
 
@@ -50257,12 +49921,12 @@ int gribapiScanTimestep(stream_t * streamptr)
       DateTime datetime0 = { LONG_MIN, LONG_MIN };
       grib_handle *gh = NULL;
       char varname[256];
-      while ( true )
+      while ( TRUE )
 	{
 	  if ( rindex > nrecs ) break;
 
-	  size_t recsize = gribGetSize(fileID);
-	  recpos = fileGetPos(fileID);
+	  size_t recsize = (size_t)gribGetSize(fileID);
+	  recpos  = fileGetPos(fileID);
 	  if ( recsize == 0 )
 	    {
 	      streamptr->ntsteps = streamptr->rtsteps + 1;
@@ -50281,9 +49945,9 @@ int gribapiScanTimestep(stream_t * streamptr)
 	      break;
 	    }
 
-          size_t unzipsize;
-	  if ( gribGetZip(recsize, gribbuffer, &unzipsize) > 0 )
-            ensureBufferSize(unzipsize + 100, &buffersize, &gribbuffer);
+          long unzipsize;
+	  if ( gribGetZip((long)recsize, gribbuffer, &unzipsize) > 0 )
+            ensureBufferSize((size_t)unzipsize + 100, &buffersize, &gribbuffer);
 
           nrecs_scanned++;
 	  gh = grib_handle_new_from_message(NULL, gribbuffer, recsize);
@@ -50329,7 +49993,7 @@ int gribapiScanTimestep(stream_t * streamptr)
 	      if (  taxis->numavg && warn_numavg &&
 		   (taxis->numavg != ISEC1_AvgNum) )
 		{
-		  warn_numavg = false;
+		  warn_numavg = FALSE;
 		}
 	      else
 		{
@@ -50375,7 +50039,7 @@ int gribapiScanTimestep(stream_t * streamptr)
 		}
 	    }
 
-          streamptr->tsteps[tsID].records[recID].used = true;
+          streamptr->tsteps[tsID].records[recID].used = TRUE;
           streamptr->tsteps[tsID].recIDs[rindex] = recID;
 
 	  if ( CDI_Debug )
@@ -50425,7 +50089,7 @@ int gribapiScanTimestep(stream_t * streamptr)
 	  if ( tsID != streamptr->rtsteps )
 	    Error("Internal error. tsID = %d", tsID);
 
-	  streamptr->tsteps[tsID-1].next   = true;
+	  streamptr->tsteps[tsID-1].next   = 1;
 	  streamptr->tsteps[tsID].position = recpos;
 	}
 
@@ -50688,12 +50352,10 @@ void gribapiDefStepUnits(int editionNumber, grib_handle *gh, int timeunit, int p
       else if ( grib2ProDefTempHasStatisticalDef(proDefTempNum) )
         {
           GRIB_CHECK(my_grib_set_long(gh, "indicatorOfUnitForTimeRange", unitsOfTime), 0);
-          GRIB_CHECK(my_grib_set_long(gh, "indicatorOfUnitOfTimeRange", unitsOfTime), 0);
+          //  GRIB_CHECK(my_grib_set_long(gh, "indicatorOfUnitOfTimeRange", unitsOfTime), 0);
         }
       else
         {
-	  // NOTE KNMI:  HIRLAM model files LAMH_D11 are in grib1 and do NOT have key indicatorOfUnitForTimeRange
-	  // Watch out for compatibility issues.
           GRIB_CHECK(my_grib_set_long(gh, "indicatorOfUnitOfTimeRange", unitsOfTime), 0);
         }
     }
@@ -50706,10 +50368,25 @@ int gribapiDefSteptype(int editionNumber, grib_handle *gh, int productDefinition
   size_t len = 64;
   const char *stepType;
 
+  static struct {
+    long productionTemplate;
+    const char sname[8];
+  } ts_tab[] = {
+    [TSTEP_INSTANT] = {  0, "instant" },
+    [TSTEP_AVG] = { 8, "avg" },
+    [TSTEP_ACCUM] = {  8, "accum" },
+    [TSTEP_MAX] = {  8, "max" },
+    [TSTEP_MIN] = {  8, "min" },
+    [TSTEP_DIFF] = {  8, "diff" },
+    [TSTEP_RMS] = {  8, "rms" },
+    [TSTEP_SD] = {  8, "sd" },
+    [TSTEP_COV] = { 8, "cov" },
+    [TSTEP_RATIO] = {  8, "ratio" }
+  };
   if (tsteptype >= TSTEP_INSTANT && tsteptype <= TSTEP_RATIO)
     {
-      stepType = cdiGribAPI_ts_str_map[tsteptype].sname;
-      proDefTempNum = cdiGribAPI_ts_str_map[tsteptype].productionTemplate;
+      stepType = ts_tab[tsteptype].sname;
+      proDefTempNum = ts_tab[tsteptype].productionTemplate;
     }
   else
     {
@@ -50770,7 +50447,7 @@ int gribapiDefDateTimeRel(int editionNumber, grib_handle *gh, int rdate, int rti
 
   int factor = getTimeunitFactor(timeunit);
 
-  if ( !(int)(fmod(days*86400.0 + secs, factor)))
+  if ( !(int) fmod(days*86400.0 + secs, factor) )
     {
       int proDefTempNum = gribapiDefSteptype(editionNumber, gh, productDefinitionTemplate, typeOfGeneratingProcess, tsteptype, gcinit);
 
@@ -50849,18 +50526,18 @@ struct gribApiMsg {
 };
 
 static struct gribApiMsg
-getGribApiCompTypeMsg(int comptype, int gridsize)
+getGribApiCompTypeMsg(grib_handle *gh, int comptype, int gridsize)
 {
   const char *mesg;
   size_t len;
 
-  if ( comptype == CDI_COMPRESS_JPEG && gridsize > 1 )
+  if ( comptype == COMPRESS_JPEG && gridsize > 1 )
     {
       static const char mesg_grid_jpeg[] = "grid_jpeg";
       len = sizeof (mesg_grid_jpeg) - 1;
       mesg = mesg_grid_jpeg;
     }
-  else if ( comptype == CDI_COMPRESS_SZIP && gridsize > 1 )
+  else if ( comptype == COMPRESS_SZIP && gridsize > 1 )
     {
       static const char mesg_grid_ccsds[] = "grid_ccsds";
       len = sizeof (mesg_grid_ccsds) - 1;
@@ -50881,8 +50558,6 @@ static
 void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype, bool lieee, int datatype, int nmiss, int gcinit)
 {
   UNUSED(nmiss);
-  bool lrotated = false;
-  bool lcurvi = false;
 
   int gridtype = gridInqType(gridID);
   int gridsize = gridInqSize(gridID);
@@ -50918,36 +50593,13 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype
     }
   else if ( gridtype == GRID_CURVILINEAR )
     {
-      int projID = gridInqProj(gridID);
-      if ( projID != CDI_UNDEFID && gridInqType(projID) == GRID_PROJECTION )
-        {
-          gridID = projID;
-          gridtype = GRID_PROJECTION;
-        }
-      else
-        {
-          static bool lwarning = true;
-          if ( lwarning && gridsize > 1 )
-            {
-              lwarning = false;
-              Warning("Curvilinear grid is unsupported in GRIB format! Created wrong Grid Description Section!");
-            }
-          lcurvi = true;
-          gridtype = GRID_LONLAT;
-        }
-    }
-
-  if ( gridtype == GRID_PROJECTION )
-    {
-      if ( gridInqProjType(gridID) == CDI_PROJ_RLL )
-        {
-          gridtype = GRID_LONLAT;
-          lrotated = true;
-        }
-      else if ( gridInqProjType(gridID) == CDI_PROJ_LCC )
-        {
-          gridtype = GRID_LCC;
-        }
+      static bool lwarn = true;
+      if ( lwarn && gridsize > 1 )
+	{
+	  lwarn = false;
+	  Warning("Curvilinear grids are unsupported in GRIB format! Created wrong Grid Description Section!");
+	}
+      gridtype = GRID_LONLAT;
     }
 
   if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN )
@@ -50956,7 +50608,8 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype
 
       if ( comptype )
         {
-          struct gribApiMsg gaMsg = getGribApiCompTypeMsg(comptype, gridsize);
+          struct gribApiMsg gaMsg
+            = getGribApiCompTypeMsg(gh, comptype, gridsize);
           size_t len = gaMsg.msgLen;
           const char *mesg = gaMsg.msg;
           GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
@@ -50974,40 +50627,45 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype
       {
 	double xfirst = 0, xlast = 0, xinc = 0;
 	double yfirst = 0, ylast = 0, yinc = 0;
+	double latIncr;
 
-        const char *mesg;
-        size_t len;
-        if ( gridtype == GRID_GAUSSIAN )
-          {
-            static const char mesg_gaussian[] = "regular_gg";
-            len = sizeof(mesg_gaussian) - 1;
-            mesg = mesg_gaussian;
-          }
-        else if ( gridtype == GRID_GAUSSIAN_REDUCED )
-          {
-            static const char mesg_gaussian_reduced[] = "reduced_gg";
-            len = sizeof(mesg_gaussian_reduced) - 1;
-            mesg = mesg_gaussian_reduced;
-          }
-        else if ( lrotated )
-          {
-            static const char mesg_rot_lonlat[] = "rotated_ll";
-            len = sizeof(mesg_rot_lonlat) - 1;
-            mesg = mesg_rot_lonlat;
-          }
-        else
-          {
-            static const char mesg_regular_ll[] = "regular_ll";
-            len = sizeof(mesg_regular_ll) - 1;
-            mesg = mesg_regular_ll;
-          }
-        GRIB_CHECK(my_grib_set_string(gh, "gridType", mesg, &len), 0);
+        {
+          const char *mesg;
+          size_t len;
+          if ( gridtype == GRID_GAUSSIAN )
+            {
+              static const char mesg_gaussian[] = "regular_gg";
+              len = sizeof (mesg_gaussian) - 1;
+              mesg = mesg_gaussian;
+            }
+          else if ( gridtype == GRID_GAUSSIAN_REDUCED )
+            {
+              static const char mesg_gaussian_reduced[] = "reduced_gg";
+              len = sizeof (mesg_gaussian_reduced) - 1;
+              mesg = mesg_gaussian_reduced;
+            }
+          else if ( gridtype == GRID_LONLAT && gridIsRotated(gridID) )
+            {
+              static const char mesg_rot_lonlat[] = "rotated_ll";
+              len = sizeof (mesg_rot_lonlat) - 1;
+              mesg = mesg_rot_lonlat;
+            }
+          else
+            {
+              static const char mesg_regular_ll[] = "regular_ll";
+              len = sizeof (mesg_regular_ll) - 1;
+              mesg = mesg_regular_ll;
+	  }
+          GRIB_CHECK(my_grib_set_string(gh, "gridType", mesg, &len), 0);
+        }
 
-	int nlon = gridInqXsize(gridID);
-	int nlat = gridInqYsize(gridID);
+	long nlon = gridInqXsize(gridID);
+	long nlat = gridInqYsize(gridID);
 
 	if ( gridtype == GRID_GAUSSIAN_REDUCED )
 	  {
+            //GRIB_CHECK(my_grib_set_long(gh, "numberOfValues", gridsize), 0);
+
 	    nlon = 0;
 
 	    int *rowlon = (int *) Malloc((size_t)nlat*sizeof(int));
@@ -51015,32 +50673,38 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype
 	    gridInqRowlon(gridID, rowlon);
 	    for ( int i = 0; i < nlat; ++i ) pl[i] = rowlon[i];
 
-            GRIB_CHECK(grib_set_long_array(gh, "pl", pl, (size_t)nlat), 0);
+            GRIB_CHECK(grib_set_long_array(gh, "pl", pl, nlat), 0);
 
 	    Free(pl);
 	    Free(rowlon);
 
 	    xfirst = 0;
-	    xinc   =        360. * 0.5 / (double)nlat;
-	    xlast  = 360. - 360. * 0.5 / (double)nlat;
+	    xlast  = 360.-360./(nlat*2);
+	    xinc   = 360./(nlat*2);
 	  }
 	else
 	  {
-	    if ( nlon == 0 ) nlon = 1;
+	    if ( nlon == 0 )
+	      {
+		nlon = 1;
+	      }
 	    else
 	      {
-		xfirst = gridInqXval(gridID, 0);
-                xlast  = gridInqXval(gridID, (lcurvi ? nlon*nlat : nlon) - 1);
-		xinc   = fabs(gridInqXinc(gridID));
+		xfirst = gridInqXval(gridID,      0);
+		xlast  = gridInqXval(gridID, nlon-1);
+		xinc   = gridInqXinc(gridID);
 	      }
 	  }
 
-	if ( nlat == 0 ) nlat = 1;
+	if ( nlat == 0 )
+	  {
+	    nlat = 1;
+	  }
 	else
 	  {
-	    yfirst = gridInqYval(gridID, 0);
-            ylast  = gridInqYval(gridID, (lcurvi ? nlon*nlat : nlat) - 1);
-	    yinc   = fabs(gridInqYinc(gridID));
+	    yfirst = gridInqYval(gridID,      0);
+	    ylast  = gridInqYval(gridID, nlat-1);
+	    yinc   = gridInqYinc(gridID);
 	  }
 
 	if ( gridtype != GRID_GAUSSIAN_REDUCED ) GRIB_CHECK(my_grib_set_long(gh, "Ni", nlon), 0);
@@ -51053,14 +50717,14 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype
 	GRIB_CHECK(my_grib_set_double(gh, "latitudeOfLastGridPointInDegrees",   ylast), 0);
 
         {
-          long iscan = xfirst > xlast;
-          GRIB_CHECK(my_grib_set_long(gh, "iScansNegatively", iscan), 0);
-        }
-        {
-          long jscan = yfirst < ylast;
+          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);
@@ -51069,103 +50733,120 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype
           }
 	else
 	  {
-	    GRIB_CHECK(my_grib_set_double(gh, "jDirectionIncrementInDegrees", yinc), 0);
+	    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 ( lrotated )
-	  {
-            double xpole = 0, ypole = 0, angle = 0;
-            gridInqParamRLL(gridID, &xpole, &ypole, &angle);
+	if ( ISEC2_NumLon == 1 && ISEC2_NumLat > 1 )
+	  if ( ISEC2_LonIncr == 0 && ISEC2_LatIncr != 0 ) ISEC2_LonIncr = ISEC2_LatIncr;
 
-            xpole += 180;
-            if ( fabs(ypole) > 0 ) ypole = -ypole; // change from north to south pole
+	if ( ISEC2_LatIncr == 0 || ISEC2_LonIncr == 0 )
+	  ISEC2_ResFlag = 0;
+	else
+	  ISEC2_ResFlag = 128;
+	*/
+	if ( gridIsRotated(gridID) )
+	  {
+	    double xpole = gridInqXpole(gridID);
+	    double ypole = gridInqYpole(gridID);
+	    double angle = gridInqAngle(gridID);
+	    /* change from north to south pole */
+	    if ( fabs(ypole) > 0 ) ypole = -ypole;
+	    xpole =  xpole + 180;
             if ( fabs(angle) > 0 ) angle = -angle;
-            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);
-          }
+	    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 = false; comptype = 0; }
 
-        if ( lieee )
-          {
-            static const char mesg_grid_ieee[] = "grid_ieee";
-            len = sizeof (mesg_grid_ieee) - 1;
-            mesg = mesg_grid_ieee;
-          }
-        else
-          {
-            struct gribApiMsg gaMsg = getGribApiCompTypeMsg(comptype, gridsize);
-            len = gaMsg.msgLen;
-            mesg = gaMsg.msg;
-          }
-        GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
-        if ( lieee )
-          GRIB_CHECK(my_grib_set_long(gh, "precision", datatype == CDI_DATATYPE_FLT64 ? 2 : 1), 0);
+        {
+          const char *mesg;
+          size_t len;
+          if ( lieee )
+            {
+              static const char mesg_grid_ieee[] = "grid_ieee";
+              len = sizeof (mesg_grid_ieee) - 1;
+              mesg = mesg_grid_ieee;
+            }
+          else
+            {
+              struct gribApiMsg gaMsg
+                = getGribApiCompTypeMsg(gh, comptype, gridsize);
+              len = gaMsg.msgLen;
+              mesg = gaMsg.msg;
+            }
+          GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
+          if ( lieee )
+            GRIB_CHECK(my_grib_set_long(gh, "precision",
+                                        datatype == DATATYPE_FLT64 ? 2 : 1), 0);
 
-        long uvRelativeToGrid = gridInqUvRelativeToGrid(gridID);
-        if ( uvRelativeToGrid ) GRIB_CHECK(my_grib_set_long(gh, "uvRelativeToGrid", uvRelativeToGrid), 0);
+        }
 
 	break;
       }
     case GRID_LCC:
       {
+	double originLon, originLat, lonParY, lat1, lat2, xincm, yincm;
+	int projflag, scanflag;
+
 	int xsize = gridInqXsize(gridID);
 	int ysize = gridInqYsize(gridID);
 
-        double lon_0, lat_0, lat_1, lat_2, a, rf, xval_0, yval_0, x_0, y_0;
-	gridInqParamLCC(gridID, grid_missval, &lon_0, &lat_0, &lat_1, &lat_2, &a, &rf, &xval_0, &yval_0, &x_0, &y_0);
-	gridVerifyGribParamLCC(grid_missval, &lon_0, &lat_0, &lat_1, &lat_2, &a, &rf, &xval_0, &yval_0, &x_0, &y_0);
-        if ( xval_0 < 0 ) xval_0 += 360;
-        bool lsouth = (lat_1 < 0);
-        if ( lsouth ) { lat_1 = -lat_2; lat_2 = -lat_2; }
-        int projflag = 0;
-        if ( lsouth ) gribbyte_set_bit(&projflag, 1);
-
-        double xinc = gridInqXinc(gridID);
-        double yinc = gridInqYinc(gridID);
+	gridInqLCC(gridID, &originLon, &originLat, &lonParY, &lat1, &lat2, &xincm, &yincm,
+		   &projflag, &scanflag);
 
         static const char mesg[] = "lambert";
-        size_t len = sizeof(mesg) -1;
+        size_t len = sizeof (mesg) -1;
         GRIB_CHECK(my_grib_set_string(gh, "gridType", mesg, &len), 0);
 
 	GRIB_CHECK(my_grib_set_long(gh, "Nx", xsize), 0);
 	GRIB_CHECK(my_grib_set_long(gh, "Ny", ysize), 0);
-	GRIB_CHECK(my_grib_set_long(gh, "DxInMetres", lround(xinc)), 0);
-	GRIB_CHECK(my_grib_set_long(gh, "DyInMetres", lround(yinc)), 0);
-	GRIB_CHECK(my_grib_set_double(gh, "longitudeOfFirstGridPointInDegrees", xval_0), 0);
-	GRIB_CHECK(my_grib_set_double(gh, "latitudeOfFirstGridPointInDegrees", yval_0), 0);
-	GRIB_CHECK(my_grib_set_double(gh, "LoVInDegrees", lon_0), 0);
-	GRIB_CHECK(my_grib_set_double(gh, "Latin1InDegrees", lat_1), 0);
-	GRIB_CHECK(my_grib_set_double(gh, "Latin2InDegrees", lat_2), 0);
-        GRIB_CHECK(my_grib_set_long(gh, "projectionCentreFlag", projflag), 0);
-
-        long uvRelativeToGrid = gridInqUvRelativeToGrid(gridID);
-        if ( uvRelativeToGrid ) GRIB_CHECK(my_grib_set_long(gh, "uvRelativeToGrid", uvRelativeToGrid), 0);
-        long earthIsOblate = (IS_EQUAL(a, 6378160.) && IS_EQUAL(rf, 297.));
-        if ( earthIsOblate ) GRIB_CHECK(my_grib_set_long(gh, "earthIsOblate", earthIsOblate), 0);
-
-        int scanflag = 0;
-        gribbyte_set_bit(&scanflag, 2);
+
+        /* FIXME: lround should probably be round here */
+	GRIB_CHECK(my_grib_set_double(gh, "DxInMetres", (double)lround(xincm)), 0);
+        /* FIXME: lround should probably be round here */
+	GRIB_CHECK(my_grib_set_double(gh, "DyInMetres", (double)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, "scanningMode", (long)scanflag), 0);
+          {
+            GRIB_CHECK(my_grib_set_long(gh, "projectionCenterFlag", projflag), 0);
+            GRIB_CHECK(my_grib_set_long(gh, "scanningMode", scanflag), 0);
+          }
 
 	break;
       }
     case GRID_SPECTRAL:
       {
-        {
-          static const char mesg[] = "sh";
-          size_t len = sizeof (mesg) -1;
-          GRIB_CHECK(my_grib_set_string(gh, "gridType", mesg, &len), 0);
-        }
-	{
-          int trunc = gridInqTrunc(gridID);
-          enum { numTruncAtt = 3 };
-          static const char truncAttNames[numTruncAtt][2] = { "J", "K", "M" };
-          for (size_t i = 0; i < numTruncAtt; ++i)
-            GRIB_CHECK(my_grib_set_long(gh, truncAttNames[i], trunc), 0);
-        }
+        static const char mesg[] = "sh";
+        size_t len = sizeof (mesg) -1;
+	GRIB_CHECK(my_grib_set_string(gh, "gridType", mesg, &len), 0);
+
+	int trunc = gridInqTrunc(gridID);
+	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", gridsize), 0);
         /*
         if ( lieee )
@@ -51182,11 +50863,10 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype
             static const char mesg[] = "spectral_complex";
             size_t len = sizeof (mesg) -1;
 	    GRIB_CHECK(my_grib_set_string(gh, "packingType", mesg, &len), 0);
-            enum { numTruncAtt = 3 };
-            static const char truncAttNames[numTruncAtt][3]
-              = { "JS", "KS", "MS" };
-            for (size_t i = 0; i < numTruncAtt; ++i)
-              GRIB_CHECK(my_grib_set_long(gh, truncAttNames[i], 20), 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
 	  {
@@ -51201,19 +50881,17 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype
       {
 	GRIB_CHECK(my_grib_set_long(gh, "gridDefinitionTemplateNumber", GRIB2_GTYPE_GME), 0);
 
-        int nd = 0, ni = 0, ni2 = 0, ni3 = 0;
-        gridInqParamGME(gridID, &nd, &ni, &ni2, &ni3);
-	GRIB_CHECK(my_grib_set_long(gh, "nd", nd), 0);
-	GRIB_CHECK(my_grib_set_long(gh, "Ni", ni), 0);
-	GRIB_CHECK(my_grib_set_long(gh, "n2", ni2), 0);
-	GRIB_CHECK(my_grib_set_long(gh, "n3", ni3), 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", gridsize), 0);
 	GRIB_CHECK(my_grib_set_long(gh, "totalNumberOfGridPoints", gridsize), 0);
 
-        if ( comptype == CDI_COMPRESS_SZIP )
+        if ( comptype == COMPRESS_SZIP )
           {
             static const char mesg[] = "grid_ccsds";
             size_t len = sizeof (mesg) -1;
@@ -51249,7 +50927,7 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int comptype
 	      Warning("Can't write UUID!");
 	  }
 
-        if ( comptype == CDI_COMPRESS_SZIP )
+        if ( comptype == COMPRESS_SZIP )
           {
             static const char mesg[] = "grid_ccsds";
             size_t len = sizeof (mesg) -1;
@@ -51270,14 +50948,16 @@ static
 void getLevelFactor(double level, long *factor, long *out_scaled_value)
 {
   double scaled_value  = level;
-  long   iscaled_value = lround(scaled_value);
+  /* FIXME: lround might be better here */
+  long   iscaled_value = (long) round(scaled_value);
   long   i;
 
   const double eps = 1.e-8;
   for ( i=0; (fabs(scaled_value - (double) iscaled_value) >= eps) && i < 7; i++ )
     {
       scaled_value *= 10.;
-      iscaled_value = lround(scaled_value);
+      /* FIXME: lround might be better here */
+      iscaled_value = (long)round(scaled_value);
     }
 
   (*factor)           = i;
@@ -51288,7 +50968,7 @@ static
 void gribapiDefLevelType(grib_handle *gh, int gcinit, const char *keyname, long leveltype)
 {
   bool lset = false;
-  if ( (leveltype == GRIB1_LTYPE_ISOBARIC_PA || leveltype == 99 || leveltype == 100) && gribEditionNumber(gh) == 1 )
+  if ( (leveltype == 99 || leveltype == 100) && gribEditionNumber(gh) == 1 )
     {
       if ( gribGetLong(gh, "indicatorOfTypeOfLevel") != leveltype ) lset = true;
     }
@@ -51333,17 +51013,34 @@ void grib2DefLevel(grib_handle *gh, int gcinit, long leveltype1, long leveltype2
     }
 }
 
+
+/*
+void grib_verfiy_zaxis(int zaxisID, double sf)
+{
+  printf("grb_verfiy_vlist called\n");
+  int zaxisID = vlistZaxis(vlistID, index);
+  int nlevels = zaxisInqSize(zaxisID);
+  int zaxistype = zaxisInqType(zaxisID);
+  double *levels = (double *) Malloc(nlevels*sizeof(double));
+  int *ilevels = (int *) Malloc(nlevels*sizeof(int));
+  zaxisInqLevels(zaxisID, levels);
+  for ( int i = 0; i < nlevels; ++i )
+    printf("level %d %g\n", i+1, levels[i]);
+  Free(ilevels);
+  Free(levels);
+}
+*/
+
 static
-void gribapiDefLevel(int editionNumber, grib_handle *gh, int zaxisID, int levelID, int gcinit, int proddef_template_num)
+void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID, int levelID, int gcinit, int proddef_template_num)
 {
-  char units[CDI_MAX_NAME];
   bool lbounds = false;
   double dlevel1 = 0, dlevel2 = 0;
 
   int zaxistype = zaxisInqType(zaxisID);
   long ltype = zaxisInqLtype(zaxisID);
   long ltype2 = zaxisInqLtype2(zaxisID);
-  double level = zaxisInqLevels(zaxisID, NULL) ? zaxisInqLevel(zaxisID, levelID) : levelID+1;
+  double level = zaxisInqLevel(zaxisID, levelID);
 
   if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
     {
@@ -51384,6 +51081,7 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int zaxisID, int levelI
         if ( zaxistype == ZAXIS_HEIGHT )
           {
             double sf = 1;
+            char units[128];
             zaxisInqUnits(zaxisID, units);
             if ( units[1] == 'm' && !units[2] )
               {
@@ -51431,9 +51129,13 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int zaxisID, int levelI
     case ZAXIS_ATMOSPHERE:
       {
         if ( editionNumber <= 1 )
-          grib1DefLevel(gh, gcinit, grib_ltype, lbounds, level, dlevel1, dlevel2);
+          {
+            grib1DefLevel(gh, gcinit, grib_ltype, lbounds, level, dlevel1, dlevel2);
+          }
         else
-          grib2DefLevel(gh, gcinit, grib_ltype, grib_ltype, lbounds, level, dlevel1, dlevel2);
+          {
+            grib2DefLevel(gh, gcinit, grib_ltype, grib_ltype, lbounds, level, dlevel1, dlevel2);
+          }
 
         break;
       }
@@ -51466,6 +51168,7 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int zaxisID, int levelI
       {
 	if ( level < 0 ) Warning("Pressure level of %f Pa is below zero!", level);
 
+	char units[128];
 	zaxisInqUnits(zaxisID, units);
 	if ( memcmp(units, "Pa", 2) != 0 )
           {
@@ -51478,7 +51181,7 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int zaxisID, int levelI
           {
             double dum;
             if ( level < 32768 && (level < 100 || modf(level/100, &dum) > 0) )
-              grib_ltype = GRIB1_LTYPE_ISOBARIC_PA;
+              grib_ltype = GRIB1_LTYPE_99;
             else
               level /= 100;
 
@@ -51505,6 +51208,7 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int zaxisID, int levelI
       }
     case ZAXIS_DEPTH_BELOW_LAND:
       {
+	char units[128];
 	zaxisInqUnits(zaxisID, units);
         double sf; //scalefactor
 
@@ -51582,427 +51286,6 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int zaxisID, int levelI
     }
 }
 
-
-int gribapiGetScanningMode(grib_handle *gh)
-{
-  long iScansNegatively;
-  long jScansPositively;
-  long jPointsAreConsecutive;
-
-  GRIB_CHECK(grib_get_long(gh, "iScansNegatively", &iScansNegatively), 0);
-  GRIB_CHECK(grib_get_long(gh, "jScansPositively", &jScansPositively), 0);
-  GRIB_CHECK(grib_get_long(gh, "jPointsAreConsecutive", &jPointsAreConsecutive), 0);
-  int scanningMode
-    = 128*(bool)iScansNegatively
-    + 64 *(bool)jScansPositively
-    + 32 *(bool)jPointsAreConsecutive;
-  if (cdiDebugExt>=30)
-    printf("gribapiGetScanningMode(): Scanning mode = %02d (%1d%1d%1d)*32; \n",\
-            scanningMode,(int)jPointsAreConsecutive,(int)jScansPositively,(int)iScansNegatively);
-
- return scanningMode;
-}
-
-
-void gribapiSetScanningMode(grib_handle *gh, int scanningMode)
-{
-   // 127: reserved for testing; generated test data will be in 64 scanning mode
-  //if (scanningMode== 127)  scanningMode = 64;
-
-  long iScansNegatively      = (scanningMode & 128)/128;
-  long jScansPositively      = (scanningMode & 64)/64;
-  long jPointsAreConsecutive = (scanningMode & 32)/32;
-
-  if (cdiDebugExt>=30)
-  {
-    long paramId, levelTypeId, levelId, uvRelativeToGrid;
-    GRIB_CHECK(grib_get_long(gh, "uvRelativeToGrid", &uvRelativeToGrid), 0);
-    GRIB_CHECK(grib_get_long(gh, "indicatorOfParameter", &paramId), 0);
-    GRIB_CHECK(grib_get_long(gh, "indicatorOfTypeOfLevel", &levelTypeId), 0);
-    GRIB_CHECK(grib_get_long(gh, "level", &levelId), 0);
-    printf("gribapiSetScanningMode(): (param,ltype,level) = (%3d,%3d,%4d); Scanning mode = %02d (%1d%1d%1d)*32;  uvRelativeToGrid = %02d\n",\
-            (int)paramId, (int)levelTypeId, (int)levelId,
-            scanningMode,(int)jPointsAreConsecutive,(int)jScansPositively,(int)iScansNegatively,
-            (int)uvRelativeToGrid);
-  }
-
-  GRIB_CHECK(my_grib_set_long(gh, "iScansNegatively", iScansNegatively), 0);
-  GRIB_CHECK(my_grib_set_long(gh, "jScansPositively", jScansPositively), 0);
-  GRIB_CHECK(my_grib_set_long(gh, "jPointsAreConsecutive", jPointsAreConsecutive), 0);
-}
-
-
-static void gribapiSetUvRelativeToGrid(grib_handle *gh, int mode)
-{
-  long uvRelativeToGridMode = mode;
-  long uvRelativeToGridModeOld;
-
-  GRIB_CHECK(grib_get_long(gh, "uvRelativeToGrid", &uvRelativeToGridModeOld), 0);
-
-  if (cdiDebugExt>=30)
-    printf("gribapiSetUvRelativeToGrid():  uvRelativeToGrid: %02d (old) => %02d (new); \n",(int)uvRelativeToGridModeOld,(int)uvRelativeToGridMode);
-
-  GRIB_CHECK(my_grib_set_long(gh, "uvRelativeToGrid", uvRelativeToGridMode), 0);
-}
-
-
-  /*
-    TABLE 8. SCANNING MODE FLAG
-
-    (GDS Octet 28)
-    BIT     VALUE     MEANING
-    1       0       Points scan in +i direction
-            1       Points scan in -i direction
-    2       0       Points scan in -j direction
-            1       Points scan in +j direction
-    3       0       Adjacent points in i direction are consecutive
-                      (FORTRAN: (I,J))
-            1       Adjacent points in j direction are consecutive
-                    (FORTRAN: (J,I))
-
-    => Scanning Mode     0 0 0 0 0 0 0 0  (00 dec)  +i, -j; i direction consecutive (row-major    order West->East   & North->South)
-    => Scanning Mode     0 1 0 0 0 0 0 0  (64 dec)  +i, +j; i direction consecutive (row-major    order West->East   & South->North )
-    => Scanning Mode     1 1 0 0 0 0 0 0  (96 dec)  +i, +j; j direction consecutive (column-major order South->North & West->East )
-
-    NOTE:  South->North  - As if you would plot the data as image on the screen
-                           where [0,0] of the data is the top-left pixel.
-
-                           grib2ppm LAMH_D11_201302150000_00000_oro | display ppm:-
-                           ImageMagick (display): [0,0] of an image belongs to the top-left pixel
-    [DEFAULT] : 64 dec
-
-    iScansNegatively = 0;
-    jScansPositively = 1;
-    jPointsAreConsecutive = 0;    => Scanning Mode 64
-
-    cdo selindexbox,1,726,100,550 LAMH_D11_201302150000_00000_oro LAMH_D11_201302150000_00000_oro_cropped
-    grib2ppm LAMH_D11_201302150000_00000_oro_cropped | /usr/bin/display ppm:- &
-    # ^^^ this image will be missing the souther parts of data
-
-    grib2ppm LAMH_D11_201302150000_00000_oro | /usr/bin/display ppm:- &
-    # ^ full domain data
-  */
-
-#ifdef HIRLAM_EXTENSIONS
-static void
-verticallyFlipGridDefinitionWhenScanningModeChanged(grib_handle *gh, double yfirst, double ylast, double yinc )
-{
-  /*
-  Nj = 550;
-  latitudeOfFirstGridPointInDegrees = -30.8;
-  latitudeOfLastGridPointInDegrees = 24.1;
-  iScansNegatively = 0;
-  jScansPositively = 0;
-  jPointsAreConsecutive = 0;
-  jDirectionIncrementInDegrees = 0.1;
-
-  When switching from scanning mode 0 <=> 64
-  yfirst = -30.8 + (550-1)*0.1
-
-  yfirst = yfirst + (ysize-1) * yinc
-  yinc   = -1.0*yinc
-
-  */
-
-
-  //long jDim=0;
-  //GRIB_CHECK(grib_get_long(gh, "Nj", &jDim), 0);
-
-  double latitudeOfFirstGridPointInDegrees;
-  double latitudeOfLastGridPointInDegrees;
-  double jDirectionIncrementInDegrees;
-
-  //GRIB_CHECK(grib_get_double(gh, "latitudeOfFirstGridPointInDegrees", &latitudeOfFirstGridPointInDegrees), 0);  // yfirst
-  //GRIB_CHECK(grib_get_double(gh, "latitudeOfLastGridPointInDegrees", &latitudeOfLastGridPointInDegrees), 0);    // ylast
-  //GRIB_CHECK(grib_get_double(gh, "jDirectionIncrementInDegrees", &jDirectionIncrementInDegrees), 0);  // yinc
-
-  if (cdiDebugExt>=10)
-  {
-      Message(" BEFORE: yfirst = %f; ylast = %f; yinc = %f; ", yfirst,ylast, yinc);
-  }
-
-  GRIB_CHECK(my_grib_set_double(gh, "latitudeOfFirstGridPointInDegrees", ylast), 0);
-  GRIB_CHECK(my_grib_set_double(gh, "latitudeOfLastGridPointInDegrees", yfirst), 0);
-  //yinc *= -1.0; // don't set yinc here ...
-  //GRIB_CHECK(my_grib_set_double(gh, "jDirectionIncrementInDegrees", yinc), 0);
-
-  if (cdiDebugExt>=10)
-  {
-    GRIB_CHECK(grib_get_double(gh, "latitudeOfFirstGridPointInDegrees", &latitudeOfFirstGridPointInDegrees), 0);  // yfirst
-    GRIB_CHECK(grib_get_double(gh, "latitudeOfLastGridPointInDegrees", &latitudeOfLastGridPointInDegrees), 0);    // ylast
-    GRIB_CHECK(grib_get_double(gh, "jDirectionIncrementInDegrees", &jDirectionIncrementInDegrees), 0);  // yinc
-    Message("CHANGED INTO:  yfirst = %f, ylast = %f, yinc = %f",latitudeOfFirstGridPointInDegrees,latitudeOfLastGridPointInDegrees, jDirectionIncrementInDegrees);
-  }
-}
-
-static void
-convertDataScanningMode(int scanModeIN, int scanModeOUT, double *data,
-                        int gridsize, int iDim, int jDim)
-{
-  int i,j;
-  int idxIN, idxOUT;
-
-   // 127: reserved for testing; it will generate test data in 64 scanning mode
-  if (scanModeOUT== 127)  // fill with testdata ...
-  {
-      scanModeOUT = 64;
-      if (cdiDebugExt>=30) printf("convertDataScanningMode(): Generating test data in 64 scanning mode..\n");
-      for (j=0; j<jDim; j++)
-      {
-        int jXiDim = j*iDim;
-        for (i=0; i<iDim; i++)
-        {
-          idxIN = i + jXiDim;
-          data[idxIN] = (double) (100.0*j +i);
-        }
-      }
-  }
-
-  if ( (iDim*jDim)!= gridsize)
-  {
-    if (cdiDebugExt>=30) printf("convertDataScanningMode(): ERROR: (iDim*jDim)!= gridsize;  (%d * %d) != %d\n", iDim,jDim, gridsize);
-    return;
-  }
-  if (cdiDebugExt>=30) printf("convertDataScanningMode(): scanModeIN=%02d => scanModeOUT=%02d ; where: (iDim * jDim == gridsize)  (%d*%d == %d)\n",scanModeIN, scanModeOUT, iDim,jDim, gridsize);
-
-  if (cdiDebugExt>=100)
-  {
-      printf("convertDataScanningMode(): data IN:\n");
-      for (j=0; j<jDim; j++)
-      {
-        int jXiDim = j*iDim;
-        for (i=0; i<iDim; i++)
-        {
-          idxIN = i + jXiDim;
-          printf("%03.0f, ",data[idxIN]);
-        }
-        printf("\n");
-      }
-  }
-
-  if (scanModeIN==scanModeOUT)
-  {
-    if (cdiDebugExt>=30) printf("convertDataScanningMode(): INFO: Nothing to do;  scanModeIN==scanModeOUT..\n");
-    return;
-  }
-
-  if (0)
-  {
-      return;
-      if (scanModeOUT==00)
-      {
-          if (cdiDebugExt>0) printf("convertDataScanningMode(): Leave data unchaged BUT set scanModeOUT=00.\n");
-          // CHECK:  Looks like that GRIB-API provide (no matter what) data in the scannning mode 00, even it is store in the gribfile as 64 !!
-          return;
-      }
-  }
-  double *dataCopy = NULL;
-  dataCopy = (double *) malloc(gridsize*sizeof(double));
-
-  memcpy((void*)dataCopy,(void*) data, gridsize*sizeof(double));
-
-  if (scanModeIN==64)           // Scanning Mode (00 dec)  +i, -j; i direction consecutive (row-major    order West->East   & South->North )
-  {                             // Scanning Mode (64 dec)  +i, +j; i direction consecutive (row-major    order West->East   & North->South )
-                                // Scanning Mode (96 dec)  +i, +j; j direction consecutive (column-major order North->South & West->East )
-      if (scanModeOUT==00)
-      // CHECK:  Looks like that GRIB-API provide (no matter what) data in the scannning mode 00, even it is store in the gribfile as 64 !!
-#define VERTICAL_FLIP
-#ifdef VERTICAL_FLIP
-      { // flip the data vertically ..
-        idxIN= 0; idxOUT= (jDim-1)*iDim;
-        if (cdiDebugExt>=30) printf("convertDataScanningMode():  copying rows nr. (%04d : %04d)\n",0,jDim-1);
-        for (j=0; j<jDim; j++)
-        {
-          memcpy((void*)&data[idxOUT], (void*)&dataCopy[idxIN], iDim*sizeof(double));
-          idxIN  += iDim; idxOUT -= iDim;
-        }
-      } // end if (scanModeOUT==00)*/
-#endif
-#ifdef HORIZONTAL_FLIP
-      { // flip data horizontally ...
-        if (1)
-        {
-            if (cdiDebugExt>=30) printf("convertDataScanningMode():  copying columns nr. (%04d : %04d);\n", 0, iDim-1);
-            for (i=0; i<iDim; i++)
-            {
-              for (j=0; j<jDim; j++)
-              {
-                int jXiDim = j*iDim;
-                idxIN  = i           + jXiDim;
-                //data[idxIN] = (double) (100.0*j +i);  // just some testdata ..
-                idxOUT = iDim - i -1 + jXiDim;
-                //printf("[%03d=>%03d] = %f;",idxIN,idxOUT,dataCopy[idxIN]);
-                data[idxOUT] =  dataCopy[idxIN];
-              }
-            }
-        }
-      } // end if (scanModeOUT==00)
-#endif
-
-      if (scanModeOUT==96)
-      { // transpose the data
-        if (cdiDebugExt>=30) printf("convertDataScanningMode():  transpose data rows=>columns nr. (%04d : %04d) => (%04d : %04d);\n", 0, iDim-1, 0, jDim-1);
-        for (j=0; j<jDim; j++)
-        {
-          int jXiDim = j*iDim;
-          for (i=0; i<iDim; i++)
-          {
-            idxIN  = i + jXiDim;
-            idxOUT = j + i*jDim;
-            //printf("[%03d=>%03d] = %f;",idxIN,idxOUT,dataCopy[idxIN]);
-            data[idxOUT] =  dataCopy[idxIN];
-          }
-          //printf(".\n");
-        }
-      } // end if (scanModeOUT==96)
-  } // end if (scanModeIN==64)
-
-  if (scanModeIN==00)           // Scanning Mode (00 dec)  +i, -j; i direction consecutive (row-major    order West->East   & South->North )
-  {                             // Scanning Mode (64 dec)  +i, +j; i direction consecutive (row-major    order West->East   & North->South )
-                               // Scanning Mode (96 dec)  +i, +j; j direction consecutive (column-major order North->South & West->East )
-    if (scanModeOUT==64)
-      { // flip the data vertically ..
-        idxIN= 0; idxOUT= (jDim-1)*iDim;
-        for (j=0; j<jDim; j++)
-        {
-          if (cdiDebugExt>=25) printf("convertDataScanningMode():  copying row nr. %04d; [idxIN=%08d] => [idxOUT=%08d]\n",j, idxIN, idxOUT);
-          memcpy((void*)&data[idxOUT], (void*)&dataCopy[idxIN], iDim*sizeof(double));
-          idxIN  += iDim; idxOUT -= iDim;
-        }
-      } // end if (scanModeOUT==64)
-
-      if (scanModeOUT==96)
-      { // transpose the data
-        int jInv;
-        for (j=0; j<jDim; j++)
-        {
-          if (cdiDebugExt>=30) printf("convertDataScanningMode():  processing row nr. %04d;\n", j);
-          jInv = (jDim-1) -j;
-          for (i=0; i<iDim; i++)
-            data[j + i*jDim] =  dataCopy[i + jInv*iDim];  // source data has -j
-        }
-      } // end if (scanModeOUT==96)
-  } // end if (scanModeIN==00)
-
-  if (scanModeIN==96)           // Scanning Mode (00 dec)  +i, -j; i direction consecutive (row-major    order West->East   & South->North )
-  {                             // Scanning Mode (64 dec)  +i, +j; i direction consecutive (row-major    order West->East   & North->South )
-                                // Scanning Mode (96 dec)  +i, +j; j direction consecutive (column-major order North->South & West->East )
-    if (scanModeOUT==64)
-      { // transpose the data
-        for (j=0; j<jDim; j++)
-        {
-          if (cdiDebugExt>=30) printf("convertDataScanningMode():  processing row nr. %04d;\n", j);
-          int jXiDim = j*iDim;
-          for (i=0; i<iDim; i++)
-            //data[j + i*jDim] =  dataCopy[i + j*iDim];
-            data[i + jXiDim] =  dataCopy[j + i*jDim];
-        }
-      } // end if (scanModeOUT==64)
-
-      if (scanModeOUT==00)
-      { // transpose the data
-        idxIN= 0; idxOUT= 0;
-        int jInv;
-        for (j=0; j<jDim; j++)
-        {
-          if (cdiDebugExt>=30) printf("convertDataScanningMode():  processing row nr. %04d;\n", j);
-          jInv = (jDim-1) -j;
-          int jXiDim = j*iDim;
-          for (i=0; i<iDim; i++)
-            //data[jInv + iXjDim] =  dataCopy[i + jXiDim];  // target data has -j
-            data[i + jXiDim] =  dataCopy[jInv + i*jDim];  // target data has -j
-        }
-      } // end if (scanModeOUT==00)
-  } // end if (scanModeIN==96)
-
-  if (cdiDebugExt>=100)
-  {
-      printf("convertDataScanningMode(): data OUT (new scanning mode):\n");
-      for (j=0; j<jDim; j++)
-      {
-        int jXiDim = j*iDim;
-        for (i=0; i<iDim; i++)
-        {
-          idxIN = i + jXiDim;
-          printf("%03.0f, ",data[idxIN]);
-        }
-        printf("\n");
-      }
-  }
-
-  free(dataCopy); return;
-}
-#endif //HIRLAM_EXTENSIONS
-
-static
-void gribapiSetExtMode(grib_handle *gh, int gridID, long datasize, const double *data)
-{
-  /*
-  Nj = 550;
-  latitudeOfFirstGridPointInDegrees = -30.8;
-  latitudeOfLastGridPointInDegrees = 24.1;
-  iScansNegatively = 0;
-  jScansPositively = 0;
-  jPointsAreConsecutive = 0;
-  jDirectionIncrementInDegrees = 0.1; */
-#ifndef HIRLAM_EXTENSIONS
-  (void)data;
-  (void)datasize;
-#endif
-  int gridtype = gridInqType(gridID);
-  if ( gridtype == GRID_GENERIC || gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN ||
-       gridtype == GRID_GAUSSIAN_REDUCED || gridtype == GRID_PROJECTION )
-    {
-#ifdef HIRLAM_EXTENSIONS
-      int scanModeIN = gridInqScanningMode(gridID);
-
-      if (cdiDebugExt>=100)
-        {
-          int gridsize = gridInqSize(gridID);
-          Message("(scanModeIN=%d; gridsize=%d", scanModeIN, gridsize);
-        }
-
-      if ( cdiGribDataScanningMode.active )   // allowed modes: <0, 64, 96>; Default is 64
-        {
-          int iDim = gridInqXsize(gridID);
-          int jDim = gridInqYsize(gridID);
-
-          double yfirst = gridInqYval(gridID,      0);
-          double ylast  = gridInqYval(gridID, jDim-1);
-          double yinc   = gridInqYinc(gridID);
-
-          int scanModeOUT = cdiGribDataScanningMode.value;
-          convertDataScanningMode(scanModeIN, scanModeOUT, (double*)data, datasize, iDim, jDim);
-          // This will overrule the old scanning mode of the given grid
-          if (cdiDebugExt>=10) Message("Set GribDataScanningMode (%d) => (%d)", scanModeIN, cdiGribDataScanningMode.value);
-          gribapiSetScanningMode(gh, cdiGribDataScanningMode.value);
-
-          if (((scanModeIN==00) && (cdiGribDataScanningMode.value==64)) ||
-              ((scanModeIN==64) && (cdiGribDataScanningMode.value==00)) )
-            verticallyFlipGridDefinitionWhenScanningModeChanged(gh, yfirst, ylast, yinc);
-        }
-      else
-        {
-          if (cdiDebugExt>=100) Message("Set GribDataScanningMode => (%d) based on used grid", scanModeIN);
-          gribapiSetScanningMode(gh, scanModeIN);
-        }
-#endif
-
-      if ( cdiGribChangeModeUvRelativeToGrid.active )
-        {
-          // this will overrule/change the UvRelativeToGrid flag;
-          // typically when the wind is rotated with respect to north pole
-          if (cdiDebugExt>=100) Message("Set ModeUvRelativeToGrid =>%d ( note grid has: %d)", cdiGribChangeModeUvRelativeToGrid.mode, gridInqUvRelativeToGrid(gridID));
-          GRIB_CHECK(my_grib_set_long(gh, "uvRelativeToGrid", (long) cdiGribChangeModeUvRelativeToGrid.mode), 0);
-        }
-      else
-        {
-          if (cdiDebugExt>=100) Message("Set ModeUvRelativeToGrid =>%d based on used grid", gridInqUvRelativeToGrid(gridID));
-          gribapiSetUvRelativeToGrid(gh, gridInqUvRelativeToGrid(gridID));
-        }
-    }
-}
-
 /* #define GRIBAPIENCODETEST 1 */
 
 size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisID,
@@ -52020,7 +51303,7 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
   long editionNumber = 2;
   char name[256];
   char stdname[256];
-
+  gribContainer_t *gc = (gribContainer_t *) gribContainer;
   // extern unsigned char _grib_template_GRIB2[];
 
   int param    = vlistInqVarParam(vlistID, varID);
@@ -52034,11 +51317,8 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
 #if defined(GRIBAPIENCODETEST)
   grib_handle *gh = (grib_handle *) gribHandleNew(editionNumber);
 #else
-  gribContainer_t *gc = (gribContainer_t *) gribContainer;
-  assert(gc != NULL);
   grib_handle *gh = (struct grib_handle *)gc->gribHandle;
 #endif
-
   GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
 
   if ( editionNumber == 2 )
@@ -52056,15 +51336,14 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
     }
   */
 
-  gribapiDefTime((int)editionNumber, productDefinitionTemplate, typeOfGeneratingProcess,
-                 gh, vdate, vtime, tsteptype, numavg, vlistInqTaxis(vlistID), gc->init);
+  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);
 
   if ( ! gc->init ) gribapiDefParam((int)editionNumber, gh, param, name, stdname);
 
-  if ( editionNumber == 2 && (datatype == CDI_DATATYPE_FLT32 || datatype == CDI_DATATYPE_FLT64) ) lieee = true;
+  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 )
@@ -52075,7 +51354,7 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
 
   gribapiDefGrid((int)editionNumber, gh, gridID, comptype, lieee, datatype, nmiss, gc->init);
 
-  gribapiDefLevel((int)editionNumber, gh, zaxisID, levelID, gc->init, productDefinitionTemplate);
+  gribapiDefLevel((int)editionNumber, gh, param, zaxisID, levelID, gc->init, productDefinitionTemplate);
 
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
   //if (!gc->init)
@@ -52091,7 +51370,7 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
           {
             //DR: Fix for multi-level fields (otherwise only the 1st level is correct)
             if ( zaxisInqSize(zaxisID)==(levelID+1) )
-              vlistptr->vars[varID].opt_grib_kvpair[i].update = false;
+              vlistptr->vars[varID].opt_grib_kvpair[i].update = FALSE;
 
             if (vlistptr->vars[varID].opt_grib_kvpair[i].data_type == t_double)
               {
@@ -52123,8 +51402,6 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
       GRIB_CHECK(my_grib_set_double(gh, "missingValue", vlistInqVarMissval(vlistID, varID)), 0);
     }
 
-  gribapiSetExtMode(gh, gridID, datasize, data);
-
   GRIB_CHECK(grib_set_double_array(gh, "values", data, (size_t)datasize), 0);
 
   /* get the size of coded message  */
@@ -52140,24 +51417,10 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
   gribHandleDelete(gh);
 #endif
 
-  gc->init = true;
+  gc->init = TRUE;
 
   return recsize;
 }
-
-
-void gribapiChangeParameterIdentification(grib_handle *gh, int code, int ltype, int lev)
-{
-  long  indicatorOfParameter,  indicatorOfTypeOfLevel,  level; //  timeRangeIndicator: could be included later
-  indicatorOfParameter = code;
-  indicatorOfTypeOfLevel = ltype;
-  level = lev;
-
-  if (indicatorOfParameter!=-1) GRIB_CHECK(my_grib_set_long(gh, "indicatorOfParameter", indicatorOfParameter), 0);
-  if (indicatorOfTypeOfLevel!=-1) GRIB_CHECK(my_grib_set_long(gh, "indicatorOfTypeOfLevel", indicatorOfTypeOfLevel), 0);
-  if (level!=-1) GRIB_CHECK(my_grib_set_long(gh, "level", level), 0);
-}
-
 #endif
 
 /*
@@ -52173,22 +51436,16 @@ void gribapiChangeParameterIdentification(grib_handle *gh, int code, int ltype,
 #endif
 
 
-static inline bool
-filetypeIsNetCDF(int filetype)
-{
-  return filetype == CDI_FILETYPE_NC
-    ||   filetype == CDI_FILETYPE_NC2
-    ||   filetype == CDI_FILETYPE_NC4
-    ||   filetype == CDI_FILETYPE_NC4C;
-}
-
 
 void streamDefHistory(int streamID, int length, const char *history)
 {
 #ifdef HAVE_LIBNETCDF
   stream_t *streamptr = stream_to_pointer(streamID);
 
-  if ( filetypeIsNetCDF(streamptr->filetype) )
+  if ( streamptr->filetype == FILETYPE_NC  ||
+       streamptr->filetype == FILETYPE_NC2 ||
+       streamptr->filetype == FILETYPE_NC4 ||
+       streamptr->filetype == FILETYPE_NC4C )
     {
       char *histstring;
       size_t len;
@@ -52217,7 +51474,10 @@ int streamInqHistorySize(int streamID)
 #ifdef HAVE_LIBNETCDF
   stream_t *streamptr = stream_to_pointer(streamID);
 
-  if ( filetypeIsNetCDF(streamptr->filetype) )
+  if ( streamptr->filetype == FILETYPE_NC  ||
+       streamptr->filetype == FILETYPE_NC2 ||
+       streamptr->filetype == FILETYPE_NC4 ||
+       streamptr->filetype == FILETYPE_NC4C )
     {
       size = cdfInqHistorySize(streamptr);
     }
@@ -52233,7 +51493,10 @@ void streamInqHistoryString(int streamID, char *history)
 #ifdef HAVE_LIBNETCDF
   stream_t *streamptr = stream_to_pointer(streamID);
 
-  if ( filetypeIsNetCDF(streamptr->filetype) )
+  if ( streamptr->filetype == FILETYPE_NC  ||
+       streamptr->filetype == FILETYPE_NC2 ||
+       streamptr->filetype == FILETYPE_NC4 ||
+       streamptr->filetype == FILETYPE_NC4C )
     {
       cdfInqHistoryString(streamptr, history);
     }
@@ -52264,30 +51527,46 @@ void streamInqHistoryString(int streamID, char *history)
 
 
 
+#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_t;
+} IEGCOMPVAR;
 
 
-static
-int iegInqDatatype(int prec)
+static int iegInqDatatype(int prec)
 {
-  return (prec == EXSE_DOUBLE_PRECISION) ? CDI_DATATYPE_FLT64 : CDI_DATATYPE_FLT32;
+  int datatype;
+
+  if ( prec == DOUBLE_PRECISION ) datatype = DATATYPE_FLT64;
+  else                            datatype = DATATYPE_FLT32;
+
+  return (datatype);
 }
 
-static
-int iegDefDatatype(int datatype)
+
+static int iegDefDatatype(int datatype)
 {
-  if ( datatype == CDI_DATATYPE_CPX32 || datatype == CDI_DATATYPE_CPX64 )
+  int prec;
+
+  if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
     Error("CDI/IEG library does not support complex numbers!");
 
-  if ( datatype != CDI_DATATYPE_FLT32 && datatype != CDI_DATATYPE_FLT64 )
-    datatype = CDI_DATATYPE_FLT32;
+  if ( datatype != DATATYPE_FLT32 && datatype != DATATYPE_FLT64 )
+    datatype = DATATYPE_FLT32;
+
+  if ( datatype == DATATYPE_FLT64 ) prec = DOUBLE_PRECISION;
+  else                              prec = SINGLE_PRECISION;
 
-  return (datatype == CDI_DATATYPE_FLT64) ? EXSE_DOUBLE_PRECISION : EXSE_SINGLE_PRECISION;
+  return (prec);
 }
 
 /* not used
@@ -52307,7 +51586,7 @@ int iegInqRecord(stream_t *streamptr, int *varID, int *levelID)
   *levelID = -1;
 
   status = iegRead(fileID, iegp);
-  if ( status != 0 ) return 0;
+  if ( status != 0 ) return (0);
 
   icode  = IEG_P_Parameter(iegp->ipdb);
   if ( IEG_P_LevelType(iegp->ipdb) == IEG_LTYPE_HYBRID_LAYER )
@@ -52317,43 +51596,51 @@ int iegInqRecord(stream_t *streamptr, int *varID, int *levelID)
 
   *varID = vlistInqVarID(vlistID, icode);
 
-  if ( *varID == CDI_UNDEFID ) Error("Code %d undefined", icode);
+  if ( *varID == UNDEFID ) Error("Code %d undefined", icode);
 
   zaxisID = vlistInqVarZaxis(vlistID, *varID);
 
   *levelID = zaxisInqLevelID(zaxisID, (double) ilevel);
 
-  return 1;
+  return (1);
 }
 */
 
 void iegReadRecord(stream_t *streamptr, double *data, int *nmiss)
 {
-  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];
-  int varID   = streamptr->tsteps[tsID].records[recID].varID;
-  off_t recpos = streamptr->tsteps[tsID].records[recID].position;
+  int vlistID, fileID;
+  int status;
+  int recID, vrecID, tsID;
+  off_t recpos;
+  int varID, gridID;
+  int i, size;
+  double missval;
+  void *iegp = 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);
 
-  void *iegp = streamptr->record->exsep;
-  int status = iegRead(fileID, iegp);
+  status = iegRead(fileID, iegp);
   if ( status != 0 )
     Error("Could not read IEG record!");
 
   iegInqDataDP(iegp, data);
 
-  double missval = vlistInqVarMissval(vlistID, varID);
-  int gridID  = vlistInqVarGrid(vlistID, varID);
-  int size    = gridInqSize(gridID);
+  missval = vlistInqVarMissval(vlistID, varID);
+  gridID  = vlistInqVarGrid(vlistID, varID);
+  size    = gridInqSize(gridID);
 
   streamptr->numvals += size;
 
   *nmiss = 0;
-  for ( int i = 0; i < size; i++ )
+  for ( i = 0; i < size; i++ )
     if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
       {
 	data[i] = missval;
@@ -52413,18 +51700,19 @@ int iegGetZaxisType(int iegleveltype)
       }
     }
 
-  return leveltype;
+  return (leveltype);
 }
 
 
 static 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 )
     {
-      int year, month, day, hour, minute, second;
       cdiDecodeDate(date, &year, &month, &day);
       cdiDecodeTime(time, &hour, &minute, &second);
 
@@ -52475,25 +51763,21 @@ calc_resfac(double xfirst, double xlast, double xinc, double yfirst, double ylas
         }
     }
 
-  return resfac;
+  return (resfac);
 }
 
 static
 void iegDefGrid(int *gdb, int gridID)
 {
-  int projID = gridInqProj(gridID);
-  if ( projID != CDI_UNDEFID && gridInqProjType(projID) == CDI_PROJ_RLL ) gridID = projID;
-
   int gridtype = gridInqType(gridID);
 
-  int projtype = CDI_UNDEFID;
-  if ( gridtype == GRID_PROJECTION && gridInqProjType(gridID) == CDI_PROJ_RLL ) projtype = CDI_PROJ_RLL;
-
-  int xsize = gridInqXsize(gridID);
-  int ysize = gridInqYsize(gridID);
-
   if ( gridtype == GRID_GENERIC )
     {
+      int xsize, ysize;
+
+      xsize = gridInqXsize(gridID);
+      ysize = gridInqYsize(gridID);
+
       if ( (ysize == 32  || ysize == 48 || ysize == 64 ||
 	    ysize == 96  || ysize == 160) &&
 	   (xsize == 2*ysize || xsize == 1) )
@@ -52517,32 +51801,39 @@ void iegDefGrid(int *gdb, int gridID)
       gridtype = GRID_LONLAT;
     }
 
-  bool lrotated = (projtype == CDI_PROJ_RLL);
-
-  if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN || projtype == CDI_PROJ_RLL )
+  if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN )
     {
       double xfirst = 0, xlast = 0, xinc = 0;
       double yfirst = 0, ylast = 0, yinc = 0;
 
-      if ( xsize == 0 ) xsize = 1;
+      int nlon = gridInqXsize(gridID),
+        nlat = gridInqYsize(gridID);
+
+      if ( nlon == 0 )
+	{
+	  nlon = 1;
+	}
       else
 	{
-	  xfirst = gridInqXval(gridID,       0);
-	  xlast  = gridInqXval(gridID, xsize-1);
+	  xfirst = gridInqXval(gridID,      0);
+	  xlast  = gridInqXval(gridID, nlon-1);
 	  xinc   = gridInqXinc(gridID);
 	}
 
-      if ( ysize == 0 ) ysize = 1;
+      if ( nlat == 0 )
+	{
+	  nlat = 1;
+	}
       else
 	{
-	  yfirst = gridInqYval(gridID,       0);
-	  ylast  = gridInqYval(gridID, ysize-1);
+	  yfirst = gridInqYval(gridID,      0);
+	  ylast  = gridInqYval(gridID, nlat-1);
 	  yinc   = gridInqYinc(gridID);
 	}
 
       if ( gridtype == GRID_GAUSSIAN )
 	IEG_G_GridType(gdb) = 4;
-      else if ( lrotated )
+      else if ( gridtype == GRID_LONLAT && gridIsRotated(gridID) )
 	IEG_G_GridType(gdb) = 10;
       else
 	IEG_G_GridType(gdb) = 0;
@@ -52553,8 +51844,8 @@ void iegDefGrid(int *gdb, int gridID)
 
       IEG_G_ResFac(gdb)   = iresfac;
 
-      IEG_G_NumLon(gdb)   = xsize;
-      IEG_G_NumLat(gdb)   = ysize;
+      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);
@@ -52564,7 +51855,7 @@ void iegDefGrid(int *gdb, int gridID)
 	IEG_G_LonIncr(gdb) = 0;
 
       if ( gridtype == GRID_GAUSSIAN )
-	IEG_G_LatIncr(gdb) = ysize/2;
+	IEG_G_LatIncr(gdb) = nlat/2;
       else
 	{
 	  IEG_G_LatIncr(gdb) = (int)lround(yinc*resfac);
@@ -52580,15 +51871,15 @@ void iegDefGrid(int *gdb, int 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_LonIncr(gdb) = IEG_G_LatIncr(gdb);
 
-      IEG_G_ResFlag(gdb) = (IEG_G_LatIncr(gdb) == 0 || IEG_G_LonIncr(gdb) == 0) ? 0 : 128;
+      if ( IEG_G_LatIncr(gdb) == 0 || IEG_G_LonIncr(gdb) == 0 )
+	IEG_G_ResFlag(gdb) = 0;
+      else
+	IEG_G_ResFlag(gdb) = 128;
 
-      if ( lrotated )
+      if ( gridIsRotated(gridID) )
 	{
-          double xpole = 0, ypole = 0, angle = 0;
-          gridInqParamRLL(gridID, &xpole, &ypole, &angle);
-
-	  IEG_G_LatSP(gdb) = - (int)lround(ypole * resfac);
-	  IEG_G_LonSP(gdb) =   (int)lround((xpole + 180) * resfac);
+	  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
@@ -52605,25 +51896,19 @@ void iegDefGrid(int *gdb, int gridID)
 }
 
 static
-void pdbDefLevel(int *pdb, int leveltype, int level1, int level2)
-{
-  IEG_P_LevelType(pdb) = leveltype;
-  IEG_P_Level1(pdb)    = level1;
-  IEG_P_Level2(pdb)    = level2;
-}
-
-static
 void iegDefLevel(int *pdb, int *gdb, double *vct, int zaxisID, int levelID)
 {
   double level;
-  int ilevel;
+  int ilevel, leveltype;
+  static int vct_warning = 1;
 
-  int leveltype = zaxisInqType(zaxisID);
+  leveltype = zaxisInqType(zaxisID);
 
   if ( leveltype == ZAXIS_GENERIC )
     {
       Message("Changed zaxis type from %s to %s",
-	      zaxisNamePtr(leveltype), zaxisNamePtr(ZAXIS_PRESSURE));
+	      zaxisNamePtr(leveltype),
+	      zaxisNamePtr(ZAXIS_PRESSURE));
       leveltype = ZAXIS_PRESSURE;
       zaxisChangeType(zaxisID, leveltype);
       zaxisDefUnits(zaxisID, "Pa");
@@ -52635,26 +51920,36 @@ void iegDefLevel(int *pdb, int *gdb, double *vct, int zaxisID, int levelID)
     {
     case ZAXIS_SURFACE:
       {
-        pdbDefLevel(pdb, IEG_LTYPE_SURFACE, 0, (int)(zaxisInqLevel(zaxisID, levelID)));
+	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;
+
 	if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
-          pdbDefLevel(pdb, IEG_LTYPE_HYBRID_LAYER, (int)(zaxisInqLbound(zaxisID, levelID)),
-                      (int)(zaxisInqUbound(zaxisID, levelID)));
+	  {
+	    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
-          pdbDefLevel(pdb, IEG_LTYPE_HYBRID, 0, (int)(zaxisInqLevel(zaxisID, levelID)));
+	  {
+	    IEG_P_LevelType(pdb) = IEG_LTYPE_HYBRID;
+	    IEG_P_Level1(pdb)    = 0;
+	    IEG_P_Level2(pdb)    = (int)(zaxisInqLevel(zaxisID, levelID));
+	  }
 
-	int vctsize = zaxisInqVctSize(zaxisID);
+	vctsize = zaxisInqVctSize(zaxisID);
 	if ( vctsize > 100 )
 	  {
-            static bool vct_warning = true;
 	    /*	    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 = false;
+		vct_warning = 0;
 	      }
 	  }
 	else
@@ -52668,10 +51963,11 @@ void iegDefLevel(int *pdb, int *gdb, double *vct, int zaxisID, int levelID)
     case ZAXIS_PRESSURE:
       {
 	double dum;
-	char units[CDI_MAX_NAME];
+	char units[128];
 
 	level = zaxisInqLevel(zaxisID, levelID);
-	if ( level < 0 ) Warning("pressure level of %f Pa is below 0.", level);
+	if ( level < 0 )
+	  Warning("pressure level of %f Pa is below 0.", level);
 
 	zaxisInqUnits(zaxisID, units);
 	if ( memcmp(units, "hPa", 3) == 0 || memcmp(units, "mb",2 ) == 0 )
@@ -52679,43 +51975,81 @@ void iegDefLevel(int *pdb, int *gdb, double *vct, int zaxisID, int levelID)
 
 	ilevel = (int) level;
 	if ( level < 32768 && (level < 100 || modf(level/100, &dum) > 0) )
-          pdbDefLevel(pdb, IEG_LTYPE_99, 0, ilevel);
+	  {
+	    IEG_P_LevelType(pdb) = IEG_LTYPE_99;
+	    IEG_P_Level1(pdb)    = 0;
+	    IEG_P_Level2(pdb)    = ilevel;
+	  }
 	else
-          pdbDefLevel(pdb, IEG_LTYPE_ISOBARIC, 0, ilevel/100);
-
-        break;
+	  {
+	    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);
-        pdbDefLevel(pdb, IEG_LTYPE_HEIGHT, 0, (int)level);
+
+	ilevel = (int) level;
+	IEG_P_LevelType(pdb) = IEG_LTYPE_HEIGHT;
+	IEG_P_Level1(pdb)    = 0;
+	IEG_P_Level2(pdb)    = ilevel;
+
 	break;
       }
     case ZAXIS_ALTITUDE:
       {
 	level = zaxisInqLevel(zaxisID, levelID);
-        pdbDefLevel(pdb, IEG_LTYPE_ALTITUDE, 0, (int)level);
+
+	ilevel = (int) level;
+	IEG_P_LevelType(pdb) = IEG_LTYPE_ALTITUDE;
+	IEG_P_Level1(pdb)    = 0;
+	IEG_P_Level2(pdb)    = ilevel;
+
 	break;
       }
     case ZAXIS_DEPTH_BELOW_LAND:
       {
 	if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
-          pdbDefLevel(pdb, IEG_LTYPE_LANDDEPTH_LAYER, (int)(zaxisInqLbound(zaxisID, levelID)), (int)(zaxisInqUbound(zaxisID, levelID)));
+	  {
+	    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
-          pdbDefLevel(pdb, IEG_LTYPE_LANDDEPTH, 0, (int)(zaxisInqLevel(zaxisID, levelID)));
+	  {
+	    level = zaxisInqLevel(zaxisID, levelID);
+
+	    ilevel = (int) level;
+	    IEG_P_LevelType(pdb) = IEG_LTYPE_LANDDEPTH;
+	    IEG_P_Level1(pdb)    = 0;
+	    IEG_P_Level2(pdb)    = ilevel;
+	  }
 
 	break;
       }
     case ZAXIS_DEPTH_BELOW_SEA:
       {
 	level = zaxisInqLevel(zaxisID, levelID);
-        pdbDefLevel(pdb, IEG_LTYPE_SEADEPTH, 0, (int)level);
+
+	ilevel = (int) level;
+	IEG_P_LevelType(pdb) = IEG_LTYPE_SEADEPTH;
+	IEG_P_Level1(pdb)    = 0;
+	IEG_P_Level2(pdb)    = ilevel;
+
 	break;
       }
     case ZAXIS_ISENTROPIC:
       {
 	level = zaxisInqLevel(zaxisID, levelID);
-        pdbDefLevel(pdb, 113, 0, (int)level);
+
+	ilevel = (int) level;
+	IEG_P_LevelType(pdb) = 113;
+	IEG_P_Level1(pdb)    = 0;
+	IEG_P_Level2(pdb)    = ilevel;
+
 	break;
       }
     default:
@@ -52735,55 +52069,68 @@ void iegCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
 
 void iegDefRecord(stream_t *streamptr)
 {
-  Record *record = streamptr->record;
-  iegrec_t *iegp = (iegrec_t*) record->exsep;
+  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;
 
-  int vlistID = streamptr->vlistID;
-  int byteorder = streamptr->byteorder;
+  vlistID = streamptr->vlistID;
+  byteorder = streamptr->byteorder;
 
-  int varID   = record->varID;
-  int levelID = record->levelID;
-  int tsID    = streamptr->curTsID;
+  varID   = streamptr->record->varID;
+  levelID = streamptr->record->levelID;
+  tsID    = streamptr->curTsID;
 
-  int gridID  = vlistInqVarGrid(vlistID, varID);
-  int zaxisID = vlistInqVarZaxis(vlistID, varID);
+  gridID  = vlistInqVarGrid(vlistID, varID);
+  zaxisID = vlistInqVarZaxis(vlistID, varID);
 
   iegInitMem(iegp);
-  for ( int i = 0; i < 37; i++ ) iegp->ipdb[i] = -1;
+  for ( i = 0; i < 37; i++ ) iegp->ipdb[i] = -1;
 
   iegp->byteswap = getByteswap(byteorder);
 
-  int param = vlistInqVarParam(vlistID, varID);
-  int pdis, pcat, pnum;
+  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;
 
-  int date = streamptr->tsteps[tsID].taxis.vdate;
-  int time = streamptr->tsteps[tsID].taxis.vtime;
   iegDefTime(iegp->ipdb, date, time, vlistInqTaxis(vlistID));
   iegDefGrid(iegp->igdb, gridID);
   iegDefLevel(iegp->ipdb, iegp->igdb, iegp->vct, zaxisID, levelID);
 
-  iegp->dprec = iegDefDatatype(record->prec);
+  datatype = streamptr->record->prec;
+
+  iegp->dprec = iegDefDatatype(datatype);
 }
 
 
 void iegWriteRecord(stream_t *streamptr, const double *data)
 {
-  Record *record = streamptr->record;
-  iegrec_t *iegp = (iegrec_t*) record->exsep;
+  int fileID;
+  int i, gridsize, gridID;
+  double refval;
+  iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
 
-  int fileID = streamptr->fileID;
-  int gridsize = gridInqSize(record->gridID);
+  fileID = streamptr->fileID;
+  gridID = streamptr->record->gridID;
+
+  gridsize = gridInqSize(gridID);
 
-  double refval = data[0];
-  for ( int i = 1; i < gridsize; i++ )
+  refval = data[0];
+  for ( i = 1; i < gridsize; i++ )
     if ( data[i] < refval ) refval = data[i];
 
   iegp->refval = refval;
 
   iegDefDataDP(iegp, data);
+
   iegWrite(fileID, iegp);
 }
 
@@ -52791,6 +52138,7 @@ static
 void iegAddRecord(stream_t *streamptr, int param, int *pdb, int *gdb, double *vct,
 		  size_t recsize, off_t position, int prec)
 {
+  int levelID = 0;
   int vlistID = streamptr->vlistID;
   int tsID    = streamptr->curTsID;
   int recID   = recordNewEntry(streamptr, tsID);
@@ -52816,20 +52164,18 @@ void iegAddRecord(stream_t *streamptr, int param, int *pdb, int *gdb, double *vc
   record->ilevel2  = level2;
   record->ltype    = IEG_P_LevelType(pdb);
 
-  int gridtype = (IEG_G_GridType(gdb) == 0) ? GRID_LONLAT :
-                 (IEG_G_GridType(gdb) == 10) ? GRID_PROJECTION :
-                 (IEG_G_GridType(gdb) == 4) ? GRID_GAUSSIAN : GRID_GENERIC;
+  int gridtype =
+   ( IEG_G_GridType(gdb) == 0 || IEG_G_GridType(gdb) == 10 ) ? GRID_LONLAT :
+    ( IEG_G_GridType(gdb) == 4 ) ? GRID_GAUSSIAN : GRID_GENERIC;
 
   grid_t *grid = (grid_t *)Malloc(sizeof (*grid));
   grid_init(grid);
   cdiGridTypeInit(grid, gridtype, IEG_G_NumLon(gdb)*IEG_G_NumLat(gdb));
-  int xsize = IEG_G_NumLon(gdb);
-  int ysize = IEG_G_NumLat(gdb);
-  grid->x.size = xsize;
-  grid->y.size = ysize;
-  grid->x.inc  = 0;
-  grid->y.inc  = 0;
-  grid->x.flag = 0;
+  grid->xsize = IEG_G_NumLon(gdb);
+  grid->ysize = IEG_G_NumLat(gdb);
+  grid->xinc  = 0;
+  grid->yinc  = 0;
+  grid->xdef  = 0;
 
   int iresfac = IEG_G_ResFac(gdb);
   if ( iresfac == 0 ) iresfac = 1000;
@@ -52837,65 +52183,78 @@ void iegAddRecord(stream_t *streamptr, int param, int *pdb, int *gdb, double *vc
 
   /* if ( IEG_G_FirstLon != 0 || IEG_G_LastLon != 0 ) */
   {
-    if ( xsize > 1 )
+    if ( grid->xsize > 1 )
       {
 	if ( IEG_G_ResFlag(gdb) && IEG_G_LonIncr(gdb) > 0 )
-	  grid->x.inc = IEG_G_LonIncr(gdb) * resfac;
+	  grid->xinc = IEG_G_LonIncr(gdb) * resfac;
 	else
-	  grid->x.inc = (IEG_G_LastLon(gdb) - IEG_G_FirstLon(gdb)) * resfac / (xsize - 1);
+	  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. / xsize;
-            /* FIXME: why not use grid->x.inc != xinc as condition? */
-	    if ( fabs(grid->x.inc-xinc) > 0.0 )
+	    double xinc = 360. / grid->xsize;
+            /* FIXME: why not use grid->xinc != xinc as condition? */
+	    if ( fabs(grid->xinc-xinc) > 0.0 )
 	      {
-		grid->x.inc = xinc;
-		if ( CDI_Debug ) Message("set xinc to %g", grid->x.inc);
+		grid->xinc = xinc;
+		if ( CDI_Debug ) Message("set xinc to %g", grid->xinc);
 	      }
 	  }
       }
-    grid->x.first = IEG_G_FirstLon(gdb) * resfac;
-    grid->x.last  = IEG_G_LastLon(gdb)  * resfac;
-    grid->x.flag  = 2;
+    grid->xfirst = IEG_G_FirstLon(gdb) * resfac;
+    grid->xlast  = IEG_G_LastLon(gdb)  * resfac;
+    grid->xdef   = 2;
   }
-  grid->y.flag = 0;
+  grid->ydef  = 0;
   /* if ( IEG_G_FirstLat != 0 || IEG_G_LastLat != 0 ) */
   {
-    if ( ysize > 1 )
+    if ( grid->ysize > 1 )
       {
 	if ( IEG_G_ResFlag(gdb) && IEG_G_LatIncr(gdb) > 0 )
-	  grid->y.inc = IEG_G_LatIncr(gdb) * resfac;
+	  grid->yinc = IEG_G_LatIncr(gdb) * resfac;
 	else
-	  grid->y.inc = (IEG_G_LastLat(gdb) - IEG_G_FirstLat(gdb)) * resfac / (ysize - 1);
+	  grid->yinc = (IEG_G_LastLat(gdb) - IEG_G_FirstLat(gdb)) * resfac / (grid->ysize - 1);
       }
-    grid->y.first = IEG_G_FirstLat(gdb) * resfac;
-    grid->y.last  = IEG_G_LastLat(gdb)  * resfac;
-    grid->y.flag  = 2;
+    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;
 
-  double xpole = 0, ypole = 0;
+  grid->isRotated = FALSE;
   if ( IEG_G_GridType(gdb) == 10 )
     {
-      xpole =   IEG_G_LonSP(gdb) * resfac - 180;
-      ypole = - IEG_G_LatSP(gdb) * resfac;
-      grid->projtype = CDI_PROJ_RLL;
+      grid->isRotated = TRUE;
+      grid->ypole     = - IEG_G_LatSP(gdb) * resfac;
+      grid->xpole     =   IEG_G_LonSP(gdb) * resfac - 180;
+      grid->angle     = 0;
     }
 
-  struct addIfNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 0);
+  struct addIffNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 0);
   int gridID = gridAdded.Id;
-  if ( !gridAdded.isNew ) Free(grid);
-  else if ( gridtype == GRID_PROJECTION ) gridDefParamRLL(gridID, xpole, ypole, 0);
+  if (!gridAdded.isNew) Free(grid);
 
   int leveltype = iegGetZaxisType(IEG_P_LevelType(pdb));
+
   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];
+      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);
     }
@@ -52905,7 +52264,6 @@ void iegAddRecord(stream_t *streamptr, int param, int *pdb, int *gdb, double *vc
   int datatype = iegInqDatatype(prec);
 
   int varID;
-  int levelID = 0;
   varAddRecord(recID, param, gridID, leveltype, lbounds, level1, level2, 0, 0,
 	       datatype, &varID, &levelID, TSTEP_INSTANT, 0, 0, -1,
                NULL, NULL, NULL, NULL, NULL, NULL);
@@ -52917,7 +52275,8 @@ void iegAddRecord(stream_t *streamptr, int param, int *pdb, int *gdb, double *vc
   streamptr->nrecs++;
 
   if ( CDI_Debug )
-    Message("varID = %d gridID = %d levelID = %d", varID, gridID, levelID);
+    Message("varID = %d gridID = %d levelID = %d",
+	    varID, gridID, levelID);
 }
 
 #if 0
@@ -52927,8 +52286,9 @@ void iegCmpRecord(stream_t *streamptr, int tsID, int recID, off_t position, int
 {
   int varID = 0;
   int levelID = 0;
+  record_t *record;
 
-  record_t *record  = &streamptr->tsteps[tsID].records[recID];
+  record  = &streamptr->tsteps[tsID].records[recID];
 
   if ( param != (*record).param || level != (*record).ilevel )
     Error("inconsistent timestep");
@@ -52948,15 +52308,17 @@ void iegCmpRecord(stream_t *streamptr, int tsID, int recID, off_t position, int
 }
 #endif
 
-static
-void iegDateTime(int *pdb, int *date, int *time)
+static void iegDateTime(int *pdb, int *date, int *time)
 {
-  int ryear   = IEG_P_Year(pdb);
-  int rmonth  = IEG_P_Month(pdb);
-  int rday    = IEG_P_Day(pdb);
+  int ryear, rmonth, rday, rhour, rminute;
 
-  int rhour   = IEG_P_Hour(pdb);
-  int rminute = IEG_P_Minute(pdb);
+  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;
 
@@ -52967,39 +52329,51 @@ void iegDateTime(int *pdb, int *date, int *time)
 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 datetime0 = { LONG_MIN, LONG_MIN };
+  int tsID;
+  int varID;
+  size_t recsize;
   off_t recpos;
-  iegcompvar_t compVar, compVar0;
+  int nrecords, nrecs, recID;
+  int taxisID = -1;
+  taxis_t *taxis;
+  int vlistID;
+  IEGCOMPVAR compVar, compVar0;
   iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
 
   streamptr->curTsID = 0;
 
-  int tsID = tstepsNewEntry(streamptr);
-  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
+  tsID  = tstepsNewEntry(streamptr);
+  taxis = &streamptr->tsteps[tsID].taxis;
 
   if ( tsID != 0 )
     Error("Internal problem! tstepsNewEntry returns %d", tsID);
 
-  int fileID = streamptr->fileID;
+  fileID = streamptr->fileID;
 
-  int nrecs = 0;
-  while ( true )
+  nrecs = 0;
+  while ( TRUE )
     {
       recpos = fileGetPos(fileID);
-      int status = iegRead(fileID, iegp);
+      status = iegRead(fileID, iegp);
       if ( status != 0 )
 	{
 	  streamptr->ntsteps = 1;
 	  break;
 	}
-      size_t recsize = (size_t)(fileGetPos(fileID) - recpos);
+      recsize = (size_t)(fileGetPos(fileID) - recpos);
 
-      int prec   = iegp->dprec;
-      int rcode  = IEG_P_Parameter(iegp->ipdb);
-      int tabnum = IEG_P_CodeTable(iegp->ipdb);
-      int param  = cdiEncodeParam(rcode, tabnum, 255);
+      prec   = iegp->dprec;
+      rcode  = IEG_P_Parameter(iegp->ipdb);
+      tabnum = IEG_P_CodeTable(iegp->ipdb);
+      param  = cdiEncodeParam(rcode, tabnum, 255);
 
-      int rlevel = 0;
       if ( IEG_P_LevelType(iegp->ipdb) == IEG_LTYPE_HYBRID_LAYER )
 	rlevel = IEG_P_Level1(iegp->ipdb);
       else
@@ -53007,7 +52381,6 @@ void iegScanTimestep1(stream_t *streamptr)
 
       if ( IEG_P_LevelType(iegp->ipdb) == 100 ) rlevel *= 100;
 
-      int vdate = 0, vtime = 0;
       iegDateTime(iegp->ipdb, &vdate, &vtime);
 
       if ( nrecs == 0 )
@@ -53019,13 +52392,12 @@ void iegScanTimestep1(stream_t *streamptr)
 	{
 	  compVar.param = param;
           compVar.level = rlevel;
-          int recID = 0;
 	  for ( recID = 0; recID < nrecs; recID++ )
 	    {
 	      compVar0.param = streamptr->tsteps[0].records[recID].param;
 	      compVar0.level = streamptr->tsteps[0].records[recID].ilevel;
 
-	      if ( memcmp(&compVar0, &compVar, sizeof(iegcompvar_t)) == 0 ) break;
+	      if ( memcmp(&compVar0, &compVar, sizeof(IEGCOMPVAR)) == 0 ) break;
 	    }
 	  if ( recID < nrecs ) break;
 	  DateTime datetime = { .date = vdate, .time = vtime};
@@ -53045,17 +52417,17 @@ void iegScanTimestep1(stream_t *streamptr)
 
   cdi_generate_vars(streamptr);
 
-  int taxisID = taxisCreate(TAXIS_ABSOLUTE);
+  taxisID = taxisCreate(TAXIS_ABSOLUTE);
   taxis->type  = TAXIS_ABSOLUTE;
   taxis->vdate = (int)datetime0.date;
   taxis->vtime = (int)datetime0.time;
 
-  int vlistID = streamptr->vlistID;
+  vlistID = streamptr->vlistID;
   vlistDefTaxis(vlistID, taxisID);
 
   vlist_check_contents(vlistID);
 
-  int nrecords = streamptr->tsteps[0].nallrecs;
+  nrecords = streamptr->tsteps[0].nallrecs;
   if ( nrecords < streamptr->tsteps[0].recordSize )
     {
       streamptr->tsteps[0].recordSize = nrecords;
@@ -53066,7 +52438,7 @@ void iegScanTimestep1(stream_t *streamptr)
 
   streamptr->tsteps[0].recIDs = (int *) Malloc((size_t)nrecords * sizeof (int));
   streamptr->tsteps[0].nrecs = nrecords;
-  for ( int recID = 0; recID < nrecords; recID++ )
+  for ( recID = 0; recID < nrecords; recID++ )
     streamptr->tsteps[0].recIDs[recID] = recID;
 
   if ( streamptr->ntsteps == -1 )
@@ -53075,7 +52447,7 @@ void iegScanTimestep1(stream_t *streamptr)
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
-      streamptr->tsteps[tsID-1].next   = true;
+      streamptr->tsteps[tsID-1].next   = TRUE;
       streamptr->tsteps[tsID].position = recpos;
     }
 
@@ -53084,7 +52456,7 @@ void iegScanTimestep1(stream_t *streamptr)
       if ( taxis->vdate == 0 && taxis->vtime == 0 )
 	{
 	  streamptr->ntsteps = 0;
-	  for ( int varID = 0; varID < streamptr->nvars; varID++ )
+	  for ( varID = 0; varID < streamptr->nvars; varID++ )
 	    {
 	      vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
 	    }
@@ -53095,55 +52467,67 @@ void iegScanTimestep1(stream_t *streamptr)
 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;
-  iegcompvar_t compVar, compVar0;
+  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 vlistID = streamptr->vlistID;
-  int fileID  = streamptr->fileID;
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
-  int tsID = streamptr->rtsteps;
+  tsID = streamptr->rtsteps;
   if ( tsID != 1 )
     Error("Internal problem! unexpected timestep %d", tsID+1);
 
-  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
+  taxis = &streamptr->tsteps[tsID].taxis;
 
   fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
   cdi_create_records(streamptr, tsID);
 
-  int nrecords = streamptr->tsteps[0].nallrecs;
+  nrecords = streamptr->tsteps[0].nallrecs;
   streamptr->tsteps[1].recIDs = (int *) Malloc((size_t)nrecords * sizeof(int));
   streamptr->tsteps[1].nrecs = 0;
-  for ( int recID = 0; recID < nrecords; recID++ )
+  for ( recID = 0; recID < nrecords; recID++ )
     streamptr->tsteps[1].recIDs[recID] = -1;
 
-  for ( int recID = 0; recID < nrecords; recID++ )
+  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 ( int rindex = 0; rindex <= nrecords; rindex++ )
+  for ( rindex = 0; rindex <= nrecords; rindex++ )
     {
       recpos = fileGetPos(fileID);
-      int status = iegRead(fileID, iegp);
+      status = iegRead(fileID, iegp);
       if ( status != 0 )
 	{
 	  streamptr->ntsteps = 2;
 	  break;
 	}
-      size_t recsize = (size_t)(fileGetPos(fileID) - recpos);
+      recsize = (size_t)(fileGetPos(fileID) - recpos);
 
-      int rcode  = IEG_P_Parameter(iegp->ipdb);
-      int tabnum = IEG_P_CodeTable(iegp->ipdb);
-      int param  = cdiEncodeParam(rcode, tabnum, 255);
+      rcode  = IEG_P_Parameter(iegp->ipdb);
+      tabnum = IEG_P_CodeTable(iegp->ipdb);
+      param  = cdiEncodeParam(rcode, tabnum, 255);
 
-      int rlevel = 0;
       if ( IEG_P_LevelType(iegp->ipdb) == IEG_LTYPE_HYBRID_LAYER )
 	rlevel = IEG_P_Level1(iegp->ipdb);
       else
@@ -53151,7 +52535,6 @@ int iegScanTimestep2(stream_t *streamptr)
 
       if ( IEG_P_LevelType(iegp->ipdb) == 100 ) rlevel *= 100;
 
-      int vdate = 0, vtime = 0;
       iegDateTime(iegp->ipdb, &vdate, &vtime);
 
       if ( rindex == 0 )
@@ -53163,22 +52546,21 @@ int iegScanTimestep2(stream_t *streamptr)
 
       compVar.param = param;
       compVar.level = rlevel;
-      bool nextstep = false;
-      int recID = 0;
+      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_t)) == 0 )
+	  if ( memcmp(&compVar0, &compVar, sizeof(IEGCOMPVAR)) == 0 )
 	    {
 	      if ( streamptr->tsteps[tsID].records[recID].used )
 		{
-		  nextstep = true;
+		  nextstep = TRUE;
 		}
 	      else
 		{
-		  streamptr->tsteps[tsID].records[recID].used = true;
+		  streamptr->tsteps[tsID].records[recID].used = TRUE;
 		  streamptr->tsteps[tsID].recIDs[rindex] = recID;
 		}
 	      break;
@@ -53189,7 +52571,7 @@ int iegScanTimestep2(stream_t *streamptr)
 	  char paramstr[32];
 	  cdiParamToString(param, paramstr, sizeof(paramstr));
 	  Warning("param %s level %d not defined at timestep 1", paramstr, rlevel);
-	  return CDI_EUFSTRUCT;
+	  return (CDI_EUFSTRUCT);
 	}
 
       if ( nextstep ) break;
@@ -53202,24 +52584,24 @@ int iegScanTimestep2(stream_t *streamptr)
       compVar0.param = streamptr->tsteps[tsID].records[recID].param;
       compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
 
-      if ( memcmp(&compVar0, &compVar, sizeof(iegcompvar_t)) != 0 )
+      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;
+	  return (CDI_EUFSTRUCT);
 	}
 
       streamptr->tsteps[1].records[recID].position = recpos;
     }
 
-  int nrecs = 0;
-  for ( int recID = 0; recID < nrecords; recID++ )
+  nrecs = 0;
+  for ( recID = 0; recID < nrecords; recID++ )
     {
       if ( ! streamptr->tsteps[tsID].records[recID].used )
 	{
-	  int varID = streamptr->tsteps[tsID].records[recID].varID;
+	  varID = streamptr->tsteps[tsID].records[recID].varID;
           vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
 	}
       else
@@ -53237,35 +52619,47 @@ int iegScanTimestep2(stream_t *streamptr)
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
-      streamptr->tsteps[tsID-1].next   = true;
+      streamptr->tsteps[tsID-1].next   = TRUE;
       streamptr->tsteps[tsID].position = recpos;
     }
 
-  return 0;
+  return (0);
 }
 
 
 int iegInqContents(stream_t *streamptr)
 {
-  int fileID = streamptr->fileID;
+  int fileID;
+  int status = 0;
+
+  fileID = streamptr->fileID;
 
   streamptr->curTsID = 0;
 
   iegScanTimestep1(streamptr);
 
-  int status = 0;
   if ( streamptr->ntsteps == -1 ) status = iegScanTimestep2(streamptr);
 
   fileSetPos(fileID, 0, SEEK_SET);
 
-  return status;
+  return (status);
 }
 
 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;
-  iegcompvar_t compVar, compVar0;
+  int recID;
+  taxis_t *taxis;
+  int rindex, nrecs = 0;
+  IEGCOMPVAR compVar, compVar0;
   iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
 
   if ( CDI_Debug )
@@ -53279,10 +52673,9 @@ long iegScanTimestep(stream_t *streamptr)
   if ( streamptr->rtsteps == 0 )
     Error("Internal problem! Missing contents.");
 
-  int tsID = streamptr->rtsteps;
-  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
+  tsID  = streamptr->rtsteps;
+  taxis = &streamptr->tsteps[tsID].taxis;
 
-  int nrecs = 0;
   if ( streamptr->tsteps[tsID].recordSize == 0 )
     {
       cdi_create_records(streamptr, tsID);
@@ -53292,29 +52685,28 @@ long iegScanTimestep(stream_t *streamptr)
       streamptr->tsteps[tsID].nrecs = nrecs;
       streamptr->tsteps[tsID].recIDs
         = (int *) Malloc((size_t)nrecs * sizeof (int));
-      for ( int recID = 0; recID < nrecs; recID++ )
+      for ( recID = 0; recID < nrecs; recID++ )
 	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
 
-      int fileID = streamptr->fileID;
+      fileID = streamptr->fileID;
 
       fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-      for ( int rindex = 0; rindex <= nrecs; rindex++ )
+      for ( rindex = 0; rindex <= nrecs; rindex++ )
 	{
 	  recpos = fileGetPos(fileID);
-	  int status = iegRead(fileID, iegp);
+	  status = iegRead(fileID, iegp);
 	  if ( status != 0 )
 	    {
 	      streamptr->ntsteps = streamptr->rtsteps + 1;
 	      break;
 	    }
-	  size_t recsize = (size_t)(fileGetPos(fileID) - recpos);
+	  recsize = (size_t)(fileGetPos(fileID) - recpos);
 
-	  int rcode  = IEG_P_Parameter(iegp->ipdb);
-	  int tabnum = IEG_P_CodeTable(iegp->ipdb);
-	  int param  = cdiEncodeParam(rcode, tabnum, 255);
+	  rcode  = IEG_P_Parameter(iegp->ipdb);
+	  tabnum = IEG_P_CodeTable(iegp->ipdb);
+	  param  = cdiEncodeParam(rcode, tabnum, 255);
 
-          int rlevel = 0;
 	  if ( IEG_P_LevelType(iegp->ipdb) == IEG_LTYPE_HYBRID_LAYER )
 	    rlevel = IEG_P_Level1(iegp->ipdb);
 	  else
@@ -53322,12 +52714,11 @@ long iegScanTimestep(stream_t *streamptr)
 
 	  if ( IEG_P_LevelType(iegp->ipdb) == 100 ) rlevel *= 100;
 
-          int vdate = 0, vtime = 0;
 	  iegDateTime(iegp->ipdb, &vdate, &vtime);
 
 	  // if ( rindex == nrecs ) break; gcc-4.5 internal compiler error
 	  if ( rindex == nrecs ) continue;
-	  int recID = streamptr->tsteps[tsID].recIDs[rindex];
+	  recID = streamptr->tsteps[tsID].recIDs[rindex];
 
 	  if ( rindex == 0 )
 	    {
@@ -53341,7 +52732,7 @@ long iegScanTimestep(stream_t *streamptr)
 	  compVar0.param = streamptr->tsteps[tsID].records[recID].param;
 	  compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
 
-	  if ( memcmp(&compVar0, &compVar, sizeof(iegcompvar_t)) != 0 )
+	  if ( memcmp(&compVar0, &compVar, sizeof(IEGCOMPVAR)) != 0 )
 	    {
 	      Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
 		      tsID, recID,
@@ -53365,7 +52756,7 @@ long iegScanTimestep(stream_t *streamptr)
 	  if ( tsID != streamptr->rtsteps )
 	    Error("Internal error. tsID = %d", tsID);
 
-	  streamptr->tsteps[tsID-1].next   = true;
+	  streamptr->tsteps[tsID-1].next   = 1;
 	  streamptr->tsteps[tsID].position = recpos;
 	}
 
@@ -53379,59 +52770,76 @@ long iegScanTimestep(stream_t *streamptr)
       streamptr->ntsteps = tsID;
     }
 
-  return streamptr->ntsteps;
+  return (streamptr->ntsteps);
 }
 
 
 int iegInqTimestep(stream_t *streamptr, int tsID)
 {
+  int nrecs;
+
   if ( tsID == 0 && streamptr->rtsteps == 0 )
     Error("Call to cdiInqContents missing!");
 
   if ( CDI_Debug )
     Message("tsID = %d rtsteps = %d", tsID, streamptr->rtsteps);
 
-  long ntsteps = CDI_UNDEFID;
-  while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == CDI_UNDEFID )
+  long ntsteps = UNDEFID;
+  while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == UNDEFID )
     ntsteps = iegScanTimestep(streamptr);
 
-  int nrecs = 0;
-  if ( !(tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID) )
+  if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID )
+    {
+      nrecs = 0;
+    }
+  else
     {
       streamptr->curTsID = tsID;
       nrecs = streamptr->tsteps[tsID].nrecs;
     }
 
-  return nrecs;
+  return (nrecs);
 }
 
 
-void iegReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, int *nmiss)
+void iegReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
 {
-  if ( CDI_Debug ) Message("streamID = %d  varID = %d  levID = %d", streamptr->self, varID, levID);
-
+  int vlistID, fileID;
+  int levID, nlevs, gridID, gridsize;
+  off_t recpos, currentfilepos;
+  int tsid;
+  int recID;
+  int i;
+  double missval;
   void *iegp = streamptr->record->exsep;
 
-  int vlistID  = streamptr->vlistID;
-  int fileID   = streamptr->fileID;
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   /* NOTE: tiles are not supported here! */
-  double missval = vlistInqVarMissval(vlistID, varID);
-  int gridsize = gridInqSize(vlistInqVarGrid(vlistID, varID));
-  int tsid     = streamptr->curTsID;
+  nlevs    = streamptr->vars[varID].recordTable[0].nlevs;
+  missval  = vlistInqVarMissval(vlistID, varID);
+  gridID   = vlistInqVarGrid(vlistID, varID);
+  gridsize = gridInqSize(gridID);
+  tsid     = streamptr->curTsID;
 
-  off_t currentfilepos = fileGetPos(fileID);
+  if ( CDI_Debug )
+    Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
 
-  /* NOTE: tiles are not supported here! */
-  int recID = streamptr->vars[varID].recordTable[0].recordID[levID];
-  off_t recpos = streamptr->tsteps[tsid].records[recID].position;
-  fileSetPos(fileID, recpos, SEEK_SET);
-  iegRead(fileID, iegp);
-  iegInqDataDP(iegp, data);
+  currentfilepos = fileGetPos(fileID);
 
+  for (levID = 0; levID < nlevs; levID++)
+    {
+      /* NOTE: tiles are not supported here! */
+      recID = streamptr->vars[varID].recordTable[0].recordID[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);
 
   *nmiss = 0;
-  for ( int i = 0; i < gridsize; i++ )
+  for ( i = 0; i < nlevs*gridsize; i++ )
     if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
       {
 	data[i] = missval;
@@ -53440,70 +52848,146 @@ void iegReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data,
 }
 
 
-void iegReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
+void iegReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, int *nmiss)
 {
-  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
+  int vlistID, fileID;
+  int nlevs, gridID, gridsize;
+  off_t recpos, currentfilepos;
+  int tsid;
+  int recID;
+  int i;
+  double missval;
+  void *iegp = streamptr->record->exsep;
 
-  int vlistID = streamptr->vlistID;
-  size_t gridsize = (size_t) gridInqSize(vlistInqVarGrid(vlistID, varID));
-  size_t nlevs    = (size_t) streamptr->vars[varID].recordTable[0].nlevs;
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
+  /* NOTE: tiles are not supported here! */
+  nlevs    = streamptr->vars[varID].recordTable[0].nlevs;
+  missval  = vlistInqVarMissval(vlistID, varID);
+  gridID   = vlistInqVarGrid(vlistID, varID);
+  gridsize = gridInqSize(gridID);
+  tsid     = streamptr->curTsID;
 
-  for ( size_t levID = 0; levID < nlevs; levID++)
-    iegReadVarSliceDP(streamptr, varID, (int)levID, &data[levID*gridsize], nmiss);
+  if ( CDI_Debug )
+    Message("nlevs = %d gridID = %d gridsize = %d",
+	     nlevs, gridID, gridsize);
+
+  currentfilepos = fileGetPos(fileID);
+
+  /* NOTE: tiles are not supported here! */
+  recID = streamptr->vars[varID].recordTable[0].recordID[levID];
+  recpos = streamptr->tsteps[tsid].records[recID].position;
+  fileSetPos(fileID, recpos, SEEK_SET);
+  iegRead(fileID, iegp);
+  iegInqDataDP(iegp, data);
+
+  fileSetPos(fileID, currentfilepos, SEEK_SET);
+
+  *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 iegWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double *data)
+void iegWriteVarDP(stream_t *streamptr, int varID, const double *data)
 {
-  if ( CDI_Debug ) Message("streamID = %d  varID = %d  levID = %d", streamptr->self, varID, levID);
-
+  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;
+
+  if ( CDI_Debug )
+    Message("streamID = %d  varID = %d", streamptr->self, varID);
+
   iegInitMem(iegp);
-  for ( int i = 0; i < 37; i++ ) iegp->ipdb[i] = -1;
+  for ( i = 0; i < 37; i++ ) iegp->ipdb[i] = -1;
 
-  int vlistID  = streamptr->vlistID;
-  int fileID   = streamptr->fileID;
-  int tsID     = streamptr->curTsID;
-  int gridID   = vlistInqVarGrid(vlistID, varID);
-  int zaxisID  = vlistInqVarZaxis(vlistID, varID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
+  tsID     = streamptr->curTsID;
+  gridID   = vlistInqVarGrid(vlistID, varID);
+  gridsize = gridInqSize(gridID);
+  zaxisID  = vlistInqVarZaxis(vlistID, varID);
+  nlevs    = zaxisInqSize(zaxisID);
 
-  int param    = vlistInqVarParam(vlistID, varID);
-  int pdis, pcat, pnum;
+  if ( CDI_Debug )
+    Message("nlevs = %d gridID = %d gridsize = %d", nlevs, gridID, gridsize);
+
+  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;
 
-  int date     = streamptr->tsteps[tsID].taxis.vdate;
-  int time     = streamptr->tsteps[tsID].taxis.vtime;
   iegDefTime(iegp->ipdb, date, time, vlistInqTaxis(vlistID));
   iegDefGrid(iegp->igdb, gridID);
-  iegDefLevel(iegp->ipdb, iegp->igdb, iegp->vct, zaxisID, levID);
 
-  iegp->dprec = iegDefDatatype(vlistInqVarDatatype(vlistID, varID));
+  datatype = vlistInqVarDatatype(vlistID, varID);
 
-  int gridsize = gridInqSize(gridID);
+  iegp->dprec = iegDefDatatype(datatype);
 
-  double refval = data[0];
-  for ( int i = 1; i < gridsize; i++ )
-    if ( data[i] < refval ) refval = data[i];
+  for ( levID = 0;  levID < nlevs; levID++ )
+    {
+      iegDefLevel(iegp->ipdb, iegp->igdb, iegp->vct, zaxisID, levID);
 
-  iegp->refval = refval;
+      refval = data[0];
+      for ( i = 1; i < gridsize; i++ )
+	if ( data[levID*gridsize+i] < refval ) refval = data[levID*gridsize+i];
 
-  iegDefDataDP(iegp, data);
-  iegWrite(fileID, iegp);
+      iegp->refval = refval;
+
+      iegDefDataDP(iegp, &data[levID*gridsize]);
+      iegWrite(fileID, iegp);
+    }
 }
 
 
-void iegWriteVarDP(stream_t *streamptr, int varID, const double *data)
+void iegWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double *data)
 {
-  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
+  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;
 
-  int vlistID = streamptr->vlistID;
-  size_t gridsize = (size_t) gridInqSize(vlistInqVarGrid(vlistID, varID));
-  size_t nlevs    = (size_t) zaxisInqSize(vlistInqVarZaxis(vlistID, varID));
+  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); */
 
-  for ( size_t levID = 0;  levID < nlevs; levID++ )
-    iegWriteVarSliceDP(streamptr, varID, (int)levID, &data[levID*gridsize]);
+  datatype = vlistInqVarDatatype(vlistID, varID);
+
+  iegp->dprec = iegDefDatatype(datatype);
+
+  iegDefDataDP(iegp, data);
+  iegWrite(fileID, iegp);
 }
 
 #endif /* HAVE_LIBIEG */
@@ -53532,7 +53016,7 @@ void recordInitEntry(record_t *record)
   record->size     = 0;
   record->param    = 0;
   record->ilevel   = CDI_UNDEFID;
-  record->used     = false;
+  record->used     = FALSE;
   record->varID    = CDI_UNDEFID;
   record->levelID  = CDI_UNDEFID;
   memset(record->varname, 0, sizeof(record->varname));
@@ -53594,19 +53078,18 @@ int recordNewEntry(stream_t *streamptr, int tsID)
 static
 void cdiInitRecord(stream_t *streamptr)
 {
-  Record *record = (Record *) Malloc(sizeof(Record));
-  streamptr->record = record;
+  streamptr->record = (Record *) Malloc(sizeof(Record));
 
-  record->param      = 0;
-  record->level      = 0;
-  record->date       = 0;
-  record->time       = 0;
-  record->gridID     = 0;
-  record->buffer     = NULL;
-  record->buffersize = 0;
-  record->position   = 0;
-  record->varID      = 0;
-  record->levelID    = CDI_UNDEFID;
+  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;
 }
 
 
@@ -53679,44 +53162,43 @@ void streamDefRecord(int streamID, int varID, int levelID)
   int param   = vlistInqVarParam(vlistID, varID);
   int level   = (int)(zaxisInqLevel(zaxisID, levelID));
 
-  Record *record = streamptr->record;
-  record->varID    = varID;
-  record->levelID  = levelID;
-  record->param    = param;
-  record->level    = level;
-  record->date     = streamptr->tsteps[tsID].taxis.vdate;
-  record->time     = streamptr->tsteps[tsID].taxis.vtime;
-  record->gridID   = gridID;
-  record->prec     = vlistInqVarDatatype(vlistID, varID);
+  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 CDI_FILETYPE_GRB:
-    case CDI_FILETYPE_GRB2:
+    case FILETYPE_GRB:
+    case FILETYPE_GRB2:
       grbDefRecord(streamptr);
       break;
 #endif
 #if  defined  (HAVE_LIBSERVICE)
-    case CDI_FILETYPE_SRV:
+    case FILETYPE_SRV:
       srvDefRecord(streamptr);
       break;
 #endif
 #if  defined  (HAVE_LIBEXTRA)
-    case CDI_FILETYPE_EXT:
+    case FILETYPE_EXT:
       extDefRecord(streamptr);
       break;
 #endif
 #if  defined  (HAVE_LIBIEG)
-    case CDI_FILETYPE_IEG:
+    case FILETYPE_IEG:
       iegDefRecord(streamptr);
       break;
 #endif
 #if  defined  (HAVE_LIBNETCDF)
-    case CDI_FILETYPE_NC:
-    case CDI_FILETYPE_NC2:
-    case CDI_FILETYPE_NC4:
-    case CDI_FILETYPE_NC4C:
+    case FILETYPE_NC:
+    case FILETYPE_NC2:
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
       if ( streamptr->accessmode == 0 ) cdfEndDef(streamptr);
       cdfDefRecord(streamptr);
       break;
@@ -53734,24 +53216,24 @@ void streamCopyRecord(int streamID2, int streamID1)
     *streamptr2 = stream_to_pointer(streamID2);
   int filetype1 = streamptr1->filetype,
     filetype2 = streamptr2->filetype,
-    filetype  = CDI_FILETYPE_UNDEF;
+    filetype  = FILETYPE_UNDEF;
 
   if ( filetype1 == filetype2 ) filetype = filetype2;
   else
     {
       switch (filetype1)
         {
-        case CDI_FILETYPE_NC:
-        case CDI_FILETYPE_NC2:
-        case CDI_FILETYPE_NC4:
-        case CDI_FILETYPE_NC4C:
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
           switch (filetype2)
             {
-            case CDI_FILETYPE_NC:
-            case CDI_FILETYPE_NC2:
-            case CDI_FILETYPE_NC4:
-            case CDI_FILETYPE_NC4C:
-              // Warning("Streams have different file types (%s -> %s)!", strfiletype(filetype1), strfiletype(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;
             }
@@ -53759,37 +53241,37 @@ void streamCopyRecord(int streamID2, int streamID1)
         }
     }
 
-  if ( filetype == CDI_FILETYPE_UNDEF )
+  if ( filetype == FILETYPE_UNDEF )
     Error("Streams have different file types (%s -> %s)!", strfiletype(filetype1), strfiletype(filetype2));
 
   switch (filetype)
     {
 #if  defined  (HAVE_LIBGRIB)
-    case CDI_FILETYPE_GRB:
-    case CDI_FILETYPE_GRB2:
+    case FILETYPE_GRB:
+    case FILETYPE_GRB2:
       grbCopyRecord(streamptr2, streamptr1);
       break;
 #endif
 #if  defined  (HAVE_LIBSERVICE)
-    case CDI_FILETYPE_SRV:
+    case FILETYPE_SRV:
       srvCopyRecord(streamptr2, streamptr1);
       break;
 #endif
 #if  defined  (HAVE_LIBEXTRA)
-    case CDI_FILETYPE_EXT:
+    case FILETYPE_EXT:
       extCopyRecord(streamptr2, streamptr1);
       break;
 #endif
 #if  defined  (HAVE_LIBIEG)
-    case CDI_FILETYPE_IEG:
+    case FILETYPE_IEG:
       iegCopyRecord(streamptr2, streamptr1);
       break;
 #endif
 #if  defined  (HAVE_LIBNETCDF)
-    case CDI_FILETYPE_NC:
-    case CDI_FILETYPE_NC2:
-    case CDI_FILETYPE_NC4:
-    case CDI_FILETYPE_NC4C:
+    case FILETYPE_NC:
+    case FILETYPE_NC2:
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
       cdfCopyRecord(streamptr2, streamptr1);
       break;
 #endif
@@ -53805,6 +53287,7 @@ void streamCopyRecord(int streamID2, int streamID1)
 void cdi_create_records(stream_t *streamptr, int tsID)
 {
   unsigned nrecords, maxrecords;
+  record_t *records;
 
   tsteps_t *sourceTstep = streamptr->tsteps;
   tsteps_t *destTstep = sourceTstep + tsID;
@@ -53848,8 +53331,10 @@ void cdi_create_records(stream_t *streamptr, int tsID)
     }
   //  printf("tsID, nrecords %d %d\n", tsID, nrecords);
 
-  record_t *records = NULL;
-  if ( maxrecords > 0 ) records = (record_t *) Malloc(maxrecords*sizeof(record_t));
+  if ( maxrecords > 0 )
+    records = (record_t *) Malloc(maxrecords*sizeof(record_t));
+  else
+    records = NULL;
 
   destTstep->records    = records;
   destTstep->recordSize = (int)maxrecords;
@@ -53874,38 +53359,12 @@ void cdi_create_records(stream_t *streamptr, int tsID)
                 {
                   destTstep->records[recID].position = CDI_UNDEFID;
                   destTstep->records[recID].size     = 0;
-                  destTstep->records[recID].used     = false;
+                  destTstep->records[recID].used     = FALSE;
                 }
             }
 	}
     }
 }
-
-
-void streamFCopyRecord(stream_t *streamptr2, stream_t *streamptr1, const char *container_name)
-{
-  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;
-
-  if (fileSetPos(fileID1, recpos, SEEK_SET) != 0)
-    Error("Cannot seek input file for %s record copy!", container_name);
-
-  char *buffer = (char *) Malloc(recsize);
-
-  if (fileRead(fileID1, buffer, recsize) != recsize)
-    Error("Failed to read record from %s file for copying!", container_name);
-
-  if (fileWrite(fileID2, buffer, recsize) != recsize)
-    Error("Failed to write record to %s file when copying!", container_name);
-
-  Free(buffer);
-}
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -53926,30 +53385,46 @@ void streamFCopyRecord(stream_t *streamptr2, stream_t *streamptr1, const char *c
 
 
 
+#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_t;
+} SRVCOMPVAR;
 
 
-static
-int srvInqDatatype(int prec)
+static int srvInqDatatype(int prec)
 {
-  return (prec == EXSE_DOUBLE_PRECISION) ? CDI_DATATYPE_FLT64 : CDI_DATATYPE_FLT32;
+  int datatype;
+
+  if ( prec == DOUBLE_PRECISION ) datatype = DATATYPE_FLT64;
+  else                            datatype = DATATYPE_FLT32;
+
+  return (datatype);
 }
 
-static
-int srvDefDatatype(int datatype)
+
+static int srvDefDatatype(int datatype)
 {
-  if ( datatype == CDI_DATATYPE_CPX32 || datatype == CDI_DATATYPE_CPX64 )
+  int prec;
+
+  if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
     Error("CDI/SERVICE library does not support complex numbers!");
 
-  if ( datatype != CDI_DATATYPE_FLT32 && datatype != CDI_DATATYPE_FLT64 )
-    datatype = CDI_DATATYPE_FLT32;
+  if ( datatype != DATATYPE_FLT32 && datatype != DATATYPE_FLT64 )
+    datatype = DATATYPE_FLT32;
 
-  return (datatype == CDI_DATATYPE_FLT64) ? EXSE_DOUBLE_PRECISION : EXSE_SINGLE_PRECISION;
+  if ( datatype == DATATYPE_FLT64 ) prec = DOUBLE_PRECISION;
+  else                              prec = SINGLE_PRECISION;
+
+  return (prec);
 }
 
 /* not used
@@ -53979,18 +53454,25 @@ int srvInqRecord(stream_t *streamptr, int *varID, int *levelID)
 
   *varID = vlistInqVarID(vlistID, icode);
 
-  if ( *varID == CDI_UNDEFID ) Error("Code %d undefined", icode);
+  if ( *varID == UNDEFID ) Error("Code %d undefined", icode);
 
   zaxisID = vlistInqVarZaxis(vlistID, *varID);
 
   *levelID = zaxisInqLevelID(zaxisID, (double) ilevel);
 
-  return 1;
+  return (1);
 }
 */
 
 void srvReadRecord(stream_t *streamptr, double *data, int *nmiss)
 {
+  int status;
+  int header[8];
+  int gridID;
+  int i, size;
+  double missval;
+  void *srvp = streamptr->record->exsep;
+
   int vlistID  = streamptr->vlistID;
   int fileID   = streamptr->fileID;
   int tsID     = streamptr->curTsID;
@@ -54001,23 +53483,21 @@ void srvReadRecord(stream_t *streamptr, double *data, int *nmiss)
 
   fileSetPos(fileID, recpos, SEEK_SET);
 
-  void *srvp = streamptr->record->exsep;
-  int status = srvRead(fileID, srvp);
+  status = srvRead(fileID, srvp);
   if ( status != 0 )
     Error("Failed to read record from SRV file");
 
-  int header[8];
   srvInqHeader(srvp, header);
   srvInqDataDP(srvp, data);
 
-  double missval = vlistInqVarMissval(vlistID, varID);
-  int gridID  = vlistInqVarGrid(vlistID, varID);
-  int size    = gridInqSize(gridID);
+  missval = vlistInqVarMissval(vlistID, varID);
+  gridID  = vlistInqVarGrid(vlistID, varID);
+  size    = gridInqSize(gridID);
 
   streamptr->numvals += size;
 
   *nmiss = 0;
-  for ( int i = 0; i < size; i++ )
+  for ( i = 0; i < size; i++ )
     if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
       {
 	data[i] = missval;
@@ -54034,21 +53514,20 @@ void srvCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
 
 void srvDefRecord(stream_t *streamptr)
 {
-  Record *record = streamptr->record;
-  srvrec_t *srvp = (srvrec_t*) record->exsep;
+  int header[8];
+  Record *restrict record = streamptr->record;
+  srvrec_t *restrict srvp = (srvrec_t*) record->exsep;
+  int gridID = record->gridID;
 
   int pdis, pcat, pnum;
   cdiDecodeParam(record->param, &pnum, &pcat, &pdis);
-
-  int header[8];
   header[0] = pnum;
   header[1] = record->level;
   header[2] = record->date;
   header[3] = record->time;
 
-  int gridID = record->gridID;
   int xsize = gridInqXsize(gridID),
-      ysize = gridInqYsize(gridID);
+    ysize = gridInqYsize(gridID);
   if ( xsize == 0 || ysize == 0 )
     {
       xsize = gridInqSize(gridID);
@@ -54064,6 +53543,7 @@ void srvDefRecord(stream_t *streamptr)
   header[7] = 0;
 
   int datatype = record->prec;
+
   srvp->dprec = srvDefDatatype(datatype);
 
   srvDefHeader(srvp, header);
@@ -54093,12 +53573,14 @@ void srv_add_record(stream_t *streamptr, int param, int level, int xsize, int ys
   record->param    = param;
   record->ilevel   = level;
 
-  grid_t *grid = (grid_t*) Malloc(sizeof(*grid));
+  grid_t *grid = (grid_t *)Malloc(sizeof (*grid));
   grid_init(grid);
   cdiGridTypeInit(grid, GRID_GENERIC, xsize*ysize);
-  grid->x.size = xsize;
-  grid->y.size = ysize;
-  struct addIfNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 0);
+  grid->xsize = xsize;
+  grid->ysize = ysize;
+  grid->xvals = NULL;
+  grid->yvals = NULL;
+  struct addIffNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, grid, 0);
   int gridID = gridAdded.Id;
   if (!gridAdded.isNew) Free(grid);
   /*
@@ -54123,7 +53605,8 @@ void srv_add_record(stream_t *streamptr, int param, int level, int xsize, int ys
   streamptr->nrecs++;
 
   if ( CDI_Debug )
-    Message("varID = %d gridID = %d levelID = %d", varID, gridID, levelID);
+    Message("varID = %d gridID = %d levelID = %d",
+	    varID, gridID, levelID);
 }
 
 static
@@ -54143,10 +53626,11 @@ void srvScanTimestep1(stream_t *streamptr)
     taxis = &streamptr->tsteps[tsID].taxis;
   }
 
+
   int fileID = streamptr->fileID;
 
   int nrecs = 0;
-  while ( true )
+  while ( TRUE )
     {
       int header[8];
       recpos = fileGetPos(fileID);
@@ -54229,7 +53713,7 @@ void srvScanTimestep1(stream_t *streamptr)
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
-      streamptr->tsteps[tsID-1].next   = true;
+      streamptr->tsteps[tsID-1].next   = TRUE;
       streamptr->tsteps[tsID].position = recpos;
     }
 
@@ -54248,43 +53732,54 @@ 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;
-  srvcompvar_t compVar, compVar0;
+  int nrecords, nrecs, recID, rindex;
+  int nextstep;
+  taxis_t *taxis;
+  int vlistID;
+  SRVCOMPVAR compVar, compVar0;
   void *srvp = streamptr->record->exsep;
 
   streamptr->curTsID = 1;
 
-  int vlistID = streamptr->vlistID;
-  int fileID  = streamptr->fileID;
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
-  int tsID = streamptr->rtsteps;
+  tsID = streamptr->rtsteps;
   if ( tsID != 1 )
     Error("Internal problem! unexpected timestep %d", tsID+1);
 
-  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
+  taxis = &streamptr->tsteps[tsID].taxis;
 
   fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
   cdi_create_records(streamptr, tsID);
 
-  int nrecords = streamptr->tsteps[0].nallrecs;
+  nrecords = streamptr->tsteps[0].nallrecs;
   streamptr->tsteps[1].recIDs = (int *) Malloc((size_t)nrecords * sizeof (int));
   streamptr->tsteps[1].nrecs = 0;
-  for ( int recID = 0; recID < nrecords; recID++ )
+  for ( recID = 0; recID < nrecords; recID++ )
     streamptr->tsteps[1].recIDs[recID] = -1;
 
-  for ( int recID = 0; recID < nrecords; recID++ )
+  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 ( int rindex = 0; rindex <= nrecords; rindex++ )
+  for ( rindex = 0; rindex <= nrecords; rindex++ )
     {
       recpos = fileGetPos(fileID);
-      int status = srvRead(fileID, srvp);
+      status = srvRead(fileID, srvp);
       if ( status != 0 )
 	{
 	  streamptr->ntsteps = 2;
@@ -54294,12 +53789,12 @@ int srvScanTimestep2(stream_t *streamptr)
 
       srvInqHeader(srvp, header);
 
-      int rcode  = header[0];
-      int rlevel = header[1];
-      int vdate  = header[2];
-      int vtime  = header[3];
+      rcode  = header[0];
+      rlevel = header[1];
+      vdate  = header[2];
+      vtime  = header[3];
 
-      int param = cdiEncodeParam(rcode, 255, 255);
+      param = cdiEncodeParam(rcode, 255, 255);
 
       if ( rindex == 0 )
 	{
@@ -54310,22 +53805,21 @@ int srvScanTimestep2(stream_t *streamptr)
 
       compVar.param = param;
       compVar.level = rlevel;
-      bool nextstep = false;
-      int recID;
+      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(srvcompvar_t)) == 0 )
+	  if ( memcmp(&compVar0, &compVar, sizeof(SRVCOMPVAR)) == 0 )
 	    {
 	      if ( streamptr->tsteps[tsID].records[recID].used )
 		{
-		  nextstep = true;
+		  nextstep = TRUE;
 		}
 	      else
 		{
-		  streamptr->tsteps[tsID].records[recID].used = true;
+		  streamptr->tsteps[tsID].records[recID].used = TRUE;
 		  streamptr->tsteps[tsID].recIDs[rindex] = recID;
 		}
 	      break;
@@ -54334,7 +53828,7 @@ int srvScanTimestep2(stream_t *streamptr)
       if ( recID == nrecords )
 	{
 	  Warning("Code %d level %d not found at timestep %d", rcode, rlevel, tsID+1);
-	  return CDI_EUFSTRUCT;
+	  return (CDI_EUFSTRUCT);
 	}
 
       if ( nextstep ) break;
@@ -54347,24 +53841,24 @@ int srvScanTimestep2(stream_t *streamptr)
       compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
       compVar0.level = streamptr->tsteps[tsID].records[recID].ilevel;
 
-      if ( memcmp(&compVar0, &compVar, sizeof(srvcompvar_t)) != 0 )
+      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;
+	  return (CDI_EUFSTRUCT);
 	}
 
       streamptr->tsteps[1].records[recID].position = recpos;
     }
 
-  int nrecs = 0;
-  for ( int recID = 0; recID < nrecords; recID++ )
+  nrecs = 0;
+  for ( recID = 0; recID < nrecords; recID++ )
     {
       if ( ! streamptr->tsteps[tsID].records[recID].used )
 	{
-	  int varID = streamptr->tsteps[tsID].records[recID].varID;
+	  varID = streamptr->tsteps[tsID].records[recID].varID;
           vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
 	}
       else
@@ -54382,37 +53876,44 @@ int srvScanTimestep2(stream_t *streamptr)
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
-      streamptr->tsteps[tsID-1].next   = true;
+      streamptr->tsteps[tsID-1].next   = TRUE;
       streamptr->tsteps[tsID].position = recpos;
     }
 
-  return 0;
+  return (0);
 }
 
 
 int srvInqContents(stream_t *streamptr)
 {
+  int fileID;
+  int status = 0;
+
+  fileID = streamptr->fileID;
+
   streamptr->curTsID = 0;
 
   srvScanTimestep1(streamptr);
 
-  int status = 0;
   if ( streamptr->ntsteps == -1 ) status = srvScanTimestep2(streamptr);
 
-  int fileID = streamptr->fileID;
   fileSetPos(fileID, 0, SEEK_SET);
 
-  return status;
+  return (status);
 }
 
 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 nrecs = 0;
+  int rindex, nrecs = 0;
   void *srvp = streamptr->record->exsep;
   /*
   if ( CDI_Debug )
@@ -54438,14 +53939,14 @@ long srvScanTimestep(stream_t *streamptr)
       for ( recID = 0; recID < nrecs; recID++ )
 	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
 
-      int fileID = streamptr->fileID;
+      fileID = streamptr->fileID;
 
       fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-      for ( int rindex = 0; rindex <= nrecs; rindex++ )
+      for ( rindex = 0; rindex <= nrecs; rindex++ )
 	{
 	  recpos = fileGetPos(fileID);
-	  int status = srvRead(fileID, srvp);
+	  status = srvRead(fileID, srvp);
 	  if ( status != 0 )
 	    {
 	      streamptr->ntsteps = streamptr->rtsteps + 1;
@@ -54455,14 +53956,14 @@ long srvScanTimestep(stream_t *streamptr)
 
 	  srvInqHeader(srvp, header);
 
-	  int rcode  = header[0];
-	  int rlevel = header[1];
-	  int vdate  = header[2];
-	  int vtime  = header[3];
+	  rcode  = header[0];
+	  rlevel = header[1];
+	  vdate  = header[2];
+	  vtime  = header[3];
           /* rxsize = header[4]; */
           /* rysize = header[5]; */
 
-	  int param = cdiEncodeParam(rcode, 255, 255);
+	  param = cdiEncodeParam(rcode, 255, 255);
 
 	  // if ( rindex == nrecs ) break; gcc-4.5 internal compiler error
 	  if ( rindex == nrecs ) continue;
@@ -54500,7 +54001,7 @@ long srvScanTimestep(stream_t *streamptr)
 	  if ( tsID != streamptr->rtsteps )
 	    Error("Internal error. tsID = %d", tsID);
 
-	  streamptr->tsteps[tsID-1].next   = true;
+	  streamptr->tsteps[tsID-1].next   = 1;
 	  streamptr->tsteps[tsID].position = recpos;
 	}
 
@@ -54514,61 +54015,128 @@ long srvScanTimestep(stream_t *streamptr)
       streamptr->ntsteps = tsID;
     }
 
-  return streamptr->ntsteps;
+  return (streamptr->ntsteps);
 }
 
 
 int srvInqTimestep(stream_t *streamptr, int tsID)
 {
+  long ntsteps;
+  int nrecs;
+
   if ( tsID == 0 && streamptr->rtsteps == 0 )
     Error("Call to cdiInqContents missing!");
 
   if ( CDI_Debug )
     Message("tsID = %d rtsteps = %d", tsID, streamptr->rtsteps);
 
-  long ntsteps = CDI_UNDEFID;
-  while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == CDI_UNDEFID )
+  ntsteps = UNDEFID;
+  while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == UNDEFID )
     ntsteps = srvScanTimestep(streamptr);
 
-  int nrecs = 0;
-  if ( !(tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID) )
+  if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != UNDEFID )
+    {
+      nrecs = 0;
+    }
+  else
     {
       streamptr->curTsID = tsID;
       nrecs = streamptr->tsteps[tsID].nrecs;
     }
 
-  return nrecs;
+  return (nrecs);
 }
 
 
-void srvReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, int *nmiss)
+void srvReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
 {
-  if ( CDI_Debug ) Message("streamID = %d  varID = %d  levID = %d", streamptr->self, varID, levID);
+  int vlistID, fileID;
+  int levID, nlevs, gridID, gridsize;
+  off_t recpos, currentfilepos;
+  int header[8];
+  int tsid;
+  int recID;
+  int i;
+  double missval;
+  void *srvp = streamptr->record->exsep;
 
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
+  /* NOTE: tiles are not supported here! */
+  nlevs    = streamptr->vars[varID].recordTable[0].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);
+
+  for (levID = 0; levID < nlevs; levID++)
+    {
+      /* NOTE: tiles are not supported here! */
+      recID = streamptr->vars[varID].recordTable[0].recordID[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)++;
+      }
+}
+
+
+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;
   void *srvp = streamptr->record->exsep;
 
-  int vlistID  = streamptr->vlistID;
-  int fileID   = streamptr->fileID;
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   /* NOTE: tiles are not supported here! */
-  double missval = vlistInqVarMissval(vlistID, varID);
-  int gridsize = gridInqSize(vlistInqVarGrid(vlistID, varID));
-  int tsid     = streamptr->curTsID;
+  nlevs    = streamptr->vars[varID].recordTable[0].nlevs;
+  missval  = vlistInqVarMissval(vlistID, varID);
+  gridID   = vlistInqVarGrid(vlistID, varID);
+  gridsize = gridInqSize(gridID);
+  tsid     = streamptr->curTsID;
 
-  off_t currentfilepos = fileGetPos(fileID);
+  if ( CDI_Debug )
+    Message("nlevs = %d gridID = %d gridsize = %d",
+	     nlevs, gridID, gridsize);
+
+  currentfilepos = fileGetPos(fileID);
 
   /* NOTE: tiles are not supported here! */
-  int recID = streamptr->vars[varID].recordTable[0].recordID[levID];
-  off_t recpos = streamptr->tsteps[tsid].records[recID].position;
+  recID = streamptr->vars[varID].recordTable[0].recordID[levID];
+  recpos = streamptr->tsteps[tsid].records[recID].position;
   fileSetPos(fileID, recpos, SEEK_SET);
-  if ( srvRead(fileID, srvp) < 0 ) abort();
-  int header[8];
+  if (srvRead(fileID, srvp) < 0)
+    abort();
   srvInqHeader(srvp, header);
   srvInqDataDP(srvp, data);
 
   fileSetPos(fileID, currentfilepos, SEEK_SET);
 
   *nmiss = 0;
-  for ( int i = 0; i < gridsize; i++ )
+  for ( i = 0; i < gridsize; i++ )
     if ( DBL_IS_EQUAL(data[i], missval) || DBL_IS_EQUAL(data[i], (float)missval) )
       {
 	data[i] = missval;
@@ -54577,39 +54145,105 @@ void srvReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data,
 }
 
 
-void srvReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
+void srvWriteVarDP(stream_t *streamptr, int varID, const double *data)
 {
-  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
+  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;
 
-  int vlistID = streamptr->vlistID;
-  size_t gridsize = (size_t) gridInqSize(vlistInqVarGrid(vlistID, varID));
-  size_t nlevs    = (size_t) streamptr->vars[varID].recordTable[0].nlevs;
+  if ( CDI_Debug )
+    Message("streamID = %d  varID = %d", streamptr->self, varID);
+
+  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);
+
+  cdiDecodeParam(vlistInqVarParam(vlistID, varID), &pnum, &pcat, &pdis);
+
+  header[0] = pnum;
+  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 )
+    {
+      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;
 
-  for ( size_t levID = 0; levID < nlevs; levID++)
-    srvReadVarSliceDP(streamptr, varID, (int)levID, &data[levID*gridsize], nmiss);
+  datatype = vlistInqVarDatatype(vlistID, varID);
+
+  srvp->dprec = srvDefDatatype(datatype);
+
+  for ( levID = 0; levID < nlevs; levID++ )
+    {
+      level = zaxisInqLevel(zaxisID, levID);
+
+      header[1] = (int) level;
+      srvDefHeader(srvp, header);
+      srvDefDataDP(srvp, &data[levID*gridsize]);
+      srvWrite(fileID, srvp);
+    }
 }
 
 
 void srvWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double *data)
 {
-  if ( CDI_Debug ) Message("streamID = %d  varID = %d  levID = %d", streamptr->self, varID, levID);
+  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 vlistID  = streamptr->vlistID;
-  int fileID   = streamptr->fileID;
-  int tsID     = streamptr->curTsID;
-  int gridID   = vlistInqVarGrid(vlistID, varID);
+  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);
 
-  int pdis, pcat, pnum;
   cdiDecodeParam(vlistInqVarParam(vlistID, varID), &pnum, &pcat, &pdis);
 
-  int header[8];
   header[0] = pnum;
-  header[1] = (int)(zaxisInqLevel(vlistInqVarZaxis(vlistID, varID), levID));
+  header[1] = (int) level;
   header[2] = streamptr->tsteps[tsID].taxis.vdate;
   header[3] = streamptr->tsteps[tsID].taxis.vtime;
 
-  int xsize = gridInqXsize(gridID);
-  int ysize = gridInqYsize(gridID);
+  xsize = gridInqXsize(gridID);
+  ysize = gridInqYsize(gridID);
   if ( xsize == 0 || ysize == 0 )
     {
       xsize = gridInqSize(gridID);
@@ -54624,9 +54258,8 @@ void srvWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double
   header[6] = 0;
   header[7] = 0;
 
-  int datatype = vlistInqVarDatatype(vlistID, varID);
+  datatype = vlistInqVarDatatype(vlistID, varID);
 
-  srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
   srvp->dprec = srvDefDatatype(datatype);
 
   srvDefHeader(srvp, header);
@@ -54634,21 +54267,7 @@ void srvWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double
   srvWrite(fileID, srvp);
 }
 
-
-void srvWriteVarDP(stream_t *streamptr, int varID, const double *data)
-{
-  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
-
-  int vlistID = streamptr->vlistID;
-  size_t gridsize = (size_t) gridInqSize(vlistInqVarGrid(vlistID, varID));
-  size_t nlevs    = (size_t) zaxisInqSize(vlistInqVarZaxis(vlistID, varID));
-
-  for ( size_t levID = 0; levID < nlevs; levID++ )
-    srvWriteVarSliceDP(streamptr, varID, (int)levID, &data[levID*gridsize]);
-}
-
 #endif /* HAVE_LIBSERVICE */
-
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -54661,6 +54280,8 @@ void srvWriteVarDP(stream_t *streamptr, int varID, const double *data)
 #if defined (HAVE_CONFIG_H)
 #endif
 
+#include <string.h>
+
 
 
 
@@ -54676,7 +54297,7 @@ static
 void streamvar_init_entry(stream_t *streamptr, int varID)
 {
   streamptr->vars[varID].ncvarid      = CDI_UNDEFID;
-  streamptr->vars[varID].defmiss      = false;
+  streamptr->vars[varID].defmiss      = 0;
 
   streamptr->vars[varID].subtypeSize  = 0;
   streamptr->vars[varID].recordTable  = NULL;
@@ -54691,24 +54312,30 @@ static
 int streamvar_new_entry(stream_t *streamptr)
 {
   int varID = 0;
-  int streamvarSize = streamptr->varsAllocated;
-  svarinfo_t *streamvar = streamptr->vars;
+  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 *) Malloc((size_t)streamvarSize * sizeof(svarinfo_t));
+      streamvar
+        = (svarinfo_t *) Malloc((size_t)streamvarSize * sizeof(svarinfo_t));
       if ( streamvar == NULL )
 	{
           Message("streamvarSize = %d", streamvarSize);
 	  SysError("Allocation of svarinfo_t failed");
 	}
 
-      for ( int i = 0; i < streamvarSize; i++ )
-	streamvar[i].isUsed = false;
+      for ( i = 0; i < streamvarSize; i++ )
+	streamvar[i].isUsed = FALSE;
     }
   else
     {
@@ -54723,8 +54350,11 @@ int streamvar_new_entry(stream_t *streamptr)
   */
   if ( varID == streamvarSize )
     {
+      int i;
+
       streamvarSize = 2*streamvarSize;
-      streamvar = (svarinfo_t *) Realloc(streamvar,
+      streamvar
+        = (svarinfo_t *) Realloc(streamvar,
                                  (size_t)streamvarSize * sizeof (svarinfo_t));
       if ( streamvar == NULL )
 	{
@@ -54733,8 +54363,8 @@ int streamvar_new_entry(stream_t *streamptr)
 	}
       varID = streamvarSize/2;
 
-      for ( int i = varID; i < streamvarSize; i++ )
-	streamvar[i].isUsed = false;
+      for ( i = varID; i < streamvarSize; i++ )
+	streamvar[i].isUsed = FALSE;
     }
 
   streamptr->varsAllocated = streamvarSize;
@@ -54742,9 +54372,8 @@ int streamvar_new_entry(stream_t *streamptr)
 
   streamvar_init_entry(streamptr, varID);
 
-  streamptr->vars[varID].isUsed = true;
-
-  return varID;
+  streamptr->vars[varID].isUsed = TRUE;
+  return (varID);
 }
 
 
@@ -54754,7 +54383,7 @@ allocate_record_table_entry(stream_t *streamptr, int varID, int subID, int nlevs
   int *level    = (int *) Malloc((size_t)nlevs * sizeof (int));
   int *lindex   = (int *) Malloc((size_t)nlevs * sizeof (int));
 
-  for ( int levID = 0; levID < nlevs; levID++ )
+  for (int levID = 0; levID < nlevs; levID++ )
     {
       level[levID]    = CDI_UNDEFID;
       lindex[levID]   = levID;
@@ -54799,7 +54428,7 @@ int stream_new_var(stream_t *streamptr, int gridID, int zaxisID, int tilesetID)
 
   streamptr->vars[varID].subtypeID = tilesetID;
 
-  return varID;
+  return (varID);
 }
 /*
  * Local Variables:
@@ -54826,7 +54455,7 @@ size_t grbEncode(int filetype, int memtype, int varID, int levelID, int vlistID,
   size_t nbytes = 0;
 
 #ifdef HAVE_LIBCGRIBEX
-  if ( filetype == CDI_FILETYPE_GRB )
+  if ( filetype == FILETYPE_GRB )
     {
       size_t gribbuffersize = datasize*4+3000;
       *gribbuffer = Malloc(gribbuffersize);
@@ -54854,7 +54483,7 @@ size_t grbEncode(int filetype, int memtype, int varID, int levelID, int vlistID,
 			     (long) datasize, datap, nmiss, gribbuffer, &gribbuffersize,
 			     comptype, gribContainer);
       
-      if ( memtype == MEMTYPE_FLOAT ) Free((void*)datap);
+      if ( memtype == MEMTYPE_FLOAT ) free((void*)datap);
     }
 #else
     {
@@ -54876,7 +54505,7 @@ size_t grbSzip(int filetype, void *gribbuffer, size_t gribbuffersize)
   /*  memcpy(buffer, gribbuffer, gribbuffersize); */
 
   size_t nbytes = 0;
-  if ( filetype == CDI_FILETYPE_GRB )
+  if ( filetype == FILETYPE_GRB )
     {
       nbytes = (size_t)gribZip((unsigned char *)gribbuffer, (long) gribbuffersize, (unsigned char *)buffer, (long) buffersize);
     }
@@ -54917,95 +54546,12 @@ void grbCopyRecord(stream_t * streamptr2, stream_t * streamptr1)
 
   size_t nbytes = recsize;
 
-  if ( filetype == CDI_FILETYPE_GRB )
-    {
-      if ( cdiGribChangeParameterID.active )
-        {
-          // Even if you are stream-copy records you might need to change a bit of grib-header !
-#if defined HAVE_LIBCGRIBEX
-          void *gh = cgribex_handle_new_from_meassage((void*) gribbuffer, recsize);
-          cgribexChangeParameterIdentification(gh, cdiGribChangeParameterID.code, cdiGribChangeParameterID.ltype, cdiGribChangeParameterID.lev);
-          cgribex_handle_delete(gh);
-#elif defined HAVE_LIBGRIB_API
-          void *gh = (void*)grib_handle_new_from_message(NULL, (void*) gribbuffer, recsize);
-          gribapiChangeParameterIdentification(gh, cdiGribChangeParameterID.code, cdiGribChangeParameterID.ltype, cdiGribChangeParameterID.lev);
-          grib_handle_delete(gh);
-#endif
-          cdiGribChangeParameterID.active = false; // after grib attributes have been changed turn it off again
-        }
-    }
-
-#ifdef HIRLAM_EXTENSIONS
-  // Even if you are stream-copy records you might need to change a bit of grib-header !
-
-  if ( cdiGribDataScanningMode.active )
-    // allowed modes: <0, 64, 96>; Default is 64
-    // This will overrule the old scanning mode of the given grid
-  {
-    grib_handle *gh = NULL;
-    gh = grib_handle_new_from_message(NULL, (void *) gribbuffer, recsize);
-
-    int scanModeIN = gribapiGetScanningMode(gh);
-
-    grib_handle_delete(gh);
-
-    if (cdiDebugExt>=20) Message("Change GribDataScanningMode => %d (scanModeIN = %d)", cdiGribDataScanningMode.value, scanModeIN);
-
-    if (scanModeIN != cdiGribDataScanningMode.value)
-    {
-        int gridID;
-        int varID, levelID;
-        int vlistID;
-        //int zip;
-        int gridsize, nmiss = 0;
-
-        vlistID = streamptr1->vlistID;
-        varID   = streamptr1->tsteps[tsID].records[recID].varID;
-        levelID   = streamptr1->tsteps[tsID].records[recID].levelID;
-        //gribbuffer = (unsigned char *) streamptr->record->buffer;
-        // allocate above ..
-        gridID   = vlistInqVarGrid(vlistID, varID);
-        gridsize = gridInqSize(gridID);
-
-        gridsize = vlistGridsizeMax(vlistID);
-        if ( vlistNumber(vlistID) != CDI_REAL ) gridsize *= 2;
-        double * data = (double *) malloc(gridsize*sizeof(double));
-        //int missval = vlistInqVarMissval(vlistID, varID);
-
-        //streamptr->numvals += gridsize;
-
-        // memtype: MEMTYPE_FLOAT or MEMTYPE_DOUBLE
-        //int statusDC = grbDecode(filetype, MEMTYPE_DOUBLE, gribbuffer, recsize, data, gridsize, streamptr1->unreduced, &nmiss, missval, vlistID, varID);
-        //int grbDecode(int filetype, int memtype, void *gribbuffer, int gribsize, void *data, size_t datasize,
-        //              int unreduced, int *nmiss, double missval, int vlistID, int varID);
-
-        //streamptr1->tsteps[tsID].records[recID].zip = zip;
-        //gribapiSetScanningMode(gh, cdoGribDataScanningMode);  // T.B.D. this will be done by grbDecode..
-
-        //varID   = streamptr1->record->varID;
-        //levelID = streamptr1->record->levelID;
-
-        if (cdiDebugExt>=20) Message(" processing varID %d; levelID %d",varID,levelID);
-
-        grb_write_var_slice(streamptr2, varID, levelID, MEMTYPE_DOUBLE, (const void *) data, nmiss);
-        //grb_write_var_slice(streamptr, varID, levelID, memtype, ((double*)data)+levelID*gridsize, nmiss);
-
-        //grb_write_var(streamptr2, varID, MEMTYPE_DOUBLE, data, nmiss);
-        //grb_write_var(stream_t *streamptr, int varID, int memtype, const void *data, int nmiss)
-        //grb_write_var_slice(streamptr2, varID, levelID, MEMTYPE_DOUBLE, (const void *) data, nmiss);
-
-        free(data);
-        free(gribbuffer);
-    }
-  }
-#endif // HIRLAM_EXTENSIONS
-
-  if ( filetype == CDI_FILETYPE_GRB )
+  if ( filetype == FILETYPE_GRB )
     {
-      size_t unzipsize;
-      int izip = gribGetZip(recsize, gribbuffer, &unzipsize);
+      long unzipsize;
+      int izip = gribGetZip((long)recsize, gribbuffer, &unzipsize);
 
-      if ( izip == 0 && streamptr2->comptype == CDI_COMPRESS_SZIP )
+      if ( izip == 0 && streamptr2->comptype == COMPRESS_SZIP )
           nbytes = grbSzip(filetype, gribbuffer, nbytes);
     }
 
@@ -55037,7 +54583,9 @@ void grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtyp
   int tsID      = streamptr->curTsID;
   int date      = streamptr->tsteps[tsID].taxis.vdate;
   int time      = streamptr->tsteps[tsID].taxis.vtime;
-  int numavg    = (tsteptype == TSTEP_AVG) ? streamptr->tsteps[tsID].taxis.numavg : 0;
+  int numavg    = 0;
+  if ( vlistInqVarTimave(vlistID, varID) )
+    numavg = streamptr->tsteps[tsID].taxis.numavg;
 
   if ( CDI_Debug )
     Message("gridID = %d zaxisID = %d", gridID, zaxisID);
@@ -55045,7 +54593,7 @@ void grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtyp
   size_t datasize = (size_t)gridInqSize(gridID);
 
 #ifdef HAVE_LIBCGRIBEX
-  if ( filetype == CDI_FILETYPE_GRB )
+  if ( filetype == FILETYPE_GRB )
     {
     }
   else
@@ -55060,9 +54608,9 @@ void grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtyp
 #endif
     }
 
-  if ( comptype != CDI_COMPRESS_JPEG && comptype != CDI_COMPRESS_SZIP ) comptype = CDI_COMPRESS_NONE;
+  if ( comptype != COMPRESS_JPEG && comptype != COMPRESS_SZIP ) comptype = COMPRESS_NONE;
 
-  if ( filetype == CDI_FILETYPE_GRB && comptype == CDI_COMPRESS_JPEG )
+  if ( filetype == FILETYPE_GRB && comptype == COMPRESS_JPEG )
     {
       static int ljpeg_warn = 1;
       if ( ljpeg_warn ) Warning("JPEG compression of GRIB1 records not available!");
@@ -55072,10 +54620,11 @@ void grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtyp
   size_t nbytes = grbEncode(filetype, memtype, varID, levelID, vlistID, gridID, zaxisID, date, time, tsteptype, numavg,
                             datasize, data, nmiss, &gribbuffer, comptype, gc);
 
-  if ( filetype == CDI_FILETYPE_GRB && streamptr->comptype == CDI_COMPRESS_SZIP )
+  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 (*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;
   size_t nwrite = myFileWrite(fileID, gribbuffer, nbytes, tsID);
@@ -55151,7 +54700,7 @@ int grbDecode(int filetype, int memtype, void *gribbuffer, int gribsize, void *d
   int status = 0;
 
 #if  defined  (HAVE_LIBCGRIBEX)
-  if ( filetype == CDI_FILETYPE_GRB )
+  if ( filetype == FILETYPE_GRB )
     {
 #if  defined  (HAVE_LIBGRIB_API)
       extern int cdiNAdditionalGRIBKeys;
@@ -55175,7 +54724,7 @@ int grbDecode(int filetype, int memtype, void *gribbuffer, int gribsize, void *d
           float *dataf = (float*) data;
           double *datad = (double*) datap;
           for ( size_t i = 0; i < datasize; ++i ) dataf[i] = (float) datad[i];
-          Free((void*)datap);
+          free((void*)datap);
         }
     }
 #else
@@ -55193,12 +54742,12 @@ int grbUnzipRecord(void *gribbuffer, size_t *gribsize)
 {
   int zip = 0;
   int izip;
-  size_t unzipsize;
+  long unzipsize;
 
   size_t igribsize = *gribsize;
   size_t ogribsize = *gribsize;
 
-  if ( (izip = gribGetZip(igribsize, (unsigned char *)gribbuffer, &unzipsize)) > 0 )
+  if ( (izip = gribGetZip((long)igribsize, (unsigned char *)gribbuffer, &unzipsize)) > 0 )
     {
       zip = izip;
       if ( izip == 128 ) /* szip */
@@ -55206,10 +54755,10 @@ int grbUnzipRecord(void *gribbuffer, size_t *gribsize)
 	  unsigned char *itmpbuffer = NULL;
 	  size_t itmpbuffersize = 0;
 
-	  if ( unzipsize < igribsize )
+	  if ( unzipsize < (long) igribsize )
 	    {
-	      fprintf(stderr, "Decompressed size smaller than compressed size (in %zu; out %zu)!\n", igribsize, unzipsize);
-	      return 0;
+	      fprintf(stderr, "Decompressed size smaller than compressed size (in %ld; out %ld)!\n", (long)igribsize, unzipsize);
+	      return (0);
 	    }
 
 	  if ( itmpbuffersize < igribsize )
@@ -55222,7 +54771,7 @@ int grbUnzipRecord(void *gribbuffer, size_t *gribsize)
 
 	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
 
-	  ogribsize = (size_t)gribUnzip((unsigned char *)gribbuffer, (long)unzipsize, itmpbuffer, (long)igribsize);
+	  ogribsize = (size_t)gribUnzip((unsigned char *)gribbuffer, unzipsize, itmpbuffer, (long)igribsize);
 
 	  Free(itmpbuffer);
 
@@ -55372,9 +54921,13 @@ void grb_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype
 
 
 
+#undef  UNDEFID
+#define UNDEFID  CDI_UNDEFID
+
+
 void cdfDefVarDeflate(int ncid, int ncvarid, int deflate_level)
 {
-#if  defined(HAVE_NETCDF4)
+#if  defined  (HAVE_NETCDF4)
   int retval;
   /* Set chunking, shuffle, and deflate. */
   int shuffle = 1;
@@ -55382,55 +54935,56 @@ void cdfDefVarDeflate(int ncid, int ncvarid, int deflate_level)
 
   if ( deflate_level < 1 || deflate_level > 9 ) deflate_level = 1;
 
-  if ( (retval = nc_def_var_deflate(ncid, ncvarid, shuffle, deflate, deflate_level)) )
+  if ((retval = nc_def_var_deflate(ncid, ncvarid, shuffle, deflate, deflate_level)))
     {
       Error("nc_def_var_deflate failed, status = %d", retval);
     }
 #else
-  static bool lwarn = true;
+  
+  static int lwarn = TRUE;
   if ( lwarn )
     {
-      lwarn = false;
+      lwarn = FALSE;
       Warning("Deflate compression failed, NetCDF4 not available!");
     }
 #endif
 }
 
-
+static
 int cdfDefDatatype(int datatype, int filetype)
 {
   int xtype = NC_FLOAT;
 
-  if ( datatype == CDI_DATATYPE_CPX32 || datatype == CDI_DATATYPE_CPX64 )
+  if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
     Error("CDI/NetCDF library does not support complex numbers!");
 
-  if ( filetype == CDI_FILETYPE_NC4 )
+  if ( filetype == FILETYPE_NC4 )
     {
-      if      ( datatype == CDI_DATATYPE_INT8   ) xtype = NC_BYTE;
-      else if ( datatype == CDI_DATATYPE_INT16  ) xtype = NC_SHORT;
-      else if ( datatype == CDI_DATATYPE_INT32  ) xtype = NC_INT;
+      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 == CDI_DATATYPE_UINT8  ) xtype = NC_UBYTE;
-      else if ( datatype == CDI_DATATYPE_UINT16 ) xtype = NC_USHORT;
-      else if ( datatype == CDI_DATATYPE_UINT32 ) xtype = NC_UINT;
+      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 == CDI_DATATYPE_UINT8  ) xtype = NC_SHORT;
-      else if ( datatype == CDI_DATATYPE_UINT16 ) xtype = NC_INT;
-      else if ( datatype == CDI_DATATYPE_UINT32 ) 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;
 #endif
-      else if ( datatype == CDI_DATATYPE_FLT64  ) xtype = NC_DOUBLE;
-      else                                        xtype = NC_FLOAT;
+      else if ( datatype == DATATYPE_FLT64  ) xtype = NC_DOUBLE;
+      else                                    xtype = NC_FLOAT;
     }
   else
     {
-      if      ( datatype == CDI_DATATYPE_INT8   ) xtype = NC_BYTE;
-      else if ( datatype == CDI_DATATYPE_INT16  ) xtype = NC_SHORT;
-      else if ( datatype == CDI_DATATYPE_INT32  ) xtype = NC_INT;
-      else if ( datatype == CDI_DATATYPE_UINT8  ) xtype = NC_SHORT;
-      else if ( datatype == CDI_DATATYPE_UINT16 ) xtype = NC_INT;
-      else if ( datatype == CDI_DATATYPE_UINT32 ) xtype = NC_INT;
-      else if ( datatype == CDI_DATATYPE_FLT64  ) xtype = NC_DOUBLE;
-      else                                        xtype = NC_FLOAT;
+      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;
@@ -55439,7 +54993,7 @@ int cdfDefDatatype(int datatype, int filetype)
 static
 void cdfDefVarMissval(stream_t *streamptr, int varID, int dtype, int lcheck)
 {
-  if ( streamptr->vars[varID].defmiss == false )
+  if ( streamptr->vars[varID].defmiss == FALSE )
     {
       int vlistID = streamptr->vlistID;
       int fileID  = streamptr->fileID;
@@ -55457,7 +55011,7 @@ void cdfDefVarMissval(stream_t *streamptr, int varID, int dtype, int lcheck)
 
       if ( lcheck && streamptr->ncmode == 2 ) cdf_enddef(fileID);
 
-      streamptr->vars[varID].defmiss = true;
+      streamptr->vars[varID].defmiss = TRUE;
     }
 }
 
@@ -55468,7 +55022,7 @@ void cdfDefInstitut(stream_t *streamptr)
   int fileID  = streamptr->fileID;
   int instID  = vlistInqInstitut(vlistID);
 
-  if ( instID != CDI_UNDEFID )
+  if ( instID != UNDEFID )
     {
       const char *longname = institutInqLongnamePtr(instID);
       if ( longname )
@@ -55491,7 +55045,7 @@ void cdfDefSource(stream_t *streamptr)
   int fileID  = streamptr->fileID;
   int modelID = vlistInqModel(vlistID);
 
-  if ( modelID != CDI_UNDEFID )
+  if ( modelID != UNDEFID )
     {
       const char *longname = modelInqNamePtr(modelID);
       if ( longname )
@@ -55510,7 +55064,7 @@ void cdfDefSource(stream_t *streamptr)
 static inline
 void *resizeBuf(void **buf, size_t *bufSize, size_t reqSize)
 {
-  if ( reqSize > *bufSize )
+  if (reqSize > *bufSize)
     {
       *buf = Realloc(*buf, reqSize);
       *bufSize = reqSize;
@@ -55518,8 +55072,8 @@ void *resizeBuf(void **buf, size_t *bufSize, size_t reqSize)
   return *buf;
 }
 
-
-void cdfDefineAttributes(int cdiID, int varID, int fileID, int ncvarID)
+static
+void cdfDefineAttributes(int vlistID, int varID, int fileID, int ncvarID)
 {
   int atttype, attlen;
   size_t len;
@@ -55528,47 +55082,37 @@ void cdfDefineAttributes(int cdiID, int varID, int fileID, int ncvarID)
   size_t attBufSize = 0;
 
   int natts;
-  cdiInqNatts(cdiID, varID, &natts);
+  vlistInqNatts(vlistID, varID, &natts);
 
-  for ( int iatt = 0; iatt < natts; ++iatt )
+  for ( int iatt = 0; iatt < natts; iatt++ )
     {
-      cdiInqAtt(cdiID, varID, iatt, attname, &atttype, &attlen);
+      vlistInqAtt(vlistID, varID, iatt, attname, &atttype, &attlen);
 
       if ( attlen == 0 ) continue;
 
-      if ( atttype == CDI_DATATYPE_TXT )
+      if ( atttype == DATATYPE_TXT )
         {
           size_t attSize = (size_t)attlen*sizeof(char);
           char *atttxt = (char *)resizeBuf(&attBuf, &attBufSize, attSize);
-          cdiInqAttTxt(cdiID, varID, attname, attlen, atttxt);
+          vlistInqAttTxt(vlistID, varID, attname, attlen, atttxt);
           len = (size_t)attlen;
           cdf_put_att_text(fileID, ncvarID, attname, len, atttxt);
         }
-      else if ( atttype == CDI_DATATYPE_INT8  || atttype == CDI_DATATYPE_UINT8  ||
-                atttype == CDI_DATATYPE_INT16 || atttype == CDI_DATATYPE_UINT16 ||
-                atttype == CDI_DATATYPE_INT32 || atttype == CDI_DATATYPE_UINT32 )
+      else if ( atttype == DATATYPE_INT16 || atttype == DATATYPE_INT32 )
         {
           size_t attSize = (size_t)attlen*sizeof(int);
           int *attint = (int *)resizeBuf(&attBuf, &attBufSize, attSize);
-          cdiInqAttInt(cdiID, varID, attname, attlen, &attint[0]);
+          vlistInqAttInt(vlistID, varID, attname, attlen, &attint[0]);
           len = (size_t)attlen;
-          nc_type xtype = (atttype == CDI_DATATYPE_INT8)  ? NC_BYTE :
-                          (atttype == CDI_DATATYPE_INT16) ? NC_SHORT :
-#if  defined  (HAVE_NETCDF4)
-                          (atttype == CDI_DATATYPE_UINT8)  ? NC_UBYTE :
-                          (atttype == CDI_DATATYPE_UINT16) ? NC_USHORT :
-                          (atttype == CDI_DATATYPE_UINT32) ? NC_UINT :
-#endif
-                          NC_INT;
-          cdf_put_att_int(fileID, ncvarID, attname, xtype, len, attint);
+          cdf_put_att_int(fileID, ncvarID, attname, atttype == DATATYPE_INT16 ? NC_SHORT : NC_INT, len, attint);
         }
-      else if ( atttype == CDI_DATATYPE_FLT32 || atttype == CDI_DATATYPE_FLT64 )
+      else if ( atttype == DATATYPE_FLT32 || atttype == DATATYPE_FLT64 )
         {
           size_t attSize = (size_t)attlen * sizeof(double);
           double *attflt = (double *)resizeBuf(&attBuf, &attBufSize, attSize);
-          cdiInqAttFlt(cdiID, varID, attname, attlen, attflt);
+          vlistInqAttFlt(vlistID, varID, attname, attlen, attflt);
           len = (size_t)attlen;
-          if ( atttype == CDI_DATATYPE_FLT32 )
+          if ( atttype == DATATYPE_FLT32 )
             {
               float attflt_sp[len];
               for ( size_t i = 0; i < len; ++i ) attflt_sp[i] = (float)attflt[i];
@@ -55578,7 +55122,7 @@ void cdfDefineAttributes(int cdiID, int varID, int fileID, int ncvarID)
             cdf_put_att_double(fileID, ncvarID, attname, NC_DOUBLE, len, attflt);
         }
     }
-
+  
   Free(attBuf);
 }
 
@@ -55594,7 +55138,7 @@ void cdfDefGlobalAtts(stream_t *streamptr)
   cdfDefInstitut(streamptr);
 
   int natts;
-  cdiInqNatts(vlistID, CDI_GLOBAL, &natts);
+  vlistInqNatts(vlistID, CDI_GLOBAL, &natts);
 
   if ( natts > 0 && streamptr->ncmode == 2 ) cdf_redef(fileID);
 
@@ -55612,7 +55156,7 @@ void cdfDefLocalAtts(stream_t *streamptr)
   int fileID  = streamptr->fileID;
 
   if ( streamptr->localatts ) return;
-  if ( vlistInqInstitut(vlistID) != CDI_UNDEFID ) return;
+  if ( vlistInqInstitut(vlistID) != UNDEFID ) return;
 
   streamptr->localatts = 1;
 
@@ -55621,7 +55165,7 @@ void cdfDefLocalAtts(stream_t *streamptr)
   for ( int varID = 0; varID < streamptr->nvars; varID++ )
     {
       int instID = vlistInqVarInstitut(vlistID, varID);
-      if ( instID != CDI_UNDEFID )
+      if ( instID != UNDEFID )
 	{
           int ncvarid = streamptr->vars[varID].ncvarid;
   	  const char *name = institutInqNamePtr(instID);
@@ -55637,48 +55181,14 @@ void cdfDefLocalAtts(stream_t *streamptr)
 }
 
 static
-void cdf_get_gmapvarname(int gridID, char *gmapvarname)
-{
-  int pgridID = gridID;
-  char mapping[CDI_MAX_NAME]; mapping[0] = 0;
-  cdiGridInqKeyStr(pgridID, CDI_KEY_MAPNAME, CDI_MAX_NAME, mapping);
-
-  if ( !mapping[0] )
-    {
-      int projID = gridInqProj(gridID);
-      if ( projID != CDI_UNDEFID )
-        {
-          pgridID = projID;
-          cdiGridInqKeyStr(pgridID, CDI_KEY_MAPNAME, CDI_MAX_NAME, mapping);
-        }
-    }
-
-  if ( mapping[0] )
-    cdiGridInqKeyStr(pgridID, CDI_KEY_MAPPING, CDI_MAX_NAME, gmapvarname);
-}
-
-static
-int nc_grid_index(stream_t *streamptr, int gridID)
-{
-  int index = 0;
-  int vlistID = streamptr->vlistID;
-  int ngrids = vlistNgrids(vlistID);
-  for ( index = 0; index < ngrids; ++index )
-    if ( streamptr->ncgrid[index].gridID == gridID ) break;
-
-  assert(index < ngrids);
-
-  return index;
-}
-
-static
 int cdfDefVar(stream_t *streamptr, int varID)
 {
   int ncvarid = -1;
-  int xid = CDI_UNDEFID, yid = CDI_UNDEFID;
+  int xid = UNDEFID, yid = UNDEFID;
   size_t xsize = 0, ysize = 0;
   char varname[CDI_MAX_NAME];
   int dims[4];
+  int lchunk = FALSE;
   size_t chunks[4] = {0,0,0,0};
   int ndims = 0;
   int tablenum;
@@ -55686,13 +55196,14 @@ int cdfDefVar(stream_t *streamptr, int varID)
   size_t iax = 0;
   char axis[5];
   int ensID, ensCount, forecast_type;
+  int retval;
 
   int fileID  = streamptr->fileID;
 
   if ( CDI_Debug )
     Message("streamID = %d, fileID = %d, varID = %d", streamptr->self, fileID, varID);
 
-  if ( streamptr->vars[varID].ncvarid != CDI_UNDEFID )
+  if ( streamptr->vars[varID].ncvarid != UNDEFID )
     return streamptr->vars[varID].ncvarid;
 
   int vlistID   = streamptr->vlistID;
@@ -55708,26 +55219,26 @@ int cdfDefVar(stream_t *streamptr, int varID)
 
   vlistInqVarDimorder(vlistID, varID, &dimorder);
 
-  size_t gridsize  = (size_t)(gridInqSize(gridID));
-  bool lchunk = (gridsize >= 16);
+  int gridsize  = gridInqSize(gridID);
+  if ( gridsize > 1 ) lchunk = TRUE;
   int gridtype  = gridInqType(gridID);
-  int gridindex = nc_grid_index(streamptr, gridID);
+  int gridindex = vlistGridIndex(vlistID, gridID);
   if ( gridtype != GRID_TRAJECTORY )
     {
-      xid = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X];
-      yid = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_Y];
-      if ( xid != CDI_UNDEFID ) cdf_inq_dimlen(fileID, xid, &xsize);
-      if ( yid != CDI_UNDEFID ) cdf_inq_dimlen(fileID, yid, &ysize);
+      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);
     }
 
   int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
   int zid = streamptr->zaxisID[zaxisindex];
-  bool zaxis_is_scalar = false;
-  if ( zid == CDI_UNDEFID ) zaxis_is_scalar = zaxisInqScalar(zaxisID) > 0;
+  int zaxis_is_scalar = FALSE;
+  if ( zid == UNDEFID ) zaxis_is_scalar = zaxisInqScalar(zaxisID);
 
-  if ( dimorder[0] != 3 ) lchunk = false; /* ZYX and ZXY */
+  if ( dimorder[0] != 3 ) lchunk = FALSE; /* ZYX and ZXY */
 
-  if ( ((dimorder[0]>0)+(dimorder[1]>0)+(dimorder[2]>0)) < ((xid!=CDI_UNDEFID)+(yid!=CDI_UNDEFID)+(zid!=CDI_UNDEFID)) )
+  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!");
@@ -55737,47 +55248,43 @@ int cdfDefVar(stream_t *streamptr, int varID)
 
   if ( tsteptype != TSTEP_CONSTANT )
     {
-      if ( tid == CDI_UNDEFID ) Error("Internal problem, time undefined!");
+      if ( tid == UNDEFID ) Error("Internal problem, time undefined!");
       chunks[ndims] = 1;
       dims[ndims++] = tid;
       axis[iax++] = 'T';
     }
   /*
-  if ( zid != CDI_UNDEFID ) axis[iax++] = 'Z';
-  if ( zid != CDI_UNDEFID ) chunks[ndims] = 1;
-  if ( zid != CDI_UNDEFID ) dims[ndims++] = zid;
+  if ( zid != UNDEFID ) axis[iax++] = 'Z';
+  if ( zid != UNDEFID ) chunks[ndims] = 1;
+  if ( zid != UNDEFID ) dims[ndims++] = zid;
 
-  if ( yid != CDI_UNDEFID ) chunks[ndims] = ysize;
-  if ( yid != CDI_UNDEFID ) dims[ndims++] = yid;
+  if ( yid != UNDEFID ) chunks[ndims] = ysize;
+  if ( yid != UNDEFID ) dims[ndims++] = yid;
 
-  if ( xid != CDI_UNDEFID ) chunks[ndims] = xsize;
-  if ( xid != CDI_UNDEFID ) dims[ndims++] = xid;
+  if ( xid != UNDEFID ) chunks[ndims] = xsize;
+  if ( xid != UNDEFID ) dims[ndims++] = xid;
   */
-  size_t chunk_size_max = 65536;
   for ( int id = 0; id < 3; ++id )
     {
-      if ( dimorder[id] == 3 && zid != CDI_UNDEFID )
+      if ( dimorder[id] == 3 && zid != UNDEFID )
         {
           axis[iax++] = 'Z';
           chunks[ndims] = 1;
           dims[ndims] = zid;
           ndims++;
         }
-      else if ( dimorder[id] == 2 && yid != CDI_UNDEFID )
+      else if ( dimorder[id] == 2 && yid != UNDEFID )
         {
-          if ( chunktype == CDI_CHUNK_AUTO )
-            chunks[ndims] = (chunk_size_max > gridsize) ? ysize : chunk_size_max/xsize;
+          if ( chunktype == CHUNK_LINES )
+            chunks[ndims] = 1;
           else
-            chunks[ndims] = (chunktype == CDI_CHUNK_LINES) ? 1 : ysize;
+            chunks[ndims] = ysize;
           dims[ndims] = yid;
           ndims++;
         }
-      else if ( dimorder[id] == 1 && xid != CDI_UNDEFID )
+      else if ( dimorder[id] == 1 && xid != UNDEFID )
         {
-          if ( chunktype == CDI_CHUNK_AUTO && yid == CDI_UNDEFID )
-            chunks[ndims] = (chunk_size_max > xsize) ? xsize : chunk_size_max;
-          else
-            chunks[ndims] = xsize;
+          chunks[ndims] = xsize;
           dims[ndims] = xid;
           ndims++;
         }
@@ -55798,17 +55305,24 @@ int cdfDefVar(stream_t *streamptr, int varID)
   if ( units    == NULL )    units = tableInqParUnitsPtr(tableID, code);
   if ( name )
     {
+      int checkname;
+      int iz;
+      int status;
+
       sprintf(varname, "%s", name);
 
-      bool checkname = true;
-      int iz = 0;
+      checkname = TRUE;
+      iz = 0;
 
       while ( checkname )
         {
           if ( iz ) sprintf(varname, "%s_%d", name, iz+1);
 
-          int status = nc_inq_varid(fileID, varname, &ncvarid);
-          if ( status != NC_NOERR ) checkname = false;
+          status = nc_inq_varid(fileID, varname, &ncvarid);
+          if ( status != NC_NOERR )
+            {
+              checkname = FALSE;
+            }
 
           if ( checkname ) iz++;
 
@@ -55837,7 +55351,7 @@ int cdfDefVar(stream_t *streamptr, int varID)
 
       char *varname2 = varname+strlen(varname);
 
-      bool checkname = true;
+      int checkname = TRUE;
       int iz = 0;
 
       while ( checkname )
@@ -55845,7 +55359,7 @@ int cdfDefVar(stream_t *streamptr, int varID)
           if ( iz ) sprintf(varname2, "_%d", iz+1);
 
           int status = nc_inq_varid(fileID, varname, &ncvarid);
-          if ( status != NC_NOERR ) checkname = false;
+          if ( status != NC_NOERR ) checkname = FALSE;
 
           if ( checkname ) iz++;
 
@@ -55865,13 +55379,20 @@ int cdfDefVar(stream_t *streamptr, int varID)
   cdf_def_var(fileID, name, (nc_type) xtype, ndims, dims, &ncvarid);
 
 #if  defined  (HAVE_NETCDF4)
-  if ( lchunk && (streamptr->filetype == CDI_FILETYPE_NC4 || streamptr->filetype == CDI_FILETYPE_NC4C) )
-    cdf_def_var_chunking(fileID, ncvarid, NC_CHUNKED, chunks);
+  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);
+
+      if ( retval ) Error("nc_def_var_chunking failed, status = %d", retval);
+    }
 #endif
 
-  if ( streamptr->comptype == CDI_COMPRESS_ZIP )
+  if ( streamptr->comptype == COMPRESS_ZIP )
     {
-      if ( lchunk && (streamptr->filetype == CDI_FILETYPE_NC4 || streamptr->filetype == CDI_FILETYPE_NC4C) )
+      if ( lchunk && (streamptr->filetype == FILETYPE_NC4 || streamptr->filetype == FILETYPE_NC4C) )
         {
           cdfDefVarDeflate(fileID, ncvarid, streamptr->complevel);
         }
@@ -55879,16 +55400,45 @@ int cdfDefVar(stream_t *streamptr, int varID)
         {
           if ( lchunk )
             {
-              static bool lwarn = true;
+              static int lwarn = TRUE;
+
               if ( lwarn )
                 {
-                  lwarn = false;
+                  lwarn = FALSE;
                   Warning("Deflate compression is only available for NetCDF4!");
                 }
             }
         }
     }
 
+  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 ( 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!");
+            }
+        }
+    }
+
   if ( stdname && *stdname )
     cdf_put_att_text(fileID, ncvarid, "standard_name", strlen(stdname), stdname);
 
@@ -55908,16 +55458,17 @@ int cdfDefVar(stream_t *streamptr, int varID)
       cdf_put_att_text(fileID, ncvarid, "param", strlen(paramstr), paramstr);
     }
 
-  if ( tableID != CDI_UNDEFID )
+  if ( tableID != UNDEFID )
     {
       tablenum = tableInqNum(tableID);
       if ( tablenum > 0 )
         cdf_put_att_int(fileID, ncvarid, "table", NC_INT, 1, &tablenum);
     }
 
-  char coordinates[CDI_MAX_NAME]; coordinates[0] = 0;
+  char coordinates[CDI_MAX_NAME];
+  coordinates[0] = 0;
 
-  if ( zaxis_is_scalar || zaxisInqType(zaxisID) == ZAXIS_CHAR )
+  if ( zaxis_is_scalar )
     {
       int nczvarID = streamptr->nczvarID[zaxisindex];
       if ( nczvarID != CDI_UNDEFID )
@@ -55928,28 +55479,42 @@ int cdfDefVar(stream_t *streamptr, int varID)
         }
     }
 
-  if ( gridtype != GRID_GENERIC && gridtype != GRID_LONLAT && gridtype != GRID_GAUSSIAN &&
-       gridtype != GRID_PROJECTION && gridtype != GRID_CURVILINEAR && gridtype != GRID_CHARXY )
+  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, "CDI_grid_type", len, gridNamePtr(gridtype));
+        cdf_put_att_text(fileID, ncvarid, "grid_type", len, gridNamePtr(gridtype));
     }
 
-  char gmapvarname[CDI_MAX_NAME]; gmapvarname[0] = 0;
-
-  cdf_get_gmapvarname(gridID, gmapvarname);
-
-  if ( gmapvarname[0] ) cdf_put_att_text(fileID, ncvarid, "grid_mapping", strlen(gmapvarname), gmapvarname);
+  if ( gridIsRotated(gridID) )
+    {
+      char mapping[] = "rotated_pole";
+      cdf_put_att_text(fileID, ncvarid, "grid_mapping", strlen(mapping), mapping);
+    }
 
-  if ( gridtype == GRID_TRAJECTORY )
+  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 == CDI_UNDEFID && yid == CDI_UNDEFID && gridsize == 1 )
+  else if ( gridtype == GRID_LONLAT && xid == UNDEFID && yid == UNDEFID && gridsize == 1 )
     {
-      int ncxvarID = streamptr->ncgrid[gridindex].ncIDs[CDF_VARID_X];
-      int ncyvarID = streamptr->ncgrid[gridindex].ncIDs[CDF_VARID_Y];
+      int ncxvarID = streamptr->ncxvarID[gridindex];
+      int ncyvarID = streamptr->ncyvarID[gridindex];
       if ( ncyvarID != CDI_UNDEFID )
         {
           size_t len = strlen(coordinates);
@@ -55966,39 +55531,20 @@ int cdfDefVar(stream_t *streamptr, int varID)
   else if ( gridtype == GRID_UNSTRUCTURED || gridtype == GRID_CURVILINEAR )
     {
       char cellarea[CDI_MAX_NAME] = "area: ";
-      int ncxvarID = streamptr->ncgrid[gridindex].ncIDs[CDF_VARID_X];
-      int ncyvarID = streamptr->ncgrid[gridindex].ncIDs[CDF_VARID_Y];
-      int ncavarID = streamptr->ncgrid[gridindex].ncIDs[CDF_VARID_A];
-      // CMOR order: coordinates = "lat lon"
-      if ( cdiCoordinatesLonLat )
+      int ncxvarID = streamptr->ncxvarID[gridindex];
+      int ncyvarID = streamptr->ncyvarID[gridindex];
+      int ncavarID = streamptr->ncavarID[gridindex];
+      if ( ncyvarID != CDI_UNDEFID )
         {
-          if ( ncxvarID != CDI_UNDEFID )
-            {
-              size_t len = strlen(coordinates);
-              if ( len ) coordinates[len++] = ' ';
-              cdf_inq_varname(fileID, ncxvarID, coordinates+len);
-            }
-          if ( ncyvarID != CDI_UNDEFID )
-            {
-              size_t len = strlen(coordinates);
-              if ( len ) coordinates[len++] = ' ';
-              cdf_inq_varname(fileID, ncyvarID, coordinates+len);
-            }
+          size_t len = strlen(coordinates);
+          if ( len ) coordinates[len++] = ' ';
+          cdf_inq_varname(fileID, ncyvarID, coordinates+len);
         }
-      else
+      if ( ncxvarID != CDI_UNDEFID )
         {
-          if ( ncyvarID != CDI_UNDEFID )
-            {
-              size_t len = strlen(coordinates);
-              if ( len ) coordinates[len++] = ' ';
-              cdf_inq_varname(fileID, ncyvarID, coordinates+len);
-            }
-          if ( ncxvarID != CDI_UNDEFID )
-            {
-              size_t len = strlen(coordinates);
-              if ( len ) coordinates[len++] = ' ';
-              cdf_inq_varname(fileID, ncxvarID, coordinates+len);
-            }
+          size_t len = strlen(coordinates);
+          if ( len ) coordinates[len++] = ' ';
+          cdf_inq_varname(fileID, ncxvarID, coordinates+len);
         }
 
       if ( ncavarID != CDI_UNDEFID )
@@ -56024,35 +55570,20 @@ int cdfDefVar(stream_t *streamptr, int varID)
       cdf_put_att_text(fileID, ncvarid, "axis", iax, axis);
       cdf_put_att_int(fileID, ncvarid, "truncation", NC_INT, 1, &gridTruncation);
     }
-  else if ( gridtype == GRID_CHARXY )
-    {
-      if ( gridInqXIsc(gridID) )
-        {
-          int ncxvarID = streamptr->ncgrid[gridindex].ncIDs[CDF_VARID_X];
-          size_t len = strlen(coordinates);
-          if ( len ) coordinates[len++] = ' ';
-          cdf_inq_varname(fileID, ncxvarID, coordinates+len);
-        }
-      else if ( gridInqYIsc(gridID) )
-        {
-          int ncyvarID = streamptr->ncgrid[gridindex].ncIDs[CDF_VARID_Y];
-          size_t len = strlen(coordinates);
-          if ( len ) coordinates[len++] = ' ';
-          cdf_inq_varname(fileID, ncyvarID, coordinates+len);
-        }
-    }
 
   size_t len = strlen(coordinates);
   if ( len ) cdf_put_att_text(fileID, ncvarid, "coordinates", len, coordinates);
 
   /*  if ( xtype == NC_BYTE || xtype == NC_SHORT || xtype == NC_INT ) */
     {
+      int laddoffset, lscalefactor;
+      double addoffset, scalefactor;
       int astype = NC_DOUBLE;
 
-      double addoffset   = vlistInqVarAddoffset(vlistID, varID);
-      double scalefactor = vlistInqVarScalefactor(vlistID, varID);
-      bool laddoffset   = IS_NOT_EQUAL(addoffset, 0);
-      bool lscalefactor = IS_NOT_EQUAL(scalefactor, 1);
+      addoffset    = vlistInqVarAddoffset(vlistID, varID);
+      scalefactor  = vlistInqVarScalefactor(vlistID, varID);
+      laddoffset   = IS_NOT_EQUAL(addoffset, 0);
+      lscalefactor = IS_NOT_EQUAL(scalefactor, 1);
 
       if ( laddoffset || lscalefactor )
         {
@@ -56069,7 +55600,7 @@ int cdfDefVar(stream_t *streamptr, int varID)
         }
     }
 
-  if ( dtype == CDI_DATATYPE_UINT8 && xtype == NC_BYTE )
+  if ( dtype == DATATYPE_UINT8 && xtype == NC_BYTE )
     {
       int validrange[2] = {0, 255};
       cdf_put_att_int(fileID, ncvarid, "valid_range", NC_SHORT, 2, validrange);
@@ -56108,6 +55639,14 @@ int cdfDefVar(stream_t *streamptr, int varID)
 	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);
+
+#ifdef DBG
+	if( DBG )
+	  {
+	    fprintf( stderr, "cdfDefVar :\n EnsID  %d\n Enscount %d\n Forecast init type %d\n",  ensID,
+		     ensCount,  forecast_type );
+	  }
+#endif
     }
 
   /* Attributes */
@@ -56148,23 +55687,25 @@ void cdfEndDef(stream_t *streamptr)
 static
 void cdfWriteGridTraj(stream_t *streamptr, int gridID)
 {
-  int gridindex = nc_grid_index(streamptr, gridID);
-  int lonID = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X];
-  int latID = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_Y];
+  int vlistID = streamptr->vlistID;
+  int fileID  = streamptr->fileID;
+
+  int gridindex = vlistGridIndex(vlistID, gridID);
+  int lonID = streamptr->xdimID[gridindex];
+  int latID = streamptr->ydimID[gridindex];
 
   double xlon = gridInqXval(gridID, 0);
   double xlat = gridInqYval(gridID, 0);
   int tsID = streamptr->curTsID;
   size_t index = (size_t)tsID;
 
-  int fileID = streamptr->fileID;
   cdf_put_var1_double(fileID, lonID, &index, &xlon);
   cdf_put_var1_double(fileID, latID, &index, &xlat);
 }
 
 static
 void cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarid, int dtype, size_t nvals, size_t xsize, size_t ysize,
-                        bool swapxy, size_t *start, size_t *count, int memtype, const void *data, int nmiss)
+                        int swapxy, size_t *start, size_t *count, int memtype, const void *data, int nmiss)
 {
   const double *pdata_dp = (const double *) data;
   double *mdata_dp = NULL;
@@ -56173,7 +55714,7 @@ void cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarid, int dty
   float *mdata_sp = NULL;
   float *sdata_sp = NULL;
 
-  /*  if ( dtype == CDI_DATATYPE_INT8 || dtype == CDI_DATATYPE_INT16 || dtype == CDI_DATATYPE_INT32 ) */
+  /*  if ( dtype == DATATYPE_INT8 || dtype == DATATYPE_INT16 || dtype == DATATYPE_INT32 ) */
     {
       double missval      = vlistInqVarMissval(vlistID, varID);
       double addoffset    = vlistInqVarAddoffset(vlistID, varID);
@@ -56241,8 +55782,8 @@ void cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarid, int dty
             }
         }
 
-      if ( dtype == CDI_DATATYPE_UINT8 || dtype == CDI_DATATYPE_INT8 ||
-           dtype == CDI_DATATYPE_INT16 || dtype == CDI_DATATYPE_INT32 )
+      if ( dtype == DATATYPE_UINT8 || dtype == DATATYPE_INT8 ||
+           dtype == DATATYPE_INT16 || dtype == DATATYPE_INT32 )
         {
           if ( memtype == MEMTYPE_FLOAT )
             {
@@ -56255,7 +55796,7 @@ void cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarid, int dty
 
               for ( size_t i = 0; i < nvals; i++ ) mdata_sp[i] = roundf(mdata_sp[i]);
 
-              if ( dtype == CDI_DATATYPE_UINT8 )
+              if ( dtype == DATATYPE_UINT8 )
                 {
                   nc_type xtype;
                   cdf_inq_vartype(fileID, ncvarid, &xtype);
@@ -56277,7 +55818,7 @@ void cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarid, int dty
 
               for ( size_t i = 0; i < nvals; i++ ) mdata_dp[i] = round(mdata_dp[i]);
 
-              if ( dtype == CDI_DATATYPE_UINT8 )
+              if ( dtype == DATATYPE_UINT8 )
                 {
                   nc_type xtype;
                   cdf_inq_vartype(fileID, ncvarid, &xtype);
@@ -56292,8 +55833,9 @@ void cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarid, int dty
 
       if ( CDF_Debug && memtype != MEMTYPE_FLOAT )
         {
-          double fmin =  1.0e200;
-          double fmax = -1.0e200;
+          double fmin, fmax;
+          fmin =  1.0e200;
+          fmax = -1.0e200;
           for ( size_t i = 0; i < nvals; ++i )
             {
               if ( !DBL_IS_EQUAL(pdata_dp[i], missval) )
@@ -56307,7 +55849,7 @@ void cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarid, int dty
         }
     }
 
-  if ( swapxy ) // implemented only for cdf_write_var_slice()
+  if ( swapxy ) // implemented only for cdf_write_var_slice() 
     {
       size_t gridsize = xsize*ysize;
       if ( memtype == MEMTYPE_FLOAT )
@@ -56348,8 +55890,9 @@ void cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data
   size_t size;
   size_t start[5];
   size_t count[5];
-  bool swapxy = false;
-  size_t ndims = 0;
+  int swapxy = FALSE;
+  int ndims = 0;
+  int idim;
 
   if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
 
@@ -56367,16 +55910,16 @@ void cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data
   int zaxisID   = vlistInqVarZaxis(vlistID, varID);
   int tsteptype = vlistInqVarTsteptype(vlistID, varID);
 
-  int xid = CDI_UNDEFID, yid = CDI_UNDEFID;
+  int xid = UNDEFID, yid = UNDEFID;
   if ( gridInqType(gridID) == GRID_TRAJECTORY )
     {
       cdfWriteGridTraj(streamptr, gridID);
     }
   else
     {
-      int gridindex = nc_grid_index(streamptr, gridID);
-      xid = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X];
-      yid = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_Y];
+      int gridindex = vlistGridIndex(vlistID, gridID);
+      xid = streamptr->xdimID[gridindex];
+      yid = streamptr->ydimID[gridindex];
     }
 
   int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
@@ -56389,14 +55932,14 @@ void cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data
       ndims++;
     }
 
-  if ( zid != CDI_UNDEFID )
+  if ( zid != UNDEFID )
     {
       start[ndims] = 0;
       count[ndims] = (size_t)zaxisInqSize(zaxisID);
       ndims++;
     }
 
-  if ( yid != CDI_UNDEFID )
+  if ( yid != UNDEFID )
     {
       start[ndims] = 0;
       cdf_inq_dimlen(fileID, yid, &size);
@@ -56405,7 +55948,7 @@ void cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data
       ndims++;
     }
 
-  if ( xid != CDI_UNDEFID )
+  if ( xid != UNDEFID )
     {
       start[ndims] = 0;
       cdf_inq_dimlen(fileID, xid, &size);
@@ -56415,7 +55958,7 @@ void cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data
     }
 
   if ( CDI_Debug )
-    for (size_t idim = 0; idim < ndims; idim++)
+    for (idim = 0; idim < ndims; idim++)
       Message("dim = %d  start = %d  count = %d", idim, start[idim], count[idim]);
 
   if ( streamptr->ncmode == 1 )
@@ -56439,12 +55982,13 @@ void cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
 {
   if ( streamptr->accessmode == 0 ) cdfEndDef(streamptr);
 
-  int xid = CDI_UNDEFID, yid = CDI_UNDEFID;
+  int xid = UNDEFID, yid = UNDEFID;
   size_t xsize = 0, ysize = 0;
   size_t start[5];
   size_t count[5];
-  bool swapxy = false;
-  size_t ndims = 0;
+  int swapxy = FALSE;
+  int ndims = 0;
+  int idim;
   int streamID = streamptr->self;
 
   if ( CDI_Debug )
@@ -56471,9 +56015,9 @@ void cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
     }
   else
     {
-      int gridindex = nc_grid_index(streamptr, gridID);
-      xid = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X];
-      yid = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_Y];
+      int gridindex = vlistGridIndex(vlistID, gridID);
+      xid = streamptr->xdimID[gridindex];
+      yid = streamptr->ydimID[gridindex];
     }
 
   int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
@@ -56485,7 +56029,7 @@ void cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
       count[ndims] = 1;
       ndims++;
     }
-  if ( zid != CDI_UNDEFID )
+  if ( zid != UNDEFID )
     {
       int size = zaxisInqSize(zaxisID);
       xassert(rect[2][0] >= 0 && rect[2][0] <= rect[2][1]
@@ -56494,7 +56038,7 @@ void cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
       count[ndims] = (size_t)rect[2][1] - (size_t)rect[2][0] + 1;
       ndims++;
     }
-  if ( yid != CDI_UNDEFID )
+  if ( yid != UNDEFID )
     {
       size_t size;
       cdf_inq_dimlen(fileID, yid, &size);
@@ -56504,7 +56048,7 @@ void cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
       count[ndims] = (size_t)rect[1][1] - (size_t)rect[1][0] + 1;
       ndims++;
     }
-  if ( xid != CDI_UNDEFID )
+  if ( xid != UNDEFID )
     {
       size_t size;
       cdf_inq_dimlen(fileID, xid, &size);
@@ -56516,7 +56060,7 @@ void cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
     }
 
   if ( CDI_Debug )
-    for (size_t idim = 0; idim < ndims; idim++)
+    for (idim = 0; idim < ndims; idim++)
       Message("dim = %d  start = %d  count = %d", idim, start[idim], count[idim]);
 
   if ( streamptr->ncmode == 1 )
@@ -56544,7 +56088,7 @@ void cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtyp
   size_t start[5];
   size_t count[5];
   int dimorder[3];
-  int xid = CDI_UNDEFID, yid = CDI_UNDEFID;
+  int xid = UNDEFID, yid = UNDEFID;
 
   if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
 
@@ -56569,15 +56113,15 @@ void cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtyp
     }
   else
     {
-      int gridindex = nc_grid_index(streamptr, gridID);
-      xid = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X];
-      yid = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_Y];
+      int gridindex = vlistGridIndex(vlistID, gridID);
+      xid = streamptr->xdimID[gridindex];
+      yid = streamptr->ydimID[gridindex];
     }
 
   int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
   int zid = streamptr->zaxisID[zaxisindex];
 
-  bool swapxy = (dimorder[2] == 2 || dimorder[0] == 1) && xid != CDI_UNDEFID && yid != CDI_UNDEFID;
+  int swapxy = (dimorder[2] == 2 || dimorder[0] == 1) && xid != UNDEFID && yid != UNDEFID;
 
   size_t ndims = 0;
   if ( tsteptype != TSTEP_CONSTANT )
@@ -56589,20 +56133,20 @@ void cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtyp
 
   for ( int id = 0; id < 3; ++id )
     {
-      if ( dimorder[id] == 3 && zid != CDI_UNDEFID )
+      if ( dimorder[id] == 3 && zid != UNDEFID )
         {
           start[ndims] = (size_t)levelID;
           count[ndims] = 1;
           ndims++;
         }
-      else if ( dimorder[id] == 2 && yid != CDI_UNDEFID )
+      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 != CDI_UNDEFID )
+      else if ( dimorder[id] == 1 && xid != UNDEFID )
         {
           start[ndims] = 0;
           cdf_inq_dimlen(fileID, xid, &xsize);
@@ -56634,16 +56178,6 @@ void cdf_write_record(stream_t *streamptr, int memtype, const void *data, int nm
 }
 
 #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
 
@@ -56654,6 +56188,10 @@ void cdf_write_record(stream_t *streamptr, int memtype, const void *data, int nm
 
 
 
+#undef  UNDEFID
+#define UNDEFID  CDI_UNDEFID
+
+
 static
 void cdfReadGridTraj(stream_t *streamptr, int gridID)
 {
@@ -56661,8 +56199,8 @@ void cdfReadGridTraj(stream_t *streamptr, int gridID)
   int fileID  = streamptr->fileID;
 
   int gridindex = vlistGridIndex(vlistID, gridID);
-  int lonID = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X];
-  int latID = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_Y];
+  int lonID = streamptr->xdimID[gridindex];
+  int latID = streamptr->ydimID[gridindex];
 
   int tsID = streamptr->curTsID;
   size_t index = (size_t)tsID;
@@ -56687,15 +56225,15 @@ void cdfGetSlapDescription(stream_t *streamptr, int varID, size_t (*start)[4], s
 
   if ( CDI_Debug ) Message("tsID = %d", tsID);
 
-  int xid = CDI_UNDEFID, yid = CDI_UNDEFID;
+  int xid = UNDEFID, yid = UNDEFID;
   if ( gridInqType(gridID) == GRID_TRAJECTORY )
     {
       cdfReadGridTraj(streamptr, gridID);
     }
   else
     {
-      xid = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X];
-      yid = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_Y];
+      xid = streamptr->xdimID[gridindex];
+      yid = streamptr->ydimID[gridindex];
     }
   int zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
   int zid = streamptr->zaxisID[zaxisindex];
@@ -56708,9 +56246,9 @@ void cdfGetSlapDescription(stream_t *streamptr, int varID, size_t (*start)[4], s
       ndims++; \
     } while(0)
   if ( tsteptype != TSTEP_CONSTANT ) addDimension((size_t)tsID, 1);
-  if ( zid != CDI_UNDEFID ) addDimension(0, (size_t)zaxisInqSize(zaxisID));
-  if ( yid != CDI_UNDEFID ) addDimension(0, (size_t)gridInqYsize(gridID));
-  if ( xid != CDI_UNDEFID ) addDimension(0, (size_t)gridInqXsize(gridID));
+  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)));
@@ -56948,12 +56486,18 @@ void transpose2dArrayDP(size_t inWidth, size_t inHeight, double *data)
   */
 
   for ( size_t yBlock = 0; yBlock < inHeight; yBlock += cacheBlockSize )
-    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];
-          }
+    {
+      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];
+                }
+            }
+        }
+    }
 
   Free(temp[0]);
 }
@@ -56983,12 +56527,18 @@ void transpose2dArraySP(size_t inWidth, size_t inHeight, float *data)
   */
 
   for ( size_t yBlock = 0; yBlock < inHeight; yBlock += cacheBlockSize )
-    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];
-          }
+    {
+      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];
+                }
+            }
+        }
+    }
 
   Free(temp);
 }
@@ -56999,7 +56549,7 @@ void cdfInqDimIds(stream_t *streamptr, int varId, int (*outDimIds)[3])
   int gridId = vlistInqVarGrid(streamptr->vlistID, varId);
   int gridindex = vlistGridIndex(streamptr->vlistID, gridId);
 
-  (*outDimIds)[0] = (*outDimIds)[1] = (*outDimIds)[2] = CDI_UNDEFID;
+  (*outDimIds)[0] = (*outDimIds)[1] = (*outDimIds)[2] = UNDEFID;
   switch ( gridInqType(gridId) )
     {
       case GRID_TRAJECTORY:
@@ -57007,12 +56557,12 @@ void cdfInqDimIds(stream_t *streamptr, int varId, int (*outDimIds)[3])
         break;
 
       case GRID_UNSTRUCTURED:
-        (*outDimIds)[0] = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X];
+        (*outDimIds)[0] = streamptr->xdimID[gridindex];
         break;
 
       default:
-        (*outDimIds)[0] = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_X];
-        (*outDimIds)[1] = streamptr->ncgrid[gridindex].ncIDs[CDF_DIMID_Y];
+        (*outDimIds)[0] = streamptr->xdimID[gridindex];
+        (*outDimIds)[1] = streamptr->ydimID[gridindex];
         break;
     }
 
@@ -57024,8 +56574,8 @@ void cdfInqDimIds(stream_t *streamptr, int varId, int (*outDimIds)[3])
 static
 int cdfGetSkipDim(int fileId, int ncvarid, int (*dimIds)[3])
 {
-  if((*dimIds)[0] != CDI_UNDEFID) return 0;
-  if((*dimIds)[1] != CDI_UNDEFID) return 0;
+  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;
@@ -57070,7 +56620,7 @@ void cdfGetSliceSlapDescription(stream_t *streamptr, int varId, int levelId, boo
   int dimorder[3];
   vlistInqVarDimorder(vlistId, varId, &dimorder);
 
-  *outSwapXY = (dimorder[2] == 2 || dimorder[0] == 1) && dimIds[0] != CDI_UNDEFID && dimIds[1] != CDI_UNDEFID ;
+  *outSwapXY = (dimorder[2] == 2 || dimorder[0] == 1) && dimIds[0] != UNDEFID && dimIds[1] != UNDEFID ;
 
   int ndims = 0;
 
@@ -57087,7 +56637,7 @@ void cdfGetSliceSlapDescription(stream_t *streamptr, int varId, int levelId, boo
     {
       size_t size;
       int curDimId = dimIds[dimorder[id]-1];
-      if ( curDimId == CDI_UNDEFID ) continue;
+      if ( curDimId == UNDEFID ) continue;
       switch ( dimorder[id] )
         {
           Error("Internal errror: Malformed dimension order encountered. Please report this bug.\n");
@@ -57216,7 +56766,7 @@ void cdfReadVarSliceDP(stream_t *streamptr, int varID, int levelID, double *data
   size_t xsize = (size_t)gridInqXsize(gridId);
   size_t ysize = (size_t)gridInqYsize(gridId);
 
-  if ( vlistInqVarDatatype(vlistID, varID) == CDI_DATATYPE_FLT32 )
+  if ( vlistInqVarDatatype(vlistID, varID) == DATATYPE_FLT32 )
     {
       float *data_fp = (float *) Malloc(gridsize*sizeof(*data_fp));
       cdf_get_vara_float(fileID, ncvarid, start, count, data_fp);
@@ -57228,7 +56778,7 @@ void cdfReadVarSliceDP(stream_t *streamptr, int varID, int levelID, double *data
     {
       cdf_get_vara_double(fileID, ncvarid, start, count, data);
       
-      if ( vlistInqVarDatatype(vlistID, varID) == CDI_DATATYPE_UINT8 )
+      if ( vlistInqVarDatatype(vlistID, varID) == DATATYPE_UINT8 )
         {
           nc_type xtype;
           cdf_inq_vartype(fileID, ncvarid, &xtype);
@@ -57273,7 +56823,7 @@ void cdfReadVarSliceSP(stream_t *streamptr, int varID, int levelID, float *data,
   size_t xsize = (size_t)gridInqXsize(gridId);
   size_t ysize = (size_t)gridInqYsize(gridId);
 
-  if ( vlistInqVarDatatype(vlistID, varID) == CDI_DATATYPE_FLT64 )
+  if ( vlistInqVarDatatype(vlistID, varID) == DATATYPE_FLT64 )
     {
       double *data_dp = (double *) Malloc(gridsize*sizeof(*data_dp));
       cdf_get_vara_double(fileID, ncvarid, start, count, data_dp);
@@ -57285,7 +56835,7 @@ void cdfReadVarSliceSP(stream_t *streamptr, int varID, int levelID, float *data,
     {
       cdf_get_vara_float(fileID, ncvarid, start, count, data);
 
-      if ( vlistInqVarDatatype(vlistID, varID) == CDI_DATATYPE_UINT8 )
+      if ( vlistInqVarDatatype(vlistID, varID) == DATATYPE_UINT8 )
         {
           nc_type xtype;
           cdf_inq_vartype(fileID, ncvarid, &xtype);
@@ -59743,6 +59293,8 @@ void tableDefault(void)
 #include <string.h>
 
 
+#undef  UNDEFID
+#define UNDEFID -1
 
 /*int TableDefine = 0; */ /* Define new table also if the entry already exist */
                           /* This is needed for createtable */
@@ -59825,8 +59377,8 @@ static void parTableInitEntry(int tableID)
   parTable[tableID].used    = 0;
   parTable[tableID].pars    = NULL;
   parTable[tableID].npars   = 0;
-  parTable[tableID].modelID = CDI_UNDEFID;
-  parTable[tableID].number  = CDI_UNDEFID;
+  parTable[tableID].modelID = UNDEFID;
+  parTable[tableID].number  = UNDEFID;
   parTable[tableID].name    = NULL;
 }
 
@@ -60054,7 +59606,7 @@ int tableRead(const char *tablefile)
   int lnr = 0;
   int id;
   char name[256], longname[256], units[256];
-  int tableID = CDI_UNDEFID;
+  int tableID = UNDEFID;
   int err;
   char *tablename;
   FILE *tablefp;
@@ -60108,57 +59660,78 @@ int tableRead(const char *tablefile)
 
 static int tableFromEnv(int modelID, int tablenum)
 {
+  int tableID = UNDEFID;
   char tablename[256] = {'\0'};
-  size_t tablenameLen = 0;
-  int instID;
+  int tablenamefound = 0;
 
-  const char *name2Use;
-  {
-    const char *modelName, *instName;
-    if ( (modelName = modelInqNamePtr(modelID)) )
-      name2Use = modelName;
-    else if ( (instID = modelInqInstitut(modelID)) != CDI_UNDEFID
-              && (instName = institutInqNamePtr(instID)) )
-      name2Use = instName;
-    else
-      return CDI_UNDEFID;
-  }
-  tablenameLen = strlen(name2Use);
-  memcpy(tablename, name2Use, tablenameLen);
-  if ( tablenum )
-    tablenameLen
-      += (size_t)(sprintf(tablename+tablenameLen, "_%03d", tablenum));
-  size_t lenp = 0, lenf = tablenameLen;
-  if ( tablePath )
-    lenp = strlen(tablePath);
-  /* if (tablePath) printf("tablePath = %s\n", tablePath); */
-  /* if (tablename) printf("tableName = %s\n", tablename); */
-  char *tablefile = (char *) Malloc(lenp+lenf+3);
-  if ( tablePath )
-    {
-      strcpy(tablefile, tablePath);
-      strcat(tablefile, "/");
+  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
-    tablefile[0] = '\0';
-  strcat(tablefile, tablename);
-  /* if (tablefile) printf("tableFile = %s\n", tablefile); */
+    {
+      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;
+	    }
+	}
+    }
 
-  int tableID = tableRead(tablefile);
-  if ( tableID != CDI_UNDEFID )
+  if ( tablenamefound )
     {
-      tableDefModelID(tableID, modelID);
-      tableDefNum(tableID, tablenum);
+      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, "/");
+	}
+      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); */
+
+      Free(tablefile);
     }
-  /* printf("tableID = %d %s\n", tableID, tablefile); */
-  Free(tablefile);
+
   return (tableID);
 }
 
 int tableInq(int modelID, int tablenum, const char *tablename)
 {
-  int tableID = CDI_UNDEFID;
-  int modelID2 = CDI_UNDEFID;
+  int tableID = UNDEFID;
+  int modelID2 = UNDEFID;
   char tablefile[256] = {'\0'};
 
   if ( ! ParTableInit ) parTableInit();
@@ -60180,7 +59753,7 @@ int tableInq(int modelID, int tablenum, const char *tablename)
 	      if ( memcmp(parTable[tableID].name, tablename, len) == 0 ) break;
 	    }
 	}
-      if ( tableID == MAX_TABLE ) tableID = CDI_UNDEFID;
+      if ( tableID == MAX_TABLE ) tableID = UNDEFID;
       if ( CDI_Debug )
 	Message("tableID = %d tablename = %s", tableID, tablename);
     }
@@ -60195,11 +59768,11 @@ int tableInq(int modelID, int tablenum, const char *tablename)
 	    }
 	}
 
-      if ( tableID == MAX_TABLE ) tableID = CDI_UNDEFID;
+      if ( tableID == MAX_TABLE ) tableID = UNDEFID;
 
-      if ( tableID == CDI_UNDEFID )
+      if ( tableID == UNDEFID )
 	{
-	  if ( modelID != CDI_UNDEFID )
+	  if ( modelID != UNDEFID )
 	    {
               const char *modelName;
 	      if ( (modelName = modelInqNamePtr(modelID)) )
@@ -60211,7 +59784,7 @@ int tableInq(int modelID, int tablenum, const char *tablename)
 		  modelID2 = modelInq(-1, 0, tablefile);
 		}
 	    }
-	  if ( modelID2 != CDI_UNDEFID )
+	  if ( modelID2 != UNDEFID )
 	    for ( tableID = 0; tableID < MAX_TABLE; tableID++ )
 	      {
 		if ( parTable[tableID].used )
@@ -60222,9 +59795,9 @@ int tableInq(int modelID, int tablenum, const char *tablename)
 	      }
 	}
 
-      if ( tableID == MAX_TABLE ) tableID = CDI_UNDEFID;
+      if ( tableID == MAX_TABLE ) tableID = UNDEFID;
 
-      if ( tableID == CDI_UNDEFID && modelID != CDI_UNDEFID )
+      if ( tableID == UNDEFID && modelID != UNDEFID )
 	tableID = tableFromEnv(modelID, tablenum);
 
       if ( CDI_Debug )
@@ -60237,14 +59810,14 @@ int tableInq(int modelID, int tablenum, const char *tablename)
 
 int tableDef(int modelID, int tablenum, const char *tablename)
 {
-  int tableID = CDI_UNDEFID;
+  int tableID = UNDEFID;
 
   if ( ! ParTableInit ) parTableInit();
   /*
-  if ( ! (modelID == CDI_UNDEFID && tablenum == 0) )
+  if ( ! (modelID == UNDEFID && tablenum == 0) )
     tableID = tableInq(modelID, tablenum, tablename);
     */
-  if ( tableID == CDI_UNDEFID )
+  if ( tableID == UNDEFID )
     {
       tableID = tableNewEntry();
 
@@ -60326,7 +59899,7 @@ void tableWrite(const char *ptfile, int tableID)
   if ( CDI_Debug )
     Message("write parameter table %d to %s", tableID, ptfile);
 
-  if ( tableID == CDI_UNDEFID )
+  if ( tableID == UNDEFID )
     {
       Warning("parameter table ID undefined");
       return;
@@ -60438,7 +60011,7 @@ void tableFWriteC(FILE *ptfp, int tableID)
   char tablename[256];
 
 
-  if ( tableID == CDI_UNDEFID )
+  if ( tableID == UNDEFID )
     {
       Warning("parameter table ID undefined");
       return;
@@ -60506,7 +60079,7 @@ int tableInqParCode(int tableID, char *varname, int *code)
 {
   int err = 1;
 
-  if ( tableID != CDI_UNDEFID && varname != NULL )
+  if ( tableID != UNDEFID && varname != NULL )
     {
       int npars = parTable[tableID].npars;
       for ( int item = 0; item < npars; item++ )
@@ -60543,7 +60116,7 @@ int tableInqParName(int tableID, int code, char *varname)
 	    }
 	}
     }
-  else if ( tableID == CDI_UNDEFID )
+  else if ( tableID == UNDEFID )
     { }
   else
     Error("Invalid table ID %d", tableID);
@@ -60556,7 +60129,7 @@ const char *tableInqParNamePtr(int tableID, int code)
 {
   const char *name = NULL;
 
-  if ( tableID != CDI_UNDEFID )
+  if ( tableID != UNDEFID )
     {
       int npars = parTable[tableID].npars;
       for ( int item = 0; item < npars; item++ )
@@ -60577,7 +60150,7 @@ const char *tableInqParLongnamePtr(int tableID, int code)
 {
   const char *longname = NULL;
 
-  if ( tableID != CDI_UNDEFID )
+  if ( tableID != UNDEFID )
     {
       int npars = parTable[tableID].npars;
       for ( int item = 0; item < npars; item++ )
@@ -60598,7 +60171,7 @@ const char *tableInqParUnitsPtr(int tableID, int code)
 {
   const char *units = NULL;
 
-  if ( tableID != CDI_UNDEFID )
+  if ( tableID != UNDEFID )
     {
       int npars = parTable[tableID].npars;
       for ( int item = 0; item < npars; item++ )
@@ -60617,12 +60190,12 @@ const char *tableInqParUnitsPtr(int tableID, int code)
 
 int tableInqParLongname(int tableID, int code, char *longname)
 {
-  if ( ((tableID >= 0) & (tableID < MAX_TABLE)) | (tableID == CDI_UNDEFID) ) { } else
+  if ( ((tableID >= 0) & (tableID < MAX_TABLE)) | (tableID == UNDEFID) ) { } else
     Error("Invalid table ID %d", tableID);
 
   int err = 1;
 
-  if ( tableID != CDI_UNDEFID )
+  if ( tableID != UNDEFID )
     {
       int npars = parTable[tableID].npars;
       for ( int item = 0; item < npars; item++ )
@@ -60644,12 +60217,12 @@ int tableInqParLongname(int tableID, int code, char *longname)
 int tableInqParUnits(int tableID, int code, char *units)
 {
 
-  if ( ((tableID >= 0) & (tableID < MAX_TABLE)) | (tableID == CDI_UNDEFID) ) { } else
+  if ( ((tableID >= 0) & (tableID < MAX_TABLE)) | (tableID == UNDEFID) ) { } else
     Error("Invalid table ID %d", tableID);
 
   int err = 1;
 
-  if ( tableID != CDI_UNDEFID )
+  if ( tableID != UNDEFID )
     {
       int npars = parTable[tableID].npars;
       for ( int item = 0; item < npars; item++ )
@@ -60671,7 +60244,7 @@ int tableInqParUnits(int tableID, int code, char *units)
 void tableInqPar(int tableID, int code, char *name, char *longname, char *units)
 {
 
-  if ( ((tableID >= 0) & (tableID < MAX_TABLE)) | (tableID == CDI_UNDEFID) ) { } else
+  if ( ((tableID >= 0) & (tableID < MAX_TABLE)) | (tableID == UNDEFID) ) { } else
     Error("Invalid table ID %d", tableID);
 
   int npars = parTable[tableID].npars;
@@ -60710,7 +60283,7 @@ int tableInqNumber(void)
 #endif
 
 #include <stddef.h>
-
+#include <string.h>
 
 
 static int DefaultTimeType = TAXIS_ABSOLUTE;
@@ -60800,15 +60373,24 @@ static int  TAXIS_Debug = 0;   /* If set to 1, debugging */
 
 const char *tunitNamePtr(int unitID)
 {
+  const char *name;
   int size = sizeof(Timeunits)/sizeof(*Timeunits);
-  return (unitID > 0 && unitID < size) ? Timeunits[unitID] : Timeunits[0];
+
+  if ( unitID > 0 && unitID < size )
+    name = Timeunits[unitID];
+  else
+    name = Timeunits[0];
+
+  return (name);
 }
 
 #if 0
 static
 void taxis_defaults(void)
 {
-  char *timeunit = getenv("TIMEUNIT");
+  char *timeunit;
+
+  timeunit = getenv("TIMEUNIT");
   if ( timeunit )
     {
       if ( strcmp(timeunit, "minutes") == 0 )
@@ -60837,8 +60419,7 @@ static
 void taxisDefaultValue(taxis_t* taxisptr)
 {
   taxisptr->self        = CDI_UNDEFID;
-  taxisptr->used        = false;
-  taxisptr->datatype    = CDI_DATATYPE_FLT64;
+  taxisptr->used        = FALSE;
   taxisptr->type        = DefaultTimeType;
   taxisptr->vdate       = 0;
   taxisptr->vtime       = 0;
@@ -60849,8 +60430,8 @@ void taxisDefaultValue(taxis_t* taxisptr)
   taxisptr->calendar    = cdiDefaultCalendar;
   taxisptr->unit        = DefaultTimeUnit;
   taxisptr->numavg      = 0;
-  taxisptr->climatology = false;
-  taxisptr->has_bounds  = false;
+  taxisptr->climatology = FALSE;
+  taxisptr->has_bounds  = FALSE;
   taxisptr->vdate_lb    = 0;
   taxisptr->vtime_lb    = 0;
   taxisptr->vdate_ub    = 0;
@@ -60859,7 +60440,6 @@ void taxisDefaultValue(taxis_t* taxisptr)
   taxisptr->fc_period   = 0;
   taxisptr->name        = NULL;
   taxisptr->longname    = NULL;
-  taxisptr->units       = NULL;
 }
 
 static taxis_t *
@@ -60876,22 +60456,33 @@ taxisNewEntry(cdiResH resH)
       reshReplace(resH, taxisptr, &taxisOps);
     }
 
-  return taxisptr;
+  return (taxisptr);
 }
 
 static
-void taxisInit(void)
+void taxisInit (void)
 {
-  static bool taxisInitialized = false;
+  static int taxisInitialized = 0;
+  char *env;
 
   if ( taxisInitialized ) return;
 
-  taxisInitialized = true;
+  taxisInitialized = 1;
 
-  char *env = getenv("TAXIS_DEBUG");
+  env = getenv("TAXIS_DEBUG");
   if ( env ) TAXIS_Debug = atoi(env);
 }
 
+#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
+
 /*
 @Function  taxisCreate
 @Title     Create a Time axis
@@ -60925,7 +60516,8 @@ taxisDefRtime(taxisID, 120000);
 */
 int taxisCreate(int taxistype)
 {
-  if ( CDI_Debug ) Message("taxistype: %d", taxistype);
+  if ( CDI_Debug )
+    Message("taxistype: %d", taxistype);
 
   taxisInit ();
 
@@ -60934,16 +60526,16 @@ int taxisCreate(int taxistype)
 
   int taxisID = taxisptr->self;
 
-  if ( CDI_Debug ) Message("taxisID: %d", taxisID);
+  if ( CDI_Debug )
+    Message("taxisID: %d", taxisID);
 
-  return taxisID;
+  return (taxisID);
 }
 
 void taxisDestroyKernel(taxis_t *taxisptr)
 {
   delete_refcount_string(taxisptr->name);
   delete_refcount_string(taxisptr->longname);
-  delete_refcount_string(taxisptr->units);
 }
 
 /*
@@ -60979,26 +60571,21 @@ int taxisDuplicate(int taxisID1)
 
   int taxisID2 = taxisptr2->self;
 
-  if ( CDI_Debug ) Message("taxisID2: %d", taxisID2);
+  if ( CDI_Debug )
+    Message("taxisID2: %d", taxisID2);
 
   ptaxisCopy(taxisptr2, taxisptr1);
-
-  return taxisID2;
+  return (taxisID2);
 }
 
 
 void taxisDefType(int taxisID, int type)
 {
-  taxis_t *taxisptr = (taxis_t *) reshGetVal(taxisID, &taxisOps);
+  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
 
-  if ( taxisptr->type != type )
+  if (taxisptr->type != type)
     {
       taxisptr->type = type;
-      if ( taxisptr->units )
-        {
-          delete_refcount_string(taxisptr->units);
-          taxisptr->units = NULL;
-        }
       reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
     }
 }
@@ -61074,11 +60661,6 @@ void taxisDefRdate(int taxisID, int rdate)
   if (taxisptr->rdate != rdate)
     {
       taxisptr->rdate = rdate;
-      if ( taxisptr->units )
-        {
-          delete_refcount_string(taxisptr->units);
-          taxisptr->units = NULL;
-        }
       reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
     }
 }
@@ -61104,11 +60686,6 @@ void taxisDefRtime(int taxisID, int rtime)
   if (taxisptr->rtime != rtime)
     {
       taxisptr->rtime = rtime;
-      if ( taxisptr->units )
-        {
-          delete_refcount_string(taxisptr->units);
-          taxisptr->units = NULL;
-        }
       reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
     }
 }
@@ -61198,11 +60775,6 @@ void taxisDefTunit(int taxisID, int unit)
   if (taxisptr->unit != unit)
     {
       taxisptr->unit = unit;
-      if ( taxisptr->units )
-        {
-          delete_refcount_string(taxisptr->units);
-          taxisptr->units = NULL;
-        }
       reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
     }
 }
@@ -61250,14 +60822,16 @@ The valid CDI time types are TAXIS_ABSOLUTE and TAXIS_RELATIVE.
 int taxisInqType(int taxisID)
 {
   taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
-  return taxisptr->type;
+
+  return (taxisptr->type);
 }
 
 
 int taxisHasBounds(int taxisID)
 {
   taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
-  return taxisptr->has_bounds;
+
+  return (taxisptr->has_bounds);
 }
 
 
@@ -61265,9 +60839,9 @@ void taxisDeleteBounds(int taxisID)
 {
   taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
 
-  if ( taxisptr->has_bounds )
+  if (taxisptr->has_bounds != FALSE)
     {
-      taxisptr->has_bounds = false;
+      taxisptr->has_bounds = FALSE;
       reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
     }
 }
@@ -61276,7 +60850,7 @@ void taxisDeleteBounds(int taxisID)
 void taxisCopyTimestep(int taxisID2, int taxisID1)
 {
   taxis_t *taxisptr1 = (taxis_t *)reshGetVal(taxisID1, &taxisOps),
-          *taxisptr2 = (taxis_t *)reshGetVal(taxisID2, &taxisOps);
+    *taxisptr2 = (taxis_t *)reshGetVal(taxisID2, &taxisOps);
 
   reshLock();
 
@@ -61323,7 +60897,8 @@ The function @func{taxisInqVdate} returns the verification date of a Time axis.
 int taxisInqVdate(int taxisID)
 {
   taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
-  return taxisptr->vdate;
+
+  return (taxisptr->vdate);
 }
 
 
@@ -61340,13 +60915,13 @@ 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 == false )
+  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;
+      taxisptr->has_bounds = TRUE;
       reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
     }
 }
@@ -61370,7 +60945,8 @@ The function @func{taxisInqVtime} returns the verification time of a Time axis.
 int taxisInqVtime(int taxisID)
 {
   taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
-  return taxisptr->vtime;
+
+  return (taxisptr->vtime);
 }
 
 
@@ -61387,13 +60963,13 @@ void taxisDefVtimeBounds(int taxisID, int vtime_lb, int vtime_ub)
 {
   taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
 
-  if ( taxisptr->vtime_lb != vtime_lb
-       || taxisptr->vtime_ub != vtime_ub
-       || taxisptr->has_bounds == false )
+  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;
+      taxisptr->has_bounds = TRUE;
       reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
     }
 }
@@ -61425,7 +61001,7 @@ int taxisInqRdate(int taxisID)
       reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
     }
 
-  return taxisptr->rdate;
+  return (taxisptr->rdate);
 }
 
 /*
@@ -61455,7 +61031,7 @@ int taxisInqRtime(int taxisID)
       reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
     }
 
-  return taxisptr->rtime;
+  return (taxisptr->rtime);
 }
 
 /*
@@ -61484,7 +61060,7 @@ int taxisInqFdate(int taxisID)
       taxisptr->ftime = taxisptr->vtime;
     }
 
-  return taxisptr->fdate;
+  return (taxisptr->fdate);
 }
 
 /*
@@ -61513,7 +61089,7 @@ int taxisInqFtime(int taxisID)
       taxisptr->ftime = taxisptr->vtime;
     }
 
-  return taxisptr->ftime;
+  return (taxisptr->ftime);
 }
 
 /*
@@ -61537,55 +61113,55 @@ The valid CDI calendar types are @func{CALENDAR_STANDARD}, @func{CALENDAR_PROLEP
 */
 int taxisInqCalendar(int taxisID)
 {
-  taxis_t *taxisptr = (taxis_t *) reshGetVal ( taxisID, &taxisOps );
-  return taxisptr->calendar;
+  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
+
+  return (taxisptr->calendar);
 }
 
 
 int taxisInqTunit(int taxisID)
 {
-  taxis_t *taxisptr = (taxis_t *) reshGetVal ( taxisID, &taxisOps );
-  return taxisptr->unit;
+  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
+
+  return (taxisptr->unit);
 }
 
 
 int taxisInqForecastTunit(int taxisID)
 {
-  taxis_t *taxisptr = (taxis_t *) reshGetVal ( taxisID, &taxisOps );
-  return taxisptr->fc_unit;
+  taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
+
+  return (taxisptr->fc_unit);
 }
 
 
 double taxisInqForecastPeriod(int taxisID)
 {
   taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
-  return taxisptr->fc_period;
+
+  return (taxisptr->fc_period);
 }
 
 
 int taxisInqNumavg(int taxisID)
 {
   taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
-  return taxisptr->numavg;
+
+  return (taxisptr->numavg);
 }
 
 
 taxis_t *taxisPtr(int taxisID)
 {
   taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
-  return taxisptr;
-}
-
 
-void ptaxisDefDatatype(taxis_t *taxisptr, int datatype)
-{
-  taxisptr->datatype = datatype;
+  return (taxisptr);
 }
 
-
-void ptaxisDefName(taxis_t *taxisptr, const char *name)
+void
+ptaxisDefName(taxis_t *taxisptr, const char *name)
 {
-  if ( name )
+  if (name)
     {
       size_t len = strlen(name);
       delete_refcount_string(taxisptr->name);
@@ -61594,10 +61170,10 @@ void ptaxisDefName(taxis_t *taxisptr, const char *name)
     }
 }
 
-
-void ptaxisDefLongname(taxis_t *taxisptr, const char *longname)
+void
+ptaxisDefLongname(taxis_t *taxisptr, const char *longname)
 {
-  if ( longname )
+  if (longname)
     {
       size_t len = strlen(longname);
       delete_refcount_string(taxisptr->longname);
@@ -61607,21 +61183,11 @@ void ptaxisDefLongname(taxis_t *taxisptr, const char *longname)
 }
 
 
-void ptaxisDefUnits(taxis_t *taxisptr, const char *units)
-{
-  if ( units )
-    {
-      size_t len = strlen(units);
-      delete_refcount_string(taxisptr->units);
-      char *taxisunits = taxisptr->units = new_refcount_string(len);
-      strcpy(taxisunits, units);
-    }
-}
-
-
 static void
 cdiDecodeTimevalue(int timeunit, double timevalue, int *days, int *secs)
 {
+  static int lwarn = TRUE;
+
   *days = 0;
   *secs = 0;
 
@@ -61666,11 +61232,10 @@ cdiDecodeTimevalue(int timeunit, double timevalue, int *days, int *secs)
     }
   else
     {
-      static bool lwarn = true;
       if ( lwarn )
 	{
 	  Warning("timeunit %s unsupported!", tunitNamePtr(timeunit));
-	  lwarn = false;
+	  lwarn = FALSE;
 	}
     }
 }
@@ -61678,6 +61243,8 @@ cdiDecodeTimevalue(int timeunit, double timevalue, int *days, int *secs)
 static
 void cdiEncodeTimevalue(int days, int secs, int timeunit, double *timevalue)
 {
+  static int lwarn = TRUE;
+
   if ( timeunit == TUNIT_SECOND )
     {
       *timevalue = days*86400. + secs;
@@ -61701,11 +61268,10 @@ void cdiEncodeTimevalue(int days, int secs, int timeunit, double *timevalue)
     }
   else
     {
-      static bool lwarn = true;
       if ( lwarn )
 	{
 	  Warning("timeunit %s unsupported!", tunitNamePtr(timeunit));
-	  lwarn = false;
+	  lwarn = FALSE;
 	}
     }
 }
@@ -61769,24 +61335,28 @@ void timeval2vtime(double timevalue, taxis_t *taxis, int *vdate, int *vtime)
 
 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;
 
-  int timeunit = (*taxis).unit;
-  int calendar = (*taxis).calendar;
+  timeunit = (*taxis).unit;
+  calendar = (*taxis).calendar;
 
-  int rdate = (*taxis).rdate;
-  int rtime = (*taxis).rtime;
+  rdate = (*taxis).rdate;
+  rtime = (*taxis).rtime;
   if ( rdate == -1 )
     {
       rdate  = (*taxis).vdate;
       rtime  = (*taxis).vtime;
     }
 
-  if ( rdate == 0 && rtime == 0 && vdate == 0 && vtime == 0 ) return value;
+  if ( rdate == 0 && rtime == 0 && vdate == 0 && vtime == 0 ) return(value);
 
-  int ryear, rmonth;
-  int year, month, day, hour, minute, second;
   cdiDecodeDate(rdate, &ryear, &rmonth, &day);
   cdiDecodeTime(rtime, &hour, &minute, &second);
 
@@ -61795,7 +61365,7 @@ double vtime2timeval(int vdate, int vtime, taxis_t *taxis)
   cdiDecodeDate(vdate, &year, &month, &day);
   cdiDecodeTime(vtime, &hour, &minute, &second);
 
-  int timeunit0 = timeunit;
+  timeunit0 = timeunit;
 
   if ( timeunit == TUNIT_MONTH && calendar == CALENDAR_360DAYS )
     {
@@ -61804,15 +61374,17 @@ double vtime2timeval(int vdate, int vtime, taxis_t *taxis)
 
   if ( timeunit == TUNIT_MONTH || timeunit == TUNIT_YEAR )
     {
+      int nmonth, dpm;
+
       value = (year-ryear)*12 - rmonth + month;
 
-      int nmonth = (int) value;
+      nmonth = (int) value;
       month -= nmonth;
 
       while ( month > 12 ) { month -= 12; year++; }
       while ( month <  1 ) { month += 12; year--; }
 
-      int dpm = days_per_month(calendar, year, month);
+      dpm = days_per_month(calendar, year, month);
 
       encode_caldaysec(calendar, year, month, day, hour, minute, second, &julday2, &secofday2);
 
@@ -61836,35 +61408,39 @@ double vtime2timeval(int vdate, int vtime, taxis_t *taxis)
       value /= 30;
     }
 
-  return value;
+  return (value);
 }
 
 
-static
-void conv_timeval(double timevalue, int *rvdate, int *rvtime)
+static void conv_timeval(double timevalue, int *rvdate, int *rvtime)
 {
+  int vdate = 0, vtime = 0;
+  int hour, minute, second;
   int daysec;
 
-  int vdate = (int) timevalue;
+  vdate = (int) timevalue;
   if ( vdate < 0 )
     daysec = (int) (-(timevalue - vdate)*86400 + 0.01);
   else
     daysec = (int) ( (timevalue - vdate)*86400 + 0.01);
 
-  int hour   =  daysec / 3600;
-  int minute = (daysec - hour*3600)/60;
-  int second =  daysec - hour*3600 - minute*60;
-  int vtime  = cdiEncodeTime(hour, minute, second);
+  hour   =  daysec / 3600;
+  minute = (daysec - hour*3600)/60;
+  second =  daysec - hour*3600 - minute*60;
+  vtime  = cdiEncodeTime(hour, minute, second);
 
   *rvdate = vdate;
   *rvtime = vtime;
 }
 
 
-static
-void splitTimevalue(double timevalue, int timeunit, int *date, int *time)
+static 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 )
     {
@@ -61904,19 +61480,16 @@ void splitTimevalue(double timevalue, int timeunit, int *date, int *time)
     }
   else
     {
-      static bool lwarn = true;
       if ( lwarn )
 	{
 	  Warning("timeunit %s unsupported!", tunitNamePtr(timeunit));
-	  lwarn = false;
+	  lwarn = FALSE;
 	}
     }
 
   /* verify date and time */
 
-  int year, month, day;
   cdiDecodeDate(vdate, &year, &month, &day);
-  int hour, minute, second;
   cdiDecodeTime(vtime, &hour, &minute, &second);
 
   if ( month > 17 || day > 31 || hour > 23 || minute > 59 || second > 59 )
@@ -61931,10 +61504,9 @@ void splitTimevalue(double timevalue, int timeunit, int *date, int *time)
       vdate = cdiEncodeDate(year, month, day);
       vtime = cdiEncodeTime(hour, minute, second);
 
-      static bool lwarn = true;
       if ( lwarn )
         {
-          lwarn = false;
+          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);
         }
@@ -61947,19 +61519,22 @@ void splitTimevalue(double timevalue, int timeunit, int *date, int *time)
 
 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;
 
   (*taxis).fc_period = timevalue;
 
-  int timeunit = (*taxis).fc_unit;
-  int calendar = (*taxis).calendar;
+  timeunit = (*taxis).fc_unit;
+  calendar = (*taxis).calendar;
 
-  int vdate = (*taxis).vdate;
-  int vtime = (*taxis).vtime;
+  vdate  = (*taxis).vdate;
+  vtime  = (*taxis).vtime;
 
   if ( vdate == 0 && vtime == 0 && DBL_IS_EQUAL(timevalue, 0.) ) return;
 
-  int year, month, day, hour, minute, second;
   cdiDecodeDate(vdate, &year, &month, &day);
   cdiDecodeTime(vtime, &hour, &minute, &second);
 
@@ -62028,21 +61603,27 @@ double cdiEncodeTimeval(int date, int time, taxis_t *taxis)
 	{
 	  int year, month, day;
 	  cdiDecodeDate(date, &year, &month, &day);
-          timevalue = date/100
-            + copysign((double)(day != 0) * 0.5, (double)date);
+          timevalue = date/100;
+	  if ( day != 0 )
+            {
+              if ( date < 0 ) timevalue -= 0.5;
+              else            timevalue += 0.5;
+            }
         }
       else
 	{
 	  int hour, minute, second;
 	  cdiDecodeTime(time, &hour, &minute, &second);
-          timevalue = copysign(1.0, (double)date)
-            * (fabs((double)date) + (hour*3600 + minute*60 + second)/86400.);
+	  if ( date < 0 )
+	    timevalue = -(-date + (hour*3600 + minute*60 + second)/86400.);
+	  else
+	    timevalue =    date + (hour*3600 + minute*60 + second)/86400.;
 	}
     }
   else
     timevalue = vtime2timeval(date, time, taxis);
 
-  return timevalue;
+  return (timevalue);
 }
 
 
@@ -62058,7 +61639,6 @@ void ptaxisCopy(taxis_t *dest, taxis_t *source)
 
   /* memcpy(dest, source, sizeof(taxis_t)); */
   dest->used        = source->used;
-  dest->datatype    = source->datatype;
   dest->type        = source->type;
   dest->vdate       = source->vdate;
   dest->vtime       = source->vtime;
@@ -62081,10 +61661,8 @@ void ptaxisCopy(taxis_t *dest, taxis_t *source)
   dest->climatology = source->climatology;
   delete_refcount_string(dest->name);
   delete_refcount_string(dest->longname);
-  delete_refcount_string(dest->units);
   dest->name = dup_refcount_string(source->name);
   dest->longname = dup_refcount_string(source->longname);
-  dest->units = dup_refcount_string(source->units);
   if (dest->self != CDI_UNDEFID)
     reshSetStatus(dest->self, &taxisOps, RESH_DESYNC_IN_USE);
   reshUnlock ();
@@ -62125,13 +61703,13 @@ taxisPrintKernel(taxis_t * taxisptr, FILE * fp)
           "fc_unit     = %d\n"
           "fc_period   = %g\n"
           "\n", taxisptr->self, taxisptr->self,
-          (int)taxisptr->used, taxisptr->type,
+          taxisptr->used, taxisptr->type,
           taxisptr->vdate, taxisptr->vtime,
           taxisptr->rdate, taxisptr->rtime,
           taxisptr->fdate, taxisptr->ftime,
           taxisptr->calendar, taxisptr->unit,
-          taxisptr->numavg, (int)taxisptr->climatology,
-          (int) taxisptr->has_bounds,
+          taxisptr->numavg, taxisptr->climatology,
+          taxisptr->has_bounds,
           vdate_lb, vtime_lb, vdate_ub, vtime_ub,
           taxisptr->fc_unit, taxisptr->fc_period );
 }
@@ -62171,21 +61749,20 @@ taxisTxCode ( void )
   return TAXIS;
 }
 
-enum { taxisNint = 22 };
+enum { taxisNint = 21 };
 
 static int
 taxisGetPackSize(void *p, void *context)
 {
   taxis_t *taxisptr = (taxis_t*) p;
   int packBufferSize
-    = serializeGetSize(taxisNint, CDI_DATATYPE_INT, context)
-    + serializeGetSize(1, CDI_DATATYPE_UINT32, context)
+    = serializeGetSize(taxisNint, DATATYPE_INT, context)
+    + serializeGetSize(1, DATATYPE_UINT32, context)
     + (taxisptr->name ?
-       serializeGetSize((int)strlen(taxisptr->name), CDI_DATATYPE_TXT, context) : 0)
+       serializeGetSize((int)strlen(taxisptr->name), DATATYPE_TXT, context) : 0)
     + (taxisptr->longname ?
-       serializeGetSize((int)strlen(taxisptr->longname), CDI_DATATYPE_TXT, context) : 0)
-    + (taxisptr->units ?
-       serializeGetSize((int)strlen(taxisptr->units), CDI_DATATYPE_TXT, context) : 0);
+       serializeGetSize((int)strlen(taxisptr->longname), DATATYPE_TXT,
+                        context) : 0);
   return packBufferSize;
 }
 
@@ -62199,11 +61776,11 @@ taxisUnpack(char * unpackBuffer, int unpackBufferSize, int * unpackBufferPos,
   int idx = 0;
 
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  intBuffer, taxisNint, CDI_DATATYPE_INT, context);
+                  intBuffer, taxisNint, DATATYPE_INT, context);
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  &d, 1, CDI_DATATYPE_UINT32, context);
+                  &d, 1, DATATYPE_UINT32, context);
 
-  xassert(cdiCheckSum(CDI_DATATYPE_INT, taxisNint, intBuffer) == d);
+  xassert(cdiCheckSum(DATATYPE_INT, taxisNint, intBuffer) == d);
 
   taxisInit();
 
@@ -62236,7 +61813,7 @@ taxisUnpack(char * unpackBuffer, int unpackBufferSize, int * unpackBufferPos,
       int len = intBuffer[idx];
       char *name = new_refcount_string((size_t)len);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      name, len, CDI_DATATYPE_TXT, context);
+                      name, len, DATATYPE_TXT, context);
       name[len] = '\0';
       taxisP->name = name;
     }
@@ -62246,19 +61823,10 @@ taxisUnpack(char * unpackBuffer, int unpackBufferSize, int * unpackBufferPos,
       int len = intBuffer[idx];
       char *longname = new_refcount_string((size_t)len);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      longname, len, CDI_DATATYPE_TXT, context);
+                      longname, len, DATATYPE_TXT, context);
       longname[len] = '\0';
       taxisP->longname = longname;
     }
-  if (intBuffer[idx])
-    {
-      int len = intBuffer[idx];
-      char *units = new_refcount_string((size_t)len);
-      serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      units, len, CDI_DATATYPE_TXT, context);
-      units[len] = '\0';
-      taxisP->units = units;
-    }
 
   reshSetStatus(taxisP->self, &taxisOps,
                 reshGetStatus(taxisP->self, &taxisOps) & ~RESH_SYNC_BIT);
@@ -62297,21 +61865,17 @@ taxisPack(void * voidP, void * packBuffer, int packBufferSize, int * packBufferP
   intBuffer[idx++] = taxisP->vtime_ub;
   intBuffer[idx++] = taxisP->name ? (int)strlen(taxisP->name) : 0;
   intBuffer[idx++] = taxisP->longname ? (int)strlen(taxisP->longname) : 0;
-  intBuffer[idx++] = taxisP->units ? (int)strlen(taxisP->units) : 0;
 
-  serializePack(intBuffer, taxisNint, CDI_DATATYPE_INT,
+  serializePack(intBuffer, taxisNint, DATATYPE_INT,
                 packBuffer, packBufferSize, packBufferPos, context);
-  d = cdiCheckSum(CDI_DATATYPE_INT, taxisNint, intBuffer);
-  serializePack(&d, 1, CDI_DATATYPE_UINT32,
+  d = cdiCheckSum(DATATYPE_INT, taxisNint, intBuffer);
+  serializePack(&d, 1, DATATYPE_UINT32,
                 packBuffer, packBufferSize, packBufferPos, context);
   if (taxisP->name)
-    serializePack(taxisP->name, intBuffer[15], CDI_DATATYPE_TXT,
+    serializePack(taxisP->name, intBuffer[15], DATATYPE_TXT,
                   packBuffer, packBufferSize, packBufferPos, context);
   if (taxisP->longname)
-    serializePack(taxisP->longname, intBuffer[16], CDI_DATATYPE_TXT,
-                  packBuffer, packBufferSize, packBufferPos, context);
-  if (taxisP->units)
-    serializePack(taxisP->units, intBuffer[16], CDI_DATATYPE_TXT,
+    serializePack(taxisP->longname, intBuffer[16], DATATYPE_TXT,
                   packBuffer, packBufferSize, packBufferPos, context);
 
 }
@@ -62710,7 +62274,7 @@ int tstepsNewEntry(stream_t *streamptr)
 
   tstepsInitEntry(streamptr, tsID);
 
-  streamptr->tsteps[tsID].taxis.used = true;
+  streamptr->tsteps[tsID].taxis.used = TRUE;
 
   return (int)tsID;
 }
@@ -62718,20 +62282,24 @@ int tstepsNewEntry(stream_t *streamptr)
 
 void cdiCreateTimesteps(stream_t *streamptr)
 {
+  long ntsteps;
+  long tsID;
+
   if ( streamptr->ntsteps < 0 || streamptr->tstepsTableSize > 0 )
     return;
 
-  long ntsteps = (streamptr->ntsteps == 0) ? 1 : streamptr->ntsteps;
+  if ( streamptr->ntsteps == 0 ) ntsteps = 1;    /* <<<<<-------- */
+  else ntsteps = streamptr->ntsteps;
 
   streamptr->tsteps = (tsteps_t *) Malloc((size_t)ntsteps*sizeof(tsteps_t));
 
   streamptr->tstepsTableSize = (int)ntsteps;
   streamptr->tstepsNextID    = (int)ntsteps;
 
-  for ( long tsID = 0; tsID < ntsteps; tsID++ )
+  for ( tsID = 0; tsID < ntsteps; tsID++ )
     {
       tstepsInitEntry(streamptr, (size_t)tsID);
-      streamptr->tsteps[tsID].taxis.used = true;
+      streamptr->tsteps[tsID].taxis.used = TRUE;
     }
 }
 /*
@@ -62758,6 +62326,47 @@ void cdiCreateTimesteps(stream_t *streamptr)
 
 
 
+void cdiPrintDatatypes(void)
+{
+#define XSTRING(x)	#x
+#define STRING(x)	XSTRING(x)
+  fprintf (stderr, "+-------------+-------+\n"
+           "| types       | bytes |\n"
+           "+-------------+-------+\n"
+           "| void *      |   %3d |\n"
+           "+-------------+-------+\n"
+           "| char        |   %3d |\n"
+           "+-------------+-------+\n"
+           "| short       |   %3d |\n"
+           "| int         |   %3d |\n"
+           "| long        |   %3d |\n"
+           "| long long   |   %3d |\n"
+           "| size_t      |   %3d |\n"
+           "| off_t       |   %3d |\n"
+           "+-------------+-------+\n"
+           "| float       |   %3d |\n"
+           "| double      |   %3d |\n"
+           "| long double |   %3d |\n"
+           "+-------------+-------+\n\n"
+           "+-------------+-----------+\n"
+           "| INT32       | %-9s |\n"
+           "| INT64       | %-9s |\n"
+           "| FLT32       | %-9s |\n"
+           "| FLT64       | %-9s |\n"
+           "+-------------+-----------+\n"
+           "\n  byte ordering is %s\n\n",
+           (int) sizeof(void *), (int) sizeof(char),
+           (int) sizeof(short), (int) sizeof(int), (int) sizeof(long), (int) sizeof(long long),
+           (int) sizeof(size_t), (int) sizeof(off_t),
+           (int) sizeof(float), (int) sizeof(double), (int) sizeof(long double),
+           STRING(INT32), STRING(INT64), STRING(FLT32), STRING(FLT64),
+           ((HOST_ENDIANNESS == CDI_BIGENDIAN) ? "BIGENDIAN"
+            : ((HOST_ENDIANNESS == CDI_LITTLEENDIAN) ? "LITTLEENDIAN"
+               : "Unhandled endianness!")));
+#undef STRING
+#undef XSTRING
+}
+
 static const char uuidFmt[] = "%02hhx%02hhx%02hhx%02hhx-"
   "%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-"
   "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx";
@@ -62848,7 +62457,7 @@ char* cdiUnescapeSpaces(const char* string, const char** outStringEnd)
   return result;
 }
 
-#if defined (HAVE_DECL_UUID_GENERATE) && defined (HAVE_UUID_UUID_H)
+#ifdef HAVE_DECL_UUID_GENERATE
 #include <sys/time.h>
 #include <uuid/uuid.h>
 void cdiCreateUUID(unsigned char *uuid)
@@ -62875,7 +62484,7 @@ void cdiCreateUUID(unsigned char *uuid)
   uuid_generate(uuid);
   setstate(caller_rand_state);
 }
-#elif defined (HAVE_DECL_UUID_CREATE) && defined (HAVE_UUID_H)
+#elif defined (HAVE_DECL_UUID_CREATE)
 typedef uint8_t u_int8_t;
 typedef uint16_t u_int16_t;
 typedef uint32_t u_int32_t;
@@ -62895,8 +62504,8 @@ void cdiCreateUUID(unsigned char *uuid)
 void cdiCreateUUID(unsigned char *uuid)
 {
   static int uuid_seeded = 0;
-#ifndef _SX
   static char uuid_rand_state[31 * sizeof (long)];
+#ifndef _SX
   char *caller_rand_state;
   if (uuid_seeded)
     caller_rand_state = setstate(uuid_rand_state);
@@ -62917,27 +62526,6 @@ void cdiCreateUUID(unsigned char *uuid)
   for (size_t i = 0; i < CDI_UUID_SIZE; ++i)
     uuid[i] = (unsigned char)random();
 #else
-  unsigned short caller_rand_state[3];
-  {
-    static unsigned short our_rand_state[3];
-    if (!uuid_seeded)
-      {
-        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;
-        our_rand_state[0] = 0x330E;
-        our_rand_state[1] = (unsigned short)(seed & 0xFFFFU);
-        our_rand_state[2] = (unsigned short)((seed >> 16) & 0xFFFFU);
-      }
-    unsigned short *p = seed48(our_rand_state);
-    uuid_seeded = 1;
-    memcpy(caller_rand_state, p, sizeof (caller_rand_state));
-  }
   for (size_t i = 0; i < CDI_UUID_SIZE; ++i)
     uuid[i] = (unsigned char)lrand48();
 #endif
@@ -62947,8 +62535,6 @@ void cdiCreateUUID(unsigned char *uuid)
   uuid[7] = (unsigned char)((uuid[7] & 0x0f) | (4 << 4));
 #ifndef _SX
   setstate(caller_rand_state);
-#else
-  seed48(caller_rand_state);
 #endif
 }
 #endif
@@ -62965,8 +62551,14 @@ void cdiCreateUUID(unsigned char *uuid)
 #if defined (HAVE_CONFIG_H)
 #endif
 
+#include <stdbool.h>
+#include <string.h>
+#include <math.h>
+
 
 
+#undef  UNDEFID
+#define UNDEFID -1
 
 static size_t Vctsize = 0;
 static double *Vct = NULL;
@@ -62998,7 +62590,6 @@ typedef struct
 
 typedef struct
 {
-  int            varID;
   int            param;
   int            prec;
   int            tsteptype;
@@ -63022,7 +62613,7 @@ typedef struct
   int            comptype;       // compression type
   int            complevel;      // compression level
   short          timave;
-  bool           lmissval;
+  short          lmissval;
   double         missval;
   char          *name;
   char          *stdname;
@@ -63044,18 +62635,18 @@ vartable_t;
 
 static vartable_t *vartable;
 static unsigned varTablesize = 0;
-static unsigned varTableUsed = 0;
+static unsigned nvars = 0;
 
-static
-void paramInitEntry(unsigned varID, int param)
+
+static void
+paramInitEntry(unsigned varID, int param)
 {
-  vartable[varID].varID          = (int)varID;
   vartable[varID].param          = param;
   vartable[varID].prec           = 0;
   vartable[varID].tsteptype      = TSTEP_INSTANT;
   vartable[varID].timave         = 0;
   vartable[varID].timaccu        = 0;
-  vartable[varID].gridID         = CDI_UNDEFID;
+  vartable[varID].gridID         = UNDEFID;
   vartable[varID].zaxistype      = 0;
   vartable[varID].ltype1         = 0;
   vartable[varID].ltype2         = -1;
@@ -63065,14 +62656,14 @@ void paramInitEntry(unsigned varID, int param)
   vartable[varID].recordTable    = NULL;
   vartable[varID].nsubtypes_alloc= 0;
   vartable[varID].nsubtypes      = 0;
-  vartable[varID].instID         = CDI_UNDEFID;
-  vartable[varID].modelID        = CDI_UNDEFID;
-  vartable[varID].tableID        = CDI_UNDEFID;
-  vartable[varID].typeOfGeneratingProcess   = CDI_UNDEFID;
-  vartable[varID].productDefinitionTemplate = CDI_UNDEFID;
-  vartable[varID].comptype       = CDI_COMPRESS_NONE;
+  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       = false;
+  vartable[varID].lmissval       = 0;
   vartable[varID].missval        = 0;
   vartable[varID].name           = NULL;
   vartable[varID].stdname        = NULL;
@@ -63091,7 +62682,7 @@ varGetEntry(int param, int zaxistype, int ltype1, int tsteptype, const char *nam
     {
       /* testing for "param" implicitly checks if we are beyond the
        * current vartable size: */
-      if ( vartable[varID].param == param )
+      if (vartable[varID].param == param)
         {
           int no_of_tiles = -1;
           if ( tiles ) no_of_tiles = tiles->numberOfTiles;
@@ -63106,11 +62697,11 @@ varGetEntry(int param, int zaxistype, int ltype1, int tsteptype, const char *nam
             {
               if ( name && name[0] && vartable[varID].name && vartable[varID].name[0] )
                 {
-                  if ( strcmp(name, vartable[varID].name) == 0 ) return varID;
+                  if ( strcmp(name, vartable[varID].name) == 0 ) return (varID);
                 }
               else
                 {
-                  return varID;
+                  return (varID);
                 }
             }
         }
@@ -63124,7 +62715,7 @@ void varFree(void)
 {
   if ( CDI_Debug ) Message("call to varFree");
 
-  for ( size_t varID = 0; varID < varTableUsed; varID++ )
+  for ( unsigned varID = 0; varID < nvars; varID++ )
     {
       if ( vartable[varID].recordTable )
         {
@@ -63158,7 +62749,7 @@ void varFree(void)
 
   vartable = NULL;
   varTablesize = 0;
-  varTableUsed = 0;
+  nvars = 0;
 
   if ( Vct )
     Free(Vct);
@@ -63246,24 +62837,24 @@ static int levelNewEntry(unsigned varID, int level1, int level2, int tileID)
       levelTable = (leveltable_t *) Malloc((size_t)levelTableSize
                                            * sizeof (leveltable_t));
       for ( int i = 0; i < levelTableSize; i++ )
-        levelTable[i].recID = CDI_UNDEFID;
+        levelTable[i].recID = UNDEFID;
     }
   else
     {
       while( levelID < levelTableSize
-             && levelTable[levelID].recID != CDI_UNDEFID )
+             && levelTable[levelID].recID != UNDEFID )
         ++levelID;
     }
   /*
     If the table overflows, double its size.
   */
-  if ( levelID == levelTableSize )
+  if( levelID == levelTableSize )
     {
       levelTable = (leveltable_t *) Realloc(levelTable,
                                             (size_t)(levelTableSize *= 2)
                                             * sizeof (leveltable_t));
       for( int i = levelID; i < levelTableSize; i++ )
-        levelTable[i].recID = CDI_UNDEFID;
+        levelTable[i].recID = UNDEFID;
     }
 
   levelTable[levelID].level1   = level1;
@@ -63274,7 +62865,7 @@ static int levelNewEntry(unsigned varID, int level1, int level2, int tileID)
   vartable[varID].recordTable[tileID].levelTableSize = levelTableSize;
   vartable[varID].recordTable[tileID].levelTable     = levelTable;
 
-  return levelID;
+  return (levelID);
 }
 
 #define  UNDEF_PARAM  -4711
@@ -63322,7 +62913,7 @@ paramNewEntry(int param)
     {
       vartable = (vartable_t *) Realloc(vartable, (size_t)(varTablesize *= 2)
                                         * sizeof (vartable_t));
-      for ( size_t i = varID; i < varTablesize; i++ )
+      for( unsigned i = varID; i < varTablesize; i++ )
         {
           vartable[i].param = UNDEF_PARAM;
           vartable[i].opt_grib_kvpair      = NULL;
@@ -63333,7 +62924,7 @@ paramNewEntry(int param)
 
   paramInitEntry(varID, param);
 
-  return varID;
+  return (varID);
 }
 
 
@@ -63370,7 +62961,6 @@ int varInsertTileSubtype(vartable_t *vptr, const var_tile_t *tiles)
     subtypeDestroyPtr(subtype_ptr);
     return vptr->tiles->nentries - 1;
   }
-
   return CDI_UNDEFID;
 }
 
@@ -63382,11 +62972,11 @@ void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
                   const var_tile_t *tiles, int *tile_index)
 {
   unsigned varID = (cdiSplitLtype105 != 1 || zaxistype != ZAXIS_HEIGHT) ?
-    varGetEntry(param, zaxistype, ltype1, tsteptype, name, tiles) : (unsigned) CDI_UNDEFID;
+    varGetEntry(param, zaxistype, ltype1, tsteptype, name, tiles) : (unsigned)UNDEFID;
 
-  if ( varID == (unsigned) CDI_UNDEFID )
+  if ( varID == (unsigned)UNDEFID )
     {
-      varTableUsed++;
+      nvars++;
       varID = paramNewEntry(param);
       vartable[varID].gridID     = gridID;
       vartable[varID].zaxistype  = zaxistype;
@@ -63427,12 +63017,11 @@ void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
   int this_tile = varInsertTileSubtype(&vartable[varID], tiles);
   int tileID = tileGetEntry(varID, this_tile);
   if ( tile_index ) (*tile_index) = this_tile;
-  if ( tileID == CDI_UNDEFID )
-    {
-      tileID = tileNewEntry((int)varID);
-      vartable[varID].recordTable[tileID].subtypeIndex = this_tile;
-      vartable[varID].nsubtypes++;
-    }
+  if (tileID == CDI_UNDEFID) {
+    tileID = tileNewEntry((int)varID);
+    vartable[varID].recordTable[tileID].subtypeIndex = this_tile;
+    vartable[varID].nsubtypes++;
+  }
 
   /* append current level to level table info */
   int levelID = levelNewEntry(varID, level1, level2, tileID);
@@ -63455,139 +63044,131 @@ int dblcmp(const void *s1, const void *s2)
   if      ( *((double *) s1) < *((double *) s2) ) cmp = -1;
   else if ( *((double *) s1) > *((double *) s2) ) cmp =  1;
 
-  return cmp;
+  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;
+  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;
 
-  return cmp;
+  return (cmp);
 }
 
 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;
+  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;
 
-  return cmp;
+  return (cmp);
 }
 
 
-struct paraminfo
+typedef struct
 {
-  int varid, param, ltype;
-};
+  int      varid;
+  int      param;
+  int      ltype;
+}
+param_t;
+
 
 static
-int cmp_param(const void* s1, const void* s2)
+int cmpparam(const void* s1, const void* s2)
 {
-  const struct paraminfo *x = (const struct paraminfo*) s1;
-  const struct paraminfo *y = (const struct paraminfo*) s2;
+  const param_t* x = (const param_t*) s1;
+  const param_t* y = (const param_t*) s2;
 
   int cmp = (( x->param > y->param ) - ( x->param < y->param )) * 2
            + ( x->ltype > y->ltype ) - ( x->ltype < y->ltype );
 
-  return cmp;
-}
-
-struct varinfo
-{
-  int        varid;
-  const char *name;
-};
-/*
-static
-int cmp_varname(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);
-}
-*/
-static
-int cmp_varname(const void *s1, const void *s2)
-{
-  const vartable_t *x = (const vartable_t *)s1,
-                   *y = (const vartable_t *)s2;
-  return strcmp(x->name, y->name);
+  return (cmp);
 }
 
 
 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;
 
-  int *varids = (int *) Malloc(varTableUsed*sizeof(int));
-  for ( size_t varID = 0; varID < varTableUsed; varID++ ) varids[varID] = (int)varID;
-  /*
-  if ( streamptr->sortparam )
+  int *varids = (int *) Malloc(nvars*sizeof(int));
+  for ( unsigned varID = 0; varID < nvars; varID++ ) varids[varID] = (int)varID;
+
+  if ( streamptr->sortname )
     {
-      struct paraminfo *varInfo = (struct paraminfo *) Malloc((size_t)varTableUsed * sizeof(struct paraminfo));
+      param_t *varInfo = (param_t *) Malloc((size_t)nvars * sizeof (param_t));
 
-      for ( unsigned varID = 0; varID < varTableUsed; 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;
 	}
-      qsort(varInfo, (size_t)varTableUsed, sizeof(struct paraminfo), cmp_param);
-      for ( unsigned varID = 0; varID < varTableUsed; varID++ )
+      qsort(varInfo, (size_t)nvars, sizeof(param_t), cmpparam);
+      for ( unsigned varID = 0; varID < nvars; varID++ )
 	{
 	  varids[varID] = varInfo[varID].varid;
 	}
       Free(varInfo);
     }
 
-  if ( streamptr->sortname )
-    {
-      qsort(vartable, (size_t)varTableUsed, sizeof(vartable_t), cmp_varname);
-    }
-  */
-  for ( size_t index = 0; index < varTableUsed; index++ )
+  for ( unsigned index = 0; index < nvars; index++ )
     {
       int varid      = varids[index];
 
-      int gridID     = vartable[varid].gridID;
-      int param      = vartable[varid].param;
-      int ltype1     = vartable[varid].ltype1;
-      int ltype2     = vartable[varid].ltype2;
-      int zaxistype  = vartable[varid].zaxistype;
+      gridID     = vartable[varid].gridID;
+      param      = vartable[varid].param;
+      ltype1     = vartable[varid].ltype1;
+      ltype2     = vartable[varid].ltype2;
+      zaxistype = vartable[varid].zaxistype;
       if ( ltype1 == 0 && zaxistype == ZAXIS_GENERIC && cdiDefaultLeveltype != -1 )
 	zaxistype = cdiDefaultLeveltype;
-      int lbounds    = vartable[varid].lbounds;
-      int prec       = vartable[varid].prec;
-      int instID     = vartable[varid].instID;
-      int modelID    = vartable[varid].modelID;
-      int tableID    = vartable[varid].tableID;
-      int tsteptype  = vartable[varid].tsteptype;
-      int timave     = vartable[varid].timave;
-      int timaccu    = vartable[varid].timaccu;
-      int comptype   = vartable[varid].comptype;
-
-      double level_sf = 1;
+      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;
+
       /* consistency check: test if all subtypes have the same levels: */
       unsigned nlevels = vartable[varid].recordTable[0].nlevels;
-      for ( int isub = 1; isub < vartable[varid].nsubtypes; isub++ ) {
-        if ( vartable[varid].recordTable[isub].nlevels != nlevels )
+      for (int isub=1; isub<vartable[varid].nsubtypes; isub++) {
+        if (vartable[varid].recordTable[isub].nlevels != nlevels)
           {
             fprintf(stderr, "var \"%s\": isub = %d / %d :: "
                     "nlevels = %d, vartable[varid].recordTable[isub].nlevels = %d\n",
@@ -63598,7 +63179,7 @@ void cdi_generate_vars(stream_t *streamptr)
 
         leveltable_t *t1 = vartable[varid].recordTable[isub-1].levelTable;
         leveltable_t *t2 = vartable[varid].recordTable[isub  ].levelTable;
-        for ( unsigned ilev = 0; ilev < nlevels; ilev++ )
+        for (unsigned ilev=0; ilev<nlevels; ilev++)
           if ((t1[ilev].level1 != t2[ilev].level1)  ||
               (t1[ilev].level2 != t2[ilev].level2)  ||
               (t1[ilev].lindex != t2[ilev].lindex))
@@ -63607,31 +63188,32 @@ void cdi_generate_vars(stream_t *streamptr)
                       "nlevels = %d, vartable[varid].recordTable[isub].nlevels = %d\n",
                       vartable[varid].name, varid, isub, vartable[varid].nsubtypes,
                       nlevels, vartable[varid].recordTable[isub].nlevels);
-              Message("t1[ilev].level1=%d / t2[ilev].level1=%d", t1[ilev].level1, t2[ilev].level1);
-              Message("t1[ilev].level2=%d / t2[ilev].level2=%d", t1[ilev].level2, t2[ilev].level2);
-              Message("t1[ilev].lindex=%d / t2[ilev].lindex=%d", t1[ilev].lindex, t2[ilev].lindex);
+              Message("t1[ilev].level1=%d / t2[ilev].level1=%d",t1[ilev].level1, t2[ilev].level1);
+              Message("t1[ilev].level2=%d / t2[ilev].level2=%d",t1[ilev].level2, t2[ilev].level2);
+              Message("t1[ilev].lindex=%d / t2[ilev].lindex=%d",t1[ilev].lindex, t2[ilev].lindex);
               Error("zaxis type must not change for same parameter!");
             }
       }
       leveltable_t *levelTable = vartable[varid].recordTable[0].levelTable;
 
-      if ( ltype1 == 0 && zaxistype == ZAXIS_GENERIC && nlevels == 1 && levelTable[0].level1 == 0 )
+      if ( ltype1 == 0 && zaxistype == ZAXIS_GENERIC && nlevels == 1 &&
+	   levelTable[0].level1 == 0 )
 	zaxistype = ZAXIS_SURFACE;
 
-      double *dlevels = (double *) Malloc(nlevels*sizeof(double));
+      dlevels = (double *) Malloc(nlevels*sizeof(double));
 
       if ( lbounds && zaxistype != ZAXIS_HYBRID && zaxistype != ZAXIS_HYBRID_HALF )
-	for ( unsigned levelID = 0; levelID < nlevels; levelID++ )
+	for (unsigned levelID = 0; levelID < nlevels; levelID++ )
 	  dlevels[levelID] = (level_sf*levelTable[levelID].level1 +
 	                      level_sf*levelTable[levelID].level2)/2;
       else
-	for ( unsigned levelID = 0; levelID < nlevels; levelID++ )
+	for (unsigned levelID = 0; levelID < nlevels; levelID++ )
 	  dlevels[levelID] = level_sf*levelTable[levelID].level1;
 
       if ( nlevels > 1 )
 	{
           bool linc = true, ldec = true, lsort = false;
-          for ( unsigned levelID = 1; levelID < nlevels; levelID++ )
+          for (unsigned levelID = 1; levelID < nlevels; levelID++ )
             {
               /* check increasing of levels */
               linc &= (dlevels[levelID] > dlevels[levelID-1]);
@@ -63643,7 +63225,7 @@ void cdi_generate_vars(stream_t *streamptr)
            * levelTable[levelID1].level1 < levelTable[levelID2].level1 <=> levelID1 > levelID2
            * unless already sorted in decreasing order
            */
-          if ( (!linc && !ldec) && zaxistype == ZAXIS_PRESSURE )
+          if ( !ldec && zaxistype == ZAXIS_PRESSURE )
             {
               qsort(levelTable, nlevels, sizeof(leveltable_t), cmpLevelTableInv);
               lsort = true;
@@ -63664,35 +63246,33 @@ void cdi_generate_vars(stream_t *streamptr)
           if ( lsort )
             {
               if ( lbounds && zaxistype != ZAXIS_HYBRID && zaxistype != ZAXIS_HYBRID_HALF )
-                for ( unsigned levelID = 0; levelID < nlevels; levelID++ )
+                for (unsigned levelID = 0; levelID < nlevels; levelID++ )
                   dlevels[levelID] = (level_sf*levelTable[levelID].level1 +
                                       level_sf*levelTable[levelID].level2)/2.;
               else
-                for ( unsigned levelID = 0; levelID < nlevels; levelID++ )
+                for (unsigned levelID = 0; levelID < nlevels; levelID++ )
                   dlevels[levelID] = level_sf*levelTable[levelID].level1;
             }
 	}
 
-      double *dlevels1 = NULL;
-      double *dlevels2 = NULL;
       if ( lbounds )
 	{
 	  dlevels1 = (double *) Malloc(nlevels*sizeof(double));
-	  for ( unsigned levelID = 0; levelID < nlevels; levelID++ )
+	  for (unsigned levelID = 0; levelID < nlevels; levelID++)
 	    dlevels1[levelID] = level_sf*levelTable[levelID].level1;
 	  dlevels2 = (double *) Malloc(nlevels*sizeof(double));
-	  for ( unsigned levelID = 0; levelID < nlevels; levelID++ )
+	  for (unsigned levelID = 0; levelID < nlevels; levelID++)
 	    dlevels2[levelID] = level_sf*levelTable[levelID].level2;
         }
 
-      const char **cvals = NULL;
       const char *unitptr = cdiUnitNamePtr(vartable[varid].level_unit);
-      int zaxisID = varDefZaxis(vlistID, zaxistype, (int)nlevels, dlevels, cvals, 0, lbounds, dlevels1, dlevels2,
-                                (int)Vctsize, Vct, NULL, NULL, unitptr, 0, 0, ltype1);
-
-      if ( CDI_cmor_mode && nlevels == 1 && zaxistype != ZAXIS_HYBRID ) zaxisDefScalar(zaxisID);
+      zaxisID = varDefZaxis(vlistID, zaxistype, (int)nlevels, dlevels, lbounds, dlevels1, dlevels2,
+                            (int)Vctsize, Vct, NULL, NULL, unitptr, 0, 0, ltype1);
 
-      if ( ltype1 != ltype2 && ltype2 != -1 ) zaxisDefLtype2(zaxisID, ltype2);
+      if ( ltype1 != ltype2 && ltype2 != -1 )
+        {
+          zaxisDefLtype2(zaxisID, ltype2);
+        }
 
       if ( zaxisInqType(zaxisID) == ZAXIS_REFERENCE )
         {
@@ -63719,10 +63299,10 @@ void cdi_generate_vars(stream_t *streamptr)
       vlistDefVarTimaccu(vlistID, varID, timaccu);
       vlistDefVarCompType(vlistID, varID, comptype);
 
-      if ( vartable[varid].typeOfGeneratingProcess != CDI_UNDEFID )
+      if ( vartable[varid].typeOfGeneratingProcess != UNDEFID )
         vlistDefVarTypeOfGeneratingProcess(vlistID, varID, vartable[varid].typeOfGeneratingProcess);
 
-      if ( vartable[varid].productDefinitionTemplate != CDI_UNDEFID )
+      if ( vartable[varid].productDefinitionTemplate != UNDEFID )
         vlistDefVarProductDefinitionTemplate(vlistID, varID, vartable[varid].productDefinitionTemplate);
 
       if ( vartable[varid].lmissval ) vlistDefVarMissval(vlistID, varID, vartable[varid].missval);
@@ -63735,8 +63315,10 @@ void cdi_generate_vars(stream_t *streamptr)
 	                                                  vartable[varid].ensdata->ens_count,
 							  vartable[varid].ensdata->forecast_init_type);
 
-      vlist_t *vlistptr = vlist_to_pointer(vlistID);
-      for ( int i = 0; i < vartable[varid].opt_grib_nentries; i++ )
+      int    i;
+      vlist_t *vlistptr;
+      vlistptr = vlist_to_pointer(vlistID);
+      for (i=0; i<vartable[varid].opt_grib_nentries; i++)
         {
           resize_opt_grib_entries(&vlistptr->vars[varID], vlistptr->vars[varID].opt_grib_nentries+1);
           vlistptr->vars[varID].opt_grib_nentries += 1;
@@ -63744,20 +63326,20 @@ void cdi_generate_vars(stream_t *streamptr)
 
           vlistptr->vars[varID].opt_grib_kvpair[idx] = vartable[varid].opt_grib_kvpair[i];
           vlistptr->vars[varID].opt_grib_kvpair[idx].keyword = NULL;
-	  if ( vartable[varid].opt_grib_kvpair[i].keyword )
-	    vlistptr->vars[varID].opt_grib_kvpair[idx].keyword =
+	  if (vartable[varid].opt_grib_kvpair[i].keyword) 
+	    vlistptr->vars[varID].opt_grib_kvpair[idx].keyword = 
 	      strdupx(vartable[varid].opt_grib_kvpair[i].keyword);
-          vlistptr->vars[varID].opt_grib_kvpair[i].update = true;
+          vlistptr->vars[varID].opt_grib_kvpair[i].update = TRUE;
         }
       /* note: if the key is not defined, we do not throw an error! */
 
-      if ( cdiDefaultTableID != CDI_UNDEFID )
+      if ( cdiDefaultTableID != UNDEFID )
 	{
 	  int pdis, pcat, pnum;
 	  cdiDecodeParam(param, &pnum, &pcat, &pdis);
 	  if ( tableInqParNamePtr(cdiDefaultTableID, pnum) )
 	    {
-	      if ( tableID != CDI_UNDEFID )
+	      if ( tableID != UNDEFID )
 		{
 		  strcpy(name, tableInqParNamePtr(cdiDefaultTableID, pnum));
 		  vlistDefVarName(vlistID, varID, name);
@@ -63775,32 +63357,43 @@ void cdi_generate_vars(stream_t *streamptr)
 	      else
 		tableID = cdiDefaultTableID;
 	    }
-	  if ( cdiDefaultModelID != CDI_UNDEFID ) modelID = cdiDefaultModelID;
-	  if ( cdiDefaultInstID  != CDI_UNDEFID )  instID = cdiDefaultInstID;
+	  if ( cdiDefaultModelID != UNDEFID ) modelID = cdiDefaultModelID;
+	  if ( cdiDefaultInstID  != UNDEFID )  instID = cdiDefaultInstID;
 	}
 
-      if ( instID  != CDI_UNDEFID ) vlistDefVarInstitut(vlistID, varID, instID);
-      if ( modelID != CDI_UNDEFID ) vlistDefVarModel(vlistID, varID, modelID);
-      if ( tableID != CDI_UNDEFID ) vlistDefVarTable(vlistID, varID, tableID);
+      if ( instID  != UNDEFID ) vlistDefVarInstitut(vlistID, varID, instID);
+      if ( modelID != UNDEFID ) vlistDefVarModel(vlistID, varID, modelID);
+      if ( tableID != UNDEFID ) vlistDefVarTable(vlistID, varID, tableID);
     }
 
-  for ( size_t index = 0; index < varTableUsed; index++ )
+  for ( unsigned index = 0; index < nvars; index++ )
     {
       int varid = varids[index];
       unsigned nlevels = vartable[varid].recordTable[0].nlevels;
 
-      unsigned nsub = vartable[varid].nsubtypes >= 0 ? (unsigned)vartable[varid].nsubtypes : 0U;
-      for ( size_t isub = 0; isub < nsub; isub++ )
+      /*
+      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);
+	}
+      */
+      unsigned nsub = vartable[varid].nsubtypes >= 0
+        ? (unsigned)vartable[varid].nsubtypes : 0U;
+      for (size_t isub=0; isub < nsub; isub++)
         {
           sleveltable_t *restrict streamRecordTable
             = streamptr->vars[index].recordTable + isub;
           leveltable_t *restrict vartableLevelTable
             = vartable[varid].recordTable[isub].levelTable;
-          for ( unsigned levelID = 0; levelID < nlevels; levelID++ )
+          for (unsigned levelID = 0; levelID < nlevels; levelID++)
             {
-              streamRecordTable->recordID[levelID] = vartableLevelTable[levelID].recID;
+              streamRecordTable->recordID[levelID]
+                = vartableLevelTable[levelID].recID;
               unsigned lindex;
-              for ( lindex = 0; lindex < nlevels; lindex++ )
+              for (lindex = 0; lindex < nlevels; lindex++ )
                 if ( levelID == (unsigned)vartableLevelTable[lindex].lindex )
                   break;
               if ( lindex == nlevels )
@@ -63835,48 +63428,50 @@ void varDefZAxisReference(int nhlev, int nvgrid, unsigned char uuid[CDI_UUID_SIZ
 }
 
 
-bool zaxisCompare(int zaxisID, int zaxistype, int nlevels, bool lbounds, const double *levels, const char *longname, const char *units, int ltype1)
+int zaxisCompare(int zaxisID, int zaxistype, int nlevels, int lbounds, const double *levels, const char *longname, const char *units, int ltype1)
 {
-  bool differ = true;
+  int differ = 1;
+  int levelID;
+  int zlbounds = 0;
+  int ltype_is_equal = FALSE;
 
-  bool ltype_is_equal = (ltype1 == zaxisInqLtype(zaxisID));
+  if ( ltype1 == zaxisInqLtype(zaxisID) ) ltype_is_equal = TRUE;
 
   if ( ltype_is_equal && (zaxistype == zaxisInqType(zaxisID) || zaxistype == ZAXIS_GENERIC) )
     {
-      bool zlbounds = (zaxisInqLbounds(zaxisID, NULL) > 0);
+      if ( zaxisInqLbounds(zaxisID, NULL) > 0 ) zlbounds = 1;
       if ( nlevels == zaxisInqSize(zaxisID) && zlbounds == lbounds )
 	{
-	  const double *dlevels = zaxisInqLevelsPtr(zaxisID);
-          if ( dlevels && levels )
-            {
-              int levelID;
-              for ( levelID = 0; levelID < nlevels; levelID++ )
-                {
-                  if ( fabs(dlevels[levelID] - levels[levelID]) > 1.e-9 )
-                    break;
-                }
-              if ( levelID == nlevels ) differ = false;
-            }
+	  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;
 
 	  if ( ! differ )
 	    {
-              if ( longname )
-                {
-                  char zlongname[CDI_MAX_NAME];
-                  zaxisInqLongname(zaxisID, zlongname);
-                  if ( zlongname[0] && strcmp(longname, zlongname) != 0 ) differ = true;
-                }
-              if ( units )
-                {
-                  char zunits[CDI_MAX_NAME];
-                  zaxisInqUnits(zaxisID, zunits);
-                  if ( zunits[0] && strcmp(units, zunits) != 0 ) differ = true;
-                }
-            }
+	      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;
+  return (differ);
 }
 
 struct varDefZAxisSearchState
@@ -63884,7 +63479,7 @@ struct varDefZAxisSearchState
   int resIDValue;
   int zaxistype;
   int nlevels;
-  bool lbounds;
+  int lbounds;
   const double *levels;
   const char *longname;
   const char *units;
@@ -63896,9 +63491,9 @@ varDefZAxisSearch(int id, void *res, void *data)
 {
   struct varDefZAxisSearchState *state = (struct varDefZAxisSearchState *)data;
   (void)res;
-  if ( zaxisCompare(id, state->zaxistype, state->nlevels, state->lbounds,
-                    state->levels, state->longname, state->units, state->ltype)
-      == false)
+  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;
@@ -63908,16 +63503,17 @@ varDefZAxisSearch(int id, void *res, void *data)
 }
 
 
-int varDefZaxis(int vlistID, int zaxistype, int nlevels, const double *levels, const char **cvals, size_t clength, bool lbounds,        const double *levels1, const double *levels2, int vctsize, const double *vct, char *name,
+int varDefZaxis(int vlistID, int zaxistype, int nlevels, const double *levels, int lbounds,
+		const double *levels1, const double *levels2, int vctsize, const double *vct, char *name,
 		const char *longname, const char *units, int prec, int mode, int ltype1)
 {
   /*
     mode: 0 search in vlist and zaxis table
           1 search in zaxis table
    */
-  int zaxisID = CDI_UNDEFID;
-  bool zaxisdefined = false;
-  bool zaxisglobdefined = false;
+  int zaxisdefined = 0;
+  int zaxisID = UNDEFID;
+  int zaxisglobdefined = 0;
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
   int nzaxis = vlistptr->nzaxis;
 
@@ -63926,9 +63522,9 @@ int varDefZaxis(int vlistID, int zaxistype, int nlevels, const double *levels, c
       {
 	zaxisID = vlistptr->zaxisIDs[index];
 
-	if ( !zaxisCompare(zaxisID, zaxistype, nlevels, lbounds, levels, longname, units, ltype1) )
+	if ( zaxisCompare(zaxisID, zaxistype, nlevels, lbounds, levels, longname, units, ltype1) == 0 )
 	  {
-	    zaxisdefined = true;
+	    zaxisdefined = 1;
 	    break;
 	  }
       }
@@ -63953,7 +63549,7 @@ int varDefZaxis(int vlistID, int zaxistype, int nlevels, const double *levels, c
 	for (int index = 0; index < nzaxis; index++ )
 	  if ( vlistptr->zaxisIDs[index] == zaxisID )
 	    {
-	      zaxisglobdefined = false;
+	      zaxisglobdefined = FALSE;
 	      break;
 	    }
     }
@@ -63963,21 +63559,19 @@ int varDefZaxis(int vlistID, int zaxistype, int nlevels, const double *levels, c
       if ( ! zaxisglobdefined )
 	{
 	  zaxisID = zaxisCreate(zaxistype, nlevels);
-	  if ( levels ) zaxisDefLevels(zaxisID, levels);
+	  zaxisDefLevels(zaxisID, levels);
 	  if ( lbounds )
 	    {
 	      zaxisDefLbounds(zaxisID, levels1);
 	      zaxisDefUbounds(zaxisID, levels2);
 	    }
 
-          if ( cvals != NULL && nlevels != 0 && clength != 0 ) zaxisDefCvals(zaxisID, cvals, clength);
-
 	  if ( (zaxistype == ZAXIS_HYBRID || zaxistype == ZAXIS_HYBRID_HALF) && vctsize > 0 )
             zaxisDefVct(zaxisID, vctsize, vct);
 
-	  if ( name && name[0] ) zaxisDefName(zaxisID, name);
-	  if ( longname && longname[0] ) zaxisDefLongname(zaxisID, longname);
-	  if ( units && units[0] ) zaxisDefUnits(zaxisID, units);
+	  zaxisDefName(zaxisID, name);
+	  zaxisDefLongname(zaxisID, longname);
+	  zaxisDefUnits(zaxisID, units);
 	  zaxisDefPrec(zaxisID, prec);
 	  zaxisDefLtype(zaxisID, ltype1);
 	}
@@ -63986,20 +63580,20 @@ int varDefZaxis(int vlistID, int zaxistype, int nlevels, const double *levels, c
       vlistptr->nzaxis++;
     }
 
-  return zaxisID;
+  return (zaxisID);
 }
 
 
 void varDefMissval(int varID, double missval)
 {
-  vartable[varID].lmissval = true;
+  vartable[varID].lmissval = 1;
   vartable[varID].missval = missval;
 }
 
 
 void varDefCompType(int varID, int comptype)
 {
-  if ( vartable[varID].comptype == CDI_COMPRESS_NONE )
+  if ( vartable[varID].comptype == COMPRESS_NONE )
     vartable[varID].comptype = comptype;
 }
 
@@ -64012,7 +63606,7 @@ void varDefCompLevel(int varID, int complevel)
 
 int varInqInst(int varID)
 {
-  return vartable[varID].instID;
+  return (vartable[varID].instID);
 }
 
 
@@ -64024,7 +63618,7 @@ void varDefInst(int varID, int instID)
 
 int varInqModel(int varID)
 {
-  return vartable[varID].modelID;
+  return (vartable[varID].modelID);
 }
 
 
@@ -64036,7 +63630,7 @@ void varDefModel(int varID, int modelID)
 
 int varInqTable(int varID)
 {
-  return vartable[varID].tableID;
+  return (vartable[varID].tableID);
 }
 
 
@@ -64070,10 +63664,10 @@ void varDefProductDefinitionTemplate(int varID, int productDefinitionTemplate)
 
 #if  defined  (HAVE_LIBGRIB_API)
 /* Resizes and initializes opt_grib_kvpair data structure. */
-static
+static 
 void resize_vartable_opt_grib_entries(vartable_t *var, int nentries)
 {
-  if (var->opt_grib_kvpair_size >= nentries)
+  if (var->opt_grib_kvpair_size >= nentries) 
     {
       return;   /* nothing to do; array is still large enough */
     }
@@ -64093,7 +63687,7 @@ void resize_vartable_opt_grib_entries(vartable_t *var, int nentries)
       for (i=var->opt_grib_kvpair_size; i<new_size; i++) {
         tmp[i].int_val =     0;
         tmp[i].dbl_val =     0;
-        tmp[i].update  = false;
+        tmp[i].update  = FALSE;
         tmp[i].keyword =  NULL;
       } // for
       var->opt_grib_kvpair_size = new_size;
@@ -64146,7 +63740,7 @@ void varDefOptGribDbl(int varID, int tile_index, double dval, const char *keywor
         idx = i;
     }
 
-  if (idx == -1)
+  if (idx == -1) 
     {
       resize_vartable_opt_grib_entries(&vartable[varID], vartable[varID].opt_grib_nentries+1);
       vartable[varID].opt_grib_nentries += 1;
@@ -64168,8 +63762,9 @@ void varDefOptGribDbl(int varID, int tile_index, double dval, const char *keywor
 #if  defined  (HAVE_LIBGRIB_API)
 int varOptGribNentries(int varID)
 {
-  int nentries = vartable[varID].opt_grib_nentries;
-  return nentries;
+  int nentries = 0;
+  nentries = vartable[varID].opt_grib_nentries;
+  return (nentries);
 }
 #endif
 
@@ -64212,6 +63807,35 @@ void cdiVlistCreateVarLevInfo(vlist_t *vlistptr, int varID);
  * require-trailing-newline: t
  * End:
  */
+#ifndef VLIST_ATT_H
+#define VLIST_ATT_H
+
+#ifdef HAVE_CONFIG_H
+#endif
+
+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
+vlistAttsUnpack(int vlistID, int varID,
+                void * buf, int size, int *position, 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:
+ */
 #if defined (HAVE_CONFIG_H)
 #endif
 
@@ -64237,7 +63861,7 @@ static pthread_once_t  _vlist_init_thread = PTHREAD_ONCE_INIT;
 
 #else
 
-static bool vlistIsInitialized = false;
+static int vlistIsInitialized = 0;
 
 #  define VLIST_INIT()               \
   if ( !vlistIsInitialized ) vlist_initialize()
@@ -64247,7 +63871,8 @@ static bool vlistIsInitialized = false;
 static int
 vlist_compare(vlist_t *a, vlist_t *b)
 {
-  int diff = (a->nvars != b->nvars) | (a->ngrids != b->ngrids)
+  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);
@@ -64256,7 +63881,7 @@ vlist_compare(vlist_t *a, vlist_t *b)
     diff |= vlistVarCompare(a, varID, b, varID);
   size_t natts = a->atts.nelems;
   for (size_t attID = 0; attID < natts; ++attID)
-    diff |= cdi_att_compare(a, CDI_GLOBAL, b, CDI_GLOBAL, (int)attID);
+    diff |= vlist_att_compare(a, CDI_GLOBAL, b, CDI_GLOBAL, (int)attID);
   return diff;
 }
 
@@ -64276,8 +63901,8 @@ const
 resOps vlistOps = {
   (valCompareFunc)vlist_compare,
   (valDestroyFunc)vlist_delete,
-  (valPrintFunc)vlistPrintKernel,
-  vlistGetSizeP,
+  (valPrintFunc)vlistPrintKernel
+  , vlistGetSizeP,
   vlistPackP,
   vlistTxCode
 };
@@ -64286,7 +63911,7 @@ resOps vlistOps = {
 vlist_t *vlist_to_pointer(int vlistID)
 {
   VLIST_INIT();
-  return (vlist_t*) reshGetVal(vlistID, &vlistOps);
+  return (vlist_t*) reshGetVal(vlistID, &vlistOps );
 }
 
 static
@@ -64308,7 +63933,7 @@ void vlist_init_entry(vlist_t *vlistptr)
   vlistptr->atts.nalloc    = MAX_ATTRIBUTES;
   vlistptr->atts.nelems    = 0;
   vlistptr->nsubtypes      = 0;
-  for ( int i = 0; i < MAX_SUBTYPES_PS; i++ )
+  for (int i=0; i<MAX_SUBTYPES_PS; i++)
     vlistptr->subtypeIDs[i] = CDI_UNDEFID;
 }
 
@@ -64324,13 +63949,15 @@ vlist_t *vlist_new_entry(cdiResH resH)
       vlistptr->self = resH;
       reshReplace(resH, vlistptr, &vlistOps);
     }
-  return vlistptr;
+  return (vlistptr);
 }
 
 static
 void vlist_delete_entry(vlist_t *vlistptr)
 {
-  int idx = vlistptr->self;
+  int idx;
+
+  idx = vlistptr->self;
 
   reshRemove(idx, &vlistOps );
 
@@ -64343,10 +63970,12 @@ void vlist_delete_entry(vlist_t *vlistptr)
 static
 void vlist_initialize(void)
 {
-  char *env = getenv("VLIST_DEBUG");
+  char *env;
+
+  env = getenv("VLIST_DEBUG");
   if ( env ) VLIST_Debug = atoi(env);
 #ifndef HAVE_LIBPTHREAD
-  vlistIsInitialized = true;
+  vlistIsInitialized = TRUE;
 #endif
 }
 
@@ -64404,7 +64033,7 @@ int vlistCreate(void)
 
   vlist_t *vlistptr = vlist_new_entry(CDI_UNDEFID);
   if ( CDI_Debug ) Message("create vlistID = %d", vlistptr->self);
-  return vlistptr->self;
+  return (vlistptr->self);
 }
 
 static void
@@ -64413,7 +64042,7 @@ vlist_delete(vlist_t *vlistptr)
   int vlistID = vlistptr->self;
   if ( CDI_Debug ) Message("call to vlist_delete, vlistID = %d", vlistID);
 
-  cdiDelAtts(vlistID, CDI_GLOBAL);
+  vlistDelAtts(vlistID, CDI_GLOBAL);
 
   int nvars = vlistptr->nvars;
   var_t *vars = vlistptr->vars;
@@ -64429,18 +64058,17 @@ vlist_delete(vlist_t *vlistptr)
 
       if ( vlistptr->vars[varID].opt_grib_kvpair )
         {
-          for ( int i = 0; i<vlistptr->vars[varID].opt_grib_nentries; i++ )
-            {
-              if ( vlistptr->vars[varID].opt_grib_kvpair[i].keyword )
-                Free(vlistptr->vars[varID].opt_grib_kvpair[i].keyword);
-            }
+          for (int i=0; i<vlistptr->vars[varID].opt_grib_nentries; i++) {
+            if ( vlistptr->vars[varID].opt_grib_kvpair[i].keyword )
+              Free(vlistptr->vars[varID].opt_grib_kvpair[i].keyword);
+          }
           Free(vlistptr->vars[varID].opt_grib_kvpair);
         }
       vlistptr->vars[varID].opt_grib_nentries    = 0;
       vlistptr->vars[varID].opt_grib_kvpair_size = 0;
       vlistptr->vars[varID].opt_grib_kvpair      = NULL;
 
-      cdiDelAtts(vlistID, varID);
+      vlistDelAtts(vlistID, varID);
     }
 
   if ( vars ) Free(vars);
@@ -64510,7 +64138,7 @@ void var_copy_entries(var_t *var2, var_t *var1)
     if ( var1->opt_grib_kvpair[i].keyword != NULL ) {
       var2->opt_grib_kvpair[i]         = var1->opt_grib_kvpair[i];
       var2->opt_grib_kvpair[i].keyword = strdupx(var1->opt_grib_kvpair[i].keyword);
-      var2->opt_grib_kvpair[i].update  = true;
+      var2->opt_grib_kvpair[i].update  = TRUE;
       if ( CDI_Debug )  Message("done.");
     }
     else {
@@ -64543,7 +64171,7 @@ void vlistCopy(int vlistID2, int vlistID1)
   var_t *vars2 = vlistptr2->vars;
   vlist_copy(vlistptr2, vlistptr1);
 
-  cdiCopyAtts(vlistID1, CDI_GLOBAL, vlistID2, CDI_GLOBAL);
+  vlistCopyVarAtts(vlistID1, CDI_GLOBAL, vlistID2, CDI_GLOBAL);
 
   if ( vars1 )
     {
@@ -64560,7 +64188,7 @@ void vlistCopy(int vlistID2, int vlistID1)
           var_copy_entries(&vars2[varID], &vars1[varID]);
 
           vlistptr2->vars[varID].atts.nelems = 0;
-	  cdiCopyAtts(vlistID1, varID, vlistID2, varID);
+	  vlistCopyVarAtts(vlistID1, varID, vlistID2, varID);
 
           if ( vars1[varID].levinfo )
             {
@@ -64594,22 +64222,23 @@ int vlistDuplicate(int vlistID)
 
   int vlistIDnew = vlistCreate();
   vlistCopy(vlistIDnew, vlistID);
-  return vlistIDnew;
+  return (vlistIDnew);
 }
 
 
 void vlistClearFlag(int vlistID)
 {
+  int varID, levID;
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  for ( int varID = 0; varID < vlistptr->nvars; varID++ )
+  for ( varID = 0; varID < vlistptr->nvars; varID++ )
     {
-      vlistptr->vars[varID].flag = false;
+      vlistptr->vars[varID].flag = FALSE;
       if ( vlistptr->vars[varID].levinfo )
         {
           int nlevs = zaxisInqSize(vlistptr->vars[varID].zaxisID);
-          for ( int levID = 0; levID < nlevs; levID++ )
-            vlistptr->vars[varID].levinfo[levID].flag = false;
+          for ( levID = 0; levID < nlevs; levID++ )
+            vlistptr->vars[varID].levinfo[levID].flag = FALSE;
         }
     }
 }
@@ -64620,7 +64249,7 @@ struct vgzSearchState
   int resIDValue;
   int zaxistype;
   int nlevels;
-  bool lbounds;
+  int lbounds;
   const double *levels;
 };
 
@@ -64631,7 +64260,7 @@ vgzZAxisSearch(int id, void *res, void *data)
   (void)res;
   if (zaxisCompare(id, state->zaxistype, state->nlevels, state->lbounds,
                    state->levels, NULL, NULL, 0)
-      == false)
+      == 0)
     {
       state->resIDValue = id;
       return CDI_APPLY_STOP;
@@ -64640,27 +64269,27 @@ vgzZAxisSearch(int id, void *res, void *data)
     return CDI_APPLY_GO_ON;
 }
 
+
 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,
-                         const char **cvals, size_t clen)
+                         const double *lbounds, const double *ubounds, int vctsize, const double *vct)
 {
   int zaxisID = CDI_UNDEFID;
-  bool zaxisdefined = false;
-  bool zaxisglobdefined = false;
-  bool has_bounds = false;
+  int zaxisglobdefined = 0;
+  int has_bounds = FALSE;
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  int zaxisdefined = 0;
   int nzaxis = vlistptr->nzaxis;
 
-  if ( lbounds && ubounds ) has_bounds = true;
+  if ( lbounds && ubounds ) has_bounds = TRUE;
 
   for ( int index = 0; index < nzaxis; ++index )
     {
       zaxisID = vlistptr->zaxisIDs[index];
 
-      if ( zaxisCompare(zaxisID, zaxistype, nlevels, has_bounds, levels, NULL, NULL, 0) == false )
+      if ( zaxisCompare(zaxisID, zaxistype, nlevels, has_bounds, levels, NULL, NULL, 0) == 0 )
         {
-          zaxisdefined = true;
+          zaxisdefined = 1;
           break;
         }
     }
@@ -64685,10 +64314,6 @@ int vlist_generate_zaxis(int vlistID, int zaxistype, int nlevels, const double *
 	{
 	  zaxisID = zaxisCreate(zaxistype, nlevels);
 	  zaxisDefLevels(zaxisID, levels);
-
-          if ( zaxistype == ZAXIS_CHAR )
-            zaxisDefCvals(zaxisID, cvals, clen);
-
 	  if ( has_bounds )
 	    {
 	      zaxisDefLbounds(zaxisID, lbounds);
@@ -64704,7 +64329,7 @@ int vlist_generate_zaxis(int vlistID, int zaxistype, int nlevels, const double *
       vlistptr->nzaxis++;
     }
 
-  return zaxisID;
+  return (zaxisID);
 }
 
 /*
@@ -64730,18 +64355,19 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
 
   vlist_copy(vlistptr2, vlistptr1);
 
-  cdiCopyAtts(vlistID1, CDI_GLOBAL, vlistID2, CDI_GLOBAL);
+  vlistCopyVarAtts(vlistID1, CDI_GLOBAL, vlistID2, CDI_GLOBAL);
 
   if ( vlistptr1->vars )
     {
       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;
+        nvars2 += (vars1[varID].flag != 0);
 
       vlistptr2->nvars = nvars2;
       vlistptr2->varsAllocated = nvars2;
@@ -64752,11 +64378,11 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
 
       vlistptr2->vars = vars2;
 
-      int varID2 = 0;
+      varID2 = 0;
       for ( int varID = 0; varID < nvars; varID++ )
 	if ( vars1[varID].flag )
 	  {
-	    vlistptr2->vars[varID2].flag = false;
+	    vlistptr2->vars[varID2].flag = FALSE;
 	    int zaxisID   = vlistptr1->vars[varID].zaxisID;
 	    int gridID    = vlistptr1->vars[varID].gridID;
 	    int subtypeID = vlistptr1->vars[varID].subtypeID;
@@ -64771,80 +64397,46 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
             var_copy_entries(&vars2[varID2], &vars1[varID]);
 
 	    vlistptr2->vars[varID2].atts.nelems = 0;
-	    cdiCopyAtts(vlistID1, varID, vlistID2, varID2);
+	    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;
+                nlevs2 += (vars1[varID].levinfo[levID].flag != 0);
 
 	    vars2[varID2].levinfo = (levinfo_t *) Malloc((size_t)nlevs2 * sizeof(levinfo_t));
 
 	    if ( nlevs != nlevs2 )
 	      {
 		int nvct = 0;
-                double *levels = NULL;
-                char **cvals1 = NULL, **cvals2 = NULL;
-                size_t clen2 = 0;
 		double *lbounds = NULL, *ubounds = NULL;
 		const double *vct = NULL;
                 char ctemp[CDI_MAX_NAME];
 
-                if ( !vars1[varID].levinfo ) cdiVlistCreateVarLevInfo(vlistptr1, varID);
-
 		zaxisID = vars1[varID].zaxisID;
-                int zaxisType = zaxisInqType(zaxisID);
-
-                int levID2 = 0;
-                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;
-                    }
-
-
-                if ( zaxisInqLevels(zaxisID, NULL) )
-                  {
-                    levels = (double *) Malloc((size_t)nlevs2 * sizeof (double));
+		double *levels = (double *) Malloc((size_t)nlevs2 * sizeof (double));
+                if ( !vars1[varID].levinfo )
+                  cdiVlistCreateVarLevInfo(vlistptr1, varID);
 
-                    levID2 = 0;
-                    for ( int levID = 0; levID < nlevs; ++levID )
-                      if ( vars1[varID].levinfo[levID].flag )
+                {
+                  int levID2 = 0;
+                  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);
-                  }
-
-                if ( zaxisType == ZAXIS_HYBRID )
-                  {
-                    nvct = zaxisInqVctSize(zaxisID);
-                    vct  = zaxisInqVctPtr(zaxisID);
-                  }
+                      }
+                }
 
-                if ( zaxisType == ZAXIS_CHAR )
-                  {
-                    cvals1 = zaxisInqCValsPtr(zaxisID);
-                    size_t clen1 = (size_t)zaxisInqCLen(zaxisID);
-                    for ( int levID = 0; levID < nlevs; ++levID )
-                      if ( vars1[varID].levinfo[levID].flag )
-                          {
-                            size_t testlen = clen1;
-                            while ( cvals1[levID][testlen] == ' ' )
-                              testlen--;
-                            if ( clen2 < testlen )
-                              clen2 = testlen;
-                          }
-                    cvals2 = (char **) Malloc((size_t)nlevs2 * sizeof (char *));
-                    levID2 = 0;
+		int zaxisType = zaxisInqType(zaxisID);
 
-                    for ( int levID = 0; levID < nlevs; ++levID )
-                      if ( vars1[varID].levinfo[levID].flag )
-                        {
-                          cvals2[levID2] = Malloc((size_t)(clen2) * sizeof (char));
-                          memcpy(cvals2[levID2], cvals1[levID], clen2*sizeof(char));
-                          levID2++;
-                        }
-                  }
+		if ( zaxisType == ZAXIS_HYBRID )
+		  {
+		    nvct = zaxisInqVctSize(zaxisID);
+		    vct  = zaxisInqVctPtr(zaxisID);
+		  }
 
                 if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
                   {
@@ -64852,12 +64444,12 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
                     ubounds = lbounds + nlevs2;
 
                     double *lbounds1 = (double *) Malloc(2 * (size_t)nlevs * sizeof (double)),
-                           *ubounds1 = lbounds1 + nlevs;
+                      *ubounds1 = lbounds1 + nlevs;
 
                     zaxisInqLbounds(zaxisID, lbounds1);
                     zaxisInqUbounds(zaxisID, ubounds1);
 
-                    levID2 = 0;
+                    int levID2 = 0;
                     for ( int levID = 0; levID < nlevs; ++levID )
                       if ( vars1[varID].levinfo[levID].flag )
                         {
@@ -64869,15 +64461,9 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
                     Free(lbounds1);
                   }
 
-		int zaxisID2 = vlist_generate_zaxis(vlistID2, zaxisType, nlevs2, levels, lbounds, ubounds, nvct, vct, (const char **)cvals2, clen2);
-		if ( levels )  Free(levels);
-                if ( lbounds ) Free(lbounds);
-                if ( cvals2 )
-                  {
-                    for ( int levID = 0; levID < nlevs2; ++levID )
-                      Free(cvals2[levID]);
-                    Free(cvals2);
-                  }
+		int zaxisID2 = vlist_generate_zaxis(vlistID2, zaxisType, nlevs2, levels, lbounds, ubounds, nvct, vct);
+		free(levels);
+                Free(lbounds);
 
                 zaxisInqName(zaxisID, ctemp);
                 zaxisDefName(zaxisID2, ctemp);
@@ -64886,23 +64472,13 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
                 zaxisInqUnits(zaxisID, ctemp);
                 zaxisDefUnits(zaxisID2, ctemp);
 
-                if ( zaxisType == ZAXIS_CHAR )
-                  {
-                    char dimname[CDI_MAX_NAME+3]; dimname[0] = 0;
-                    cdiZaxisInqKeyStr(zaxisID, CDI_KEY_DIMNAME, CDI_MAX_NAME, dimname);
-                    if ( dimname[0] == 0 ) { memcpy(dimname, "area_type", 10); dimname[10] = 0; }
-                    cdiZaxisDefKeyStr(zaxisID2, CDI_KEY_DIMNAME, CDI_MAX_NAME, dimname);
-                  }
-
-                if ( zaxisType == ZAXIS_GENERIC ) zaxisDefLtype(zaxisID2, zaxisInqLtype(zaxisID));
-
 		zaxisID = zaxisID2;
 		vars2[varID2].zaxisID = zaxisID2;
 	      }
 
 	    for ( int levID = 0; levID < nlevs2; levID++ )
 	      {
-		vars2[varID2].levinfo[levID].flag  = false;
+		vars2[varID2].levinfo[levID].flag  = FALSE;
 		vars2[varID2].levinfo[levID].index = -1;
 	      }
 
@@ -64985,7 +64561,7 @@ void vlistCat(int vlistID2, int vlistID1)
         }
 
       vars2[varID2].atts.nelems = 0;
-      cdiCopyAtts(vlistID1, varID, vlistID2, varID2);
+      vlistCopyVarAtts(vlistID1, varID, vlistID2, varID2);
 
       vlistAdd2GridIDs(vlistptr2, vars1[varID].gridID);
       vlistAdd2ZaxisIDs(vlistptr2, vars1[varID].zaxisID);
@@ -65069,11 +64645,11 @@ void vlistMerge(int vlistID2, int vlistID1)
             vars1[varID].levinfo[levID].mlevelID = nlevs2 + levID;
 	}
 
-      bool *lvar = (bool *) Calloc((size_t)nvars2, sizeof(bool));
+      int *lvar = (int *) Calloc((size_t)nvars2, sizeof(int));
 
       for ( varID = 0; varID < nvars2; varID++ )
         {
-          if ( lvar[varID] == true ) continue;
+          if ( lvar[varID] == TRUE ) continue;
 
           int zaxisID1 = vars1[varID].zaxisID;
           int zaxisID2 = vars2[varID].zaxisID;
@@ -65089,32 +64665,30 @@ void vlistMerge(int vlistID2, int vlistID1)
           int nlevs = nlevs1 + nlevs2;
 
           int zaxisID = zaxisDuplicate(zaxisID2);
+
           zaxisResize(zaxisID, nlevs);
 
-          if ( zaxisInqLevels(zaxisID1, NULL) )
-            {
-              double *levels = (double *) Malloc((size_t)nlevs1 * sizeof(double));
+          double *levels = (double *) Malloc((size_t)nlevs1 * sizeof(double));
 
-              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]);
+          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]);
 
-              Free(levels);
-            }
+          Free(levels);
 
           for ( int index = 0; index < vlistptr2->nzaxis; index++ )
             if ( vlistptr2->zaxisIDs[index] == zaxisID2 )
               vlistptr2->zaxisIDs[index] = zaxisID;
 
           for ( int varID2 = 0; varID2 < nvars2; varID2++ )
-            if ( lvar[varID2] == false && vars2[varID2].zaxisID == zaxisID2 )
+            if ( lvar[varID2] == FALSE && vars2[varID2].zaxisID == zaxisID2 )
               {
                 vars2[varID2].zaxisID = zaxisID;
-                lvar[varID2] = true;
+                lvar[varID2] = TRUE;
               }
         }
 
@@ -65145,29 +64719,29 @@ The function @func{vlistNvars} returns the number of variables in the variable l
 int vlistNvars(int vlistID)
 {
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  return vlistptr->nvars;
+  return (vlistptr->nvars);
 }
 
 
 int vlistNrecs(int vlistID)
 {
+  int nrecs = 0;
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  int nrecs = 0;
   for ( int varID = 0; varID < vlistptr->nvars; varID++ )
     nrecs +=  zaxisInqSize(vlistptr->vars[varID].zaxisID);
 
-  return nrecs;
+  return (nrecs);
 }
 
 
 int vlistNumber(int vlistID)
 {
-  int number, number2;
+  int number, number2, datatype;
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  int datatype = vlistptr->vars[0].datatype;
-  if (  datatype== CDI_DATATYPE_CPX32 || datatype == CDI_DATATYPE_CPX64 )
+  datatype = vlistptr->vars[0].datatype;
+  if (  datatype== DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
     number = CDI_COMP;
   else
     number = CDI_REAL;
@@ -65175,7 +64749,7 @@ int vlistNumber(int vlistID)
   for ( int varID = 1; varID < vlistptr->nvars; varID++ )
     {
       datatype = vlistptr->vars[varID].datatype;
-      if ( datatype == CDI_DATATYPE_CPX32 || datatype == CDI_DATATYPE_CPX64 )
+      if ( datatype == DATATYPE_CPX32 || datatype == DATATYPE_CPX64 )
         number2 = CDI_COMP;
       else
         number2 = CDI_REAL;
@@ -65187,7 +64761,7 @@ int vlistNumber(int vlistID)
         }
     }
 
-  return number;
+  return (number);
 }
 
 /*
@@ -65210,7 +64784,7 @@ int vlistNgrids(int vlistID)
 {
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  return vlistptr->ngrids;
+  return (vlistptr->ngrids);
 }
 
 /*
@@ -65233,7 +64807,7 @@ int vlistNzaxis(int vlistID)
 {
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  return vlistptr->nzaxis;
+  return (vlistptr->nzaxis);
 }
 
 
@@ -65241,7 +64815,7 @@ int vlistNsubtypes(int vlistID)
 {
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  return vlistptr->nsubtypes;
+  return (vlistptr->nsubtypes);
 }
 
 
@@ -65249,7 +64823,7 @@ void vlistDefNtsteps(int vlistID, int nts)
 {
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  if ( vlistptr->ntsteps != nts )
+  if (vlistptr->ntsteps != nts)
     {
       vlistptr->ntsteps = nts;
       reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
@@ -65327,8 +64901,7 @@ void vlistPrintKernel(vlist_t *vlistptr, FILE *fp)
               int mlevID = li.mlevelID;
               int index  = li.index;
               int flag   = li.flag;
-
-              double level = zaxisInqLevels(zaxisID, NULL) ? zaxisInqLevel(zaxisID, levID) : levID+1;
+              double level  = zaxisInqLevel(zaxisID, levID);
 
               fprintf(fp, "%6d %6d %6d %6d %6d %6d %6d %6d %5d  %.9g\n",
                       varID, levID, fvarID, flevID, mvarID, mlevID, index,
@@ -65372,7 +64945,7 @@ void vlistDefTaxis(int vlistID, int taxisID)
 {
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  if ( vlistptr->taxisID != 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;
@@ -65400,7 +64973,7 @@ int vlistInqTaxis(int vlistID)
 {
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  return vlistptr->taxisID;
+  return (vlistptr->taxisID);
 }
 
 
@@ -65408,7 +64981,7 @@ void vlistDefTable(int vlistID, int tableID)
 {
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  if ( vlistptr->tableID != tableID )
+  if (vlistptr->tableID != tableID)
     {
       vlistptr->tableID = tableID;
       reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
@@ -65420,7 +64993,7 @@ int vlistInqTable(int vlistID)
 {
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  return vlistptr->tableID;
+  return (vlistptr->tableID);
 }
 
 
@@ -65428,7 +65001,7 @@ void vlistDefInstitut(int vlistID, int instID)
 {
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  if ( vlistptr->instID != instID )
+  if (vlistptr->instID != instID)
     {
       vlistptr->instID = instID;
       reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
@@ -65455,7 +65028,7 @@ int vlistInqInstitut(int vlistID)
       vlistDefInstitut(vlistID, instID);
     }
 
-  return instID;
+  return (instID);
 }
 
 
@@ -65463,7 +65036,7 @@ void vlistDefModel(int vlistID, int modelID)
 {
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  if ( vlistptr->modelID != modelID )
+  if (vlistptr->modelID != modelID)
     {
       vlistptr->modelID = modelID;
       reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
@@ -65491,7 +65064,7 @@ int vlistInqModel(int vlistID)
       vlistDefModel(vlistID, modelID);
     }
 
-  return modelID;
+  return (modelID);
 }
 
 
@@ -65507,7 +65080,7 @@ int vlistGridsizeMax(int vlistID)
       if ( gridsize > gridsizemax ) gridsizemax = gridsize;
     }
 
-  return gridsizemax;
+  return (gridsizemax);
 }
 
 
@@ -65519,7 +65092,7 @@ int vlistGrid(int vlistID, int index)
   if ( index < vlistptr->ngrids && index >= 0 )
     gridID = vlistptr->gridIDs[index];
 
-  return gridID;
+  return (gridID);
 }
 
 
@@ -65533,7 +65106,7 @@ int vlistGridIndex(int vlistID, int gridID)
 
   if ( index == vlistptr->ngrids ) index = -1;
 
-  return index;
+  return (index);
 }
 
 
@@ -65587,7 +65160,7 @@ int vlistZaxis(int vlistID, int index)
   if ( index < vlistptr->nzaxis && index >= 0 )
     zaxisID = vlistptr->zaxisIDs[index];
 
-  return zaxisID;
+  return (zaxisID);
 }
 
 
@@ -65601,7 +65174,7 @@ int vlistZaxisIndex(int vlistID, int zaxisID)
 
   if ( index == vlistptr->nzaxis ) index = -1;
 
-  return index;
+  return (index);
 }
 
 
@@ -65695,24 +65268,25 @@ int vlistSubtypeIndex(int vlistID, int subtypeID)
 
 int vlistHasTime(int vlistID)
 {
-  bool hastime = false;
+  int hastime = FALSE;
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
   for ( int varID = 0; varID <  vlistptr->nvars; varID++ )
     if ( vlistptr->vars[varID].tsteptype != TSTEP_CONSTANT )
       {
-        hastime = true;
+        hastime = TRUE;
         break;
       }
 
-  return (int)hastime;
+  return (hastime);
 }
 
 enum {
   vlist_nints=6,
 };
 
-static int vlistTxCode ( void )
+static int
+vlistTxCode ( void )
 {
   return VLIST;
 }
@@ -65723,9 +65297,9 @@ int  vlistGetSizeP ( void * vlistptr, void *context)
 {
   int txsize, varID;
   vlist_t *p = (vlist_t*) vlistptr;
-  txsize = serializeGetSize(vlist_nints, CDI_DATATYPE_INT, context);
-  txsize += serializeGetSize(1, CDI_DATATYPE_LONG, context);
-  txsize += cdiAttsGetSize(p, CDI_GLOBAL, context);
+  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;
@@ -65744,10 +65318,10 @@ void vlistPackP ( void * vlistptr, void * buf, int size, int *position,
   tempbuf[3] = p->tableID;
   tempbuf[4] = p->instID;
   tempbuf[5] = p->modelID;
-  serializePack(tempbuf, vlist_nints, CDI_DATATYPE_INT, buf, size, position, context);
-  serializePack(&p->ntsteps, 1, CDI_DATATYPE_LONG, buf, size, position, context);
+  serializePack(tempbuf, vlist_nints, DATATYPE_INT, buf, size, position, context);
+  serializePack(&p->ntsteps, 1, DATATYPE_LONG, buf, size, position, context);
 
-  cdiAttsPack(p, CDI_GLOBAL, buf, size, position, context);
+  vlistAttsPack(p, CDI_GLOBAL, buf, size, position, context);
   for ( varID = 0; varID < p->nvars; varID++ )
     {
       vlistVarPack(p, varID, (char *)buf, size, position, context);
@@ -65758,7 +65332,7 @@ 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, CDI_DATATYPE_INT, context);
+  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);
@@ -65770,8 +65344,8 @@ void vlistUnpack(char * buf, int size, int *position, int originNamespace,
   p->tableID = tempbuf[3];
   p->instID = namespaceAdaptKey(tempbuf[4], originNamespace);
   p->modelID = namespaceAdaptKey(tempbuf[5], originNamespace);
-  serializeUnpack(buf, size, position, &p->ntsteps, 1, CDI_DATATYPE_LONG, context);
-  cdiAttsUnpack(targetID, CDI_GLOBAL, buf, size, position, context);
+  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);
   reshSetStatus(targetID, &vlistOps,
@@ -65781,10 +65355,11 @@ void vlistUnpack(char * buf, int size, int *position, int originNamespace,
 
 void vlist_check_contents(int vlistID)
 {
-  int zaxisID;
-  int nzaxis = vlistNzaxis(vlistID);
+  int index, nzaxis, zaxisID;
 
-  for ( int index = 0; index < nzaxis; index++ )
+  nzaxis = vlistNzaxis(vlistID);
+
+  for ( index = 0; index < nzaxis; index++ )
     {
       zaxisID = vlistZaxis(vlistID, index);
       if ( zaxisInqType(zaxisID) == ZAXIS_GENERIC )
@@ -65796,7 +65371,7 @@ void vlist_check_contents(int vlistID)
 /* Resizes and initializes opt_grib_kvpair data structure. */
 void resize_opt_grib_entries(var_t *var, int nentries)
 {
-  if (var->opt_grib_kvpair_size >= nentries)
+  if (var->opt_grib_kvpair_size >= nentries) 
     {
       if ( CDI_Debug )
         Message("data structure has size %d, no resize to %d needed.", var->opt_grib_kvpair_size, nentries);
@@ -65816,7 +65391,7 @@ void resize_opt_grib_entries(var_t *var, int nentries)
       for (i=var->opt_grib_kvpair_size; i<new_size; i++) {
         tmp[i].int_val =     0;
         tmp[i].dbl_val =     0;
-        tmp[i].update  = false;
+        tmp[i].update  = FALSE;
         tmp[i].keyword =  NULL;
       } // for
       var->opt_grib_kvpair_size = new_size;
@@ -65844,7 +65419,6 @@ void resize_opt_grib_entries(var_t *var, int nentries)
 
 
 
-
 static
 cdi_atts_t *get_attsp(vlist_t *vlistptr, int varID)
 {
@@ -65860,7 +65434,7 @@ cdi_atts_t *get_attsp(vlist_t *vlistptr, int varID)
 	attsp = &(vlistptr->vars[varID].atts);
     }
 
-  return attsp;
+  return (attsp);
 }
 
 static
@@ -65878,24 +65452,27 @@ cdi_att_t *find_att(cdi_atts_t *attsp, const char *name)
     {
       cdi_att_t *attp = atts + attid;
       if ( attp->namesz == slen && memcmp(attp->name, name, slen) == 0 )
-        return attp; /* Normal return */
+        return (attp); /* Normal return */
     }
 
-  return NULL;
+  return (NULL);
 }
 
 static
 cdi_att_t *new_att(cdi_atts_t *attsp, const char *name)
 {
+  cdi_att_t *attp;
+  size_t slen;
+
   xassert(attsp != NULL);
   xassert(name  != NULL);
 
-  if ( attsp->nelems == attsp->nalloc ) return NULL;
+  if ( attsp->nelems == attsp->nalloc ) return (NULL);
 
-  cdi_att_t *attp = &(attsp->value[attsp->nelems]);
+  attp = &(attsp->value[attsp->nelems]);
   attsp->nelems++;
 
-  size_t slen = strlen(name);
+  slen = strlen(name);
   if ( slen > CDI_MAX_NAME ) slen = CDI_MAX_NAME;
 
   attp->name = (char *) Malloc(slen+1);
@@ -65903,7 +65480,7 @@ cdi_att_t *new_att(cdi_atts_t *attsp, const char *name)
   attp->namesz = slen;
   attp->xvalue = NULL;
 
-  return attp;
+  return (attp);
 }
 
 static
@@ -65923,64 +65500,44 @@ void fill_att(cdi_att_t *attp, int indtype, int exdtype, size_t nelems, size_t x
     }
 }
 
-static
-cdi_atts_t *cdi_get_attsp(int objID, int varID)
-{
-  cdi_atts_t *attsp = NULL;
-
-  if ( varID == CDI_GLOBAL && reshGetTxCode(objID) == GRID )
-    {
-      grid_t *gridptr = grid_to_pointer(objID);
-      attsp = &gridptr->atts;
-    }
-  else if ( varID == CDI_GLOBAL && reshGetTxCode(objID) == ZAXIS )
-    {
-      zaxis_t *zaxisptr = zaxis_to_pointer(objID);
-      attsp = &zaxisptr->atts;
-    }
-  else
-    {
-      vlist_t *vlistptr = vlist_to_pointer(objID);
-      attsp = get_attsp(vlistptr, varID);
-    }
-
-  return attsp;
-}
-
 /*
- at Function  cdiInqNatts
- at Title     Get number of attributes
+ at Function  vlistInqNatts
+ at Title     Get number of variable attributes
 
- at Prototype int cdiInqNatts(int cdiID, int varID, int *nattsp)
+ at Prototype int vlistInqNatts(int vlistID, int varID, int *nattsp)
 @Parameter
-    @Item  cdiID    CDI ID, from a previous call to @fref{vlistCreate}, @fref{gridCreate} or @fref{streamInqVlist}.
+    @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 attributes.
+    @Item  nattsp   Pointer to location for returned number of variable attributes.
 
 @Description
-The function @func{cdiInqNatts} gets the number of attributes assigned to this variable.
+The function @func{vlistInqNatts} gets the number of variable attributes assigned to this variable.
 
 @EndFunction
 */
-int cdiInqNatts(int cdiID, int varID, int *nattsp)
+int vlistInqNatts(int vlistID, int varID, int *nattsp)
 {
   int status = CDI_NOERR;
+  vlist_t *vlistptr;
+  cdi_atts_t *attsp;
 
-  cdi_atts_t *attsp = cdi_get_attsp(cdiID, varID);
+  vlistptr = vlist_to_pointer(vlistID);
+
+  attsp = get_attsp(vlistptr, varID);
   xassert(attsp != NULL);
 
   *nattsp = (int)attsp->nelems;
 
-  return status;
+  return (status);
 }
 
 /*
- at Function  cdiInqAtt
+ at Function  vlistInqAtt
 @Title     Get information about an attribute
 
- at Prototype int cdiInqAtt(int cdiID, int varID, int attnum, char *name, int *typep, int *lenp)
+ at Prototype int vlistInqAtt(int vlistID, int varID, int attnum, char *name, int *typep, int *lenp)
 @Parameter
-    @Item  cdiID    CDI ID, from a previous call to @fref{vlistCreate}, @fref{gridCreate} or @fref{streamInqVlist}.
+    @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
@@ -65990,20 +65547,22 @@ int cdiInqNatts(int cdiID, int varID, int *nattsp)
     @Item  lenp     Pointer to location for returned attribute number.
 
 @Description
-The function @func{cdiInqAtt} gets information about an attribute.
+The function @func{vlistInqAtt} gets information about an attribute.
 
 @EndFunction
 */
-int cdiInqAtt(int cdiID, int varID, int attnum, char *name, int *typep, int *lenp)
+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);
 
-  cdi_atts_t *attsp = cdi_get_attsp(cdiID, varID);
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+
+  cdi_atts_t *attsp = get_attsp(vlistptr, varID);
   xassert(attsp != NULL);
 
-  cdi_att_t *attp = NULL;
   if ( attnum >= 0 && attnum < (int)attsp->nelems )
     attp = &(attsp->value[attnum]);
 
@@ -66021,79 +65580,102 @@ int cdiInqAtt(int cdiID, int varID, int attnum, char *name, int *typep, int *len
       status  = -1;
     }
 
-  return status;
+  return (status);
 }
 
 
-int cdiDelAtts(int cdiID, int varID)
+int vlistDelAtts(int vlistID, int varID)
 {
   int status = CDI_NOERR;
+  vlist_t *vlistptr;
+  cdi_att_t *attp = NULL;
+  cdi_atts_t *attsp;
+  int attid;
 
-  cdi_atts_t *attsp = cdi_get_attsp(cdiID, varID);
+  vlistptr = vlist_to_pointer(vlistID);
+
+  attsp = get_attsp(vlistptr, varID);
   xassert(attsp != NULL);
 
-  for ( int attid = 0; attid < (int)attsp->nelems; attid++ )
+  for ( attid = 0; attid < (int)attsp->nelems; attid++ )
     {
-      cdi_att_t *attp = &(attsp->value[attid]);
+      attp = &(attsp->value[attid]);
       if ( attp->name   ) Free(attp->name);
       if ( attp->xvalue ) Free(attp->xvalue);
     }
 
   attsp->nelems = 0;
 
-  return status;
+  return (status);
 }
 
 
-int cdiDelAtt(int cdiID, int varID, const char *name)
+int vlistDelAtt(int vlistID, int varID, const char *name)
 {
   int status = CDI_NOERR;
 
-  UNUSED(cdiID);
+  UNUSED(vlistID);
   UNUSED(varID);
   UNUSED(name);
 
-  fprintf(stderr, "cdiDelAtt not implemented!\n");
+  fprintf(stderr, "vlistDelAtt not implemented!\n");
 
-  return status;
+  return (status);
 }
 
 static
-int cdi_def_att(int indtype, int exdtype, int cdiID, int varID, const char *name, size_t len, size_t xsz, const void *xp)
+int vlist_def_att(int indtype, int exdtype, int vlistID, int varID, const char *name, size_t len, size_t xsz, const void *xp)
 {
   int status = CDI_NOERR;
+  vlist_t *vlistptr;
+  cdi_att_t *attp;
+  cdi_atts_t *attsp;
 
   if ( len != 0 && xp == NULL ) /* Null arg */
-    return CDI_EINVAL;
+    {
+      return (CDI_EINVAL);
+    }
+
+  vlistptr = vlist_to_pointer(vlistID);
 
-  cdi_atts_t *attsp = cdi_get_attsp(cdiID, varID);
+  attsp = get_attsp(vlistptr, varID);
   xassert(attsp != NULL);
 
-  cdi_att_t *attp = find_att(attsp, name);
-  if ( attp == NULL ) attp = new_att(attsp, name);
+  attp = find_att(attsp, name);
+  if ( attp == NULL )
+    attp = new_att(attsp, name);
 
-  if ( attp != NULL ) fill_att(attp, indtype, exdtype, len, xsz, xp);
+  if ( attp != NULL )
+    fill_att(attp, indtype, exdtype, len, xsz, xp);
 
-  return status;
+  return (status);
 }
 
 static
-int cdi_inq_att(int indtype, int cdiID, int varID, const char *name, size_t mxsz, void *xp)
+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 */
-    return CDI_EINVAL;
+    {
+      return (CDI_EINVAL);
+    }
 
-  cdi_atts_t *attsp = cdi_get_attsp(cdiID, varID);
+  vlistptr = vlist_to_pointer(vlistID);
+
+  attsp = get_attsp(vlistptr, varID);
   xassert(attsp != NULL);
 
-  cdi_att_t *attp = find_att(attsp, name);
+  attp = find_att(attsp, name);
   if ( attp != NULL ) /* name in use */
     {
       if ( attp->indtype == indtype )
 	{
-	  size_t xsz = attp->xsz;
+	  xsz = attp->xsz;
 	  if ( mxsz < xsz ) xsz = mxsz;
 	  if ( xsz > 0 )
 	    memcpy(xp, attp->xvalue, xsz);
@@ -66110,178 +65692,184 @@ int cdi_inq_att(int indtype, int cdiID, int varID, const char *name, size_t mxsz
       status = -1;
     }
 
-  return status;
+  return (status);
 }
 
 
-int cdiCopyAtts(int cdiID1, int varID1, int cdiID2, int varID2)
+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;
 
-  cdi_atts_t *attsp1 = cdi_get_attsp(cdiID1, varID1);
+  vlistptr1 = vlist_to_pointer(vlistID1);
+
+  attsp1 = get_attsp(vlistptr1, varID_1);
   xassert(attsp1 != NULL);
 
-  for ( int attid = 0; attid < (int)attsp1->nelems; attid++ )
+  for ( attid = 0; attid < (int)attsp1->nelems; attid++ )
     {
-      cdi_att_t *attp = &(attsp1->value[attid]);
-      cdi_def_att(attp->indtype, attp->exdtype, cdiID2, varID2, attp->name, attp->nelems, attp->xsz, attp->xvalue);
+      attp = &(attsp1->value[attid]);
+      vlist_def_att(attp->indtype, attp->exdtype, vlistID2, varID_2, attp->name, attp->nelems, attp->xsz, attp->xvalue);
     }
 
-  return status;
+  return (status);
 }
 
 /*
- at Function  cdiDefAttInt
+ at Function  vlistDefAttInt
 @Title     Define an integer attribute
 
- at Prototype int cdiDefAttInt(int cdiID, int varID, const char *name, int type, int len, const int *ip)
+ at Prototype int vlistDefAttInt(int vlistID, int varID, const char *name, int type, int len, const int *ip)
 
 @Parameter
-    @Item  cdiID    CDI ID, from a previous call to @fref{vlistCreate} or @fref{gridCreate}.
+    @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{CDI_DATATYPE_INT16} or @func{CDI_DATATYPE_INT32}).
+    @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.
 
 @Description
-The function @func{cdiDefAttInt} defines an integer attribute.
+The function @func{vlistDefAttInt} defines an integer attribute.
 
 @EndFunction
 */
-int cdiDefAttInt(int cdiID, int varID, const char *name, int type, int len, const int *ip)
+int vlistDefAttInt(int vlistID, int varID, const char *name, int type, int len, const int *ip)
 {
-  return cdi_def_att(CDI_DATATYPE_INT, type, cdiID, varID, name, (size_t)len, (size_t)len * sizeof(int), ip);
+  return vlist_def_att(DATATYPE_INT, type, vlistID, varID, name, (size_t)len, (size_t)len * sizeof (int), ip);
 }
 
 /*
- at Function  cdiDefAttFlt
+ at Function  vlistDefAttFlt
 @Title     Define a floating point attribute
 
- at Prototype int cdiDefAttFlt(int cdiID, int varID, const char *name, int type, int len, const double *dp)
+ at Prototype int vlistDefAttFlt(int vlistID, int varID, const char *name, int type, int len, const double *dp)
 
 @Parameter
-    @Item  cdiID    CDI ID, from a previous call to @fref{vlistCreate} or @fref{gridCreate}.
+    @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{CDI_DATATYPE_FLT32} or @func{CDI_DATATYPE_FLT64}).
+    @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.
 
 @Description
-The function @func{cdiDefAttFlt} defines a floating point attribute.
+The function @func{vlistDefAttFlt} defines a floating point attribute.
 
 @EndFunction
 */
-int cdiDefAttFlt(int cdiID, int varID, const char *name, int type, int len, const double *dp)
+int vlistDefAttFlt(int vlistID, int varID, const char *name, int type, int len, const double *dp)
 {
-  return cdi_def_att(CDI_DATATYPE_FLT, type, cdiID, varID, name, (size_t)len, (size_t)len * sizeof(double), dp);
+  return vlist_def_att(DATATYPE_FLT, type, vlistID, varID, name, (size_t)len, (size_t)len * sizeof (double), dp);
 }
 
 /*
- at Function  cdiDefAttTxt
+ at Function  vlistDefAttTxt
 @Title     Define a text attribute
 
- at Prototype int cdiDefAttTxt(int cdiID, int varID, const char *name, int len, const char *tp)
+ at Prototype int vlistDefAttTxt(int vlistID, int varID, const char *name, int len, const char *tp)
 
 @Parameter
-    @Item  cdiID    CDI ID, from a previous call to @fref{vlistCreate} or @fref{gridCreate}.
+    @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.
 
 @Description
-The function @func{cdiDefAttTxt} defines a text attribute.
+The function @func{vlistDefAttTxt} defines a text attribute.
 
 @EndFunction
 */
-int cdiDefAttTxt(int cdiID, int varID, const char *name, int len, const char *tp)
+int vlistDefAttTxt(int vlistID, int varID, const char *name, int len, const char *tp)
 {
-  return cdi_def_att(CDI_DATATYPE_TXT, CDI_DATATYPE_TXT, cdiID, varID, name, (size_t)len, (size_t)len, tp);
+  return vlist_def_att(DATATYPE_TXT, DATATYPE_TXT, vlistID, varID, name, (size_t)len, (size_t)len, tp);
 }
 
 /*
- at Function  cdiInqAttInt
+ at Function  vlistInqAttInt
 @Title     Get the value(s) of an integer attribute
 
- at Prototype int cdiInqAttInt(int cdiID, int varID, const char *name, int mlen, int *ip)
+ at Prototype int vlistInqAttInt(int vlistID, int varID, const char *name, int mlen, int *ip)
 @Parameter
-    @Item  cdiID    CDI ID, from a previous call to @fref{vlistCreate}, @fref{gridCreate} or @fref{streamInqVlist}.
+    @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).
 
 @Description
-The function @func{cdiInqAttInt} gets the values(s) of an integer attribute.
+The function @func{vlistInqAttInt} gets the values(s) of an integer attribute.
 
 @EndFunction
 */
-int cdiInqAttInt(int cdiID, int varID, const char *name, int mlen, int *ip)
+int vlistInqAttInt(int vlistID, int varID, const char *name, int mlen, int *ip)
 {
-  return cdi_inq_att(CDI_DATATYPE_INT, cdiID, varID, name, (size_t)mlen * sizeof(int), ip);
+  return vlist_inq_att(DATATYPE_INT, vlistID, varID, name, (size_t)mlen * sizeof (int), ip);
 }
 
 /*
- at Function  cdiInqAttFlt
+ at Function  vlistInqAttFlt
 @Title     Get the value(s) of a floating point attribute
 
- at Prototype int cdiInqAttFlt(int cdiID, int varID, const char *name, int mlen, double *dp)
+ at Prototype int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double *dp)
 @Parameter
-    @Item  cdiID    CDI ID, from a previous call to @fref{vlistCreate}, @fref{gridCreate} or @fref{streamInqVlist}.
+    @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).
 
 @Description
-The function @func{cdiInqAttFlt} gets the values(s) of a floating point attribute.
+The function @func{vlistInqAttFlt} gets the values(s) of a floating point attribute.
 
 @EndFunction
 */
-int cdiInqAttFlt(int cdiID, int varID, const char *name, int mlen, double *dp)
+int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double *dp)
 {
-  return cdi_inq_att(CDI_DATATYPE_FLT, cdiID, varID, name, (size_t)mlen * sizeof(double), dp);
+  return vlist_inq_att(DATATYPE_FLT, vlistID, varID, name, (size_t)mlen * sizeof (double), dp);
 }
 
 /*
- at Function  cdiInqAttTxt
+ at Function  vlistInqAttTxt
 @Title     Get the value(s) of a text attribute
 
- at Prototype int cdiInqAttTxt(int cdiID, int varID, const char *name, int mlen, char *tp)
+ at Prototype int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp)
 @Parameter
-    @Item  cdiID    CDI ID, from a previous call to @fref{vlistCreate}, @fref{gridCreate} or @fref{streamInqVlist}.
+    @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).
 
 @Description
-The function @func{cdiInqAttTxt} gets the values(s) of a text attribute.
+The function @func{vlistInqAttTxt} gets the values(s) of a text attribute.
 
 @EndFunction
 */
-int cdiInqAttTxt(int cdiID, int varID, const char *name, int mlen, char *tp)
+int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp)
 {
-  return cdi_inq_att(CDI_DATATYPE_TXT, cdiID, varID, name, (size_t)mlen * sizeof(char), tp);
+  return vlist_inq_att(DATATYPE_TXT, vlistID, varID, name, (size_t)mlen * sizeof (char), tp);
 }
 
 enum {
-  cdi_att_nints = 4,          /* namesz, exdtype, indtype, nelems */
+  vlist_att_nints = 4,          /* namesz, exdtype, indtype, nelems */
 };
 
-static inline
-int cdiAttTypeLookup(cdi_att_t *attp)
+static inline int
+vlistAttTypeLookup(cdi_att_t *attp)
 {
   int type;
   switch (attp->indtype)
   {
-  case CDI_DATATYPE_FLT:
-    type = CDI_DATATYPE_FLT64;
+  case DATATYPE_FLT:
+    type = DATATYPE_FLT64;
     break;
-  case CDI_DATATYPE_INT:
-  case CDI_DATATYPE_TXT:
+  case DATATYPE_INT:
+  case DATATYPE_TXT:
     type = attp->indtype;
     break;
   default:
@@ -66292,7 +65880,8 @@ int cdiAttTypeLookup(cdi_att_t *attp)
 }
 
 
-int cdi_att_compare(vlist_t *a, int varIDA, vlist_t *b, int varIDB, int attnum)
+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);
@@ -66316,8 +65905,8 @@ int cdi_att_compare(vlist_t *a, int varIDA, vlist_t *b, int varIDB, int attnum)
 }
 
 
-static
-int cdiAttGetSize(vlist_t *vlistptr, int varID, int attnum, void *context)
+static int
+vlistAttGetSize(vlist_t *vlistptr, int varID, int attnum, void *context)
 {
   cdi_atts_t *attsp;
   cdi_att_t *attp;
@@ -66325,31 +65914,30 @@ int cdiAttGetSize(vlist_t *vlistptr, int varID, int attnum, void *context)
   xassert(attsp = get_attsp(vlistptr, varID));
   xassert(attnum >= 0 && attnum < (int)attsp->nelems);
   attp = &(attsp->value[attnum]);
-  int txsize = serializeGetSize(cdi_att_nints, CDI_DATATYPE_INT, context)
-    + serializeGetSize((int)attp->namesz, CDI_DATATYPE_TXT, context);
-  txsize += serializeGetSize((int)attp->nelems, cdiAttTypeLookup(attp), context);
+  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;
 }
 
-
-int cdiAttsGetSize(void *vp, int varID, void *context)
+int
+vlistAttsGetSize(vlist_t *p, int varID, void *context)
 {
-  vlist_t *p = (vlist_t*) vp;
   cdi_atts_t *attsp = get_attsp(p, varID);
-  int txsize = serializeGetSize(1, CDI_DATATYPE_INT, context);
+  int txsize = serializeGetSize(1, DATATYPE_INT, context);
   size_t numAtts = attsp->nelems;
   for (size_t i = 0; i < numAtts; ++i)
-    txsize += cdiAttGetSize(p, varID, (int)i, context);
+    txsize += vlistAttGetSize(p, varID, (int)i, context);
   return txsize;
 }
 
-static
-void cdiAttPack(vlist_t *vlistptr, int varID, int attnum,
-                void *buf, int size, int *position, void *context)
+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[cdi_att_nints];
+  int tempbuf[vlist_att_nints];
 
   xassert(attsp = get_attsp(vlistptr, varID));
   xassert(attnum >= 0 && attnum < (int)attsp->nelems);
@@ -66358,49 +65946,50 @@ void cdiAttPack(vlist_t *vlistptr, int varID, int attnum,
   tempbuf[1] = attp->exdtype;
   tempbuf[2] = attp->indtype;
   tempbuf[3] = (int)attp->nelems;
-  serializePack(tempbuf, cdi_att_nints, CDI_DATATYPE_INT, buf, size, position, context);
-  serializePack(attp->name, (int)attp->namesz, CDI_DATATYPE_TXT, buf, size, position, context);
-  serializePack(attp->xvalue, (int)attp->nelems, cdiAttTypeLookup(attp),
+  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);
 }
 
-
-void cdiAttsPack(void *vp, int varID, void *buf, int size, int *position, void *context)
+void
+vlistAttsPack(vlist_t *p, int varID,
+              void * buf, int size, int *position, void *context)
 {
-  vlist_t *p = (vlist_t*) vp;
   cdi_atts_t *attsp = get_attsp(p, varID);
   size_t numAtts = attsp->nelems;
   int numAttsI = (int)numAtts;
   xassert(numAtts <= INT_MAX);
-  serializePack(&numAttsI, 1, CDI_DATATYPE_INT, buf, size, position, context);
+  serializePack(&numAttsI, 1, DATATYPE_INT, buf, size, position, context);
   for (size_t i = 0; i < numAtts; ++i)
-    cdiAttPack(p, varID, (int)i, buf, size, position, context);
+    vlistAttPack(p, varID, (int)i, buf, size, position, context);
 }
 
-static
-void cdiAttUnpack(int cdiID, int varID, void *buf, int size, int *position, void *context)
+static void
+vlistAttUnpack(int vlistID, int varID,
+               void * buf, int size, int *position, void *context)
 {
-  int tempbuf[cdi_att_nints];
+  int tempbuf[vlist_att_nints];
 
   serializeUnpack(buf, size, position,
-                  tempbuf, cdi_att_nints, CDI_DATATYPE_INT, context);
+                  tempbuf, vlist_att_nints, DATATYPE_INT, context);
   char *attName = (char *) Malloc((size_t)tempbuf[0] + 1);
-  serializeUnpack(buf, size, position, attName, tempbuf[0], CDI_DATATYPE_TXT, context);
+  serializeUnpack(buf, size, position, attName, tempbuf[0], DATATYPE_TXT, context);
   attName[tempbuf[0]] = '\0';
   int attVDt;
   size_t elemSize;
   switch (tempbuf[2])
   {
-  case CDI_DATATYPE_FLT:
-    attVDt = CDI_DATATYPE_FLT64;
+  case DATATYPE_FLT:
+    attVDt = DATATYPE_FLT64;
     elemSize = sizeof(double);
     break;
-  case CDI_DATATYPE_INT:
-    attVDt = CDI_DATATYPE_INT;
+  case DATATYPE_INT:
+    attVDt = DATATYPE_INT;
     elemSize = sizeof(int);
     break;
-  case CDI_DATATYPE_TXT:
-    attVDt = CDI_DATATYPE_TXT;
+  case DATATYPE_TXT:
+    attVDt = DATATYPE_TXT;
     elemSize = 1;
     break;
   default:
@@ -66409,19 +65998,22 @@ void cdiAttUnpack(int cdiID, int varID, void *buf, int size, int *position, void
   }
   void *attData = (void *) Malloc(elemSize * (size_t)tempbuf[3]);
   serializeUnpack(buf, size, position, attData, tempbuf[3], attVDt, context);
-  cdi_def_att(tempbuf[2], tempbuf[1], cdiID, varID, attName,
-              (size_t)tempbuf[3], (size_t)tempbuf[3] * elemSize, attData);
+  vlist_def_att(tempbuf[2], tempbuf[1], vlistID, varID, attName,
+                (size_t)tempbuf[3], (size_t)tempbuf[3] * elemSize, attData);
   Free(attName);
   Free(attData);
 }
 
-
-void cdiAttsUnpack(int cdiID, int varID, void *buf, int size, int *position, void *context)
+void
+vlistAttsUnpack(int vlistID, int varID,
+                void * buf, int size, int *position, void *context)
 {
-  int numAtts;
-  serializeUnpack(buf, size, position, &numAtts, 1, CDI_DATATYPE_INT, context);
-  for ( int i = 0; i < numAtts; ++i )
-    cdiAttUnpack(cdiID, varID, buf, size, position, 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);
+  }
 }
 
 /*
@@ -66467,7 +66059,7 @@ void vlistvarInitEntry(int vlistID, int varID)
   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].missvalused   = FALSE;
   vlistptr->vars[varID].missval       = cdiDefaultMissval;
   vlistptr->vars[varID].addoffset     = 0.0;
   vlistptr->vars[varID].scalefactor   = 1.0;
@@ -66477,11 +66069,11 @@ void vlistvarInitEntry(int vlistID, int varID)
   vlistptr->vars[varID].units         = NULL;
   vlistptr->vars[varID].extra         = NULL;
   vlistptr->vars[varID].levinfo       = NULL;
-  vlistptr->vars[varID].comptype      = CDI_COMPRESS_NONE;
+  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   = false;
+  vlistptr->vars[varID].lvalidrange   = 0;
   vlistptr->vars[varID].validrange[0] = VALIDMISS;
   vlistptr->vars[varID].validrange[1] = VALIDMISS;
   vlistptr->vars[varID].ensdata       = NULL;
@@ -66491,13 +66083,18 @@ void vlistvarInitEntry(int vlistID, int varID)
   vlistptr->vars[varID].opt_grib_nentries    = 0;
 }
 
+
+
 static
 int vlistvarNewEntry(int vlistID)
 {
   int varID = 0;
+  int vlistvarSize;
+  var_t *vlistvar;
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  int vlistvarSize = vlistptr->varsAllocated;
-  var_t *vlistvar = vlistptr->vars;
+
+  vlistvarSize = vlistptr->varsAllocated;
+  vlistvar     = vlistptr->vars;
   /*
     Look for a free slot in vlistvar.
     (Create the table the first time through).
@@ -66506,8 +66103,8 @@ int vlistvarNewEntry(int vlistID)
     {
       vlistvarSize = 2;
       vlistvar = (var_t *) Malloc((size_t)vlistvarSize * sizeof (var_t));
-      for ( int i = 0; i < vlistvarSize; i++ )
-	vlistvar[i].isUsed = false;
+      for (int i = 0; i < vlistvarSize; i++ )
+	vlistvar[i].isUsed = FALSE;
     }
   else
     {
@@ -66522,7 +66119,7 @@ int vlistvarNewEntry(int vlistID)
       vlistvar = (var_t *) Realloc(vlistvar,
                                    (size_t)(vlistvarSize *= 2) * sizeof(var_t));
       for ( int i = varID; i < vlistvarSize; i++ )
-	vlistvar[i].isUsed = false;
+	vlistvar[i].isUsed = FALSE;
     }
 
   vlistptr->varsAllocated = vlistvarSize;
@@ -66530,9 +66127,9 @@ int vlistvarNewEntry(int vlistID)
 
   vlistvarInitEntry(vlistID, varID);
 
-  vlistptr->vars[varID].isUsed = true;
+  vlistptr->vars[varID].isUsed = TRUE;
 
-  return varID;
+  return (varID);
 }
 
 void vlistCheckVarID(const char *caller, int vlistID, int varID)
@@ -66552,12 +66149,12 @@ void vlistCheckVarID(const char *caller, int vlistID, int varID)
 
 int vlistDefVarTiles(int vlistID, int gridID, int zaxisID, int tsteptype, int tilesetID)
 {
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
   if ( CDI_Debug )
     Message("gridID = %d  zaxisID = %d  tsteptype = %d", gridID, zaxisID, tsteptype);
 
   int varID = vlistvarNewEntry(vlistID);
 
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
   vlistptr->nvars++;
   vlistptr->vars[varID].gridID    = gridID;
   vlistptr->vars[varID].zaxisID   = zaxisID;
@@ -66576,8 +66173,7 @@ int vlistDefVarTiles(int vlistID, int gridID, int zaxisID, int tsteptype, int ti
 
   vlistptr->vars[varID].param = cdiEncodeParam(-(varID + 1), 255, 255);
   reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
-
-  return varID;
+  return (varID);
 }
 
 /*
@@ -66735,7 +66331,7 @@ int vlistInqVarGrid(int vlistID, int varID)
 
   vlistCheckVarID(__func__, vlistID, varID);
 
-  return vlistptr->vars[varID].gridID;
+  return (vlistptr->vars[varID].gridID);
 }
 
 /*
@@ -66761,7 +66357,7 @@ int vlistInqVarZaxis(int vlistID, int varID)
 
   vlistCheckVarID(__func__, vlistID, varID);
 
-  return vlistptr->vars[varID].zaxisID;
+  return (vlistptr->vars[varID].zaxisID);
 }
 
 
@@ -66782,8 +66378,7 @@ int vlistInqVarSubtype(int vlistID, int varID)
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
   vlistCheckVarID(__func__, vlistID, varID);
-
-  return vlistptr->vars[varID].subtypeID;
+  return (vlistptr->vars[varID].subtypeID);
 }
 
 
@@ -66810,7 +66405,7 @@ int vlistInqVarParam(int vlistID, int varID)
 
   vlistCheckVarID(__func__, vlistID, varID);
 
-  return vlistptr->vars[varID].param;
+  return (vlistptr->vars[varID].param);
 }
 
 /*
@@ -66847,7 +66442,7 @@ int vlistInqVarCode(int vlistID, int varID)
       tableInqParCode(vlistptr->vars[varID].tableID, vlistptr->vars[varID].name, &code);
     }
 
-  return code;
+  return (code);
 }
 
 
@@ -66857,7 +66452,7 @@ const char *vlistInqVarNamePtr(int vlistID, int varID)
 
   vlistCheckVarID(__func__, vlistID, varID);
 
-  return vlistptr->vars[varID].name;
+  return (vlistptr->vars[varID].name);
 }
 
 
@@ -66867,7 +66462,7 @@ const char *vlistInqVarLongnamePtr(int vlistID, int varID)
 
   vlistCheckVarID(__func__, vlistID, varID);
 
-  return vlistptr->vars[varID].longname;
+  return (vlistptr->vars[varID].longname);
 }
 
 
@@ -66877,7 +66472,7 @@ const char *vlistInqVarStdnamePtr(int vlistID, int varID)
 
   vlistCheckVarID(__func__, vlistID, varID);
 
-  return vlistptr->vars[varID].stdname;
+  return (vlistptr->vars[varID].stdname);
 }
 
 
@@ -66887,7 +66482,7 @@ const char *vlistInqVarUnitsPtr(int vlistID, int varID)
 
   vlistCheckVarID(__func__, vlistID, varID);
 
-  return vlistptr->vars[varID].units;
+  return (vlistptr->vars[varID].units);
 }
 
 /*
@@ -67134,10 +66729,10 @@ int vlistInqVarID(int vlistID, int code)
       int param = vlistptr->vars[varID].param;
       int pdis, pcat, pnum;
       cdiDecodeParam(param, &pnum, &pcat, &pdis);
-      if ( pnum == code ) return varID;
+      if ( pnum == code ) return (varID);
     }
 
-  return CDI_UNDEFID;
+  return (CDI_UNDEFID);
 }
 
 
@@ -67145,7 +66740,8 @@ int vlistInqVarSize(int vlistID, int varID)
 {
   vlistCheckVarID(__func__, vlistID, varID);
 
-  int zaxisID, gridID, tsteptype;
+  int zaxisID, gridID;
+  int tsteptype;
   vlistInqVar(vlistID, varID, &gridID, &zaxisID, &tsteptype);
 
   int nlevs = zaxisInqSize(zaxisID);
@@ -67154,7 +66750,7 @@ int vlistInqVarSize(int vlistID, int varID)
 
   int size = gridsize*nlevs;
 
-  return size;
+  return (size);
 }
 
 /*
@@ -67171,9 +66767,9 @@ The function @func{vlistInqVarDatatype} returns the data type of a variable.
 
 @Result
 @func{vlistInqVarDatatype} returns an identifier to the data type of the variable.
-The valid CDI data types are @func{CDI_DATATYPE_PACK8}, @func{CDI_DATATYPE_PACK16}, @func{CDI_DATATYPE_PACK24},
- at func{CDI_DATATYPE_FLT32}, @func{CDI_DATATYPE_FLT64}, @func{CDI_DATATYPE_INT8}, @func{CDI_DATATYPE_INT16} and 
- at func{CDI_DATATYPE_INT32}.
+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}.
 
 @EndFunction
 */
@@ -67183,7 +66779,7 @@ int vlistInqVarDatatype(int vlistID, int varID)
 
   vlistCheckVarID(__func__, vlistID, varID);
 
-  return vlistptr->vars[varID].datatype;
+  return (vlistptr->vars[varID].datatype);
 }
 
 
@@ -67194,11 +66790,11 @@ int vlistInqVarNumber(int vlistID, int varID)
   vlistCheckVarID(__func__, vlistID, varID);
 
   int number = CDI_REAL;
-  if ( vlistptr->vars[varID].datatype == CDI_DATATYPE_CPX32 ||
-       vlistptr->vars[varID].datatype == CDI_DATATYPE_CPX64 )
+  if ( vlistptr->vars[varID].datatype == DATATYPE_CPX32 ||
+       vlistptr->vars[varID].datatype == DATATYPE_CPX64 )
     number = CDI_COMP;
 
-  return number;
+  return (number);
 }
 
 /*
@@ -67210,9 +66806,9 @@ int vlistInqVarNumber(int vlistID, int varID)
     @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{CDI_DATATYPE_PACK8}, @func{CDI_DATATYPE_PACK16},
-                    @func{CDI_DATATYPE_PACK24}, @func{CDI_DATATYPE_FLT32}, @func{CDI_DATATYPE_FLT64},
-                    @func{CDI_DATATYPE_INT8}, @func{CDI_DATATYPE_INT16} and @func{CDI_DATATYPE_INT32}.
+                    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}.
 
 @Description
 The function @func{vlistDefVarDatatype} defines the data type of a variable.
@@ -67229,15 +66825,15 @@ void vlistDefVarDatatype(int vlistID, int varID, int datatype)
     {
       vlistptr->vars[varID].datatype = datatype;
 
-      if ( !vlistptr->vars[varID].missvalused )
+      if ( vlistptr->vars[varID].missvalused == FALSE )
         switch (datatype)
           {
-          case CDI_DATATYPE_INT8:   vlistptr->vars[varID].missval = -SCHAR_MAX; break;
-          case CDI_DATATYPE_UINT8:  vlistptr->vars[varID].missval =  UCHAR_MAX; break;
-          case CDI_DATATYPE_INT16:  vlistptr->vars[varID].missval = -SHRT_MAX;  break;
-          case CDI_DATATYPE_UINT16: vlistptr->vars[varID].missval =  USHRT_MAX; break;
-          case CDI_DATATYPE_INT32:  vlistptr->vars[varID].missval = -INT_MAX;   break;
-          case CDI_DATATYPE_UINT32: vlistptr->vars[varID].missval =  UINT_MAX;  break;
+          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);
     }
@@ -67258,7 +66854,7 @@ void vlistDefVarInstitut(int vlistID, int varID, int instID)
 int vlistInqVarInstitut(int vlistID, int varID)
 {
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  return vlistptr->vars[varID].instID;
+  return (vlistptr->vars[varID].instID);
 }
 
 
@@ -67276,7 +66872,7 @@ void vlistDefVarModel(int vlistID, int varID, int modelID)
 int vlistInqVarModel(int vlistID, int varID)
 {
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  return vlistptr->vars[varID].modelID;
+  return (vlistptr->vars[varID].modelID);
 }
 
 
@@ -67302,7 +66898,7 @@ void vlistDefVarTable(int vlistID, int varID, int tableID)
 int vlistInqVarTable(int vlistID, int varID)
 {
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  return vlistptr->vars[varID].tableID;
+  return (vlistptr->vars[varID].tableID);
 }
 
 /*
@@ -67464,7 +67060,7 @@ double vlistInqVarMissval(int vlistID, int varID)
 
   vlistCheckVarID(__func__, vlistID, varID);
 
-  return vlistptr->vars[varID].missval;
+  return (vlistptr->vars[varID].missval);
 }
 
 /*
@@ -67489,7 +67085,7 @@ void vlistDefVarMissval(int vlistID, int varID, double missval)
   vlistCheckVarID(__func__, vlistID, varID);
 
   vlistptr->vars[varID].missval = missval;
-  vlistptr->vars[varID].missvalused = true;
+  vlistptr->vars[varID].missvalused = TRUE;
 }
 
 /*
@@ -67574,7 +67170,7 @@ int vlistInqVarValidrange(int vlistID, int varID, double *validrange)
       validrange[1] = vlistptr->vars[varID].validrange[1];
     }
 
-  return (int)vlistptr->vars[varID].lvalidrange;
+  return (vlistptr->vars[varID].lvalidrange);
 }
 
 
@@ -67586,7 +67182,7 @@ void vlistDefVarValidrange(int vlistID, int varID, const double *validrange)
 
   vlistptr->vars[varID].validrange[0] = validrange[0];
   vlistptr->vars[varID].validrange[1] = validrange[1];
-  vlistptr->vars[varID].lvalidrange = true;
+  vlistptr->vars[varID].lvalidrange = TRUE;
   reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
 }
 
@@ -67597,7 +67193,7 @@ double vlistInqVarScalefactor(int vlistID, int varID)
 
   vlistCheckVarID(__func__, vlistID, varID);
 
-  return vlistptr->vars[varID].scalefactor;
+  return (vlistptr->vars[varID].scalefactor);
 }
 
 
@@ -67607,7 +67203,7 @@ double vlistInqVarAddoffset(int vlistID, int varID)
 
   vlistCheckVarID(__func__, vlistID, varID);
 
-  return vlistptr->vars[varID].addoffset;
+  return (vlistptr->vars[varID].addoffset);
 }
 
 
@@ -67672,7 +67268,7 @@ The valid CDI timestep types are @func{TSTEP_CONSTANT}, @func{TSTEP_INSTANT},
 int vlistInqVarTsteptype(int vlistID, int varID)
 {
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  return vlistptr->vars[varID].tsteptype;
+  return (vlistptr->vars[varID].tsteptype);
 }
 
 
@@ -67690,7 +67286,7 @@ void vlistDefVarTimave(int vlistID, int varID, int timave)
 int vlistInqVarTimave(int vlistID, int varID)
 {
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  return vlistptr->vars[varID].timave;
+  return (vlistptr->vars[varID].timave);
 }
 
 
@@ -67708,7 +67304,7 @@ void vlistDefVarTimaccu(int vlistID, int varID, int timaccu)
 int vlistInqVarTimaccu(int vlistID, int varID)
 {
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  return vlistptr->vars[varID].timaccu;
+  return (vlistptr->vars[varID].timaccu);
 }
 
 
@@ -67726,7 +67322,7 @@ void vlistDefVarTypeOfGeneratingProcess(int vlistID, int varID, int typeOfGenera
 int vlistInqVarTypeOfGeneratingProcess(int vlistID, int varID)
 {
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  return vlistptr->vars[varID].typeOfGeneratingProcess;
+  return (vlistptr->vars[varID].typeOfGeneratingProcess);
 }
 
 
@@ -67745,7 +67341,8 @@ void vlistDefVarProductDefinitionTemplate(int vlistID, int varID, int productDef
 int vlistInqVarProductDefinitionTemplate(int vlistID, int varID)
 {
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  return vlistptr->vars[varID].productDefinitionTemplate;
+
+  return (vlistptr->vars[varID].productDefinitionTemplate);
 }
 
 
@@ -67803,7 +67400,7 @@ void vlistDestroyVarUnits(int vlistID, int varID)
 int vlistInqVarMissvalUsed(int vlistID, int varID)
 {
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  return (int)vlistptr->vars[varID].missvalused;
+  return (vlistptr->vars[varID].missvalused);
 }
 
 
@@ -67842,7 +67439,7 @@ int vlistInqFlag(int vlistID, int varID, int levID)
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
   if (vlistptr->vars[varID].levinfo)
-    return vlistptr->vars[varID].levinfo[levID].flag;
+    return (vlistptr->vars[varID].levinfo[levID].flag);
   else
     {
       levinfo_t li = DEFAULT_LEVINFO(levID);
@@ -67867,7 +67464,7 @@ int vlistFindVar(int vlistID, int fvarID)
       Message("varID not found for fvarID %d in vlistID %d!", fvarID, vlistID);
     }
 
-  return varID;
+  return (varID);
 }
 
 
@@ -67894,14 +67491,14 @@ int vlistFindLevel(int vlistID, int fvarID, int flevelID)
 	}
     }
 
-  return levelID;
+  return (levelID);
 }
 
 
 int vlistMergedVar(int vlistID, int varID)
 {
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
-  return vlistptr->vars[varID].mvarID;
+  return (vlistptr->vars[varID].mvarID);
 }
 
 
@@ -67940,7 +67537,7 @@ int vlistInqIndex(int vlistID, int varID, int levelID)
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
   if (vlistptr->vars[varID].levinfo)
-    return vlistptr->vars[varID].levinfo[levelID].index;
+    return (vlistptr->vars[varID].levinfo[levelID].index);
   else
     {
       levinfo_t li = DEFAULT_LEVINFO(levelID);
@@ -68029,7 +67626,7 @@ int vlistInqVarCompType(int vlistID, int varID)
 
   vlistCheckVarID(__func__, vlistID, varID);
 
-  return vlistptr->vars[varID].comptype;
+  return (vlistptr->vars[varID].comptype);
 }
 
 
@@ -68053,7 +67650,7 @@ int vlistInqVarCompLevel(int vlistID, int varID)
 
   vlistCheckVarID(__func__, vlistID, varID);
 
-  return vlistptr->vars[varID].complevel;
+  return (vlistptr->vars[varID].complevel);
 }
 
 
@@ -68077,7 +67674,7 @@ int vlistInqVarChunkType(int vlistID, int varID)
 
   vlistCheckVarID(__func__, vlistID, varID);
 
-  return vlistptr->vars[varID].chunktype;
+  return (vlistptr->vars[varID].chunktype);
 }
 
 static
@@ -68138,7 +67735,9 @@ void  vlistDefVarXYZ(int vlistID, int varID, int xyz)
 
 void vlistInqVarDimorder(int vlistID, int varID, int (*outDimorder)[3])
 {
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  vlist_t *vlistptr;
+
+  vlistptr = vlist_to_pointer(vlistID);
 
   vlistCheckVarID(__func__, vlistID, varID);
 
@@ -68152,7 +67751,7 @@ int vlistInqVarXYZ(int vlistID, int varID)
 
   vlistCheckVarID(__func__, vlistID, varID);
 
-  return vlistptr->vars[varID].xyz;
+  return (vlistptr->vars[varID].xyz);
 }
 
 /* Ensemble Info Routines */
@@ -68189,7 +67788,7 @@ int vlistInqVarEnsemble( int vlistID, int varID, int *ensID, int *ensCount, int
       status = 1;
     }
 
-  return status;
+  return (status);
 }
 
 
@@ -68214,7 +67813,7 @@ void vlistDefVarIntKey(int vlistID, int varID, const char *name, int value)
   if ( idx < vlistptr->vars[varID].opt_grib_nentries )
     {
       vlistptr->vars[varID].opt_grib_kvpair[idx].int_val = value;
-      vlistptr->vars[varID].opt_grib_kvpair[idx].update  = true;
+      vlistptr->vars[varID].opt_grib_kvpair[idx].update  = TRUE;
     }
   else
     {
@@ -68223,7 +67822,7 @@ void vlistDefVarIntKey(int vlistID, int varID, const char *name, int value)
       idx = vlistptr->vars[varID].opt_grib_nentries -1;
       vlistptr->vars[varID].opt_grib_kvpair[idx].data_type   = t_int;
       vlistptr->vars[varID].opt_grib_kvpair[idx].int_val     = value;
-      vlistptr->vars[varID].opt_grib_kvpair[idx].update      = true;
+      vlistptr->vars[varID].opt_grib_kvpair[idx].update      = TRUE;
       if ( name )
         vlistptr->vars[varID].opt_grib_kvpair[idx].keyword = strdupx(name);
       else
@@ -68277,7 +67876,7 @@ void vlistDefVarDblKey(int vlistID, int varID, const char *name, double value)
   if ( idx < vlistptr->vars[varID].opt_grib_nentries )
     {
       vlistptr->vars[varID].opt_grib_kvpair[idx].dbl_val = value;
-      vlistptr->vars[varID].opt_grib_kvpair[idx].update  = true;
+      vlistptr->vars[varID].opt_grib_kvpair[idx].update  = TRUE;
     }
   else
     {
@@ -68286,7 +67885,7 @@ void vlistDefVarDblKey(int vlistID, int varID, const char *name, double value)
       idx = vlistptr->vars[varID].opt_grib_nentries - 1;
       vlistptr->vars[varID].opt_grib_kvpair[idx].data_type = t_double;
       vlistptr->vars[varID].opt_grib_kvpair[idx].dbl_val   = value;
-      vlistptr->vars[varID].opt_grib_kvpair[idx].update    = true;
+      vlistptr->vars[varID].opt_grib_kvpair[idx].update    = TRUE;
       if ( name )
         vlistptr->vars[varID].opt_grib_kvpair[idx].keyword = strdupx(name);
       else
@@ -68419,7 +68018,7 @@ int vlistInqVarIntKey(int vlistID, int varID, const char* name)
 
 void vlistDefVarIOrank(int vlistID, int varID, int iorank)
 {
-  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  vlist_t *vlistptr = vlist_to_pointer(vlistID );
 
   vlistCheckVarID ( __func__, vlistID, varID );
 
@@ -68479,7 +68078,7 @@ int vlistVarCompare(vlist_t *a, int varIDA, vlist_t *b, int varIDB)
   if (natts != b->vars[varIDB].atts.nelems)
     return 1;
   for (size_t attID = 0; attID < natts; ++attID)
-    diff |= cdi_att_compare(a, varIDA, b, varIDB, (int)attID);
+    diff |= vlist_att_compare(a, varIDA, b, varIDB, (int)attID);
   if ((diff |= ((pva->ensdata == NULL) ^ (pvb->ensdata == NULL))))
     return 1;
   if (pva->ensdata)
@@ -68497,21 +68096,21 @@ enum {
 int vlistVarGetPackSize(vlist_t *p, int varID, void *context)
 {
   var_t *var = p->vars + varID;
-  int varsize = serializeGetSize(vlistvar_nints, CDI_DATATYPE_INT, context)
-    + serializeGetSize(vlistvar_ndbls, CDI_DATATYPE_FLT64, context);
+  int varsize = serializeGetSize(vlistvar_nints, DATATYPE_INT, context)
+    + serializeGetSize(vlistvar_ndbls, DATATYPE_FLT64, context);
   if (var->name)
-    varsize += serializeGetSize((int)strlen(var->name), CDI_DATATYPE_TXT, context);
+    varsize += serializeGetSize((int)strlen(var->name), DATATYPE_TXT, context);
   if (var->longname)
-    varsize += serializeGetSize((int)strlen(var->longname), CDI_DATATYPE_TXT, context);
+    varsize += serializeGetSize((int)strlen(var->longname), DATATYPE_TXT, context);
   if (var->stdname)
-    varsize += serializeGetSize((int)strlen(var->stdname), CDI_DATATYPE_TXT, context);
+    varsize += serializeGetSize((int)strlen(var->stdname), DATATYPE_TXT, context);
   if (var->units)
-    varsize += serializeGetSize((int)strlen(var->units), CDI_DATATYPE_TXT, context);
+    varsize += serializeGetSize((int)strlen(var->units), DATATYPE_TXT, context);
   if (var->extra)
-    varsize += serializeGetSize((int)strlen(var->extra), CDI_DATATYPE_TXT, context);
+    varsize += serializeGetSize((int)strlen(var->extra), DATATYPE_TXT, context);
   varsize += serializeGetSize(4 * zaxisInqSize(var->zaxisID),
-                              CDI_DATATYPE_INT, context);
-  varsize += cdiAttsGetSize(p, varID, context);
+                              DATATYPE_INT, context);
+  varsize += vlistAttsGetSize(p, varID, context);
   return varsize;
 }
 
@@ -68538,7 +68137,7 @@ void vlistVarPack(vlist_t *p, int varID, char * buf, int size, int *position,
   tempbuf[12] = var->tableID;
   tempbuf[13] = var->timave;
   tempbuf[14] = var->timaccu;
-  tempbuf[15] = (int)var->missvalused;
+  tempbuf[15] = var->missvalused;
   tempbuf[16] = var->comptype;
   tempbuf[17] = var->complevel;
   int nlevs = var->levinfo ? zaxisInqSize(var->zaxisID) : 0;
@@ -68548,23 +68147,23 @@ void vlistVarPack(vlist_t *p, int varID, char * buf, int size, int *position,
   dtempbuf[0] = var->missval;
   dtempbuf[1] = var->scalefactor;
   dtempbuf[2] = var->addoffset;
-  serializePack(tempbuf, vlistvar_nints, CDI_DATATYPE_INT,
+  serializePack(tempbuf, vlistvar_nints, DATATYPE_INT,
                 buf, size, position, context);
-  serializePack(dtempbuf, vlistvar_ndbls, CDI_DATATYPE_FLT64,
+  serializePack(dtempbuf, vlistvar_ndbls, DATATYPE_FLT64,
                 buf, size, position, context);
   if (namesz)
-    serializePack(var->name, namesz, CDI_DATATYPE_TXT, buf, size, position, context);
+    serializePack(var->name, namesz, DATATYPE_TXT, buf, size, position, context);
   if (longnamesz)
-    serializePack(var->longname, longnamesz, CDI_DATATYPE_TXT,
+    serializePack(var->longname, longnamesz, DATATYPE_TXT,
                   buf, size, position, context);
   if (stdnamesz)
-    serializePack(var->stdname, stdnamesz, CDI_DATATYPE_TXT,
+    serializePack(var->stdname, stdnamesz, DATATYPE_TXT,
                   buf, size, position, context);
   if (unitssz)
-    serializePack(var->units, unitssz, CDI_DATATYPE_TXT,
+    serializePack(var->units, unitssz, DATATYPE_TXT,
                   buf, size, position, context);
   if (extralen)
-    serializePack(var->extra, extralen, CDI_DATATYPE_TXT,
+    serializePack(var->extra, extralen, DATATYPE_TXT,
                   buf, size, position, context);
   if (nlevs)
     {
@@ -68576,10 +68175,10 @@ void vlistVarPack(vlist_t *p, int varID, char * buf, int size, int *position,
           levbuf[levID][2] = var->levinfo[levID].mlevelID;
           levbuf[levID][3] = var->levinfo[levID].flevelID;
         }
-      serializePack(levbuf, nlevs * 4, CDI_DATATYPE_INT,
+      serializePack(levbuf, nlevs * 4, DATATYPE_INT,
                     buf, size, position, context);
     }
-  cdiAttsPack(p, varID, buf, size, position, context);
+  vlistAttsPack(p, varID, buf, size, position, context);
 }
 
 static inline int
@@ -68597,9 +68196,9 @@ void vlistVarUnpack(int vlistID, char * buf, int size, int *position,
   char *varname = NULL;
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
   serializeUnpack(buf, size, position,
-                  tempbuf, vlistvar_nints, CDI_DATATYPE_INT, context);
+                  tempbuf, vlistvar_nints, DATATYPE_INT, context);
   serializeUnpack(buf, size, position,
-                  dtempbuf, vlistvar_ndbls, CDI_DATATYPE_FLT64, context);
+                  dtempbuf, vlistvar_ndbls, DATATYPE_FLT64, context);
 
   /* ------------------------------------------- */
   /* NOTE: Tile sets  currently not supported!!! */
@@ -68617,35 +68216,35 @@ void vlistVarUnpack(int vlistID, char * buf, int size, int *position,
   if (tempbuf[4])
   {
     serializeUnpack(buf, size, position,
-                    varname, tempbuf[4], CDI_DATATYPE_TXT, context);
+                    varname, tempbuf[4], DATATYPE_TXT, context);
     varname[tempbuf[4]] = '\0';
     vlistDefVarName(vlistID, newvar, varname);
   }
   if (tempbuf[5])
   {
     serializeUnpack(buf, size, position,
-                    varname, tempbuf[5], CDI_DATATYPE_TXT, context);
+                    varname, tempbuf[5], DATATYPE_TXT, context);
     varname[tempbuf[5]] = '\0';
     vlistDefVarLongname(vlistID, newvar, varname);
   }
   if (tempbuf[6])
   {
     serializeUnpack(buf, size, position,
-                    varname, tempbuf[6], CDI_DATATYPE_TXT, context);
+                    varname, tempbuf[6], DATATYPE_TXT, context);
     varname[tempbuf[6]] = '\0';
     vlistDefVarStdname(vlistID, newvar, varname);
   }
   if (tempbuf[7])
   {
     serializeUnpack(buf, size, position,
-                    varname, tempbuf[7], CDI_DATATYPE_TXT, context);
+                    varname, tempbuf[7], DATATYPE_TXT, context);
     varname[tempbuf[7]] = '\0';
     vlistDefVarUnits(vlistID, newvar, varname);
   }
   if (tempbuf[20])
     {
       serializeUnpack(buf, size, position,
-                      varname, tempbuf[20], CDI_DATATYPE_TXT, context);
+                      varname, tempbuf[20], DATATYPE_TXT, context);
       varname[tempbuf[20]] = '\0';
       vlistDefVarExtra(vlistID, newvar, varname);
     }
@@ -68674,7 +68273,7 @@ void vlistVarUnpack(int vlistID, char * buf, int size, int *position,
       int i, flagSetLev = 0;
       cdiVlistCreateVarLevInfo(vlistptr, newvar);
       serializeUnpack(buf, size, position,
-                      levbuf, nlevs * 4, CDI_DATATYPE_INT, context);
+                      levbuf, nlevs * 4, DATATYPE_INT, context);
       for (i = 0; i < nlevs; ++i)
         {
           vlistDefFlag(vlistID, newvar, i, levbuf[i][0]);
@@ -68688,7 +68287,7 @@ void vlistVarUnpack(int vlistID, char * buf, int size, int *position,
       vlistDefFlag(vlistID, newvar, flagSetLev, levbuf[flagSetLev][0]);
     }
   vlistDefVarIOrank(vlistID, newvar, tempbuf[19]);
-  cdiAttsUnpack(vlistID, newvar, buf, size, position, context);
+  vlistAttsUnpack(vlistID, newvar, buf, size, position, context);
 }
 
 
@@ -68723,10 +68322,10 @@ static const struct {
 }
 ZaxistypeEntry[] = {
   { /*  0 */ 0, "sfc",               "surface",                "",               ""},
-  { /*  1 */ 0, "lev",               "generic",                "",               ""},
+  { /*  1 */ 0, "lev",               "generic",                "",               "level"},
   { /*  2 */ 2, "lev",               "hybrid",                 "",               "level"},
   { /*  3 */ 2, "lev",               "hybrid_half",            "",               "level"},
-  { /*  4 */ 2, "plev",              "pressure",               "air_pressure",   "Pa"},
+  { /*  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"},
@@ -68748,7 +68347,6 @@ ZaxistypeEntry[] = {
   { /* 23 */ 0, "sedimentbottomtw",  "sediment_bottom_tw",     "",               ""},
   { /* 24 */ 0, "mixlayer",          "mix_layer",              "",               ""},
   { /* 25 */ 0, "height",            "generalized_height",     "height",         ""},
-  { /* 26 */ 0, "character",         "area_type",              "",               ""},
 };
 
 enum {
@@ -68756,6 +68354,35 @@ enum {
 };
 
 
+typedef struct {
+  char     dimname[CDI_MAX_NAME];
+  char     vdimname[CDI_MAX_NAME];
+  char     name[CDI_MAX_NAME];
+  char     longname[CDI_MAX_NAME];
+  char     stdname[CDI_MAX_NAME];
+  char     units[CDI_MAX_NAME];
+  char     psname[CDI_MAX_NAME];
+  double  *vals;
+  double  *lbounds;
+  double  *ubounds;
+  double  *weights;
+  int      self;
+  int      prec;
+  int      scalar;
+  int      type;
+  int      ltype;    /* GRIB level type */
+  int      ltype2;
+  int      size;
+  int      direction;
+  int      vctsize;
+  unsigned positive;
+  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 );
@@ -68779,75 +68406,65 @@ const resOps *getZaxisOps(void)
 
 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)
+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(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;
+      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;
+      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;
     }
 }
 
-
-zaxis_t *zaxis_to_pointer(int id)
-{
-  return (zaxis_t *)reshGetVal(id, &zaxisOps);
-}
-
 static
-void zaxis_init(zaxis_t *zaxisptr)
-{
-  zaxisptr->self          = CDI_UNDEFID;
-  zaxisptr->name[0]       = 0;
-  zaxisptr->longname[0]   = 0;
-  zaxisptr->stdname[0]    = 0;
-  zaxisptr->dimname[0]    = 0;
-  zaxisptr->vdimname[0]   = 0;
-  zaxisptr->units[0]      = 0;
-  zaxisptr->psname[0]     = 0;
-  zaxisptr->p0name[0]     = 0;
-  zaxisptr->p0value.defined = false;
-  zaxisptr->vals          = NULL;
-  zaxisptr->cvals         = NULL;
-  zaxisptr->clength       = 0;
-  zaxisptr->ubounds       = NULL;
-  zaxisptr->lbounds       = NULL;
-  zaxisptr->weights       = NULL;
-  zaxisptr->type          = CDI_UNDEFID;
-  zaxisptr->ltype         = 0;
-  zaxisptr->ltype2        = -1;
-  zaxisptr->positive      = 0;
-  zaxisptr->scalar        = 0;
-  zaxisptr->direction     = 0;
-  zaxisptr->prec          = 0;
-  zaxisptr->size          = 0;
-  zaxisptr->vctsize       = 0;
-  zaxisptr->vct           = NULL;
-  zaxisptr->number        = 0;
-  zaxisptr->nhlev         = 0;
+void zaxisDefaultValue(zaxis_t *zaxisptr)
+{
+  zaxisptr->self        = CDI_UNDEFID;
+  zaxisptr->name[0]     = 0;
+  zaxisptr->longname[0] = 0;
+  zaxisptr->stdname[0]  = 0;
+  zaxisptr->dimname[0]  = 0;
+  zaxisptr->vdimname[0] = 0;
+  zaxisptr->units[0]    = 0;
+  zaxisptr->psname[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->scalar      = 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);
-  zaxisptr->atts.nalloc   = MAX_ATTRIBUTES;
-  zaxisptr->atts.nelems   = 0;
 }
 
+
 static
 zaxis_t *zaxisNewEntry(int id)
 {
   zaxis_t *zaxisptr = (zaxis_t *) Malloc(sizeof(zaxis_t));
-  zaxis_init(zaxisptr);
 
-  if ( id == CDI_UNDEFID )
+  zaxisDefaultValue ( zaxisptr );
+
+  if (id == CDI_UNDEFID)
     zaxisptr->self = reshPut(zaxisptr, &zaxisOps);
   else
     {
@@ -68855,17 +68472,27 @@ zaxis_t *zaxisNewEntry(int id)
       reshReplace(id, zaxisptr, &zaxisOps);
     }
 
-  return zaxisptr;
+  return (zaxisptr);
 }
 
+static inline zaxis_t *
+zaxisID2Ptr(int id)
+{
+  return (zaxis_t *)reshGetVal(id, &zaxisOps);
+}
+
+
 static
 void zaxisInit(void)
 {
-  static bool zaxisInitialized = false;
+  static int zaxisInitialized = 0;
+  char *env;
+
   if ( zaxisInitialized ) return;
-  zaxisInitialized = true;
 
-  const char *env = getenv("ZAXIS_DEBUG");
+  zaxisInitialized = 1;
+
+  env = getenv("ZAXIS_DEBUG");
   if ( env ) ZAXIS_Debug = atoi(env);
 }
 
@@ -68877,14 +68504,14 @@ void zaxis_copy(zaxis_t *zaxisptr2, zaxis_t *zaxisptr1)
   zaxisptr2->self = zaxisID2;
 }
 
-
 unsigned cdiZaxisCount(void)
 {
   return reshCountType(&zaxisOps);
 }
 
-static
-int zaxisCreate_(int zaxistype, int size, int id)
+
+static int
+zaxisCreate_(int zaxistype, int size, int id)
 {
   zaxis_t *zaxisptr = zaxisNewEntry(id);
 
@@ -68905,9 +68532,16 @@ int zaxisCreate_(int zaxistype, int size, int id)
 
   zaxisptr->positive = ZaxistypeEntry[zaxistype].positive;
 
+  double *vals = zaxisptr->vals
+    = (double *) Malloc((size_t)size * sizeof(double));
+
+  for ( int ilev = 0; ilev < size; ilev++ )
+    vals[ilev] = 0.0;
+
   return zaxisID;
 }
 
+
 /*
 @Function  zaxisCreate
 @Title     Create a vertical Z-axis
@@ -68949,27 +68583,21 @@ zaxisDefLevels(zaxisID, levs);
 */
 int zaxisCreate(int zaxistype, int size)
 {
-  if ( CDI_Debug ) Message("zaxistype: %d size: %d ", zaxistype, size);
-
-  zaxisInit();
+  if ( CDI_Debug )
+    Message("zaxistype: %d size: %d ", zaxistype, size);
 
+  zaxisInit ();
   return zaxisCreate_(zaxistype, size, CDI_UNDEFID);
 }
 
-static
-void zaxisDestroyKernel( zaxis_t * zaxisptr )
+
+static void zaxisDestroyKernel( zaxis_t * zaxisptr )
 {
   xassert ( zaxisptr );
 
   int id = zaxisptr->self;
 
   if ( zaxisptr->vals )    Free( zaxisptr->vals );
-  if ( zaxisptr->cvals )
-    {
-      for ( int i=0; i<zaxisptr->size; i++)
-        Free(zaxisptr->cvals[i]);
-      Free( zaxisptr->cvals );
-    }
   if ( zaxisptr->lbounds ) Free( zaxisptr->lbounds );
   if ( zaxisptr->ubounds ) Free( zaxisptr->ubounds );
   if ( zaxisptr->weights ) Free( zaxisptr->weights );
@@ -68992,15 +68620,16 @@ void zaxisDestroyKernel( zaxis_t * zaxisptr )
 */
 void zaxisDestroy(int zaxisID)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
-  zaxisDestroyKernel(zaxisptr);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+
+  zaxisDestroyKernel ( zaxisptr );
 }
 
 
 static
-void zaxisDestroyP(void *zaxisptr)
+void zaxisDestroyP ( void * zaxisptr )
 {
-  zaxisDestroyKernel((zaxis_t *) zaxisptr);
+  zaxisDestroyKernel (( zaxis_t * ) zaxisptr );
 }
 
 
@@ -69009,7 +68638,7 @@ const char *zaxisNamePtr(int zaxistype)
   const char *name = (zaxistype >= 0 && zaxistype < CDI_NumZaxistype)
     ? ZaxistypeEntry[zaxistype].longname
     : ZaxistypeEntry[ZAXIS_GENERIC].longname;
-  return name;
+  return (name);
 }
 
 
@@ -69023,44 +68652,36 @@ void zaxisSetString(char *zaxisstrname, const char *name, size_t len)
 {
   if ( len > CDI_MAX_NAME ) len = CDI_MAX_NAME;
   strncpy(zaxisstrname, name, len);
-  zaxisstrname[len-1] = 0;
+  zaxisstrname[len - 1] = 0;
 }
 
 static inline
 void zaxisGetString(char *name, const char *zaxisstrname, size_t len)
 {
-  size_t slen = strlen(zaxisstrname)+1;
-  if ( slen > len ) slen = len;
-  if ( slen > CDI_MAX_NAME ) slen = CDI_MAX_NAME;
-  strncpy(name, zaxisstrname, slen);
-  name[slen-1] = 0;
+  if ( len > CDI_MAX_NAME ) len = CDI_MAX_NAME;
+  strncpy(name, zaxisstrname, len);
+  name[len - 1] = 0;
 }
 
 static
-void *zaxis_key_to_ptr(zaxis_t *zaxisptr, int key)
+char *zaxis_key_to_string(zaxis_t *zaxisptr, int key)
 {
-  void *keyptr = NULL;
+  char *zaxisstring = NULL;
 
   switch (key)
     {
-    case CDI_KEY_NAME:      keyptr = (void*)zaxisptr->name; break;
-    case CDI_KEY_LONGNAME:  keyptr = (void*)zaxisptr->longname; break;
-    case CDI_KEY_UNITS:     keyptr = (void*)zaxisptr->units; break;
-    case CDI_KEY_DIMNAME:   keyptr = (void*)zaxisptr->dimname; break;
-    case CDI_KEY_VDIMNAME:  keyptr = (void*)zaxisptr->vdimname; break;
-    case CDI_KEY_PSNAME:    keyptr = (void*)zaxisptr->psname; break;
-    case CDI_KEY_P0NAME:    keyptr = (void*)zaxisptr->p0name; break;
-    case CDI_KEY_P0VALUE:   keyptr = (void*)&zaxisptr->p0value; break;
+    case CDI_ZAXIS_DIMNAME:  zaxisstring = zaxisptr->dimname; break;
+    case CDI_ZAXIS_VDIMNAME: zaxisstring = zaxisptr->vdimname; break;
     }
 
-  return keyptr;
+  return zaxisstring;
 }
 
 /*
- at Function  cdiZaxisDefKeyStr
+ at Function  cdiZaxisDefString
 @Title     Define a CDI Z-axis string value from a key
 
- at Prototype int cdiZaxisDefKeyStr(int zaxisID, int key, int size, const char *mesg)
+ at Prototype int cdiZaxisDefString(int zaxisID, int key, int size, const char *mesg)
 @Parameter
     @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
     @Item  key      The key to be searched
@@ -69068,37 +68689,37 @@ void *zaxis_key_to_ptr(zaxis_t *zaxisptr, int key)
     @Item  mesg     The address of a string where the data will be read
 
 @Description
-The function @func{cdiZaxisDefKeyStr} defines a CDI Z-axis string value from a key.
+The function @func{cdiZaxisDefString} defines a CDI Z-axis string value from a key.
 
 @Result
- at func{cdiZaxisDefKeyStr} returns 0 if OK and integer value on error.
+ at func{cdiZaxisDefString} returns 0 if OK and integer value on error.
 
 @EndFunction
 */
-int cdiZaxisDefKeyStr(int zaxisID, int key, int size, const char *mesg)
+int cdiZaxisDefString(int zaxisID, int key, int size, const char *mesg)
 {
-  if ( size < 1 || mesg == NULL || *mesg == 0 ) return -1;
+  if ( size <= 0 || mesg == NULL || *mesg == 0 ) return -1;
 
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
 
-  char *keyptr = (char*)zaxis_key_to_ptr(zaxisptr, key);
-  if ( keyptr == NULL)
+  char *zaxisstring = zaxis_key_to_string(zaxisptr, key);
+  if ( zaxisstring == NULL)
     {
       Warning("CDI zaxis string key %d not supported!", key);
       return -1;
     }
 
-  zaxisSetString(keyptr, mesg, (size_t)size);
+  zaxisSetString(zaxisstring, mesg, (size_t)size);
   reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
 
   return 0;
 }
 
 /*
- at Function  cdiZaxisInqKeyStr
+ at Function  cdiZaxisInqString
 @Title     Get a CDI Z-axis string value from a key
 
- at Prototype int cdiZaxisInqKeyStr(int zaxisID, int key, int size, char *mesg)
+ at Prototype int cdiZaxisInqString(int zaxisID, int key, int size, char *mesg)
 @Parameter
     @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
     @Item  key      The key to be searched.
@@ -69109,99 +68730,26 @@ int cdiZaxisDefKeyStr(int zaxisID, int key, int size, const char *mesg)
                     is given by the predefined constant @func{CDI_MAX_NAME}.
 
 @Description
-The function @func{cdiZaxisInqKeyStr} return a CDI Z-axis string value from a key.
+The function @func{cdiZaxisInqString} return a CDI Z-axis string value from a key.
 
 @Result
- at func{cdiZaxisInqKeyStr} returns 0 if OK and integer value on error.
+ at func{cdiZaxisInqString} returns 0 if OK and integer value on error.
 
 @EndFunction
 */
-int cdiZaxisInqKeyStr(int zaxisID, int key, int size, char *mesg)
+int cdiZaxisInqString(int zaxisID, int key, int size, char *mesg)
 {
-  if ( size < 1 || mesg == NULL ) return -1;
+  if ( size <= 0 || mesg == NULL ) return -1;
 
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
-  const char *keyptr = (const char*)zaxis_key_to_ptr(zaxisptr, key);
-  if ( keyptr == NULL)
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+  const char *zaxisstring = zaxis_key_to_string(zaxisptr, key);
+  if ( zaxisstring == NULL)
     {
       Warning("CDI zaxis string key %d not supported!", key);
       return -1;
     }
 
-  zaxisGetString(mesg, keyptr, (size_t)size);
-
-  return 0;
-}
-
-
-/*
- at Function  cdiZaxisDefKeyFlt
- at Title     Define a CDI Z-axis floating point value from a key
-
- at Prototype int cdiZaxisDefKeyFlt(int zaxisID, int key, double value)
- at Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
-    @Item  key      The key to be searched
-    @Item  value    A double where the data will be read
-
- at Description
-The function @func{cdiZaxisDefKeyFlt} defines a CDI Z-axis double value from a key.
-
- at Result
- at func{cdiZaxisDefKeyFlt} returns 0 if OK and integer value on error.
-
- at EndFunction
-*/
-int cdiZaxisDefKeyFlt(int zaxisID, int key, double value)
-{
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
-
-  zkey_double_t *keyptr = (zkey_double_t*)zaxis_key_to_ptr(zaxisptr, key);
-  if ( keyptr == NULL)
-    {
-      Warning("CDI zaxis double key %d not supported!", key);
-      return -1;
-    }
-
-  keyptr->value = value;
-  keyptr->defined = true;
-
-  reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
-
-  return 0;
-}
-
-/*
- at Function  cdiZaxisInqKeyFlt
- at Title     Get a CDI Z-axis floating point value from a key
-
- at Prototype int cdiZaxisInqKeyFlt(int zaxisID, int key, double *value)
- at Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
-    @Item  key      The key to be searched.
-    @Item value     The address of a double where the data will be retrieved.
-
- at Description
-The function @func{cdiZaxisInqKeyFlt} return a CDI Z-axis double value from a key.
-
- at Result
- at func{cdiZaxisInqKeyFlt} returns 0 if OK and integer value on error.
-
- at EndFunction
-*/
-int cdiZaxisInqKeyFlt(int zaxisID, int key, double *value)
-{
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
-  zkey_double_t *keyptr = (zkey_double_t*)zaxis_key_to_ptr(zaxisptr, key);
-  if ( keyptr == NULL)
-    {
-      Warning("CDI zaxis double key %d not supported!", key);
-      return -1;
-    }
-
-  if ( !keyptr->defined ) return 1;
-
-  *value = keyptr->value;
+  zaxisGetString(mesg, zaxisstring, (size_t)size);
 
   return 0;
 }
@@ -69222,7 +68770,14 @@ The function @func{zaxisDefName} defines the name of a Z-axis.
 */
 void zaxisDefName(int zaxisID, const char *name)
 {
-  (void)cdiZaxisDefKeyStr(zaxisID, CDI_KEY_NAME, CDI_MAX_NAME, name);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+
+  if ( name )
+    {
+      strncpy(zaxisptr->name, name, CDI_MAX_NAME - 1);
+      zaxisptr->name[CDI_MAX_NAME - 1] = '\0';
+      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
+    }
 }
 
 /*
@@ -69241,7 +68796,14 @@ The function @func{zaxisDefLongname} defines the longname of a Z-axis.
 */
 void zaxisDefLongname(int zaxisID, const char *longname)
 {
-  (void)cdiZaxisDefKeyStr(zaxisID, CDI_KEY_LONGNAME, CDI_MAX_NAME, longname);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+
+  if ( longname )
+    {
+      strncpy(zaxisptr->longname, longname, CDI_MAX_NAME - 1);
+      zaxisptr->longname[CDI_MAX_NAME - 1] = '\0';
+      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
+    }
 }
 
 /*
@@ -69260,7 +68822,27 @@ The function @func{zaxisDefUnits} defines the units of a Z-axis.
 */
 void zaxisDefUnits(int zaxisID, const char *units)
 {
-  (void)cdiZaxisDefKeyStr(zaxisID, CDI_KEY_UNITS, CDI_MAX_NAME, units);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+
+  if ( units )
+    {
+      strncpy(zaxisptr->units, units, CDI_MAX_NAME - 1);
+      zaxisptr->units[CDI_MAX_NAME - 1] = '\0';
+      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
+    }
+}
+
+
+void zaxisDefPsName(int zaxisID, const char *psname)
+{
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+
+  if ( psname )
+    {
+      strncpy(zaxisptr->psname, psname, CDI_MAX_NAME - 1);
+      zaxisptr->name[CDI_MAX_NAME - 1] = '\0';
+      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
+    }
 }
 
 /*
@@ -69284,12 +68866,13 @@ The function @func{zaxisInqName} returns the name of a Z-axis.
 */
 void zaxisInqName(int zaxisID, char *name)
 {
-  (void)cdiZaxisInqKeyStr(zaxisID, CDI_KEY_NAME, CDI_MAX_NAME, name);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+  strcpy(name, zaxisptr->name);
 }
 
 const char *zaxisInqNamePtr(int zaxisID)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
   return zaxisptr->name;
 }
 
@@ -69314,7 +68897,8 @@ The function @func{zaxisInqLongname} returns the longname of a Z-axis.
 */
 void zaxisInqLongname(int zaxisID, char *longname)
 {
-  (void)cdiZaxisInqKeyStr(zaxisID, CDI_KEY_LONGNAME, CDI_MAX_NAME, longname);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+  strcpy(longname, zaxisptr->longname);
 }
 
 /*
@@ -69338,22 +68922,30 @@ The function @func{zaxisInqUnits} returns the units of a Z-axis.
 */
 void zaxisInqUnits(int zaxisID, char *units)
 {
-  (void)cdiZaxisInqKeyStr(zaxisID, CDI_KEY_UNITS, CDI_MAX_NAME, units);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+  strcpy(units, zaxisptr->units);
 }
 
 
 void zaxisInqStdname(int zaxisID, char *stdname)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
   strcpy(stdname, zaxisptr->stdname);
 }
 
 
+void zaxisInqPsName(int zaxisID, char *psname)
+{
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+  strcpy(psname, zaxisptr->psname);
+}
+
+
 void zaxisDefPrec(int zaxisID, int prec)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
 
-  if ( zaxisptr->prec != prec )
+  if (zaxisptr->prec != prec)
     {
       zaxisptr->prec = prec;
       reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
@@ -69363,18 +68955,18 @@ void zaxisDefPrec(int zaxisID, int prec)
 
 int zaxisInqPrec(int zaxisID)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
-  return zaxisptr->prec;
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+  return (zaxisptr->prec);
 }
 
 
 void zaxisDefPositive(int zaxisID, int positive)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
 
-  if ( zaxisptr->positive != (unsigned)positive )
+  if (zaxisptr->positive != (unsigned)(positive != 0))
     {
-      zaxisptr->positive = (unsigned)positive;
+      zaxisptr->positive = (unsigned)(positive != 0);
       reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
     }
 }
@@ -69382,14 +68974,14 @@ void zaxisDefPositive(int zaxisID, int positive)
 
 int zaxisInqPositive(int zaxisID)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
   return (int)zaxisptr->positive;
 }
 
 
 void zaxisDefScalar(int zaxisID)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
 
   zaxisptr->scalar = 1;
   reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
@@ -69397,14 +68989,14 @@ void zaxisDefScalar(int zaxisID)
 
 int zaxisInqScalar(int zaxisID)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
   return zaxisptr->scalar;
 }
 
 
 void zaxisDefLtype(int zaxisID, int ltype)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
 
   if (zaxisptr->ltype != ltype)
     {
@@ -69416,16 +69008,16 @@ void zaxisDefLtype(int zaxisID, int ltype)
 
 int zaxisInqLtype(int zaxisID)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
   return zaxisptr->ltype;
 }
 
 
 void zaxisDefLtype2(int zaxisID, int ltype2)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
 
-  if ( zaxisptr->ltype2 != ltype2 )
+  if (zaxisptr->ltype2 != ltype2)
     {
       zaxisptr->ltype2 = ltype2;
       reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
@@ -69435,7 +69027,7 @@ void zaxisDefLtype2(int zaxisID, int ltype2)
 
 int zaxisInqLtype2(int zaxisID)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
   return zaxisptr->ltype2;
 }
 
@@ -69455,41 +69047,15 @@ The function @func{zaxisDefLevels} defines the levels of a Z-axis.
 */
 void zaxisDefLevels(int zaxisID, const double *levels)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
-  size_t size = (size_t)zaxisptr->size;
-
-  if ( levels )
-    {
-      if ( zaxisptr->vals == NULL )
-        zaxisptr->vals = (double*) Malloc(size*sizeof(double));
-
-      double *vals = zaxisptr->vals;
-
-      for ( size_t ilev = 0; ilev < size; ++ilev )
-        vals[ilev] = levels[ilev];
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
 
-      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
-    }
-}
-
-
-void zaxisDefCvals(int zaxisID, const char **cvals, size_t clen)
-{
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
-  size_t size = (size_t)zaxisptr->size;
+  int size = zaxisptr->size;
 
-  if ( cvals && clen )
-    {
-      zaxisptr->clength = clen;
-      zaxisptr->cvals = (char**) Malloc(size*sizeof(char *));
+  double *vals = zaxisptr->vals;
 
-      for ( size_t ilev = 0; ilev < size; ++ilev )
-        {
-          zaxisptr->cvals[ilev] = Malloc(clen*sizeof(char));
-          memcpy(zaxisptr->cvals[ilev],cvals[ilev], clen*sizeof(char));
-        }
-      reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
-    }
+  for (int ilev = 0; ilev < size; ilev++ )
+    vals[ilev] = levels[ilev];
+  reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
 }
 
 /*
@@ -69509,22 +69075,16 @@ The function @func{zaxisDefLevel} defines one level of a Z-axis.
 */
 void zaxisDefLevel(int zaxisID, int levelID, double level)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
-  int size = zaxisptr->size;
-
-  if ( zaxisptr->vals == NULL )
-    zaxisptr->vals = (double*) Malloc((size_t)size*sizeof(double));
-
-  if ( levelID >= 0 && levelID < size )
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+  if ( levelID >= 0 && levelID < zaxisptr->size )
     zaxisptr->vals[levelID] = level;
-
   reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
 }
 
 
 void zaxisDefNlevRef(int zaxisID, const int nhlev)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
   if (zaxisptr->nhlev != nhlev)
     {
       zaxisptr->nhlev = nhlev;
@@ -69535,7 +69095,7 @@ void zaxisDefNlevRef(int zaxisID, const int nhlev)
 
 int zaxisInqNlevRef(int zaxisID)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
   return zaxisptr->nhlev;
 }
 
@@ -69555,7 +69115,7 @@ The function @func{zaxisDefNumber} defines the reference number for a generalize
 */
 void zaxisDefNumber(int zaxisID, const int number)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
   if (zaxisptr->number != number)
     {
       zaxisptr->number = number;
@@ -69580,7 +69140,7 @@ The function @func{zaxisInqNumber} returns the reference number to a generalized
 */
 int zaxisInqNumber(int zaxisID)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
   return zaxisptr->number;
 }
 
@@ -69600,7 +69160,7 @@ The function @func{zaxisDefUUID} defines the UUID for a generalized  Z-axis.
 */
 void zaxisDefUUID(int zaxisID, const unsigned char uuid[CDI_UUID_SIZE])
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
   memcpy(zaxisptr->uuid, uuid, CDI_UUID_SIZE);
   reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
 }
@@ -69623,7 +69183,7 @@ The function @func{zaxisInqUUID} returns the UUID to a generalized Z-axis.
 */
 void zaxisInqUUID(int zaxisID, unsigned char uuid[CDI_UUID_SIZE])
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
   memcpy(uuid, zaxisptr->uuid, CDI_UUID_SIZE);
 }
 
@@ -69646,54 +69206,43 @@ The function @func{zaxisInqLevel} returns one level of a Z-axis.
 double zaxisInqLevel(int zaxisID, int levelID)
 {
   double level = 0;
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
 
-  if ( zaxisptr->vals && levelID >= 0 && levelID < zaxisptr->size )
+  if ( levelID >= 0 && levelID < zaxisptr->size )
     level = zaxisptr->vals[levelID];
 
   return level;
 }
 
-
-double zaxisInqLbound(int zaxisID, int levelID)
+double zaxisInqLbound(int zaxisID, int index)
 {
   double level = 0;
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
 
-  if ( zaxisptr->lbounds && levelID >= 0 && levelID < zaxisptr->size )
-    level = zaxisptr->lbounds[levelID];
+  if ( zaxisptr->lbounds && ( index >= 0 && index < zaxisptr->size ) )
+      level = zaxisptr->lbounds[index];
 
   return level;
 }
 
 
-double zaxisInqUbound(int zaxisID, int levelID)
+double zaxisInqUbound(int zaxisID, int index)
 {
   double level = 0;
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
-
-  if ( zaxisptr->ubounds && levelID >= 0 && levelID < zaxisptr->size )
-    level = zaxisptr->ubounds[levelID];
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
 
+  if ( zaxisptr->ubounds && ( index >= 0 && index < zaxisptr->size ) )
+    level = zaxisptr->ubounds[index];
   return level;
 }
 
 
 const double *zaxisInqLevelsPtr(int zaxisID)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
   return zaxisptr->vals;
 }
 
-
-char **zaxisInqCValsPtr(int zaxisID)
-{
-  char **cvals = NULL;
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
-  cvals = zaxisptr->cvals;
-  return cvals;
-}
-
 /*
 @Function  zaxisInqLevels
 @Title     Get all levels of a Z-axis
@@ -69711,98 +69260,55 @@ The function @func{zaxisInqLevels} returns all levels of a Z-axis.
 @func{zaxisInqLevels} saves all levels to the parameter @func{levels}.
 @EndFunction
 */
-int zaxisInqLevels(int zaxisID, double *levels)
+void zaxisInqLevels(int zaxisID, double *levels)
 {
-  int size = 0;
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
-
-  if ( zaxisptr->vals )
-    {
-      size = zaxisptr->size;
-
-      if ( levels )
-        for ( int i = 0; i < size; i++ )
-          levels[i] = zaxisptr->vals[i];
-    }
-
-  return size;
-}
-
-int zaxisInqCLen(int zaxisID)
-{
-  int size = 0;
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
-
-  if ( zaxisptr->cvals && zaxisptr->clength)
-    size = zaxisptr->clength;
-  return size;
-}
-
-int zaxisInqCVals(int zaxisID, char ***clevels)
-{
-  int size = 0;
-  size_t clen = 0;
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
-
-  if ( zaxisptr->cvals )
-    {
-      size = zaxisptr->size;
-      clen = zaxisptr->clength;
-      if ( size && clen )
-        {
-          (*clevels) = Malloc(size*sizeof(char*));
-          for ( int i = 0; i < size; i++ )
-            {
-              (*clevels)[i] = Malloc(clen*sizeof(char));
-              memcpy((*clevels)[i], zaxisptr->cvals[i], clen*sizeof(char));
-            }
-          }
-    }
-
-  return size;
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+  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 = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
 
   if ( zaxisptr->lbounds )
     {
       size = zaxisptr->size;
 
       if ( lbounds )
-        for ( int i = 0; i < size; i++ )
-          lbounds[i] = zaxisptr->lbounds[i];
+        for (int i = 0; i < size; i++ )
+          lbounds[i] =  zaxisptr->lbounds[i];
     }
 
-  return size;
+  return (size);
 }
 
 
 int zaxisInqUbounds(int zaxisID, double *ubounds)
 {
   int size = 0;
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
 
   if ( zaxisptr->ubounds )
     {
       size = zaxisptr->size;
 
       if ( ubounds )
-        for ( int i = 0; i < size; i++ )
-          ubounds[i] = zaxisptr->ubounds[i];
+        for (int i = 0; i < size; i++ )
+          ubounds[i] =  zaxisptr->ubounds[i];
     }
 
-  return size;
+  return (size);
 }
 
 
 int zaxisInqWeights(int zaxisID, double *weights)
 {
   int size = 0;
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
 
   if ( zaxisptr->weights )
     {
@@ -69810,29 +69316,25 @@ int zaxisInqWeights(int zaxisID, double *weights)
 
       if ( weights )
         for ( int i = 0; i < size; i++ )
-          weights[i] = zaxisptr->weights[i];
+          weights[i] =  zaxisptr->weights[i];
     }
 
-  return size;
+  return (size);
 }
 
 
 int zaxisInqLevelID(int zaxisID, double level)
 {
   int levelID = CDI_UNDEFID;
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
-
-  if ( zaxisptr->vals )
-    {
-      int size = zaxisptr->size;
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
 
-      for ( int i = 0; i < size; i++ )
-        if ( fabs(level-zaxisptr->vals[i]) < DBL_EPSILON )
-          {
-            levelID = i;
-            break;
-          }
-    }
+  int size = zaxisptr->size;
+  for ( int i = 0; i < size; i++ )
+    if ( fabs(level-zaxisptr->vals[i]) < DBL_EPSILON )
+      {
+        levelID = i;
+        break;
+      }
 
   return levelID;
 }
@@ -69864,8 +69366,8 @@ The valid CDI Z-axis types are @func{ZAXIS_GENERIC}, @func{ZAXIS_SURFACE},
 */
 int zaxisInqType(int zaxisID)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
-  return zaxisptr->type;
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+  return (zaxisptr->type);
 }
 
 /*
@@ -69886,16 +69388,16 @@ The function @func{zaxisInqSize} returns the size of a Z-axis.
 */
 int zaxisInqSize(int zaxisID)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
-  return zaxisptr->size;
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+  return (zaxisptr->size);
 }
 
 
 void cdiCheckZaxis(int zaxisID)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
 
-  if ( zaxisInqType(zaxisID) == ZAXIS_GENERIC && zaxisptr->vals )
+  if ( zaxisInqType(zaxisID) == ZAXIS_GENERIC )
     {
       int size = zaxisptr->size;
       if ( size > 1 )
@@ -69929,7 +69431,7 @@ void cdiCheckZaxis(int zaxisID)
 
 void zaxisDefVct(int zaxisID, int size, const double *vct)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
 
   if ( zaxisptr->vct == 0 || zaxisptr->vctsize != size )
     {
@@ -69944,28 +69446,28 @@ void zaxisDefVct(int zaxisID, int size, const double *vct)
 
 void zaxisInqVct(int zaxisID, double *vct)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
   memcpy(vct, zaxisptr->vct, (size_t)zaxisptr->vctsize * sizeof (double));
 }
 
 
 int zaxisInqVctSize(int zaxisID)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
-  return zaxisptr->vctsize;
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+  return (zaxisptr->vctsize);
 }
 
 
 const double *zaxisInqVctPtr(int zaxisID)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
-  return zaxisptr->vct;
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+  return (zaxisptr->vct);
 }
 
 
 void zaxisDefLbounds(int zaxisID, const double *lbounds)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
 
   size_t size = (size_t)zaxisptr->size;
 
@@ -69983,7 +69485,7 @@ void zaxisDefLbounds(int zaxisID, const double *lbounds)
 
 void zaxisDefUbounds(int zaxisID, const double *ubounds)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
 
   size_t size = (size_t)zaxisptr->size;
 
@@ -70001,7 +69503,7 @@ void zaxisDefUbounds(int zaxisID, const double *ubounds)
 
 void zaxisDefWeights(int zaxisID, const double *weights)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
 
   size_t size = (size_t)zaxisptr->size;
 
@@ -70019,33 +69521,34 @@ void zaxisDefWeights(int zaxisID, const double *weights)
 
 void zaxisChangeType(int zaxisID, int zaxistype)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
   zaxisptr->type = zaxistype;
 }
 
 
 void zaxisResize(int zaxisID, int size)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
 
   xassert(size >= 0);
 
   zaxisptr->size = size;
 
   if ( zaxisptr->vals )
-    zaxisptr->vals = (double *) Realloc(zaxisptr->vals, (size_t)size*sizeof(double));
+    zaxisptr->vals = (double *) Realloc(zaxisptr->vals, (size_t)size * sizeof(double));
 }
 
 
 int zaxisDuplicate(int zaxisID)
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
+  int zaxisIDnew;
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
 
   int zaxistype = zaxisInqType(zaxisID);
   int zaxissize = zaxisInqSize(zaxisID);
 
-  int zaxisIDnew = zaxisCreate(zaxistype, zaxissize);
-  zaxis_t *zaxisptrnew = zaxis_to_pointer(zaxisIDnew);
+  zaxisIDnew = zaxisCreate(zaxistype, zaxissize);
+  zaxis_t *zaxisptrnew = zaxisID2Ptr(zaxisIDnew);
 
   zaxis_copy(zaxisptrnew, zaxisptr);
 
@@ -70053,9 +69556,10 @@ int zaxisDuplicate(int zaxisID)
   strcpy(zaxisptrnew->longname, zaxisptr->longname);
   strcpy(zaxisptrnew->units, zaxisptr->units);
 
-  if ( zaxisptr->vals )
+  if ( zaxisptr->vals != NULL )
     {
       size_t size = (size_t)zaxissize;
+
       zaxisptrnew->vals = (double *) Malloc(size * sizeof (double));
       memcpy(zaxisptrnew->vals, zaxisptr->vals, size * sizeof (double));
     }
@@ -70063,6 +69567,7 @@ int zaxisDuplicate(int zaxisID)
   if ( zaxisptr->lbounds )
     {
       size_t size = (size_t)zaxissize;
+
       zaxisptrnew->lbounds = (double *) Malloc(size * sizeof (double));
       memcpy(zaxisptrnew->lbounds, zaxisptr->lbounds, size * sizeof(double));
     }
@@ -70070,13 +69575,15 @@ int zaxisDuplicate(int zaxisID)
   if ( zaxisptr->ubounds )
     {
       size_t size = (size_t)zaxissize;
+
       zaxisptrnew->ubounds = (double *) Malloc(size * sizeof (double));
       memcpy(zaxisptrnew->ubounds, zaxisptr->ubounds, size * sizeof (double));
     }
 
-  if ( zaxisptr->vct )
+  if ( zaxisptr->vct != NULL )
     {
       size_t size = (size_t)zaxisptr->vctsize;
+
       if ( size )
         {
           zaxisptrnew->vctsize = (int)size;
@@ -70085,71 +69592,55 @@ int zaxisDuplicate(int zaxisID)
         }
     }
 
-  return zaxisIDnew;
+  return (zaxisIDnew);
 }
 
-static
-void zaxisPrintKernel(zaxis_t *zaxisptr, FILE *fp)
+
+static void zaxisPrintKernel ( zaxis_t * zaxisptr, int index, FILE * fp )
 {
-  xassert(zaxisptr);
+  unsigned char uuid[CDI_UUID_SIZE];
+  int levelID;
+  int nbyte;
+
+  xassert ( zaxisptr );
 
   int zaxisID = zaxisptr->self;
+
   int type    = zaxisptr->type;
   int nlevels = zaxisptr->size;
   int prec    = zaxisptr->prec;
 
-  int dig = (prec == CDI_DATATYPE_FLT64) ? 15 : 7;
+  int dig = (prec == DATATYPE_FLT64) ? 15 : 7;
 
-  int nbyte;
   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 ( nlevels == 1 )
-    {
-      bool zscalar = (bool)zaxisptr->scalar;
-      if ( zscalar ) fprintf(fp, "scalar    = true\n");
-    }
   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);
 
-  if ( zaxisptr->vals )
+  nbyte0 = fprintf(fp, "levels    = ");
+  nbyte = nbyte0;
+  for ( levelID = 0; levelID < nlevels; levelID++ )
     {
-      nbyte0 = fprintf(fp, "levels    = ");
-      nbyte = nbyte0;
-      for ( int levelID = 0; levelID < nlevels; levelID++ )
-        {
-          if ( nbyte > 80 )
-            {
-              fprintf(fp, "\n");
-              fprintf(fp, "%*s", nbyte0, "");
-              nbyte = nbyte0;
-            }
-          nbyte += fprintf(fp, "%.*g ", dig, zaxisptr->vals[levelID]);
-        }
-      fprintf(fp, "\n");
-    }
-
-  if ( zaxisptr->cvals )
-    {
-      dig = prec;
-      nbyte0 = fprintf(fp, "types     = ");
-      nbyte = nbyte0;
-      for ( int levelID = 0; levelID < nlevels; levelID++ )
-        {
-          fprintf(fp, "\n");
-          fprintf(fp, "%*s", nbyte0, "");
-          nbyte = nbyte0;
-          nbyte += fprintf(fp, "%.*s [%d]", dig, zaxisptr->cvals[levelID], levelID+1);
-        }
-      fprintf(fp, "\n");
+      if ( nbyte > 80 )
+	{
+	  fprintf(fp, "\n");
+	  fprintf(fp, "%*s", nbyte0, "");
+	  nbyte = nbyte0;
+	}
+      nbyte += fprintf(fp, "%.*g ", dig, zaxisptr->vals[levelID]);
     }
+  fprintf(fp, "\n");
 
   if ( zaxisptr->lbounds && zaxisptr->ubounds )
     {
       nbyte0 = fprintf(fp, "lbounds   = ");
       nbyte = nbyte0;
-      for ( int levelID = 0; levelID < nlevels; levelID++ )
+      for ( levelID = 0; levelID < nlevels; levelID++ )
 	{
 	  if ( nbyte > 80 )
 	    {
@@ -70163,7 +69654,7 @@ void zaxisPrintKernel(zaxis_t *zaxisptr, FILE *fp)
 
       nbyte0 = fprintf(fp, "ubounds   = ");
       nbyte = nbyte0;
-      for ( int levelID = 0; levelID < nlevels; levelID++ )
+      for ( levelID = 0; levelID < nlevels; levelID++ )
 	{
 	  if ( nbyte > 80 )
 	    {
@@ -70214,7 +69705,6 @@ void zaxisPrintKernel(zaxis_t *zaxisptr, FILE *fp)
 
   if ( type == ZAXIS_REFERENCE )
     {
-      unsigned char uuid[CDI_UUID_SIZE];
       zaxisInqUUID(zaxisID, uuid);
       if ( *uuid )
         {
@@ -70227,28 +69717,31 @@ void zaxisPrintKernel(zaxis_t *zaxisptr, FILE *fp)
 }
 
 
-void zaxisPrint(int zaxisID)
+void zaxisPrint ( int zaxisID, int index )
 {
-  zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
-  zaxisPrintKernel(zaxisptr, stdout);
+  zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
+
+  zaxisPrintKernel ( zaxisptr, index, stdout );
 }
 
 
 static
-void zaxisPrintP(void * voidptr, FILE * fp)
+void zaxisPrintP ( void * voidptr, FILE * fp )
 {
   zaxis_t *zaxisptr = ( zaxis_t * ) voidptr;
 
   xassert ( zaxisptr );
 
-  zaxisPrintKernel(zaxisptr, fp);
+  zaxisPrintKernel(zaxisptr, zaxisptr->self, fp);
 }
 
 
-static
-int zaxisCompareP(zaxis_t *z1, zaxis_t *z2)
+static int
+zaxisCompareP(zaxis_t *z1, zaxis_t *z2)
 {
-  enum { differ = 1 };
+  enum {
+    differ = 1,
+  };
   int diff = 0;
   xassert(z1 && z2);
 
@@ -70260,8 +69753,8 @@ int zaxisCompareP(zaxis_t *z1, zaxis_t *z2)
     | (z1->vctsize != z2->vctsize)
     | (z1->positive != z2->positive);
 
-  if ( diff ) return differ;
-
+  if (diff)
+    return differ;
   int size = z1->size;
   int anyPresent = 0;
   int present = (z1->vals != NULL);
@@ -70270,7 +69763,7 @@ int zaxisCompareP(zaxis_t *z1, zaxis_t *z2)
   if (!diff && present)
     {
       const double *p = z1->vals, *q = z2->vals;
-      for ( int i = 0; i < size; i++ )
+      for (int i = 0; i < size; i++)
         diff |= IS_NOT_EQUAL(p[i], q[i]);
     }
 
@@ -70280,7 +69773,7 @@ int zaxisCompareP(zaxis_t *z1, zaxis_t *z2)
   if (!diff && present)
     {
       const double *p = z1->lbounds, *q = z2->lbounds;
-      for ( int i = 0; i < size; i++ )
+      for (int i = 0; i < size; i++)
         diff |= IS_NOT_EQUAL(p[i], q[i]);
     }
 
@@ -70290,7 +69783,7 @@ int zaxisCompareP(zaxis_t *z1, zaxis_t *z2)
   if (!diff && present)
     {
       const double *p = z1->ubounds, *q = z2->ubounds;
-      for ( int i = 0; i < size; ++i )
+      for (int i = 0; i < size; ++i)
         diff |= IS_NOT_EQUAL(p[i], q[i]);
     }
 
@@ -70300,7 +69793,7 @@ int zaxisCompareP(zaxis_t *z1, zaxis_t *z2)
   if (!diff && present)
     {
       const double *p = z1->weights, *q = z2->weights;
-      for ( int i = 0; i < size; ++i )
+      for (int i = 0; i < size; ++i)
         diff |= IS_NOT_EQUAL(p[i], q[i]);
     }
 
@@ -70311,7 +69804,7 @@ int zaxisCompareP(zaxis_t *z1, zaxis_t *z2)
       int vctsize = z1->vctsize;
       xassert(vctsize);
       const double *p = z1->vct, *q = z2->vct;
-      for ( int i = 0; i < vctsize; ++i )
+      for (int i = 0; i < vctsize; ++i)
         diff |= IS_NOT_EQUAL(p[i], q[i]);
     }
 
@@ -70327,8 +69820,8 @@ int zaxisCompareP(zaxis_t *z1, zaxis_t *z2)
 }
 
 
-static
-int zaxisTxCode(void)
+static int
+zaxisTxCode ( void )
 {
   return ZAXIS;
 }
@@ -70343,10 +69836,10 @@ enum { zaxisNint     = 8,
 };
 
 #define ZAXIS_STR_SERIALIZE { zaxisP->name, zaxisP->longname, \
-                              zaxisP->stdname, zaxisP->units }
+      zaxisP->stdname, zaxisP->units }
 
 static
-int zaxisGetMemberMask( zaxis_t * zaxisP )
+int zaxisGetMemberMask ( zaxis_t * zaxisP )
 {
   int memberMask = 0;
 
@@ -70363,33 +69856,33 @@ static int
 zaxisGetPackSize(void * voidP, void *context)
 {
   zaxis_t * zaxisP = ( zaxis_t * ) voidP;
-  int packBufferSize = serializeGetSize(zaxisNint, CDI_DATATYPE_INT, context)
-    + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
+  int packBufferSize = serializeGetSize(zaxisNint, DATATYPE_INT, context)
+    + serializeGetSize(1, DATATYPE_UINT32, context);
 
   if (zaxisP->vals || zaxisP->lbounds || zaxisP->ubounds || zaxisP->weights)
     xassert(zaxisP->size);
 
   if ( zaxisP->vals )
-    packBufferSize += serializeGetSize(zaxisP->size, CDI_DATATYPE_FLT64, context)
-      + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
+    packBufferSize += serializeGetSize(zaxisP->size, DATATYPE_FLT64, context)
+      + serializeGetSize(1, DATATYPE_UINT32, context);
 
   if ( zaxisP->lbounds )
-    packBufferSize += serializeGetSize(zaxisP->size, CDI_DATATYPE_FLT64, context)
-      + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
+    packBufferSize += serializeGetSize(zaxisP->size, DATATYPE_FLT64, context)
+      + serializeGetSize(1, DATATYPE_UINT32, context);
 
   if ( zaxisP->ubounds )
-    packBufferSize += serializeGetSize(zaxisP->size, CDI_DATATYPE_FLT64, context)
-      + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
+    packBufferSize += serializeGetSize(zaxisP->size, DATATYPE_FLT64, context)
+      + serializeGetSize(1, DATATYPE_UINT32, context);
 
   if ( zaxisP->weights )
-    packBufferSize += serializeGetSize(zaxisP->size, CDI_DATATYPE_FLT64, context)
-      + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
+    packBufferSize += serializeGetSize(zaxisP->size, DATATYPE_FLT64, context)
+      + serializeGetSize(1, DATATYPE_UINT32, context);
 
   if ( zaxisP->vct )
     {
       xassert ( zaxisP->vctsize );
-      packBufferSize += serializeGetSize(zaxisP->vctsize, CDI_DATATYPE_FLT64, context)
-        + serializeGetSize(1, CDI_DATATYPE_UINT32, context);
+      packBufferSize += serializeGetSize(zaxisP->vctsize, DATATYPE_FLT64, context)
+        + serializeGetSize(1, DATATYPE_UINT32, context);
     }
 
   {
@@ -70399,10 +69892,10 @@ zaxisGetPackSize(void * voidP, void *context)
       += serializeStrTabGetPackSize(strTab, (int)numStr, context);
   }
 
-  packBufferSize += serializeGetSize(1, CDI_DATATYPE_UCHAR, context);
+  packBufferSize += serializeGetSize(1, DATATYPE_UCHAR, context);
 
   if (!cdiUUIDIsNull(zaxisP->uuid))
-    packBufferSize += serializeGetSize(CDI_UUID_SIZE, CDI_DATATYPE_UCHAR, context);
+    packBufferSize += serializeGetSize(CDI_UUID_SIZE, DATATYPE_UCHAR, context);
 
   return packBufferSize;
 }
@@ -70417,11 +69910,11 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
   uint32_t d;
 
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  intBuffer, zaxisNint, CDI_DATATYPE_INT, context);
+                  intBuffer, zaxisNint, DATATYPE_INT, context);
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  &d, 1, CDI_DATATYPE_UINT32, context);
+                  &d, 1, DATATYPE_UINT32, context);
 
-  xassert(cdiCheckSum(CDI_DATATYPE_INT, zaxisNint, intBuffer) == d);
+  xassert(cdiCheckSum(DATATYPE_INT, zaxisNint, intBuffer) == d);
 
   zaxisInit();
 
@@ -70444,10 +69937,10 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
 
       zaxisP->vals = (double *) Malloc((size_t)size * sizeof (double));
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      zaxisP->vals, size, CDI_DATATYPE_FLT64, context);
+                      zaxisP->vals, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, CDI_DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(CDI_DATATYPE_FLT, size, zaxisP->vals) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, zaxisP->vals) == d);
     }
 
   if (memberMask & lbounds)
@@ -70457,10 +69950,10 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
 
       zaxisP->lbounds = (double *) Malloc((size_t)size * sizeof (double));
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      zaxisP->lbounds, size, CDI_DATATYPE_FLT64, context);
+                      zaxisP->lbounds, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, CDI_DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(CDI_DATATYPE_FLT, size, zaxisP->lbounds) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, zaxisP->lbounds) == d);
     }
 
   if (memberMask & ubounds)
@@ -70470,10 +69963,10 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
 
       zaxisP->ubounds = (double *) Malloc((size_t)size * sizeof (double));
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      zaxisP->ubounds, size, CDI_DATATYPE_FLT64, context);
+                      zaxisP->ubounds, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, CDI_DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(CDI_DATATYPE_FLT, size, zaxisP->ubounds) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, zaxisP->ubounds) == d);
     }
 
   if (memberMask & weights)
@@ -70483,10 +69976,10 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
 
       zaxisP->weights = (double *) Malloc((size_t)size * sizeof (double));
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      zaxisP->weights, size, CDI_DATATYPE_FLT64, context);
+                      zaxisP->weights, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, CDI_DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(CDI_DATATYPE_FLT, size, zaxisP->weights) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, zaxisP->weights) == d);
     }
 
   if ( memberMask & vct )
@@ -70496,10 +69989,10 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
 
       zaxisP->vct = (double *) Malloc((size_t)size * sizeof (double));
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      zaxisP->vct, size, CDI_DATATYPE_FLT64, context);
+                      zaxisP->vct, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, CDI_DATATYPE_UINT32, context);
-      xassert(cdiCheckSum(CDI_DATATYPE_FLT64, size, zaxisP->vct) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT64, size, zaxisP->vct) == d);
     }
 
   {
@@ -70510,11 +70003,11 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
   }
 
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  &zaxisP->positive, 1, CDI_DATATYPE_UCHAR, context);
+                  &zaxisP->positive, 1, DATATYPE_UCHAR, context);
 
   if (memberMask & zaxisHasUUIDFlag)
     serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                    zaxisP->uuid, CDI_UUID_SIZE, CDI_DATATYPE_UCHAR, context);
+                    zaxisP->uuid, CDI_UUID_SIZE, DATATYPE_UCHAR, context);
 
   reshSetStatus(zaxisP->self, &zaxisOps,
                 reshGetStatus(zaxisP->self, &zaxisOps) & ~RESH_SYNC_BIT);
@@ -70538,30 +70031,30 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
   intBuffer[6]  = zaxisP->vctsize;
   intBuffer[7]  = memberMask = zaxisGetMemberMask ( zaxisP );
 
-  serializePack(intBuffer, zaxisNint, CDI_DATATYPE_INT,
+  serializePack(intBuffer, zaxisNint, DATATYPE_INT,
                 packBuffer, packBufferSize, packBufferPos, context);
-  d = cdiCheckSum(CDI_DATATYPE_INT, zaxisNint, intBuffer);
-  serializePack(&d, 1, CDI_DATATYPE_UINT32,
+  d = cdiCheckSum(DATATYPE_INT, zaxisNint, intBuffer);
+  serializePack(&d, 1, DATATYPE_UINT32,
                 packBuffer, packBufferSize, packBufferPos, context);
 
 
   if ( memberMask & vals )
     {
       xassert(zaxisP->size);
-      serializePack(zaxisP->vals, zaxisP->size, CDI_DATATYPE_FLT64,
+      serializePack(zaxisP->vals, zaxisP->size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(CDI_DATATYPE_FLT, zaxisP->size, zaxisP->vals );
-      serializePack(&d, 1, CDI_DATATYPE_UINT32,
+      d = cdiCheckSum(DATATYPE_FLT, zaxisP->size, zaxisP->vals );
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
   if (memberMask & lbounds)
     {
       xassert(zaxisP->size);
-      serializePack(zaxisP->lbounds, zaxisP->size, CDI_DATATYPE_FLT64,
+      serializePack(zaxisP->lbounds, zaxisP->size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(CDI_DATATYPE_FLT, zaxisP->size, zaxisP->lbounds);
-      serializePack(&d, 1, CDI_DATATYPE_UINT32,
+      d = cdiCheckSum(DATATYPE_FLT, zaxisP->size, zaxisP->lbounds);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -70569,10 +70062,10 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
     {
       xassert(zaxisP->size);
 
-      serializePack(zaxisP->ubounds, zaxisP->size, CDI_DATATYPE_FLT64,
+      serializePack(zaxisP->ubounds, zaxisP->size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(CDI_DATATYPE_FLT, zaxisP->size, zaxisP->ubounds);
-      serializePack(&d, 1, CDI_DATATYPE_UINT32,
+      d = cdiCheckSum(DATATYPE_FLT, zaxisP->size, zaxisP->ubounds);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -70580,10 +70073,10 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
     {
       xassert(zaxisP->size);
 
-      serializePack(zaxisP->weights, zaxisP->size, CDI_DATATYPE_FLT64,
+      serializePack(zaxisP->weights, zaxisP->size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(CDI_DATATYPE_FLT, zaxisP->size, zaxisP->weights);
-      serializePack(&d, 1, CDI_DATATYPE_UINT32,
+      d = cdiCheckSum(DATATYPE_FLT, zaxisP->size, zaxisP->weights);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -70591,10 +70084,10 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
     {
       xassert(zaxisP->vctsize);
 
-      serializePack(zaxisP->vct, zaxisP->vctsize, CDI_DATATYPE_FLT64,
+      serializePack(zaxisP->vct, zaxisP->vctsize, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = cdiCheckSum(CDI_DATATYPE_FLT64, zaxisP->vctsize, zaxisP->vct);
-      serializePack(&d, 1, CDI_DATATYPE_UINT32,
+      d = cdiCheckSum(DATATYPE_FLT64, zaxisP->vctsize, zaxisP->vct);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -70605,11 +70098,11 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
                         packBuffer, packBufferSize, packBufferPos, context);
   }
 
-  serializePack(&zaxisP->positive, 1, CDI_DATATYPE_UCHAR,
+  serializePack(&zaxisP->positive, 1, DATATYPE_UCHAR,
                 packBuffer, packBufferSize, packBufferPos, context);
 
   if (memberMask & zaxisHasUUIDFlag)
-    serializePack(zaxisP->uuid, CDI_UUID_SIZE, CDI_DATATYPE_UCHAR,
+    serializePack(zaxisP->uuid, CDI_UUID_SIZE, DATATYPE_UCHAR,
                   packBuffer, packBufferSize, packBufferPos, context);
 
 }
@@ -70631,7 +70124,7 @@ void cdiZaxisGetIndexList(unsigned nzaxis, int *zaxisResHs)
  * require-trailing-newline: t
  * End:
  */
-   static const char cdi_libvers[] = "1.9.0" " of " "Jun 19 2017"" " "10:32:27";
+   static const char cdi_libvers[] = "1.7.2" " of " "Jun  7 2016"" " "20:09:57";
 const char *cdiLibraryVersion(void)
 {
   return (cdi_libvers);
@@ -71235,7 +70728,7 @@ if (e>s) {                           /* Need this to handle NULL string.*/
 } return s; }
 
 #ifndef __CF__KnR
-static int num_elem(const char *strv, unsigned elem_len, int term_char, int num_term);
+static int num_elem(char *strv, unsigned elem_len, int term_char, int num_term);
 #endif
 /* kill_trailingn(s,t,e) will kill the trailing t's in string s. e normally 
 points to the terminating '\0' of s, but may actually point to anywhere in s.
@@ -71252,7 +70745,8 @@ else if (e>s) {                      /* Watch out for neg. length string.*/
   while (e>s && *--e==t){;}          /* Don't follow t's past beginning. */
   e[*e==t?0:1] = '\0';               /* Handle s[0]=t correctly.       */
 }
-(void)num_elem;  /* to prevent not used warnings in gcc (added by TJ) */
+if (0)  /* to prevent not used warnings in gcc (added by TJ) */
+  num_elem("", 0, '\0', 1);
 
  return s; }
 
@@ -71302,7 +70796,7 @@ typedef DSC$DESCRIPTOR_A(1) fstringvector;
 #define NUM_ELEM_ARG(B) *_2(A,B),_NUM_ELEM_ARG
 #define TERM_CHARS(A,B) A,B
 #ifndef __CF__KnR
-static int num_elem(const char *strv, unsigned elem_len, int term_char, int num_term)
+static int num_elem(char *strv, unsigned elem_len, int term_char, int num_term)
 #else
 static int num_elem(      strv,          elem_len,     term_char,     num_term)
                     char *strv; unsigned elem_len; int term_char; int num_term;
@@ -71321,10 +70815,10 @@ for (num=0; ; num++) {
   if (i==(unsigned)num_term) break;
   else strv += elem_len-i;
 }
-/* to prevent not used warnings in gcc (added by ROOT, changed by TJ
- * because of unreachable warnings from clang) */
-(void)c2fstrv; (void)f2cstrv; (void)kill_trailing;
-(void)vkill_trailing; (void)num_elem;
+if (0) {  /* to prevent not used warnings in gcc (added by ROOT) */
+   c2fstrv(0, 0, 0, 0); f2cstrv(0, 0, 0, 0); kill_trailing(0, 0);
+   vkill_trailing(0, 0, 0, 0); num_elem(0, 0, 0, 0);
+}
 return (int)num;
 }
 /* #endif removed 2/10/98 (CFITSIO) */
@@ -73215,19 +72709,7 @@ string. */
 #if defined (HAVE_CF_INTERFACE)
 
 #if ! defined (__CFORTRAN_LOADED)
-#  if defined __clang__
-#    pragma GCC diagnostic push
-#    pragma GCC diagnostic ignored "-Wreserved-id-macro"
-#  endif
 #  include "cfortran.h"
-#  if defined __clang__
-#    pragma GCC diagnostic pop
-#  endif
-#endif
-/* These functions are meant to be called from Fortran and don't
- * need an interface declaration in a C header. */
-#if defined __clang__
-#  pragma GCC diagnostic ignored "-Wmissing-prototypes"
 #endif
 
 
@@ -73350,7 +72832,7 @@ FCALLSCFUN1 (STRING, streamFilename, STREAMFILENAME, streamfilename, INT)
 FCALLSCFUN1 (STRING, streamFilesuffix, STREAMFILESUFFIX, streamfilesuffix, INT)
 FCALLSCFUN1 (INT, streamInqNvars, STREAMINQNVARS, streaminqnvars, INT)
 
-/*  STREAM var I/O routines (random access)  */
+/*  STREAM var I/O routines  */
 
 FCALLSCSUB4 (streamWriteVar, STREAMWRITEVAR, streamwritevar, INT, INT, DOUBLEV, INT)
 FCALLSCSUB4 (streamWriteVarF, STREAMWRITEVARF, streamwritevarf, INT, INT, FLOATV, INT)
@@ -73362,7 +72844,7 @@ FCALLSCSUB5 (streamReadVarSlice, STREAMREADVARSLICE, streamreadvarslice, INT, IN
 FCALLSCSUB5 (streamReadVarSliceF, STREAMREADVARSLICEF, streamreadvarslicef, INT, INT, INT, FLOATV, PINT)
 FCALLSCSUB5 (streamWriteVarChunk, STREAMWRITEVARCHUNK, streamwritevarchunk, INT, INT, INTVV, DOUBLEV, INT)
 
-/*  STREAM record I/O routines (sequential access)  */
+/*  STREAM record I/O routines  */
 
 FCALLSCSUB3 (streamDefRecord, STREAMDEFRECORD, streamdefrecord, INT, INT, INT)
 FCALLSCSUB3 (streamInqRecord, STREAMINQRECORD, streaminqrecord, INT, PINT, PINT)
@@ -73503,18 +72985,17 @@ FCALLSCFUN2 (STRING, vlistInqVarNamePtr, VLISTINQVARNAMEPTR, vlistinqvarnameptr,
 FCALLSCFUN2 (STRING, vlistInqVarLongnamePtr, VLISTINQVARLONGNAMEPTR, vlistinqvarlongnameptr, INT, INT)
 FCALLSCFUN2 (STRING, vlistInqVarUnitsPtr, VLISTINQVARUNITSPTR, vlistinqvarunitsptr, INT, INT)
 
-/*  CDI attributes  */
+/*  VLIST attributes  */
 
-FCALLSCFUN3 (INT, cdiInqNatts, CDIINQNATTS, cdiinqnatts, INT, INT, PINT)
-FCALLSCFUN6 (INT, cdiInqAtt, CDIINQATT, cdiinqatt, INT, INT, INT, PSTRING, PINT, PINT)
-FCALLSCFUN3 (INT, cdiDelAtt, CDIDELATT, cdidelatt, INT, INT, STRING)
-FCALLSCFUN4 (INT, cdiCopyAtts, CDICOPYATTS, cdicopyatts, INT, INT, INT, INT)
-FCALLSCFUN6 (INT, cdiDefAttInt, CDIDEFATTINT, cdidefattint, INT, INT, STRING, INT, INT, INTV)
-FCALLSCFUN6 (INT, cdiDefAttFlt, CDIDEFATTFLT, cdidefattflt, INT, INT, STRING, INT, INT, DOUBLEV)
-FCALLSCFUN5 (INT, cdiDefAttTxt, CDIDEFATTTXT, cdidefatttxt, INT, INT, STRING, INT, PPSTRING)
-FCALLSCFUN5 (INT, cdiInqAttInt, CDIINQATTINT, cdiinqattint, INT, INT, STRING, INT, INTV)
-FCALLSCFUN5 (INT, cdiInqAttFlt, CDIINQATTFLT, cdiinqattflt, INT, INT, STRING, INT, DOUBLEV)
-FCALLSCFUN5 (INT, cdiInqAttTxt, CDIINQATTTXT, cdiinqatttxt, INT, INT, STRING, INT, PPSTRING)
+FCALLSCFUN3 (INT, vlistInqNatts, VLISTINQNATTS, vlistinqnatts, INT, INT, PINT)
+FCALLSCFUN6 (INT, vlistInqAtt, VLISTINQATT, vlistinqatt, INT, INT, INT, PSTRING, PINT, PINT)
+FCALLSCFUN3 (INT, vlistDelAtt, VLISTDELATT, vlistdelatt, INT, INT, STRING)
+FCALLSCFUN6 (INT, vlistDefAttInt, VLISTDEFATTINT, vlistdefattint, INT, INT, STRING, INT, INT, INTV)
+FCALLSCFUN6 (INT, vlistDefAttFlt, VLISTDEFATTFLT, vlistdefattflt, INT, INT, STRING, INT, INT, DOUBLEV)
+FCALLSCFUN5 (INT, vlistDefAttTxt, VLISTDEFATTTXT, vlistdefatttxt, INT, INT, STRING, INT, PPSTRING)
+FCALLSCFUN5 (INT, vlistInqAttInt, VLISTINQATTINT, vlistinqattint, INT, INT, STRING, INT, INTV)
+FCALLSCFUN5 (INT, vlistInqAttFlt, VLISTINQATTFLT, vlistinqattflt, INT, INT, STRING, INT, DOUBLEV)
+FCALLSCFUN5 (INT, vlistInqAttTxt, VLISTINQATTTXT, vlistinqatttxt, INT, INT, STRING, INT, PPSTRING)
 
 /*  GRID routines  */
 
@@ -73525,13 +73006,10 @@ FCALLSCSUB2 (gridDefMaskGME, GRIDDEFMASKGME, griddefmaskgme, INT, INTV)
 FCALLSCFUN2 (INT, gridInqMaskGME, GRIDINQMASKGME, gridinqmaskgme, INT, INTV)
 FCALLSCSUB2 (gridDefMask, GRIDDEFMASK, griddefmask, INT, INTV)
 FCALLSCFUN2 (INT, gridInqMask, GRIDINQMASK, gridinqmask, INT, INTV)
-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)
-FCALLSCSUB2 (gridDefProj, GRIDDEFPROJ, griddefproj, INT, INT)
-FCALLSCFUN1 (INT, gridInqProj, GRIDINQPROJ, gridinqproj, INT)
-FCALLSCFUN1 (INT, gridInqProjType, GRIDINQPROJTYPE, gridinqprojtype, INT)
 FCALLSCFUN1 (INT, gridInqType, GRIDINQTYPE, gridinqtype, INT)
 FCALLSCFUN1 (INT, gridInqSize, GRIDINQSIZE, gridinqsize, INT)
 FCALLSCSUB2 (gridDefXsize, GRIDDEFXSIZE, griddefxsize, INT, INT)
@@ -73542,20 +73020,13 @@ FCALLSCSUB2 (gridDefNP, GRIDDEFNP, griddefnp, INT, INT)
 FCALLSCFUN1 (INT, gridInqNP, GRIDINQNP, gridinqnp, INT)
 FCALLSCSUB2 (gridDefXvals, GRIDDEFXVALS, griddefxvals, INT, DOUBLEV)
 FCALLSCFUN2 (INT, gridInqXvals, GRIDINQXVALS, gridinqxvals, INT, DOUBLEV)
-FCALLSCFUN1 (INT, gridInqXIsc, GRIDINQXISC, gridinqxisc, INT)
 FCALLSCSUB2 (gridDefYvals, GRIDDEFYVALS, griddefyvals, INT, DOUBLEV)
 FCALLSCFUN2 (INT, gridInqYvals, GRIDINQYVALS, gridinqyvals, INT, DOUBLEV)
-FCALLSCFUN1 (INT, gridInqYIsc, GRIDINQYISC, gridinqyisc, INT)
 
 /*  CDI grid string key values  */
 
-
-/*  CDI zaxis string key values  */
-
-FCALLSCFUN4 (INT, cdiGridDefKeyStr, CDIGRIDDEFKEYSTR, cdigriddefkeystr, INT, INT, INT, STRING)
-FCALLSCFUN4 (INT, cdiGridInqKeyStr, CDIGRIDINQKEYSTR, cdigridinqkeystr, INT, INT, INT, PSTRING)
-FCALLSCFUN3 (INT, cdiZaxisDefKeyFlt, CDIZAXISDEFKEYFLT, cdizaxisdefkeyflt, INT, INT, DOUBLE)
-FCALLSCFUN3 (INT, cdiZaxisInqKeyFlt, CDIZAXISINQKEYFLT, cdizaxisinqkeyflt, INT, INT, PDOUBLE)
+FCALLSCFUN4 (INT, cdiGridDefString, CDIGRIDDEFSTRING, cdigriddefstring, INT, INT, INT, STRING)
+FCALLSCFUN4 (INT, cdiGridInqString, CDIGRIDINQSTRING, cdigridinqstring, INT, INT, INT, PSTRING)
 FCALLSCSUB2 (gridDefXname, GRIDDEFXNAME, griddefxname, INT, STRING)
 FCALLSCSUB2 (gridInqXname, GRIDINQXNAME, gridinqxname, INT, PSTRING)
 FCALLSCSUB2 (gridDefXlongname, GRIDDEFXLONGNAME, griddefxlongname, INT, STRING)
@@ -73577,9 +73048,27 @@ FCALLSCFUN2 (DOUBLE, gridInqYval, GRIDINQYVAL, gridinqyval, INT, INT)
 FCALLSCFUN1 (DOUBLE, gridInqXinc, GRIDINQXINC, gridinqxinc, INT)
 FCALLSCFUN1 (DOUBLE, gridInqYinc, GRIDINQYINC, gridinqyinc, INT)
 FCALLSCFUN1 (INT, gridIsCircular, GRIDISCIRCULAR, gridiscircular, INT)
+FCALLSCFUN1 (INT, gridIsRotated, GRIDISROTATED, gridisrotated, INT)
+FCALLSCSUB2 (gridDefXpole, GRIDDEFXPOLE, griddefxpole, INT, DOUBLE)
+FCALLSCFUN1 (DOUBLE, gridInqXpole, GRIDINQXPOLE, gridinqxpole, INT)
+FCALLSCSUB2 (gridDefYpole, GRIDDEFYPOLE, griddefypole, INT, DOUBLE)
+FCALLSCFUN1 (DOUBLE, gridInqYpole, GRIDINQYPOLE, gridinqypole, INT)
+FCALLSCSUB2 (gridDefAngle, GRIDDEFANGLE, griddefangle, INT, DOUBLE)
+FCALLSCFUN1 (DOUBLE, gridInqAngle, GRIDINQANGLE, gridinqangle, INT)
 FCALLSCFUN1 (INT, gridInqTrunc, GRIDINQTRUNC, gridinqtrunc, INT)
 FCALLSCSUB2 (gridDefTrunc, GRIDDEFTRUNC, griddeftrunc, INT, INT)
 
+/*  Hexagonal GME grid  */
+
+FCALLSCSUB2 (gridDefGMEnd, GRIDDEFGMEND, griddefgmend, INT, INT)
+FCALLSCFUN1 (INT, gridInqGMEnd, GRIDINQGMEND, gridinqgmend, INT)
+FCALLSCSUB2 (gridDefGMEni, GRIDDEFGMENI, griddefgmeni, INT, INT)
+FCALLSCFUN1 (INT, gridInqGMEni, GRIDINQGMENI, gridinqgmeni, INT)
+FCALLSCSUB2 (gridDefGMEni2, GRIDDEFGMENI2, griddefgmeni2, INT, INT)
+FCALLSCFUN1 (INT, gridInqGMEni2, GRIDINQGMENI2, gridinqgmeni2, INT)
+FCALLSCSUB2 (gridDefGMEni3, GRIDDEFGMENI3, griddefgmeni3, INT, INT)
+FCALLSCFUN1 (INT, gridInqGMEni3, GRIDINQGMENI3, gridinqgmeni3, INT)
+
 /*  Reference of an unstructured grid  */
 
 FCALLSCSUB2 (gridDefNumber, GRIDDEFNUMBER, griddefnumber, INT, INT)
@@ -73591,20 +73080,20 @@ FCALLSCFUN2 (INT, gridInqReference, GRIDINQREFERENCE, gridinqreference, INT, PST
 FCALLSCSUB2 (gridDefUUID, GRIDDEFUUID, griddefuuid, INT, PVOID)
 FCALLSCSUB2 (gridInqUUID, GRIDINQUUID, gridinquuid, INT, PVOID)
 
-/*  Rotated Lon/Lat grid  */
+/*  Lambert Conformal Conic grid (GRIB version)  */
 
-FCALLSCSUB4 (gridDefParamRLL, GRIDDEFPARAMRLL, griddefparamrll, INT, DOUBLE, DOUBLE, DOUBLE)
-FCALLSCSUB4 (gridInqParamRLL, GRIDINQPARAMRLL, gridinqparamrll, INT, PDOUBLE, PDOUBLE, PDOUBLE)
+FCALLSCSUB10 (gridDefLCC, GRIDDEFLCC, griddeflcc, INT, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, INT, INT)
+FCALLSCSUB10 (gridInqLCC, GRIDINQLCC, gridinqlcc, INT, PDOUBLE, PDOUBLE, PDOUBLE, PDOUBLE, PDOUBLE, PDOUBLE, PDOUBLE, PINT, PINT)
 
-/*  Hexagonal GME grid  */
+/*  Lambert Conformal Conic 2 grid (PROJ version)  */
 
-FCALLSCSUB5 (gridDefParamGME, GRIDDEFPARAMGME, griddefparamgme, INT, INT, INT, INT, INT)
-FCALLSCSUB5 (gridInqParamGME, GRIDINQPARAMGME, gridinqparamgme, INT, PINT, PINT, PINT, PINT)
+FCALLSCSUB6 (gridDefLcc2, GRIDDEFLCC2, griddeflcc2, INT, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE)
+FCALLSCSUB6 (gridInqLcc2, GRIDINQLCC2, gridinqlcc2, INT, PDOUBLE, PDOUBLE, PDOUBLE, PDOUBLE, PDOUBLE)
 
-/*  Lambert Conformal Conic grid (GRIB version)  */
+/*  Lambert Azimuthal Equal Area grid  */
 
-FCALLSCSUB12 (gridDefParamLCC, GRIDDEFPARAMLCC, griddefparamlcc, INT, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE)
-FCALLSCFUN12 (INT, gridInqParamLCC, GRIDINQPARAMLCC, gridinqparamlcc, INT, DOUBLE, PDOUBLE, PDOUBLE, PDOUBLE, PDOUBLE, PDOUBLE, PDOUBLE, PDOUBLE, PDOUBLE, PDOUBLE, PDOUBLE)
+FCALLSCSUB4 (gridDefLaea, GRIDDEFLAEA, griddeflaea, INT, DOUBLE, DOUBLE, DOUBLE)
+FCALLSCSUB4 (gridInqLaea, GRIDINQLAEA, gridinqlaea, INT, PDOUBLE, PDOUBLE, PDOUBLE)
 FCALLSCSUB2 (gridDefArea, GRIDDEFAREA, griddefarea, INT, DOUBLEV)
 FCALLSCSUB2 (gridInqArea, GRIDINQAREA, gridinqarea, INT, DOUBLEV)
 FCALLSCFUN1 (INT, gridHasArea, GRIDHASAREA, gridhasarea, INT)
@@ -73619,23 +73108,19 @@ FCALLSCSUB2 (gridInqRowlon, GRIDINQROWLON, gridinqrowlon, INT, INTV)
 FCALLSCSUB2 (gridChangeType, GRIDCHANGETYPE, gridchangetype, INT, INT)
 FCALLSCSUB2 (gridDefComplexPacking, GRIDDEFCOMPLEXPACKING, griddefcomplexpacking, INT, INT)
 FCALLSCFUN1 (INT, gridInqComplexPacking, GRIDINQCOMPLEXPACKING, gridinqcomplexpacking, INT)
-FCALLSCSUB2 (gridDefUvRelativeToGrid, GRIDDEFUVRELATIVETOGRID, griddefuvrelativetogrid, INT, INT)
-FCALLSCFUN1 (INT, gridInqUvRelativeToGrid, GRIDINQUVRELATIVETOGRID, gridinquvrelativetogrid, INT)
-FCALLSCSUB2 (gridDefScanningMode, GRIDDEFSCANNINGMODE, griddefscanningmode, INT, INT)
-FCALLSCFUN1 (INT, gridInqScanningMode, GRIDINQSCANNINGMODE, gridinqscanningmode, INT)
 
 /*  ZAXIS routines  */
 
 FCALLSCSUB2 (zaxisName, ZAXISNAME, zaxisname, INT, PSTRING)
-FCALLSCFUN1 (STRING, zaxisNamePtr, ZAXISNAMEPTR, zaxisnameptr, INT)
 FCALLSCFUN2 (INT, zaxisCreate, ZAXISCREATE, zaxiscreate, INT, INT)
 FCALLSCSUB1 (zaxisDestroy, ZAXISDESTROY, zaxisdestroy, INT)
 FCALLSCFUN1 (INT, zaxisInqType, ZAXISINQTYPE, zaxisinqtype, INT)
 FCALLSCFUN1 (INT, zaxisInqSize, ZAXISINQSIZE, zaxisinqsize, INT)
 FCALLSCFUN1 (INT, zaxisDuplicate, ZAXISDUPLICATE, zaxisduplicate, INT)
-FCALLSCSUB1 (zaxisPrint, ZAXISPRINT, zaxisprint, INT)
+FCALLSCSUB2 (zaxisResize, ZAXISRESIZE, zaxisresize, INT, INT)
+FCALLSCSUB2 (zaxisPrint, ZAXISPRINT, zaxisprint, INT, INT)
 FCALLSCSUB2 (zaxisDefLevels, ZAXISDEFLEVELS, zaxisdeflevels, INT, DOUBLEV)
-FCALLSCFUN2 (INT, zaxisInqLevels, ZAXISINQLEVELS, zaxisinqlevels, INT, DOUBLEV)
+FCALLSCSUB2 (zaxisInqLevels, ZAXISINQLEVELS, zaxisinqlevels, INT, DOUBLEV)
 FCALLSCSUB3 (zaxisDefLevel, ZAXISDEFLEVEL, zaxisdeflevel, INT, INT, DOUBLE)
 FCALLSCFUN2 (DOUBLE, zaxisInqLevel, ZAXISINQLEVEL, zaxisinqlevel, INT, INT)
 FCALLSCSUB2 (zaxisDefNlevRef, ZAXISDEFNLEVREF, zaxisdefnlevref, INT, INT)
@@ -73644,8 +73129,11 @@ FCALLSCSUB2 (zaxisDefNumber, ZAXISDEFNUMBER, zaxisdefnumber, INT, INT)
 FCALLSCFUN1 (INT, zaxisInqNumber, ZAXISINQNUMBER, zaxisinqnumber, INT)
 FCALLSCSUB2 (zaxisDefUUID, ZAXISDEFUUID, zaxisdefuuid, INT, PVOID)
 FCALLSCSUB2 (zaxisInqUUID, ZAXISINQUUID, zaxisinquuid, INT, PVOID)
-FCALLSCFUN4 (INT, cdiZaxisDefKeyStr, CDIZAXISDEFKEYSTR, cdizaxisdefkeystr, INT, INT, INT, STRING)
-FCALLSCFUN4 (INT, cdiZaxisInqKeyStr, CDIZAXISINQKEYSTR, cdizaxisinqkeystr, INT, INT, INT, PSTRING)
+
+/*  CDI zaxis string key values  */
+
+FCALLSCFUN4 (INT, cdiZaxisDefString, CDIZAXISDEFSTRING, cdizaxisdefstring, INT, INT, INT, STRING)
+FCALLSCFUN4 (INT, cdiZaxisInqString, CDIZAXISINQSTRING, cdizaxisinqstring, INT, INT, INT, PSTRING)
 FCALLSCSUB2 (zaxisDefName, ZAXISDEFNAME, zaxisdefname, INT, STRING)
 FCALLSCSUB2 (zaxisInqName, ZAXISINQNAME, zaxisinqname, INT, PSTRING)
 FCALLSCSUB2 (zaxisDefLongname, ZAXISDEFLONGNAME, zaxisdeflongname, INT, STRING)
@@ -73653,6 +73141,8 @@ FCALLSCSUB2 (zaxisInqLongname, ZAXISINQLONGNAME, zaxisinqlongname, INT, PSTRING)
 FCALLSCSUB2 (zaxisDefUnits, ZAXISDEFUNITS, zaxisdefunits, INT, STRING)
 FCALLSCSUB2 (zaxisInqUnits, ZAXISINQUNITS, zaxisinqunits, INT, PSTRING)
 FCALLSCSUB2 (zaxisInqStdname, ZAXISINQSTDNAME, zaxisinqstdname, INT, PSTRING)
+FCALLSCSUB2 (zaxisDefPsName, ZAXISDEFPSNAME, zaxisdefpsname, INT, STRING)
+FCALLSCSUB2 (zaxisInqPsName, ZAXISINQPSNAME, zaxisinqpsname, INT, PSTRING)
 FCALLSCSUB2 (zaxisDefPrec, ZAXISDEFPREC, zaxisdefprec, INT, INT)
 FCALLSCFUN1 (INT, zaxisInqPrec, ZAXISINQPREC, zaxisinqprec, INT)
 FCALLSCSUB2 (zaxisDefPositive, ZAXISDEFPOSITIVE, zaxisdefpositive, INT, INT)
@@ -73786,7 +73276,4 @@ FCALLSCFUN4 (INT, subtypeInqAttribute, SUBTYPEINQATTRIBUTE, subtypeinqattribute,
 FCALLSCFUN2 (INT, vlistInqVarSubtype, VLISTINQVARSUBTYPE, vlistinqvarsubtype, INT, INT)
 FCALLSCSUB3 (gribapiLibraryVersion, GRIBAPILIBRARYVERSION, gribapilibraryversion, PINT, PINT, PINT)
 
-#if defined __clang__
-#  pragma GCC diagnostic pop
-#endif
 #endif
diff --git a/libcdi/src/cgribexlib.c b/libcdi/src/cgribexlib.c
index 31c37c6..351fd45 100644
--- a/libcdi/src/cgribexlib.c
+++ b/libcdi/src/cgribexlib.c
@@ -1,7 +1,7 @@
 
-/* Automatically generated by m214003 at 2017-07-12, do not edit */
+/* Automatically generated by m214003 at 2017-09-29, do not edit */
 
-/* CGRIBEXLIB_VERSION="1.8.1" */
+/* CGRIBEXLIB_VERSION="1.9.0" */
 
 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5) || defined (__clang__)
 #pragma GCC diagnostic push
@@ -54,23 +54,23 @@
 
 
 #if ! defined   (CGRIBEX_H)
-#  include "cgribex.h"
+#include "cgribex.h"
 #endif
 #if ! defined   (ERROR_H)
-#  include "error.h"
+#include "error.h"
 #endif
 #if ! defined   (DTYPES_H)
-#  include "dtypes.h"
+#include "dtypes.h"
 #endif
 
 
 #if ! defined   (UCHAR)
-#  define  UCHAR  unsigned char
+#define  UCHAR  unsigned char
 #endif
 
 
 #if defined (CRAY) || defined (SX) || defined (__uxpch__)
-#  define VECTORCODE
+#define VECTORCODE
 #endif
 
 
@@ -114,12 +114,13 @@
 
 /* dummy use of unused parameters to silence compiler warnings */
 #ifndef UNUSED
-#  define  UNUSED(x) (void)(x)
+#define  UNUSED(x) (void)(x)
 #endif
 
-#define  JP23SET    0x7FFFFF  /* 2**23 - 1 (---> 8388607)  */
+#define  JP24SET    0xFFFFFF  /* 2**24     (---> 16777215) */
+#define  JP23SET    0x7FFFFF  /* 2**23 - 1 (--->  8388607) */
 
-#define  POW_2_M24  0.000000059604644775390625  /*  pow(2.0, -24.0) */
+#define  POW_2_M24  0.000000059604644775390625  /* pow(2.0, -24.0) */
 
 #ifdef __cplusplus
 extern "C" {
@@ -127,8 +128,7 @@ extern "C" {
 
 #define intpow2(x) (ldexp(1.0, (x)))
 
-int gribrec_len(unsigned b1, unsigned b2, unsigned b3);
-int correct_bdslen(int bdslen, long recsize, long gribpos);
+unsigned correct_bdslen(unsigned bdslen, long recsize, long gribpos);
 
 /* CDI converter routines */
 
@@ -149,11 +149,12 @@ int     cdiEncodeTime(int hour, int minute, int second);
 /* 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
+#define  CALENDAR_GREGORIAN       1
+#define  CALENDAR_PROLEPTIC       2
+#define  CALENDAR_360DAYS         3
+#define  CALENDAR_365DAYS         4
+#define  CALENDAR_366DAYS         5
+#define  CALENDAR_NONE            6
 
 extern FILE *grprsm;
 
@@ -229,10 +230,10 @@ int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **i
 #define  GET_INT1(a)        ((1-(int) ((unsigned) (a & 128) >> 6)) * (int) (a&127))
 
 /* 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))
+#define  GET_UINT4(a,b,c,d) ((unsigned) ((a << 24) + (b << 16) + (c << 8) + (d)))
+#define  GET_UINT3(a,b,c)   ((unsigned) ((a << 16) + (b << 8)  + (c)))
+#define  GET_UINT2(a,b)     ((unsigned) ((a << 8)  + (b)))
+#define  GET_UINT1(a)       ((unsigned)  (a))
 
 #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')
@@ -241,7 +242,7 @@ int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **i
 
 /* GRIB1 Section 0: Indicator Section (IS) */
 
-#define  GRIB1_SECLEN(s)     GET_INT3(s[ 4], s[ 5], s[ 6])
+#define  GRIB1_SECLEN(s)     GET_UINT3(s[ 4], s[ 5], s[ 6])
 #define  GRIB_EDITION(s)     GET_UINT1(s[ 7])
 
 /* GRIB1 Section 1: Product Definition Section (PDS) */
@@ -279,7 +280,7 @@ int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **i
 
 /* GRIB1 Section 2: Grid Description Section (GDS) */
 
-#define  GDS_Len             ((gds) == NULL ? 0 : GET_UINT3(gds[ 0], gds[ 1], gds[ 2]))
+#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)
@@ -333,7 +334,7 @@ int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **i
 
 /* GRIB1 Section 3: Bit Map Section (BMS) */
 
-#define  BMS_Len	     ((bms) == NULL ? 0 : (int) (bms[0]<<16)+(bms[1]<<8)+bms[2])
+#define  BMS_Len	     ((bms) == NULL ? 0 : GET_UINT3(bms[0], bms[1], bms[2]))
 #define  BMS_UnusedBits      (bms[3])
 #define  BMS_Numeric         
 #define  BMS_Bitmap	     ((bms) == NULL ? NULL : (bms)+6)
@@ -341,10 +342,10 @@ int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **i
 
 /* GRIB1 Section 4: Binary Data Section (BDS) */
 
-#define  BDS_Len	    ((int) ((bds[0]<<16)+(bds[1]<<8)+bds[2]))
+#define  BDS_Len	    GET_UINT3(bds[0], bds[1], 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_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]))
@@ -1893,21 +1894,11 @@ double decfp2(int kexp, int kmant)
         - replace pow(16.0, (double)(iexp - 64)) by pow16m64tab[iexp]
   */
 
-  double pval;
-  //extern int CGRIBEX_Debug;
   /* ----------------------------------------------------------------- */
   /*   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;
-    }
+  if ( (kexp == 128) || (kexp == 0) || (kexp == 255) ) return 0.0;
 
   /* ----------------------------------------------------------------- */
   /*   Section 2 . Convert other values.                               */
@@ -1915,7 +1906,7 @@ double decfp2(int kexp, int kmant)
 
   /*  Sign of value. */
 
-  int iexp  = kexp,
+  int iexp = kexp,
     isign = (iexp < 128) * 2 - 1;
 
   iexp -= iexp < 128 ? 0 : 128;
@@ -1926,17 +1917,13 @@ double decfp2(int kexp, int kmant)
 
   iexp -= 64;
 
-  pval = ldexp(1.0, 4 * iexp) * isign * POW_2_M24 * kmant;
+  double pval = ldexp(1.0, 4 * iexp) * isign * POW_2_M24 * kmant;
 
   /* ----------------------------------------------------------------- */
   /*   Section 9. Return to calling routine.                           */
   /* ----------------------------------------------------------------- */
 
-LABEL900:
-
-  //if ( CGRIBEX_Debug ) Message("Returned value = %f", pval);
-
-  return (pval);
+  return pval;
 } /* decfp2 */
 #include <stdint.h>
 #include <string.h>
@@ -3720,7 +3707,6 @@ void gribPrintSec4Wave(int *isec4)
     }
 }
 #if defined (HAVE_CONFIG_H)
-#  include "config.h"
 #endif
 
 #include <string.h>
@@ -3755,34 +3741,6 @@ off_t gribGetPos(int fileID)
 }
 
 
-int gribCheckFiletype(int fileID)
-{
-  int found = 0;
-  char buffer[4];
-
-  if ( fileRead(fileID, buffer, 4) != 4 ) return found;
-
-  if ( memcmp(buffer, "GRIB", 4) == 0 )
-    {
-      found = 1;
-      if ( CGRIBEX_Debug ) Message("found GRIB file = %s", fileInqName(fileID));
-    }
-  else
-    {
-      long offset;
-      int ierr = gribFileSeek(fileID, &offset);
-      fileRewind(fileID);
-      if ( !ierr )
-	{
-	  found = 1;
-	  if ( CGRIBEX_Debug ) Message("found seek GRIB file = %s", fileInqName(fileID));
-	}
-    }
-
-  return found;
-}
-
-
 int gribCheckSeek(int fileID, long *offset, int *version)
 {
   int ierr = gribFileSeek(fileID, offset);
@@ -3799,59 +3757,6 @@ int gribCheckSeek(int fileID, long *offset, int *version)
 }
 
 
-int gribFileSeekOld(int fileID, long *offset)
-{
-  /* position file pointer after GRIB */
-  enum { buffersize = 4096 };
-  unsigned char buffer[buffersize];
-  int retry = 4096;
-
-  *offset = 0;
-
-  void *fileptr = filePtr(fileID);
-
-  for ( size_t i = 0; i < 4; ++i)
-    {
-      int ch = filePtrGetc(fileptr);
-      if ( ch == EOF ) return (-1);
-      buffer[i] = (unsigned char)ch;
-    }
-  /*
-  fileRead(fileID, buffer, 4);
-  */
-
-  while ( retry-- )
-    {
-      size_t i;
-      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
-	    {
-	      int ch = filePtrGetc(fileptr); if ( ch == EOF ) return (-1); buffer[i+4] = (unsigned char)ch;
-	      (*offset)++;
-	    }
-	}
-      buffer[0] = buffer[i  ];
-      buffer[1] = buffer[i+1];
-      buffer[2] = buffer[i+2];
-      buffer[3] = buffer[i+3];
-    }
-
-  if ( CGRIBEX_Debug ) Message("record offset = %d", (int) *offset);
-
-  return 1;
-}
-
-
 int gribFileSeek(int fileID, long *offset)
 {
   /* position file pointer after GRIB */
@@ -3867,80 +3772,30 @@ int gribFileSeek(int fileID, long *offset)
   while ( retry-- )
     {
       ch = filePtrGetc(fileptr);
-      if ( ch == EOF ) return (-1);
+      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);
-
-  return 1;
-}
-
-
-int gribFileSeekTest(int fileID, long *offset)
-{
-  /* position file pointer after GRIB */
-  const long GRIB = 0x47524942L;
-  long code = 0;
-  int ch;
-  int i = 0;
-  enum { buffersize = 8 };
-  unsigned char buffer[buffersize];
-  unsigned long retry = 4096L*4096L;
-  int nread = 0;
-
-  *offset = 0;
-
-  void *fileptr = filePtr(fileID);
-
-  while ( retry-- )
-    {
-      if ( i >= nread )
-	{
-	  nread = (int) filePtrRead(fileptr, buffer, buffersize);
-	  if ( nread == 0 ) return (-1);
-	  i = 0;
-	}
-
-      ch = buffer[i++];
-      code = ( (code << 8) + ch ) & 0xFFFFFFFFL;
-
-      if ( code == GRIB )
-	{
-	  /* 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);
+	  if ( CGRIBEX_Debug ) Message("record offset = %ld", *offset);
+	  return 0;
 	}
 
       (*offset)++;
     }
 
-  if ( CGRIBEX_Debug ) Message("record offset = %d", (int) *offset);
+  if ( CGRIBEX_Debug ) Message("record offset = %ld", *offset);
 
   return 1;
 }
 
-static inline int
-read3ByteMSBFirst(void *fileptr)
+static inline
+unsigned read3ByteMSBFirst(void *fileptr)
 {
   unsigned b1 = (unsigned)(filePtrGetc(fileptr));
   unsigned b2 = (unsigned)(filePtrGetc(fileptr));
   unsigned b3 = (unsigned)(filePtrGetc(fileptr));
-  return (int)((b1 << 16) + (b2 << 8) + b3);
+  return GET_UINT3(b1, b2, b3);
 }
 
 
@@ -3950,31 +3805,23 @@ size_t gribReadSize(int fileID)
   void *fileptr = filePtr(fileID);
   off_t pos = fileGetPos(fileID); 
 
-  unsigned b1 = (unsigned) filePtrGetc(fileptr);
-  unsigned b2 = (unsigned) filePtrGetc(fileptr);
-  unsigned b3 = (unsigned) filePtrGetc(fileptr);
+  unsigned gribsize = read3ByteMSBFirst(fileptr);
 
-  int gribsize = gribrec_len(b1, b2, b3);
   int gribversion = filePtrGetc(fileptr);
 
-  if ( gribsize == 24 )
-    {
-      if ( gribversion != 1 && gribversion != 2 ) gribversion = 0;
-    }
+  if ( gribsize == 24 && gribversion != 1 && gribversion != 2 ) gribversion = 0;
 
-  if ( CGRIBEX_Debug )
-    Message("gribversion = %d", gribversion);
+  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 = 0;
+      unsigned gdssize = 0, bmssize = 0;
+      unsigned issize = 4, essize = 4;
 
-      pdssize = gribsize;
+      unsigned pdssize = gribsize;
       fileSetPos(fileID, (off_t) 3, SEEK_CUR);
-      if ( CGRIBEX_Debug ) Message("pdssize     = %d", pdssize);
-      flag = filePtrGetc(fileptr);
+      if ( CGRIBEX_Debug ) Message("pdssize     = %u", pdssize);
+      int flag = filePtrGetc(fileptr);
       if ( CGRIBEX_Debug ) Message("flag        = %d", flag);
   
       fileSetPos(fileID, (off_t) pdssize-8, SEEK_CUR);
@@ -3983,57 +3830,63 @@ size_t gribReadSize(int fileID)
 	{
 	  gdssize = read3ByteMSBFirst(fileptr);
 	  fileSetPos(fileID, (off_t) gdssize-3, SEEK_CUR);
-	  if ( CGRIBEX_Debug ) Message("gdssize     = %d", gdssize);
+	  if ( CGRIBEX_Debug ) Message("gdssize     = %u", gdssize);
 	}
 
       if ( flag & 64 )
 	{
 	  bmssize = read3ByteMSBFirst(fileptr);
 	  fileSetPos(fileID, (off_t) bmssize-3, SEEK_CUR);
-	  if ( CGRIBEX_Debug ) Message("bmssize     = %d", bmssize);
+	  if ( CGRIBEX_Debug ) Message("bmssize     = %u", bmssize);
 	}
 
-      bdssize = read3ByteMSBFirst(fileptr);
-      if ( CGRIBEX_Debug ) Message("bdssize     = %d", bdssize);
+      unsigned bdssize = read3ByteMSBFirst(fileptr);
+      if ( CGRIBEX_Debug ) Message("bdssize     = %u", bdssize);
 
       gribsize = issize + pdssize + gdssize + bmssize + bdssize + essize;
       rgribsize = (size_t) gribsize;
     }
   else if ( gribversion == 1 )
     {
-      if ( gribsize > JP23SET ) /* Large GRIB record */
+      if ( gribsize > JP23SET ) // Large GRIB record
 	{
-	  int pdssize = 0, gdssize = 0, bmssize = 0, bdssize = 0;
-	  int issize = 4, essize = 4;
-	  int flag;
-
-	  pdssize = read3ByteMSBFirst(fileptr);
-	  if ( CGRIBEX_Debug ) Message("pdssize     = %d", pdssize);
+	  unsigned pdssize = read3ByteMSBFirst(fileptr);
+	  if ( CGRIBEX_Debug ) Message("pdssize     = %u", pdssize);
 
+	  int flag;
 	  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);
 
+          unsigned gdssize = 0;
 	  if ( flag & 128 )
 	    {
 	      gdssize = read3ByteMSBFirst(fileptr);
 	      fileSetPos(fileID, (off_t) gdssize-3, SEEK_CUR);
-	      if ( CGRIBEX_Debug ) Message("gdssize     = %d", gdssize);
+	      if ( CGRIBEX_Debug ) Message("gdssize     = %u", gdssize);
 	    }
-	  
+
+          unsigned bmssize = 0;
 	  if ( flag & 64 )
 	    {
 	      bmssize = read3ByteMSBFirst(fileptr);
 	      fileSetPos(fileID, (off_t) bmssize-3, SEEK_CUR);
-	      if ( CGRIBEX_Debug ) Message("bmssize     = %d", bmssize);
+	      if ( CGRIBEX_Debug ) Message("bmssize     = %u", bmssize);
 	    }
 
-	  bdssize = read3ByteMSBFirst(fileptr);
-	  bdssize = correct_bdslen(bdssize, gribsize, issize+pdssize+gdssize+bmssize);
-	  if ( CGRIBEX_Debug ) Message("bdssize     = %d", bdssize);
+	  unsigned bdssize = read3ByteMSBFirst(fileptr);
+	  if ( CGRIBEX_Debug ) Message("bdssize     = %u", bdssize);
+          if ( bdssize <= 120 )
+            {
+              const int issize = 4;
+              gribsize &= JP23SET;
+              gribsize *= 120;
+              bdssize = correct_bdslen(bdssize, gribsize, issize+pdssize+gdssize+bmssize);
+              if ( CGRIBEX_Debug ) Message("bdssize     = %u", bdssize);
 
-	  gribsize = issize + pdssize + gdssize + bmssize + bdssize + essize;
+              gribsize = issize + pdssize + gdssize + bmssize + bdssize + 4;
+            }
 	}
       rgribsize = (size_t) gribsize;
     }
@@ -4064,7 +3917,7 @@ size_t gribReadSize(int fileID)
 size_t gribGetSize(int fileID)
 {
   long offset;
-  int 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!");
@@ -4087,11 +3940,11 @@ size_t gribGetSize(int fileID)
 int gribRead(int fileID, unsigned char *buffer, size_t *buffersize)
 {
   long offset;
-  int 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);
+      return -2;
     }
 
   if      ( ierr == -1 ) { *buffersize = 0; return -1; }
@@ -4126,7 +3979,7 @@ int gribRead(int fileID, unsigned char *buffer, size_t *buffersize)
 
 int gribWrite(int fileID, unsigned char *buffer, size_t buffersize)
 {
-  int  nwrite = 0;
+  int nwrite = 0;
 
   if ( (nwrite = (int)(fileWrite(fileID, buffer, buffersize))) != (int) buffersize )
     {
@@ -4136,25 +3989,6 @@ int gribWrite(int fileID, unsigned char *buffer, size_t buffersize)
 
   return nwrite;
 }
-
-
-int gribrec_len(unsigned b1, unsigned b2, unsigned b3)
-{
-  /*
-    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 = (int)((((b1&127) << 16)+(b2<<8) + b3));
-
-  if ( needRescaling ) gribsize *= 120;
-
-  return gribsize;
-}
-
 #include <string.h>
 #include <ctype.h>
 
@@ -5016,7 +4850,7 @@ void ref2ibm(double *pref, int kbits)
 #include <string.h>
 
 
-int correct_bdslen(int bdslen, long recsize, long gribpos)
+unsigned correct_bdslen(unsigned bdslen, long recsize, long gribpos)
 {
   /*
     If a very large product, the section 4 length field holds
@@ -5026,7 +4860,7 @@ int correct_bdslen(int bdslen, long recsize, long gribpos)
     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 = (int)(recsize - gribpos - bdslen);
+  if ( recsize > JP23SET && bdslen <= 120 ) bdslen = (unsigned)(recsize - gribpos - bdslen);
   return bdslen;
 }
 
@@ -5034,20 +4868,14 @@ int correct_bdslen(int bdslen, long recsize, long gribpos)
 int grib1Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **pdsp,
 		  unsigned char **gdsp, unsigned char **bmsp, unsigned char **bdsp, long *gribrecsize)
 {
-  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;
 
-  section = gribbuffer;
-  is = gribbuffer;
+  unsigned char *section = gribbuffer;
+  unsigned char *is = gribbuffer;
   if ( ! GRIB_START(section) )
     {
       fprintf(stderr, "Wrong GRIB indicator section: found >%c%c%c%c<\n",
@@ -5055,45 +4883,41 @@ int grib1Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **p
       return -1;
     }
 
-  recsize = gribrec_len(section[4], section[5], section[6]);
+  unsigned recsize = GET_UINT3(section[4], section[5], section[6]);
 
-  gribversion = GRIB_EDITION(section);
-  if ( GRIB1_SECLEN(section) == 24 && gribversion == 0 ) gribversion = 0;
+  int gribversion = GRIB_EDITION(section);
+  if ( recsize == 24 && gribversion == 0 ) gribversion = 0;
 
-  if ( gribversion == 1 )
-    grib1offset = 4;
-  else
-    grib1offset = 0;
+  unsigned grib1offset = (gribversion == 1) ? 4 : 0;
 
-  pds = is + 4 + grib1offset;
-  bufpointer = pds + PDS_Len;
-  gribsize += 4 + grib1offset + PDS_Len;
+  unsigned char *pds = is + 4 + grib1offset;
+  unsigned char *bufpointer = pds + PDS_Len;
+  unsigned gribsize = 4 + grib1offset + PDS_Len;
 
+  unsigned char *gds = NULL;
   if ( PDS_HAS_GDS )
     {
       gds = bufpointer;
       bufpointer += GDS_Len;
       gribsize += GDS_Len;
     }
-  else
-    {
-      gds = NULL;
-    }
 
+  unsigned char *bms = NULL;
   if ( PDS_HAS_BMS )
     {
       bms = bufpointer;
       bufpointer += BMS_Len;
       gribsize += BMS_Len;
     }
-  else
+
+  unsigned char *bds = bufpointer;
+  unsigned bdslen = BDS_Len;
+  if ( recsize > JP23SET && bdslen <= 120 )
     {
-      bms = NULL;
+      recsize &= JP23SET;
+      recsize *= 120;
+      bdslen = correct_bdslen(bdslen, recsize, gribsize);
     }
-
-  bds = bufpointer;
-  bdslen = BDS_Len;
-  bdslen = correct_bdslen(bdslen, recsize, gribsize);
   bufpointer += bdslen;
   gribsize += bdslen;
   gribsize += 4;
@@ -5104,15 +4928,13 @@ int grib1Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **p
   *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);
+      fprintf(stderr, "Inconsistent length of GRIB message (grib_buffer_size=%ld < grib_record_size=%u)!\n", gribbufsize, gribsize);
       return 1;
     }
 
-  /* end section - "7777" in ascii */
-  if ( !GRIB_FIN(bufpointer) )
+  if ( !GRIB_FIN(bufpointer) ) // end section - "7777" in ASCII
     {
       fprintf(stderr, "Missing GRIB end section: found >%c%c%c%c<\n",
 	      bufpointer[0], bufpointer[1], bufpointer[2], bufpointer[3]);
@@ -5127,14 +4949,6 @@ int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **i
 		  unsigned char **lusp, unsigned char **gdsp, unsigned char **pdsp,
 		  unsigned char **drsp, unsigned char **bmsp, unsigned char **bdsp)
 {
-  unsigned char *section;
-  long sec_len;
-  int sec_num;
-  int gribversion;
-  int i, msec;
-  long gribsize;
-  long grib_len = 0;
-
   UNUSED(gribbufsize);
 
   *idsp = NULL;
@@ -5145,8 +4959,8 @@ int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **i
   *bmsp = NULL;
   *bdsp = NULL;
 
-  section = gribbuffer;
-  sec_len = 16;
+  unsigned char *section = gribbuffer;
+  unsigned sec_len = 16;
 
   if ( !GRIB_START(section) )
     {
@@ -5155,22 +4969,22 @@ int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **i
       return -1;
     }
 
-  gribversion = GRIB_EDITION(section);
+  int gribversion = GRIB_EDITION(section);
   if ( gribversion != 2 )
     {
       fprintf(stderr, "wrong GRIB version %d\n", gribversion);
       return -1;      
     }
 
-  gribsize = 0;
-  for ( i = 0; i < 8; i++ ) gribsize = (gribsize << 8) | section[8+i];
+  unsigned gribsize = 0;
+  for ( int i = 0; i < 8; i++ ) gribsize = (gribsize << 8) | section[8+i];
 
-  grib_len += sec_len;
+  unsigned grib_len = sec_len;
   section  += sec_len;
 
   /* section 1 */
   sec_len = GRIB2_SECLEN(section);
-  sec_num = GRIB2_SECNUM(section);
+  int sec_num = GRIB2_SECNUM(section);
   //fprintf(stderr, "ids %d %ld\n", sec_num, sec_len);
 
   if ( sec_num != 1 )
@@ -5281,7 +5095,7 @@ int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **i
   section  += sec_len;
 
   /* skip multi GRIB sections */
-  msec = 1;
+  int msec = 1;
   while ( !GRIB_FIN(section) )
     {
       sec_len = GRIB2_SECLEN(section);
@@ -5313,16 +5127,11 @@ int grib2Sections(unsigned char *gribbuffer, long gribbufsize, unsigned char **i
 int grib_info_for_grads(off_t recpos, long recsize, unsigned char *gribbuffer,
 			int *intnum, float *fltnum, off_t *bignum)
 {
-  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;
+  off_t bpos = 0;
 
-  section = gribbuffer;
-  is = gribbuffer;
+  unsigned char *section = gribbuffer;
+  unsigned char *is = gribbuffer;
   if ( ! GRIB_START(section) )
     {
       fprintf(stderr, "wrong indicator section >%c%c%c%c<\n",
@@ -5330,48 +5139,37 @@ int grib_info_for_grads(off_t recpos, long recsize, unsigned char *gribbuffer,
       return -1;
     }
 
-  gribversion = GRIB_EDITION(section);
-  if ( GRIB1_SECLEN(section) == 24 && gribversion == 0 ) gribversion = 0;
+  int gribversion = GRIB_EDITION(section);
+  if ( recsize == 24 && gribversion == 0 ) gribversion = 0;
 
-  if ( gribversion == 1 )
-    grib1offset = 4;
-  else
-    grib1offset = 0;
+  unsigned grib1offset = (gribversion == 1) ? 4 : 0;
 
-  pds = is + 4 + grib1offset;
-  bufpointer = pds + PDS_Len;
+  unsigned char *pds = is + 4 + grib1offset;
+  unsigned char *bufpointer = pds + PDS_Len;
   gribsize += 4 + grib1offset + PDS_Len;
 
+  unsigned char *gds = NULL;
   if ( PDS_HAS_GDS )
     {
       gds = bufpointer;
       bufpointer += GDS_Len;
       gribsize += GDS_Len;
     }
-  else
-    {
-      gds = NULL;
-    }
 
+  unsigned char *bms = NULL;
   if ( PDS_HAS_BMS )
     {
       bms = bufpointer;
       bufpointer += BMS_Len;
-
       bpos = recpos + gribsize + 6;
-
       gribsize += BMS_Len;
     }
-  else
-    {
-      bms = NULL;
-    }
 
-  bds = bufpointer;
+  unsigned char *bds = bufpointer;
 
-  dpos = recpos + gribsize + 11;
+  off_t dpos = recpos + gribsize + 11;
 
-  bdslen = BDS_Len;
+  unsigned bdslen = BDS_Len;
   bdslen = correct_bdslen(bdslen, recsize, bds-gribbuffer);
   bufpointer += bdslen;
   gribsize += bdslen;
@@ -5390,11 +5188,9 @@ int grib_info_for_grads(off_t recpos, long recsize, unsigned char *gribbuffer,
 	      bufpointer[0], bufpointer[1], bufpointer[2], bufpointer[3]);
     }
 
-  {
-    int bs = BDS_BinScale;
-    if ( bs > 32767 ) bs = 32768-bs;
-    bsf = ldexpf(1.0f, bs);
-  }
+  int bs = BDS_BinScale;
+  if ( bs > 32767 ) bs = 32768-bs;
+  float bsf = ldexpf(1.0f, bs);
 
   bignum[0] = dpos;
   bignum[1] = bms ? bpos : -999;
@@ -5411,15 +5207,36 @@ int grib_info_for_grads(off_t recpos, long recsize, unsigned char *gribbuffer,
   return 0;
 }
 
+static
+int get_level(unsigned char *pds)
+{
+  int level = 0;
+
+  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;
+
+  return level;
+}
+
+static
+double get_cr(unsigned char *w1, unsigned char *w2)
+{
+  unsigned s1 = GET_UINT3(w1[0], w1[1], w1[2]);
+  unsigned s2 = GET_UINT3(w2[0], w2[1], w2[2]);
+  return ((double)s1)/s2;
+}
+
 
 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;
 
   if ( header )
     {
@@ -5431,40 +5248,27 @@ void grib1PrintALL(int nrec, long offset, long recpos, long recsize, unsigned ch
 
   is = gribbuffer;
 
-  if ( gribrec_len(is[4], is[5], is[6]) > JP23SET ) llarge = 1;
+  unsigned gribsize = GET_UINT3(is[4], is[5], is[6]);
 
   long gribrecsize;
-  nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
+  int 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
-    GridType = GDS_GridType;
+  int GridType = (gds == NULL) ? -1 : (int)GDS_GridType;
 
-  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;
+  int level = get_level(pds);
+
+  unsigned bdslen = BDS_Len;
+
+  bool llarge = (gribsize > JP23SET && bdslen <= 120);
 
-  bdslen = BDS_Len;
   bdslen = correct_bdslen(bdslen, recsize, bds-gribbuffer);
 
-  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;
-    }
+  double cr = (((BDS_Flag >> 4)&1) && (BDS_Z == 128 || BDS_Z == 130)) ? get_cr(&bds[14], &gribbuffer[4]) : 1;
 
   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),
@@ -5479,7 +5283,6 @@ void grib1PrintALL(int nrec, long offset, long recpos, long recsize, unsigned ch
 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;
@@ -5498,7 +5301,7 @@ void grib2PrintALL(int nrec, long offset, long recpos, long recsize, unsigned ch
 
   is = gribbuffer;
 
-  nerr = grib2Sections(gribbuffer, recsize, &ids, &lus, &gds, &pds, &drs, &bms, &bds);
+  int 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);
@@ -5513,15 +5316,8 @@ void grib2PrintALL(int nrec, long offset, long recpos, long recsize, unsigned ch
   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;
-    }
-  */
+  // double cr = (((BDS_Flag >> 4)&1) && (BDS_Z == 128 || BDS_Z == 130)) ? get_cr(&bds[14], &gribbuffer[4]) : 1;
+
   gridtype   = GET_UINT2(gds[12],gds[13]);
   paramnum   = GET_UINT1(pds[10]);
   level1type = GET_UINT1(pds[22]);
@@ -5542,9 +5338,7 @@ void grib2PrintALL(int nrec, long offset, long recpos, long recsize, unsigned ch
 
 void gribPrintALL(int nrec, long offset, long recpos, long recsize, unsigned char *gribbuffer)
 {
-  int gribversion;
-
-  gribversion = gribVersion(gribbuffer, (size_t)recsize);
+  int gribversion = gribVersion(gribbuffer, (size_t)recsize);
 
   if ( gribversion == 0 || gribversion == 1 )
     grib1PrintALL(nrec, offset, recpos, recsize, gribbuffer);
@@ -5562,7 +5356,7 @@ void grib1PrintPDS(int nrec, long recpos, long recsize, unsigned char *gribbuffe
 {
   static int header = 1;
   unsigned char *is = NULL, *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
-  int century, subcenter, decimalscale, nerr;
+  int century, subcenter, decimalscale;
   int fc_num = 0;
   int year = 0, date;
 
@@ -5579,7 +5373,7 @@ void grib1PrintPDS(int nrec, long recpos, long recsize, unsigned char *gribbuffe
   is = gribbuffer;
 
   long gribrecsize;
-  nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
+  int nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
   if ( nerr < 0 )
     {
       fprintf(stdout, "%5d : GRIB message error\n", nrec);
@@ -5634,9 +5428,7 @@ void grib1PrintPDS(int nrec, long recpos, long recsize, unsigned char *gribbuffe
 
 void gribPrintPDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
 {
-  int gribversion;
-
-  gribversion = gribVersion(gribbuffer, (size_t)recsize);
+  int gribversion = gribVersion(gribbuffer, (size_t)recsize);
 
   if ( gribversion == 0 || gribversion == 1 )
     grib1PrintPDS(nrec, recpos, recsize, gribbuffer);
@@ -5655,7 +5447,6 @@ void gribPrintPDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer
 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;
 
   UNUSED(recpos);
@@ -5669,7 +5460,7 @@ void grib1PrintGDS(int nrec, long recpos, long recsize, unsigned char *gribbuffe
     }
 
   long gribrecsize;
-  nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
+  int nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
   if ( nerr < 0 )
     {
       fprintf(stdout, "%5d : GRIB message error\n", nrec);
@@ -5695,9 +5486,7 @@ void grib1PrintGDS(int nrec, long recpos, long recsize, unsigned char *gribbuffe
 
 void gribPrintGDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
 {
-  int gribversion;
-
-  gribversion = gribVersion(gribbuffer, (size_t)recsize);
+  int gribversion = gribVersion(gribbuffer, (size_t)recsize);
 
   if ( gribversion == 0 || gribversion == 1 )
     grib1PrintGDS(nrec, recpos, recsize, gribbuffer);
@@ -5716,7 +5505,6 @@ void gribPrintGDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer
 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;
 
   UNUSED(recpos);
@@ -5730,26 +5518,20 @@ void grib1PrintBMS(int nrec, long recpos, long recsize, unsigned char *gribbuffe
     }
 
   long gribrecsize;
-  nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
+  int nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
   if ( nerr < 0 )
     {
       fprintf(stdout, "%5d : GRIB message error\n", nrec);
       return;
     }
 
-  if ( PDS_LevelType == 100 )
-    level = PDS_Level * 100;
-  else if ( PDS_LevelType == 99 )
-    level = PDS_Level;
-  else
-    level = PDS_Level1;
+  int level = get_level(pds);
 
   fprintf(stdout, "%5d :", nrec);
 
   if ( bms )
     fprintf(stdout, "%4d%7d %7d %7d",
-	    PDS_Parameter, level,
-	    BMS_Len, BMS_BitmapSize);
+	    PDS_Parameter, level, BMS_Len, BMS_BitmapSize);
   else
     fprintf(stdout, "%4d%7d Bit Map Section not defined", PDS_Parameter, level);
 
@@ -5760,9 +5542,7 @@ void grib1PrintBMS(int nrec, long recpos, long recsize, unsigned char *gribbuffe
 
 void gribPrintBMS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
 {
-  int gribversion;
-
-  gribversion = gribVersion(gribbuffer, (size_t)recsize);
+  int gribversion = gribVersion(gribbuffer, (size_t)recsize);
 
   if ( gribversion == 0 || gribversion == 1 )
     grib1PrintBMS(nrec, recpos, recsize, gribbuffer);
@@ -5781,10 +5561,8 @@ void gribPrintBMS(int nrec, long recpos, long recsize, unsigned char *gribbuffer
 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;
+  double scale;
 
   UNUSED(recpos);
 
@@ -5797,29 +5575,18 @@ void grib1PrintBDS(int nrec, long recpos, long recsize, unsigned char *gribbuffe
     }
 
   long gribrecsize;
-  nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
+  int nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
   if ( nerr < 0 )
     {
       fprintf(stdout, "%5d : GRIB message error\n", nrec);
       return;
     }
 
-  if ( PDS_LevelType == 100 )
-    level = PDS_Level * 100;
-  else if ( PDS_LevelType == 99 )
-    level = PDS_Level;
-  else
-    level = PDS_Level1;
+  int level = get_level(pds);
 
-  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;
-    }
+  double cr = (((BDS_Flag >> 4)&1) && BDS_Z == 128) ? get_cr(&bds[17], &bds[20]) : 1;
 
-  refval = BDS_RefValue;
+  double refval = BDS_RefValue;
 
   if ( BDS_BinScale < 0 )
     scale = 1.0/pow(2.0, (double) -BDS_BinScale);
@@ -5828,8 +5595,7 @@ void grib1PrintBDS(int nrec, long recpos, long recsize, unsigned char *gribbuffe
 
   if ( PDS_DecimalScale )
     {
-      double decscale;
-      decscale = pow(10.0, (double)-PDS_DecimalScale);
+      double decscale = pow(10.0, (double)-PDS_DecimalScale);
       refval *= decscale;
       scale  *= decscale;
     }
@@ -5850,9 +5616,7 @@ void grib1PrintBDS(int nrec, long recpos, long recsize, unsigned char *gribbuffe
 
 void gribPrintBDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
 {
-  int gribversion;
-
-  gribversion = gribVersion(gribbuffer, (size_t)recsize);
+  int gribversion = gribVersion(gribbuffer, (size_t)recsize);
 
   if ( gribversion == 0 || gribversion == 1 )
     grib1PrintBDS(nrec, recpos, recsize, gribbuffer);
@@ -5870,14 +5634,12 @@ void gribPrintBDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer
 
 void gribCheck1(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
 {
-  int level, nerr;
   unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
-  double cr = 1;
 
   UNUSED(recpos);
 
   long gribrecsize;
-  nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
+  int nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
   if ( nerr < 0 )
     {
       fprintf(stdout, "%5d : GRIB message error\n", nrec);
@@ -5890,44 +5652,29 @@ void gribCheck1(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
       return;
     }
 
-  if ( PDS_LevelType == 100 )
-    level = PDS_Level * 100;
-  else if ( PDS_LevelType == 99 )
-    level = PDS_Level;
-  else
-    level = PDS_Level1;
+  int level = get_level(pds);
 
-  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;
-    }
+  double cr = (((BDS_Flag >> 4)&1) && BDS_Z == 128) ? get_cr(&bds[17], &bds[20]) : 1;
 
   if ( IS_EQUAL(cr, 1) && BDS_NumBits == 24 )
-    {
-      fprintf(stdout, "GRIB record %5d : code = %4d   level = %7d\n", nrec, PDS_Parameter, level);
-    }
+    fprintf(stdout, "GRIB record %5d : code = %4d   level = %7d\n", nrec, PDS_Parameter, level);
 }
 
 
 static
 void repair1(unsigned char *gbuf, long gbufsize)
 {
-  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_nbits, bds_flag, lspherc, lcomplex /*, lcompress */;
   int bds_head = 11;
   int bds_ext = 0, bds_ubits;
   int datstart = 0;
-  // bool llarge = false;
 
   long gribrecsize;
-  nerr = grib1Sections(gbuf, gbufsize, &pds, &gds, &bms, &bds, &gribrecsize);
+  int nerr = grib1Sections(gbuf, gbufsize, &pds, &gds, &bms, &bds, &gribrecsize);
   if ( nerr < 0 )
     {
       fprintf(stdout, "GRIB message error\n");
@@ -5940,10 +5687,7 @@ void repair1(unsigned char *gbuf, long gbufsize)
       return;
     }
 
-  /* recLen = gribrec_len(gbuf[4], gbuf[5], gbuf[6]); */
-  /* if ( recLen > JP23SET ) llarge = true; */
-
-  bds_len   = BDS_Len;
+  unsigned bds_len   = BDS_Len;
   bds_nbits = BDS_NumBits;
   bds_flag  = BDS_Flag;
   bds_ubits = bds_flag & 15;
@@ -5990,12 +5734,10 @@ void repair1(unsigned char *gbuf, long gbufsize)
 
 void gribRepair1(int nrec, long recsize, unsigned char *gribbuffer)
 {
-  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);
+  int nerr = grib1Sections(gribbuffer, recsize, &pds, &gds, &bms, &bds, &gribrecsize);
   if ( nerr < 0 )
     {
       fprintf(stdout, "%5d : GRIB message error\n", nrec);
@@ -6008,20 +5750,9 @@ void gribRepair1(int nrec, long recsize, unsigned char *gribbuffer)
       return;
     }
 
-  if ( PDS_LevelType == 100 )
-    level = PDS_Level * 100;
-  else if ( PDS_LevelType == 99 )
-    level = PDS_Level;
-  else
-    level = PDS_Level1;
+  int level = get_level(pds);
 
-  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;
-    }
+  double cr = (((BDS_Flag >> 4)&1) && BDS_Z == 128) ? get_cr(&bds[17], &bds[20]) : 1;
 
   if ( IS_EQUAL(cr, 1) && BDS_NumBits == 24 )
     {
@@ -6099,7 +5830,7 @@ int gribGetZip(size_t recsize, unsigned char *gribbuffer, size_t *urecsize)
   if ( lcompress )
     {
       compress = BDS_Z;
-      if ( compress == Z_SZIP ) gribsize = (size_t) gribrec_len(bds[14], bds[15], bds[16]);
+      if ( compress == Z_SZIP ) gribsize = (size_t) GET_UINT3(bds[14], bds[15], bds[16]);
     }
 
   *urecsize = gribsize;
@@ -6108,15 +5839,15 @@ int gribGetZip(size_t recsize, unsigned char *gribbuffer, size_t *urecsize)
 }
 
 
-int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize)
+int gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize)
 {
 #if ! defined(HAVE_LIBSZ)
   static int libszwarn = 1;
 #endif
   unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
+  bool llarge = false;
 
-  int gribLen = gribrec_len(dbuf[4], dbuf[5], dbuf[6]);
-  int llarge = (gribLen > JP23SET);
+  unsigned gribLen = GET_UINT3(dbuf[4], dbuf[5], dbuf[6]);
 
   int rec_len = gribLen;
 
@@ -6125,28 +5856,37 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
   if ( nerr < 0 )
     {
       fprintf(stdout, "GRIB message error\n");
-      return rec_len;
+      return gribrecsize;
     }
 
   if ( nerr > 0 )
     {
       fprintf(stdout, "GRIB data corrupted!\n");
-      return rec_len;
+      return gribrecsize;
     }
 
+   int bds_zoffset = 12;
+
+   int bds_len   = BDS_Len;
+   if ( gribLen > JP23SET && bds_len <= 120 )
+     {
+       gribLen &= JP23SET;
+       gribLen *= 120;
+       bds_len = correct_bdslen(bds_len, gribLen, bds-dbuf);
+       llarge = true;
+       bds_zoffset += 2;
+     }
+
+   if ( gribLen > JP24SET || llarge ) return gribLen;
+ 
 #if  defined(HAVE_LIBSZ)
   {
-    int gribLenOld = 0;
+    int bds_zstart = 14;
+    unsigned gribLenOld = 0;
     int bds_head = 11;
     int bds_ext = 0;
     unsigned char *pbuf = NULL;
 
-    int bds_zstart  = 14;
-    int bds_zoffset = 12;
-    if ( llarge ) bds_zoffset += 2;
-
-    int bds_len   = BDS_Len;
-    bds_len   = correct_bdslen(bds_len, gribLen, bds-dbuf);
     int bds_nbits = BDS_NumBits;
     int bds_flag  = BDS_Flag;
     int bds_ubits = bds_flag & 15;
@@ -6156,11 +5896,11 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
     
     if ( bds_nbits != 8 && bds_nbits != 16 && bds_nbits != 24 && bds_nbits != 32 )
       {
-	static int linfo = 1;
+	static bool linfo = true;
 	if ( linfo && bds_nbits != 0 )
 	  {
-	    linfo = 0;
-	    fprintf(stderr, "GRIB szip only supports 8, 16, 24 and 32 bit data!\n");
+	    linfo = false;
+	    fprintf(stderr, "GRIB szip supports only 8, 16, 24 and 32 bit data!\n");
 	  }
 	return rec_len;
       }
@@ -6175,15 +5915,12 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
 
     if ( lspherc )
       {
-	if ( lcomplex  )
+        bds_ext = 4;
+	if ( lcomplex )
 	  {
 	    int jup  = bds[15];
 	    int ioff = (jup+1)*(jup+2);
-	    bds_ext = 4 + 3 + 4*ioff;
-	  }
-	else
-	  {
-	    bds_ext = 4;
+	    bds_ext += 3 + 4*ioff;
 	  }
       }
 
@@ -6263,8 +6000,8 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
 		fprintf(stderr, "Internal problem, record length not multiple of 120!");
 		while ( gribLenOld%120 ) gribLenOld++;
 	      }
-	    gribLenOld = gribLenOld / (-120);
-	    gribLenOld = JP23SET - gribLenOld + 1;
+            // gribLenOld = gribLenOld / (-120);
+	    // gribLenOld = JP23SET - gribLenOld + 1;
 
 	    SetLen3(bds, bds_zstart, gribLenOld);
 	    SetLen4(bds, bds_zstart+3, sourceLen);
@@ -6372,7 +6109,6 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
   size_t destLen, sourceLen;
   enum { bds_head = 11 };
   int bds_ext = 0;
-  bool llarge = false;
 
   UNUSED(dbufsize);
 
@@ -6390,15 +6126,12 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
       return 0;
     }
 
-  int bds_zstart = 14;
-
-  int recLen = gribrec_len(bds[bds_zstart], bds[bds_zstart+1], bds[bds_zstart+2]);
-  if ( recLen > JP23SET ) llarge = true;
+  //unsigned bds_len = BDS_Len;
+  bool llarge = false;
 
   int bds_zoffset = 12;
   if ( llarge ) bds_zoffset += 2;
 
-  /* bds_len   = BDS_Len; */
   int bds_nbits = BDS_NumBits;
   int bds_flag  = BDS_Flag;
   int lspherc   =  bds_flag >> 7;
@@ -6452,6 +6185,9 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
 
 #if  defined(HAVE_LIBSZ)
   {
+    int bds_zstart = 14;
+    unsigned recLen = GET_UINT3(bds[bds_zstart], bds[bds_zstart+1], bds[bds_zstart+2]);
+
     int bits_per_sample = (bds_nbits == 24) ? 8 : bds_nbits;
 
     SZ_com_t sz_param;          /* szip parameter block */
@@ -8465,29 +8201,18 @@ double GET_Real(unsigned char *grib)
 static 
 int decodeIS(unsigned char *is, int *isec0, int *iret)
 {
-  int isLen = 0;
-  int grib1offset;
-  bool lgrib = false, lbudg = false, ltide = false;
+  // Octets 1 - 4 : The letters G R I B. Four 8 bit fields.
 
-  /*
-    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.
-  */
+  // Check letters -> GRIB, BUDG or TIDE.
+
+  // Check that 'GRIB' is found where expected.
+  bool lgrib = GRIB_START(is);
+
+  // ECMWF pseudo-grib data uses 'BUDG' and 'TIDE'.
+  bool lbudg = BUDG_START(is);
+  bool ltide = TIDE_START(is);
+
+  // Data is not GRIB or pseudo-grib.
   if ( lgrib == false && lbudg == false && ltide == false )
     {
       *iret = 305;
@@ -8501,23 +8226,18 @@ int decodeIS(unsigned char *is, int *isec0, int *iret)
       gprintf(__func__, "Return code = %d", *iret);
     }
 
-  /*
-    Octets 5 - 7 : Length of message.
-    One 24 bit field.
-  */
+  // 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.
-  */
+
+  // Octet 8 : GRIB Edition Number. One 8 bit field.
   ISEC0_GRIB_Version = GRIB_EDITION(is);
 
   if ( ISEC0_GRIB_Version > 1 )
     Error("GRIB version %d unsupported!", ISEC0_GRIB_Version);
 
-  grib1offset = ISEC0_GRIB_Version * 4;
+  int grib1offset = ISEC0_GRIB_Version * 4;
 
-  isLen = 4 + grib1offset;
+  int isLen = 4 + grib1offset;
 
   return isLen;
 }
@@ -8538,35 +8258,24 @@ void decodePDS_ECMWF_local_Extension_1(unsigned char *pds, int *isec1)
 static 
 void decodePDS_DWD_local_Extension_254(unsigned char *pds, int *isec1)
 {
-  long i;
-  int isvn;
-
   isec1[36] = GET_UINT1(pds[40]); /* extension identifier */
-  for ( i = 0; i < 11; i++ ) 
-    { 
-      isec1[37+i] =  GET_UINT1(pds[41+i]);
-    } 
+  for ( int i = 0; i < 11; i++ ) 
+    isec1[37+i] =  GET_UINT1(pds[41+i]);
 
-  isvn = GET_UINT2(pds[52],pds[53]);
+  int 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) */
-
 }
 
 static 
 void decodePDS_DWD_local_Extension_253(unsigned char *pds, int *isec1)
 {
-  long i;
-  int isvn;
-
   isec1[36] = GET_UINT1(pds[40]); /* extension identifier */
-  for ( i = 0; i < 11; i++ ) 
-    { 
-      isec1[37+i] =  GET_UINT1(pds[41+i]);
-    } 
+  for ( int i = 0; i < 11; i++ ) 
+    isec1[37+i] =  GET_UINT1(pds[41+i]);
 
-  isvn = GET_UINT2(pds[52],pds[53]);
+  int 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) */
@@ -8577,7 +8286,6 @@ void decodePDS_DWD_local_Extension_253(unsigned char *pds, int *isec1)
   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           */
-
 }
 
 static 
@@ -8592,9 +8300,7 @@ void decodePDS_MPIM_local_Extension_1(unsigned char *pds, int *isec1)
 static 
 int decodePDS(unsigned char *pds, int *isec0, int *isec1)
 {
-  int pdsLen;
-
-  pdsLen = PDS_Len;
+  int pdsLen = PDS_Len;
 
   ISEC1_CodeTable      = PDS_CodeTable;
   ISEC1_CenterID       = PDS_CenterID;
@@ -8651,8 +8357,7 @@ int decodePDS(unsigned char *pds, int *isec0, int *isec1)
     }
   else
     {
-      int year;
-      year                 = GET_UINT1(pds[12]);
+      int year             = GET_UINT1(pds[12]);
       if ( year <= 100 )
 	{
 	  ISEC1_Year       = year;
@@ -8676,8 +8381,7 @@ int decodePDS(unsigned char *pds, int *isec0, int *isec1)
   ISEC1_LocalFLag = 0;
   if ( pdsLen > 28 )
     {
-      int localextlen;
-      localextlen = pdsLen-28;
+      int localextlen = pdsLen-28;
 
       if ( localextlen > 4000 )
 	{
@@ -8690,13 +8394,9 @@ int decodePDS(unsigned char *pds, int *isec0, int *isec1)
 	  if ( ISEC1_CenterID == 78 || ISEC1_CenterID == 215 || ISEC1_CenterID == 250 )
 	    {
 	      if ( pds[40] == 254 ) 
-		{
-		  decodePDS_DWD_local_Extension_254(pds, isec1);
-		}
+                decodePDS_DWD_local_Extension_254(pds, isec1);
 	      else if ( pds[40] == 253 )
-		{ 
-		  decodePDS_DWD_local_Extension_253(pds, isec1);
-		}
+                decodePDS_DWD_local_Extension_253(pds, isec1);
 	    }
 	  else if ( (ISEC1_CenterID    == 98 && ISEC1_LocalFLag ==  1) ||
 		    (ISEC1_SubCenterID == 98 && ISEC1_LocalFLag ==  1) ||
@@ -8712,11 +8412,8 @@ int decodePDS(unsigned char *pds, int *isec0, int *isec1)
 	    }
 	  else
 	    {
-	      long i;
-	      for ( i = 0; i < localextlen; i++ )
-		{
-		  isec1[24+i] = pds[28+i];
-		}
+	      for ( int i = 0; i < localextlen; i++ )
+                isec1[24+i] = pds[28+i];
 	    }
 	}
     }
@@ -9213,8 +8910,8 @@ void TEMPLATE(decode_array,T)(const unsigned char *restrict igrib, long jlend, i
 static 
 int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2, int *numGridVals)
 {
-  /* int imisng = 0; */
-  bool  ReducedGrid = false, VertCoorTab = false;
+  // int imisng = 0;
+  bool ReducedGrid = false, VertCoorTab = false;
 #if defined (VECTORCODE)
   unsigned char *igrib;
   GRIBPACK *lgrib = NULL;
@@ -9225,9 +8922,9 @@ int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2,
 
   memset(isec2, 0, 22*sizeof(int));
 
-  int gdsLen = GDS_Len;
+  unsigned gdsLen = GDS_Len;
 
-  int ipvpl = GDS_PVPL;
+  unsigned ipvpl = GDS_PVPL;
   if ( ipvpl == 0 ) ipvpl = 0xFF;
 
   if ( ipvpl != 0xFF )
@@ -9235,11 +8932,8 @@ int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2,
       if ( GDS_NV != 0 )
 	{ /* we have vct */
 	  VertCoorTab = true;
-	  int ipl =  4*GDS_NV + ipvpl - 1;
-	  if ( ipl < gdsLen )
-	    {
-	      ReducedGrid = true;
-	    }
+	  unsigned ipl =  4*GDS_NV + ipvpl - 1;
+	  if ( ipl < gdsLen ) ReducedGrid = true;
 	}
       else
 	{
@@ -9256,13 +8950,13 @@ int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2,
   
   if ( ReducedGrid )
     {
-      int locnl = GDS_PVPL - 1 + (VertCoorTab * 4 * GDS_NV);
-      int jlenl = (gdsLen - locnl)  >> 1;
+      unsigned locnl = GDS_PVPL - 1 + (VertCoorTab * 4 * GDS_NV);
+      unsigned jlenl = (gdsLen - locnl)  >> 1;
       if ( jlenl == GDS_NumLat )
 	{
 	  *numGridVals = 0;
 	  ISEC2_Reduced = true;
-	  for ( int i = 0; i < jlenl; i++ )
+	  for ( unsigned i = 0; i < jlenl; i++ )
 	    {
 	      ISEC2_RowLon(i) = GET_UINT2(gds[locnl+2*i], gds[locnl+2*i+1]);
 	      *numGridVals += ISEC2_RowLon(i);
@@ -9412,10 +9106,8 @@ int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2,
       if ( ISEC2_NumVCP > 0 ) (void) UNPACK_GRIB(igrib, lgrib, lGribLen, -1L);
       for ( int i = 0; i < ISEC2_NumVCP; i++ )
 	{
-	  int iexp   = (lgrib[4*i  ]);
-	  int imant  =(((lgrib[4*i+1]) << 16) +
-                       ((lgrib[4*i+2]) <<  8) +
-                       ( lgrib[4*i+3]));
+	  int iexp  = lgrib[4*i];
+	  int imant = GET_UINT3(lgrib[4*i+1], lgrib[4*i+2], lgrib[4*i+3]);
 	  fsec2[10+i] = POW_2_M24 * imant * ldexp(1.0, 4 * (iexp - 64));
 	}
 
@@ -9423,10 +9115,8 @@ int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2,
 #else
       for ( int i = 0; i < ISEC2_NumVCP; i++ )
 	{
-	  int iexp   = (gds[locnv+4*i  ]);
-	  int imant  =(((gds[locnv+4*i+1]) << 16) +
-                       ((gds[locnv+4*i+2]) <<  8) +
-                       ( gds[locnv+4*i+3]));
+	  int iexp  = gds[locnv+4*i];
+	  int imant = GET_UINT3(gds[locnv+4*i+1], gds[locnv+4*i+2], gds[locnv+4*i+3]);
 	  fsec2[10+i] = (T)decfp2(iexp,imant);
 	}
 #endif
@@ -9436,55 +9126,33 @@ int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2,
 }
 
 #define ldexp_double ldexp
-#define ldexp_float ldexpf
+#define ldexp_float  ldexpf
 
 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 TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *isec4, 
+                           T *fsec4, int fsec4len, int dfunc, int bdsLen, int numGridVals, int *iret)
 {
-  unsigned char *igrib;
-  bool lspherc = false, lcomplex = false;
-  int lcompress;
-  int jup, kup, mup;
-  int locnd;
-  int bds_flag, jscale, imiss;
-  int bds_ubits;
   int ioff = 0;
-  int iexp, imant;
-  int zoff;
-  int bds_head = 11;
+  unsigned zoff;
+  unsigned bds_head = 11;
   T zscale = 0.;
   T fmin = 0.;
   T *fpdata = fsec4;
-  int bdsLen;
   extern int CGRIBEX_Fix_ZSE;
 
   *iret = 0;
-  igrib = bds;
+  unsigned char *igrib = bds;
 
   memset(isec4, 0, 42*sizeof(int));
 
-  /* 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;
-
   /* 4 bit flag / 4 bit count of unused bits at end of block octet. */
 
-  bds_flag = BDS_Flag;
+  int bds_flag = BDS_Flag;
 
   /* 0------- grid point           */
   /* 1------- spherical harmonics  */
 
-  lspherc = (bds_flag >> 7)&1;
+  bool lspherc = (bds_flag >> 7)&1;
 
   if ( lspherc ) isec4[2] = 128;
   else           isec4[2] = 0;
@@ -9492,7 +9160,7 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
   /* -0------  simple packing */
   /* -1------ complex packing */
 
-  lcomplex = (bds_flag >> 6)&1;
+  bool lcomplex = (bds_flag >> 6)&1;
 
   if ( lcomplex ) isec4[3] = 64;
   else            isec4[3] =  0;
@@ -9500,7 +9168,7 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
   /* ---0---- No additional flags */
   /* ---1---- No additional flags */
 
-  lcompress = (bds_flag >> 4)&1; /* compress */
+  bool lcompress = (bds_flag >> 4)&1;
 
   if ( lcompress )
     { isec4[5] = 16; isec4[6] = BDS_Z; zoff = 12; }
@@ -9509,18 +9177,18 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
 
   /* ----++++ number of unused bits at end of section) */
 
-  bds_ubits = bds_flag & 0xF;
+  int bds_ubits = bds_flag & 0xF;
   
   /* scale factor (2 bytes) */;
 
-  jscale = BDS_BinScale;
+  int jscale = BDS_BinScale;
 
   /* check for missing data indicators. */
 
-  iexp  = bds[ 6];
-  imant = GET_UINT3(bds[ 7], bds[ 8], bds[ 9]);
+  int iexp  = bds[ 6];
+  int imant = GET_UINT3(bds[ 7], bds[ 8], bds[ 9]);
 
-  imiss = (jscale == 0xFFFF && iexp == 0xFF && imant == 0xFFFFFF);
+  int imiss = (jscale == 0xFFFF && iexp == 0xFF && imant == 0xFFFFFF);
 
   /* convert reference value and scale factor. */
 
@@ -9537,7 +9205,7 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
   /* octet number of start of packed data */
   /* calculated from start of block 4 - 1 */
 
-  locnd = zoff + bds_head;
+  unsigned locnd = zoff + bds_head;
 
   /* if data is in spherical harmonic form, distinguish   */
   /* between simple/complex packing (lcomplex = 0/1)      */
@@ -9547,9 +9215,6 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
       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 */
 
@@ -9574,9 +9239,9 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
 	  /*    pentagonal resolution parameters of the */
 	  /*    unpacked section of data field          */
 
-	  jup = bds[zoff+15];
-	  kup = bds[zoff+16];
-	  mup = bds[zoff+17];
+	  int jup = bds[zoff+15];
+	  int kup = bds[zoff+16];
+	  int mup = bds[zoff+17];
 
 	  isec4[zoff+17] = jup;
 	  isec4[zoff+18] = kup;
@@ -9595,11 +9260,8 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
 		  *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 iexp  = (bds[locnd+4*i]);
+		    int imant = GET_UINT3(bds[locnd+4*i+1], bds[locnd+4*i+2], bds[locnd+4*i+3]);
 		    *fpdata++ = (T)decfp2(iexp,imant);
 		  }
 	      }
@@ -9614,7 +9276,7 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
 	  *iret = 1999;
 	  gprintf(__func__, " Second order packed grids unsupported!");
 	  gprintf(__func__, " Return code =  %d", *iret);
-	  return 0;
+	  return;
 	}
     }
 
@@ -9632,7 +9294,7 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
 	  *iret = 2001;
 	  gprintf(__func__, " Number of bits per data value = 0!");
 	  gprintf(__func__, " Return code =  %d", *iret);
-	  return 0;
+	  return;
 	}
 
       if ( numGridVals == 0 )
@@ -9640,7 +9302,7 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
 	  *iret = 2002;
 	  gprintf(__func__, " Constant field unsupported for this grid type!");
 	  gprintf(__func__, " Return code =  %d", *iret);
-	  return 0;
+	  return;
 	}
 
       jlend = numGridVals;
@@ -9648,7 +9310,7 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
     }
   else
     {
-      jlend = (jlend*8 - bds_ubits) / ISEC4_NumBits;
+      jlend = (int) (((long)jlend*8 - bds_ubits) / ISEC4_NumBits);
     }
 
   ISEC4_NumValues        = jlend + ioff;
@@ -9656,25 +9318,14 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
 
   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]));
+      size_t len = ((size_t) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
 
       ISEC4_NumValues = (int)(len*8/(size_t)ISEC4_NumBits);
 
-      if ( lspherc )
-	{
-	  if ( lcomplex )
-	    ISEC4_NumValues += ioff;
-	  else
-	    ISEC4_NumValues++;
-	}
+      if ( lspherc ) ISEC4_NumValues += lcomplex ? ioff : 1;
     }
 
-  if ( dfunc == 'J' ) return bdsLen;
+  if ( dfunc == 'J' ) return;
 
   /* check length of output array. */
   
@@ -9684,7 +9335,7 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
       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;
+      return;
     }
 
   if ( imiss ) memset((char *)fpdata, 0, (size_t)jlend*sizeof(T));
@@ -9718,8 +9369,6 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
       T scale = (T) pow(10.0, (double)-decscale);
       for ( int i = 0; i < ISEC4_NumValues; i++ ) fsec4[i] *= scale;
     }
-
-  return bdsLen;
 }
 
 
@@ -9727,17 +9376,14 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
 			     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;
-  bool gdsIncluded = false;
-  bool bmsIncluded = false;
+  UCHAR *gds = NULL, *bms = NULL;
+  int gdsLen = 0, bmsLen = 0;
   int bitmapSize = 0;
   int imaskSize = 0;
-  bool ldebug = false;
-  bool llarge = false, l_iorj = false;
+  bool ldebug = false, l_iorj = false;
   bool lsect2 = false, lsect3 = false;
   int numGridVals = 0;
-  static bool lmissvalinfo = 1;
+  static bool lmissvalinfo = true;
 
   UNUSED(kleng);
 
@@ -9747,27 +9393,14 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
 
   ISEC2_Reduced = false;
 
-  /*
-    ----------------------------------------------------------------
-    IS Indicator Section (Section 0)
-    ----------------------------------------------------------------
-  */
-  is = (unsigned char *) &kgrib[0];
-  isLen = decodeIS(is, isec0, iret);
+  // ----------------------------------------------------------------
+  // IS Indicator Section (Section 0)
+  // ----------------------------------------------------------------
+  UCHAR *is = (UCHAR *) &kgrib[0];
+  int isLen = decodeIS(is, isec0, iret);
+
+  int gribLen = ISEC0_GRIB_Len;
 
-  /*
-    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 ( 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.
@@ -9843,45 +9476,31 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
   */
   if ( ISEC0_GRIB_Len == 24 && ISEC0_GRIB_Version == 0 )
     {
-      /*
-	Set length of GRIB message to missing data value.
-      */
+      // 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;
-
-  /*
-    ----------------------------------------------------------------
-    PDS Product Definition Section (Section 1)
-    ----------------------------------------------------------------
-  */ 
-  pds = is + isLen;
-  pdsLen = decodePDS(pds, isec0, isec1);
 
-  /*
-    ----------------------------------------------------------------
-    GDS Grid Description Section (Section 2)
-    ----------------------------------------------------------------
-  */
-  gdsIncluded = ISEC1_Sec2Or3Flag & 128;
+  // ----------------------------------------------------------------
+  // PDS Product Definition Section (Section 1)
+  // ----------------------------------------------------------------
+  UCHAR *pds = is + isLen;
+  int pdsLen = decodePDS(pds, isec0, isec1);
 
+  // ----------------------------------------------------------------
+  // GDS Grid Description Section (Section 2)
+  // ----------------------------------------------------------------
+  bool gdsIncluded = ISEC1_Sec2Or3Flag & 128;
   if ( gdsIncluded )
     {
       gds = is + isLen + pdsLen;
       gdsLen = TEMPLATE(decodeGDS,T)(gds, isec0, isec2, fsec2, &numGridVals);
     }
 
-  /*
-    ----------------------------------------------------------------
-    BMS Bit-Map Section Section (Section 3)
-    ----------------------------------------------------------------
-  */ 
-  bmsIncluded = ISEC1_Sec2Or3Flag & 64;
-
+  // ----------------------------------------------------------------
+  // BMS Bit-Map Section Section (Section 3)
+  // ----------------------------------------------------------------
   isec3[0] = 0;
+  bool bmsIncluded = ISEC1_Sec2Or3Flag & 64;
   if ( bmsIncluded )
     {
       bms = is + isLen + pdsLen + gdsLen;
@@ -9889,20 +9508,30 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
 
       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)
+  // ----------------------------------------------------------------
+  UCHAR *bds = is + isLen + pdsLen + gdsLen + bmsLen;
+  int bdsLen = BDS_Len;
   /*
-    ----------------------------------------------------------------
-    BDS Binary Data Section (Section 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.
   */
-  bds = is + isLen + pdsLen + gdsLen + bmsLen;
-  bdsLen = ISEC0_GRIB_Len - (isLen + pdsLen + gdsLen + bmsLen);
-  bdsLen = TEMPLATE(decodeBDS,T)(ISEC1_DecScaleFactor, bds, isec2, isec4, 
-				 fsec4, fsec4len, dfunc, bdsLen, numGridVals, llarge, iret);
+  if ( gribLen > JP23SET && bdsLen <= 120 )
+    {
+      gribLen &= JP23SET;
+      gribLen *= 120;
+      ISEC0_GRIB_Len = gribLen;
+      bdsLen = correct_bdslen(bdsLen, gribLen, isLen+pdsLen+gdsLen+bmsLen);
+    }
+  TEMPLATE(decodeBDS,T)(ISEC1_DecScaleFactor, bds, isec2, isec4, 
+                        fsec4, fsec4len, dfunc, bdsLen, numGridVals, iret);
 
   if ( *iret != 0 ) return;
 
@@ -9919,7 +9548,7 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
 	  }
 
       /* ISEC4_NumNonMissValues = ISEC4_NumValues; */
-      ISEC4_NumValues        = bitmapSize;
+      ISEC4_NumValues = bitmapSize;
 
       if ( dfunc != 'J' || bitmapSize == ISEC4_NumNonMissValues )
 	{
@@ -10051,25 +9680,20 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
 
 
   if ( ISEC0_GRIB_Version == 1 ) isLen = 8;
-  esLen = 4;
-
-  int gribLen = isLen + pdsLen + gdsLen + bmsLen + bdsLen + esLen;
+  int esLen = 4;
+  gribLen = isLen + pdsLen + gdsLen + bmsLen + bdsLen + esLen;
 
   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);
+      Warning("Inconsistent length of GRIB message (grib_message_size=%d < grib_record_size=%d)!", ISEC0_GRIB_Len, gribLen);
 
   ISEC0_GRIB_Len = gribLen;
 
   *kword = (int)(((size_t)gribLen + sizeof(int) - 1) / sizeof(int));
 
-  /*
-    ----------------------------------------------------------------
-    Section 9 . Abort/return to calling routine.
-    ----------------------------------------------------------------
-  */
- LABEL900:;
-
+  // ----------------------------------------------------------------
+  // Section 9 . Abort/return to calling routine.
+  // ----------------------------------------------------------------
   if ( ldebug )
     {
       gprintf(__func__, "Section 9.");
@@ -10077,23 +9701,16 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
 
       gribPrintSec0(isec0);
       gribPrintSec1(isec0, isec1);
-      /*
-	Print section 2 if present.
-      */
+      // Print section 2 if present.
       if ( lsect2 ) TEMPLATE(gribPrintSec2,T)(isec0, isec2, fsec2);
 
       if ( ! l_iorj )
 	{
-	  /*
-	    Print section 3 if present.
-	  */
+	  // Print section 3 if present.
 	  if ( lsect3 ) TEMPLATE(gribPrintSec3,T)(isec0, isec3, fsec3);
 
 	  TEMPLATE(gribPrintSec4,T)(isec0, isec4, fsec4);
-	  /*
-	    Special print for 2D spectra wave field real values in
-	    section 4
-	  */
+	  // Special print for 2D spectra wave field real values in section 4
 	  if ( (isec1[ 0] ==  140) && 
 	       (isec1[ 1] ==   98) && 
 	       (isec1[23] ==    1) && 
@@ -10121,8 +9738,8 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
 static 
 int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2, int *numGridVals)
 {
-  /* int imisng = 0; */
-  bool  ReducedGrid = false, VertCoorTab = false;
+  // int imisng = 0;
+  bool ReducedGrid = false, VertCoorTab = false;
 #if defined (VECTORCODE)
   unsigned char *igrib;
   GRIBPACK *lgrib = NULL;
@@ -10133,9 +9750,9 @@ int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2,
 
   memset(isec2, 0, 22*sizeof(int));
 
-  int gdsLen = GDS_Len;
+  unsigned gdsLen = GDS_Len;
 
-  int ipvpl = GDS_PVPL;
+  unsigned ipvpl = GDS_PVPL;
   if ( ipvpl == 0 ) ipvpl = 0xFF;
 
   if ( ipvpl != 0xFF )
@@ -10143,11 +9760,8 @@ int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2,
       if ( GDS_NV != 0 )
 	{ /* we have vct */
 	  VertCoorTab = true;
-	  int ipl =  4*GDS_NV + ipvpl - 1;
-	  if ( ipl < gdsLen )
-	    {
-	      ReducedGrid = true;
-	    }
+	  unsigned ipl =  4*GDS_NV + ipvpl - 1;
+	  if ( ipl < gdsLen ) ReducedGrid = true;
 	}
       else
 	{
@@ -10164,13 +9778,13 @@ int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2,
   
   if ( ReducedGrid )
     {
-      int locnl = GDS_PVPL - 1 + (VertCoorTab * 4 * GDS_NV);
-      int jlenl = (gdsLen - locnl)  >> 1;
+      unsigned locnl = GDS_PVPL - 1 + (VertCoorTab * 4 * GDS_NV);
+      unsigned jlenl = (gdsLen - locnl)  >> 1;
       if ( jlenl == GDS_NumLat )
 	{
 	  *numGridVals = 0;
 	  ISEC2_Reduced = true;
-	  for ( int i = 0; i < jlenl; i++ )
+	  for ( unsigned i = 0; i < jlenl; i++ )
 	    {
 	      ISEC2_RowLon(i) = GET_UINT2(gds[locnl+2*i], gds[locnl+2*i+1]);
 	      *numGridVals += ISEC2_RowLon(i);
@@ -10320,10 +9934,8 @@ int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2,
       if ( ISEC2_NumVCP > 0 ) (void) UNPACK_GRIB(igrib, lgrib, lGribLen, -1L);
       for ( int i = 0; i < ISEC2_NumVCP; i++ )
 	{
-	  int iexp   = (lgrib[4*i  ]);
-	  int imant  =(((lgrib[4*i+1]) << 16) +
-                       ((lgrib[4*i+2]) <<  8) +
-                       ( lgrib[4*i+3]));
+	  int iexp  = lgrib[4*i];
+	  int imant = GET_UINT3(lgrib[4*i+1], lgrib[4*i+2], lgrib[4*i+3]);
 	  fsec2[10+i] = POW_2_M24 * imant * ldexp(1.0, 4 * (iexp - 64));
 	}
 
@@ -10331,10 +9943,8 @@ int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2,
 #else
       for ( int i = 0; i < ISEC2_NumVCP; i++ )
 	{
-	  int iexp   = (gds[locnv+4*i  ]);
-	  int imant  =(((gds[locnv+4*i+1]) << 16) +
-                       ((gds[locnv+4*i+2]) <<  8) +
-                       ( gds[locnv+4*i+3]));
+	  int iexp  = gds[locnv+4*i];
+	  int imant = GET_UINT3(gds[locnv+4*i+1], gds[locnv+4*i+2], gds[locnv+4*i+3]);
 	  fsec2[10+i] = (T)decfp2(iexp,imant);
 	}
 #endif
@@ -10344,55 +9954,33 @@ int TEMPLATE(decodeGDS,T)(unsigned char  *gds, int *isec0, int *isec2, T *fsec2,
 }
 
 #define ldexp_double ldexp
-#define ldexp_float ldexpf
+#define ldexp_float  ldexpf
 
 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 TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *isec4, 
+                           T *fsec4, int fsec4len, int dfunc, int bdsLen, int numGridVals, int *iret)
 {
-  unsigned char *igrib;
-  bool lspherc = false, lcomplex = false;
-  int lcompress;
-  int jup, kup, mup;
-  int locnd;
-  int bds_flag, jscale, imiss;
-  int bds_ubits;
   int ioff = 0;
-  int iexp, imant;
-  int zoff;
-  int bds_head = 11;
+  unsigned zoff;
+  unsigned bds_head = 11;
   T zscale = 0.;
   T fmin = 0.;
   T *fpdata = fsec4;
-  int bdsLen;
   extern int CGRIBEX_Fix_ZSE;
 
   *iret = 0;
-  igrib = bds;
+  unsigned char *igrib = bds;
 
   memset(isec4, 0, 42*sizeof(int));
 
-  /* 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;
-
   /* 4 bit flag / 4 bit count of unused bits at end of block octet. */
 
-  bds_flag = BDS_Flag;
+  int bds_flag = BDS_Flag;
 
   /* 0------- grid point           */
   /* 1------- spherical harmonics  */
 
-  lspherc = (bds_flag >> 7)&1;
+  bool lspherc = (bds_flag >> 7)&1;
 
   if ( lspherc ) isec4[2] = 128;
   else           isec4[2] = 0;
@@ -10400,7 +9988,7 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
   /* -0------  simple packing */
   /* -1------ complex packing */
 
-  lcomplex = (bds_flag >> 6)&1;
+  bool lcomplex = (bds_flag >> 6)&1;
 
   if ( lcomplex ) isec4[3] = 64;
   else            isec4[3] =  0;
@@ -10408,7 +9996,7 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
   /* ---0---- No additional flags */
   /* ---1---- No additional flags */
 
-  lcompress = (bds_flag >> 4)&1; /* compress */
+  bool lcompress = (bds_flag >> 4)&1;
 
   if ( lcompress )
     { isec4[5] = 16; isec4[6] = BDS_Z; zoff = 12; }
@@ -10417,18 +10005,18 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
 
   /* ----++++ number of unused bits at end of section) */
 
-  bds_ubits = bds_flag & 0xF;
+  int bds_ubits = bds_flag & 0xF;
   
   /* scale factor (2 bytes) */;
 
-  jscale = BDS_BinScale;
+  int jscale = BDS_BinScale;
 
   /* check for missing data indicators. */
 
-  iexp  = bds[ 6];
-  imant = GET_UINT3(bds[ 7], bds[ 8], bds[ 9]);
+  int iexp  = bds[ 6];
+  int imant = GET_UINT3(bds[ 7], bds[ 8], bds[ 9]);
 
-  imiss = (jscale == 0xFFFF && iexp == 0xFF && imant == 0xFFFFFF);
+  int imiss = (jscale == 0xFFFF && iexp == 0xFF && imant == 0xFFFFFF);
 
   /* convert reference value and scale factor. */
 
@@ -10445,7 +10033,7 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
   /* octet number of start of packed data */
   /* calculated from start of block 4 - 1 */
 
-  locnd = zoff + bds_head;
+  unsigned locnd = zoff + bds_head;
 
   /* if data is in spherical harmonic form, distinguish   */
   /* between simple/complex packing (lcomplex = 0/1)      */
@@ -10455,9 +10043,6 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
       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 */
 
@@ -10482,9 +10067,9 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
 	  /*    pentagonal resolution parameters of the */
 	  /*    unpacked section of data field          */
 
-	  jup = bds[zoff+15];
-	  kup = bds[zoff+16];
-	  mup = bds[zoff+17];
+	  int jup = bds[zoff+15];
+	  int kup = bds[zoff+16];
+	  int mup = bds[zoff+17];
 
 	  isec4[zoff+17] = jup;
 	  isec4[zoff+18] = kup;
@@ -10503,11 +10088,8 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
 		  *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 iexp  = (bds[locnd+4*i]);
+		    int imant = GET_UINT3(bds[locnd+4*i+1], bds[locnd+4*i+2], bds[locnd+4*i+3]);
 		    *fpdata++ = (T)decfp2(iexp,imant);
 		  }
 	      }
@@ -10522,7 +10104,7 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
 	  *iret = 1999;
 	  gprintf(__func__, " Second order packed grids unsupported!");
 	  gprintf(__func__, " Return code =  %d", *iret);
-	  return 0;
+	  return;
 	}
     }
 
@@ -10540,7 +10122,7 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
 	  *iret = 2001;
 	  gprintf(__func__, " Number of bits per data value = 0!");
 	  gprintf(__func__, " Return code =  %d", *iret);
-	  return 0;
+	  return;
 	}
 
       if ( numGridVals == 0 )
@@ -10548,7 +10130,7 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
 	  *iret = 2002;
 	  gprintf(__func__, " Constant field unsupported for this grid type!");
 	  gprintf(__func__, " Return code =  %d", *iret);
-	  return 0;
+	  return;
 	}
 
       jlend = numGridVals;
@@ -10556,7 +10138,7 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
     }
   else
     {
-      jlend = (jlend*8 - bds_ubits) / ISEC4_NumBits;
+      jlend = (int) (((long)jlend*8 - bds_ubits) / ISEC4_NumBits);
     }
 
   ISEC4_NumValues        = jlend + ioff;
@@ -10564,25 +10146,14 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
 
   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]));
+      size_t len = ((size_t) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
 
       ISEC4_NumValues = (int)(len*8/(size_t)ISEC4_NumBits);
 
-      if ( lspherc )
-	{
-	  if ( lcomplex )
-	    ISEC4_NumValues += ioff;
-	  else
-	    ISEC4_NumValues++;
-	}
+      if ( lspherc ) ISEC4_NumValues += lcomplex ? ioff : 1;
     }
 
-  if ( dfunc == 'J' ) return bdsLen;
+  if ( dfunc == 'J' ) return;
 
   /* check length of output array. */
   
@@ -10592,7 +10163,7 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
       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;
+      return;
     }
 
   if ( imiss ) memset((char *)fpdata, 0, (size_t)jlend*sizeof(T));
@@ -10626,8 +10197,6 @@ int TEMPLATE(decodeBDS,T)(int decscale, unsigned char *bds, int *isec2, int *ise
       T scale = (T) pow(10.0, (double)-decscale);
       for ( int i = 0; i < ISEC4_NumValues; i++ ) fsec4[i] *= scale;
     }
-
-  return bdsLen;
 }
 
 
@@ -10635,17 +10204,14 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
 			     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;
-  bool gdsIncluded = false;
-  bool bmsIncluded = false;
+  UCHAR *gds = NULL, *bms = NULL;
+  int gdsLen = 0, bmsLen = 0;
   int bitmapSize = 0;
   int imaskSize = 0;
-  bool ldebug = false;
-  bool llarge = false, l_iorj = false;
+  bool ldebug = false, l_iorj = false;
   bool lsect2 = false, lsect3 = false;
   int numGridVals = 0;
-  static bool lmissvalinfo = 1;
+  static bool lmissvalinfo = true;
 
   UNUSED(kleng);
 
@@ -10655,27 +10221,14 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
 
   ISEC2_Reduced = false;
 
-  /*
-    ----------------------------------------------------------------
-    IS Indicator Section (Section 0)
-    ----------------------------------------------------------------
-  */
-  is = (unsigned char *) &kgrib[0];
-  isLen = decodeIS(is, isec0, iret);
+  // ----------------------------------------------------------------
+  // IS Indicator Section (Section 0)
+  // ----------------------------------------------------------------
+  UCHAR *is = (UCHAR *) &kgrib[0];
+  int isLen = decodeIS(is, isec0, iret);
+
+  int gribLen = ISEC0_GRIB_Len;
 
-  /*
-    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 ( 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.
@@ -10751,45 +10304,31 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
   */
   if ( ISEC0_GRIB_Len == 24 && ISEC0_GRIB_Version == 0 )
     {
-      /*
-	Set length of GRIB message to missing data value.
-      */
+      // 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;
-
-  /*
-    ----------------------------------------------------------------
-    PDS Product Definition Section (Section 1)
-    ----------------------------------------------------------------
-  */ 
-  pds = is + isLen;
-  pdsLen = decodePDS(pds, isec0, isec1);
 
-  /*
-    ----------------------------------------------------------------
-    GDS Grid Description Section (Section 2)
-    ----------------------------------------------------------------
-  */
-  gdsIncluded = ISEC1_Sec2Or3Flag & 128;
+  // ----------------------------------------------------------------
+  // PDS Product Definition Section (Section 1)
+  // ----------------------------------------------------------------
+  UCHAR *pds = is + isLen;
+  int pdsLen = decodePDS(pds, isec0, isec1);
 
+  // ----------------------------------------------------------------
+  // GDS Grid Description Section (Section 2)
+  // ----------------------------------------------------------------
+  bool gdsIncluded = ISEC1_Sec2Or3Flag & 128;
   if ( gdsIncluded )
     {
       gds = is + isLen + pdsLen;
       gdsLen = TEMPLATE(decodeGDS,T)(gds, isec0, isec2, fsec2, &numGridVals);
     }
 
-  /*
-    ----------------------------------------------------------------
-    BMS Bit-Map Section Section (Section 3)
-    ----------------------------------------------------------------
-  */ 
-  bmsIncluded = ISEC1_Sec2Or3Flag & 64;
-
+  // ----------------------------------------------------------------
+  // BMS Bit-Map Section Section (Section 3)
+  // ----------------------------------------------------------------
   isec3[0] = 0;
+  bool bmsIncluded = ISEC1_Sec2Or3Flag & 64;
   if ( bmsIncluded )
     {
       bms = is + isLen + pdsLen + gdsLen;
@@ -10797,20 +10336,30 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
 
       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)
+  // ----------------------------------------------------------------
+  UCHAR *bds = is + isLen + pdsLen + gdsLen + bmsLen;
+  int bdsLen = BDS_Len;
   /*
-    ----------------------------------------------------------------
-    BDS Binary Data Section (Section 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.
   */
-  bds = is + isLen + pdsLen + gdsLen + bmsLen;
-  bdsLen = ISEC0_GRIB_Len - (isLen + pdsLen + gdsLen + bmsLen);
-  bdsLen = TEMPLATE(decodeBDS,T)(ISEC1_DecScaleFactor, bds, isec2, isec4, 
-				 fsec4, fsec4len, dfunc, bdsLen, numGridVals, llarge, iret);
+  if ( gribLen > JP23SET && bdsLen <= 120 )
+    {
+      gribLen &= JP23SET;
+      gribLen *= 120;
+      ISEC0_GRIB_Len = gribLen;
+      bdsLen = correct_bdslen(bdsLen, gribLen, isLen+pdsLen+gdsLen+bmsLen);
+    }
+  TEMPLATE(decodeBDS,T)(ISEC1_DecScaleFactor, bds, isec2, isec4, 
+                        fsec4, fsec4len, dfunc, bdsLen, numGridVals, iret);
 
   if ( *iret != 0 ) return;
 
@@ -10827,7 +10376,7 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
 	  }
 
       /* ISEC4_NumNonMissValues = ISEC4_NumValues; */
-      ISEC4_NumValues        = bitmapSize;
+      ISEC4_NumValues = bitmapSize;
 
       if ( dfunc != 'J' || bitmapSize == ISEC4_NumNonMissValues )
 	{
@@ -10959,25 +10508,20 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
 
 
   if ( ISEC0_GRIB_Version == 1 ) isLen = 8;
-  esLen = 4;
-
-  int gribLen = isLen + pdsLen + gdsLen + bmsLen + bdsLen + esLen;
+  int esLen = 4;
+  gribLen = isLen + pdsLen + gdsLen + bmsLen + bdsLen + esLen;
 
   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);
+      Warning("Inconsistent length of GRIB message (grib_message_size=%d < grib_record_size=%d)!", ISEC0_GRIB_Len, gribLen);
 
   ISEC0_GRIB_Len = gribLen;
 
   *kword = (int)(((size_t)gribLen + sizeof(int) - 1) / sizeof(int));
 
-  /*
-    ----------------------------------------------------------------
-    Section 9 . Abort/return to calling routine.
-    ----------------------------------------------------------------
-  */
- LABEL900:;
-
+  // ----------------------------------------------------------------
+  // Section 9 . Abort/return to calling routine.
+  // ----------------------------------------------------------------
   if ( ldebug )
     {
       gprintf(__func__, "Section 9.");
@@ -10985,23 +10529,16 @@ void TEMPLATE(grib_decode,T)(int *isec0, int *isec1, int *isec2, T *fsec2, int *
 
       gribPrintSec0(isec0);
       gribPrintSec1(isec0, isec1);
-      /*
-	Print section 2 if present.
-      */
+      // Print section 2 if present.
       if ( lsect2 ) TEMPLATE(gribPrintSec2,T)(isec0, isec2, fsec2);
 
       if ( ! l_iorj )
 	{
-	  /*
-	    Print section 3 if present.
-	  */
+	  // Print section 3 if present.
 	  if ( lsect3 ) TEMPLATE(gribPrintSec3,T)(isec0, isec3, fsec3);
 
 	  TEMPLATE(gribPrintSec4,T)(isec0, isec4, fsec4);
-	  /*
-	    Special print for 2D spectra wave field real values in
-	    section 4
-	  */
+	  // Special print for 2D spectra wave field real values in section 4
 	  if ( (isec1[ 0] ==  140) && 
 	       (isec1[ 1] ==   98) && 
 	       (isec1[23] ==    1) && 
@@ -11032,10 +10569,8 @@ void encodeIS(GRIBPACK *lGrib, long *gribLen)
   lGrib[2] = 'I';
   lGrib[3] = 'B';
 
-  /* 
-   * lGrib[4]-lGrib[6] contains full length of grib record. 
-   * included before finished CODEGB
-   */
+  // lGrib[4]-lGrib[6] contains full length of grib record. 
+  // included before finished CODEGB
 
   z = 7;   
   Put1Byte(1); /* grib version */
@@ -11055,14 +10590,11 @@ void encodeES(GRIBPACK *lGrib, long *gribLen, long bdsstart)
   lGrib[z++] = '7';
   lGrib[z++] = '7';
 
-  if ( z > JP23SET )
+  if ( z > JP24SET )
     {
-      long itemp;
       long bdslen = z - 4;
-      /*
-      fprintf(stderr, "Abort: GRIB record too large (max = %d)!\n", JP23SET);
-      exit(1);
-      */
+      // 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
@@ -11079,7 +10611,7 @@ void encodeES(GRIBPACK *lGrib, long *gribLen, long bdsstart)
 	  exit(1);
 	}
 
-      itemp = z / (-120);
+      long itemp = z / (-120);
       itemp = JP23SET - itemp + 1;
 
       lGrib[4] = (GRIBPACK)(itemp >> 16);
@@ -11132,7 +10664,7 @@ long getLocalExtLen(int *isec1)
         }
     }
 
-  return (extlen);
+  return extlen;
 }
 
 static
@@ -11142,23 +10674,18 @@ long getPdsLen(int *isec1)
 
   pdslen += getLocalExtLen(isec1);
 
-  return (pdslen);
+  return pdslen;
 }
 
 static
 void encodePDS_DWD_local_Extension_254(GRIBPACK *lGrib, long *zs, int *isec1)
 {
-  int isvn;
-  long localextlen, i;
   long z = *zs;
 
-  localextlen = getLocalExtLen(isec1);
-  for ( i = 0; i < localextlen-2; i++ )
-    {
-      Put1Byte(isec1[24+i]);
-    }
+  long localextlen = getLocalExtLen(isec1);
+  for ( long i = 0; i < localextlen-2; i++ ) Put1Byte(isec1[24+i]);
 
-  isvn = isec1[49] << 15 | isec1[48]; /* DWD experiment identifier    */
+  int isvn = isec1[49] << 15 | isec1[48]; /* DWD experiment identifier    */
   Put2Byte(isvn);             /* DWD run type (0=main, 2=ass, 3=test) */
 
   *zs = z;
@@ -11167,17 +10694,12 @@ void encodePDS_DWD_local_Extension_254(GRIBPACK *lGrib, long *zs, int *isec1)
 static
 void encodePDS_DWD_local_Extension_253(GRIBPACK *lGrib, long *zs, int *isec1)
 {
-  int isvn;
-  long localextlen, i;
   long z = *zs;
 
-  localextlen = DWD_extension_254_len;
-  for ( i = 0; i < localextlen-2; i++ )
-    {
-      Put1Byte(isec1[24+i]);
-    }
+  long localextlen = DWD_extension_254_len;
+  for ( long i = 0; i < localextlen-2; i++ ) Put1Byte(isec1[24+i]);
 
-  isvn = isec1[49] << 15 | isec1[48]; /* DWD experiment identifier    */
+  int 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             */
@@ -11194,15 +10716,10 @@ void encodePDS_DWD_local_Extension_253(GRIBPACK *lGrib, long *zs, int *isec1)
 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++ )
-    {
-      Put1Byte(isec1[24+i]);
-    }
+  long localextlen = getLocalExtLen(isec1);
+  for ( long 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 */
@@ -11226,15 +10743,10 @@ void encodePDS_ECMWF_local_Extension_1(GRIBPACK *lGrib, long *zs, int *isec1)
 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]);
-    }
+  long localextlen = getLocalExtLen(isec1);
+  for ( long 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)                  */
@@ -11251,10 +10763,10 @@ void encodePDS(GRIBPACK *lpds, long pdsLen, int *isec1)
 {
   GRIBPACK *lGrib = lpds;
   long z = 0;
-  int ival, century, year;
+  int ival;
 
-  century = ISEC1_Century;
-  year    = ISEC1_Year;
+  int century = ISEC1_Century;
+  int year    = ISEC1_Year;
 
   if ( century < 0 )
     {
@@ -11329,7 +10841,7 @@ void encodePDS(GRIBPACK *lpds, long pdsLen, int *isec1)
   Put1Byte(ISEC1_AvgMiss);        /* 23 Missing from averages    */
   Put1Byte(century);              /* 24 Century                  */
   Put1Byte(ISEC1_SubCenterID);    /* 25 Subcenter                */
-  Put2Byte(ISEC1_DecScaleFactor); /* 26 Decimal scale factor     */
+  Put2Int(ISEC1_DecScaleFactor);  /* 26 Decimal scale factor     */
 
   if ( ISEC1_LocalFLag )
     {
@@ -12706,7 +12218,8 @@ int TEMPLATE(encodeBDS,T)(GRIBPACK *lGrib, long *gribLen, int decscale, int *ise
   long i;
   int numBits;
   int ival;
-  long PackStart = 0, Flag = 0;
+  long PackStart = 0;
+  int Flag = 0;
   int binscale = 0;
   int bds_head = 11;
   int bds_ext = 0;
@@ -12773,16 +12286,15 @@ int TEMPLATE(encodeBDS,T)(GRIBPACK *lGrib, long *gribLen, int decscale, int *ise
   if ( decscale )
     {
       T scale = (T) pow(10.0, (double) decscale);
-      for ( i = 0; i < datasize; ++i ) data[i] *= scale;
+      for ( long i = 0; i < datasize; ++i ) data[i] *= scale;
     }
 
   if ( lspherc )
     {
       if ( lcomplex )
 	{
-	  int jup, ioff;
-	  jup  = isubset;
-	  ioff = (jup+1)*(jup+2);
+	  int jup  = isubset;
+	  int ioff = (jup+1)*(jup+2);
 	  bds_ext = 4 + 3 + 4*ioff;
 	  PackStart = ioff;
 	  Flag = 192;
@@ -13283,7 +12795,8 @@ int TEMPLATE(encodeBDS,T)(GRIBPACK *lGrib, long *gribLen, int decscale, int *ise
   long i;
   int numBits;
   int ival;
-  long PackStart = 0, Flag = 0;
+  long PackStart = 0;
+  int Flag = 0;
   int binscale = 0;
   int bds_head = 11;
   int bds_ext = 0;
@@ -13350,16 +12863,15 @@ int TEMPLATE(encodeBDS,T)(GRIBPACK *lGrib, long *gribLen, int decscale, int *ise
   if ( decscale )
     {
       T scale = (T) pow(10.0, (double) decscale);
-      for ( i = 0; i < datasize; ++i ) data[i] *= scale;
+      for ( long i = 0; i < datasize; ++i ) data[i] *= scale;
     }
 
   if ( lspherc )
     {
       if ( lcomplex )
 	{
-	  int jup, ioff;
-	  jup  = isubset;
-	  ioff = (jup+1)*(jup+2);
+	  int jup  = isubset;
+	  int ioff = (jup+1)*(jup+2);
 	  bds_ext = 4 + 3 + 4*ioff;
 	  PackStart = ioff;
 	  Flag = 192;
@@ -13647,7 +13159,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.8.1" " of ""Jul 12 2017"" ""18:11:37";
+static const char grb_libvers[] = "1.9.0" " of ""Sep 29 2017"" ""10:16:02";
 const char *
 cgribexLibraryVersion(void)
 {
diff --git a/libcdi/src/grid.c b/libcdi/src/grid.c
index f4acd57..d87ccd6 100644
--- a/libcdi/src/grid.c
+++ b/libcdi/src/grid.c
@@ -150,7 +150,7 @@ void grid_init(grid_t *gridptr)
   gridptr->number        = 0;
   gridptr->position      = 0;
   gridptr->reference     = NULL;
-  gridptr->prec          = 0;
+  gridptr->datatype      = 0;
   gridptr->size          = 0;
   gridptr->x.size        = 0;
   gridptr->y.size        = 0;
@@ -310,32 +310,33 @@ void cdiGridTypeInit(grid_t *gridptr, int gridtype, int size)
       {
         if ( gridtype == GRID_TRAJECTORY )
           {
-            if ( gridptr->x.name[0] == 0 ) gridSetName(gridptr->x.name, "tlon");
-            if ( gridptr->y.name[0] == 0 ) gridSetName(gridptr->y.name, "tlat");
+            if ( !gridptr->x.name[0] ) gridSetName(gridptr->x.name, "tlon");
+            if ( !gridptr->y.name[0] ) gridSetName(gridptr->y.name, "tlat");
           }
         else
           {
-            if ( gridptr->x.name[0] == 0 ) gridSetName(gridptr->x.name, "lon");
-            if ( gridptr->y.name[0] == 0 ) gridSetName(gridptr->y.name, "lat");
+            if ( !gridptr->x.name[0] ) gridSetName(gridptr->x.name, "lon");
+            if ( !gridptr->y.name[0] ) gridSetName(gridptr->y.name, "lat");
           }
 
-        gridSetName(gridptr->x.longname, "longitude");
-        gridSetName(gridptr->y.longname, "latitude");
+        if ( !gridptr->x.longname[0] ) gridSetName(gridptr->x.longname, "longitude");
+        if ( !gridptr->y.longname[0] ) gridSetName(gridptr->y.longname, "latitude");
+
+        if ( !gridptr->x.units[0] ) gridSetName(gridptr->x.units, "degrees_east");
+        if ( !gridptr->y.units[0] ) gridSetName(gridptr->y.units, "degrees_north");
 
         gridptr->x.stdname = xystdname_tab[grid_xystdname_latlon][0];
         gridptr->y.stdname = xystdname_tab[grid_xystdname_latlon][1];
-        gridSetName(gridptr->x.units, "degrees_east");
-        gridSetName(gridptr->y.units, "degrees_north");
 
         break;
       }
     case GRID_CHARXY:
       {
-        if ( gridptr->x.cvals )
-          gridptr->x.stdname = xystdname_tab[grid_xystdname_char][0];
-        if ( gridptr->y.cvals )
-          gridptr->y.stdname = xystdname_tab[grid_xystdname_char][0];
-      }
+        if ( gridptr->x.cvals ) gridptr->x.stdname = xystdname_tab[grid_xystdname_char][0];
+        if ( gridptr->y.cvals ) gridptr->y.stdname = xystdname_tab[grid_xystdname_char][0];
+
+        break;
+     }
     case GRID_GENERIC:
     case GRID_PROJECTION:
       {
@@ -347,8 +348,9 @@ void cdiGridTypeInit(grid_t *gridptr, int gridtype, int size)
 
             gridptr->x.stdname = xystdname_tab[grid_xystdname_projection][0];
             gridptr->y.stdname = xystdname_tab[grid_xystdname_projection][1];
-            gridSetName(gridptr->x.units, "m");
-            gridSetName(gridptr->y.units, "m");
+
+            if ( !gridptr->x.units[0] ) gridSetName(gridptr->x.units, "m");
+            if ( !gridptr->y.units[0] ) gridSetName(gridptr->y.units, "m");
           }
         break;
       }
@@ -1043,8 +1045,8 @@ void gridVerifyProj(int gridID)
     {
       gridptr->x.stdname = xystdname_tab[grid_xystdname_projection][0];
       gridptr->y.stdname = xystdname_tab[grid_xystdname_projection][1];
-      gridSetName(gridptr->x.units, "m");
-      gridSetName(gridptr->y.units, "m");
+      if ( !gridptr->x.units[0] ) gridSetName(gridptr->x.units, "m");
+      if ( !gridptr->y.units[0] ) gridSetName(gridptr->y.units, "m");
     }
 }
 
@@ -1208,14 +1210,14 @@ void gridDefXsize(int gridID, int xsize)
 
 @EndFunction
 */
-void gridDefPrec(int gridID, int prec)
+void gridDefDatatype(int gridID, int datatype)
 {
   grid_t *gridptr = grid_to_pointer(gridID);
 
-  if ( gridptr->prec != prec )
+  if ( gridptr->datatype != datatype )
     {
       gridMark4Update(gridID);
-      gridptr->prec = prec;
+      gridptr->datatype = datatype;
     }
 }
 
@@ -1229,10 +1231,10 @@ void gridDefPrec(int gridID, int prec)
 
 @EndFunction
 */
-int gridInqPrec(int gridID)
+int gridInqDatatype(int gridID)
 {
   grid_t *gridptr = grid_to_pointer(gridID);
-  return gridptr->prec;
+  return gridptr->datatype;
 }
 
 /*
@@ -2403,7 +2405,7 @@ int gridCompareP(void *gridptr1, void *gridptr2)
   xassert ( g2 );
 
   if ( g1->type          != g2->type         ) return differ;
-  if ( g1->prec          != g2->prec         ) return differ;
+  if ( g1->datatype      != g2->datatype     ) return differ;
   if ( g1->isCyclic      != g2->isCyclic     ) return differ;
   if ( g1->x.flag        != g2->x.flag       ) return differ;
   if ( g1->y.flag        != g2->y.flag       ) return differ;
@@ -2567,7 +2569,7 @@ static
 void gridComplete(grid_t *grid)
 {
   int gridID = grid->self;
-  gridDefPrec(gridID, grid->prec);
+  gridDefDatatype(gridID, grid->datatype);
 
   int gridtype = grid->type;
   switch (gridtype)
@@ -2709,7 +2711,7 @@ int gridGenerate(const grid_t *grid)
   int gridtype = grid->type;
   int gridID = gridCreate(gridtype, grid->size);
   grid_t *restrict gridptr = grid_to_pointer(gridID);
-  gridptr->prec = grid->prec;
+  gridptr->datatype = grid->datatype;
   gridptr->x.size = grid->x.size;
   gridptr->y.size = grid->y.size;
   gridptr->np = grid->np;
@@ -3392,9 +3394,9 @@ void gridPrintKernel(int gridID, int opt, FILE *fp)
   int xstrlen  = gridInqXIsc(gridID);
   int ystrlen  = gridInqYIsc(gridID);
   int nvertex  = gridInqNvertex(gridID);
-  int prec     = gridInqPrec(gridID);
+  int datatype = gridInqDatatype(gridID);
 
-  int dig = (prec == CDI_DATATYPE_FLT64) ? 15 : 7;
+  int dig = (datatype == CDI_DATATYPE_FLT64) ? 15 : 7;
 
   fprintf(fp, "gridtype  = %s\n" "gridsize  = %d\n", gridNamePtr(type), gridsize);
 
@@ -3671,7 +3673,7 @@ void gridPrintP(void *voidptr, FILE *fp)
   gridPrintKernel(gridID, 0, fp);
 
   fprintf(fp,
-          "precision = %d\n"
+          "datatype  = %d\n"
           "nd        = %d\n"
           "ni        = %d\n"
           "ni2       = %d\n"
@@ -3681,7 +3683,7 @@ void gridPrintP(void *voidptr, FILE *fp)
           "trunc     = %d\n"
           "lcomplex  = %d\n"
           "nrowlon   = %d\n",
-          gridptr->prec, gridptr->gme.nd, gridptr->gme.ni, gridptr->gme.ni2,
+          gridptr->datatype, gridptr->gme.nd, gridptr->gme.ni, gridptr->gme.ni2,
           gridptr->gme.ni3, gridptr->number, gridptr->position, gridptr->trunc,
           gridptr->lcomplex, gridptr->nrowlon );
 
@@ -4211,7 +4213,7 @@ gridTxCode ()
 enum {
   GRID_PACK_INT_IDX_SELF,
   GRID_PACK_INT_IDX_TYPE,
-  GRID_PACK_INT_IDX_PREC,
+  GRID_PACK_INT_IDX_DATATYPE,
   GRID_PACK_INT_IDX_IS_CYCLIC,
   GRID_PACK_INT_IDX_X_FLAG,
   GRID_PACK_INT_IDX_Y_FLAG,
@@ -4417,7 +4419,7 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
     xassert(!force_id || targetID == gridP->self);
 
     gridP->type          =   intBuffer[GRID_PACK_INT_IDX_TYPE];
-    gridP->prec          =   intBuffer[GRID_PACK_INT_IDX_PREC];
+    gridP->datatype      =   intBuffer[GRID_PACK_INT_IDX_DATATYPE];
     gridP->isCyclic      =   (signed char)intBuffer[GRID_PACK_INT_IDX_IS_CYCLIC];
     gridP->x.flag        =   (short)intBuffer[GRID_PACK_INT_IDX_X_FLAG];
     gridP->y.flag        =   (short)intBuffer[GRID_PACK_INT_IDX_Y_FLAG];
@@ -4603,7 +4605,7 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
 
     intBuffer[GRID_PACK_INT_IDX_SELF]         = gridP->self;
     intBuffer[GRID_PACK_INT_IDX_TYPE]         = gridP->type;
-    intBuffer[GRID_PACK_INT_IDX_PREC]         = gridP->prec;
+    intBuffer[GRID_PACK_INT_IDX_DATATYPE]     = gridP->datatype;
     intBuffer[GRID_PACK_INT_IDX_IS_CYCLIC]    = gridP->isCyclic;
     intBuffer[GRID_PACK_INT_IDX_X_FLAG]       = gridP->x.flag;
     intBuffer[GRID_PACK_INT_IDX_Y_FLAG]       = gridP->y.flag;
diff --git a/libcdi/src/grid.h b/libcdi/src/grid.h
index 40da2ec..65618ee 100644
--- a/libcdi/src/grid.h
+++ b/libcdi/src/grid.h
@@ -83,7 +83,7 @@ struct grid_t {
   int     self;
   int     size;
   int     type;                   /* grid type                      */
-  int     prec;                   /* grid precision                 */
+  int     datatype;               /* grid data type                 */
   int     proj;                   /* grid projection                */
   int     projtype;               /* grid projection type           */
   mask_t *mask;
diff --git a/libcdi/src/iterator.c b/libcdi/src/iterator.c
index 37f8933..46a7e28 100644
--- a/libcdi/src/iterator.c
+++ b/libcdi/src/iterator.c
@@ -29,6 +29,7 @@ static const char* fileType2String(int fileType)
         case CDI_FILETYPE_NC2: return "CDI::Iterator::NetCDF2";
         case CDI_FILETYPE_NC4: return "CDI::Iterator::NetCDF4";
         case CDI_FILETYPE_NC4C: return "CDI::Iterator::NetCDF4C";
+        case CDI_FILETYPE_NC5: return "CDI::Iterator::NetCDF5";
 #endif
 #ifdef HAVE_LIBSERVICE
         case CDI_FILETYPE_SRV: return "CDI::Iterator::SRV";
@@ -63,6 +64,7 @@ static int string2FileType(const char* fileType, const char **outRestString)
   check(fileType, "CDI::Iterator::NetCDF2", CDI_FILETYPE_NC2);
   check(fileType, "CDI::Iterator::NetCDF4", CDI_FILETYPE_NC4);
   check(fileType, "CDI::Iterator::NetCDF4C", CDI_FILETYPE_NC4C);
+  check(fileType, "CDI::Iterator::NetCDF5", CDI_FILETYPE_NC5);
   check(fileType, "CDI::Iterator::SRV", CDI_FILETYPE_SRV);
   check(fileType, "CDI::Iterator::EXT", CDI_FILETYPE_EXT);
   check(fileType, "CDI::Iterator::IEG", CDI_FILETYPE_IEG);
@@ -114,6 +116,7 @@ CdiIterator* cdiIterator_new(const char* path)
         case CDI_FILETYPE_NC2:
         case CDI_FILETYPE_NC4:
         case CDI_FILETYPE_NC4C:
+        case CDI_FILETYPE_NC5:
 #endif
 #ifdef HAVE_LIBSERVICE
         case CDI_FILETYPE_SRV:
@@ -203,6 +206,7 @@ CdiIterator* cdiIterator_clone(CdiIterator* me)
         case CDI_FILETYPE_NC2:
         case CDI_FILETYPE_NC4:
         case CDI_FILETYPE_NC4C:
+        case CDI_FILETYPE_NC5:
 #endif
 #ifdef HAVE_LIBSERVICE
         case CDI_FILETYPE_SRV:
@@ -284,6 +288,7 @@ char* cdiIterator_serialize(CdiIterator* me)
         case CDI_FILETYPE_NC2:
         case CDI_FILETYPE_NC4:
         case CDI_FILETYPE_NC4C:
+        case CDI_FILETYPE_NC5:
 #endif
 #ifdef HAVE_LIBSERVICE
         case CDI_FILETYPE_SRV:
@@ -343,6 +348,7 @@ CdiIterator* cdiIterator_deserialize(const char* description)
         case CDI_FILETYPE_NC2:
         case CDI_FILETYPE_NC4:
         case CDI_FILETYPE_NC4C:
+        case CDI_FILETYPE_NC5:
 #endif
 #ifdef HAVE_LIBSERVICE
         case CDI_FILETYPE_SRV:
@@ -415,6 +421,7 @@ int cdiIterator_nextField(CdiIterator* me)
         case CDI_FILETYPE_NC2:
         case CDI_FILETYPE_NC4:
         case CDI_FILETYPE_NC4C:
+        case CDI_FILETYPE_NC5:
 #endif
 #ifdef HAVE_LIBSERVICE
         case CDI_FILETYPE_SRV:
@@ -449,6 +456,7 @@ static char* cdiIterator_inqTime(CdiIterator* me, CdiTimeType timeType)
         case CDI_FILETYPE_NC2:
         case CDI_FILETYPE_NC4:
         case CDI_FILETYPE_NC4C:
+        case CDI_FILETYPE_NC5:
 #endif
 #ifdef HAVE_LIBSERVICE
         case CDI_FILETYPE_SRV:
@@ -609,6 +617,7 @@ int cdiIterator_inqLevelType(CdiIterator* me, int levelSelector, char **outName,
         case CDI_FILETYPE_NC2:
         case CDI_FILETYPE_NC4:
         case CDI_FILETYPE_NC4C:
+        case CDI_FILETYPE_NC5:
 #endif
 #ifdef HAVE_LIBSERVICE
         case CDI_FILETYPE_SRV:
@@ -659,6 +668,7 @@ int cdiIterator_inqLevel(CdiIterator* me, int levelSelector, double* outValue1,
         case CDI_FILETYPE_NC2:
         case CDI_FILETYPE_NC4:
         case CDI_FILETYPE_NC4C:
+        case CDI_FILETYPE_NC5:
 #endif
 #ifdef HAVE_LIBSERVICE
         case CDI_FILETYPE_SRV:
@@ -709,6 +719,7 @@ int cdiIterator_inqLevelUuid(CdiIterator* me, int* outVgridNumber, int* outLevel
         case CDI_FILETYPE_NC2:
         case CDI_FILETYPE_NC4:
         case CDI_FILETYPE_NC4C:
+        case CDI_FILETYPE_NC5:
 #endif
 #ifdef HAVE_LIBSERVICE
         case CDI_FILETYPE_SRV:
@@ -758,6 +769,7 @@ int cdiIterator_inqTile(CdiIterator* me, int* outTileIndex, int* outTileAttribut
         case CDI_FILETYPE_NC2:
         case CDI_FILETYPE_NC4:
         case CDI_FILETYPE_NC4C:
+        case CDI_FILETYPE_NC5:
       #endif
       #ifdef HAVE_LIBSERVICE
         case CDI_FILETYPE_SRV:
@@ -808,6 +820,7 @@ int cdiIterator_inqTileCount(CdiIterator* me, int* outTileCount, int* outTileAtt
         case CDI_FILETYPE_NC2:
         case CDI_FILETYPE_NC4:
         case CDI_FILETYPE_NC4C:
+        case CDI_FILETYPE_NC5:
       #endif
       #ifdef HAVE_LIBSERVICE
         case CDI_FILETYPE_SRV:
@@ -938,6 +951,7 @@ char* cdiIterator_inqVariableName(CdiIterator* me)
         case CDI_FILETYPE_NC2:
         case CDI_FILETYPE_NC4:
         case CDI_FILETYPE_NC4C:
+        case CDI_FILETYPE_NC5:
 #endif
 #ifdef HAVE_LIBSERVICE
         case CDI_FILETYPE_SRV:
@@ -1008,6 +1022,7 @@ void cdiIterator_readField(CdiIterator* me, double* buffer, size_t* nmiss)
         case CDI_FILETYPE_NC2:
         case CDI_FILETYPE_NC4:
         case CDI_FILETYPE_NC4C:
+        case CDI_FILETYPE_NC5:
 #endif
 #ifdef HAVE_LIBSERVICE
         case CDI_FILETYPE_SRV:
@@ -1057,6 +1072,7 @@ void cdiIterator_readFieldF(CdiIterator* me, float* buffer, size_t* nmiss)
         case CDI_FILETYPE_NC2:
         case CDI_FILETYPE_NC4:
         case CDI_FILETYPE_NC4C:
+        case CDI_FILETYPE_NC5:
 #endif
 #ifdef HAVE_LIBSERVICE
         case CDI_FILETYPE_SRV:
@@ -1068,7 +1084,7 @@ void cdiIterator_readFieldF(CdiIterator* me, float* buffer, size_t* nmiss)
         case CDI_FILETYPE_IEG:
 #endif
           cdiFallbackIterator_readFieldF(me, buffer, nmiss);
-          return; 
+          return;
       default:
         Error(kUnexpectedFileTypeMessage);
     }
@@ -1102,6 +1118,7 @@ void cdiIterator_delete(CdiIterator* me)
         case CDI_FILETYPE_NC2:
         case CDI_FILETYPE_NC4:
         case CDI_FILETYPE_NC4C:
+        case CDI_FILETYPE_NC5:
 #endif
 #ifdef HAVE_LIBSERVICE
         case CDI_FILETYPE_SRV:
diff --git a/libcdi/src/iterator_fallback.c b/libcdi/src/iterator_fallback.c
index 34a431a..03749a3 100644
--- a/libcdi/src/iterator_fallback.c
+++ b/libcdi/src/iterator_fallback.c
@@ -54,7 +54,7 @@ static CdiFallbackIterator *cdiFallbackIterator_condestruct(CdiFallbackIterator
   me->curVariable = -1;
   me->curSubtype = -1;
   me->curLevel = -1;
-  me->path = strdup(path);
+  me->path = path ? strdup(path) : NULL;
   if(!me->path) goto closeStream;
 
   return me;
diff --git a/libcdi/src/mo_cdi.f90 b/libcdi/src/mo_cdi.f90
index a39334c..c126d09 100644
--- a/libcdi/src/mo_cdi.f90
+++ b/libcdi/src/mo_cdi.f90
@@ -49,9 +49,10 @@ module mo_cdi
   integer(c_int), public, parameter :: CDI_FILETYPE_NC2 = 4
   integer(c_int), public, parameter :: CDI_FILETYPE_NC4 = 5
   integer(c_int), public, parameter :: CDI_FILETYPE_NC4C = 6
-  integer(c_int), public, parameter :: CDI_FILETYPE_SRV = 7
-  integer(c_int), public, parameter :: CDI_FILETYPE_EXT = 8
-  integer(c_int), public, parameter :: CDI_FILETYPE_IEG = 9
+  integer(c_int), public, parameter :: CDI_FILETYPE_NC5 = 7
+  integer(c_int), public, parameter :: CDI_FILETYPE_SRV = 8
+  integer(c_int), public, parameter :: CDI_FILETYPE_EXT = 9
+  integer(c_int), public, parameter :: CDI_FILETYPE_IEG = 10
   integer(c_int), public, parameter :: FILETYPE_GRB = 1
   integer(c_int), public, parameter :: FILETYPE_GRB2 = 2
   integer(c_int), public, parameter :: FILETYPE_NC = 3
@@ -178,8 +179,8 @@ module mo_cdi
   integer(c_int), public, parameter :: ZAXIS_CHAR = 26
   integer(c_int), public, parameter :: MAX_KV_PAIRS_MATCH = 10
   integer(c_int), public, parameter :: TIME_CONSTANT = 0
+  integer(c_int), public, parameter :: TIME_VARYING = 1
   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
@@ -208,11 +209,12 @@ module mo_cdi
   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 :: CALENDAR_GREGORIAN = 1
+  integer(c_int), public, parameter :: CALENDAR_PROLEPTIC = 2
+  integer(c_int), public, parameter :: CALENDAR_360DAYS = 3
+  integer(c_int), public, parameter :: CALENDAR_365DAYS = 4
+  integer(c_int), public, parameter :: CALENDAR_366DAYS = 5
+  integer(c_int), public, parameter :: CALENDAR_NONE = 6
   integer(c_int), public, parameter :: CDI_UUID_SIZE = 16
 
   public t_CdiParam
@@ -370,6 +372,8 @@ module mo_cdi
   public :: vlistInqVarGrid
   public :: vlistInqVarZaxis
   public :: vlistInqVarID
+  public :: vlistDefVarTimetype
+  public :: vlistInqVarTimetype
   public :: vlistDefVarTsteptype
   public :: vlistInqVarTsteptype
   public :: vlistDefVarCompType
@@ -510,8 +514,8 @@ module mo_cdi
   public :: gridInqYunits
   public :: gridInqXstdname
   public :: gridInqYstdname
-  public :: gridDefPrec
-  public :: gridInqPrec
+  public :: gridDefDatatype
+  public :: gridInqDatatype
   public :: gridInqXval
   public :: gridInqYval
   public :: gridInqXinc
@@ -579,8 +583,8 @@ module mo_cdi
   public :: zaxisDefUnits
   public :: zaxisInqUnits
   public :: zaxisInqStdname
-  public :: zaxisDefPrec
-  public :: zaxisInqPrec
+  public :: zaxisDefDatatype
+  public :: zaxisInqDatatype
   public :: zaxisDefPositive
   public :: zaxisInqPositive
   public :: zaxisDefScalar
@@ -618,6 +622,7 @@ module mo_cdi
   public :: taxisInqFdate
   public :: taxisInqFtime
   public :: taxisHasBounds
+  public :: taxisWithBounds
   public :: taxisDeleteBounds
   public :: taxisDefVdateBounds
   public :: taxisDefVtimeBounds
@@ -1275,24 +1280,24 @@ module mo_cdi
     end function vlistInqModel
 
     function vlistDefVarTiles(vlistID_dummy, gridID_dummy, zaxisID_dummy,&
-    & tsteptype_dummy, tilesetID_dummy) bind(c, name = 'vlistDefVarTiles')&
+    & timetype_dummy, tilesetID_dummy) bind(c, name = 'vlistDefVarTiles')&
     & result(f_result)
       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
+      integer(c_int), value :: timetype_dummy
       integer(c_int), value :: tilesetID_dummy
       integer(c_int) :: f_result
     end function vlistDefVarTiles
 
     function vlistDefVar(vlistID_dummy, gridID_dummy, zaxisID_dummy,&
-    & tsteptype_dummy) bind(c, name = 'vlistDefVar') result(f_result)
+    & timetype_dummy) bind(c, name = 'vlistDefVar') result(f_result)
       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
+      integer(c_int), value :: timetype_dummy
       integer(c_int) :: f_result
     end function vlistDefVar
 
@@ -1313,13 +1318,13 @@ module mo_cdi
     end subroutine vlistChangeVarZaxis
 
     subroutine vlistInqVar(vlistID_dummy, varID_dummy, gridID_dummy,&
-    & zaxisID_dummy, tsteptype_dummy) bind(c, name = 'vlistInqVar')
+    & zaxisID_dummy, timetype_dummy) bind(c, name = 'vlistInqVar')
       import c_int
       integer(c_int), value :: vlistID_dummy
       integer(c_int), value :: varID_dummy
       integer(c_int), intent(inout) :: gridID_dummy
       integer(c_int), intent(inout) :: zaxisID_dummy
-      integer(c_int), intent(inout) :: tsteptype_dummy
+      integer(c_int), intent(inout) :: timetype_dummy
     end subroutine vlistInqVar
 
     function vlistInqVarGrid(vlistID_dummy, varID_dummy) bind(c, name =&
@@ -1346,6 +1351,22 @@ module mo_cdi
       integer(c_int) :: f_result
     end function vlistInqVarID
 
+    subroutine vlistDefVarTimetype(vlistID_dummy, varID_dummy, timetype_dummy)&
+    & bind(c, name = 'vlistDefVarTimetype')
+      import c_int
+      integer(c_int), value :: vlistID_dummy
+      integer(c_int), value :: varID_dummy
+      integer(c_int), value :: timetype_dummy
+    end subroutine vlistDefVarTimetype
+
+    function vlistInqVarTimetype(vlistID_dummy, varID_dummy) bind(c, name =&
+    & 'vlistInqVarTimetype') result(f_result)
+      import c_int
+      integer(c_int), value :: vlistID_dummy
+      integer(c_int), value :: varID_dummy
+      integer(c_int) :: f_result
+    end function vlistInqVarTimetype
+
     subroutine vlistDefVarTsteptype(vlistID_dummy, varID_dummy,&
     & tsteptype_dummy) bind(c, name = 'vlistDefVarTsteptype')
       import c_int
@@ -1967,19 +1988,19 @@ module mo_cdi
       integer(c_int) :: f_result
     end function cdiZaxisInqKeyFlt
 
-    subroutine gridDefPrec(gridID_dummy, prec_dummy) bind(c, name =&
-    & 'gridDefPrec')
+    subroutine gridDefDatatype(gridID_dummy, prec_dummy) bind(c, name =&
+    & 'gridDefDatatype')
       import c_int
       integer(c_int), value :: gridID_dummy
       integer(c_int), value :: prec_dummy
-    end subroutine gridDefPrec
+    end subroutine gridDefDatatype
 
-    function gridInqPrec(gridID_dummy) bind(c, name = 'gridInqPrec')&
+    function gridInqDatatype(gridID_dummy) bind(c, name = 'gridInqDatatype')&
     & result(f_result)
       import c_int
       integer(c_int), value :: gridID_dummy
       integer(c_int) :: f_result
-    end function gridInqPrec
+    end function gridInqDatatype
 
     function gridInqXval(gridID_dummy, index_dummy) bind(c, name =&
     & 'gridInqXval') result(f_result)
@@ -2398,19 +2419,19 @@ module mo_cdi
       integer(kind = c_signed_char), intent(inout) :: uuid_dummy(CDI_UUID_SIZE)
     end subroutine zaxisInqUUID
 
-    subroutine zaxisDefPrec(zaxisID_dummy, prec_dummy) bind(c, name =&
-    & 'zaxisDefPrec')
+    subroutine zaxisDefDatatype(zaxisID_dummy, prec_dummy) bind(c, name =&
+    & 'zaxisDefDatatype')
       import c_int
       integer(c_int), value :: zaxisID_dummy
       integer(c_int), value :: prec_dummy
-    end subroutine zaxisDefPrec
+    end subroutine zaxisDefDatatype
 
-    function zaxisInqPrec(zaxisID_dummy) bind(c, name = 'zaxisInqPrec')&
+    function zaxisInqDatatype(zaxisID_dummy) bind(c, name = 'zaxisInqDatatype')&
     & result(f_result)
       import c_int
       integer(c_int), value :: zaxisID_dummy
       integer(c_int) :: f_result
-    end function zaxisInqPrec
+    end function zaxisInqDatatype
 
     subroutine zaxisDefPositive(zaxisID_dummy, positive_dummy) bind(c, name =&
     & 'zaxisDefPositive')
@@ -2649,6 +2670,11 @@ module mo_cdi
       integer(c_int) :: f_result
     end function taxisHasBounds
 
+    subroutine taxisWithBounds(taxisID_dummy) bind(c, name = 'taxisWithBounds')
+      import c_int
+      integer(c_int), value :: taxisID_dummy
+    end subroutine taxisWithBounds
+
     subroutine taxisDeleteBounds(taxisID_dummy) bind(c, name =&
     & 'taxisDeleteBounds')
       import c_int
diff --git a/libcdi/src/pio_server.c b/libcdi/src/pio_server.c
index 5a11f16..5774a78 100644
--- a/libcdi/src/pio_server.c
+++ b/libcdi/src/pio_server.c
@@ -1117,6 +1117,8 @@ readGetBuffers(size_t streamIdx, const struct cdiPioConf *conf)
       case CDI_FILETYPE_NC:
       case CDI_FILETYPE_NC2:
       case CDI_FILETYPE_NC4:
+      case CDI_FILETYPE_NC4C:
+      case CDI_FILETYPE_NC5:
         writeNetCDFStream(streamIdx, map, &data, &currentDataBufSize, conf);
         break;
 #endif
@@ -1262,6 +1264,7 @@ cdiPioServerStreamClose(stream_t *streamptr, int recordBufIsToBeDeleted)
         case CDI_FILETYPE_NC2:
         case CDI_FILETYPE_NC4:
         case CDI_FILETYPE_NC4C:
+        case CDI_FILETYPE_NC5:
           {
             int rank, rankOpen = cdiPioSerialOpenFileMap(streamptr->self);
             if (commInqIOMode() == PIO_NONE
diff --git a/libcdi/src/stream.c b/libcdi/src/stream.c
index 28fbef0..ad1c3eb 100644
--- a/libcdi/src/stream.c
+++ b/libcdi/src/stream.c
@@ -1,5 +1,5 @@
-#if defined (HAVE_CONFIG_H)
-#  include "config.h"
+#ifdef  HAVE_CONFIG_H
+#include "config.h"
 #endif
 
 #ifndef _XOPEN_SOURCE
@@ -129,6 +129,11 @@ int cdiGetFiletype(const char *filename, int *byteorder)
       filetype = CDI_FILETYPE_NC2;
       if ( CDI_Debug ) Message("found CDF2 file = %s", filename);
     }
+  else if ( memcmp(buffer, "CDF\005", 4) == 0 )
+    {
+      filetype = CDI_FILETYPE_NC5;
+      if ( CDI_Debug ) Message("found CDF5 file = %s", filename);
+    }
   else if ( memcmp(buffer+1, "HDF", 3) == 0 )
     {
       filetype = CDI_FILETYPE_NC4;
@@ -185,7 +190,7 @@ The function @func{streamInqFiletype} returns the filetype of a stream.
 @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{CDI_FILETYPE_GRB}, @func{CDI_FILETYPE_GRB2}, @func{CDI_FILETYPE_NC}, @func{CDI_FILETYPE_NC2},
- at func{CDI_FILETYPE_NC4}, @func{CDI_FILETYPE_NC4C}, @func{CDI_FILETYPE_SRV}, @func{CDI_FILETYPE_EXT} and @func{CDI_FILETYPE_IEG}.
+ at func{CDI_FILETYPE_NC4}, @func{CDI_FILETYPE_NC4C}, @func{CDI_FILETYPE_NC5}, @func{CDI_FILETYPE_SRV}, @func{CDI_FILETYPE_EXT} and @func{CDI_FILETYPE_IEG}.
 
 @EndFunction
 */
@@ -240,7 +245,7 @@ void streamDefByteorder(int streamID, int byteorder)
 
   switch (filetype)
     {
-#if  defined  (HAVE_LIBSERVICE)
+#ifdef  HAVE_LIBSERVICE
     case CDI_FILETYPE_SRV:
       {
 	srvrec_t *srvp = (srvrec_t*) streamptr->record->exsep;
@@ -249,7 +254,7 @@ void streamDefByteorder(int streamID, int byteorder)
 	break;
       }
 #endif
-#if  defined  (HAVE_LIBEXTRA)
+#ifdef  HAVE_LIBEXTRA
     case CDI_FILETYPE_EXT:
       {
 	extrec_t *extp = (extrec_t*) streamptr->record->exsep;
@@ -258,7 +263,7 @@ void streamDefByteorder(int streamID, int byteorder)
 	break;
       }
 #endif
-#if  defined  (HAVE_LIBIEG)
+#ifdef  HAVE_LIBIEG
     case CDI_FILETYPE_IEG:
       {
 	iegrec_t *iegp = (iegrec_t*) streamptr->record->exsep;
@@ -340,7 +345,7 @@ int cdiInqContents(stream_t *streamptr)
 
   switch (filetype)
     {
-#if  defined  (HAVE_LIBGRIB)
+#ifdef  HAVE_LIBGRIB
     case CDI_FILETYPE_GRB:
     case CDI_FILETYPE_GRB2:
       {
@@ -348,32 +353,33 @@ int cdiInqContents(stream_t *streamptr)
 	break;
       }
 #endif
-#if  defined  (HAVE_LIBSERVICE)
+#ifdef  HAVE_LIBSERVICE
     case CDI_FILETYPE_SRV:
       {
         status = srvInqContents(streamptr);
 	break;
       }
 #endif
-#if  defined  (HAVE_LIBEXTRA)
+#ifdef  HAVE_LIBEXTRA
     case CDI_FILETYPE_EXT:
       {
         status = extInqContents(streamptr);
 	break;
       }
 #endif
-#if  defined  (HAVE_LIBIEG)
+#ifdef  HAVE_LIBIEG
     case CDI_FILETYPE_IEG:
       {
         status = iegInqContents(streamptr);
 	break;
       }
 #endif
-#if  defined  (HAVE_LIBNETCDF)
+#ifdef  HAVE_LIBNETCDF
     case CDI_FILETYPE_NC:
     case CDI_FILETYPE_NC2:
     case CDI_FILETYPE_NC4:
     case CDI_FILETYPE_NC4C:
+    case CDI_FILETYPE_NC5:
       {
         status = cdfInqContents(streamptr);
 	break;
@@ -411,9 +417,9 @@ int cdiStreamOpenDefaultDelegate(const char *filename, char filemode,
   int fileID;
   switch (filetype)
     {
-#if  defined  (HAVE_LIBGRIB)
+#ifdef  HAVE_LIBGRIB
     case CDI_FILETYPE_GRB:
-#if  defined  (HAVE_LIBGRIB_API)
+#ifdef  HAVE_LIBGRIB_API
     case CDI_FILETYPE_GRB2:
 #endif
       {
@@ -432,7 +438,7 @@ int cdiStreamOpenDefaultDelegate(const char *filename, char filemode,
         break;
       }
 #endif
-#if  defined  (HAVE_LIBSERVICE)
+#ifdef  HAVE_LIBSERVICE
     case CDI_FILETYPE_SRV:
       {
 #ifndef __cplusplus
@@ -451,7 +457,7 @@ int cdiStreamOpenDefaultDelegate(const char *filename, char filemode,
         break;
       }
 #endif
-#if  defined  (HAVE_LIBEXTRA)
+#ifdef  HAVE_LIBEXTRA
     case CDI_FILETYPE_EXT:
       {
 #ifndef __cplusplus
@@ -471,7 +477,7 @@ int cdiStreamOpenDefaultDelegate(const char *filename, char filemode,
         break;
       }
 #endif
-#if  defined  (HAVE_LIBIEG)
+#ifdef  HAVE_LIBIEG
     case CDI_FILETYPE_IEG:
       {
 #ifndef __cplusplus
@@ -490,24 +496,16 @@ int cdiStreamOpenDefaultDelegate(const char *filename, char filemode,
         break;
       }
 #endif
-#if  defined  (HAVE_LIBNETCDF)
+#ifdef  HAVE_LIBNETCDF
     case CDI_FILETYPE_NC:
-      {
-#ifndef __cplusplus
-        fileID = cdfOpen(filename, (char [2]){filemode, 0});
-#else
-        char temp[2] = { filemode, 0 };
-        fileID = cdfOpen(filename, temp);
-#endif
-        break;
-      }
     case CDI_FILETYPE_NC2:
+    case CDI_FILETYPE_NC5:
       {
 #ifndef __cplusplus
-        fileID = cdfOpen64(filename, (char [2]){filemode, 0});
+        fileID = cdfOpen(filename, (char [2]){filemode, 0}, filetype);
 #else
         char temp[2] = { filemode, 0 };
-        fileID = cdfOpen64(filename, temp);
+        fileID = cdfOpen(filename, temp, filetype);
 #endif
         break;
       }
@@ -657,9 +655,9 @@ int streamOpenA(const char *filename, const char *filemode, int filetype)
 
   switch (filetype)
     {
-#if  defined  (HAVE_LIBGRIB)
+#ifdef  HAVE_LIBGRIB
     case CDI_FILETYPE_GRB:
-#if  defined  (HAVE_LIBGRIB_API)
+#ifdef  HAVE_LIBGRIB_API
     case CDI_FILETYPE_GRB2:
 #endif
       {
@@ -668,37 +666,33 @@ int streamOpenA(const char *filename, const char *filemode, int filetype)
 	break;
       }
 #endif
-#if  defined  (HAVE_LIBSERVICE)
+#ifdef  HAVE_LIBSERVICE
     case CDI_FILETYPE_SRV:
       {
         fileID = fileOpen(filename, filemode);
 	break;
       }
 #endif
-#if  defined  (HAVE_LIBEXTRA)
+#ifdef  HAVE_LIBEXTRA
     case CDI_FILETYPE_EXT:
       {
         fileID = fileOpen(filename, filemode);
 	break;
       }
 #endif
-#if  defined  (HAVE_LIBIEG)
+#ifdef  HAVE_LIBIEG
     case CDI_FILETYPE_IEG:
       {
         fileID = fileOpen(filename, filemode);
 	break;
       }
 #endif
-#if  defined  (HAVE_LIBNETCDF)
+#ifdef  HAVE_LIBNETCDF
     case CDI_FILETYPE_NC:
-      {
-	fileID = cdfOpen(filename, filemode);
-	streamptr->ncmode = 2;
-	break;
-      }
     case CDI_FILETYPE_NC2:
+    case CDI_FILETYPE_NC5:
       {
-	fileID = cdfOpen64(filename, filemode);
+	fileID = cdfOpen(filename, filemode, filetype);
 	streamptr->ncmode = 2;
 	break;
       }
@@ -813,7 +807,7 @@ int streamOpenAppend(const char *filename)
     @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{CDI_FILETYPE_GRB}, @func{CDI_FILETYPE_GRB2}, @func{CDI_FILETYPE_NC},
-                     @func{CDI_FILETYPE_NC2}, @func{CDI_FILETYPE_NC4}, @func{CDI_FILETYPE_NC4C}, @func{CDI_FILETYPE_SRV},
+                     @func{CDI_FILETYPE_NC2}, @func{CDI_FILETYPE_NC4}, @func{CDI_FILETYPE_NC4C}, @func{CDI_FILETYPE_NC5}, @func{CDI_FILETYPE_SRV},
                      @func{CDI_FILETYPE_EXT} and @func{CDI_FILETYPE_IEG}.
 
 @Description
@@ -937,7 +931,7 @@ void cdiStreamCloseDefaultDelegate(stream_t *streamptr, int recordBufIsToBeDelet
   else
     switch (filetype)
       {
-#if  defined  (HAVE_LIBGRIB)
+#ifdef  HAVE_LIBGRIB
       case CDI_FILETYPE_GRB:
       case CDI_FILETYPE_GRB2:
         {
@@ -946,7 +940,7 @@ void cdiStreamCloseDefaultDelegate(stream_t *streamptr, int recordBufIsToBeDelet
           break;
         }
 #endif
-#if  defined  (HAVE_LIBSERVICE)
+#ifdef  HAVE_LIBSERVICE
       case CDI_FILETYPE_SRV:
         {
           fileClose(fileID);
@@ -954,7 +948,7 @@ void cdiStreamCloseDefaultDelegate(stream_t *streamptr, int recordBufIsToBeDelet
           break;
         }
 #endif
-#if  defined  (HAVE_LIBEXTRA)
+#ifdef  HAVE_LIBEXTRA
       case CDI_FILETYPE_EXT:
         {
           fileClose(fileID);
@@ -962,7 +956,7 @@ void cdiStreamCloseDefaultDelegate(stream_t *streamptr, int recordBufIsToBeDelet
           break;
         }
 #endif
-#if  defined  (HAVE_LIBIEG)
+#ifdef  HAVE_LIBIEG
       case CDI_FILETYPE_IEG:
         {
           fileClose(fileID);
@@ -970,11 +964,12 @@ void cdiStreamCloseDefaultDelegate(stream_t *streamptr, int recordBufIsToBeDelet
           break;
         }
 #endif
-#if  defined  (HAVE_LIBNETCDF)
+#ifdef  HAVE_LIBNETCDF
       case CDI_FILETYPE_NC:
       case CDI_FILETYPE_NC2:
       case CDI_FILETYPE_NC4:
       case CDI_FILETYPE_NC4C:
+      case CDI_FILETYPE_NC5:
         {
           cdfClose(fileID);
           if (streamptr->ntsteps == 0)
@@ -1117,11 +1112,12 @@ void cdiStreamSync_(stream_t *streamptr)
 	{
 	  switch (filetype)
 	    {
-#if  defined  (HAVE_LIBNETCDF)
+#ifdef  HAVE_LIBNETCDF
 	    case CDI_FILETYPE_NC:
 	    case CDI_FILETYPE_NC2:
 	    case CDI_FILETYPE_NC4:
 	    case CDI_FILETYPE_NC4C:
+	    case CDI_FILETYPE_NC5:
 	      {
 		void cdf_sync(int ncid);
 		if ( streamptr->ncmode == 2 ) cdf_sync(fileID);
@@ -1163,19 +1159,18 @@ void streamSync(int streamID)
 
 int cdiStreamDefTimestep_(stream_t *streamptr, int tsID)
 {
-  int taxisID = 0;
-
   stream_check_ptr(__func__, streamptr);
 
   if ( CDI_Debug ) Message("streamID = %d  tsID = %d", streamptr->self, tsID);
 
   int vlistID = streamptr->vlistID;
-
   int time_is_varying = vlistHasTime(vlistID);
+  int taxisID = vlistInqTaxis(vlistID) ;
 
+  /* moved to cdiStreamSetupVlist
+  int taxisID = time_is_varying ? vlistInqTaxis(vlistID) : CDI_UNDEFID;
   if ( time_is_varying )
     {
-      taxisID = vlistInqTaxis(vlistID);
       if ( taxisID == CDI_UNDEFID )
         {
           Warning("taxisID undefined for fileID = %d! Using absolute time axis.", streamptr->self);
@@ -1183,26 +1178,24 @@ int cdiStreamDefTimestep_(stream_t *streamptr, int tsID)
           vlistDefTaxis(vlistID, taxisID);
         }
     }
-
-  int newtsID = tstepsNewEntry(streamptr);
-
-  if ( tsID != newtsID )
-    Error("Internal problem: tsID = %d newtsID = %d", tsID, newtsID);
-
-  streamptr->curTsID = tsID;
-
-  if ( time_is_varying )
+  */
+  if ( tsID > 0 )
     {
-      taxis_t *taxisptr1 = taxisPtr(taxisID);
-      taxis_t *taxisptr2 = &streamptr->tsteps[tsID].taxis;
-      ptaxisCopy(taxisptr2, taxisptr1);
+      int newtsID = tstepsNewEntry(streamptr);
+      if ( tsID != newtsID )
+        Error("Internal problem: tsID = %d newtsID = %d", tsID, newtsID);
     }
 
+  if ( time_is_varying )
+    ptaxisCopy(&streamptr->tsteps[tsID].taxis, taxisPtr(taxisID));
+
+  streamptr->curTsID = tsID;
   streamptr->ntsteps = tsID + 1;
 
 #ifdef HAVE_LIBNETCDF
   if ((streamptr->filetype == CDI_FILETYPE_NC  ||
        streamptr->filetype == CDI_FILETYPE_NC2 ||
+       streamptr->filetype == CDI_FILETYPE_NC5 ||
        streamptr->filetype == CDI_FILETYPE_NC4 ||
        streamptr->filetype == CDI_FILETYPE_NC4C)
       && time_is_varying)
@@ -1221,7 +1214,7 @@ int cdiStreamDefTimestep_(stream_t *streamptr, int tsID)
 
 /*
 @Function  streamDefTimestep
- at Title     Define time step
+ at Title     Define a timestep
 
 @Prototype int streamDefTimestep(int streamID, int tsID)
 @Parameter
@@ -1229,10 +1222,13 @@ int cdiStreamDefTimestep_(stream_t *streamptr, int tsID)
     @Item  tsID      Timestep identifier.
 
 @Description
-The function @func{streamDefTimestep} defines the time step of a stream.
+The function @func{streamDefTimestep} defines a timestep of a stream by the identifier tsID.
+The identifier tsID is the timestep index starting at 0 for the first timestep.
+Before calling this function the functions @func{taxisDefVdate} and @func{taxisDefVtime} should be used
+to define the timestamp for this timestep. All calls to write the data refer to this timestep.
 
 @Result
- at func{streamDefTimestep} returns the number of records of the time step.
+ at func{streamDefTimestep} returns the number of expected records of the timestep.
 
 @EndFunction
 */
@@ -1254,7 +1250,7 @@ int streamInqCurTimestepID(int streamID)
 
 /*
 @Function  streamInqTimestep
- at Title     Get time step
+ at Title     Get timestep information
 
 @Prototype int streamInqTimestep(int streamID, int tsID)
 @Parameter
@@ -1262,10 +1258,13 @@ int streamInqCurTimestepID(int streamID)
     @Item  tsID      Timestep identifier.
 
 @Description
-The function @func{streamInqTimestep} returns the time step of a stream.
+The function @func{streamInqTimestep} sets the next timestep to the identifier tsID.
+The identifier tsID is the timestep index starting at 0 for the first timestep.
+After a call to this function the functions @func{taxisInqVdate} and @func{taxisInqVtime} can be used
+to read the timestamp for this timestep. All calls to read the data refer to this timestep.
 
 @Result
- at func{streamInqTimestep} returns the number of records of the time step.
+ at func{streamInqTimestep} returns the number of records of the timestep or 0, if the end of the file is reached.
 
 @EndFunction
 */
@@ -1301,7 +1300,7 @@ int streamInqTimestep(int streamID, int tsID)
 
   switch (filetype)
     {
-#if  defined  (HAVE_LIBGRIB)
+#ifdef  HAVE_LIBGRIB
     case CDI_FILETYPE_GRB:
     case CDI_FILETYPE_GRB2:
       {
@@ -1309,32 +1308,33 @@ int streamInqTimestep(int streamID, int tsID)
 	break;
       }
 #endif
-#if  defined  (HAVE_LIBSERVICE)
+#ifdef  HAVE_LIBSERVICE
     case CDI_FILETYPE_SRV:
       {
         nrecs = srvInqTimestep(streamptr, tsID);
 	break;
       }
 #endif
-#if  defined  (HAVE_LIBEXTRA)
+#ifdef  HAVE_LIBEXTRA
     case CDI_FILETYPE_EXT:
       {
         nrecs = extInqTimestep(streamptr, tsID);
 	break;
       }
 #endif
-#if  defined  (HAVE_LIBIEG)
+#ifdef  HAVE_LIBIEG
     case CDI_FILETYPE_IEG:
       {
         nrecs = iegInqTimestep(streamptr, tsID);
 	break;
       }
 #endif
-#if  defined  (HAVE_LIBNETCDF)
+#ifdef  HAVE_LIBNETCDF
     case CDI_FILETYPE_NC:
     case CDI_FILETYPE_NC2:
     case CDI_FILETYPE_NC4:
     case CDI_FILETYPE_NC4C:
+    case CDI_FILETYPE_NC5:
       {
         nrecs = cdfInqTimestep(streamptr, tsID);
 	break;
@@ -1607,32 +1607,69 @@ void cdiStreamSetupVlist_(stream_t *streamptr, int vlistID)
     }
 
   if (streamptr->filemode == 'w')
-    switch (streamptr->filetype)
-      {
-#ifdef HAVE_LIBNETCDF
-      case CDI_FILETYPE_NC:
-      case CDI_FILETYPE_NC2:
-      case CDI_FILETYPE_NC4:
-      case CDI_FILETYPE_NC4C:
+    {
+      tstepsNewEntry(streamptr); // timestep 0
+      int vlistID = streamptr->vlistID;
+      int time_is_varying = vlistHasTime(vlistID);
+      if ( time_is_varying )
         {
-          /* calls cdfDefVars in serial mode but
-           * cdiPioClientStreamNOP (i.e. nothing) on client ranks
-           * and cdiPioServerCdfDefVars on server ranks in parallel mode*/
-          void (*myCdfDefVars)(stream_t *streamptr)
-            = (void (*)(stream_t *)) namespaceSwitchGet(NSSWITCH_CDF_STREAM_SETUP).func;
-          myCdfDefVars(streamptr);
+          int 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 ( taxisInqType(taxisID) == TAXIS_RELATIVE )
+            switch (streamptr->filetype)
+              {
+#ifdef HAVE_LIBNETCDF
+              case CDI_FILETYPE_NC:
+              case CDI_FILETYPE_NC2:
+              case CDI_FILETYPE_NC4:
+              case CDI_FILETYPE_NC4C:
+              case CDI_FILETYPE_NC5:
+                {
+                  taxis_t *taxisptr = taxisPtr(taxisID);
+                  if ( taxisptr->rdate == -1 ) taxisDefRdate(taxisID, 10101);
+                }
+                break;
+#endif
+              default:
+                ;
+              }
+          ptaxisCopy(&streamptr->tsteps[0].taxis, taxisPtr(taxisID));
         }
-        break;
+
+      switch (streamptr->filetype)
+        {
+#ifdef HAVE_LIBNETCDF
+        case CDI_FILETYPE_NC:
+        case CDI_FILETYPE_NC2:
+        case CDI_FILETYPE_NC4:
+        case CDI_FILETYPE_NC4C:
+        case CDI_FILETYPE_NC5:
+          {
+            /* calls cdfDefVars in serial mode but
+             * cdiPioClientStreamNOP (i.e. nothing) on client ranks
+             * and cdiPioServerCdfDefVars on server ranks in parallel mode*/
+            void (*myCdfDefVars)(stream_t *streamptr)
+              = (void (*)(stream_t *)) namespaceSwitchGet(NSSWITCH_CDF_STREAM_SETUP).func;
+            myCdfDefVars(streamptr);
+          }
+          break;
 #endif
 #ifdef HAVE_LIBGRIB
-      case CDI_FILETYPE_GRB:
-      case CDI_FILETYPE_GRB2:
-        gribContainersNew(streamptr);
-        break;
+        case CDI_FILETYPE_GRB:
+        case CDI_FILETYPE_GRB2:
+          gribContainersNew(streamptr);
+          break;
 #endif
-      default:
-        ;
-      }
+        default:
+          ;
+        }
+    }
 }
 
 
diff --git a/libcdi/src/stream_cdf_i.c b/libcdi/src/stream_cdf_i.c
index dc738c9..2c7fe11 100644
--- a/libcdi/src/stream_cdf_i.c
+++ b/libcdi/src/stream_cdf_i.c
@@ -54,13 +54,13 @@ typedef struct {
   bool     calendar;
   bool     climatology;
   bool     lformulaterms;
-  int      tsteptype;
   int      param;
   int      code;
   int      tabnum;
   int      bounds;
   int      gridID;
   int      zaxisID;
+  int      timetype;
   int      gridtype;
   int      zaxistype;
   int      xdim;
@@ -195,7 +195,7 @@ void setForecastTime(const char *timestr, taxis_t *taxis)
 static
 int setBaseTime(const char *timeunits, taxis_t *taxis)
 {
-  int timetype = TAXIS_ABSOLUTE;
+  int taxistype = TAXIS_ABSOLUTE;
   int rdate = -1, rtime = -1;
 
   size_t len = strlen(timeunits);
@@ -220,14 +220,14 @@ int setBaseTime(const char *timeunits, taxis_t *taxis)
       while ( isspace(tu[pos]) ) ++pos;
 
       if ( str_is_equal(tu+pos, "since") )
-        timetype = TAXIS_RELATIVE;
+        taxistype = TAXIS_RELATIVE;
 
       while ( pos < len && !isspace(tu[pos]) ) ++pos;
       if ( tu[pos] )
         {
           while ( isspace(tu[pos]) ) ++pos;
 
-          if ( timetype == TAXIS_ABSOLUTE )
+          if ( taxistype == TAXIS_ABSOLUTE )
             {
               if ( timeunit == TUNIT_DAY )
                 {
@@ -246,7 +246,7 @@ int setBaseTime(const char *timeunits, taxis_t *taxis)
                     }
                 }
             }
-          else if ( timetype == TAXIS_RELATIVE )
+          else if ( taxistype == TAXIS_RELATIVE )
             {
               scanTimeString(tu+pos, &rdate, &rtime);
 
@@ -259,13 +259,13 @@ int setBaseTime(const char *timeunits, taxis_t *taxis)
         }
     }
 
-  taxis->type = timetype;
+  taxis->type = taxistype;
   taxis->unit = timeunit;
 
   Free(tu);
 
   if ( CDI_Debug )
-    Message("timetype = %d  unit = %d", timetype, timeunit);
+    Message("taxistype = %d  unit = %d", taxistype, timeunit);
 
   return 0;
 }
@@ -520,7 +520,7 @@ void cdfCreateRecords(stream_t *streamptr, int tsID)
       int nvrecs = 0;
       for ( int varID = 0; varID < nvars; varID++ )
         {
-          if ( vlistInqVarTsteptype(vlistID, varID) != TSTEP_CONSTANT )
+          if ( vlistInqVarTimetype(vlistID, varID) != TIME_CONSTANT )
             {
               int zaxisID = vlistInqVarZaxis(vlistID, varID);
               nvrecs += zaxisInqSize(zaxisID);
@@ -543,7 +543,7 @@ void cdfCreateRecords(stream_t *streamptr, int tsID)
           for ( int recID = 0, vrecID = 0; recID < nrecs; recID++ )
             {
               int varID = destTstep->records[recID].varID;
-              if ( vlistInqVarTsteptype(vlistID, varID) != TSTEP_CONSTANT )
+              if ( vlistInqVarTimetype(vlistID, varID) != TIME_CONSTANT )
                 {
                   destTstep->recIDs[vrecID++] = recID;
                 }
@@ -640,7 +640,7 @@ void init_ncvars(long nvars, ncvar_t *ncvars)
       ncvars[ncvarid].calendar        = false;
       ncvars[ncvarid].climatology     = false;
       ncvars[ncvarid].lformulaterms   = false;
-      ncvars[ncvarid].tsteptype       = TSTEP_CONSTANT;
+      ncvars[ncvarid].timetype        = TIME_CONSTANT;
       ncvars[ncvarid].param           = CDI_UNDEFID;
       ncvars[ncvarid].code            = CDI_UNDEFID;
       ncvars[ncvarid].tabnum          = 0;
@@ -1128,7 +1128,7 @@ void cdf_scan_var_attr(int nvars, ncvar_t *ncvars, ncdim_t *ncdims, int timedimi
         {
           if ( timedimid == dimidsp[0] )
             {
-              ncvars[ncvarid].tsteptype = TSTEP_INSTANT;
+              ncvars[ncvarid].timetype = TIME_VARYING;
               cdf_set_dim(ncvars, ncvarid, 0, T_AXIS);
             }
           else
@@ -1905,7 +1905,8 @@ void verify_coordinate_vars_2(int nvars, ncvar_t *ncvars)
 		  ncvars[ncvarid].isy = true;
 		  continue;
 		}
-	      else if ( strcmp(ncvars[ncvarid].units, "level") == 0 || strcmp(ncvars[ncvarid].units, "1") == 0 )
+	      else if ( ncvars[ncvarid].zaxistype == CDI_UNDEFID &&
+                        (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;
@@ -2156,7 +2157,7 @@ bool cdf_read_xcoord(struct cdfLazyGrid *restrict lazyGrid, ncdim_t *ncdims, ncv
   *islon = axisvar->islon;
   int ndims = axisvar->ndims;
   size_t size = 0;
-  int prec = cdfInqDatatype(axisvar->xtype, axisvar->lunsigned);
+  int datatype = cdfInqDatatype(axisvar->xtype, axisvar->lunsigned);
 
   if ( (ndims - ntdims) == 2 )
     {
@@ -2166,7 +2167,7 @@ bool cdf_read_xcoord(struct cdfLazyGrid *restrict lazyGrid, ncdim_t *ncdims, ncv
       dimid = axisvar->dimids[ndims-1];
       size_t dimsize2 = ncdims[dimid].len;
 
-      if ( prec == CDI_DATATYPE_UINT8 )
+      if ( datatype == CDI_DATATYPE_UINT8 )
         {
           ncvar->gridtype = GRID_CHARXY;
           size = dimsize1*dimsize2;
@@ -2200,9 +2201,9 @@ bool cdf_read_xcoord(struct cdfLazyGrid *restrict lazyGrid, ncdim_t *ncdims, ncv
       return true;
     }
 
-  if ( prec != -1 )  grid->prec = prec;
+  if ( datatype != -1 )  grid->datatype = datatype;
 
-  if ( prec == CDI_DATATYPE_UINT8 && !CDI_netcdf_lazy_grid_load )
+  if ( datatype == CDI_DATATYPE_UINT8 && !CDI_netcdf_lazy_grid_load )
     {
       cdf_load_cvals(size, xvarid, axisvar, &grid->x.cvals, *xsize);
       grid->x.clength = size / (*xsize) ;
@@ -2224,7 +2225,7 @@ bool cdf_read_ycoord(struct cdfLazyGrid *restrict lazyGrid, ncdim_t *ncdims, ncv
   *islat = axisvar->islat;
   int ndims = axisvar->ndims;
   size_t size = 0;
-  int prec = cdfInqDatatype(axisvar->xtype, axisvar->lunsigned);
+  int datatype = cdfInqDatatype(axisvar->xtype, axisvar->lunsigned);
 
   if ( (ndims - ntdims) == 2 )
     {
@@ -2234,7 +2235,7 @@ bool cdf_read_ycoord(struct cdfLazyGrid *restrict lazyGrid, ncdim_t *ncdims, ncv
       dimid = axisvar->dimids[ndims-1];
       size_t dimsize2 = ncdims[dimid].len;
 
-      if ( prec == CDI_DATATYPE_UINT8 )
+      if ( datatype == CDI_DATATYPE_UINT8 )
         {
           ncvar->gridtype = GRID_CHARXY;
           size = dimsize1*dimsize2;
@@ -2269,9 +2270,9 @@ bool cdf_read_ycoord(struct cdfLazyGrid *restrict lazyGrid, ncdim_t *ncdims, ncv
       return true;
     }
 
-  if ( prec != -1 )  grid->prec = prec;
+  if ( datatype != -1 )  grid->datatype = datatype;
 
-  if ( prec == CDI_DATATYPE_UINT8 && !CDI_netcdf_lazy_grid_load )
+  if ( datatype == CDI_DATATYPE_UINT8 && !CDI_netcdf_lazy_grid_load )
     {
       cdf_load_cvals(size, yvarid, axisvar, &grid->y.cvals, *ysize);
       grid->y.clength = size / (*ysize) ;
@@ -2291,7 +2292,7 @@ bool cdf_read_coordinates(struct cdfLazyGrid *restrict lazyGrid, ncvar_t *ncvar,
   grid_t *grid = &lazyGrid->base;
   size_t size = 0;
 
-  grid->prec = CDI_DATATYPE_FLT64;
+  grid->datatype = CDI_DATATYPE_FLT64;
 
   if ( ncvar->gridtype == GRID_TRAJECTORY )
     {
@@ -2481,7 +2482,8 @@ bool cdf_read_coordinates(struct cdfLazyGrid *restrict lazyGrid, ncvar_t *ncvar,
     {
       int ndims = ncvar->ndims;
       int *dimtype = ncvar->dimtype;
-      if ( (ndims == 1 && dimtype[0] == T_AXIS) ||
+      if ( ndims == 0 ||
+           (ndims == 1 && dimtype[0] == T_AXIS) ||
            (ndims == 1 && dimtype[0] == Z_AXIS) ||
            (ndims == 2 && dimtype[0] == T_AXIS && dimtype[1] == Z_AXIS) )
         {
@@ -2769,6 +2771,11 @@ int cdf_define_all_grids(ncgrid_t *ncgrid, int vlistID, ncdim_t *ncdims, int nva
           ncgrid[gridindex].gridID = gridID;
           ncgrid[gridindex].ncIDs[CDF_DIMID_X] = xdimid;
           ncgrid[gridindex].ncIDs[CDF_DIMID_Y] = ydimid;
+          if ( grid->type == GRID_TRAJECTORY )
+            {
+              ncgrid[gridindex].ncIDs[CDF_VARID_X] = xvarid;
+              ncgrid[gridindex].ncIDs[CDF_VARID_Y] = yvarid;
+            }
 
           if ( xdimid == CDI_UNDEFID && ydimid == CDI_UNDEFID && grid->size == 1 )
             gridDefHasDims(gridID, FALSE);
@@ -2858,7 +2865,7 @@ int cdf_define_all_zaxes(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int
 	  if ( zvarid != CDI_UNDEFID ) zaxisType = ncvars[zvarid].zaxistype;
 	  if ( zaxisType == CDI_UNDEFID ) zaxisType = ZAXIS_GENERIC;
 
-	  int zprec = CDI_DATATYPE_FLT64;
+	  int zdatatype = CDI_DATATYPE_FLT64;
 	  double *restrict lbounds = NULL;
 	  double *restrict ubounds = NULL;
 
@@ -2868,7 +2875,7 @@ int cdf_define_all_zaxes(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int
 	      pname     = ncvars[zvarid].name;
 	      plongname = ncvars[zvarid].longname;
 	      punits    = ncvars[zvarid].units;
-	      if ( ncvars[zvarid].xtype == NC_FLOAT ) zprec = CDI_DATATYPE_FLT32;
+	      if ( ncvars[zvarid].xtype == NC_FLOAT ) zdatatype = CDI_DATATYPE_FLT32;
 	      /* don't change the name !!! */
 	      /*
 	      if ( (len = strlen(pname)) > 2 )
@@ -2879,7 +2886,7 @@ int cdf_define_all_zaxes(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int
                 {
                   if ( ncvars[zvarid].ndims == 2 )
                     {
-                      zprec = CDI_DATATYPE_UINT8;
+                      zdatatype = CDI_DATATYPE_UINT8;
                       zclength = ncdims[ncvars[zvarid].dimids[1]].len;
                       cdf_load_cvals(zsize*zclength, zvarid, ncvar, &zcvals, zsize);
                     }
@@ -2947,7 +2954,7 @@ int cdf_define_all_zaxes(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int
             }
 
       	  ncvar->zaxisID = varDefZaxis(vlistID, zaxisType, (int) zsize, zvar, (const char **)zcvals, zclength, with_bounds, lbounds, ubounds,
-                                       (int)vctsize, vct, pname, plongname, punits, zprec, 1, 0);
+                                       (int)vctsize, vct, pname, plongname, punits, zdatatype, 1, 0);
 
           int zaxisID = ncvar->zaxisID;
 
@@ -3088,7 +3095,7 @@ void cdf_define_all_vars(stream_t *streamptr, int vlistID, int instID, int model
       int zaxisID = ncvars[ncvarid].zaxisID;
 
       stream_new_var(streamptr, gridID, zaxisID, CDI_UNDEFID);
-      int varID = vlistDefVar(vlistID, gridID, zaxisID, ncvars[ncvarid].tsteptype);
+      int varID = vlistDefVar(vlistID, gridID, zaxisID, ncvars[ncvarid].timetype);
 
 #if  defined  (HAVE_NETCDF4)
       if ( ncvars[ncvarid].deflate )
@@ -3153,7 +3160,7 @@ void cdf_define_all_vars(stream_t *streamptr, int vlistID, int instID, int model
       int ixyz = 0;
       static const int ipow10[4] = {1, 10, 100, 1000};
 
-      if ( ncvars[ncvarid].tsteptype != TSTEP_CONSTANT ) iodim++;
+      if ( ncvars[ncvarid].timetype != TIME_CONSTANT ) iodim++;
 
       const int *dimids = ncvars[ncvarid].dimids;
 
@@ -3708,15 +3715,15 @@ int cdfInqContents(stream_t *streamptr)
 
   if ( CDI_Debug )
     Message("root: ndims %d, nvars %d, ngatts %d", ndims, nvars, ngatts);
-
+  /*
   if ( ndims == 0 )
     {
       Warning("No dimensions found!");
       return CDI_EUFSTRUCT;
     }
-
-  /* alloc ncdims */
-  ncdim_t *ncdims = (ncdim_t *) Malloc((size_t)ndims * sizeof (ncdim_t));
+  */
+  // alloc ncdims
+  ncdim_t *ncdims = ndims ? (ncdim_t *) Malloc((size_t)ndims * sizeof(ncdim_t)) : NULL;
   init_ncdims(ndims, ncdims);
 
 #if  defined  (TEST_GROUPS)
@@ -3752,18 +3759,18 @@ int cdfInqContents(stream_t *streamptr)
       return CDI_EUFSTRUCT;
     }
 
-  /* alloc ncvars */
-  ncvar_t *ncvars = (ncvar_t *) Malloc((size_t)nvars * sizeof (ncvar_t));
+  // alloc ncvars
+  ncvar_t *ncvars = nvars ? (ncvar_t *) Malloc((size_t)nvars * sizeof (ncvar_t)) : NULL;
   init_ncvars(nvars, ncvars);
 
   for ( ncvarid = 0; ncvarid < nvars; ++ncvarid ) ncvars[ncvarid].ncid = fileID;
 
 
-  /* scan global attributes */
+  // scan global attributes
   cdf_scan_global_attr(fileID, vlistID, streamptr, ngatts, &instID, &modelID, &ucla_les,
                        uuidOfHGrid, uuidOfVGrid, gridfile, &number_of_grid_used);
 
-  /* find time dim */
+  // find time dim
   int timedimid = (unlimdimid >= 0) ? unlimdimid : cdf_time_dimid(fileID, ndims, nvars);
 
   streamptr->basetime.ncdimid = timedimid;
@@ -3779,7 +3786,7 @@ int cdfInqContents(stream_t *streamptr)
   if ( CDI_Debug ) Message("Number of timesteps = %zu", ntsteps);
   if ( CDI_Debug ) Message("Time dimid = %d", streamptr->basetime.ncdimid);
 
-  /* read ncdims */
+  // read ncdims
   for ( ncdimid = 0; ncdimid < ndims; ncdimid++ )
     {
       cdf_inq_dimlen(fileID, ncdimid, &ncdims[ncdimid].len);
@@ -3790,13 +3797,13 @@ int cdfInqContents(stream_t *streamptr)
 
   if ( CDI_Debug ) cdf_print_vars(ncvars, nvars, "cdf_scan_var_attr");
 
-  /* scan attributes of all variables */
+  // scan attributes of all variables
   cdf_scan_var_attr(nvars, ncvars, ncdims, timedimid, modelID, format);
 
 
   if ( CDI_Debug ) cdf_print_vars(ncvars, nvars, "find coordinate vars");
 
-  /* find coordinate vars */
+  // find coordinate vars
   for ( ncdimid = 0; ncdimid < ndims; ncdimid++ )
     {
       for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
@@ -3823,20 +3830,20 @@ int cdfInqContents(stream_t *streamptr)
 	}
     }
 
-  /* find time vars */
+  // 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 != CDI_UNDEFID ) ncvars[leadtime_id].isvar = FALSE;
 
-  /* check ncvars */
+  // check ncvars
   timedimid = cdf_check_vars(nvars, ncvars, ntsteps, timedimid);
 
-  /* verify coordinate vars - first scan (dimname == varname) */
+  // verify coordinate vars - first scan (dimname == varname)
   bool lhybrid_cf = false;
   verify_coordinate_vars_1(fileID, ndims, ncdims, ncvars, timedimid, &lhybrid_cf);
 
-  /* verify coordinate vars - second scan (all other variables) */
+  // verify coordinate vars - second scan (all other variables)
   verify_coordinate_vars_2(nvars, ncvars);
 
   if ( CDI_Debug ) cdf_print_vars(ncvars, nvars, "verify_coordinate_vars");
@@ -3869,7 +3876,7 @@ int cdfInqContents(stream_t *streamptr)
     }
   */
 
-  /* Set coordinate varids (att: associate)  */
+  // Set coordinate varids (att: associate)
   for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
     {
       ncvar_t *ncvar = &ncvars[ncvarid];
@@ -3888,10 +3895,10 @@ int cdfInqContents(stream_t *streamptr)
 	}
     }
 
-  /* set dim type */
+  // set dim type
   cdf_set_dimtype(nvars, ncvars, ncdims);
 
-  /* read ECHAM VCT if present */
+  // read ECHAM VCT if present
   size_t vctsize = 0;
   double *vct = NULL;
   if ( !lhybrid_cf ) read_vct_echam(fileID, nvars, ncvars, ncdims, &vct, &vctsize);
@@ -3899,18 +3906,18 @@ int cdfInqContents(stream_t *streamptr)
 
   if ( CDI_Debug ) cdf_print_vars(ncvars, nvars, "cdf_define_all_grids");
 
-  /* define all grids */
+  // define all grids
   int status;
   status = cdf_define_all_grids(streamptr->ncgrid, vlistID, ncdims, nvars, ncvars, timedimid, uuidOfHGrid, gridfile, number_of_grid_used);
   if ( status < 0 ) return status;
 
-  /* define all zaxes */
+  // define all zaxes
   status = cdf_define_all_zaxes(streamptr, vlistID, ncdims, nvars, ncvars, vctsize, vct, uuidOfVGrid);
   if ( vct ) Free(vct);
   if ( status < 0 ) return status;
 
 
-  /* select vars */
+  // select vars
   varids = (int *) Malloc((size_t)nvars * sizeof (int));
   nvarids = 0;
   for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
@@ -3934,13 +3941,13 @@ int cdfInqContents(stream_t *streamptr)
 
   streamptr->ntsteps = (long)ntsteps;
 
-  /* define all data variables */
+  // define all data variables
   cdf_define_all_vars(streamptr, vlistID, instID, modelID, varids, nvars_data, nvars, ncvars);
 
 
   cdiCreateTimesteps(streamptr);
 
-  /* time varID */
+  // time varID
   int nctimevarid = streamptr->basetime.ncvarid;
 
   if ( time_has_units )
@@ -4045,11 +4052,11 @@ int cdfInqContents(stream_t *streamptr)
 
   cdfCreateRecords(streamptr, 0);
 
-  /* free ncdims */
-  Free(ncdims);
+  // free ncdims
+  if ( ncdims ) Free(ncdims);
 
-  /* free ncvars */
-  Free(ncvars);
+  // free ncvars
+  if ( ncvars ) Free(ncvars);
 
   return 0;
 }
@@ -4131,7 +4138,7 @@ int cdfInqTimestep(stream_t * streamptr, int tsID)
       if ( nctimevarid != CDI_UNDEFID )
 	{
 	  int fileID = streamptr->fileID;
-	  size_t index  = (size_t)tsID;
+	  size_t index = (size_t)tsID;
 
 	  if ( streamptr->basetime.lwrf )
 	    {
diff --git a/libcdi/src/stream_cdf_o.c b/libcdi/src/stream_cdf_o.c
index 9e5527e..e0268ad 100644
--- a/libcdi/src/stream_cdf_o.c
+++ b/libcdi/src/stream_cdf_o.c
@@ -74,11 +74,11 @@ void cdfDefTimeValue(stream_t *streamptr, int tsID)
 
   if ( taxis->has_bounds )
     {
-      size_t start[2], count[2];
-
       ncvarid = streamptr->basetime.ncvarboundsid;
+      if ( ncvarid == CDI_UNDEFID ) Error("Call to taxisWithBounds() missing!");
 
       timevalue = cdiEncodeTimeval(taxis->vdate_lb, taxis->vtime_lb, &streamptr->tsteps[0].taxis);
+      size_t start[2], count[2];
       start[0] = (size_t)tsID; count[0] = 1; start[1] = 0; count[1] = 1;
       cdf_put_vara_double(fileID, ncvarid, start, count, &timevalue);
 
@@ -97,10 +97,6 @@ void cdfDefTimeValue(stream_t *streamptr, int tsID)
 
 void cdfDefTimestep(stream_t *streamptr, int tsID)
 {
-  int vlistID = streamptr->vlistID;
-
-  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
-
   cdfDefTimeValue(streamptr, tsID);
 }
 
@@ -301,15 +297,14 @@ static void
 cdfDefTrajLatLon(stream_t *streamptr, int gridID, int gridindex,
                  const struct cdfDefGridAxisInqs *inqs, int dimtype)
 {
-  nc_type xtype = (gridInqPrec(gridID) == CDI_DATATYPE_FLT32) ? NC_FLOAT : NC_DOUBLE;
+  nc_type xtype = (gridInqDatatype(gridID) == CDI_DATATYPE_FLT32) ? NC_FLOAT : NC_DOUBLE;
   ncgrid_t *ncgrid = streamptr->ncgrid;
 
   int dimlen = inqs->axisSize(gridID);
   if ( dimlen != 1 )
     Error("%c size isn't 1 for %s grid!", dimtype, gridNamePtr(gridInqType(gridID)));
 
-  int ncvarid
-    = ncgrid[gridindex].ncIDs[dimtype == 'X' ? CDF_DIMID_X : CDF_DIMID_Y];
+  int ncvarid = ncgrid[gridindex].ncIDs[dimtype == 'X' ? CDF_DIMID_X : CDF_DIMID_Y];
 
   if ( ncvarid == CDI_UNDEFID )
     {
@@ -458,7 +453,7 @@ cdfDefAxisCommon(stream_t *streamptr, int gridID, int gridindex, int ndims,
   int nvdimID = CDI_UNDEFID;
   int fileID  = streamptr->fileID;
   size_t dimlen = (size_t)gridAxisInq->axisSize(gridID);
-  nc_type xtype = (nc_type)cdfDefDatatype(gridInqPrec(gridID), streamptr->filetype);
+  nc_type xtype = (nc_type)cdfDefDatatype(gridInqDatatype(gridID), streamptr->filetype);
 
   ncgrid_t *ncgrid = streamptr->ncgrid;
 
@@ -532,11 +527,13 @@ cdfDefAxisCommon(stream_t *streamptr, int gridID, int gridindex, int ndims,
             cdf_put_att_text(fileID, ncvarid, "axis", 1, axisStr);
           }
 
+          size_t nvertex = gridInqNvertex(gridID);
           pbounds = (double *)gridAxisInq->axisBoundsPtr(gridID);
 
           if ( CDI_cmor_mode && grid_is_cyclic && !pbounds )
             {
               gen_bounds = true;
+              nvertex = 2;
               pbounds = (double*) Malloc(2*dimlen*sizeof(double));
               for ( size_t i = 0; i < dimlen-1; ++i )
                 {
@@ -547,13 +544,12 @@ cdfDefAxisCommon(stream_t *streamptr, int gridID, int gridindex, int ndims,
             }
           if ( pbounds )
             {
-              size_t nvertex = gridInqNvertex(gridID);
               if ( nc_inq_dimid(fileID, bndsName, &nvdimID) != NC_NOERR )
                 cdf_def_dim(fileID, bndsName, nvertex, &nvdimID);
             }
           if ( pbounds && nvdimID != CDI_UNDEFID )
             {
-              char boundsname[extendedAxisnameLen + 1 + sizeof (bndsName)];
+              char boundsname[extendedAxisnameLen + 1 + sizeof(bndsName)];
               memcpy(boundsname, axisname, extendedAxisnameLen);
               boundsname[extendedAxisnameLen] = '_';
               memcpy(boundsname + extendedAxisnameLen + 1, bndsName, sizeof bndsName);
@@ -668,7 +664,7 @@ cdfDefIrregularGridCommon(stream_t *streamptr, int gridID,
                           size_t nvertex, const char *vdimname_default,
                           bool setVdimname)
 {
-  nc_type xtype = (nc_type)cdfDefDatatype(gridInqPrec(gridID), streamptr->filetype);
+  nc_type xtype = (nc_type)cdfDefDatatype(gridInqDatatype(gridID), streamptr->filetype);
   int xdimID = CDI_UNDEFID;
   int ydimID = CDI_UNDEFID;
   int ncxvarid = CDI_UNDEFID, ncyvarid = CDI_UNDEFID, ncavarid = CDI_UNDEFID;
@@ -1482,7 +1478,7 @@ void cdfDefZaxis(stream_t *streamptr, int zaxisID)
   char axisname[CDI_MAX_NAME];
   int dimID = CDI_UNDEFID;
   int ncvarid = CDI_UNDEFID, ncbvarid = CDI_UNDEFID;
-  int xtype = zaxisInqPrec(zaxisID) == CDI_DATATYPE_FLT32 ? NC_FLOAT : NC_DOUBLE;
+  int xtype = zaxisInqDatatype(zaxisID) == CDI_DATATYPE_FLT32 ? NC_FLOAT : NC_DOUBLE;
 
   int vlistID = streamptr->vlistID;
   int fileID  = streamptr->fileID;
@@ -1492,39 +1488,40 @@ void cdfDefZaxis(stream_t *streamptr, int zaxisID)
   int nzaxis = vlistNzaxis(vlistID);
 
   size_t dimlen = (size_t)zaxisInqSize(zaxisID);
-  int type   = zaxisInqType(zaxisID);
+  int type = zaxisInqType(zaxisID);
+
+  int ndims = 1;
 
-  bool is_scalar = false;
   if ( dimlen == 1 )
     {
-      is_scalar = zaxisInqScalar(zaxisID) > 0;
+      bool is_scalar = zaxisInqScalar(zaxisID) > 0;
       if ( !is_scalar && CDI_cmor_mode )
         {
           is_scalar = true;
           zaxisDefScalar(zaxisID);
         }
-    }
 
-  int ndims = is_scalar ? 0 : 1;
+      if ( is_scalar ) ndims = 0;
+      if ( CDI_reduce_dim ) return;
 
-  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;
-      }
+      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;
+        }
+    }
 
   zaxisInqName(zaxisID, axisname);
 
@@ -1798,7 +1795,7 @@ void cdfDefRgrid(stream_t *streamptr, int gridID, int gridindex)
           lwarn = false;
         }
 
-      char axisname[7] = "rgridX";
+      char axisname[16] = "rgridX";
       if ( iz == 0 ) axisname[5] = '\0';
       else           sprintf(&axisname[5], "%1d", iz+1);
 
@@ -1874,6 +1871,13 @@ void cdfDefGrid(stream_t *streamptr, int gridID, int gridindex)
   if ( CDI_Debug )
     Message("gridtype = %d  size = %d", gridtype, size);
 
+  if ( CDI_reduce_dim && size == 1 )
+    {
+      // no grid information
+      streamptr->ncgrid[gridindex].gridID = gridID;
+      return;
+    }
+
   if ( gridtype == GRID_GAUSSIAN    ||
        gridtype == GRID_LONLAT      ||
        gridtype == GRID_PROJECTION  ||
@@ -1883,7 +1887,7 @@ void cdfDefGrid(stream_t *streamptr, int gridID, int gridindex)
         {
           if ( size == 1 && gridInqXsize(gridID) == 0 && gridInqYsize(gridID) == 0 )
             {
-              /* no grid information */
+              // no grid information
               streamptr->ncgrid[gridindex].gridID = gridID;
             }
           else
@@ -1973,6 +1977,8 @@ void cdfDefVars(stream_t *streamptr)
   if ( vlistID == CDI_UNDEFID )
     Error("Internal problem! vlist undefined for streamptr %p", streamptr);
 
+  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
+
   int ngrids = vlistNgrids(vlistID);
   if ( 2*ngrids > MAX_GRIDS_PS ) Error("Internal problem! Too many grids per stream (max=%d)\n", MAX_GRIDS_PS);
   for ( int index = 0; index < 2*ngrids; ++index )
@@ -2002,6 +2008,12 @@ void cdfDefVars(stream_t *streamptr)
       int zaxisID = vlistZaxis(vlistID, index);
       if ( streamptr->zaxisID[index] == CDI_UNDEFID ) cdfDefZaxis(streamptr, zaxisID);
     }
+
+  if ( streamptr->ncmode != 2 )
+    {
+      cdf_enddef(streamptr->fileID);
+      streamptr->ncmode = 2;
+    }
 }
 
 #endif
diff --git a/libcdi/src/stream_cdf_time.c b/libcdi/src/stream_cdf_time.c
index dd9d35b..dfce44d 100644
--- a/libcdi/src/stream_cdf_time.c
+++ b/libcdi/src/stream_cdf_time.c
@@ -4,15 +4,13 @@
 
 #ifdef HAVE_LIBNETCDF
 
-#  include <stdio.h>
-#  include <string.h>
+#include <stdio.h>
+#include <string.h>
 
-#  include <netcdf.h>
-
-#  include "cdi.h"
-#  include "cdi_int.h"
-#  include "stream_cdf.h"
-#  include "cdf_int.h"
+#include "cdi.h"
+#include "cdi_int.h"
+#include "stream_cdf.h"
+#include "cdf_int.h"
 
 static
 int cdfDefTimeBounds(int fileID, int nctimevarid, int nctimedimid, const char *taxis_name, taxis_t* taxis)
@@ -57,7 +55,7 @@ int cdfDefTimeBounds(int fileID, int nctimevarid, int nctimedimid, const char *t
 }
 
 static
-void cdfDefTimeUnits(char *unitstr, taxis_t* taxis0, taxis_t* taxis)
+void cdfDefTimeUnits(char *unitstr, taxis_t *taxis0, taxis_t *taxis)
 {
   if ( taxis->units && taxis->units[0] )
     {
@@ -80,14 +78,12 @@ void cdfDefTimeUnits(char *unitstr, taxis_t* taxis0, taxis_t* taxis)
         }
       else
         {
-          int timeunit = taxis->unit != -1 ? taxis->unit : TUNIT_HOUR;
-          int rdate    = taxis->rdate != -1 ? taxis->rdate : taxis->vdate;
-          int rtime    = taxis->rdate != -1 ? taxis->rtime : taxis->vtime;
           int year, month, day, hour, minute, second;
-          cdiDecodeDate(rdate, &year, &month, &day);
-          cdiDecodeTime(rtime, &hour, &minute, &second);
+          cdiDecodeDate(taxis->rdate, &year, &month, &day);
+          cdiDecodeTime(taxis->rtime, &hour, &minute, &second);
 
-          if ( timeunit == TUNIT_QUARTER   ) timeunit = TUNIT_MINUTE;
+          int timeunit = taxis->unit  != -1 ? taxis->unit  : TUNIT_HOUR;
+          if      ( timeunit == TUNIT_QUARTER   ) timeunit = TUNIT_MINUTE;
           else if ( timeunit == TUNIT_30MINUTES ) timeunit = TUNIT_MINUTE;
           else if (    timeunit == TUNIT_3HOURS
                     || timeunit == TUNIT_6HOURS
@@ -119,6 +115,7 @@ void cdfDefCalendar(int fileID, int ncvarid, int calendar)
 {
   static const struct { int calCode; const char *calStr; } calTab[] = {
     { CALENDAR_STANDARD, "standard" },
+    { CALENDAR_GREGORIAN, "gregorian" },
     { CALENDAR_PROLEPTIC, "proleptic_gregorian" },
     { CALENDAR_NONE, "none" },
     { CALENDAR_360DAYS, "360_day" },
diff --git a/libcdi/src/stream_cgribex.c b/libcdi/src/stream_cgribex.c
index 3fd9cb2..c5a0c6c 100644
--- a/libcdi/src/stream_cgribex.c
+++ b/libcdi/src/stream_cgribex.c
@@ -595,7 +595,7 @@ cgribexScanTsConstAdjust(stream_t *streamptr, taxis_t *taxis)
 	{
 	  streamptr->ntsteps = 0;
 	  for ( int varID = 0; varID < streamptr->nvars; varID++ )
-            vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
+            vlistDefVarTimetype(vlistID, varID, TIME_CONSTANT);
 	}
     }
 }
@@ -1035,7 +1035,7 @@ int cgribexScanTimestep2(stream_t * streamptr)
       if ( ! streamptr->tsteps[tsID].records[recID].used )
 	{
 	  varID = streamptr->tsteps[tsID].records[recID].varID;
-          vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
+          vlistDefVarTimetype(vlistID, varID, TIME_CONSTANT);
 	}
       else
 	{
@@ -1534,16 +1534,12 @@ void cgribexDefTime(int *isec1, int vdate, int vtime, int tsteptype, int numavg,
 
   if ( timetype == TAXIS_RELATIVE )
     {
-      int factor = 1;
-      int rdate, rtime;
-      int ip1 = 0, ip2 = 0;
-      int calendar;
-
-      calendar = taxisInqCalendar(taxisID);
-      rdate    = taxisInqRdate(taxisID);
-      rtime    = taxisInqRtime(taxisID);
+      int calendar = taxisInqCalendar(taxisID);
+      int rdate    = taxisInqRdate(taxisID);
+      int rtime    = taxisInqRtime(taxisID);
 
-      factor = cgribexDefDateTime(isec1, timeunit, rdate, rtime);
+      int factor = cgribexDefDateTime(isec1, timeunit, rdate, rtime);
+      int ip1 = 0, ip2 = 0;
       timerange = cgribexDefTimerange(tsteptype, factor, calendar,
 				      rdate, rtime, vdate, vtime, &ip1, &ip2);
 
diff --git a/libcdi/src/stream_ext.c b/libcdi/src/stream_ext.c
index 4d5a83e..f5456ce 100644
--- a/libcdi/src/stream_ext.c
+++ b/libcdi/src/stream_ext.c
@@ -178,7 +178,7 @@ void extAddRecord(stream_t *streamptr, int param, int level, int xysize,
   int vlistID = streamptr->vlistID;
   int tsID    = streamptr->curTsID;
   int recID   = recordNewEntry(streamptr, tsID);
-  record_t *record  = &streamptr->tsteps[tsID].records[recID];
+  record_t *record = &streamptr->tsteps[tsID].records[recID];
 
   record->size     = recsize;
   record->position = position;
@@ -330,9 +330,7 @@ void extScanTimestep1(stream_t *streamptr)
 	{
 	  streamptr->ntsteps = 0;
 	  for ( varID = 0; varID < streamptr->nvars; varID++ )
-	    {
-	      vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
-	    }
+            vlistDefVarTimetype(vlistID, varID, TIME_CONSTANT);
 	}
     }
 }
@@ -461,7 +459,7 @@ int extScanTimestep2(stream_t *streamptr)
       if ( ! streamptr->tsteps[tsID].records[recID].used )
 	{
 	  varID = streamptr->tsteps[tsID].records[recID].varID;
-          vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
+          vlistDefVarTimetype(vlistID, varID, TIME_CONSTANT);
 	}
       else
 	{
diff --git a/libcdi/src/stream_gribapi.c b/libcdi/src/stream_gribapi.c
index 156bb91..88f40d8 100644
--- a/libcdi/src/stream_gribapi.c
+++ b/libcdi/src/stream_gribapi.c
@@ -1004,9 +1004,7 @@ int gribapiScanTimestep1(stream_t * streamptr)
         {
           streamptr->ntsteps = 0;
           for ( int varID = 0; varID < streamptr->nvars; varID++ )
-            {
-              vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
-            }
+            vlistDefVarTimetype(vlistID, varID, TIME_CONSTANT);
         }
     }
 
@@ -1208,7 +1206,7 @@ int gribapiScanTimestep2(stream_t * streamptr)
       if ( ! streamptr->tsteps[tsID].records[recID].used )
 	{
 	  int varID = streamptr->tsteps[tsID].records[recID].varID;
-	  vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
+	  vlistDefVarTimetype(vlistID, varID, TIME_CONSTANT);
 	}
       else
 	{
diff --git a/libcdi/src/stream_history.c b/libcdi/src/stream_history.c
index 0ac5400..3fd1d8b 100644
--- a/libcdi/src/stream_history.c
+++ b/libcdi/src/stream_history.c
@@ -1,5 +1,5 @@
-#if defined (HAVE_CONFIG_H)
-#  include "config.h"
+#ifdef  HAVE_CONFIG_H
+#include "config.h"
 #endif
 
 #include "dmemory.h"
@@ -7,15 +7,17 @@
 #include "cdi_int.h"
 #include "stream_cdf.h"
 
+#ifdef HAVE_LIBNETCDF
 static inline bool
 filetypeIsNetCDF(int filetype)
 {
   return filetype == CDI_FILETYPE_NC
     ||   filetype == CDI_FILETYPE_NC2
+    ||   filetype == CDI_FILETYPE_NC5
     ||   filetype == CDI_FILETYPE_NC4
     ||   filetype == CDI_FILETYPE_NC4C;
 }
-
+#endif
 
 void streamDefHistory(int streamID, int length, const char *history)
 {
diff --git a/libcdi/src/stream_ieg.c b/libcdi/src/stream_ieg.c
index 8527ac8..8850336 100644
--- a/libcdi/src/stream_ieg.c
+++ b/libcdi/src/stream_ieg.c
@@ -845,9 +845,7 @@ void iegScanTimestep1(stream_t *streamptr)
 	{
 	  streamptr->ntsteps = 0;
 	  for ( int varID = 0; varID < streamptr->nvars; varID++ )
-	    {
-	      vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
-	    }
+            vlistDefVarTimetype(vlistID, varID, TIME_CONSTANT);
 	}
     }
 }
@@ -980,7 +978,7 @@ int iegScanTimestep2(stream_t *streamptr)
       if ( ! streamptr->tsteps[tsID].records[recID].used )
 	{
 	  int varID = streamptr->tsteps[tsID].records[recID].varID;
-          vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
+          vlistDefVarTimetype(vlistID, varID, TIME_CONSTANT);
 	}
       else
 	{
diff --git a/libcdi/src/stream_read.c b/libcdi/src/stream_read.c
index b4e4971..031ef34 100644
--- a/libcdi/src/stream_read.c
+++ b/libcdi/src/stream_read.c
@@ -70,6 +70,7 @@ int cdiStreamReadVar(int streamID, int varID, int memtype, void *data, int *nmis
     case CDI_FILETYPE_NC2:
     case CDI_FILETYPE_NC4:
     case CDI_FILETYPE_NC4C:
+    case CDI_FILETYPE_NC5:
       {
         cdf_read_var(streamptr, varID, memtype, data, nmiss);
 	break;
@@ -196,6 +197,7 @@ int cdiStreamReadVarSlice(int streamID, int varID, int levelID, int memtype, voi
     case CDI_FILETYPE_NC2:
     case CDI_FILETYPE_NC4:
     case CDI_FILETYPE_NC4C:
+    case CDI_FILETYPE_NC5:
       {
         cdf_read_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
         break;
@@ -317,6 +319,7 @@ int stream_read_record(int streamID, int memtype, void *data, int *nmiss)
     case CDI_FILETYPE_NC2:
     case CDI_FILETYPE_NC4:
     case CDI_FILETYPE_NC4C:
+    case CDI_FILETYPE_NC5:
       cdf_read_record(streamptr, memtype, data, nmiss);
       break;
 #endif
diff --git a/libcdi/src/stream_record.c b/libcdi/src/stream_record.c
index f6d44a2..cccd20c 100644
--- a/libcdi/src/stream_record.c
+++ b/libcdi/src/stream_record.c
@@ -1,5 +1,5 @@
-#if defined (HAVE_CONFIG_H)
-#  include "config.h"
+#ifdef  HAVE_CONFIG_H
+#include "config.h"
 #endif
 
 #include <limits.h>
@@ -131,7 +131,7 @@ void streamInqRecord(int streamID, int *varID, int *levelID)
   *levelID = streamptr->vars[*varID].recordTable[isub].lindex[lindex];
 
   if ( CDI_Debug )
-    Message("tsID = %d, recID = %d, varID = %d, levelID = %d\n", tsID, recID, *varID, *levelID);
+    Message("tsID = %d, recID = %d, varID = %d, levelID = %d", tsID, recID, *varID, *levelID);
 
   streamptr->curTsID = tsID;
   streamptr->tsteps[tsID].curRecID = rindex;
@@ -209,6 +209,7 @@ void streamDefRecord(int streamID, int varID, int levelID)
     case CDI_FILETYPE_NC2:
     case CDI_FILETYPE_NC4:
     case CDI_FILETYPE_NC4C:
+    case CDI_FILETYPE_NC5:
       if ( streamptr->accessmode == 0 ) cdfEndDef(streamptr);
       cdfDefRecord(streamptr);
       break;
@@ -237,12 +238,14 @@ void streamCopyRecord(int streamID2, int streamID1)
         case CDI_FILETYPE_NC2:
         case CDI_FILETYPE_NC4:
         case CDI_FILETYPE_NC4C:
+        case CDI_FILETYPE_NC5:
           switch (filetype2)
             {
             case CDI_FILETYPE_NC:
             case CDI_FILETYPE_NC2:
             case CDI_FILETYPE_NC4:
             case CDI_FILETYPE_NC4C:
+            case CDI_FILETYPE_NC5:
               // Warning("Streams have different file types (%s -> %s)!", strfiletype(filetype1), strfiletype(filetype2));
               filetype = filetype2;
               break;
@@ -282,6 +285,7 @@ void streamCopyRecord(int streamID2, int streamID1)
     case CDI_FILETYPE_NC2:
     case CDI_FILETYPE_NC4:
     case CDI_FILETYPE_NC4C:
+    case CDI_FILETYPE_NC5:
       cdfCopyRecord(streamptr2, streamptr1);
       break;
 #endif
@@ -330,7 +334,7 @@ void cdi_create_records(stream_t *streamptr, int tsID)
 	{
 	  int varID = sourceTstep->records[recID].varID;
 	  nrecords += (varID == CDI_UNDEFID /* varID = CDI_UNDEFID for write mode !!! */
-                       || vlistInqVarTsteptype(vlistID, varID) != TSTEP_CONSTANT);
+                       || vlistInqVarTimetype(vlistID, varID) != TIME_CONSTANT);
           //    printf("varID nrecords %d %d %d \n", varID, nrecords, vlistInqVarTsteptype(vlistID, varID));
 	}
     }
@@ -362,7 +366,7 @@ void cdi_create_records(stream_t *streamptr, int tsID)
           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 )
+              if ( vlistInqVarTimetype(vlistID, curRecord->varID) != TIME_CONSTANT )
                 {
                   destTstep->records[recID].position = CDI_UNDEFID;
                   destTstep->records[recID].size     = 0;
diff --git a/libcdi/src/stream_srv.c b/libcdi/src/stream_srv.c
index f4d28fa..cae8a90 100644
--- a/libcdi/src/stream_srv.c
+++ b/libcdi/src/stream_srv.c
@@ -334,7 +334,7 @@ void srvScanTimestep1(stream_t *streamptr)
 	{
 	  streamptr->ntsteps = 0;
 	  for ( int varID = 0; varID < streamptr->nvars; varID++ )
-            vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
+            vlistDefVarTimetype(vlistID, varID, TIME_CONSTANT);
 	}
     }
 }
@@ -460,7 +460,7 @@ int srvScanTimestep2(stream_t *streamptr)
       if ( ! streamptr->tsteps[tsID].records[recID].used )
 	{
 	  int varID = streamptr->tsteps[tsID].records[recID].varID;
-          vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
+          vlistDefVarTimetype(vlistID, varID, TIME_CONSTANT);
 	}
       else
 	{
diff --git a/libcdi/src/stream_write.c b/libcdi/src/stream_write.c
index 36f62cc..dd8cf2e 100644
--- a/libcdi/src/stream_write.c
+++ b/libcdi/src/stream_write.c
@@ -72,6 +72,7 @@ int cdiStreamWriteVar_(int streamID, int varID, int memtype, const void *data, i
     case CDI_FILETYPE_NC2:
     case CDI_FILETYPE_NC4:
     case CDI_FILETYPE_NC4C:
+    case CDI_FILETYPE_NC5:
       {
         cdf_write_var(streamptr, varID, memtype, data, nmiss);
 	break;
@@ -208,6 +209,7 @@ int cdiStreamWriteVarSlice(int streamID, int varID, int levelID, int memtype, co
     case CDI_FILETYPE_NC2:
     case CDI_FILETYPE_NC4:
     case CDI_FILETYPE_NC4C:
+    case CDI_FILETYPE_NC5:
       cdf_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
       break;
 #endif
@@ -323,6 +325,7 @@ void cdiStreamWriteVarChunk_(int streamID, int varID, int memtype,
     case CDI_FILETYPE_NC2:
     case CDI_FILETYPE_NC4:
     case CDI_FILETYPE_NC4C:
+    case CDI_FILETYPE_NC5:
       cdf_write_var_chunk(streamptr, varID, memtype, rect, data, nmiss);
       break;
 #endif
@@ -374,6 +377,7 @@ int stream_write_record(int streamID, int memtype, const void *data, int nmiss)
     case CDI_FILETYPE_NC2:
     case CDI_FILETYPE_NC4:
     case CDI_FILETYPE_NC4C:
+    case CDI_FILETYPE_NC5:
       {
 	cdf_write_record(streamptr, memtype, data, nmiss);
 	break;
diff --git a/libcdi/src/table.c b/libcdi/src/table.c
index a6ac127..6224861 100644
--- a/libcdi/src/table.c
+++ b/libcdi/src/table.c
@@ -78,6 +78,7 @@ static void tableLink(int tableID, const param_type *pars, int npars)
   for ( int item = 0; item < npars; item++ )
     {
       parTable[tableID].pars[item].id       = pars[item].id;
+      parTable[tableID].pars[item].ltype    = pars[item].ltype;
       parTable[tableID].pars[item].dupflags = 0;
       parTable[tableID].pars[item].name     = pars[item].name;
       parTable[tableID].pars[item].longname = pars[item].longname;
diff --git a/libcdi/src/taxis.c b/libcdi/src/taxis.c
index de00160..e0ed2da 100644
--- a/libcdi/src/taxis.c
+++ b/libcdi/src/taxis.c
@@ -379,6 +379,7 @@ void taxisDefRdate(int taxisID, int rdate)
   if (taxisptr->rdate != rdate)
     {
       taxisptr->rdate = rdate;
+
       if ( taxisptr->units )
         {
           delete_refcount_string(taxisptr->units);
@@ -566,6 +567,18 @@ int taxisHasBounds(int taxisID)
 }
 
 
+void taxisWithBounds(int taxisID)
+{
+  taxis_t *taxisptr = (taxis_t *)reshGetVal(taxisID, &taxisOps);
+
+  if ( taxisptr->has_bounds == false )
+    {
+      taxisptr->has_bounds = true;
+      reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
+    }
+}
+
+
 void taxisDeleteBounds(int taxisID)
 {
   taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
@@ -1084,8 +1097,8 @@ double vtime2timeval(int vdate, int vtime, taxis_t *taxis)
   int rtime = (*taxis).rtime;
   if ( rdate == -1 )
     {
-      rdate  = (*taxis).vdate;
-      rtime  = (*taxis).vtime;
+      rdate = (*taxis).vdate;
+      rtime = (*taxis).vtime;
     }
 
   if ( rdate == 0 && rtime == 0 && vdate == 0 && vtime == 0 ) return value;
@@ -1392,6 +1405,7 @@ void ptaxisCopy(taxis_t *dest, taxis_t *source)
   dest->units = dup_refcount_string(source->units);
   if (dest->self != CDI_UNDEFID)
     reshSetStatus(dest->self, &taxisOps, RESH_DESYNC_IN_USE);
+
   reshUnlock ();
 }
 
diff --git a/libcdi/src/timebase.c b/libcdi/src/timebase.c
index 5371ea9..4dd410f 100644
--- a/libcdi/src/timebase.c
+++ b/libcdi/src/timebase.c
@@ -17,7 +17,7 @@ void decode_julday(int calendar,
   double b = floor((a - 1867216.25)/36524.25);
   double c = a + b - floor(b/4) + 1525;
 
-  if ( calendar == CALENDAR_STANDARD )
+  if ( calendar == CALENDAR_STANDARD || calendar == CALENDAR_GREGORIAN )
     if ( a < 2299161 ) c = a + 1524;
 
   double d = floor((c - 122.1)/365.25);
@@ -54,7 +54,7 @@ int encode_julday(int calendar, int year, int month, int day)
   else
     ib = (int)(iy/400) - (int)(iy/100);
 
-  if ( calendar == CALENDAR_STANDARD )
+  if ( calendar == CALENDAR_STANDARD || calendar == CALENDAR_GREGORIAN )
     {
       if ( year > 1582 || (year == 1582 && (month > 10 || (month == 10 && day >= 15))) )
 	{
diff --git a/libcdi/src/varscan.c b/libcdi/src/varscan.c
index 56d5e06..98328a3 100644
--- a/libcdi/src/varscan.c
+++ b/libcdi/src/varscan.c
@@ -446,10 +446,10 @@ void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
 
       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);
+      if ( name && name[0] )         vartable[varID].name     = strdup(name);
+      if ( stdname && stdname[0] )   vartable[varID].stdname  = strdup(stdname);
+      if ( longname && longname[0] ) vartable[varID].longname = strdup(longname);
+      if ( units && units[0] )       vartable[varID].units    = strdup(units);
     }
   else
     {
@@ -757,8 +757,9 @@ void cdi_generate_vars(stream_t *streamptr)
 
       /* generate new variable */
       int varID = stream_new_var(streamptr, gridID, zaxisID, tilesetID);
-      varID = vlistDefVarTiles(vlistID, gridID, zaxisID, tsteptype, tilesetID);
+      varID = vlistDefVarTiles(vlistID, gridID, zaxisID, TIME_VARYING, tilesetID);
 
+      vlistDefVarTsteptype(vlistID, varID, tsteptype);
       vlistDefVarParam(vlistID, varID, param);
       vlistDefVarDatatype(vlistID, varID, prec);
       vlistDefVarTimave(vlistID, varID, timave);
@@ -901,17 +902,17 @@ bool zaxisCompare(int zaxisID, int zaxistype, int nlevels, bool lbounds, const d
 
 	  if ( ! differ )
 	    {
-              if ( longname )
+              if ( longname && longname[0] )
                 {
-                  char zlongname[CDI_MAX_NAME];
+                  char zlongname[CDI_MAX_NAME]; zlongname[0] = 0;
                   zaxisInqLongname(zaxisID, zlongname);
-                  if ( zlongname[0] && strcmp(longname, zlongname) != 0 ) differ = true;
+                  if ( zlongname[0] && (strcmp(longname, zlongname) != 0) ) differ = true;
                 }
-              if ( units )
+              if ( units && units[0] )
                 {
-                  char zunits[CDI_MAX_NAME];
+                  char zunits[CDI_MAX_NAME]; zunits[0] = 0;
                   zaxisInqUnits(zaxisID, zunits);
-                  if ( zunits[0] && strcmp(units, zunits) != 0 ) differ = true;
+                  if ( zunits[0] && (strcmp(units, zunits) != 0) ) differ = true;
                 }
             }
 	}
@@ -949,7 +950,8 @@ varDefZAxisSearch(int id, void *res, void *data)
 }
 
 
-int varDefZaxis(int vlistID, int zaxistype, int nlevels, const double *levels, const char **cvals, size_t clength, bool lbounds,        const double *levels1, const double *levels2, int vctsize, const double *vct, char *name,
+int varDefZaxis(int vlistID, int zaxistype, int nlevels, const double *levels, const char **cvals, size_t clength, bool lbounds,
+                const double *levels1, const double *levels2, int vctsize, const double *vct, char *name,
 		const char *longname, const char *units, int prec, int mode, int ltype1)
 {
   /*
@@ -1018,8 +1020,10 @@ int varDefZaxis(int vlistID, int zaxistype, int nlevels, const double *levels, c
 
 	  if ( name && name[0] ) zaxisDefName(zaxisID, name);
 	  if ( longname && longname[0] ) zaxisDefLongname(zaxisID, longname);
+          else                           zaxisDefLongname(zaxisID, "");
 	  if ( units && units[0] ) zaxisDefUnits(zaxisID, units);
-	  zaxisDefPrec(zaxisID, prec);
+          else                     zaxisDefUnits(zaxisID, "");
+	  zaxisDefDatatype(zaxisID, prec);
 	  zaxisDefLtype(zaxisID, ltype1);
 	}
 
diff --git a/libcdi/src/vlist.c b/libcdi/src/vlist.c
index b1302d4..ab654e0 100644
--- a/libcdi/src/vlist.c
+++ b/libcdi/src/vlist.c
@@ -535,21 +535,17 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
 
   if ( vlistptr1->vars )
     {
-      int nvars = vlistptr1->nvars;
-      int nvars2 = 0;
-
       vlistptr2->ngrids = 0;
       vlistptr2->nzaxis = 0;
 
+      int nvars = vlistptr1->nvars;
+      int nvars2 = 0;
       for ( int varID = 0; varID < nvars; varID++ )
         nvars2 += vars1[varID].flag;
 
       vlistptr2->nvars = nvars2;
       vlistptr2->varsAllocated = nvars2;
-      if ( nvars2 > 0 )
-        vars2 = (var_t *) Malloc((size_t)nvars2*sizeof(var_t));
-      else
-        vars2 = NULL;
+      vars2 = (nvars2 > 0) ? (var_t *) Malloc((size_t)nvars2*sizeof(var_t)) : NULL;
 
       vlistptr2->vars = vars2;
 
@@ -686,6 +682,7 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
                 zaxisDefLongname(zaxisID2, ctemp);
                 zaxisInqUnits(zaxisID, ctemp);
                 zaxisDefUnits(zaxisID2, ctemp);
+                zaxisDefDatatype(zaxisID2, zaxisInqDatatype(zaxisID));
 
                 if ( zaxisType == ZAXIS_CHAR )
                   {
@@ -1499,12 +1496,15 @@ int vlistHasTime(int vlistID)
   bool hastime = false;
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
-  for ( int varID = 0; varID <  vlistptr->nvars; varID++ )
-    if ( vlistptr->vars[varID].tsteptype != TSTEP_CONSTANT )
-      {
-        hastime = true;
-        break;
-      }
+  if ( !(CDI_reduce_dim && vlistptr->ntsteps == 1) )
+    {
+      for ( int varID = 0; varID <  vlistptr->nvars; varID++ )
+        if ( vlistptr->vars[varID].timetype != TIME_CONSTANT )
+          {
+            hastime = true;
+            break;
+          }
+    }
 
   return (int)hastime;
 }
diff --git a/libcdi/src/vlist.h b/libcdi/src/vlist.h
index c2eea4c..b55e806 100644
--- a/libcdi/src/vlist.h
+++ b/libcdi/src/vlist.h
@@ -54,6 +54,7 @@ typedef struct
   int         param;
   int         gridID;
   int         zaxisID;
+  int         timetype;  /* TIME_* */
   int         tsteptype; /* TSTEP_* */
   int         datatype;  /* CDI_DATATYPE_PACKX for GRIB data, else CDI_DATATYPE_FLT32 or CDI_DATATYPE_FLT64 */
   int         instID;
@@ -127,7 +128,6 @@ void     vlistDestroyVarLongname(int vlistID, int varID);
 void     vlistDestroyVarStdname(int vlistID, int varID);
 void     vlistDestroyVarUnits(int vlistID, int varID);
 void     cdiVlistDestroy_(int vlistID);
-void     vlistDefVarTsteptype(int vlistID, int varID, int tsteptype);
 int      vlistInqVarMissvalUsed(int vlistID, int varID);
 int      vlistHasTime(int vlistID);
 
diff --git a/libcdi/src/vlist_var.c b/libcdi/src/vlist_var.c
index eb753ac..9990cf7 100644
--- a/libcdi/src/vlist_var.c
+++ b/libcdi/src/vlist_var.c
@@ -32,6 +32,7 @@ void vlistvarInitEntry(int vlistID, int varID)
   vlistptr->vars[varID].flag          = 0;
   vlistptr->vars[varID].param         = 0;
   vlistptr->vars[varID].datatype      = CDI_UNDEFID;
+  vlistptr->vars[varID].timetype      = CDI_UNDEFID;
   vlistptr->vars[varID].tsteptype     = TSTEP_INSTANT;
   vlistptr->vars[varID].timave        = 0;
   vlistptr->vars[varID].timaccu       = 0;
@@ -128,10 +129,10 @@ void vlistCheckVarID(const char *caller, int vlistID, int varID)
 }
 
 
-int vlistDefVarTiles(int vlistID, int gridID, int zaxisID, int tsteptype, int tilesetID)
+int vlistDefVarTiles(int vlistID, int gridID, int zaxisID, int timetype, int tilesetID)
 {
   if ( CDI_Debug )
-    Message("gridID = %d  zaxisID = %d  tsteptype = %d", gridID, zaxisID, tsteptype);
+    Message("gridID = %d  zaxisID = %d  timetype = %d", gridID, zaxisID, timetype);
 
   int varID = vlistvarNewEntry(vlistID);
 
@@ -139,13 +140,13 @@ int vlistDefVarTiles(int vlistID, int gridID, int zaxisID, int tsteptype, int ti
   vlistptr->nvars++;
   vlistptr->vars[varID].gridID    = gridID;
   vlistptr->vars[varID].zaxisID   = zaxisID;
-  vlistptr->vars[varID].tsteptype = tsteptype;
+  vlistptr->vars[varID].timetype = timetype;
   vlistptr->vars[varID].subtypeID = tilesetID;
 
-  if ( tsteptype < 0 )
+  if ( timetype < 0 )
     {
-      Message("Unexpected tstep type %d, set to TSTEP_INSTANT!", tsteptype);
-      vlistptr->vars[varID].tsteptype = TSTEP_INSTANT;
+      Message("Unexpected time type %d, set to TIME_VARYING!", timetype);
+      vlistptr->vars[varID].timetype = TIME_VARYING;
     }
 
   vlistAdd2GridIDs(vlistptr, gridID);
@@ -162,14 +163,13 @@ int vlistDefVarTiles(int vlistID, int gridID, int zaxisID, int tsteptype, int ti
 @Function  vlistDefVar
 @Title     Define a Variable
 
- at Prototype int vlistDefVar(int vlistID, int gridID, int zaxisID, int tsteptype)
+ at Prototype int vlistDefVar(int vlistID, int gridID, int zaxisID, int timetype)
 @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}, @func{TSTEP_INSTANT},
-                     @func{TSTEP_ACCUM}, @func{TSTEP_AVG}, @func{TSTEP_MAX}, @func{TSTEP_MIN} and @func{TSTEP_SD}.
+    @Item  timetype  One of the set of predefined CDI timestep types.
+                     The valid CDI timestep types are @func{TIME_CONSTANT} and @func{TIME_VARYING}.
 
 @Description
 The function @func{vlistDefVar} adds a new variable to vlistID.
@@ -187,7 +187,7 @@ and add a variable with @func{vlistDefVar}.
 int vlistID, varID;
    ...
 vlistID = vlistCreate();
-varID = vlistDefVar(vlistID, gridID, zaxisID, TIME_INSTANT);
+varID = vlistDefVar(vlistID, gridID, zaxisID, TIME_VARYING);
    ...
 streamDefVlist(streamID, vlistID);
    ...
@@ -196,10 +196,10 @@ vlistDestroy(vlistID);
 @EndSource
 @EndFunction
 */
-int vlistDefVar(int vlistID, int gridID, int zaxisID, int tsteptype)
+int vlistDefVar(int vlistID, int gridID, int zaxisID, int timetype)
 {
   /* call "vlistDefVarTiles" with a trivial tile index: */
-  return vlistDefVarTiles(vlistID, gridID, zaxisID, tsteptype, CDI_UNDEFID);
+  return vlistDefVarTiles(vlistID, gridID, zaxisID, timetype, CDI_UNDEFID);
 }
 
 void
@@ -278,15 +278,15 @@ void vlistDefVarCode(int vlistID, int varID, int code)
 }
 
 
-void vlistInqVar(int vlistID, int varID, int *gridID, int *zaxisID, int *tsteptype)
+void vlistInqVar(int vlistID, int varID, int *gridID, int *zaxisID, int *timetype)
 {
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
 
   vlistCheckVarID(__func__, vlistID, varID);
 
-  *gridID    = vlistptr->vars[varID].gridID;
-  *zaxisID   = vlistptr->vars[varID].zaxisID;
-  *tsteptype = vlistptr->vars[varID].tsteptype;
+  *gridID   = vlistptr->vars[varID].gridID;
+  *zaxisID  = vlistptr->vars[varID].zaxisID;
+  *timetype = vlistptr->vars[varID].timetype;
 
   return;
 }
@@ -698,8 +698,8 @@ int vlistInqVarSize(int vlistID, int varID)
 {
   vlistCheckVarID(__func__, vlistID, varID);
 
-  int zaxisID, gridID, tsteptype;
-  vlistInqVar(vlistID, varID, &gridID, &zaxisID, &tsteptype);
+  int zaxisID, gridID, timetype;
+  vlistInqVar(vlistID, varID, &gridID, &zaxisID, &timetype);
 
   int nlevs = zaxisInqSize(zaxisID);
 
@@ -1192,6 +1192,24 @@ void vlistDefVarAddoffset(int vlistID, int varID, double addoffset)
 }
 
 
+void vlistDefVarTimetype(int vlistID, int varID, int timetype)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  if (vlistptr->vars[varID].timetype != timetype)
+    {
+      vlistptr->vars[varID].timetype = timetype;
+      reshSetStatus(vlistID, &vlistOps, RESH_DESYNC_IN_USE);
+    }
+}
+
+
+int vlistInqVarTimetype(int vlistID, int varID)
+{
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
+  return vlistptr->vars[varID].timetype;
+}
+
+
 void vlistDefVarTsteptype(int vlistID, int varID, int tsteptype)
 {
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
@@ -1217,7 +1235,7 @@ The function @func{vlistInqVarTsteptype} returns the timestep type of a Variable
 @Result
 @func{vlistInqVarTsteptype} returns the timestep type of the Variable,
 one of the set of predefined CDI timestep types.
-The valid CDI timestep types are @func{TSTEP_CONSTANT}, @func{TSTEP_INSTANT},
+The valid CDI timestep types are @func{TSTEP_INSTANT},
 @func{TSTEP_ACCUM}, @func{TSTEP_AVG}, @func{TSTEP_MAX}, @func{TSTEP_MIN} and @func{TSTEP_SD}.
 
 @EndFunction
@@ -2006,7 +2024,7 @@ int vlistVarCompare(vlist_t *a, int varIDA, vlist_t *b, int varIDB)
 #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(datatype) | FCMP(timetype) | 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)
@@ -2079,7 +2097,7 @@ void vlistVarPack(vlist_t *p, int varID, char * buf, int size, int *position,
   tempbuf[0] = var->flag;
   tempbuf[1] = var->gridID;
   tempbuf[2] = var->zaxisID;
-  tempbuf[3] = var->tsteptype;
+  tempbuf[3] = var->timetype;
   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;
diff --git a/libcdi/src/zaxis.c b/libcdi/src/zaxis.c
index 9d28e0c..108714f 100644
--- a/libcdi/src/zaxis.c
+++ b/libcdi/src/zaxis.c
@@ -102,7 +102,7 @@ void zaxisGetTypeDescription(int zaxisType, int *outPositive, const char **outNa
     {
       if (outPositive) *outPositive = ZaxistypeEntry[zaxisType].positive;
       if (outName) *outName = ZaxistypeEntry[zaxisType].name;
-      if (outLongName) *outLongName = ZaxistypeEntry[zaxisType].longname;
+      if (outLongName && zaxisType != ZAXIS_GENERIC) *outLongName = ZaxistypeEntry[zaxisType].longname;
       if (outStdName) *outStdName = ZaxistypeEntry[zaxisType].stdname;
       if (outUnit) *outUnit = ZaxistypeEntry[zaxisType].units;
     }
@@ -139,7 +139,7 @@ void zaxis_init(zaxis_t *zaxisptr)
   zaxisptr->positive      = 0;
   zaxisptr->scalar        = 0;
   zaxisptr->direction     = 0;
-  zaxisptr->prec          = 0;
+  zaxisptr->datatype      = 0;
   zaxisptr->size          = 0;
   zaxisptr->vctsize       = 0;
   zaxisptr->vct           = NULL;
@@ -206,7 +206,7 @@ int zaxisCreate_(int zaxistype, int size, int id)
 
   int zaxisID = zaxisptr->self;
   zaxisDefName(zaxisID, ZaxistypeEntry[zaxistype].name);
-  zaxisDefLongname(zaxisID, ZaxistypeEntry[zaxistype].longname);
+  if ( zaxistype != ZAXIS_GENERIC ) zaxisDefLongname(zaxisID, ZaxistypeEntry[zaxistype].longname);
   zaxisDefUnits(zaxisID, ZaxistypeEntry[zaxistype].units);
 
   if ( *ZaxistypeEntry[zaxistype].stdname )
@@ -387,7 +387,7 @@ The function @func{cdiZaxisDefKeyStr} defines a CDI Z-axis string value from a k
 */
 int cdiZaxisDefKeyStr(int zaxisID, int key, int size, const char *mesg)
 {
-  if ( size < 1 || mesg == NULL || *mesg == 0 ) return -1;
+  if ( size < 1 || mesg == NULL ) return -1;
 
   zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
 
@@ -659,22 +659,22 @@ void zaxisInqStdname(int zaxisID, char *stdname)
 }
 
 
-void zaxisDefPrec(int zaxisID, int prec)
+void zaxisDefDatatype(int zaxisID, int datatype)
 {
   zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
 
-  if ( zaxisptr->prec != prec )
+  if ( zaxisptr->datatype != datatype )
     {
-      zaxisptr->prec = prec;
+      zaxisptr->datatype = datatype;
       reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
     }
 }
 
 
-int zaxisInqPrec(int zaxisID)
+int zaxisInqDatatype(int zaxisID)
 {
   zaxis_t *zaxisptr = zaxis_to_pointer(zaxisID);
-  return zaxisptr->prec;
+  return zaxisptr->datatype;
 }
 
 
@@ -1406,9 +1406,9 @@ void zaxisPrintKernel(zaxis_t *zaxisptr, FILE *fp)
   int zaxisID = zaxisptr->self;
   int type    = zaxisptr->type;
   int nlevels = zaxisptr->size;
-  int prec    = zaxisptr->prec;
+  int datatype = zaxisptr->datatype;
 
-  int dig = (prec == CDI_DATATYPE_FLT64) ? 15 : 7;
+  int dig = (datatype == CDI_DATATYPE_FLT64) ? 15 : 7;
 
   int nbyte;
   int nbyte0 = 0;
@@ -1442,7 +1442,7 @@ void zaxisPrintKernel(zaxis_t *zaxisptr, FILE *fp)
 
   if ( zaxisptr->cvals )
     {
-      dig = prec;
+      dig = datatype;
       nbyte0 = fprintf(fp, "types     = ");
       nbyte = nbyte0;
       for ( int levelID = 0; levelID < nlevels; levelID++ )
@@ -1565,7 +1565,7 @@ int zaxisCompareP(zaxis_t *z1, zaxis_t *z2)
   diff |= (z1->type != z2->type)
     | (z1->ltype != z2->ltype)
     | (z1->direction != z2->direction)
-    | (z1->prec != z2->prec)
+    | (z1->datatype != z2->datatype)
     | (z1->size != z2->size)
     | (z1->vctsize != z2->vctsize)
     | (z1->positive != z2->positive);
@@ -1739,7 +1739,7 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
     = zaxisNewEntry(force_id ? namespaceAdaptKey(intBuffer[0], originNamespace)
                     : CDI_UNDEFID);
 
-  zaxisP->prec      = intBuffer[1];
+  zaxisP->datatype  = intBuffer[1];
   zaxisP->type      = intBuffer[2];
   zaxisP->ltype     = intBuffer[3];
   zaxisP->size      = intBuffer[4];
@@ -1840,7 +1840,7 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
   uint32_t d;
 
   intBuffer[0]  = zaxisP->self;
-  intBuffer[1]  = zaxisP->prec;
+  intBuffer[1]  = zaxisP->datatype;
   intBuffer[2]  = zaxisP->type;
   intBuffer[3]  = zaxisP->ltype;
   intBuffer[4]  = zaxisP->size;
diff --git a/libcdi/src/zaxis.h b/libcdi/src/zaxis.h
index 60ccad5..aa57a9d 100644
--- a/libcdi/src/zaxis.h
+++ b/libcdi/src/zaxis.h
@@ -26,7 +26,7 @@ typedef struct {
   double  *ubounds;
   double  *weights;
   int      self;
-  int      prec;
+  int      datatype;
   int      scalar;
   int      type;
   int      ltype;    /* GRIB level type */
diff --git a/libcdi/tests/test_cdf_const.in b/libcdi/tests/test_cdf_const.in
index 52cffa3..9b9546d 100644
--- a/libcdi/tests/test_cdf_const.in
+++ b/libcdi/tests/test_cdf_const.in
@@ -39,9 +39,9 @@ fi
 
 #PATTERNS
 #^   File format : NetCDF
-#^   Var : Institut Source   Ttype    Levels Num  Gridsize Num Dtype : Parameter ID
-#^     1 : unknown  unknown  constant      1   1        72   1  F32  : -1         
-#^     2 : unknown  unknown  constant      5   2        72   1  F32  : -2         
+#^   Var : Institut Source   T Steptype Levels Num    Points Num Dtype : Parameter ID
+#^     1 : unknown  unknown  c instant       1   1        72   1  F32  : -1         
+#^     2 : unknown  unknown  c instant       5   2        72   1  F32  : -2         
 #^   Grid coordinates :
 #^     1 : lonlat                   : points=72 (12x6)
 #^                              lon : 0 to 330 by 30 degrees_east  circular
diff --git a/libcdi/tests/test_cdf_write.c b/libcdi/tests/test_cdf_write.c
index 300621a..bc10a0a 100644
--- a/libcdi/tests/test_cdf_write.c
+++ b/libcdi/tests/test_cdf_write.c
@@ -78,7 +78,7 @@ int main(int argc, const char **argv)
   int zaxisID = zaxisCreate(ZAXIS_SURFACE, 1);
 
   int vlistID = vlistCreate();
-  int varID = vlistDefVar(vlistID, gridID, zaxisID, TSTEP_INSTANT);
+  int varID = vlistDefVar(vlistID, gridID, zaxisID, TIME_VARYING);
   vlistDefVarMissval(vlistID, varID, missValue);
   {
     static const char creatorText[] = "CDI test_cdf_write";
diff --git a/libcdi/tests/test_resource_copy.c b/libcdi/tests/test_resource_copy.c
index 17f4c1e..f87eba7 100644
--- a/libcdi/tests/test_resource_copy.c
+++ b/libcdi/tests/test_resource_copy.c
@@ -22,7 +22,7 @@ typedef int MPI_Comm;
 #endif
 
 enum {
-  DOUBLE_PRECISION = 8,
+  DOUBLE_PRECISION = CDI_DATATYPE_FLT64,
   nlon             = 12,
   nlat             = 6,
   nlev             = 5,
@@ -61,7 +61,7 @@ static int defineGrid (void)
   gridDefYname ( gridID, "myYname" );
   gridDefYlongname ( gridID, "myYlongname" );
   gridDefYunits ( gridID, "myYunits" );
-  gridDefPrec ( gridID, DOUBLE_PRECISION );
+  gridDefDatatype ( gridID, DOUBLE_PRECISION );
   gridDefTrunc ( gridID, 1 );
   gridDefParamGME ( gridID, 2, 3, 4, 5 );
   gridDefNumber ( gridID, 6 );
@@ -94,7 +94,7 @@ static int defineZaxis (void)
   zaxisDefName ( zaxisID, "myName" );
   zaxisDefLongname ( zaxisID, "myLongname" );
   zaxisDefUnits ( zaxisID, "myUnits" );
-  zaxisDefPrec ( zaxisID, DOUBLE_PRECISION );
+  zaxisDefDatatype ( zaxisID, DOUBLE_PRECISION );
   zaxisDefLtype ( zaxisID, 1 );
   zaxisDefVct ( zaxisID, 3, vct );
   zaxisDefLbounds ( zaxisID, &levs[0] );
diff --git a/src/Adisit.cc b/src/Adisit.cc
index 3618847..aa4d6c8 100644
--- a/src/Adisit.cc
+++ b/src/Adisit.cc
@@ -261,7 +261,7 @@ void *Adisit(void *argument)
 
   int vlistID2 = vlistCreate();
 
-  int tisID2 = vlistDefVar(vlistID2, gridID, zaxisID, TSTEP_INSTANT);
+  int tisID2 = vlistDefVar(vlistID2, gridID, zaxisID, TIME_VARYING);
   if ( operatorID == ADISIT )
     {
       vlistDefVarParam(vlistID2, tisID2, cdiEncodeParam(20, 255, 255));
@@ -280,7 +280,7 @@ void *Adisit(void *argument)
   vlistDefVarMissval(vlistID2, tisID2, tis.missval);
   vlistDefVarDatatype(vlistID2, tisID2, datatype);
 
-  int saoID2 = vlistDefVar(vlistID2, gridID, zaxisID, TSTEP_INSTANT);
+  int saoID2 = vlistDefVar(vlistID2, gridID, zaxisID, TIME_VARYING);
   vlistDefVarParam(vlistID2, saoID2, cdiEncodeParam(5, 255, 255));
   vlistDefVarName(vlistID2, saoID2, "s");
   vlistDefVarLongname(vlistID2, saoID2, "Sea water salinity");
diff --git a/src/Afterburner.cc b/src/Afterburner.cc
index 9921f26..3feb434 100644
--- a/src/Afterburner.cc
+++ b/src/Afterburner.cc
@@ -19,6 +19,7 @@
 #if defined(CDO)
 #include "cdo.h"
 #include "cdo_int.h"
+#include "cdo_task.h"
 #include "pstream_write.h"
 #define  streamOpenWrite          pstreamOpenWrite
 #define  streamDefVlist           pstreamDefVlist
@@ -34,10 +35,6 @@
 #include "compare.h"
 #include "vct_l191.h"
 
-#if  defined  (HAVE_LIBPTHREAD)
-#include <pthread.h>
-#endif
-
 #if defined (_OPENMP)
 #include <omp.h>
 #endif
@@ -105,11 +102,7 @@ static int oVertID = -1;
 static int Lhybrid2pressure = FALSE;
 
 static int TsID;
-#if  defined  (HAVE_LIBPTHREAD)
-static bool ParallelRead = true;
-#else
-static bool ParallelRead = false;
-#endif
+static bool lparallelread = true;
 
 #define TIMESTEP_INTERVAL  -1
 #define MONTHLY_INTERVAL    0
@@ -143,13 +136,11 @@ void cdiError(int cdiErrno, const char *fmt, ...)
 static
 void lprintf(FILE *fp)
 {
-  int inum;
   int num = 67;
   int cval = '-';
 
   fprintf(fp, " ");
-  for (inum = 0; inum < num; inum++)
-    fprintf(fp, "%c", cval);
+  for ( int inum = 0; inum < num; inum++ ) fprintf(fp, "%c", cval);
   fprintf(fp, "\n");
 }
 
@@ -198,7 +189,7 @@ static
 void after_SwitchFile(struct Control *globs)
 {
   bool echam4 = false;
-  int i, n;
+  int n;
   char y3, y2, y1, y0;
   char         m1, m0;
   char         d1, d0;
@@ -207,7 +198,7 @@ void after_SwitchFile(struct Control *globs)
 
   if ( globs->Multi > 0 )
     {
-      i = strlen(ifile);
+      int i = strlen(ifile);
       if ( i < 10 )
 	{
 	  fprintf(stderr, " Not a valid filename: %s \n", ifile);
@@ -349,9 +340,7 @@ void after_printProcessStatus(int tsID)
 static
 int after_setNextDate(struct Control *globs)
 {
-  int nrecs;
-  int i;
-  int vdate, vtime;
+  int nrecs = 0;
 
   bool righttime = false;
   while ( TRUE )
@@ -374,12 +363,11 @@ int after_setNextDate(struct Control *globs)
 #if defined(CDO)
       //      processDefTimesteps(globs->istreamID);
 #endif
-      vdate = taxisInqVdate(globs->taxisID);
-      vtime = taxisInqVtime(globs->taxisID);
-
+      int vdate = taxisInqVdate(globs->taxisID);
+      int vtime = taxisInqVtime(globs->taxisID);
       after_setDateTime(&globs->NextDate, vdate, vtime);
 
-      for ( i = 0; i < nrqh; i++ )
+      for ( int i = 0; i < nrqh; i++ )
 	if ( hours[i] < 0 || hours[i] == globs->NextDate.hr )
 	  {
 	    righttime = true;
@@ -398,12 +386,11 @@ int after_setNextDate(struct Control *globs)
 
 static int num_recs = 0;
 
+
 static
 void *after_readTimestep(void *arg)
 {
-  int i;
   int varID, gridID, zaxisID, levelID, timeID;
-  int code, leveltype;
   int nmiss;
   RARG *rarg = (RARG *) arg;
 
@@ -412,16 +399,13 @@ void *after_readTimestep(void *arg)
   struct Variable *vars = rarg->vars;
   struct Control *globs = rarg->globs;
 
-  for ( code = 0; code < MaxCodes; code++ ) vars[code].nmiss0 = 0;
-
-  int level = 0;
-  int levelOffset = 0;
+  for ( int code = 0; code < MaxCodes; code++ ) vars[code].nmiss0 = 0;
 
   for ( int recID = 0; recID < nrecs; recID++ )
     {
       streamInqRecord(globs->istreamID, &varID, &levelID);
 
-      code = vlistInqVarCode(globs->ivlistID, varID);
+      int code = vlistInqVarCode(globs->ivlistID, varID);
       if ( code <= 0 || code >= MaxCodes ) continue;
 
       /* Skip records containing unneeded codes */
@@ -430,18 +414,18 @@ void *after_readTimestep(void *arg)
 
       vlistInqVar(globs->ivlistID, varID, &gridID, &zaxisID, &timeID);
 
-      leveltype = zaxisInqType(zaxisID);
+      int leveltype = zaxisInqType(zaxisID);
 	  
       /* Skip records with unselected levels */
 
-      levelOffset = -1;
+      int 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 )
+	  int level = (int) zaxisInqLevel(zaxisID, levelID);
+	  for ( int i = 0; i < globs->NumLevelRequest; ++i )
 	    {
 	      if ( IS_EQUAL(globs->LevelRequest[i], level) )
 		{
@@ -465,12 +449,17 @@ void *after_readTimestep(void *arg)
 		  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);
+        {
+          streamReadRecord(globs->istreamID, globs->Field, &nmiss);
+          after_AnalysisAddRecord(globs, vars, code, gridID, zaxisID, levelID, nmiss);
+        }
       else
-	after_EchamAddRecord(globs, vars, code, gridID, zaxisID, levelID, nmiss);
+        {
+          double *dataptr = after_get_dataptr(vars, code, gridID, zaxisID, levelID);
+          streamReadRecord(globs->istreamID, dataptr, &nmiss);
+          after_EchamAddRecord(globs, vars, code, gridID, zaxisID, levelID, nmiss);
+        }
 
       if ( iVertID != -1 && oVertID != -1 && (vars[code].izaxisID == iVertID) )
 	vars[code].ozaxisID = oVertID;
@@ -646,25 +635,17 @@ void after_control(struct Control *globs, struct Variable *vars)
   int code;
   RARG rarg;
   void *statusp = NULL;
-#if  defined  (HAVE_LIBPTHREAD)
-  pthread_t thrID;
-  pthread_attr_t attr;
-  int rval;
+  void *read_task = NULL;
 
-  if ( ParallelRead )
+  if ( lparallelread )
     {
-      size_t stacksize;
-
-      pthread_attr_init(&attr);
-      pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-      int status = pthread_attr_getstacksize(&attr, &stacksize);
-      if ( status && stacksize < 2097152 )
-	{
-	  stacksize = 2097152;
-	  pthread_attr_setstacksize(&attr, stacksize);
-	}
+      read_task = cdo_task_new();
+      if ( read_task == NULL )
+        {
+          lparallelread = false;
+          cdoWarning("CDO tasks not available!");
+        }
     }
-#endif
 
   for ( code = 0; code < MaxCodes; code++ )
     vars[code].needed0 = vars[code].needed;
@@ -703,7 +684,8 @@ void after_control(struct Control *globs, struct Variable *vars)
       rtime = after_getTime(globs->StartDate);
     }
 
-  if ( ofiletype == CDI_FILETYPE_NC || ofiletype == CDI_FILETYPE_NC2 || ofiletype == CDI_FILETYPE_NC4 )
+  if ( ofiletype == CDI_FILETYPE_NC || ofiletype == CDI_FILETYPE_NC2 || ofiletype == CDI_FILETYPE_NC4 ||
+       ofiletype == CDI_FILETYPE_NC4C || ofiletype == CDI_FILETYPE_NC5 )
     {
       taxisDefCalendar(globs->taxisID2, CALENDAR_PROLEPTIC);
       taxisDefType(globs->taxisID2, TAXIS_RELATIVE);
@@ -723,43 +705,34 @@ void after_control(struct Control *globs, struct Variable *vars)
       rarg.vars  = vars;
       rarg.globs = globs;
 
-      if ( tsFirst || ParallelRead == false )
+      if ( tsFirst || lparallelread == false )
 	{
-	  if ( ParallelRead == false )
+	  if ( lparallelread == 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!");
+              cdo_task_start(read_task, after_readTimestep, &rarg);
 	    }
-#endif
 
-	  if ( tsFirst )
-	    {
-	      if ( globs->Type >  0 ) after_legini_setup(globs, vars);
-	    }
+	  if ( tsFirst && globs->Type >  0 ) after_legini_setup(globs, vars);
 
-#if defined(HAVE_LIBPTHREAD)
-	  if ( ParallelRead )
+	  if ( lparallelread )
 	    {
-	      pthread_join(thrID, &statusp);
+              statusp = cdo_task_wait(read_task);
 	      if ( *(int *)statusp < 0 )
 		Error("after_readTimestep error! (status = %d)", *(int *)statusp);
 	    }
-#endif
 	  tsFirst = false;
 	}
-#if defined(HAVE_LIBPTHREAD)
       else
 	{
-	  pthread_join(thrID, &statusp);
+          statusp = cdo_task_wait(read_task);
 	  if ( *(int *)statusp < 0 )
 	    Error("after_readTimestep error! (status = %d)", *(int *)statusp);
 	}
-#endif
+
       nrecs = *(int *)statusp;
 
       globs->MeanCount0 = globs->MeanCount;
@@ -767,13 +740,10 @@ void after_control(struct Control *globs, struct Variable *vars)
 
       after_moveTimestep(vars);
 
-#if  defined  (HAVE_LIBPTHREAD)
-      if ( nrecs && ParallelRead )
+      if ( nrecs && lparallelread )
 	{
-	  rval = pthread_create(&thrID, &attr, after_readTimestep, &rarg);
-	  if ( rval != 0 ) Error("pthread_create failed!");
+          cdo_task_start(read_task, after_readTimestep, &rarg);
 	}
-#endif
 
       after_setEndOfInterval(globs, nrecs);
       
@@ -805,12 +775,7 @@ void after_control(struct Control *globs, struct Variable *vars)
       globs->OldDate = globs->NewDate;
     }
 
-#if  defined  (HAVE_LIBPTHREAD)
-  if ( ParallelRead )
-    {
-      pthread_attr_destroy(&attr);
-    }
-#endif
+  if ( read_task ) cdo_task_delete(read_task);
 }
 
 static
@@ -1368,6 +1333,7 @@ void after_parini(struct Control *globs, struct Variable *vars)
     case  2: ofiletype = CDI_FILETYPE_NC;   break;
     case  3: ofiletype = CDI_FILETYPE_EXT;  break;
     case  4: ofiletype = CDI_FILETYPE_NC2;  break;
+    case  5: ofiletype = CDI_FILETYPE_NC5;  break;
     case  6: ofiletype = CDI_FILETYPE_NC4;  break;
     default: Error( "unknown file format %d", fileFormat);
     }
@@ -1803,12 +1769,11 @@ void after_postcntl(struct Control *globs, struct Variable *vars)
 	    vlistInqVarUnits(globs->ivlistID, ivarID, units);
 	  }
 
-        int tsteptype = (globs->Mean) ? TSTEP_AVG : TSTEP_INSTANT;
-
         if ( globs->Mean != 2 )
 	  {
 	    vlistDefTaxis(globs->ovlistID, globs->taxisID2);
-	    ovarID = vlistDefVar(globs->ovlistID, ogridID, ozaxisID, tsteptype);
+	    ovarID = vlistDefVar(globs->ovlistID, ogridID, ozaxisID, TIME_VARYING);
+            if ( globs->Mean ) vlistDefVarTsteptype(globs->ovlistID, ovarID, TSTEP_AVG);
 	    vlistDefVarCode(globs->ovlistID, ovarID, code);
 	    vars[code].ovarID = ovarID;
 	    vlistDefVarInstitut(globs->ovlistID, ovarID, instID);
@@ -1824,7 +1789,8 @@ void after_postcntl(struct Control *globs, struct Variable *vars)
 	if ( globs->Mean >= 2 )
 	  {
 	    vlistDefTaxis(globs->ovlistID2, globs->taxisID2);
-	    ovarID2 = vlistDefVar(globs->ovlistID2, ogridID, ozaxisID, tsteptype);
+	    ovarID2 = vlistDefVar(globs->ovlistID2, ogridID, ozaxisID, TIME_VARYING);
+            if ( globs->Mean ) vlistDefVarTsteptype(globs->ovlistID2, ovarID2, TSTEP_AVG);
 	    vlistDefVarCode(globs->ovlistID2, ovarID2, code);
 	    vars[code].ovarID2 = ovarID2;
 	    vlistDefVarInstitut(globs->ovlistID2, ovarID2, instID);
@@ -2165,7 +2131,7 @@ void after_processing(struct Control *globs, struct Variable *vars)
       if ( ofiletype == CDI_FILETYPE_GRB )
 	Error("Can't write fourier coefficients to GRIB!");
       else if ( ofiletype == CDI_FILETYPE_NC || ofiletype == CDI_FILETYPE_NC2 ||
-		ofiletype == CDI_FILETYPE_NC4 )
+		ofiletype == CDI_FILETYPE_NC4 || ofiletype == CDI_FILETYPE_NC4C || ofiletype == CDI_FILETYPE_NC5 )
 	Error("Can't write fourier coefficients to NetCDF!");
     }
 
@@ -2330,7 +2296,7 @@ int afterburner(int argc, char *argv[])
       case 'b': Message( "option -b not longer needed!"); break;
       case 'c': after_printCodes(); break;
       case 'd': globs->Debug = 1; break;
-      case 'p': ParallelRead = true; break;
+      case 'p': lparallelread = true; break;
       case 'P': numThreads = atoi(optarg); break;
       case 'V': after_version(); break;
       case 'v': Vctfile = optarg; break;
@@ -2339,8 +2305,6 @@ int afterburner(int argc, char *argv[])
       }
 
 #if defined (_OPENMP)
-  /* ParallelRead = true; */
-
   lprintf(stdout);
   if ( numThreads <= 0 ) numThreads = 1;
   omp_set_num_threads(numThreads);
@@ -2355,15 +2319,7 @@ int afterburner(int argc, char *argv[])
     }
 #endif
 
-  if ( ParallelRead )
-    {
-#if  defined  (HAVE_LIBPTHREAD)
-      fprintf(stdout, " Parallel read enabled\n");
-#else
-      fprintf(stdout, " Parallel read disabled\n");
-      ParallelRead = false;
-#endif
-    }
+  if ( lparallelread ) fprintf(stdout, " Parallel read enabled\n");
 
   fargc0 = optind;
   fargcn = argc;
@@ -2451,6 +2407,8 @@ void *Afterburner(void *argument)
 {
   cdoInitialize(argument);
 
+  CDO_task = true;
+
   lstdout = !cdoSilentMode;
 
   struct Control *globs = (struct Control *) Malloc(sizeof(struct Control));
diff --git a/src/Arith.cc b/src/Arith.cc
index c9ba2e4..7e26534 100644
--- a/src/Arith.cc
+++ b/src/Arith.cc
@@ -50,13 +50,14 @@ void *Arith(void *argument)
   cdoInitialize(argument);
 
   // clang-format off
-  cdoOperatorAdd("add",   func_add,   0, NULL);
-  cdoOperatorAdd("sub",   func_sub,   0, NULL);
-  cdoOperatorAdd("mul",   func_mul,   0, NULL);
-  cdoOperatorAdd("div",   func_div,   0, NULL);
-  cdoOperatorAdd("min",   func_min,   0, NULL);
-  cdoOperatorAdd("max",   func_max,   0, NULL);
-  cdoOperatorAdd("atan2", func_atan2, 0, NULL);
+  cdoOperatorAdd("add",     func_add,     0, NULL);
+  cdoOperatorAdd("sub",     func_sub,     0, NULL);
+  cdoOperatorAdd("mul",     func_mul,     0, NULL);
+  cdoOperatorAdd("div",     func_div,     0, NULL);
+  cdoOperatorAdd("min",     func_min,     0, NULL);
+  cdoOperatorAdd("max",     func_max,     0, NULL);
+  cdoOperatorAdd("atan2",   func_atan2,   0, NULL);
+  cdoOperatorAdd("setmiss", func_setmiss, 0, NULL);
   // clang-format on
 
   int operatorID = cdoOperatorID();
diff --git a/src/CDIread.cc b/src/CDIread.cc
index 7b6a8ab..fabeed1 100644
--- a/src/CDIread.cc
+++ b/src/CDIread.cc
@@ -33,6 +33,7 @@ const char *filetypestr(int filetype)
     case CDI_FILETYPE_NC2:  return ("NetCDF2");
     case CDI_FILETYPE_NC4:  return ("NetCDF4");
     case CDI_FILETYPE_NC4C: return ("NetCDF4 classic");
+    case CDI_FILETYPE_NC5:  return ("NetCDF5");
     case CDI_FILETYPE_SRV:  return ("SERVICE");
     case CDI_FILETYPE_EXT:  return ("EXTRA");
     case CDI_FILETYPE_IEG:  return ("IEG");
diff --git a/src/CDIwrite.cc b/src/CDIwrite.cc
index cb41a73..7ff22ea 100644
--- a/src/CDIwrite.cc
+++ b/src/CDIwrite.cc
@@ -34,6 +34,7 @@ const char *filetypestr(int filetype)
     case CDI_FILETYPE_NC2:  return ("NetCDF2");         break;
     case CDI_FILETYPE_NC4:  return ("NetCDF4");         break;
     case CDI_FILETYPE_NC4C: return ("NetCDF4 classic"); break;
+    case CDI_FILETYPE_NC5:  return ("NetCDF5");         break;
     case CDI_FILETYPE_SRV:  return ("SERVICE");         break;
     case CDI_FILETYPE_EXT:  return ("EXTRA");           break;
     case CDI_FILETYPE_IEG:  return ("IEG");             break;
@@ -198,7 +199,7 @@ void *CDIwrite(void *argument)
 
   for ( i = 0; i < nvars; ++i )
     {
-      varID = vlistDefVar(vlistID, gridID, zaxisID, TSTEP_INSTANT);
+      varID = vlistDefVar(vlistID, gridID, zaxisID, TIME_VARYING);
       vlistDefVarParam(vlistID, varID, cdiEncodeParam(varID+1, 255, 255));
       //    vlistDefVarName(vlistID, varID, );
     }
diff --git a/src/CMOR.cc b/src/CMOR.cc
index defc06e..68da1e4 100644
--- a/src/CMOR.cc
+++ b/src/CMOR.cc
@@ -1,4 +1,5 @@
 #include <cdi.h>
+#include <signal.h>
 #include "cdo.h"
 #include "cdo_int.h"
 #include "pstream.h"
@@ -7,7 +8,15 @@
 #include <unistd.h>
 #include "uthash.h"
 #include "util.h"
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
 #include "cmor.h"
+#ifdef __cplusplus
+  }
+#endif
+
 #include "netcdf.h"
 #include "pmlist.h"
 
@@ -18,8 +27,18 @@
 /* */
 int stringToParam(const char *paramstr);
 
+static char *kv_get_a_val(list_t *kvl, const char *key, const char *replacer)
+{
+  keyValues_t *kv = kvlist_search(kvl, key);
+  if ( kv )
+    return kv->values[0];
+  if ( replacer )
+    return (char *)replacer;
+  else
+    return NULL;
+}
 
-list_t *maptab_search_miptab(list_t *pmlist, const char *cmorname, const char *miptab, char *key)
+list_t *maptab_search_miptab(list_t *pmlist, const char *cmorname, const char *miptab, const char *key)
 {
   if ( pmlist && cmorname && miptab )
     {
@@ -44,7 +63,8 @@ list_t *maptab_search_miptab(list_t *pmlist, const char *cmorname, const char *m
         }
       if ( listlatest )
         {
-          printf("No attribute 'mip_table' found in mapping table line for cmorname '%s'.\n The latest line of the mapping table is used.", cmorname);
+          if ( cdoVerbose )
+            cdoPrint("No attribute 'mip_table' found in mapping table line for cmorname '%s'.\n          The latest line of the mapping table is used.", cmorname);
           return listlatest;
         }
     }
@@ -98,14 +118,44 @@ char *skipSeparator(char *pline)
   return pline;
 }
 
+static void *handleError(list_t *kvl, int errnum, char *argument)
+{
+  char *filename = NULL;
+  if ( kvl )
+    filename = kv_get_a_val(kvl, "workfile4err", NULL);
+  else 
+    cdoAbort("In parsing the command line:\n          More than 100 values for a key are not supported.");
+  if ( !filename )
+    cdoAbort("In parsing file:\n          Cannot resolve recent working file.");
+  switch ( errnum )
+    {
+    case ( 1 ): cdoAbort("In parsing file '%s':\n          Unexpected blank in line:\n          '%s'\n          Check syntax.", filename, argument);
+    case ( 2 ): cdoAbort("In parsing file '%s':\n          Unexpected separator sign ',' in a key of line:\n          '%s'\n          Check syntax.", filename, argument);
+    case ( 3 ): cdoAbort("In parsing file '%s':\n          More than 100 values for a key are not supported.", filename);
+    case ( 4 ): cdoAbort("In parsing file '%s':\n          No values found for a keyword in line:\n          '%s'.\n          Check syntax.", filename, argument);
+    case ( 5 ): cdoAbort("In parsing file '%s':\n          A value for a keyword begins with ',' in line:\n          '%s'.\n          Check syntax.", filename, argument);
+    case ( 6 ): cdoAbort("In parsing file '%s':\n          A Value for a keyword has a start quote sign but no end quote sign in line:\n          '%s'.\n          Check syntax.",filename,  argument);
+    case ( 7 ): cdoAbort("In parsing file '%s':\n          Unexpected separator sign '=' or ':' is found in values in line:\n          '%s'.", filename, argument);
+    case ( 8 ): cdoAbort("In parsing file '%s':\n          Connected lines for one keyvalue contain more than the allowed 4096 characters.",filename);
+    case ( 9 ): cdoAbort("In parsing file '%s':\n          A ',' is found at end of a line without information in next line.",filename);
+    case ( 10): cdoAbort("In parsing file '%s':\n          A ',' is found at end of file.",filename);
+    }
+}
+
 static
-char *getElementName(char *pline, char *name)
+char *getElementName(char *pline, char *name, int *errh)
 {
   while ( isspace((int) *pline) ) pline++;
   size_t len = strlen(pline);
   size_t pos = 0;
-  while ( pos < len && !isspace((int) *(pline+pos)) && *(pline+pos) != '=' && *(pline+pos) != ':' )
+  while ( pos < len && *(pline+pos) != '=' )
     {
+      if ( isspace((int) *(pline+pos)) )
+        { *errh=1; return pline; }
+      if ( *(pline+pos) == ',' )
+        { *errh=2; return pline; }
+      if ( *(pline+pos) == ':' )
+        cdoWarning("In parsing file:\n          Separator sign ':' is not supported. Use '=' instead.\n          ...'%s'...", pline);
       name[pos] = tolower(*(pline+pos));
       pos++;
     }
@@ -115,15 +165,17 @@ char *getElementName(char *pline, char *name)
   return pline;
 }
 
-static void copy_value(char *value, char **values, int *nvalues)
+static int copy_value(char *value, char **values, int *nvalues)
 {
   if ( *nvalues > 100 )
-    cdoAbort("More than 100 values for a key are not supported.");
+    return 3;
   values[*nvalues] = strdup(value);
   (*nvalues)++;
   values[*nvalues] = NULL;
+  return 0;
 }
 
+
 static void free_array(char **tofree)
 {
   int i = 0;
@@ -148,17 +200,28 @@ static void quote_replace(char **values, int nvalues, int i)
 }
 
 static
-char *getElementValues(char *pline, char **values, int *nvalues)
+char *getElementValues(char *pline, char **values, int *nvalues, char *keyword, int *errh)
 {
   while ( isspace((int) *pline) ) pline++;
   size_t len = strlen(pline);
+  while ( isspace((int) *(pline+(int)len)) ) len--;
+  *(pline+len) = 0;
+  if ( (int)len == 0 )
+    {*errh=4; return keyword;}
   *nvalues = 0;
   int i = 0;
   while ( i < len && len )
     {
       if ( *(pline+i) == ',')
         {
-          copy_value(pline, values, nvalues);
+          if ( i == 0 )
+            {
+              *errh=5;
+              return pline;
+            }
+          *errh = copy_value(pline, values, nvalues);
+          if ( *errh > 0 )
+            return pline;
           if ( *(values[*nvalues-1]+i-1) == '"' || *(values[*nvalues-1]+i-1) == '\'' )
             quote_replace(values, *nvalues-1,i);
           else
@@ -176,40 +239,34 @@ char *getElementValues(char *pline, char **values, int *nvalues)
             {
               i++;
               if ( *(pline+i) == 0 )
-                cdoAbort("Found a start quote sign for a value but no end quote sign.\n");
+                {*errh=6; return pline;}
             }
           i++;
         }
       else if ( isspace((int) *(pline+i)) )
+        break;          
+      else if ( *(pline+i) == '=' || *(pline+i) == ':' )
         {
-          copy_value(pline, values, nvalues);
-          if ( *(values[*nvalues-1]+i-1) == '"' || *(values[*nvalues-1]+i-1) == '\'' )
-            quote_replace(values, *nvalues-1,i);
-          else
-            *(values[*nvalues-1]+i) = 0;
-          i++; 
-          pline+=i;
-          break;          
+          *errh=7;
+          return pline;
         }
-      else if ( *(pline+i) == '=' || *(pline+i) == ':' )
-        cdoAbort("Found unexpected separator sign in value: '%c'.", *(pline+i) );
       else
         i++;
     }
-  if ( i == len && len )
-    {
-      copy_value(pline, values, nvalues);
-      if ( *(values[*nvalues-1]+i-1) == '"' )
-        quote_replace(values, *nvalues-1, i);
-      else
-        *(values[*nvalues-1]+i) = 0;
-      *pline = 0;
-    }
+  *errh = copy_value(pline, values, nvalues);
+  if ( *errh > 0 )
+    return pline;
+  if ( *(values[*nvalues-1]+i-1) == '"' )
+    quote_replace(values, *nvalues-1, i);
+  else
+    *(values[*nvalues-1]+i) = 0;
+  pline+=i;
   return pline;
 }
 
-static void parse_line_to_list(list_t *list, char *pline, char *kvlname, int checkpml, int lowprior)
+static int parse_line_to_list(list_t *list, char *pline, const char *kvlname, int checkpml, int lowprior)
 {
+  int errh = 0;
   char name[256];
   int i = 0, nvalues;
   list_t *kvl = NULL;
@@ -222,21 +279,28 @@ static void parse_line_to_list(list_t *list, char *pline, char *kvlname, int che
     {
       char **values = (char **) Malloc( 100 * sizeof(char *) );
       
-      pline = getElementName(pline, name);
+      pline = getElementName(pline, name, &errh);
+      if ( strcmp(name, "conventions") == 0 )
+        strcpy(name, "Conventions");
+      if ( strcmp(name, "cordex_domain") == 0 )
+        strcpy(name, "CORDEX_domain");
+      if ( errh > 0 )
+        return errh;
       if ( *pline == 0 )
         {
-          if ( cdoVerbose )
-            printf("Could not find values for: '%s'\n", name);
+          cdoPrint("In parsing a line of a file:\n          Could not find values for key: '%s'. Use correct 'key=value' syntax.", name);
           break;
         }
       pline = skipSeparator(pline);
       if ( *pline == 0 )
         {
-          if ( cdoVerbose )
-            printf("Could not find values for: '%s'\n", name);
+          cdoPrint("In parsing a line of a file:\n          Could not find values for: '%s'. Use correct 'key=value' syntax.", name);
           break;
         }
-      pline = getElementValues(pline, values, &nvalues);
+      pline = getElementValues(pline, values, &nvalues, name, &errh);
+      if ( errh > 0 )
+        return errh;
+
       if ( checkpml )
         kvlist_append(kvl, name, (const char **)values, nvalues);
       else
@@ -254,11 +318,12 @@ static void parse_line_to_list(list_t *list, char *pline, char *kvlname, int che
         *pline = 0;
       free_array(values);
     }
+  return 0;
 }
 
 static void remove_space_and_comms(char **pline, char *line)
 {
-  while ( isspace((int) *(*pline)) ) *pline++;
+  while ( isspace((int) *(*pline)) ) (*pline)++;
   char *tester = *pline;
   int i = 0;
   while ( *tester != 0 )
@@ -272,43 +337,47 @@ static void remove_space_and_comms(char **pline, char *line)
     }
 }
 
-static void add_lines(char *line, char **buffer, size_t *buffersize)
+static int add_lines_tester(char *line)
 {
   char *tester = line;
   while ( *tester != 0 ) tester++;
   tester--;
   while ( isspace((int) *tester) ) tester--;
   if ( *tester == ',' )
+    return 1;
+  return 0;
+}
+
+static int add_lines(char *line, char **buffer, size_t *buffersize)
+{
+  int len = strlen(line);
+  char nextline[4096];
+  if ( (*buffer = readLineFromBuffer(*buffer, buffersize, nextline, sizeof(nextline))) )
     {
-      int len = strlen(line);
-      char nextline[4096];
-      if ( (*buffer = readLineFromBuffer(*buffer, buffersize, nextline, sizeof(nextline))) )
+      char *nexttester = nextline;
+      remove_space_and_comms(&nexttester, nextline);
+      if ( *nexttester != '\0' && *nexttester != '&' )
         {
-          char *nexttester = nextline;
-          remove_space_and_comms(&nexttester, nextline);
-          if ( *nexttester != '\0' && *nexttester != '&' )
-            {
-              if ( strlen(nexttester) + len > 4096 )
-                cdoAbort("Line too long!");
-              strcat(line, nextline);
-              add_lines(line, buffer, buffersize);          
-            }
-          else
-            cdoAbort("Found ',' at end of line.");
+          if ( strlen(nexttester) + len > 4096 )
+            return 8;
+          strcat(line, nextline);
         }
       else
-        cdoAbort("Found ',' at end of line.");
-    }      
-}
+        return 9;
+    }
+  else
+    return 10;
+}  
 
-void parse_buffer_to_list(list_t *list, size_t buffersize, char *buffer, int checkpml, int lowprior)
+void parse_buffer_to_list(list_t *list, size_t buffersize, char *buffer, int checkpml, int lowprior, list_t *kvl)
 {
   char line[4096];
   char name[256];
   char *pline;
-  char *listkeys[] = {"axis_entry:", "variable_entry:", "&parameter", NULL};
+  const char *listkeys[] = {"axis_entry:", "variable_entry:", "&parameter", NULL};
   int linenumber = 0;
   int listtype = 0;
+  int errh = 0;
 
   while ( (buffer = readLineFromBuffer(buffer, &buffersize, line, sizeof(line))) )
     {
@@ -316,7 +385,12 @@ void parse_buffer_to_list(list_t *list, size_t buffersize, char *buffer, int che
       pline = line;
       remove_space_and_comms(&pline, line);
       if ( *pline == '\0' ) continue;
-      add_lines(line, &buffer, &buffersize);
+      while ( add_lines_tester(line) )
+        {
+          errh = add_lines(line, &buffer, &buffersize);
+          if ( errh > 0 )
+            handleError(kvl, errh, NULL);
+        }
       //  len = (int) strlen(pline);
       if ( listtype == 0 && *pline == '&' ) listtype = 1;
 /* MAXNVALUES*/
@@ -333,9 +407,11 @@ void parse_buffer_to_list(list_t *list, size_t buffersize, char *buffer, int che
           i++;
         }
       if ( listtype )
-        parse_line_to_list(list, pline, listkeys[i], checkpml, lowprior);
+        errh = parse_line_to_list(list, pline, listkeys[i], checkpml, lowprior);
       else
-        parse_line_to_list(list, pline, "keyvals", checkpml, lowprior);
+        errh = parse_line_to_list(list, pline, "keyvals", checkpml, lowprior);
+      if ( errh > 0 )
+        handleError(kvl, errh, pline);
     }
 }
 
@@ -358,14 +434,6 @@ static void kv_insert_a_val(list_t *kvl, const char *key, char *value, int repla
     }
 }
 
-static char *kv_get_a_val(list_t *kvl, const char *key, char *replacer)
-{
-  keyValues_t *kv = kvlist_search(kvl, key);
-  if ( kv )
-    return kv->values[0];
-  return replacer;
-}
-
 static char **kv_get_vals(list_t *kvl, const char *key, int *numvals)
 {
   keyValues_t *kv = kvlist_search(kvl, key);
@@ -374,21 +442,21 @@ static char **kv_get_vals(list_t *kvl, const char *key, int *numvals)
   return NULL;
 }
 
-list_t *cdo_parse_cmor_file(const char *filename)
+list_t *cdo_parse_cmor_file(const char *filename, list_t *kvl)
 {
   assert(filename != NULL);
 
   size_t filesize = fileSize(filename);
   if ( filesize == 0 )
     {
-      fprintf(stderr, "Empty table file: %s\n", filename);
+      fprintf(stderr, "In reading the mapping table:\n          Empty table file: %s.", filename);
       return NULL;
     }
 
   FILE *fp = fopen(filename, "r");
   if ( fp == NULL )
     {
-      fprintf(stderr, "Open failed on %s: %s\n", filename, strerror(errno));
+      fprintf(stderr, "In reading the mapping table:\n          Open failed on %s: %s.", filename, strerror(errno));
       return NULL;
     }
 
@@ -399,7 +467,7 @@ list_t *cdo_parse_cmor_file(const char *filename)
 
   if ( nitems != filesize )
     {
-      fprintf(stderr, "Read failed on %s!\n", filename);
+      fprintf(stderr, "In reading the mapping table:\n          Read failed on %s.", filename);
       return NULL;
     }
  
@@ -408,10 +476,10 @@ list_t *cdo_parse_cmor_file(const char *filename)
 /*  if ( buffer[0] == '{' )
     parse_json_buffer_to_pml(pml, filesize, buffer);
   else */
-  parse_buffer_to_list(pml, filesize, buffer, 1, 0);
+  parse_buffer_to_list(pml, filesize, buffer, 1, 0, kvl);
 
   if ( buffer ) Free(buffer);
-  
+
   return pml;
 }
 
@@ -434,7 +502,7 @@ static void get_ifilevalue(char *ifilevalue, const char *key, int vlistID, int v
     }
 }
 
-static int getVarIDToMap(int vlistID, int nvars, char *key, char *value)
+static int getVarIDToMap(int vlistID, int nvars, const char *key, const char *value)
 {
   for ( int varID = 0; varID < nvars; varID++ )
     {
@@ -446,19 +514,58 @@ static int getVarIDToMap(int vlistID, int nvars, char *key, char *value)
   return CDI_UNDEFID;
 }
 
-static void map_it(list_t *kvl, int vlistID, int varID)
+
+static const char *check_short_key(char *key)
+{
+  const char *short_keys[]={"cn", "n", "c", "u", "cm", "vc", "p", "szc", "i", "ca", "za", "gi", "rtu", "mt", "om", "ms", "dr", "d", "lc", "dj", NULL};
+  const char *long_keys[]={"cmor_name", "name", "code", "units", "cell_methods", "variable_comment", "positive", "scalar_z_coordinate", "info", "character_axis", "z_axis",  "grid_info", "required_time_units", "mapping_table", "output_mode", "max_size", "drs_root", "drs", "last_chunk", "dataset_json", NULL};
+
+  for ( int i = 0; short_keys[i]; i++ )
+    if ( strcmp(key, short_keys[i]) == 0 || strcmp(key, long_keys[i]) == 0 )
+      return short_keys[i];
+/*  if ( strcmp(key, "cmor_name") == 0 ) short_key = strdup("cn");
+  else if ( strcmp(key, "name") == 0 ) short_key = strdup("n");
+  else if ( strcmp(key, "code") == 0 ) short_key = strdup("c");
+  else if ( strcmp(key, "units") == 0 ) short_key = strdup("u");
+  else if ( strcmp(key, "cell_methods") == 0 ) short_key = strdup("cm");
+  else if ( strcmp(key, "comment") == 0 ) short_key = strdup("k");
+  else if ( strcmp(key, "positive") == 0 ) short_key = strdup("p");
+  else if ( strcmp(key, "scalar_z_coordinate") == 0 ) short_key = strdup("szc");
+  else if ( strcmp(key, "info") == 0 ) short_key = strdup("i");
+  else if ( strcmp(key, "character_axis") == 0 ) short_key = strdup("ca");
+  else if ( strcmp(key, "z_axis") == 0 ) short_key = strdup("za");
+  else if ( strcmp(key, "grid_info") == 0 ) short_key = strdup("gi");
+  else if ( strcmp(key, "required_time_units") == 0 ) short_key = strdup("rtu");
+  else if ( strcmp(key, "mapping_table") == 0 ) short_key = strdup("mt");
+  else if ( strcmp(key, "calendar") == 0 ) short_key = strdup("l");
+  else if ( strcmp(key, "output_mode") == 0 ) short_key = strdup("om");
+  else if ( strcmp(key, "max_size") == 0 ) short_key = strdup("ms");
+  else if ( strcmp(key, "drs_root") == 0 ) short_key = strdup("dr");
+  else if ( strcmp(key, "drs") == 0 ) short_key = strdup("d");
+  else if ( strcmp(key, "last_chunk") == 0 ) short_key = strdup("lc"); 
+  else if ( strcmp(key, "dataset_json") == 0 ) short_key = strdup("dj"); */
+  return NULL;
+}
+
+static void map_it(list_t *kvl, int vlistID, int varID, char *var2map)
 {
   for ( listNode_t *kvnode = kvl->head; kvnode; kvnode = kvnode->next )
     {
       keyValues_t *kv = *(keyValues_t **)kvnode->data;
-      const char *key = kv->key;
+      const char *key = ( check_short_key((char *)kv->key ) ) ? check_short_key((char *)kv->key) : NULL;
+      if ( !key )
+        {
+          if ( strcmp(kv->key, "mip_table") != 0 )
+            cdoWarning("In variable mapping:\n           you try to assign '%s' to variable '%s'.\n          This mapping table keyword is skipped. Check allowed mapping table keywords.", kv->key, var2map);
+          continue;
+         }
       const char *value = kv->values[0];
 /*      printf("'%s' = '%s'\n", key, value); */
       if ( !value ) continue;
 /* Not necessary because cmor_name is what we use for renaming :
       else if ( STR_IS_EQ(key, "name")          ) vlistDefVarName(vlistID, varID, parameter2word(value));
 */
-      else if ( STR_IS_EQ(key, "cmor_name") )
+      else if ( STR_IS_EQ(key, "cn") )
         {
           char name[CDI_MAX_NAME];
           vlistInqVarName(vlistID, varID, name);
@@ -466,9 +573,10 @@ static void map_it(list_t *kvl, int vlistID, int varID)
             cdiDefAttTxt(vlistID, varID, "original_name", (int) strlen(name), parameter2word(name));
           vlistDefVarName(vlistID, varID, parameter2word(value));
          }
-      else if ( STR_IS_EQ(key, "units")        ) vlistDefVarUnits(vlistID, varID, value);
-      else if ( STR_IS_EQ(key, "cell_methods")  ) cdiDefAttTxt(vlistID, varID, "cell_methods", (int) strlen(value), value);
-      else if ( STR_IS_EQ(key, "character_axis")  ) cdiDefAttTxt(vlistID, varID, "character_axis", (int) strlen(value), value);
+      else if ( STR_IS_EQ(key, "u")        ) vlistDefVarUnits(vlistID, varID, value);
+      else if ( STR_IS_EQ(key, "cm")  ) cdiDefAttTxt(vlistID, varID, "cell_methods", (int) strlen(value), value);
+      else if ( STR_IS_EQ(key, "ca")  ) cdiDefAttTxt(vlistID, varID, "character_axis", (int) strlen(value), value);
+      else if ( STR_IS_EQ(key, "za")  ) cdiDefAttTxt(vlistID, varID, "z_axis", (int) strlen(value), value);
 /*      else if ( STR_IS_EQ(key, "factor")        ) {}
       else if ( STR_IS_EQ(key, "delete")        ) {}
       else if ( STR_IS_EQ(key, "long_name")     ) vlistDefVarLongname(vlistID, varID, value);
@@ -478,7 +586,7 @@ static void map_it(list_t *kvl, int vlistID, int varID)
               // else if ( STR_IS_EQ(key, "code")          ) vlistDefVarParam(vlistID, varID, cdiEncodeParam(parameter2int(value), ptab, 255));
               // else if ( STR_IS_EQ(key, "out_code")      ) vlistDefVarParam(vlistID, varID, cdiEncodeParam(parameter2int(value), ptab, 255));
 */
-      else if ( STR_IS_EQ(key, "comment")       ) cdiDefAttTxt(vlistID, varID, "comment", (int) strlen(value), value);
+      else if ( STR_IS_EQ(key, "vc")       ) cdiDefAttTxt(vlistID, varID, "comment", (int) strlen(value), value);
       else if ( STR_IS_EQ(key, "p")       )
         {
           if ( !isspace(value[0]) )
@@ -494,7 +602,7 @@ static void map_it(list_t *kvl, int vlistID, int varID)
       else if ( STR_IS_EQ(key, "datatype") || STR_IS_EQ(key, "type") ) {} */
       else
         {
-          if ( cdoVerbose ) printf("For Mapping key '%s' is ignored.\n", key);
+          if ( cdoVerbose ) cdoPrint("In applying the mapping table:\n          Key: '%s' is ignored.", key);
         }
     }
 }
@@ -536,90 +644,118 @@ static int change_name_via_code(int vlistID, char *map_code, char *cmor_name)
 static int maptab_via_key(list_t *pml, int vlistID, int varID, int nventry, const char **ventry, const char *key, char *miptabfreq)
 {
   char ifilevalue[CDI_MAX_NAME];
-  get_ifilevalue(ifilevalue, key, vlistID, varID);
+  if ( strcmp(key, "cmor_name") != 0 )
+    get_ifilevalue(ifilevalue, key, vlistID, varID);
+  else
+    get_ifilevalue(ifilevalue, "name", vlistID, varID);
 
   if ( ifilevalue[0] )
     {
-      list_t *kvl = maptab_search_miptab(pml, ifilevalue, miptabfreq, (char *)key);
+      list_t *kvl = maptab_search_miptab(pml, ifilevalue, miptabfreq, key);
       if ( kvl )
         {
-          printf("Started mapping of variable via '%s'.\n", key);
-          map_it(kvl, vlistID, varID);
+          if ( cdoVerbose )
+            cdoPrint("Start to map via '%s'.", key);
+          map_it(kvl, vlistID, varID, ifilevalue);
           return 1;
         }
-      cdoWarning("Variable named '%s' with varID '%d' could not be mapped via '%s' because no corresponding key '%s' was found in mapping table file.", ifilevalue, varID, key, key);
+      if ( cdoVerbose )
+        cdoPrint("In variable mapping:\n          Variable named '%s' with varID '%d' could not be mapped via '%s' because no corresponding key '%s' was found in mapping table file.", ifilevalue, varID, key, key);
       return 0;
     }
   else
     {
-      cdoWarning("Variable with varID '%d' could not be mapped via '%s' because it does not possess a '%s' in Ifile.", varID, key, key);
+      if ( cdoVerbose )
+        cdoPrint("In variable mapping:\n          Variable with varID '%d' could not be mapped via '%s' because it does not possess a '%s' in infile.", varID, key, key);
       return 0;
     }
 }
 
-static int maptab_via_cn_and_key(list_t *kvl_oname, int vlistID, int nvars, char *key)
+static int maptab_via_cn_and_key(list_t *kvl_oname, int vlistID, int nvars, const char *key)
 {
   keyValues_t *kv = kvlist_search(kvl_oname, key);
+  keyValues_t *kvcn = kvlist_search(kvl_oname, "cmor_name");
   if ( kv )
     {
-      int varID = getVarIDToMap(vlistID, nvars, key, kv->values[0]);
+      int varID = ( strcmp(key, "cmor_name") == 0 ) ? getVarIDToMap(vlistID, nvars, "name", kv->values[0]) : getVarIDToMap(vlistID, nvars, key, kv->values[0]);
       if ( varID != CDI_UNDEFID )
         {
-          printf("Started mapping of variable via '%s'.\n", key);
-          map_it(kvl_oname, vlistID, varID);
+          if ( cdoVerbose )
+            cdoPrint("Started mapping of variable via '%s'.", key);
+          map_it(kvl_oname, vlistID, varID, kv->values[0]);
           return 1;
         }
-      cdoWarning("Could not map via key '%s' because no Ifile variable '%s' equals '%s'.", key, key, kv->values[0]);
+      cdoPrint("In variable mapping:\n          Variable '%s' configured via cmor_name\n          could not be mapped via key '%s' because no infile variable '%s' equals '%s'.", kvcn->values[0], key, key, kv->values[0]);
     }
   else
-    cdoWarning("Could not map via key '%s' because it possesses no corresponding key '%s' in mapping file.", key, key);
+    if ( cdoVerbose )
+      cdoPrint("In variable mapping:\n          Variable '%s' configured via cmor_name\n          could not be mapped via key '%s' because it possesses no corresponding key '%s' in mapping file.", kvcn->values[0], key, key);
   return 0;
 }
 
-static void maptab_via_cmd(list_t *pml, char *origValue, int vlistID, int nvars, char *key, char *cmorName, char *miptabfreq)
+static void maptab_via_cmd(list_t *pml, const char *origValue, int vlistID, int nvars, const char *key, char *cmorName, char *miptabfreq)
 {
   int varIDToMap = getVarIDToMap(vlistID, nvars, key, origValue);
   if ( varIDToMap == CDI_UNDEFID )
-    cdoAbort("Could not find variable with '%s': '%s' in Ifile.", key, origValue);
+    cdoAbort("In variable mapping:\n          Variable with '%s': '%s' configured via cmdline could not be found in infile '%s'.", key, origValue, cdoStreamName(0)->args);
   list_t *kvl_maptab = maptab_search_miptab(pml, cmorName, miptabfreq, "cmor_name");
   if ( !kvl_maptab )
     {
-      cdoWarning("Could not find cmor_name '%s' in mapping table.\n No mapping table is applied.", cmorName);
+      cdoWarning("In variable mapping:\n          The registered cmor_name '%s' via cmdline could not be found in mapping table.\n          No mapping table is applied.", cmorName);
       vlistDefVarName(vlistID, varIDToMap, parameter2word((const char *) cmorName));
     }
   else
     {
-      printf("Started mapping of variable via '%s'.\n", key);
-      map_it(kvl_maptab, vlistID, varIDToMap);
+      if ( cdoVerbose )
+        cdoPrint("Started mapping of variable via '%s'.", key);
+      map_it(kvl_maptab, vlistID, varIDToMap, cmorName);
     }
 }
 
-static void maptab_via_cn(list_t *pml, char **request, int vlistID, int nvars, int numvals, char *miptabfreq)
+static void maptab_via_cn(list_t *pml, char **request, int vlistID, int nvars, int numvals, char *miptabfreq, int filetype)
 {
   for ( int j = 0; j<numvals; j++)
     {
       list_t *kvl_oname = maptab_search_miptab(pml, request[j], miptabfreq, "cmor_name");
       if ( kvl_oname )
         {
+          if ( filetype == FILETYPE_GRB || filetype ==  FILETYPE_GRB2 )
+            {
+              if ( maptab_via_cn_and_key(kvl_oname, vlistID, nvars, "code") )
+                {
+                  if ( cdoVerbose )
+                    cdoPrint("Successfully mapped variable via code to cmor_name '%s'.", request[j]); 
+                  continue;
+                }
+            }
           if ( maptab_via_cn_and_key(kvl_oname, vlistID, nvars, "name") )
             {
-              printf("*******Succesfully mapped variable via name to cmor_name: '%s'.********\n", request[j]); 
+              if ( cdoVerbose )
+                cdoPrint("Successfully mapped variable via name to cmor_name: '%s'.", request[j]); 
               continue;
             }
-          else if ( maptab_via_cn_and_key(kvl_oname, vlistID, nvars, "code") )
+          else if ( ( filetype != FILETYPE_GRB && filetype != FILETYPE_GRB2 ) && maptab_via_cn_and_key(kvl_oname, vlistID, nvars, "code") )
             {
-              printf("*******Succesfully mapped variable via code to cmor_name '%s'.********\n", request[j]); 
+              if ( cdoVerbose )
+                cdoPrint("Successfully mapped variable via code to cmor_name '%s'.", request[j]); 
               continue;
             }
           else
             {
-              cdoWarning("No identification 'name' or 'key' in mapping table line of cmor_name '%s'. Variable not mapped.\n", request[j]);
+              if ( cdoVerbose )
+                cdoPrint("In variable mapping:\n          Try to use cmor_name for selecting the infile variable.", request[j]);
+              if ( maptab_via_cn_and_key(kvl_oname, vlistID, nvars, "cmor_name") )
+                {
+                  cdoPrint("Successfully mapped variable via cmor_name to cmor_name '%s'.", request[j]); 
+                  continue;
+                }
+              cdoWarning("In variable mapping:\n          Mapping table line of cmor_name '%s' could neither be mapped via 'name', 'code' nor 'cmor_name'.\n          No mapping for cmor_name: '%s'.", request[j],request[j]);
               continue;
             }
         }
       else
         {
-          cdoWarning("Requested cmor_name: '%s' is not found in mapping table.'\n", request[j]);
+          cdoWarning("In variable mapping:\n          Requested cmor_name: '%s' is not found in mapping table.\n          No mapping for cmor_name: '%s'", request[j],request[j]);
           continue;
         }
     }
@@ -691,17 +827,17 @@ static int count_axis_ids(int *axis_ids)
   return i;
 }
 
-static void addcharvar(keyValues_t *charvars, int vlistID, char *key, struct mapping vars[])
+static void addcharvar(keyValues_t *charvars, int vlistID, const char *key, struct mapping vars[])
 {
   if ( cdoVerbose )
-    printf("*******Start to merge variables to one character coordinate.*******\n");
+    cdoPrint("Start to merge variables to one character coordinate.");
   int varIDs[charvars->nvalues];
   int nvars = vlistNvars(vlistID);
   for ( int i = 0; i < charvars->nvalues; i++)
     {
       varIDs[i] = getVarIDToMap(vlistID, nvars, key, charvars->values[i]);
       if ( varIDs[i] == CDI_UNDEFID )
-        cdoAbort("Could not find '%s' to build a variable with character coordinate.", charvars->values[i]);
+        cdoAbort("In merging variables to a variable with a character coordinate:\n          Could not find '%s' in infile '%s' to build a variable with character coordinate.", charvars->values[i], cdoStreamName(0)->args);
     }
 
   int gridID = vlistInqVarGrid(vlistID, varIDs[0]);
@@ -724,7 +860,7 @@ static void addcharvar(keyValues_t *charvars, int vlistID, char *key, struct map
   int axissize[3];
   double *xvals, *yvals, *zvals, *subsvals;
 
-  subsvals = Malloc(charvars->nvalues * sizeof(double));
+  subsvals = (double *) Malloc(charvars->nvalues * sizeof(double));
   for ( int i = 0; i < charvars->nvalues; i++ )
     subsvals[i] = i+1;
 
@@ -734,7 +870,7 @@ static void addcharvar(keyValues_t *charvars, int vlistID, char *key, struct map
 
 
   if ( axissize[0] != 1 && axissize[1] != 1 && axissize[2] != 1 )
-    cdoAbort("No axis found to merge. One axis may not be allocated with more than one value.");
+    cdoAbort("In merging variables to a variable with a character coordinate:\n          No axis found to merge. One axis may not be allocated with more than one value.");
 
   int oldgridsize = axissize[0] * axissize[1];
   double *buffer_old = (double *)Malloc(oldgridsize * sizeof(double));
@@ -744,35 +880,35 @@ static void addcharvar(keyValues_t *charvars, int vlistID, char *key, struct map
       gridID = vlistInqVarGrid(vlistID, varIDs[i]);  
       zaxisID = vlistInqVarZaxis(vlistID, varIDs[i]);
       if ( axissize[0] != gridInqXsize(gridID) )
-        cdoAbort("Size of x-axis: '%d' of variable '%s'\n differ from x-axis size of variable '%s': '%d'.", gridInqXsize(gridID), charvars->values[i], charvars->values[0], axissize[0]);
+        cdoAbort("In merging variables to a variable with a character coordinate:\n          Size of x-axis: '%d' of variable '%s'\n          differ from x-axis size of variable '%s': '%d'.", gridInqXsize(gridID), charvars->values[i], charvars->values[0], axissize[0]);
       if ( axissize[1] != gridInqYsize(gridID) )
-        cdoAbort("Size of y-axis: '%d' of variable '%s'\n differ from y-axis size of variable '%s': '%d'.", gridInqYsize(gridID), charvars->values[i], charvars->values[0], axissize[1]);
+        cdoAbort("In merging variables to a variable with a character coordinate:\n          Size of y-axis: '%d' of variable '%s'\n          differ from y-axis size of variable '%s': '%d'.", gridInqYsize(gridID), charvars->values[i], charvars->values[0], axissize[1]);
       if ( axissize[2] != zaxisInqSize(zaxisID) )
-        cdoAbort("Size of z-axis: '%d' of variable '%s'\n differ from z-axis size of variable '%s': '%d'.", zaxisInqSize(zaxisID), charvars->values[i], charvars->values[0], axissize[2]);
+        cdoAbort("In merging variables to a variable with a character coordinate:\n          Size of z-axis: '%d' of variable '%s'\n          differ from z-axis size of variable '%s': '%d'.", zaxisInqSize(zaxisID), charvars->values[i], charvars->values[0], axissize[2]);
     }
 
   if ( axissize[0] == 1 )
     {
       xvals = subsvals;
-      yvals = Malloc(axissize[1] * sizeof(double));
-      zvals = Malloc(axissize[2] * sizeof(double));
+      yvals = (double *) Malloc(axissize[1] * sizeof(double));
+      zvals = (double *) Malloc(axissize[2] * sizeof(double));
       gridInqYvals(gridID, yvals);
       zaxisInqLevels(zaxisID, zvals); 
       axissize[0] = charvars->nvalues;
     }
   else if ( axissize[1] == 1 )
     {
-      xvals = Malloc(axissize[0] * sizeof(double));
+      xvals = (double *) Malloc(axissize[0] * sizeof(double));
       yvals = subsvals;
-      zvals = Malloc(axissize[2] * sizeof(double));
+      zvals = (double *) Malloc(axissize[2] * sizeof(double));
       gridInqXvals(gridID, xvals);
       zaxisInqLevels(zaxisID, zvals); 
       axissize[1] = charvars->nvalues;
     }
   else if ( axissize[2] == 1 )
     {
-      xvals = Malloc(axissize[0] * sizeof(double));
-      yvals = Malloc(axissize[1] * sizeof(double));
+      xvals = (double *) Malloc(axissize[0] * sizeof(double));
+      yvals = (double *) Malloc(axissize[1] * sizeof(double));
       zvals = subsvals;
       gridInqXvals(gridID, xvals);
       gridInqYvals(gridID, yvals);
@@ -789,7 +925,7 @@ static void addcharvar(keyValues_t *charvars, int vlistID, char *key, struct map
   zaxisDefLevels(subzaxisID, zvals); 
 
   struct mapping *var = new_var_mapping(vars);
-  var->cdi_varID = vlistDefVar(vlistID, subgridID, subzaxisID,  TSTEP_INSTANT); 
+  var->cdi_varID = vlistDefVar(vlistID, subgridID, subzaxisID,  TIME_VARYING);
   vlistDefVarName(vlistID, getVarIDToMap(vlistID, nvars+1, key, charvars->values[0]), "ChangedForMap");
   vlistDefVarName(vlistID, var->cdi_varID, charvars->values[0]);
   vlistDefVarDatatype(vlistID, var->cdi_varID,  DATATYPE_FLT64);
@@ -834,7 +970,7 @@ static void addcharvar(keyValues_t *charvars, int vlistID, char *key, struct map
   Free(buffer_old);
 
   if ( cdoVerbose )
-    printf("*******Successfully merged variables into one character axis. The final variable is called '%s' and has the ID: '%d'*******\n", charvars->values[0], var->cdi_varID);
+    cdoPrint("Successfully merged variables into one character axis. The final variable is called '%s' and has the ID: '%d'", charvars->values[0], var->cdi_varID);
 }
 
 static char *trim(char *s)
@@ -849,31 +985,25 @@ static char *trim(char *s)
   return s;
 }
 
-static int file_exist(const char *tfilename, int force)
+static int file_exist(const char *tfilename, int force, const char *fileart)
 {
   assert(tfilename != NULL);
   size_t filesize = fileSize(tfilename);
   if ( filesize == 0 && force)
-    {
-      fprintf(stderr, "Empty file: %s\n", tfilename);
-      return 0;
-    }
+    cdoAbort("In checking wether a %s file exist:\n          Empty file: '%s'.", fileart, tfilename);
   else if ( filesize == 0 && !force )
     {
-      cdoWarning("cannot open '%s'", tfilename);
+      cdoPrint("In checking wether a %s file exist:\n          Empty file: '%s'.", fileart, tfilename);
       return 0;
     }
   if ( strstr(tfilename, ".nc") || strstr(tfilename, ".grb") )
     return 1;
   FILE *fp = fopen(tfilename, "r");
   if ( fp == NULL && force )
-    {
-      fprintf(stderr, "Open failed on %s: %s\n", tfilename, strerror(errno));
-      return 0;
-    }
+    cdoAbort("In checking wether a %s file exist:\n          Open failed on: '%s'.", fileart, tfilename);
   else if ( fp == NULL && !force )
     {
-      cdoWarning("cannot open '%s'", tfilename);
+      cdoPrint("In checking wether a %s file exist::\n          Open failed on: '%s'.", fileart, tfilename);
       return 0;
     }
 
@@ -883,8 +1013,7 @@ static int file_exist(const char *tfilename, int force)
   
 static int parse_kv_file(list_t *kvl, const char *filename)
 {
-  if ( !file_exist(filename, 1) )
-    cdoAbort("Configuration failed.\n");
+  file_exist(filename, 1, "Configuration");
 
   FILE *fp = fopen(filename, "r");
   size_t filesize = fileSize(filename);
@@ -892,22 +1021,23 @@ static int parse_kv_file(list_t *kvl, const char *filename)
   size_t nitems = fread(buffer, 1, filesize, fp);
   fclose(fp);
 
-  parse_buffer_to_list(kvl, filesize, buffer, 0, 1);
+  kv_insert_a_val(kvl, "workfile4err", (char *)filename, 1);
+  parse_buffer_to_list(kvl, filesize, buffer, 0, 1, kvl);
 
   if ( buffer ) Free(buffer);
-  return 0;
+  return 1;
 }
 
-static void check_compare_set(char **finalset, char *attribute, char *attname, const char *returner)
+static void check_compare_set(char **finalset, char *attribute, const char *attname, const char *defaultstr)
 {
   if ( !(*finalset) )
     {
       if ( !attribute )
         {
-          if ( returner )
-            *finalset = strdup(returner);
+          if ( defaultstr )
+            *finalset = strdup(defaultstr);
           else
-            cdoAbort("Required value for attribute '%s' is neither found in input file nor in the configuration.", attname);
+            cdoAbort("In comparison of configuration attribute and infile attribute:\n          Required value for attribute '%s' is neither found in input file nor in the configuration.", attname);
         }
       else 
         *finalset = strdup(attribute);
@@ -916,13 +1046,14 @@ static void check_compare_set(char **finalset, char *attribute, char *attname, c
     {
       if ( strcmp(attribute, *finalset) != 0 )
         {
-          cdoWarning("%s of variable in input file: '%s' does not agree with configuration attribute %s: '%s'.\nCmor libary is called with attribute unit '%s'.\n", attname, *finalset, attname, attribute, attribute);
-          strcpy(*finalset, attribute);
+          cdoPrint("In comparison of configuration attribute and infile attribute:\n          '%s' of variable in input file: '%s' does not agree with configuration attribute %s: '%s'.\n          Cmor libary is called with attribute unit '%s'.", attname, *finalset, attname, attribute, attribute);
+          Free(*finalset);
+          *finalset = strdup(attribute);
         }
     }
 }
 
-static int check_attr(list_t *kvl, char *project_id)
+static void add_globalhybrids(list_t *kvl)
 {
   const char *longAtt[] = {"required_time_units", "grid_info", "mapping_table", NULL};
   const char *shortAtt[] = {"rtu", "gi", "mt", NULL};
@@ -938,24 +1069,53 @@ static int check_attr(list_t *kvl, char *project_id)
         kv_insert_a_val(kvl, longAtt[i], kv_satt->values[0], 1);      
       i++;
     }
+}
 
-/* Project id moved to main void fct */
-  const char *reqAtt[] = {"institute_id", "institution", "contact", "model_id", "source",
-            "experiment_id", "required_time_units", NULL};
-  const char *reqAttCMIP5[] = {"product", "member", NULL};
-  const char *reqAttCORDEX[] = {"product", "member", "cordex_domain", "driving_model_id", NULL};
-/* In all Projects needed Attributes are tested first */
-
+static int check_attarray(list_t *kvl, const char **reqAtt)
+{
+  int i = 0;
   while ( reqAtt[i] != NULL )
     {
       keyValues_t *kv_reqatt = kvlist_search(kvl, reqAtt[i]);
-      
       if ( !kv_reqatt || strcmp(kv_reqatt->values[0], "notSet") == 0 )
-        cdoAbort("Attribute '%s' is required. Either it is missing or notSet.", reqAtt[i]);
+        return i;
       if ( cdoVerbose )
-        printf("Attribute '%s' is '%s' \n", reqAtt[i], kv_reqatt->values[0]);
+        cdoPrint("Attribute '%s' is '%s'. ", reqAtt[i], kv_reqatt->values[0]);
+      i++;
+    }
+  return -1;
+}
+
+static void attErr(const char **reqAtt, int errnum)
+{
+  char errStr[CMOR_MAX_STRING];
+  int i = 1;
+
+  sprintf(errStr, "Attribute '%s' is required. Either it is missing or notSet.\n          Make sure that you have configured all following attributes:\n          %s", reqAtt[errnum], reqAtt[0]);
+  while ( reqAtt[i] )
+    {
+      sprintf(errStr, "%s, %s", errStr, reqAtt[i]);
       i++;
     }
+  cdoAbort(errStr);
+}
+
+static int check_attr(list_t *kvl, char *project_id)
+{
+/* Project id moved to main void fct */
+  const char *reqAtt[] = {"institution", "contact", "model_id", "source",
+            "experiment_id", "required_time_units", NULL};
+  const char *reqAttCMIP5[] = {"institute_id", "product", "member", NULL};
+  const char *reqAttCMIP5CMOR3[] = {"modeling_realm", NULL};
+  const char *reqAttCORDEX[] = {"institute_id", "product", "member", "CORDEX_domain", "driving_model_id", NULL};
+  const char *reqAttCMIP6CMOR3[] = {"outpath", "output_path_template", "output_file_template", "tracking_prefix", NULL};
+  const char *reqAttCMIP6[] = {"Conventions", "activity_id", "experiment", "further_info_url", "grid", "grid_label", "institution_id", "license", "mip_era", "nominal_resolution", "product", "source_id", "source_type", "variant_label", NULL};
+  const char *expdepAttCMIP6[] = {"parent_experiment_id", "parent_activity_id", "parent_mip_era", "parent_source_id", "parent_variant_label", "parent_time_units", "sub_experiment", "sub_experiment_id", "branch_method", NULL};
+/* In all Projects needed Attributes are tested first */
+
+  int errnum = 0;
+  if ( ( errnum = check_attarray(kvl, reqAtt) ) != -1 )
+    attErr(reqAtt, errnum);
 /* Set default attributes */
   keyValues_t *kv = kvlist_search(kvl, "references");
 
@@ -965,42 +1125,51 @@ static int check_attr(list_t *kvl, char *project_id)
       char *references = (char *) Malloc(strlen(kv_model_id->values[0]) + 28);
       strcpy(references, "No references available for ");
       strcat(references, kv_model_id->values[0]);
-      cdoWarning("Attribute 'references' is set to '%s' ", references);
+      cdoPrint("Attribute 'references' is set to '%s' ", references);
       kv_insert_a_val(kvl, "references", references, 1);
       Free(references);
     }
 
-/* Special check for CMIP5 or CORDEX projects */
-  i=0;
-  if ( strcmp(project_id, "CMIP6") == 0 )
-    cdoAbort("Not yet possible to create data for project CMIP6 since cmor version 2.9 is used in this operator.\n");
+/* Special check for CMIP or CORDEX projects */
   if ( strcmp(project_id, "CMIP5") == 0 )
     {
       if ( cdoVerbose )
-        printf("Since the project id is %s further attributes are tested. \n", project_id);
-      while ( reqAttCMIP5[i] != NULL )
-        {
-          keyValues_t *kv_reqattCMIP5 = kvlist_search(kvl, reqAttCMIP5[i]);
-          if ( !kv_reqattCMIP5 || strcmp(kv_reqattCMIP5->values[0], "notSet") == 0 )
-            cdoAbort("Attribute '%s' is required. Either it is missing or notSet", reqAttCMIP5[i]);
-          if ( cdoVerbose )
-            printf("Attribute '%s' is '%s' \n", reqAttCMIP5[i], kv_reqattCMIP5->values[0]);
-          i++;
-        }
+        cdoPrint("Since the project id is CMIP5 further attributes are tested. ");
+      if ( ( errnum = check_attarray(kvl, reqAttCMIP5) ) != -1 )
+        attErr(reqAttCMIP5, errnum);
+#if ( CMOR_VERSION_MAJOR == 3 )
+/**************/
+/* Add additional attributes for CMIP5 */
+/* allthough using CMOR 3 */
+/**************/
+      if ( ( errnum = check_attarray(kvl, reqAttCMIP5CMOR3) ) != -1 )
+        attErr(reqAttCMIP5CMOR3, errnum);
+#endif
     }
   else if (strcmp(project_id, "CORDEX") == 0 )
     {
       if ( cdoVerbose )
-        printf("\nSince the project id is %s further attributes are tested\n", project_id);
-      i=0;
-      while ( reqAttCORDEX[i] != NULL )
+        cdoPrint("Since the project id is CORDEX further attributes are tested.");
+      if ( ( errnum = check_attarray(kvl, reqAttCORDEX) ) != -1 )
+        attErr(reqAttCORDEX, errnum);
+    }
+  else if (strcmp(project_id, "CMIP6") == 0 )
+    {
+      kv_insert_a_val(kvl, "_cmip6_option", (char *)"CMIP6", 1);
+      if ( cdoVerbose )
+        cdoPrint("Since the project_id is CMIP6 further attributes are tested.");
+      if ( ( errnum = check_attarray(kvl, reqAttCMIP6) ) != -1 )
+        attErr(reqAttCMIP6, errnum);
+      int j = 0;
+      while ( expdepAttCMIP6[j] != NULL )
         {
-          keyValues_t *kv_reqattCORDEX = kvlist_search(kvl, reqAttCORDEX[i]);
-          if ( !kv_reqattCORDEX || strcmp(kv_reqattCORDEX->values[0], "notSet") == 0 )
-            cdoAbort("Attribute '%s' is required. Either it is missing or notSet", reqAttCORDEX[i]);
-          if ( cdoVerbose )
-            printf("Attribute '%s' is '%s' \n", reqAttCORDEX[i], kv_reqattCORDEX->values[0]);
-          i++;
+          keyValues_t *kv_reqatt = kvlist_search(kvl, expdepAttCMIP6[j]);
+          if ( !kv_reqatt || strcmp(kv_reqatt->values[0], "notSet") == 0 )
+            if ( cdoVerbose )
+              cdoPrint("Depending on the experiment, attribute '%s' may be required. Either it is missing or notSet", expdepAttCMIP6[j]);
+          else if ( cdoVerbose )
+            cdoPrint("Attribute '%s' is '%s'. ", expdepAttCMIP6[j], kv_reqatt->values[0]);
+          j++;
         }
     }
   return 1;
@@ -1008,17 +1177,91 @@ static int check_attr(list_t *kvl, char *project_id)
 
 static int check_mem(list_t *kvl, char *project_id)
 {
+  const char *ripcharCMIP5[] = {"realization", "initialization_method", "physics_version"};
+  const char *ripcharCMIP6[] = {"realization_index","initialization_index","physics_index","forcing_index"};
+  char ripchar[5];
+  strcpy(ripchar, "ripf");
+
   char *kv_member = kv_get_a_val(kvl, "member", "");
-  char *ripchar[] = {"realization", "initialization", "physics_version"};
-  char *crealiz, *cinitial, *cphysics;
+  int ripcharlen = 3;
+  if ( strcmp(project_id, "CMIP6") == 0 )
+    {
+      kv_member= kv_get_a_val(kvl, "variant_label", "");
+      kv_insert_a_val(kvl, (char *)"member", kv_member, 1);
+      ripcharlen = 4;
+    }
+  int memberlen = strlen(kv_member);
+  char ripvaluechar[memberlen][CMOR_MAX_STRING];
+  for ( int k = 0; k < memberlen; k++ )
+    strcpy(ripvaluechar[k], kv_member);
+
+  int firstNum, tonull, j = 0;
+  for ( int i = 0; i < ripcharlen; i++ )
+    {
+      while ( kv_member[j] != ripchar[i] && j < memberlen )
+        j++;
+      if ( j == memberlen )
+        {
+          j = -1;
+          if ( ripcharlen == 3)
+            cdoPrint("Attribute 'member' has no RIP format! Default setting is used: \n          realization=-1 \n          initialization=-1 \n          physics=-1. \n          forcing=-1.");
+          else
+            cdoPrint("Attribute 'variant_label' has no RIPF format! Default setting is used: \n          realization=-1 \n          initialization=-1 \n          physics=-1. \n          forcing=-1.");
+          break;
+        }
+      firstNum = j+1;
+      j = 0;
+      if ( i < (ripcharlen - 1) )
+        while ( kv_member[j] != ripchar[i+1] && j < memberlen )
+          j++;
+      if ( j == memberlen )
+        {
+          j = -1;
+          if ( ripcharlen == 3)
+            cdoPrint("Attribute 'member' has no RIP format! Default setting is used: \n          realization=-1 \n          initialization=-1 \n          physics=-1. \n          forcing=-1.");
+          else
+            cdoPrint("Attribute 'variant_label' has no RIPF format! Default setting is used: \n          realization=-1 \n          initialization=-1 \n          physics=-1. \n          forcing=-1.");
+          break;
+        }
+      tonull = j;
+      j = 0;
+      char *temp = ripvaluechar[i];
+      temp += firstNum;
+      strcpy(ripvaluechar[i], temp);
+
+      if ( i < ripcharlen - 1 )
+        ripvaluechar[i][tonull-firstNum] = '\0';
+    }
+  if ( j != -1 )
+    {
+      if ( ripcharlen == 3 )
+        for ( int i = 0; i < ripcharlen; i++ )
+          kv_insert_a_val(kvl, (char *)ripcharCMIP5[i], ripvaluechar[i], 1);
+      else
+        for ( int i = 0; i < ripcharlen; i++ )
+          kv_insert_a_val(kvl, (char *)ripcharCMIP6[i], ripvaluechar[i], 1);
+    }
+  else
+    {
+      if ( ripcharlen == 3 )
+        for ( int i = 0; i < ripcharlen; i++ )
+          kv_insert_a_val(kvl, (char *)ripcharCMIP5[i], (char *)"-1", 1);
+      else
+        for ( int i = 0; i < ripcharlen; i++ )
+          kv_insert_a_val(kvl, (char *)ripcharCMIP6[i], (char *)"-1", 1);
+    }
+  return 0;
+
+/*
   char workchar[CMOR_MAX_STRING]; 
-  int realization, initialization_method, physics_version;
+  int realization, initialization_method, physics_version, forcing;
   int ipos=0, ppos=0;
 
-/* Test for the right member, else abort or warn */ 
+/* Test for the right member, else abort or warn */
+/*
+  
   if ( strlen(kv_member) >= 6 && kv_member[0] == 'r' )
     {
-      crealiz = cinitial = cphysics = (char *) Malloc(strlen(kv_member));
       strcpy(crealiz, &kv_member[1]);
       if ( strtok_r(crealiz, "i", &cinitial) )
         {
@@ -1029,25 +1272,25 @@ static int check_mem(list_t *kvl, char *project_id)
         }
       else cphysics=NULL;
     }
-  else crealiz=cinitial=cphysics=NULL;
+  else {crealiz[0] = '\0'; cinitial[0] = '\0'; cphysics[0] = '\0';};
   if ( realization && initialization_method && physics_version)
     {
       char *ripvaluechar[] = {crealiz, cinitial, cphysics};
       for ( int i = 0; i < 3; i++ )
-        kv_insert_a_val(kvl, (const char *)ripchar[i], ripvaluechar[i], 1);
+        kv_insert_a_val(kvl, ripchar[i], ripvaluechar[i], 1);
       return 1;
     }
   else if ( strcmp(kv_member, "notSet") == 0 )
     {
-      cdoWarning("The member has no RIP format! We set \n Attribute realization=-1 \n Attribute initialization_method=-1 \n Attribute physics_version=-1 \n");
+      cdoPrint("The member has no RIP format! Default setting is used: \n          realization=-1 \n           initialization_method=-1 \n           physics_version=-1. ");
       for ( int i = 0; i < 3; i++ )   
-        kv_insert_a_val(kvl, (const char *)ripchar[i], "-1", 1);
+        kv_insert_a_val(kvl, ripchar[i], (char *)"-1", 1);
     }
-/* Now abort or warn */ 
+/* Now abort or warn */
+/* 
   if (strcmp(project_id, "CMIP5") == 0 || strcmp(project_id, "CORDEX") == 0)
-    cdoAbort("The member has no RIP format (at least 6 characters and in RIP order)! Found for \n member: %s. This is interpreted as \n Realization: %s \n Initialization: %s \n Physics: %s \n   But three Integers are needed", kv_member, crealiz, cinitial, cphysics);
-
-  return 0;
+    cdoAbort("Attribute member has no RIP format (at least 6 characters and in RIP order)! Found for \n          member: %s. This is interpreted as \n           Realization: %s \n           Initialization: %s \n           Physics: %s \n             But three Integers are needed", kv_member, crealiz, cinitial, cphysics);
+*/
 } 
 
 
@@ -1117,7 +1360,7 @@ static void dump_special_attributes(list_t *kvl, int streamID)
 
   if ( historysize )
     {
-      char *history = Malloc(historysize + 1);
+      char *history = (char *)Malloc(historysize + 1);
       memset(history, 0, historysize + 1);
       if ( old_historysize )
         {
@@ -1139,6 +1382,8 @@ static void dump_special_attributes(list_t *kvl, int streamID)
 
 static void read_config_files(list_t *kvl)
 {
+  if ( cdoVerbose )
+    cdoPrint("1. Start to read configuration files.");
   /* Files from info key in command line. */
   keyValues_t *info = kvlist_search(kvl, "i");
   int i = 0;
@@ -1146,19 +1391,26 @@ static void read_config_files(list_t *kvl)
     while ( i < info->nvalues )
       {
         if ( cdoVerbose )
-          printf("Try to parse file: '%s' configured with key 'info'.\n", info->values[i]);
-        parse_kv_file(kvl, info->values[i]);
+          cdoPrint("1.1. Try to parse file: '%s' configured with key 'info'.", info->values[i]);
+        if ( parse_kv_file(kvl, info->values[i]) == 0 )
+          cdoAbort("File '%s' does not exist.", info->values[i]);
+        if ( cdoVerbose )
+          cdoPrint("1.1. Successfully parsed file: '%s' configured with key 'info'.", info->values[i]);
         i++;
       }
 
-  /* Config file in user's $HOME directory. */
-  char *home = getenv("HOME");
+  /* Config file in user's $cwd directory. */
+  char cwd[1024];
+  getcwd(cwd, sizeof(cwd));
   const char *dotconfig = ".cdocmorinfo";
-  char *workfile = Malloc(strlen(home) + strlen(dotconfig) + 2);
-  sprintf(workfile, "%s/%s", home, dotconfig);
+  char *workfile = (char *)Malloc((strlen(cwd) + strlen(dotconfig) + 2 ) * sizeof(char));
+  sprintf(workfile, "%s/%s", cwd, dotconfig);
   if ( cdoVerbose )
-    printf("Try to parse default file: '%s'\n", workfile);
-  parse_kv_file(kvl, workfile);
+    cdoPrint("1.2. Try to parse default file: '%s'.", workfile);
+  if ( parse_kv_file(kvl, workfile) == 0 )
+    cdoWarning("Default file for keyword 'info': '%s' does not exist.", workfile);
+  else if ( cdoVerbose )
+    cdoPrint("1.2. Successfully parsed default file: '%s'.", workfile);
   Free(workfile);
   
   if ( i == 0 )
@@ -1168,11 +1420,16 @@ static void read_config_files(list_t *kvl)
         while ( i < info2->nvalues )
           {
             if ( cdoVerbose )
-              printf("Try to parse file: '%s' configured with key 'info' in file '.cdocmorinfo'.\n", info2->values[i]);
-            parse_kv_file(kvl, info2->values[i]);
+              cdoPrint("1.3. Try to parse file: '%s' configured with key 'info' in file '.cdocmorinfo'.", info2->values[i]);
+            if ( parse_kv_file(kvl, info2->values[i]) == 0 )
+              cdoAbort("File '%s' does not exist.", info2->values[i]);
+            if ( cdoVerbose )
+              cdoPrint("1.3. Successfully parsed file: '%s' configured with key 'info' in file '.cdocmorinfo'.", info2->values[i]);
             i++;
           }
     }
+  if ( cdoVerbose )
+    cdoPrint("1. Successfully read configuration files.");
 }
 
 static int in_list(char **list, const char *needle, int num)
@@ -1185,17 +1442,35 @@ static int in_list(char **list, const char *needle, int num)
 
 static int get_netcdf_file_action(list_t *kvl)
 {
+  char *proj = kv_get_a_val(kvl, "project_id", NULL);
   char *chunk = kv_get_a_val(kvl, "om", "r");
-  if ( chunk[0] == 'r' )
-    return CMOR_REPLACE;
-  else if ( chunk[0] == 'a')
-    return CMOR_APPEND;
-  else if ( chunk[0] == 'p')
-    return CMOR_PRESERVE;
+  if ( strcmp(proj, "CORDEX") == 0 )
+    {
+      if ( chunk[0] == 'r' )
+        return CMOR_REPLACE_4;
+      else if ( chunk[0] == 'a')
+        return CMOR_APPEND_4;
+      else if ( chunk[0] == 'p')
+        return CMOR_PRESERVE_4;
+      else
+        {
+          cdoWarning("You set output_mode = '%s', but valid are 'a' for append ,'r' for replace or 'p' for preserve.\n          CMOR output mode is set to: replace.", chunk);
+          return CMOR_REPLACE;
+        }
+    }
   else
     {
-      cdoWarning("No valid CMOR output mode! \nAttribute output_mode is '%s', but valid are 'a' for append ,'r' for replace or 'p' for preserve.\nCMOR output mode is set to: replace.", chunk);
-      return CMOR_REPLACE;
+      if ( chunk[0] == 'r' )
+        return CMOR_REPLACE;
+      else if ( chunk[0] == 'a')
+        return CMOR_APPEND;
+      else if ( chunk[0] == 'p')
+        return CMOR_PRESERVE;
+      else
+        {
+          cdoWarning("You set output_mode = '%s', but valid are 'a' for append ,'r' for replace or 'p' for preserve.\n          CMOR output mode is set to: replace.", chunk);
+          return CMOR_REPLACE;
+        }
     }
 }
 
@@ -1225,10 +1500,11 @@ static int get_cmor_exit_control(list_t *kvl)
 
 static char *get_calendar_ptr(int calendar)
 {
-  char *calendar_ptr = Malloc(CMOR_MAX_STRING * sizeof(char));
+  char *calendar_ptr = (char *)Malloc(CMOR_MAX_STRING * sizeof(char));
   switch ( calendar )
     {
     case CALENDAR_STANDARD:
+    case CALENDAR_GREGORIAN:
       strcpy(calendar_ptr, "gregorian"); break;
     case CALENDAR_PROLEPTIC:
       strcpy(calendar_ptr, "proleptic_gregorian"); break;
@@ -1260,12 +1536,12 @@ static int get_calendar_int(char *calendar)
     return  CALENDAR_366DAYS;
   else
     {
-      cdoWarning("Calendar type %s is not supported by CMOR.\n", calendar);
+      cdoWarning("You set calendar type = '%s' which is not supported by CMOR.", calendar);
       return 0;
     }
 }
 
-static char *get_txtatt(int vlistID, int varID, char *key)
+static char *get_txtatt(int vlistID, int varID, const char *key)
 {
   int natts;
   cdiInqNatts(vlistID, varID, &natts);
@@ -1278,7 +1554,7 @@ static char *get_txtatt(int vlistID, int varID, char *key)
       cdiInqAtt(vlistID, varID, i, name, &type, &len);
       if ( strcmp(name, key) == 0 )
         {
-          txtatt = Malloc(CMOR_MAX_STRING * sizeof(char));
+          txtatt = (char *)Malloc(CMOR_MAX_STRING * sizeof(char));
           cdiInqAttTxt(vlistID, varID, name, len, txtatt);
           txtatt[len] = '\0';
           return txtatt;
@@ -1287,97 +1563,13 @@ static char *get_txtatt(int vlistID, int varID, char *key)
   return txtatt;
 }
 
-static void setup_dataset(list_t *kvl, int streamID, int *calendar)
-{
-  if ( cdoVerbose )
-    printf("*******Start to process cmor_setup and cmor_dataset.*******\n");
-  int netcdf_file_action = get_netcdf_file_action(kvl);
-  int set_verbosity = get_cmor_verbosity(kvl);
-  int exit_control = get_cmor_exit_control(kvl);
-  int creat_subs = 1;
-  char *drs = kv_get_a_val(kvl, "d", "y");
-  if ( drs[0] == 'n' )
-    creat_subs = 0;
-  else if ( drs[0] != 'y' )
-    {
-      cdoWarning("Unknown value for keyword 'drs' is found: '%s'.\nAllowed are: 'n' or 'y'. DRS is set to 'y'.", drs);
-      kv_insert_a_val(kvl, "d", "y", 1);
-    }
-
-  int vlistID = pstreamInqVlist(streamID);
-
-  cmor_setup(kv_get_a_val(kvl, "inpath", "/usr/share/cmor/"),
-             &netcdf_file_action,
-             &set_verbosity,
-             &exit_control,
-             kv_get_a_val(kvl, "logfile", NULL),
-             &creat_subs);
-
-  int taxisID = vlistInqTaxis(pstreamInqVlist(streamID));
-
-/*
-  char *attcomment = kv_get_a_val(kvl, "comment", NULL);
-  char *comment = get_txtatt(vlistID, CDI_GLOBAL, "comment");
-*/
-  
-  char *attcalendar = kv_get_a_val(kvl, "calendar", NULL);
-  char *calendarptr = get_calendar_ptr(taxisInqCalendar(taxisID));
-  if ( cdoVerbose )
-    printf("Checking attribute 'calendar' from configuration.\n");
-  if ( *calendar = get_calendar_int(attcalendar) )
-    check_compare_set(&calendarptr, attcalendar, "calendar", NULL);
-  else 
-    {
-      if ( cdoVerbose )
-        printf("Try to use Ifile calendar.\n");
-      if ( !get_calendar_int(calendarptr) )
-        cdoAbort("No valid configuration and no valid Ifile calendar found.");
-      else
-        *calendar = get_calendar_int(calendarptr);
-    }
-
-#if defined(CMOR_VERSION_MAJOR)
-  int cmor_version_exists = 1;
-  if ( CMOR_VERSION_MAJOR == 2 && CMOR_VERSION_MINOR == 9 )
-    {
-      double branch_time = atof(kv_get_a_val(kvl, "branch_time", "0.0"));
-      cmor_dataset(kv_get_a_val(kvl, "dr", "./"),
-               kv_get_a_val(kvl, "experiment_id", ""),
-               kv_get_a_val(kvl, "institution", ""),
-               kv_get_a_val(kvl, "source", ""),
-               calendarptr,
-               atoi(kv_get_a_val(kvl, "realization", "")),
-               kv_get_a_val(kvl, "contact", ""),
-               kv_get_a_val(kvl, "history", ""),
-/* comment:*/
-               kv_get_a_val(kvl, "comment", ""),
-               kv_get_a_val(kvl, "references", ""),
-               atoi(kv_get_a_val(kvl, "leap_year", "")),
-               atoi(kv_get_a_val(kvl, "leap_month", "")),
-               NULL,
-               kv_get_a_val(kvl, "model_id", ""),
-               kv_get_a_val(kvl, "forcing", ""),
-               atoi(kv_get_a_val(kvl, "initialization_method", "")),
-               atoi(kv_get_a_val(kvl, "physics_version", "")),
-               kv_get_a_val(kvl, "institute_id", ""),
-               kv_get_a_val(kvl, "parent_experiment_id", ""),
-               &branch_time,
-               kv_get_a_val(kvl, "parent_experiment_rip", ""));
-    }
-  else
-    cdoAbort("Cmor version %d.%d not yet enabled!\n", (int) CMOR_VERSION_MAJOR, (int) CMOR_VERSION_MINOR);
-#endif
-  if ( !cmor_version_exists )
-    cdoAbort("It is not clear which CMOR version is installed since\nMakros CMOR_VERSION_MAJOR and CMOR_VERSION_MINOR are not available.\n");
-  Free(calendarptr);
-  if ( cdoVerbose )
-    printf("*******Setup finished successfully.*******\n");
-}
-
+/***********************************************/
+/*Time related functions************************/
+/***********************************************/
 
 static char *get_time_units(int taxisID)
 {
-  char *units = Malloc ( CMOR_MAX_STRING * sizeof(char) );
+  char *units = (char *)Malloc ( CMOR_MAX_STRING * sizeof(char) );
   int timeunit = taxisInqTunit(taxisID);
   int year, month, day, hour, minute, second;
   cdiDecodeDate(taxisInqRdate(taxisID), &year, &month, &day);
@@ -1388,7 +1580,7 @@ static char *get_time_units(int taxisID)
        timeunit == TUNIT_12HOURS )
     timeunit = TUNIT_HOUR;
 
-  sprintf(units, "%s since %d-%d-%d %02d:%02d:%02d", tunitNamePtr(timeunit),
+  sprintf(units, "%s since %d-%d-%d %02d:%02d:%02d\0", tunitNamePtr(timeunit),
           year, month, day, hour, minute, second);
   return units;
 }
@@ -1405,7 +1597,7 @@ static int get_time_step_int(char *time_step)
     return TUNIT_YEAR;
   else
     {
-      cdoWarning("Timeunit %s not yet implemented in cmor.\n", time_step);
+      cdoWarning("You set required_time_units = '%s since...'.\n          This time step is not yet implemented in cmor.", time_step);
       return 0;
     }
 }
@@ -1419,7 +1611,7 @@ static int check_time_units(char *time_units)
                   time_step, &attyear, &attmonth, &attday, &atthour,
                   &attminute, &attsecond) != 7)
     {
-      cdoWarning("Could not read all 7 required time unit values.");
+      cdoWarning("You set required_time_units = '%s'\n          but it requires the form 'timestep since year-month-day hour:minute:second.\n          Could not read all 7 required time unit values.", time_units);
       return 0;
     }
   if ( !get_time_step_int(time_step) )
@@ -1427,6 +1619,37 @@ static int check_time_units(char *time_units)
   return 1;
 }
 
+static void get_time_method(list_t *kvl, int vlistID, int varID, char *cmor_time_name, char *project_id, int miptab_freq, int *time_axis)
+{
+  if ( ( strcmp(project_id, "CMIP5") == 0 || strcmp(project_id, "CMIP6") == 0 ) && miptab_freq )
+    switch ( miptab_freq )
+      {
+      case 1: strcpy(cmor_time_name, "time2"); *time_axis=2; break;
+      case 2: strcpy(cmor_time_name, "time"); *time_axis=0; break;
+      case 4: strcpy(cmor_time_name, "time"); *time_axis=0; break;
+      case 5: strcpy(cmor_time_name, "time1"); *time_axis=1; break;
+      case 6: strcpy(cmor_time_name, "time1"); *time_axis=1; break;
+      case 7: strcpy(cmor_time_name, "time3"); *time_axis=3; break;
+      }
+  if ( cmor_time_name[0] != 't' )
+    {
+      char *time_method = get_txtatt(vlistID, varID, "cell_methods");
+      char *att_time_method = kv_get_a_val(kvl, "cm", NULL);
+      check_compare_set(&time_method, att_time_method, "cell_methods", " ");
+      if ( time_method[0] == 'm' )      { strcpy(cmor_time_name, "time \0"); *time_axis=0; }
+      else if ( time_method[0] == 'p' ) { strcpy(cmor_time_name, "time1\0"); *time_axis=1; }
+      else if ( time_method[0] == 'c' ) { strcpy(cmor_time_name, "time2\0"); *time_axis=2; }
+      else if ( time_method[0] == 'd' ) { strcpy(cmor_time_name, "time3\0"); *time_axis=3; }
+      else if ( time_method[0] == 'n' ) { strcpy(cmor_time_name, "none\0"); *time_axis=4; }
+      else
+        {
+          cdoWarning("You set cell method = '%s' which is not valid. Check CF-conventions for allowed time cell methods.\n          Time cell method is set to 'mean'. ", time_method);
+          strcpy(cmor_time_name, "time \0");
+        }
+      Free(time_method);
+    }
+}
+
 static void get_taxis(char *required_time_units, int *sdate, int *stime, int *timeunit)
 {
   int attyear, attmonth, attday, atthour, attminute, attsecond;
@@ -1440,35 +1663,304 @@ static void get_taxis(char *required_time_units, int *sdate, int *stime, int *ti
   *timeunit = get_time_step_int(atttimeunit);
 }
 
-static void get_time_method(list_t *kvl, int vlistID, int varID, char *cmor_time_name, char *project_id, int miptab_freq, int *time_axis)
+static double *get_branch_times(list_t *kvl, int calendar, char *time_units)
 {
-  if (strcmp(project_id, "CMIP5") == 0 && miptab_freq )
-    switch ( miptab_freq )
+  if ( cdoVerbose )
+    cdoPrint("6.1.3. Start to compute attribute 'branch_time'.");
+  double *branch_time = (double *)Malloc(2 * sizeof(double));
+  branch_time[0] = 0.0;
+  branch_time[1] = 0.0;
+
+  int numdates;
+  char **branch_times_p = kv_get_vals(kvl, "branch_times", &numdates);
+
+  if ( numdates == 2 && kv_get_a_val(kvl, "parent_experiment_id", NULL) )
+    {
+      int parentdates[2], parentyears[2], parentmonths[2], parentdays[2], parentvdates[2], parentvtimes[2];
+      juldate_t parentstartdate, parentbranchdate, childstartdate ;
+      for ( int i = 0; i < 2; i++ )
+        {
+          parentdates[i]  = atol(branch_times_p[i]);
+          parentyears[i]  =  parentdates[i]/100/100;
+          parentmonths[i] = (parentdates[i] - parentyears[i]*100*100)/100;
+          parentdays[i]   =  parentdates[i] - parentyears[i]*100*100 - parentmonths[i]*100;
+          parentvdates[i] = cdiEncodeDate(parentyears[i], parentmonths[i], parentdays[i]);
+          parentvtimes[i] = 0;
+        }
+      parentstartdate   = juldate_encode(calendar, parentvdates[0], parentvtimes[0]);
+      parentbranchdate  = juldate_encode(calendar, parentvdates[1], parentvtimes[1]);
+
+      int childsdate, childstime, childtimeunit;
+      get_taxis(time_units, &childsdate, &childstime, &childtimeunit);
+      childstartdate    = juldate_encode(calendar, childsdate, childstime);
+
+/* If time unit is always "days since.." */
+      branch_time[0] = juldate_to_seconds(juldate_sub(parentbranchdate, parentstartdate)) / 86400;
+      branch_time[1] = juldate_to_seconds(juldate_sub(parentbranchdate, childstartdate)) / 86400;
+    }
+  if ( cdoVerbose )
+    cdoPrint("6.1.3. Successfully computed 'branch_time': '%f', '%f'.", branch_time[0], branch_time[1]);
+  return branch_time;
+}
+
+static char *check_required_time_units(list_t *kvl, int taxisID)
+{
+  if ( cdoVerbose )
+    cdoPrint("6.1.2. Start to check attribute 'required_time_units'.");
+  char *time_units = get_time_units(taxisID);
+  char *required_time_units = kv_get_a_val(kvl, "required_time_units", NULL);
+  if ( check_time_units(required_time_units) )
+    check_compare_set(&time_units, required_time_units, "time_units", NULL);
+  else 
+    cdoAbort("Required Attribute 'required_time_units' from configuration is invalid!");
+  kv_insert_a_val(kvl, "required_time_units", time_units, 1);
+  if ( cdoVerbose )
+    cdoPrint("6.1.2. Successfully checked attribute 'required_time_units'.");
+  return time_units;
+}
+
+static char *check_calendar(list_t *kvl, int taxisID, int *calendar)
+{ 
+  if ( cdoVerbose )
+    cdoPrint("6.1.1. Start to check attribute 'calendar'.");
+  char *attcalendar = kv_get_a_val(kvl, "calendar", NULL);
+  char *calendarptr = get_calendar_ptr(taxisInqCalendar(taxisID));
+  if ( *calendar = get_calendar_int(attcalendar) )
+    check_compare_set(&calendarptr, attcalendar, "calendar", NULL);
+  else 
+    {
+      if ( cdoVerbose )
+        cdoPrint("Try to use infile calendar.");
+      if ( !get_calendar_int(calendarptr) )
+        cdoAbort("In validating calendar:\n          No valid configuration calendar and no valid infile calendar found.");
+      else
+        *calendar = get_calendar_int(calendarptr);
+    }
+  if ( cdoVerbose )
+    cdoPrint("6.1.1. Successfully checked attribute 'calendar'.");
+  return calendarptr;
+}
+
+/*********/
+/* main: */
+/*********/
+
+static void setup_dataset(list_t *kvl, int streamID, int *calendar)
+{
+  if ( cdoVerbose )
+    cdoPrint("6. Start to process cmor_setup and cmor_dataset.");
+  int netcdf_file_action = get_netcdf_file_action(kvl);
+  int set_verbosity = get_cmor_verbosity(kvl);
+  int exit_control = get_cmor_exit_control(kvl);
+  int creat_subs = 1;
+  char *drs = kv_get_a_val(kvl, "d", "y");
+  if ( drs[0] == 'n' )
+    creat_subs = 0;
+  else if ( drs[0] != 'y' )
+    {
+      cdoWarning("In preparing cmor_setup:\n          You set 'd' = '%s' which is not valid.\n          Allowed are: 'n' or 'y'. d is set to 'y'.", drs);
+      kv_insert_a_val(kvl, "d", (char *)"y", 1);
+    }
+
+  int vlistID = pstreamInqVlist(streamID);
+
+  int cmf = cmor_setup(kv_get_a_val(kvl, "inpath", "/usr/share/cmor/"),
+             &netcdf_file_action,
+             &set_verbosity,
+             &exit_control,
+             kv_get_a_val(kvl, "logfile", NULL),
+             &creat_subs);
+  if ( cmf != 0 )
+    cdoAbort("Function cmor_setup failed!");
+
+  int taxisID = vlistInqTaxis(vlistID);
+
+/*
+  char *attcomment = kv_get_a_val(kvl, "comment", NULL);
+  char *comment = get_txtatt(vlistID, CDI_GLOBAL, "comment");
+*/
+
+/* First compare file calendar and config calendar and retrieve pointer and integer
+   Then check the required time units from config and retrieve
+   Then compute branch_time_in_parent and branch_time_in_child */
+
+  if ( cdoVerbose )
+    cdoPrint("6.1. Start to check model calendar as well as 'required_time_units' and 'branch_times' attributes.");
+  char *calendarptr = check_calendar(kvl, taxisID, calendar);  
+  char *time_units = check_required_time_units(kvl, taxisID);
+  double *branch_times = get_branch_times(kvl, *calendar, time_units); 
+  if ( cdoVerbose )
+    cdoPrint("6.1. Successfully found valid calendar, 'required_time_units' and 'branch_times'.");
+#if defined(CMOR_VERSION_MAJOR)
+#if ( CMOR_VERSION_MAJOR == 2 )
+    {
+      cmf = cmor_dataset(kv_get_a_val(kvl, "dr", "./"),
+               kv_get_a_val(kvl, "experiment_id", ""),
+               kv_get_a_val(kvl, "institution", ""),
+               kv_get_a_val(kvl, "source", ""),
+               calendarptr,
+               atoi(kv_get_a_val(kvl, "realization", "")),
+               kv_get_a_val(kvl, "contact", ""),
+               kv_get_a_val(kvl, "history", ""),
+               kv_get_a_val(kvl, "comment", ""),
+               kv_get_a_val(kvl, "references", ""),
+               atoi(kv_get_a_val(kvl, "leap_year", "")),
+               atoi(kv_get_a_val(kvl, "leap_month", "")),
+               NULL,
+               kv_get_a_val(kvl, "model_id", ""),
+               kv_get_a_val(kvl, "forcing", ""),
+               atoi(kv_get_a_val(kvl, "initialization_method", "")),
+               atoi(kv_get_a_val(kvl, "physics_version", "")),
+               kv_get_a_val(kvl, "institute_id", ""),
+               kv_get_a_val(kvl, "parent_experiment_id", ""),
+               &(branch_times[0]),
+               kv_get_a_val(kvl, "parent_experiment_rip", ""));
+      if ( cmf != 0 )
+        cdoAbort("Function cmor_dataset failed!");
+    }
+  const char *allneeded2[] = {"cordex_domain",  "driving_experiment", "driving_model_id", "driving_model_ensemble_member", "driving_experiment_name", "rcm_version_id", NULL};
+  int ind = 0;
+  if ( strcmp(kv_get_a_val(kvl, "project_id", NULL),"CORDEX") == 0 )
+    while ( allneeded2[ind] )
       {
-      case 1: strcpy(cmor_time_name, "time2"); break;
-      case 2: strcpy(cmor_time_name, "time"); break;
-      case 4: strcpy(cmor_time_name, "time"); break;
-      case 5: strcpy(cmor_time_name, "time1"); break;
-      case 6: strcpy(cmor_time_name, "time1"); break;
+        char *tmp = kv_get_a_val(kvl, allneeded2[ind], NULL );
+        if ( tmp )
+          cmf = cmor_set_cur_dataset_attribute((char *)allneeded2[ind], tmp, 1);
+        if ( cmf != 0 )
+          cdoAbort("Function cmor_set_cur_dataset_attribute failed!");
+        ind++;
       }
-  if ( cmor_time_name[0] != 't' )
+#elif ( CMOR_VERSION_MAJOR == 3 )
     {
-      char *time_method = get_txtatt(vlistID, varID, "cell_methods");
-      char *att_time_method = kv_get_a_val(kvl, "cm", NULL);
-      check_compare_set(&time_method, att_time_method, "cell_methods", " ");
-      if ( time_method[0] == 'm' )      { strcpy(cmor_time_name, "time \0"); *time_axis=0; }
-      else if ( time_method[0] == 'p' ) { strcpy(cmor_time_name, "time1\0"); *time_axis=1; }
-      else if ( time_method[0] == 'c' ) { strcpy(cmor_time_name, "time2\0"); *time_axis=2; }
-      else if ( time_method[0] == 'n' ) { strcpy(cmor_time_name, "none\0"); *time_axis=3; }
-      else
+/***/
+/* Could not give CMOR all attributes separately because some are required to be in a json file (outpath,...). /
+/* Better collect them in this file. */
+/* todo this **/
+/* If a Json file is denoted, read this file and check attributes */
+/***/
+
+/*
+      char *filename = kv_get_a_val(kvl, "dj", NULL); */
+
+      char cwd[1024];
+      getcwd(cwd, sizeof(cwd));
+      char *dataset_path = (char *) Malloc( (strlen(cwd) + 1 + strlen("dataset.json") + 3) * sizeof(char));;
+      FILE *dataset_json;
+      int procID = getpid();
+
+      sprintf(dataset_path, "%s/dataset%d.json\0", cwd,procID);
+
+      dataset_json = fopen(dataset_path, "w+");
+      if ( !dataset_json )
+        cdoAbort("In preparing cmor_dataset:\n          Could not open a dataset file '%s' for cmor_dataset.", dataset_path);
+      fputs("{\n", dataset_json);
+
+      const char *allneeded[] = /*CMIP5*/{"project_id", "experiment_id", "institution", "source", "realization", "contact", "history", "comment", "references", "leap_year", "leap_month", "source_id", "model_id", "forcing", "initialization_method", "modeling_realm", "physics_version", "institute_id", "parent_experiment_rip", 
+/*CORDEX */
+  "CORDEX_domain",  "driving_experiment", "driving_model_id", "driving_model_ensemble_member", "driving_experiment_name", "rcm_version_id",
+/* CMIP6: */
+  /* Glob Atts */
+"_cmip6_option", "Conventions", "activity_id", "branch_method", "experiment", "experiment_id", "forcing_index", "further_info_url", "grid", "grid_label", "initialization_index", "institution", "institution_id", "license", "mip_era", "nominal_resolution", "physics_index", "product", "realization_index", "source", "source_id", "source_type", "sub_experiment", "sub_experiment_id", "table_id", "variant_label", "parent_experiment_id", "parent_activity_id", "parent_mip_era", "parent_source_id" [...]
+"parent_time_units", NULL};
+      int i = 0;
+
+      while ( allneeded[i] )
         {
-          cdoWarning("Found configuration time cell method '%s' is not valid. Check CF-conventions for allowed time cell methods.\nTime cell method is set to 'mean'. \n", time_method);
-          strcpy(cmor_time_name, "time \0");
+          char *tmp = kv_get_a_val(kvl, allneeded[i], "notSet");
+          if ( strncmp(tmp, "notSet", 6) != 0 )
+            {
+                  int linelen = strlen(allneeded[i]) + strlen(tmp) + 10;
+                  char line[linelen];
+                  sprintf(line, "\"%s\" : \"%s\",\n", allneeded[i], tmp);
+                  fputs((const char *) line, dataset_json);
+            }
+          i++;
         }
-      Free(time_method);
+
+/*      char *miptabfreq = kv_get_a_val(kvl, "miptab_freq", NULL);
+      char *freq = (char *) Malloc(11 * sizeof(char));
+      if ( strstr(miptabfreq, "yr") || strstr(miptabfreq, "Yr") )
+        strcpy(freq, "yr");
+      else if ( strstr(miptabfreq, "mon") || strstr(miptabfreq, "Mon") )
+        {
+          strcpy(freq, "mon");
+          if ( strstr(miptabfreq, "ClimMon") )
+            strcpy(freq, "ClimMon");
+        }
+      else if ( strstr(miptabfreq, "day") || strstr(miptabfreq, "Day") )
+        strcpy(freq, "day");
+      else if ( strstr(miptabfreq, "6hr") )
+        strcpy(freq, "6hr");
+      else if ( strstr(miptabfreq, "3hr") )
+        strcpy(freq, "3hr");
+      else if ( strstr(miptabfreq, "1hr") )
+        {
+          strcpy(freq, "1hr");
+          if ( strstr(miptabfreq, "1hrClimMon") )
+            strcpy(freq, "1hrClimMon");
+        }
+      else if ( strstr(miptabfreq, "fx") )
+        strcpy(freq, "fx"); */
+
+      char *branch_time_in_parent = (char *) Malloc(2*sizeof(double));
+      char *branch_time_in_child = (char *) Malloc(2*sizeof(double));
+      snprintf(branch_time_in_parent, sizeof(double), "%.12f", branch_times[0]);
+      snprintf(branch_time_in_child, sizeof(double), "%.12f", branch_times[1]);
+
+  /* CMOR internal */ 
+          fputs("\"outpath\" : \"", dataset_json);
+          fputs(kv_get_a_val(kvl, "dr", "./"), dataset_json);
+          fputs("\",\n", dataset_json); 
+          fputs("\"output_path_template\" : \"", dataset_json);
+          fputs(kv_get_a_val(kvl, "output_path_template", "<mip_era><activity_id><institution_id><source_id><experiment_id><variant_label><table><variable_id><grid_label><version>"), dataset_json);
+          fputs("\",\n", dataset_json); 
+          fputs("\"output_file_template\" : \"", dataset_json);
+          fputs(kv_get_a_val(kvl, "output_file_template", "<variable_id><table><source_id><experiment_id><variant_label><grid_label>"), dataset_json);
+          fputs("\",\n", dataset_json); 
+          fputs("\"tracking_prefix\" : \"", dataset_json);
+          fputs(kv_get_a_val(kvl, "tracking_prefix", "hdl:21.14100"), dataset_json);
+          fputs("\",\n", dataset_json); 
+/*          fputs("\"frequency\" : \"", dataset_json);
+          fputs(freq, dataset_json);
+          fputs("\",\n", dataset_json);  */
+
+/* cdo cmor preprocessed: */
+          fputs("\"calendar\" : \"", dataset_json);
+          fputs(calendarptr, dataset_json);
+          fputs("\",\n", dataset_json); 
+          fputs("\"branch_time_in_parent\" : \"", dataset_json);
+          fputs(branch_time_in_parent, dataset_json);
+          fputs("\",\n", dataset_json);
+          fputs("\"branch_time_in_child\" : \"", dataset_json);
+          fputs(branch_time_in_child, dataset_json);
+          fputs("\",\n", dataset_json); 
+
+          fputs("}\n", dataset_json);
+          fclose(dataset_json);
+          cmf = cmor_dataset_json(dataset_path);
+          if ( cmf != 0 )
+            cdoAbort("Function cmor_dataset_json failed!");
+          Free(dataset_path);
+
+
+      Free(branch_time_in_parent);
+      Free(branch_time_in_child);
+/*      Free(freq); */
     }
+#else
+    cdoAbort("Cmor version %d not yet enabled!", (int) CMOR_VERSION_MAJOR);
+#endif
+#else
+    cdoAbort("It is not clear which CMOR version is installed since\n          Makros CMOR_VERSION_MAJOR and CMOR_VERSION_MINOR are not available.");
+#endif
+  Free(calendarptr);
+  Free(branch_times);
+  Free(time_units);
+  if ( cdoVerbose )
+    cdoPrint("6. Successfully finished cmor_setup and cmor_dataset.");
 }
 
+
 static void gen_bounds(int n, double *vals, double *bounds)
 {
   for ( int i = 0; i < n-1; ++i )
@@ -1484,10 +1976,10 @@ static void gen_bounds(int n, double *vals, double *bounds)
 static void get_zcell_bounds(int zaxisID, double *zcell_bounds, double *levels, int zsize)
 {
   double *lbounds;
-  lbounds = Malloc(zsize * sizeof(double));
+  lbounds = (double *)Malloc(zsize * sizeof(double));
   zaxisInqLbounds(zaxisID, lbounds);
   double *ubounds;
-  ubounds = Malloc(zsize * sizeof(double));
+  ubounds = (double *)Malloc(zsize * sizeof(double));
   zaxisInqUbounds(zaxisID, ubounds);
   if ( !lbounds || !ubounds || pow((ubounds[1] - ubounds[0]),2) < 0.001 || pow((lbounds[1] - lbounds[0]), 2) < 0.001 )
     gen_bounds(zsize, levels, zcell_bounds);
@@ -1515,7 +2007,7 @@ static void get_zhybrid(int zaxisID, double *p0, double *alev_val, double *alev_
 {
   int zsize = zaxisInqSize(zaxisID);
   int vctsize = zaxisInqVctSize(zaxisID);
-  double *vct = Malloc(vctsize * sizeof(double) );
+  double *vct = (double *)Malloc(vctsize * sizeof(double) );
   zaxisInqVct(zaxisID, vct);
   for ( int i = 0; i<(zsize+1); i++)
     {
@@ -1544,7 +2036,9 @@ static int get_strmaxlen(char **array, int len)
 
 static void register_z_axis(list_t *kvl, int vlistID, int varID, int zaxisID, char *varname, int *axis_ids, int *zfactor_id, char *project_id, int miptab_freq)
 {
+
   *zfactor_id = 0;
+  int cmf = 0;
   int zsize = zaxisInqSize(zaxisID);
   double *levels;
 
@@ -1554,16 +2048,16 @@ static void register_z_axis(list_t *kvl, int vlistID, int varID, int zaxisID, ch
   if ( strcmp(chardim, "vegtype") == 0 || strcmp(chardim, "oline") == 0  )
     {
       if ( zsize )
-        cdoWarning("You configured a character coordinate '%s' but a zaxis is found with '%d' numerical values. The zaxis attributes are ignored and the '%d' levels are interpreted as the character coordinates in the order they are given for '%s'.", chardim, zsize, zsize, varname);
+        cdoPrint("In Z-axis registration:\n          You configured a character coordinate '%s' but a zaxis is found with '%d' numerical values. The zaxis attributes are ignored and the '%d' levels are interpreted as the character coordinates in the order they are given for '%s'.", chardim, zsize, zsize, varname);
       int numchar = 0;
-      char *charvalstring = Malloc(CMOR_MAX_STRING * sizeof(char));
+      char *charvalstring = (char *) Malloc(CMOR_MAX_STRING * sizeof(char));
       sprintf(charvalstring, "char_axis_%s", chardim);
       char **charvals = kv_get_vals(kvl, charvalstring, &numchar);
       Free(charvalstring);
       if ( charvals )
         {
           int maxlen = get_strmaxlen(charvals, numchar);
-          void *charcmor = (void *) Malloc ( numchar * maxlen * sizeof(char));
+          void *charcmor = (void *) Malloc ( (numchar * maxlen + 1) * sizeof(char));
           sprintf((char *)charcmor, "%s", charvals[0]);
           char blanks[maxlen];
           for ( int i = 0; i < maxlen; i++)
@@ -1575,116 +2069,149 @@ static void register_z_axis(list_t *kvl, int vlistID, int varID, int zaxisID, ch
               sprintf((char *)charcmor, "%s%.*s", (char *)charcmor, maxlen-strlen(charvals[i]), blanks);         
             }
           if ( numchar == zsize )
-            cmor_axis(new_axis_id(axis_ids), chardim, "", numchar, (void *)charcmor, 'c',  NULL, maxlen, NULL); 
+            cmf = cmor_axis(new_axis_id(axis_ids), chardim, (char *)"", numchar, (void *)charcmor, 'c',  NULL, maxlen, NULL); 
           else
-            cdoAbort("The number of registered character coordinates differ from the number of axis levels.");
+            cdoAbort("In registration of a character coordinate as a substitution for a vertical coordinate:\n          The number of registered character coordinates '%d' differ from the number of axis levels '%d'.", numchar, zsize);
+          if ( cmf != 0 )
+            cdoAbort("Function cmor_axis failed!");
           Free(charcmor);
         }
       else
-        cdoAbort("You configured a character coordinate '%s' but no values are found! Configure values via attribute 'char_dim_vals'!", chardim);
-      Free(chardim);
+        cdoAbort("In registration of a character coordinate as a substitution for a vertical coordinate:\n          You configured a character coordinate '%s' but no values are found! Configure values via attribute 'char_dim_vals'.", chardim);
     }
   else
   {
   if ( zsize > 1)
     {
-      levels = Malloc(zsize * sizeof(double));
+      levels = (double *)Malloc(zsize * sizeof(double));
       zaxisInqLevels(zaxisID, levels);
       double *zcell_bounds;
-      zcell_bounds = Malloc( 2*zsize * sizeof(double) );
+      zcell_bounds = (double *)Malloc( 2*zsize * sizeof(double) );
       get_zcell_bounds(zaxisID, zcell_bounds, levels, zsize);
       if ( zaxisInqType(zaxisID) == ZAXIS_PRESSURE )
         {
-          if ( strcmp(project_id, "CMIP5") != 0 )
-            cmor_axis(new_axis_id(axis_ids),
-                        "plevs",
-                        "Pa",
+          char *zaxis = get_txtatt(vlistID, varID, "z_axis");
+          char *attzaxis = kv_get_a_val(kvl, "za", NULL);
+          check_compare_set(&zaxis, attzaxis, "z_axis", "notSet");
+
+          if ( strcmp(zaxis, "notSet") != 0 )
+            cmf = cmor_axis(new_axis_id(axis_ids),
+                        zaxis,
+                        (char *) "Pa",
+                        zsize,
+                        (void *)levels,
+                        'd', NULL, 0, NULL);
+          else if ( strcmp(project_id, "CMIP5") != 0 && strcmp(project_id, "CMIP6") != 0 )
+            cmf = cmor_axis(new_axis_id(axis_ids),
+                        (char *)"plevs",
+                        (char *)"Pa",
                         zsize,
                         (void *)levels,
                         'd', NULL, 0, NULL);
           else
-            {  
-              switch ( miptab_freq )
+            {
+              if ( strcmp(project_id, "CMIP6") == 0 )
                 {
-                case 3: cmor_axis(new_axis_id(axis_ids),
-                        "plev7",
-                        "Pa",
+                  switch ( miptab_freq )
+                    {
+                    case 12: cmf = cmor_axis(new_axis_id(axis_ids),
+                        (char *) "plev19",
+                        (char *) "Pa",
                         zsize,
                         (void *)levels,
                         'd', NULL, 0, NULL); break;
-                case 4: cmor_axis(new_axis_id(axis_ids),
-                        "plev8",
-                        "Pa",
+                    case 4: cmf = cmor_axis(new_axis_id(axis_ids),
+                        (char *) "plev8",
+                        (char *) "Pa",
                         zsize,
                         (void *)levels,
                         'd', NULL, 0, NULL); break;
-                case 5: cmor_axis(new_axis_id(axis_ids),
-                        "plev3",
-                        "Pa",
+                    default: cmf = cmor_axis(new_axis_id(axis_ids),
+                        (char *) "plevs",
+                        (char *) "Pa",
                         zsize,
                         (void *)levels,
                         'd', NULL, 0, NULL); break;
-                default: cmor_axis(new_axis_id(axis_ids),
-                        "plevs",
-                        "Pa",
+                    }
+                }
+              else
+                {
+                  switch ( miptab_freq )
+                    {
+                    case 3: cmf = cmor_axis(new_axis_id(axis_ids),
+                        (char *) "plev7",
+                        (char *) "Pa",
                         zsize,
                         (void *)levels,
                         'd', NULL, 0, NULL); break;
-                }                
+                    case 4: cmf = cmor_axis(new_axis_id(axis_ids),
+                        (char *) "plev8",
+                        (char *) "Pa",
+                        zsize,
+                        (void *)levels,
+                        'd', NULL, 0, NULL); break;
+                    case 5: cmf = cmor_axis(new_axis_id(axis_ids),
+                        (char *) "plev3",
+                        (char *) "Pa",
+                        zsize,
+                        (void *)levels,
+                        'd', NULL, 0, NULL); break;
+                    default: cmf = cmor_axis(new_axis_id(axis_ids),
+                        (char *) "plevs",
+                        (char *) "Pa",
+                        zsize,
+                        (void *)levels,
+                        'd', NULL, 0, NULL); break;
+                    }         
+                }       
             }
+          if ( zaxis ) Free(zaxis);
         }
       else if ( zaxisInqType(zaxisID) == ZAXIS_HYBRID )
         {
-          double *alev_val = Malloc(zsize * sizeof(double));
-          double *alev_bnds = Malloc((zsize + 1) * sizeof(double));
-          double *ap_val = Malloc(zsize * sizeof(double));
-          double *ap_bnds = Malloc((zsize + 1) * sizeof(double));
-          double *b_val = Malloc(zsize * sizeof(double));
-          double *b_bnds = Malloc((zsize + 1) * sizeof(double));
-          double *p0 = Malloc(sizeof(double));
+          double *alev_val = (double *) Malloc(zsize * sizeof(double));
+          double *alev_bnds = (double *) Malloc((zsize + 1) * sizeof(double));
+          double *ap_val = (double *) Malloc(zsize * sizeof(double));
+          double *ap_bnds = (double *) Malloc((zsize + 1) * sizeof(double));
+          double *b_val = (double *) Malloc(zsize * sizeof(double));
+          double *b_bnds = (double *) Malloc((zsize + 1) * sizeof(double));
+          double *p0 = (double *) Malloc(sizeof(double));
           p0[0] = 101325.0;
 
           char *mtproof = kv_get_a_val(kvl, "mtproof", NULL);
           if ( mtproof )
             {
               if ( cdoVerbose )
-                printf("Try to apply mapping table: '%s' for ps.\n", mtproof);
-              list_t *pml = cdo_parse_cmor_file(mtproof);
-              if ( pml == NULL )
-                cdoWarning("Mapping table: '%s' could not be parsed. Infile variable name needs to be 'ps'.", mtproof);
-              else
-                {
-                  char *tempo[] = {"ps"};
-                  maptab_via_cn(pml, tempo, vlistID, vlistNvars(vlistID), 1, kv_get_a_val(kvl, "miptab_freq", NULL)); 
-                  if ( cdoVerbose )
-                    printf("*******Succesfully applied mapping table: '%s' for ps.*******\n", mtproof);
-                  list_destroy(pml);
-                }
+                cdoPrint("Mapping table: '%s' is applied for ps.", mtproof);
+              kv_insert_a_val(kvl, "workfile4err", mtproof, 1);
+              list_t *pml = cdo_parse_cmor_file(mtproof, kvl);
+              const char *tempo[] = {"ps"};
+              maptab_via_cn(pml, (char **)tempo, vlistID, vlistNvars(vlistID), 1, kv_get_a_val(kvl, "miptab_freq", NULL),  FILETYPE_NC ); 
+              list_destroy(pml);
             }
           else
             {
-              if ( cdoVerbose )
-                printf("Ps needs to be one infile variable name.");
+              cdoPrint("Ps needs to be one infile variable name.");
             }
           int psID = getVarIDToMap(vlistID, vlistNvars(vlistID), "name", "ps");
           if ( psID == CDI_UNDEFID )
-            cdoAbort("Could not find a surface pressure variable in infile. Cannot register a hybrid zaxis without surface pressure.");
+            cdoAbort("In registration of a vertical axis:\n          Could not find a surface pressure variable in infile. Cannot register a hybrid zaxis without surface pressure.");
 
           get_zhybrid(zaxisID, p0, alev_val, alev_bnds, b_val, b_bnds, ap_val, ap_bnds);
 /*cmor_zfactor (int *zfactor_id,int zaxis_id, char *zfactor_name, char *units, int ndims, int axis_ids[], char type, void *zfactor_values, void *zfactor_bounds)*/
-          cmor_axis(new_axis_id(axis_ids),
-                        "alternate_hybrid_sigma",
-                        "",
+          cmf = cmor_axis(new_axis_id(axis_ids),
+                        (char *) "alternate_hybrid_sigma",
+                        (char *) "",
                         zsize,
                         (void *)alev_val,
                         'd', alev_bnds,  1, NULL);
           int lev_id = axis_ids[count_axis_ids(axis_ids)-1];
           int lev_id_array[2];
           lev_id_array[0] = lev_id;
-          cmor_zfactor(zfactor_id, lev_id, "p0", "Pa", 0, 0, 'd', (void *)p0, NULL);
-          cmor_zfactor(zfactor_id, lev_id, "b", "", 1, &lev_id_array[0], 'd', (void *)b_val, (void *)b_bnds);
-          cmor_zfactor(zfactor_id, lev_id, "ap", "Pa", 1, &lev_id_array[0], 'd', (void *)ap_val, (void *)ap_bnds);
-          cmor_zfactor(zfactor_id, lev_id, "ps", "Pa", count_axis_ids(axis_ids)-1, axis_ids, 'd', NULL, NULL);  
+          cmf = cmor_zfactor(zfactor_id, lev_id, (char *)"p0", (char *)"Pa", 0, 0, 'd', (void *)p0, NULL);
+          cmf = cmor_zfactor(zfactor_id, lev_id, (char *)"b",  (char *)"", 1, &lev_id_array[0], 'd', (void *)b_val, (void *)b_bnds);
+          cmf = cmor_zfactor(zfactor_id, lev_id, (char *)"ap", (char *)"Pa", 1, &lev_id_array[0], 'd', (void *)ap_val, (void *)ap_bnds);
+          cmf = cmor_zfactor(zfactor_id, lev_id, (char *)"ps", (char *)"Pa", count_axis_ids(axis_ids)-1, axis_ids, 'd', NULL, NULL);  
           Free(alev_val);  
           Free(alev_bnds);  
           Free(ap_val);  
@@ -1695,9 +2222,9 @@ static void register_z_axis(list_t *kvl, int vlistID, int varID, int zaxisID, ch
       else if ( zaxisInqType(zaxisID) == ZAXIS_DEPTH_BELOW_SEA )
         {
           zcell_bounds[0] = (double) 0;
-          cmor_axis(new_axis_id(axis_ids),
-                        "depth_coord",
-                        "m",
+          cmf = cmor_axis(new_axis_id(axis_ids),
+                        (char *) "depth_coord",
+                        (char *) "m",
                         zsize,
                         (void *)levels,
                         'd', zcell_bounds,  2, NULL);
@@ -1705,20 +2232,20 @@ static void register_z_axis(list_t *kvl, int vlistID, int varID, int zaxisID, ch
       else if ( zaxisInqType(zaxisID) == ZAXIS_DEPTH_BELOW_LAND )
         {
           zcell_bounds[0] = (double) 0;
-          cmor_axis(new_axis_id(axis_ids),
-                        "sdepth",
-                        "cm",
+          cmf = cmor_axis(new_axis_id(axis_ids),
+                        (char *) "sdepth",
+                        (char *) "cm",
                         zsize,
                         (void *)levels,
                         'd', zcell_bounds, 2, NULL);
         }
       else if ( zaxisInqType(zaxisID) == ZAXIS_GENERIC || zaxisInqType(zaxisID) == ZAXIS_HEIGHT)
         {
-          char *zaxisname = Malloc(CDI_MAX_NAME * sizeof(char));
+          char *zaxisname = (char *) Malloc(CDI_MAX_NAME * sizeof(char));
           zaxisInqName(zaxisID, zaxisname);
           if ( strcmp(zaxisname, "rho") == 0 )
             {
-              char *zaxisunits = Malloc(CDI_MAX_NAME * sizeof(char));
+              char *zaxisunits = (char *) Malloc(CDI_MAX_NAME * sizeof(char));
               zaxisInqUnits(zaxisID, zaxisunits);
               if ( strcmp(zaxisunits, "kg m-3") != 0 )
                 {
@@ -1726,14 +2253,14 @@ static void register_z_axis(list_t *kvl, int vlistID, int varID, int zaxisID, ch
                 }
               else
                 {
-                  levels = Malloc(zsize * sizeof(double));
+                  levels = (double *) Malloc(zsize * sizeof(double));
                   zaxisInqLevels(zaxisID, levels);
                   double *zcell_bounds;
-                  zcell_bounds = Malloc( 2*zsize * sizeof(double) );
+                  zcell_bounds = (double *) Malloc( 2*zsize * sizeof(double) );
                   get_zcell_bounds(zaxisID, zcell_bounds, levels, zsize);
-                  cmor_axis(new_axis_id(axis_ids),
-                      "rho",
-                      "kg m-3",
+                  cmf = cmor_axis(new_axis_id(axis_ids),
+                      (char *) "rho",
+                      (char *) "kg m-3",
                       zsize,
                       (void *) levels,
                       'd', zcell_bounds, 2, NULL);
@@ -1741,11 +2268,11 @@ static void register_z_axis(list_t *kvl, int vlistID, int varID, int zaxisID, ch
               Free(zaxisunits);
             }
           else
-            cdoAbort("Z-axis type %d with name '%s' not yet enabled.", zaxisInqType(zaxisID), zaxisname);
+            cdoAbort("In registration of a vertical axis:\n          Z-axis type %d with name '%s' not yet enabled.", zaxisInqType(zaxisID), zaxisname);
           Free(zaxisname);
         }
       else
-        cdoAbort("Invalid Z-axis type %d . \n", zaxisInqType(zaxisID));
+        cdoAbort("In registration of a vertical axis:\n          Invalid Z-axis type %d . ", zaxisInqType(zaxisID));
       Free(zcell_bounds);
       Free(levels);
     }
@@ -1756,19 +2283,22 @@ static void register_z_axis(list_t *kvl, int vlistID, int varID, int zaxisID, ch
       strtok_r(szc_name, "_", &szc_value);
       if ( !szc_value || !szc_value[0] )
         cdoAbort("Could not find an underscore '_' in szc value '%s' to seperate axis name from axis value", szc_name);
-      levels = Malloc(sizeof(double));
+      levels = (double *)Malloc(sizeof(double));
       levels[0] = (double) atof(szc_value);
       if ( cdoVerbose )
-        printf("Attribute szc is found.\nScalar z coordinate name is: '%s'\nScalar z coordinate value is: '%f'\n", szc_name, levels[0]);
-      cmor_axis(new_axis_id(axis_ids),
+        cdoPrint("Attribute szc is found.\n          Scalar z coordinate name is: '%s'\n          Scalar z coordinate value is: '%f'\n          ", szc_name, levels[0]);
+      cmf = cmor_axis(new_axis_id(axis_ids),
                       szc_name,
-                      "m",
+                      (char *) "m",
                       zsize,
                       (void *) levels,
                       'd', NULL, 0, NULL);
       Free(levels);
     }
   }
+  Free(chardim);
+  if ( cmf != 0 )
+    cdoAbort("Function cmor_axis failed!");
 }
 
 /*
@@ -1812,33 +2342,33 @@ static void register_character_dimension(int *axis_ids, char *filename)
 static void change_grid(char *grid_file, int gridID, int vlistID)
 {
   if ( cdoVerbose )
-    printf("You configured a grid_info file: '%s'. It is tested for a valid use as substitution.\n");
+    cdoPrint("You configured a grid_info file: '%s'. It is tested for a valid use as substitution.\n");
   argument_t *fileargument = file_argument_new(grid_file);
   int streamID2 = pstreamOpenRead(fileargument); 
   int vlistID2 = pstreamInqVlist(streamID2);
   int gridID2 = vlistInqVarGrid(vlistID2, 0); 
 
   if ( !gridID2 )
-    cdoAbort("Could not use grid from file '%s' configured via attribute 'ginfo'\n because of internal problems.", grid_file);
+    cdoAbort("Could not use grid from file '%s' configured via attribute 'ginfo'\n          because of internal problems.", grid_file);
 
   int a,b;
   a = gridInqSize(gridID);
   b = gridInqSize(gridID2);
   if ( a != b )
-    cdoAbort("Could not use grid from file '%s' configured via attribute 'ginfo'\n because total size of $IFILE: '%d' is not identical to total size of ginfo file: '%d'.", grid_file, a, b);
+    cdoAbort("Could not use grid from file '%s' configured via attribute 'ginfo'\n          because total size of $IFILE: '%d' is not identical to total size of ginfo file: '%d'.", grid_file, a, b);
 
   a = gridInqYsize(gridID);
   b = gridInqYsize(gridID2);
   if ( a != b )
-    cdoAbort("Could not use grid from file '%s' configured via attribute 'ginfo'\n because ysize of $IFILE: '%d' is not identical to ysize of ginfo file: '%d'.", grid_file, a, b);
+    cdoAbort("Could not use grid from file '%s' configured via attribute 'ginfo'\n          because ysize of $IFILE: '%d' is not identical to ysize of ginfo file: '%d'.", grid_file, a, b);
 
   a = gridInqXsize(gridID);
   b = gridInqXsize(gridID2);
   if ( a != b )
-    cdoAbort("Could not use grid from file '%s' configured via attribute 'ginfo'\n because xsize of $IFILE: '%d' is not identical to xsize of ginfo file: '%d'.", grid_file, a, b);
+    cdoAbort("Could not use grid from file '%s' configured via attribute 'ginfo'\n          because xsize of $IFILE: '%d' is not identical to xsize of ginfo file: '%d'.", grid_file, a, b);
 
   vlistChangeGrid(vlistID, gridID, gridID2);
-  printf("Succesfully substituted grid.\n");
+  cdoPrint("Successfully substituted grid.");
 
   pstreamClose(streamID2);
 }
@@ -1873,21 +2403,30 @@ static void inquire_vals_and_bounds(int gridID, int *xnbounds, int *ynbounds, do
 static void get_cmor_table(list_t *kvl, char *project_id)
 {
   int gridtable_id;
+  int cmf = 0;
   char gridtable[CMOR_MAX_STRING];
   char *mip_table_dir = kv_get_a_val(kvl, "mip_table_dir", NULL);
   if ( mip_table_dir && project_id )
     {
+#if ( CMOR_VERSION_MAJOR == 2 )
       sprintf(gridtable, "%s/%s_grids\0", mip_table_dir, project_id);
-      if ( file_exist(gridtable, 1) )  
+#elif ( CMOR_VERSION_MAJOR == 3 )
+      sprintf(gridtable, "%s/%s_grids.json\0", mip_table_dir, project_id);
+#endif
+      if ( file_exist(gridtable, 0, "Cmor-grid_table") )  
         {
-          cmor_load_table(gridtable, &gridtable_id);
-          cmor_set_table(gridtable_id);
+          cmf = cmor_load_table(gridtable, &gridtable_id);
+          cmf = cmor_set_table(gridtable_id);
         }
+      else
+        cdoAbort("In grid registration:\n          A project grid table is required for this type of grid but not found in the mip table directory '%s'.", mip_table_dir);
     }
   else
     {
-      cdoAbort("A project grid table is required for this type of grid but not found in the mip table directory. Check attributes \n mip_table_dir \n and \n project_id !");
+      cdoAbort("In grid registration:\n          A project grid table is required for this type of grid but not found in the mip table directory. Check attributes 'mip_table_dir' and 'project_id' !");
     } 
+  if ( cmf != 0 )
+    cdoAbort("Function cmor_load_table or cmor_set_table failed!"); 
 }
 
 static void check_and_gen_bounds(int gridID, int nbounds, int length, double *coord_vals, double *cell_bounds, int x)
@@ -2180,15 +2719,17 @@ static void select_and_register_character_dimension(char *grid_file, int *axis_i
 */
 static void register_lon_axis(int gridID, int xlength, int *axis_ids)
 {
-  double *xcoord_vals = Malloc(xlength * sizeof(double));
+  double *xcoord_vals = (double *) Malloc(xlength * sizeof(double));
   if ( gridInqXvals(gridID, xcoord_vals) == 0 )
     Free(xcoord_vals);
   else
     {
-      double *xcell_bounds = Malloc(2 * xlength * sizeof(double));
+      double *xcell_bounds = (double *) Malloc(2 * xlength * sizeof(double));
       int xnbounds = gridInqXbounds(gridID, xcell_bounds);
       check_and_gen_bounds(gridID, xnbounds, xlength, xcoord_vals, xcell_bounds, 1);
-      cmor_axis(new_axis_id(axis_ids),    "longitude",    "degrees_east",    xlength,    (void *)xcoord_vals,    'd',    (void *)xcell_bounds,    2,    NULL);
+      int cmf = cmor_axis(new_axis_id(axis_ids),    (char *) "longitude",    (char *) "degrees_east",    xlength,    (void *)xcoord_vals,    'd',    (void *)xcell_bounds,    2,    NULL);
+      if ( cmf != 0 )
+        cdoAbort("Function cmor_axis failed!");
       if ( xcell_bounds ) Free(xcell_bounds);
       if ( xcoord_vals ) Free(xcoord_vals);
     }
@@ -2196,15 +2737,17 @@ static void register_lon_axis(int gridID, int xlength, int *axis_ids)
 
 static void register_lat_axis(int gridID, int ylength, int *axis_ids)
 {
-  double *ycoord_vals = Malloc(ylength * sizeof(double));
+  double *ycoord_vals = (double *) Malloc(ylength * sizeof(double));
   if ( gridInqYvals(gridID, ycoord_vals) == 0 )
     Free(ycoord_vals);
   else
     {
-      double *ycell_bounds = Malloc(2 * ylength * sizeof(double));
+      double *ycell_bounds = (double *) Malloc(2 * ylength * sizeof(double));
       int ynbounds = gridInqYbounds(gridID, ycell_bounds);
       check_and_gen_bounds(gridID, ynbounds, ylength, ycoord_vals, ycell_bounds, 0);
-      cmor_axis(new_axis_id(axis_ids),    "latitude",    "degrees_north",    ylength,    (void *)ycoord_vals,    'd',    (void *)ycell_bounds,    2,    NULL);
+      int cmf = cmor_axis(new_axis_id(axis_ids),    (char *) "latitude",    (char *) "degrees_north",    ylength,    (void *)ycoord_vals,    'd',    (void *)ycell_bounds,    2,    NULL);
+      if ( cmf != 0 )
+        cdoAbort("Function cmor_axis failed!");
       if ( ycell_bounds ) Free(ycell_bounds);
       if ( ycoord_vals ) Free(ycoord_vals);  
     }
@@ -2224,12 +2767,162 @@ static void register_char_axis(int numchar, char **charvals, int *axis_ids, char
       sprintf((char *)charcmor, "%s%s", (char *)charcmor, charvals[i]);
       sprintf((char *)charcmor, "%s%.*s", (char *)charcmor, maxlen-strlen(charvals[i]), blanks);   
     }
-  cmor_axis(new_axis_id(axis_ids), chardim, "", numchar, (void *)charcmor, 'c',  NULL, maxlen, NULL); 
+  int cmf = cmor_axis(new_axis_id(axis_ids), chardim, (char *) "", numchar, (void *)charcmor, 'c',  NULL, maxlen, NULL); 
+  if ( cmf != 0 )
+    cdoAbort("Function cmor_axis failed!");
   Free(charcmor);
 }
 
+static void register_projection(int *grid_ids, int projID, double *ycoord_vals, double *xcoord_vals, double *ycell_bounds, double *xcell_bounds, int xlength, int ylength)
+{
+              int cmf = 0;
+              int pxnbounds;
+              int pynbounds;
+              int pylength = gridInqYsize(projID);
+              int pxlength = gridInqXsize(projID);
+              double *pxcoord_vals = (double *) Malloc(pxlength * sizeof(double));
+              double *pycoord_vals = (double *) Malloc(pylength * sizeof(double));
+              double *pxcell_bounds = (double *) Malloc(2 * pxlength * sizeof(double));
+              double *pycell_bounds = (double *) Malloc(2 * pylength * sizeof(double));
+              inquire_vals_and_bounds(projID, &pxnbounds, &pynbounds, pxcoord_vals, pycoord_vals, pxcell_bounds, pycell_bounds);
+              check_and_gen_bounds(projID, pxnbounds, pxlength, pxcoord_vals, pxcell_bounds, 1);
+              check_and_gen_bounds(projID, pynbounds, pylength, pycoord_vals, pycell_bounds, 0);
+
+              int projtype = gridInqProjType(projID);
+
+              char p_rll_cmor[CMOR_MAX_STRING];
+              int l_p_rll = strlen("grid_north_pole_longitude")+1;
+              memcpy(p_rll_cmor, "grid_north_pole_latitude\0 grid_north_pole_longitude\0north_pole_grid_longitude\0", 3*l_p_rll);
+
+              char u_rll_cmor[CMOR_MAX_STRING];
+              int l_u_rll = strlen("degrees_north")+1;
+              memcpy(u_rll_cmor, "degrees_north\0degrees_east\0 degrees_east\0 ", 3*l_u_rll);
+
+
+              char p_lcc_cmor[CMOR_MAX_STRING];
+              int l_p_lcc = strlen("longitude_of_central_meridian")+1;
+              memcpy(p_lcc_cmor, "standard_parallel1\0           longitude_of_central_meridian\0latitude_of_projection_origin\0standard_parallel2\0           ", 4*l_p_lcc);
+
+
+              char u_lcc_cmor[CMOR_MAX_STRING];
+              int l_u_lcc = 6;
+              memcpy(u_lcc_cmor, "      \0      \0      \0      \0", 4*l_u_lcc);
+
+              const char *p_rll[] = {"grid_north_pole_latitude",
+                               "grid_north_pole_longitude",
+                               "north_pole_grid_longitude", NULL};
+
+              const char *p_lcc[] = {"standard_parallel1",
+                               "longitude_of_central_meridian",
+                               "latitude_of_projection_origin",
+                               "standard_parallel2", NULL};
+
+              double *parameter_values = NULL;
+
+              char mapping[CDI_MAX_NAME]; mapping[0] = 0;
+              cdiGridInqKeyStr(projID, CDI_KEY_MAPPING, CDI_MAX_NAME, mapping);
+
+              int atttype, attlen;
+              char attname[CDI_MAX_NAME];
+
+              int natts;
+              cdiInqNatts(projID, CDI_GLOBAL, &natts);
+
+              int p_len;
+              switch ( projtype )
+                {
+                case CDI_PROJ_RLL: 
+                 p_len = (sizeof(p_rll) / sizeof(p_rll[0]))-1; break;
+                case CDI_PROJ_LAEA: cdoAbort("In grid registration:\n          This grid projection is not yet enabled."); break;
+                case CDI_PROJ_LCC:
+                  p_len = (sizeof(p_lcc) / sizeof(p_lcc[0]))-1; break;
+                case CDI_PROJ_SINU: cdoAbort("In grid registration:\n          This grid projection is not yet enabled."); break;
+                }
+              if ( natts != p_len )
+                cdoWarning("In grid registration:\n          Number of required grid mapping attributes '%d' differs from the number of given grid mapping attributes '%d'.\n          Note that all required mapping attributes are set to 0.0 by default in case they are not given.", p_len, natts);
+ 
+              parameter_values = (double *) Malloc(p_len * sizeof(double));
+              for ( int i = 0; i < p_len; i++ )
+                parameter_values[i] = 0.0;
+
+              for ( int iatt = 0; iatt < natts; ++iatt )
+                {
+                  cdiInqAtt(projID, CDI_GLOBAL, iatt, attname, &atttype, &attlen);
+                  if ( atttype == DATATYPE_FLT32 || atttype == DATATYPE_FLT64 )
+                    {
+                      if ( attlen > 1 )
+                        cdoAbort("In grid registration:\n          Dont know what to do with grid mapping attribute '%s'.", attname);
+                      double attflt[attlen];
+                      cdiInqAttFlt(projID, CDI_GLOBAL, attname, attlen, attflt);
+                      int i = 0;
+                      for ( i = 0; i < p_len; i++ )
+                        {
+                          if ( projtype == CDI_PROJ_RLL )
+                            if ( strcmp(attname, p_rll[i]) == 0 )
+                                {
+                                  parameter_values[i] = attflt[0];
+                                  break;
+                                }
+                          else if ( projtype == CDI_PROJ_LCC ) 
+                            if ( strcmp(attname, p_lcc[i]) == 0 )
+                                {
+                                  parameter_values[i] = attflt[0];
+                                  break;
+                                }
+
+                        }
+                      if ( i == p_len )
+                        cdoWarning("In grid registration:\n          grid mapping attribute '%s' is neglected.", attname);
+                    }
+                  else if ( atttype  == DATATYPE_TXT )
+                    {
+                      char atttxt[attlen];
+                      cdiInqAttTxt(projID, CDI_GLOBAL, attname, attlen, atttxt);
+                    }
+                }
+
+              int grid_axis[2];
+              if ( projtype == CDI_PROJ_RLL )
+                {
+                  cmf = cmor_axis(&grid_axis[0],    (char *) "grid_latitude",   (char *) "degrees_north",    pylength,    (void *)pycoord_vals,    'd',    0, 0,   NULL);
+                  cmf = cmor_axis(&grid_axis[1],    (char *)"grid_longitude",   (char *) "degrees_east",    pxlength,    (void *)pxcoord_vals,    'd',    0, 0,   NULL);
+                  cmf = cmor_grid(&grid_ids[0],    2,    grid_axis,    'd',    (void *)ycoord_vals,    (void *)xcoord_vals,    4,     (void *)ycell_bounds,    (void *)xcell_bounds);
+#if ( CMOR_VERSION_MAJOR == 2 )
+                  cmf = cmor_set_grid_mapping(grid_ids[0], "rotated_latitude_longitude", p_len, (char **) p_rll_cmor, l_p_rll, parameter_values, (char **)u_rll_cmor,  l_u_rll);
+#elif ( CMOR_VERSION_MAJOR == 3 )
+                  cmf = cmor_set_grid_mapping(grid_ids[0], (char *)"rotated_latitude_longitude", p_len, p_rll_cmor, l_p_rll, parameter_values, u_rll_cmor,  l_u_rll);
+#endif
+                }
+              else if ( projtype == CDI_PROJ_LCC )
+                {
+                  double *xii = (double *) Malloc(xlength * sizeof(double));
+                  double *yii = (double *) Malloc(ylength * sizeof(double));
+                  for ( int i = 0; i < xlength; i++ )
+                    xii[i] = (double) i;
+                  for ( int i = 0; i < ylength; i++ )
+                    yii[i] = (double) i;
+                  cmf = cmor_axis(&grid_axis[0],  (char *)  "x",  (char *)  "m",    ylength,    (void *)yii,    'd',    0, 0,   NULL);
+                  cmf = cmor_axis(&grid_axis[1],  (char *)  "y",  (char *)  "m",    xlength,    (void *)xii,    'd',    0, 0,   NULL);
+                  cmf = cmor_grid(&grid_ids[0],    2,    grid_axis,    'd',    (void *)ycoord_vals,    (void *)xcoord_vals,    4,     (void *)ycell_bounds,    (void *)xcell_bounds);
+#if ( CMOR_VERSION_MAJOR == 2 )
+                  cmf = cmor_set_grid_mapping(grid_ids[0], mapping, p_len,(char **)p_lcc_cmor, l_p_lcc, parameter_values, (char **)u_lcc_cmor,  l_u_lcc);
+#elif ( CMOR_VERSION_MAJOR == 3 )
+                  cmf = cmor_set_grid_mapping(grid_ids[0], mapping, p_len, p_lcc_cmor, l_p_lcc, parameter_values, u_lcc_cmor,  l_u_lcc);
+#endif
+                  Free(xii); Free(yii);
+                }
+              Free(parameter_values);
+              Free(pxcell_bounds);
+              Free(pycell_bounds);
+              Free(pxcoord_vals);
+              Free(pycoord_vals);
+              if ( cmf != 0 )
+                cdoAbort("Function cmor_axis or cmor_set_grid_mapping failed!");
+}
+
 static void register_grid(list_t *kvl, int vlistID, int varID, int *axis_ids, int *grid_ids, char *project_id)
 {
+  int cmf = 0;
   int gridID = vlistInqVarGrid(vlistID, varID);
 
   char *grid_file = kv_get_a_val(kvl, "gi", NULL);
@@ -2245,6 +2938,7 @@ static void register_grid(list_t *kvl, int vlistID, int varID, int *axis_ids, in
     }
 
   int type = gridInqType(gridID);
+  int projID = gridInqProj(gridID);
   int ylength = gridInqYsize(gridID);
   int xlength = gridInqXsize(gridID);
   int totalsize = gridInqSize(gridID);
@@ -2258,214 +2952,238 @@ static void register_grid(list_t *kvl, int vlistID, int varID, int *axis_ids, in
   int xnbounds;
   int ynbounds;
 
-  if ( totalsize > 1 )
-  {
-  if ( type == GRID_GAUSSIAN || type == GRID_LONLAT )
-    {
-      grid_ids[0] = 0;
-      xcoord_vals = Malloc(xlength * sizeof(double));
-      ycoord_vals = Malloc(ylength * sizeof(double));
-      xcell_bounds = Malloc(2 * xlength * sizeof(double));
-      ycell_bounds = Malloc(2 * ylength * sizeof(double));
-      inquire_vals_and_bounds(gridID, &xnbounds, &ynbounds, xcoord_vals, ycoord_vals, xcell_bounds, ycell_bounds);
-
-      check_and_gen_bounds(gridID, xnbounds, xlength, xcoord_vals, xcell_bounds, 1);
-      check_and_gen_bounds(gridID, ynbounds, ylength, ycoord_vals, ycell_bounds, 0);
-      
-      cmor_axis(new_axis_id(axis_ids),    "latitude",    "degrees_north",    ylength,    (void *)ycoord_vals,    'd',    (void *)ycell_bounds,    2,    NULL);
-      cmor_axis(new_axis_id(axis_ids),    "longitude",    "degrees_east",    xlength,    (void *)xcoord_vals,    'd', 
-   (void *)xcell_bounds,    2,    NULL);
-
-      Free(xcell_bounds);
-      Free(ycell_bounds);
-      Free(xcoord_vals);
-      Free(ycoord_vals);
-    }
-  else if ( type == GRID_CURVILINEAR || type == GRID_UNSTRUCTURED)
-    {
-      xcoord_vals = Malloc(totalsize * sizeof(double));
-      ycoord_vals = Malloc(totalsize * sizeof(double));
-/* maximal 4 gridbounds per gridcell permitted */
-      xcell_bounds = Malloc(4 * totalsize * sizeof(double));
-      ycell_bounds = Malloc(4 * totalsize * sizeof(double));
-      inquire_vals_and_bounds(gridID, &xnbounds, &ynbounds, xcoord_vals, ycoord_vals, xcell_bounds, ycell_bounds);
-      move_lons(xcoord_vals, xcell_bounds, totalsize, 4 * totalsize, xnbounds);   
-      x2cell_bounds = Malloc(4 * totalsize * sizeof(double));
-      y2cell_bounds = Malloc(4 * totalsize * sizeof(double));
-      get_cmor_table(kvl, project_id);
-      int grid_axis[2];
-      check_and_gen_bounds_curv(gridID, totalsize, xnbounds, xlength, xcoord_vals, x2cell_bounds, ynbounds, ylength, ycoord_vals, y2cell_bounds);
-      if ( type == GRID_CURVILINEAR )
-        {
-          double *xncoord_vals;
-          double *yncoord_vals;
-          xncoord_vals = Malloc(xlength * sizeof(double));
-          yncoord_vals = Malloc(ylength * sizeof(double)); 
-          for (int j=0; j<ylength; j++) 
-            yncoord_vals[j]= (double) j;
-          for (int j=0; j<xlength; j++)
-            xncoord_vals[j]= (double) j;
-          cmor_axis(&grid_axis[0], "j_index",    "1",    ylength,    (void *)yncoord_vals,
-    'd', 0, 0, NULL);
-          cmor_axis(&grid_axis[1], "i_index",    "1",    xlength,    (void *)xncoord_vals,    'd', 0, 0, NULL);
-          cmor_grid(&grid_ids[0],    2,    grid_axis,    'd',    (void *)ycoord_vals,    (void *)xcoord_vals,    4,     (void *)y2cell_bounds,    (void *)x2cell_bounds);
-          Free(xncoord_vals);
-          Free(yncoord_vals);
-        }
-      /*else
-        { 
-          cmor_axis(&grid_axis[0],    "grid_longitude",   "degrees",    xlength,    (void *)xcoord_vals,    'd', 0, 0, NULL);
-          cmor_axis(&grid_axis[1],    "grid_latitude",    "degrees",    ylength,    (void *)ycoord_vals,    'd', 0, 0, NULL);
-          cmor_grid(&grid_ids[0],    2,    grid_axis,    'd',    (void *)ycoord_vals,    (void *)xcoord_vals,    2,     (void *)ycell_bounds,    (void *)xcell_bounds); 
-        }*/
-      Free(xcoord_vals);
-      Free(ycoord_vals);
-      Free(xcell_bounds);
-      Free(ycell_bounds);
-      Free(x2cell_bounds);
-      Free(y2cell_bounds);
-    }
-  else if ( type == GRID_GENERIC && ( strcmp(chardim, "oline") == 0 || strcmp(chardim, "basin") == 0 ))
-    {
-      if ( cdoVerbose )
-        printf("*******Start to define a character axis '%s' instead of a grid axis'.******\n", chardim);
-      grid_ids[0] = 0;
-      int numchar = 0;
-      char *charvalstring = Malloc(CMOR_MAX_STRING * sizeof(char));
-      sprintf(charvalstring, "char_axis_%s", chardim);
-      char **charvals = kv_get_vals(kvl, charvalstring, &numchar);
-      Free(charvalstring);
-      if ( ( xlength > 0 && xlength != numchar ) && ( ylength > 0 && ylength != numchar ) )
-        cdoAbort("You configured a character coordinate '%s' with '%d' string values but you also registered a grid with '%d' numerical values on X axis and '%d' numerical values on Y axis. Both is not supported!", chardim, numchar, xlength, ylength);
-      if ( !charvals )
-        cdoAbort("You configured a character coordinate '%s' but no values are found! Configure values via attribute 'char_dim_vals'!", chardim);
-      if ( charvals && ( xlength == numchar || xlength == 0 ) )
-        {
-          register_char_axis(numchar, charvals, axis_ids, chardim);
-          if ( ylength > 0 )
-            register_lat_axis(gridID, ylength, axis_ids);
-        }
-      else
-        {
-          register_lon_axis(gridID, xlength, axis_ids);
-          register_char_axis(numchar, charvals, axis_ids, chardim);
-        }
-      if ( cdoVerbose )
-        printf("*******Succesfully defined a character axis '%s' instead of a grid axis.******\n", chardim);
-      Free(chardim);
-    }
-/*
-      grid_ids[0] = 0;
-      xcoord_vals = Malloc(xlength * sizeof(double));
-      gridInqXvals(gridID, xcoord_vals);
-      ycoord_vals = Malloc(ylength * sizeof(double));
-      gridInqYvals(gridID, ycoord_vals);
-      char yname[CDI_MAX_NAME];
-      cdiGridInqKeyStr(gridID, CDI_KEY_YDIMNAME, CDI_MAX_NAME, yname);
-      if ( strcmp(yname, "basin") != 0 )
-        {
-          invert_ygriddes(kvl, vlistID, &gridID, ylength, ycoord_vals, ycell_bounds, &ynbounds);
-          ycell_bounds = Malloc(2 * ylength * sizeof(double));
-          ynbounds = gridInqYbounds(gridID, ycell_bounds);
-          check_and_gen_bounds(gridID, ynbounds, ylength, ycoord_vals, ycell_bounds, 0);
-          cmor_axis(new_axis_id(axis_ids),    "latitude",    "degrees_north",    ylength,    (void *)ycoord_vals,    'd',    (void *)ycell_bounds,    2,    NULL);
-          Free(ycell_bounds);
-        }
-      else
-        select_and_register_character_dimension(grid_file, axis_ids);
-
-      char xname[CDI_MAX_NAME];
-      cdiGridInqKeyStr(gridID, CDI_KEY_XDIMNAME, CDI_MAX_NAME, xname);
-      if ( strcmp(xname, "basin") != 0 )
+  if ( totalsize > 1 )
+    {
+      if ( type == GRID_GAUSSIAN || type == GRID_LONLAT )
         {
-          xcell_bounds = Malloc(2 * xlength * sizeof(double));
-          xnbounds = gridInqXbounds(gridID, xcell_bounds);
+          grid_ids[0] = 0;
+          xcoord_vals = (double *) Malloc(xlength * sizeof(double));
+          ycoord_vals = (double *) Malloc(ylength * sizeof(double));
+          xcell_bounds = (double *) Malloc(2 * xlength * sizeof(double));
+          ycell_bounds = (double *) Malloc(2 * ylength * sizeof(double));
+          inquire_vals_and_bounds(gridID, &xnbounds, &ynbounds, xcoord_vals, ycoord_vals, xcell_bounds, ycell_bounds);
+
           check_and_gen_bounds(gridID, xnbounds, xlength, xcoord_vals, xcell_bounds, 1);
-          cmor_axis(new_axis_id(axis_ids),    "longitude",    "degrees_east",    xlength,    (void *)xcoord_vals,    'd',    (void *)xcell_bounds,    2,    NULL);
+          check_and_gen_bounds(gridID, ynbounds, ylength, ycoord_vals, ycell_bounds, 0);
+
+          cmf = cmor_axis(new_axis_id(axis_ids),  (char *)  "latitude",   (char *) "degrees_north",    ylength,    (void *)ycoord_vals,    'd',    (void *)ycell_bounds,    2,    NULL);
+          cmf = cmor_axis(new_axis_id(axis_ids),  (char *)  "longitude",  (char *) "degrees_east",    xlength,    (void *)xcoord_vals,    'd',    (void *)xcell_bounds,    2,    NULL);
+
           Free(xcell_bounds);
+          Free(ycell_bounds);
+          Free(xcoord_vals);
+          Free(ycoord_vals);
         }
+      else if ( type == GRID_CURVILINEAR || type == GRID_UNSTRUCTURED )
+            {
+              xcoord_vals = (double *) Malloc(totalsize * sizeof(double));
+              ycoord_vals = (double *) Malloc(totalsize * sizeof(double));
+        /* maximal 4 gridbounds per gridcell permitted */
+              xcell_bounds = (double *) Malloc(4 * totalsize * sizeof(double));
+              ycell_bounds = (double *) Malloc(4 * totalsize * sizeof(double));
+              inquire_vals_and_bounds(gridID, &xnbounds, &ynbounds, xcoord_vals, ycoord_vals, xcell_bounds, ycell_bounds);
+       /* In a projection, this is done by setting mapping parameter */
+              move_lons(xcoord_vals, xcell_bounds, totalsize, 4 * totalsize, xnbounds);   
+              get_cmor_table(kvl, project_id);
+              int grid_axis[2];
+              check_and_gen_bounds_curv(gridID, totalsize, xnbounds, xlength, xcoord_vals, xcell_bounds, ynbounds, ylength, ycoord_vals, ycell_bounds);
+              if ( type == GRID_CURVILINEAR && projID == CDI_UNDEFID )
+                {
+                  double *xncoord_vals;
+                  double *yncoord_vals;
+                  xncoord_vals = (double *) Malloc(xlength * sizeof(double));
+                  yncoord_vals = (double *) Malloc(ylength * sizeof(double)); 
+                  for (int j=0; j<ylength; j++) 
+                    yncoord_vals[j]= (double) j;
+                  for (int j=0; j<xlength; j++)
+                    xncoord_vals[j]= (double) j;
+                  cmf = cmor_axis(&grid_axis[0],(char *) "j_index",   (char *) "1",    ylength,    (void *)yncoord_vals,
+            'd', 0, 0, NULL);
+                  cmf = cmor_axis(&grid_axis[1],(char *) "i_index",   (char *) "1",    xlength,    (void *)xncoord_vals,    'd', 0, 0, NULL);
+                  cmf = cmor_grid(&grid_ids[0],    2,    grid_axis,    'd',    (void *)ycoord_vals,    (void *)xcoord_vals,    4,     (void *)ycell_bounds,    (void *)xcell_bounds);
+                  Free(xncoord_vals);
+                  Free(yncoord_vals);
+                  Free(xcoord_vals);
+                  Free(ycoord_vals);
+                  Free(xcell_bounds);
+                  Free(ycell_bounds);
+                }
+              /*else
+                { 
+                  cmf = cmor_axis(&grid_axis[0],    "grid_longitude",   "degrees",    xlength,    (void *)xcoord_vals,    'd', 0, 0, NULL);
+                  cmf = cmor_axis(&grid_axis[1],    "grid_latitude",    "degrees",    ylength,    (void *)ycoord_vals,    'd', 0, 0, NULL);
+                  cmf = cmor_grid(&grid_ids[0],    2,    grid_axis,    'd',    (void *)ycoord_vals,    (void *)xcoord_vals,    2,     (void *)ycell_bounds,    (void *)xcell_bounds); 
+                }*/
+            }
+      else if ( type == GRID_GENERIC && ( strcmp(chardim, "oline") == 0 || strcmp(chardim, "basin") == 0 ))
+            {
+              if ( cdoVerbose )
+                cdoPrint("Start to define a character axis '%s' instead of a grid axis'.", chardim);
+              grid_ids[0] = 0;
+              int numchar = 0;
+              char *charvalstring = (char *) Malloc(CMOR_MAX_STRING * sizeof(char));
+              sprintf(charvalstring, "char_axis_%s", chardim);
+              char **charvals = kv_get_vals(kvl, charvalstring, &numchar);
+              Free(charvalstring);
+              if ( ( xlength > 0 && xlength != numchar ) && ( ylength > 0 && ylength != numchar ) )
+                cdoAbort("In registration of a character coordinate as substitution for a horizontal axis:\n          You configured a character coordinate '%s' with '%d' string values but you also registered a grid with '%d' numerical values on X axis and '%d' numerical values on Y axis. One axis must match the number of string values.", chardim, numchar, xlength, ylength);
+              if ( !charvals )
+                cdoAbort("In registration of a character coordinate as substitution for a horizontal axis:\n          You configured a character coordinate '%s' but no values are found! Configure values via attribute 'char_dim_vals'!", chardim);
+              if ( charvals && ( xlength == numchar || xlength == 0 ) )
+                {
+                  register_char_axis(numchar, charvals, axis_ids, chardim);
+                  if ( ylength > 0 )
+                    register_lat_axis(gridID, ylength, axis_ids);
+                }
+              else
+                {
+                  register_lon_axis(gridID, xlength, axis_ids);
+                  register_char_axis(numchar, charvals, axis_ids, chardim);
+                }
+              if ( cdoVerbose )
+                cdoPrint("Successfully defined a character axis '%s' instead of a grid axis.", chardim);
+            }
+        /*
+              grid_ids[0] = 0;
+              xcoord_vals = Malloc(xlength * sizeof(double));
+              gridInqXvals(gridID, xcoord_vals);
+              ycoord_vals = Malloc(ylength * sizeof(double));
+              gridInqYvals(gridID, ycoord_vals);
+              char yname[CDI_MAX_NAME];
+              cdiGridInqKeyStr(gridID, CDI_KEY_YDIMNAME, CDI_MAX_NAME, yname);
+              if ( strcmp(yname, "basin") != 0 )
+                {
+                  invert_ygriddes(kvl, vlistID, &gridID, ylength, ycoord_vals, ycell_bounds, &ynbounds);        
+                  ycell_bounds = Malloc(2 * ylength * sizeof(double));        
+                  ynbounds = gridInqYbounds(gridID, ycell_bounds);
+                  check_and_gen_bounds(gridID, ynbounds, ylength, ycoord_vals, ycell_bounds, 0);
+                  cmf = cmor_axis(new_axis_id(axis_ids),    "latitude",    "degrees_north",    ylength,    (void *)ycoord_vals,    'd',    (void *)ycell_bounds,    2,    NULL);
+                  Free(ycell_bounds);
+                }
+              else
+                select_and_register_character_dimension(grid_file, axis_ids);
+
+              char xname[CDI_MAX_NAME];
+              cdiGridInqKeyStr(gridID, CDI_KEY_XDIMNAME, CDI_MAX_NAME, xname);
+              if ( strcmp(xname, "basin") != 0 )
+                {
+                  xcell_bounds = Malloc(2 * xlength * sizeof(double));
+                  xnbounds = gridInqXbounds(gridID, xcell_bounds);
+                  check_and_gen_bounds(gridID, xnbounds, xlength, xcoord_vals, xcell_bounds, 1);
+                  cmf = cmor_axis(new_axis_id(axis_ids),    "longitude",    "degrees_east",    xlength,    (void *)xcoord_vals,    'd',    (void *)xcell_bounds,    2,    NULL);
+                  Free(xcell_bounds);
+                }
+              else
+                select_and_register_character_dimension(grid_file, axis_ids);
+              Free(xcoord_vals);
+              Free(ycoord_vals);
+            */
+      else if ( type == GRID_CHARXY )
+            {
+              grid_ids[0] = 0;
+              char *xname = (char *) Malloc(CDI_MAX_NAME * sizeof(char));
+              char *yname = (char *) Malloc(CDI_MAX_NAME * sizeof(char));
+              gridInqXname(gridID, xname);
+              gridInqYname(gridID, yname);
+              char *xdimname = (char *) Malloc(CDI_MAX_NAME * sizeof(char));
+              char *ydimname = (char *) Malloc(CDI_MAX_NAME * sizeof(char));
+              cdiGridInqKeyStr(gridID, 902, CDI_MAX_NAME, xdimname);
+              cdiGridInqKeyStr(gridID, 912, CDI_MAX_NAME, ydimname);
+              if ( strcmp(xdimname, "line") == 0 )
+                strcpy(xdimname, "oline");
+              int dimstrlen;   
+              if ( dimstrlen = gridInqXIsc(gridID) )
+                {
+                  char **xchars = (char **)Malloc( (xlength+1) * sizeof(char *));
+                  for ( int i = 0; i < xlength; i++ )
+                    xchars[i] = (char *)Malloc( (dimstrlen+1) * sizeof(char));
+                  gridInqXCvals(gridID, xchars);
+                  for ( int j = 0; j < xlength; j++ )
+                    xchars[j][dimstrlen] = 0;
+                  xchars[xlength] = NULL;
+                  register_char_axis(xlength, xchars, axis_ids, xdimname);
+                  free_array(xchars);
+                }
+              else if ( xlength)
+                register_lon_axis(gridID, xlength, axis_ids);
+
+              if ( dimstrlen = gridInqYIsc(gridID) )
+                {
+                  char **ychars = (char **) Malloc( (ylength + 1) * sizeof(char));
+                  for ( int i = 0; i < ylength; i++ )
+                    ychars[i] = (char *)Malloc( (dimstrlen +1) * sizeof(char));
+                  gridInqYCvals(gridID, ychars);
+                  for ( int j = 0; j < ylength; j++ )
+                    ychars[j][dimstrlen] = 0;
+                  ychars[ylength] = NULL;
+                  register_char_axis(ylength, ychars, axis_ids, ydimname);
+                  free_array(ychars);
+                }
+              else if ( ylength )
+                register_lat_axis(gridID, ylength, axis_ids);
+              Free(xname); Free(yname); Free(xdimname); Free(ydimname);
+            }
+      else if ( type == GRID_PROJECTION )
+            {
+              cdoAbort("In grid registration:\n          For a 'rotated_lat_lon' projection, both grids, the unprojected lat/lon and the projected rlat/rlon are required.");            
+            }
       else
-        select_and_register_character_dimension(grid_file, axis_ids);
-      Free(xcoord_vals);
-      Free(ycoord_vals);
-    */
-  else if ( type == GRID_CHARXY )
-    {
-      grid_ids[0] = 0;
-      char *xname = Malloc(CDI_MAX_NAME * sizeof(char));
-      char *yname = Malloc(CDI_MAX_NAME * sizeof(char));
-      gridInqXname(gridID, xname);
-      gridInqYname(gridID, yname);
-      char *xdimname = Malloc(CDI_MAX_NAME * sizeof(char));
-      char *ydimname = Malloc(CDI_MAX_NAME * sizeof(char));
-      cdiGridInqKeyStr(gridID, 902, CDI_MAX_NAME, xdimname);
-      cdiGridInqKeyStr(gridID, 912, CDI_MAX_NAME, ydimname);
-      if ( strcmp(xdimname, "line") == 0 )
-        strcpy(xdimname, "oline");
-      int dimstrlen;   
-      if ( dimstrlen = gridInqXIsc(gridID) )
-        {
-          char **xchars = (char **)Malloc( (xlength+1) * sizeof(char *));
-          for ( int i = 0; i < xlength; i++ )
-            xchars[i] = (char *)Malloc( (dimstrlen+1) * sizeof(char));
-          gridInqXCvals(gridID, xchars);
-          for ( int j = 0; j < xlength; j++ )
-            xchars[j][dimstrlen] = 0;
-          xchars[xlength] = NULL;
-          register_char_axis(xlength, xchars, axis_ids, xdimname);
-          free_array(xchars);
-        }
-      else if ( xlength)
-        register_lon_axis(gridID, xlength, axis_ids);
-
-      if ( dimstrlen = gridInqYIsc(gridID) )
-        {
-          char **ychars = (char **) Malloc( (ylength + 1) * sizeof(char));
-          for ( int i = 0; i < ylength; i++ )
-            ychars[i] = (char *)Malloc( (dimstrlen +1) * sizeof(char));
-          gridInqYCvals(gridID, ychars);
-          for ( int j = 0; j < ylength; j++ )
-            ychars[j][dimstrlen] = 0;
-          ychars[ylength] = NULL;
-          register_char_axis(ylength, ychars, axis_ids, ydimname);
-          free_array(ychars);
-        }
-      else if ( ylength )
-        register_lat_axis(gridID, ylength, axis_ids);
-      Free(xname); Free(yname); Free(xdimname); Free(ydimname);
-    }
-  else
-    {
-      grid_ids[0] = 0;
-      cdoWarning("Either the grid type is unknown or a registration is not necessary. However, it is not registered by cdo.\n");
+            {
+              grid_ids[0] = 0;
+              cdoWarning("Registration of a grid is skipped. Either the grid type is unknown or a registration is not necessary.");
+            }
+
+      if ( projID != CDI_UNDEFID )
+            {
+              register_projection(grid_ids, projID, ycoord_vals, xcoord_vals, ycell_bounds, xcell_bounds, xlength, ylength);
+              Free(xcoord_vals);
+              Free(ycoord_vals);
+              Free(xcell_bounds);
+              Free(ycell_bounds);
+            }
+        
     }
-  }
   else
     grid_ids[0] = 0;
+  Free(chardim);
+  if ( cmf != 0 )
+    cdoAbort("Function cmor_axis failed!");
 }
 
 static void register_variable(list_t *kvl, int vlistID, int varID, int *axis_ids,
                               struct mapping *var, int *grid_ids, char *name)
 {
+  int cmf = 0;
   if ( cdoVerbose )
-    printf("*******Start to retrieve 'positive' and 'units'.******\n");
+    cdoPrint("Start to retrieve 'positive' and 'units'.");
   char *positive = get_txtatt(vlistID, varID, "positive");
   char *origname = get_txtatt(vlistID, varID, "original_name");
   char *history = get_txtatt(vlistID, varID, "history");
-  char *units = Malloc(CDI_MAX_NAME * sizeof(char));
+  char *varcom = get_txtatt(vlistID, varID, "variable_comment");
+  char *units = (char *) Malloc(CDI_MAX_NAME * sizeof(char));
   vlistInqVarUnits(vlistID, varID, units);
   char *attunits = kv_get_a_val(kvl, "u", NULL);
   char *attp = kv_get_a_val(kvl, "p", NULL);
   char *attorigname = kv_get_a_val(kvl, "original_name", NULL);
+  char *attvarcom = kv_get_a_val(kvl, "vc", NULL);
   check_compare_set(&positive, attp, "positive", "");
   if ( strcmp(positive, " ") == 0 )
     strcpy(positive, "");
   check_compare_set(&units, attunits, "units", NULL);
   check_compare_set(&origname, attorigname, "original_name", "");
   if ( strcmp(origname, "") == 0 || strstr(origname, "var") )
-    origname = NULL;
+    {
+      Free(origname);
+      origname = NULL;
+    }
+  check_compare_set(&varcom, attvarcom, "variable_comment", "");
+  if ( strcmp(varcom, "") == 0 )
+    {
+      Free(varcom);
+      varcom = NULL;
+    }
   if ( cdoVerbose )
-    printf("*******Succesfully retrieved 'positive': '%s' and 'units' : '%s'.******\n", positive, units);
+    cdoPrint("Successfully retrieved 'positive': '%s' and 'units' : '%s'.", positive, units);
   char missing_value[sizeof(double)];
   double tolerance = 1e-4;
   size_t gridsize = vlistGridsizeMax(vlistID);
@@ -2492,12 +3210,12 @@ static void register_variable(list_t *kvl, int vlistID, int varID, int *axis_ids
     *(double *) missing_value = vlistInqVarMissval(vlistID, varID);
    
   if ( cdoVerbose )
-    printf("*******Start to call cmor_variable.******\n");
+    cdoPrint("Start to call cmor_variable.");
   if ( grid_ids[0] != 0 )
     {
       int *tmp_id = new_axis_id(axis_ids);
       *tmp_id = grid_ids[0];
-      cmor_variable(&var->cmor_varID,
+      cmf = cmor_variable(&var->cmor_varID,
             name,units,(count_axis_ids(axis_ids)), axis_ids, var->datatype,
             (void *) missing_value, &tolerance, positive,
                         origname,
@@ -2506,45 +3224,41 @@ static void register_variable(list_t *kvl, int vlistID, int varID, int *axis_ids
     }
   else
     {
-      cmor_variable(&var->cmor_varID,
+      cmf = cmor_variable(&var->cmor_varID,
            name, units, count_axis_ids(axis_ids),  axis_ids,   var->datatype,
           (void *) missing_value, &tolerance, positive,
                         origname,
                         history,
                         kv_get_a_val(kvl, "vc", NULL));
     }
+  if ( cmf != 0 )
+    cdoAbort("Function cmor_variable failed!");
   if ( cdoVerbose )
-    printf("*******Succesfully called cmor_variable.******\n");
+    cdoPrint("Successfully called cmor_variable.");
   if (positive) Free(positive); 
+  if (origname) Free(origname); 
+  if (history) Free(history); 
   if (units) Free(units);
 }
 
 static void register_all_dimensions(list_t *kvl, int streamID,
                              struct mapping vars[], int table_id, char *project_id, int miptab_freq, int *time_axis)
 {
+  int cmf = 0;
   int vlistID = pstreamInqVlist(streamID);
   int taxisID = vlistInqTaxis(vlistID);
 
-  if ( cdoVerbose )
-    printf("*******Start to check attribute 'required_time_units'.******\n");
-  char *time_units = get_time_units(taxisID);
-  char *required_time_units = kv_get_a_val(kvl, "required_time_units", NULL);
-  if ( check_time_units(required_time_units) )
-    check_compare_set(&time_units, required_time_units, "time_units", NULL);
-  else 
-    cdoAbort("Required Attribute 'required_time_units' from configuration is invalid!");
-  if ( cdoVerbose )
-    printf("*******Succesfully checked attribute 'required_time_units'.*******\n");
+  char *time_units = kv_get_a_val(kvl, "required_time_units", NULL);
 
   if ( cdoVerbose )
-    printf("*******Start to retrieve requested variables.******\n");
+    cdoPrint("7. Start to retrieve requested variables.");
 
   int numvals = 0;
   char **cmor_names = kv_get_vals(kvl, "cn", &numvals);
 
 /* Cmdlinemapping: */
   char *mapname, *mapcode;
-  if ( kv_get_a_val(kvl, "mt", NULL) && numvals )
+  if ( !kv_get_a_val(kvl, "mt", NULL) && numvals )
     {
       if ( mapname = kv_get_a_val(kvl, "n", NULL) )
         change_name_via_name(vlistID, mapname, cmor_names[0]);
@@ -2553,9 +3267,9 @@ static void register_all_dimensions(list_t *kvl, int streamID,
     }
 
   if ( cmor_names == NULL && vlistNvars(vlistID) > 1 )
-    cdoWarning("You have not requested any specific variable but there are several in input! Notice that all command line configuration attributes including cmor_name and units will be used for every variable!\n");
+    cdoPrint("In registration of all dimensions for the variables:\n          You have not requested any specific variable but there are several in infile! Notice that if attributes e.g. units are configured via cmdline, they will be used for every variable!");
   if ( cdoVerbose )
-    printf("*******Succesfully retrieved requested variables*******\n");
+    cdoPrint("7. Successfully retrieved requested variables");
   int foundName = 0;
   int ps_required = 0;
   int ps_in_file = 0;
@@ -2572,50 +3286,53 @@ static void register_all_dimensions(list_t *kvl, int streamID,
           axis_ids[0] = CMOR_UNDEFID;
           int zaxisID = vlistInqVarZaxis(vlistID, varID);
           if ( cdoVerbose )
-            printf("*******Start to define variable with ID: '%d' and name: '%s'*******\n", varID, name);
+            cdoPrint("8. Start to define variable with ID: '%d' and name: '%s'", varID, name);
           if ( zaxisInqType(zaxisID) == ZAXIS_HYBRID )
             {
-              if ( cdoVerbose )
-                printf("Since the zaxis of variable '%s' is of type HYBRID, surface pressure is required. An infile variable must have the name ps.\n", name);
+              cdoPrint("Since the zaxis of variable '%s' is of type HYBRID, surface pressure is required. An infile variable must have the name ps.", name);
               ps_required++;
             }
           foundName++;
           /* Time-Axis */
           if ( cdoVerbose )
-            printf("*******Start to register a time axis*******\n");
-          char cmor_time_name[CMOR_MAX_STRING];
+            cdoPrint("8.1. Start to register a time axis");
+          char cmor_time_name[CMOR_MAX_STRING]; cmor_time_name[0] = '\0';
           get_time_method(kvl, vlistID, varID, cmor_time_name, project_id, miptab_freq, time_axis);
           if ( strcmp(cmor_time_name, "none") != 0 )
-            cmor_axis(new_axis_id(axis_ids),
+            cmf = cmor_axis(new_axis_id(axis_ids),
                     cmor_time_name,
                     time_units,
                     0,NULL, 0, NULL, 0, NULL);
-          if ( cdoVerbose )
-            printf("*******Succesfully handled time axis registration*******\n");
+          if ( cdoVerbose && cmf == 0 )
+            cdoPrint("8.1. Successfully handled time axis registration.");
+          else if ( cmf != 0 )
+            cdoAbort("Function cmor_axis failed!");
           /* Grid: */
           if ( cdoVerbose )
-            printf("*******Start to register a grid*******\n");
+            cdoPrint("8.2. Start to register a grid");
           int grid_ids[CMOR_MAX_GRIDS];
           register_grid(kvl, vlistID, varID, axis_ids, grid_ids, project_id);
-          cmor_set_table(table_id);
+          cmf = cmor_set_table(table_id);
+          if ( cmf != 0 )
+            cdoAbort("Function cmor_set_table failed!");
           if ( cdoVerbose )
-            printf("*******Succesfully handled grid registration*******\n");
+            cdoPrint("8.2. Successfully handled grid registration.");
           /* Z-Axis */
           if ( cdoVerbose )
-            printf("*******Start to register a zaxis*******\n");
+            cdoPrint("8.3. Start to register a zaxis");
           register_z_axis(kvl, vlistID, varID, zaxisID, name, axis_ids, &var->zfactor_id, project_id, miptab_freq);
           if ( cdoVerbose )
-            printf("*******Succesfully handled zaxis registration*******\n");
+            cdoPrint("8.3. Successfully handled zaxis registration.");
           /* Variable */
           register_variable(kvl, vlistID, varID, axis_ids, var, grid_ids, name);     
           if ( cdoVerbose )
-            printf("*******Succesfully defined variable with ID: '%d' and name: '%s'*******\n", varID, name);
+            cdoPrint("8. Successfully defined variable with ID: '%d' and name: '%s'.", varID, name);
         }
     }
   if ( ps_required )
     {
       if ( cdoVerbose )
-        printf("\n *******Start to find surface pressure.*******\\n");
+        cdoPrint("9. Start to find surface pressure.");
       for ( int varID = 0; varID < vlistNvars(vlistID); varID++ )
         if ( vlistInqVarCode(vlistID, varID) == 134 )
           {
@@ -2642,22 +3359,19 @@ static void register_all_dimensions(list_t *kvl, int streamID,
               }
           }
       if ( cdoVerbose )
-        printf("\n *******Succesfully registered surface pressure.*******\\n");
+        cdoPrint("9. Successfully registered surface pressure.");
     }
   if ( ps_required && !ps_in_file )
-    cdoAbort("No surface pressure found in Ifile but required for a hybrid sigma pressure z axis!");
-  if ( !foundName && cmor_names == NULL )
-    cdoAbort("No variables from your table %s found in Ifile.\n");
+    cdoAbort("After registration of all dimensions for all variables:\n          No surface pressure found in infile but required for a hybrid sigma pressure z axis!");
   if ( !foundName && cmor_names )
-    cdoAbort("None of the given variables to process by attribute 'cmor_name' is found in Ifile.\n");
-  if ( time_units) Free(time_units);
+    cdoAbort("After registration of all dimensions for all variables:\n          None of the given variables to process by attribute 'cmor_name' is found in infile.");
   if ( cdoVerbose )
-    printf("*******Succesfully registered all dimensions for %d variables successfully.*******\n", foundName);
+    cdoPrint("Successfully registered all dimensions for %d variables successfully.", foundName);
 }
 
 static char *get_frequency(list_t *kvl, int streamID, int vlistID, int taxisID, int miptab_freq)
 {
-  char *frequency = Malloc(CMOR_MAX_STRING * sizeof(char));
+  char *frequency = (char *) Malloc(CMOR_MAX_STRING * sizeof(char));
   int ntsteps = vlistNtsteps(vlistID);
   int reccounter = 0;
   int recdummy = 0;
@@ -2731,7 +3445,7 @@ static char *get_frequency(list_t *kvl, int streamID, int vlistID, int taxisID,
               int step_per_year = 0;
               reccounter = 0;
               if ( cdoVerbose )
-                printf("Frequency is calculated by counting all timesteps in year %d\nin order to calculate time bounds in case they are not given.\n", fyear, fmonth);
+                cdoPrint("Frequency is calculated by counting all timesteps in year %d\n          in order to calculate time bounds in case they are not given.", fyear, fmonth);
               while ( recdummy = pstreamInqTimestep(streamID2, reccounter++) )
                 {
                   int reqyear;
@@ -2742,7 +3456,7 @@ static char *get_frequency(list_t *kvl, int streamID, int vlistID, int taxisID,
                 } 
               int covered_months = lmonth-fmonth+1;
               if ( step_per_year > 366*8 )
-                cdoAbort("Frequency is sub-3hourly! Not yet enabled.");
+                cdoAbort("In estimating frequency:\n          Frequency is sub-3hourly! Not yet enabled.");
               else
                 {
                   if ( (double)step_per_year / (double)covered_months > 31*8 )
@@ -2757,15 +3471,15 @@ static char *get_frequency(list_t *kvl, int streamID, int vlistID, int taxisID,
                     strcpy(frequency, "mon");
                 }
               if ( cdoVerbose )
-                printf("Found %d time steps in year %d.\nTherefore, the frequency is %s.\n", step_per_year, fyear, frequency);
+                cdoPrint("Found %d time steps in year %d.\n          Therefore, the frequency is %s.", step_per_year, fyear, frequency);
             }
         }
       else
         {
           if ( !taxisHasBounds(taxisID2) && ntsteps > 0 )
-            cdoAbort("No time bounds are found in Ifile and for %d found timesteps no frequency can be computed - at least 3 timesteps are required.\nDefine time bounds before cdo cmor.", ntsteps);
+            cdoAbort("In estimating frequency:\n          No time bounds are found in Ifile and for %d found timesteps no frequency can be computed - at least 3 timesteps are required.\n          Define time bounds before cdo cmor.", ntsteps);
           else
-            cdoWarning("For %d found timesteps no frequency can be computed - at least 3 timesteps are required.\nTime bounds of the rec are used.\n", ntsteps);
+            cdoWarning("In frequency estimation:\n          For %d found timesteps no frequency can be computed - at least 3 timesteps are required.\n          Time bounds of the rec are used.", ntsteps);
         }
       pstreamClose(streamID2);
     }
@@ -2784,52 +3498,154 @@ static int get_tunitsec(int tunit)
     }
 }
 
-static double get_cmor_time_val(int taxisID, juldate_t ref_date, int tunitsec, int calendar)
+static juldate_t get_cmor_time_val(int taxisID, juldate_t ref_date, int tunitsec, int calendar, char *frequency, int ts_id)
 {
+  int year, month, day;
+  cdiDecodeDate(taxisInqVdate(taxisID), &year, &month, &day);
   juldate_t juldate = juldate_encode(calendar, taxisInqVdate(taxisID),
                                      taxisInqVtime(taxisID));
-  return juldate_to_seconds(juldate_sub(juldate, ref_date)) / tunitsec;
+
+  if ( month == 0 || day == 0 || year == 0 )
+    {
+      int rdate, rtime;
+      int ryear, rmonth, rday, addseconds = 0;
+      juldate_decode(calendar, ref_date, &rdate, &rtime);
+      cdiDecodeDate(rdate, &ryear, &rmonth, &rday);
+      if ( ts_id < 2 )
+        cdoWarning("In writing the data:\n          Time axis is incorrect. It is tried to calculate time values with frequency.\n          Note: These are only valid if\n           - cm=m \n           - a equally spaced monotonical time axis exist according to the frequency \n           - a correct calendar exist!");
+      if ( strcmp(frequency, "yr") == 0 )
+        {
+          year = ryear+ts_id;
+          month = 6; /* Is set to mid point by CMOR */
+          day = 14; /* Is set to mid point by CMOR */
+        }
+      else if ( strcmp(frequency, "mon") == 0 )
+        {
+          year = ryear + floor(((double)(ts_id-1))/12);
+          month = (ts_id % 12);
+          if ( month == 0 )
+            month = 12;
+          day = 14; /* Is set to mid point by CMOR */
+        }
+      else if ( strcmp(frequency, "day") == 0 )
+        {
+          addseconds = ts_id * 24*60*60 + 60*60*12;
+          juldate = juldate_add_seconds(addseconds, ref_date);
+        }
+      else if ( strcmp(frequency, "6hr") == 0 )
+        {
+          addseconds = ts_id * 6*60*60;
+          juldate = juldate_add_seconds(addseconds, ref_date);
+        }
+      else if ( strcmp(frequency, "3hr") == 0 )
+        {
+          addseconds = ts_id * 3*60*60;
+          juldate = juldate_add_seconds(addseconds, ref_date);
+        }
+      if ( addseconds == 0 )
+        {
+          int vdate = cdiEncodeDate(year, month, 1);
+          int vtime = 0;
+          juldate = juldate_encode(calendar, vdate, vtime);
+        }
+    }
+
+  return juldate;
 }
 
-static double *get_time_bounds(int taxisID, char *frequency, juldate_t ref_date, double time_val, int calendar, int tunitsec, double *time_bnds)
+static double *get_time_bounds(list_t *kvl, int taxisID, char *frequency, juldate_t ref_date, juldate_t jtime_val, int calendar, int tunitsec, double *time_bnds, int time_axis)
 {
-  int vdate0b, vdate1b, vtime0b, vtime1b;
+  double time_val = juldate_to_seconds(juldate_sub(jtime_val, ref_date)) / tunitsec;
+  int vdate0b, vdate1b, vtime0b, vtime1b, vdatecorr, vtimecorr;
   int year, month, day;
+  int hour, min, sec;
   cdiDecodeDate(taxisInqVdate(taxisID), &year, &month, &day);
-  if ( !taxisHasBounds(taxisID) )
+  if ( month == 0 || day == 0 )
+    {
+      juldate_decode(calendar, jtime_val, &vdatecorr, &vtimecorr);
+      cdiDecodeDate(vdatecorr, &year, &month, &day);
+    }
+/***/
+/* If file time axis has bounds use them, otherwise use cmor time axis deduced from miptable frequency and cell_methods or frequency itself*/
+/***/
+
+  if ( !taxisHasBounds(taxisID) || strcmp(kv_get_a_val(kvl, "tbnds_force", "n"), "y") == 0 )
     {
-      if ( strcmp(frequency, "yr") == 0 )
-        {
-          vdate0b = cdiEncodeDate(year,   1, 1);
-          vdate1b = cdiEncodeDate(year+1, 1, 1);
-        }     
-      if ( strcmp(frequency, "mon") == 0 )
-        {
-          vdate0b = cdiEncodeDate(year, month, 1);
-          month++;
-          if ( month > 12 ) { month = 1; year++; }
-          vdate1b = cdiEncodeDate(year, month, 1);
-        }  
-      if ( strcmp(frequency, "day") == 0 )
-        {
-          time_bnds[0] = floor(time_val);
-          time_bnds[1] = ceil(time_val);
-          return time_bnds;
-        }  
-      if ( strcmp(frequency, "6hr") == 0 || strcmp(frequency, "3hr") == 0 )
-        {
-          time_bnds[0] = time_val - 0.125;
-          time_bnds[1] = time_val + 0.125;
-          return time_bnds;
-        }  
-      if ( strcmp(frequency, "3hr") == 0 )
-        {
-          time_bnds[0] = time_val - 0.0625;
-          time_bnds[1] = time_val + 0.0625;
-          return time_bnds;
-        }  
       vtime0b = 0;
       vtime1b = 0;
+  
+      if ( time_axis == 2 || time_axis == 3 )
+        {
+          int numdates;
+          char **climyears = kv_get_vals(kvl, "climatology_interval", &numdates);
+          if ( numdates != 2 )
+            cdoAbort("In writing model output:\n          Could not calculate time bounds for climatology time axis because attribute 'climatology_interval' has not two values.");
+          int expstartyear = atol(climyears[0]);
+          int expendyear = atol(climyears[1]);
+/***/
+/* Climatologies */
+/***/
+          if ( time_axis == 2 )
+            {
+              vdate0b = cdiEncodeDate(expstartyear, month, 1);
+              month++;
+              if ( month > 12 ) { month = 1; year++; }
+              vdate1b = cdiEncodeDate(expendyear, month, 1);
+            }
+/***/
+/* Diurnal cycle */
+/***/
+          if ( time_axis == 3 )
+            {
+              vdate0b = cdiEncodeDate(expstartyear, month, day);
+              cdiDecodeTime(taxisInqVtime(taxisID), & hour, &min, &sec);
+              vtime0b = cdiEncodeTime(hour,0,0);
+
+              hour++;
+              if ( hour > 23 ) { hour = 0; day++; }
+              vtime1b = cdiEncodeTime(hour,0,0);
+              vdate1b = cdiEncodeDate(expendyear, month, day);
+            }
+        }
+      else
+        {
+/***/
+/* Frequency dependent: */
+/***/
+          if ( strcmp(frequency, "yr") == 0 )
+            {
+              vdate0b = cdiEncodeDate(year,   1, 1);
+              vdate1b = cdiEncodeDate(year+1, 1, 1);
+            }     
+          else if ( strcmp(frequency, "mon") == 0 )
+            {
+              vdate0b = cdiEncodeDate(year, month, 1);
+              month++;
+              if ( month > 12 ) { month = 1; year++; }
+              vdate1b = cdiEncodeDate(year, month, 1);
+            }  
+          else if ( strcmp(frequency, "day") == 0 )
+            {
+              time_bnds[0] = floor(time_val);
+              time_bnds[1] = ceil(time_val);
+              return time_bnds;
+            }
+/***/
+/* Note that time_val must be correct in Infile for subdaily frequencies */
+/***/  
+          else if ( strcmp(frequency, "6hr") == 0 )
+            {
+              time_bnds[0] = time_val - 0.125;
+              time_bnds[1] = time_val + 0.125;
+              return time_bnds;
+            }  
+          else if ( strcmp(frequency, "3hr") == 0 )
+            {
+              time_bnds[0] = time_val - 0.0625;
+              time_bnds[1] = time_val + 0.0625;
+              return time_bnds;
+            } 
+        }
     }
   else
     {
@@ -2903,8 +3719,8 @@ static void check_for_sfc_pressure(int *ps_index, struct mapping vars[], int vli
       else if ( zaxisInqType(vlistInqVarZaxis(vlistID, vars[j].cdi_varID)) == ZAXIS_HYBRID )
         ps_required ++;
     }
-  if ( ps_index < 0 && ps_required )
-    cdoAbort("No surface pressure found for time step %d but required in Hybrid-sigma-pressure-coordinates! \n", timestep);
+  if ( *ps_index < 0 && ps_required )
+    cdoAbort("In writing data with CMOR:\n          No surface pressure found for time step %d but required in Hybrid-sigma-pressure-coordinates. ", timestep);
 }
 
 
@@ -2916,7 +3732,7 @@ static int check_append_and_size(list_t *kvl, int vlistID, char *testIn, int ifr
   char old_end_date[CMOR_MAX_STRING];
   int i = 0, j = 0;
 /* Get dates from chunk string */
-  if ( cdoVerbose) printf("*******Start to retrieve dates from chunk string.******\n");
+  if ( cdoVerbose) cdoPrint("Start to retrieve dates from chunk string.");
   while ( *(test+i) != 0 )
     {
       if ( *(test+i) == '_' )
@@ -2930,7 +3746,7 @@ static int check_append_and_size(list_t *kvl, int vlistID, char *testIn, int ifr
     }
   if ( !i || !j || *(test+j+1) == 0 || *(test+2*j) == 0 )
     {
-      cdoWarning("Error while checking chunk size for append mode.\nNew data will be appended.");
+      cdoWarning("In checking the last chunk:\n          Date from filename of the chunk cannot be read.\n          Switched to replace mode for this variable.");
       return 0;
     }
 
@@ -2940,16 +3756,20 @@ static int check_append_and_size(list_t *kvl, int vlistID, char *testIn, int ifr
   strncpy(old_end_date, test, j);
   old_end_date[j] = 0;
 
-  if ( cdoVerbose) printf("*******Succesfully retrieved start date: '%s' and end date: '%s' chunk string.******\n", old_start_date, old_end_date);
+  if ( cdoVerbose) cdoPrint("Successfully retrieved start date: '%s' and end date: '%s' chunk string.\n", old_start_date, old_end_date);
 /* Check frequency of chunk with frequency of file */
 
   if ( (j == 8 && ifreq !=3) || (ifreq == 3 && j != 8)
     || (j == 6 && ifreq !=2) || (ifreq == 2 && j != 6)
     || (j == 4 && ifreq !=1) || (ifreq == 1 && j != 4) )
-    cdoAbort("Frequency of chunk file does not agree with frequency of the working file.");
+    {
+      cdoWarning("In checking last chunk:\n          Frequency of chunk file does not agree with frequency of the working file.\n          Switched to replace mode for this variable.");
+      return 0;
+    }
+
 
 /* Encode in julseconds depending on frequency */
-  if ( cdoVerbose) printf("*******Start to encode dates with frequencies to julseconds.******\n");
+  if ( cdoVerbose) cdoPrint("Start to encode dates with frequencies to julseconds.");
 
   int old_start_year, old_start_month = 1, old_start_day = 1;
   int old_end_year, old_end_month = 1, old_end_day = 1;
@@ -2970,7 +3790,10 @@ static int check_append_and_size(list_t *kvl, int vlistID, char *testIn, int ifr
       old_end_year = atol(old_end_date);
       break;
     default:
-      cdoAbort("Selected chunk to append data has subdaily frequency which is yet not enabled by cdo cmor.\nA new file will be written.");
+      {
+        cdoWarning("In checking last chunk:\n          Last chunk has subdaily frequency which is yet not enabled by cdo cmor.\n          Switched to replace mode for this variable.");
+        return 0;
+      }
     }
 
   int cdi_startdate = cdiEncodeDate(old_start_year, old_start_month, old_start_day);
@@ -2979,12 +3802,12 @@ static int check_append_and_size(list_t *kvl, int vlistID, char *testIn, int ifr
   juldate_t julostart = juldate_encode(calendar, cdi_startdate, cdi_time);
   juldate_t juloend = juldate_encode(calendar, cdi_enddate, cdi_time);
 
-  if ( cdoVerbose) printf("*******Succesfully calculated juldates.******\n", old_start_date);
+  if ( cdoVerbose) cdoPrint("Successfully calculated juldates.", old_start_date);
 /* Read in first vdate in case not piped */
-  if ( cdoVerbose) printf("*******Start to calculate temporal gap between chunk and working file.******\n");
+  if ( cdoVerbose) cdoPrint("Start to calculate temporal gap between chunk and working file.");
   if ( cdoStreamName(0)->args[0] == '-' )
     {
-      cdoWarning("Cdo cmor cannot enable append mode since you piped several cdo operators.\nA new file will be written.");
+      cdoWarning("Cdo cmor cannot enable append mode since you piped several cdo operators.\n          Switched to replace mode for this variable.");
       return 0;
     }
       
@@ -3001,14 +3824,14 @@ static int check_append_and_size(list_t *kvl, int vlistID, char *testIn, int ifr
      ||( j == 6 && ( append_distance/24.0 > 62.0 || append_distance < 0 ) )
      ||( j == 4 && ( append_distance/24.0/30.5 > 24.0 || append_distance < 0 ) ) )
     {
-      cdoWarning("A temporal gap is diagnosed between end date of chunk file and first date of working file of: '%f' hours. Maximal valid gaps are:\n48 hours for daily frequency\n62 days for monthly frequency\n24 month for yearly frequency.\nSwitched to replace mode.", append_distance);
+      cdoWarning("In checking the last chunk:\n          A temporal gap is diagnosed between end date of chunk file and first date of working file of: '%f' hours. Maximal valid gaps are:\n          48 hours for daily frequency\n          62 days for monthly frequency\n          24 month for yearly frequency.\n          Switched to replace mode for this variable.", append_distance);
       pstreamClose(streamID2);
       return 0;
     }
 
-  if ( cdoVerbose) printf("*******Succesfully checked temporal gap.******\n");
+  if ( cdoVerbose) cdoPrint("Successfully checked temporal gap.");
 /* Check file size */
-  if ( cdoVerbose) printf("*******Start to check file size of chunk + working file.******\n");
+  if ( cdoVerbose) cdoPrint("Start to check file size of chunk + working file.");
   double old_interval_sec = juldate_to_seconds(juldate_sub(juloend, julostart));
   double size_per_sec = (double) filesize / old_interval_sec;
 
@@ -3022,7 +3845,7 @@ static int check_append_and_size(list_t *kvl, int vlistID, char *testIn, int ifr
       while ( pstreamInqTimestep(streamID2, ntsteps++)) ;
       if ( ntsteps == 0 )
         {
-          cdoWarning("A mistake occured during timesteps determination.\nSwitched to replace mode.");
+          cdoWarning("In checking whether append mode is possible:\n          No time steps found in infile.\n          Switched to replace mode for this variable.");
           pstreamClose(streamID2);
           return 0;
         }
@@ -3042,7 +3865,7 @@ static int check_append_and_size(list_t *kvl, int vlistID, char *testIn, int ifr
       break;
     default:
       {
-        cdoWarning("Selected chunk to append data has subdaily frequency which is yet not enabled by cdo cmor.\nA new file will be written.");
+        cdoWarning("In checking whether append mode is valid:\n          Selected chunk to append data has subdaily frequency which is yet not enabled by cdo cmor.\n          Switched to replace mode for this variable.");
         pstreamClose(streamID2);
         return 0;
       }
@@ -3050,30 +3873,33 @@ static int check_append_and_size(list_t *kvl, int vlistID, char *testIn, int ifr
 
   if ( (unsigned int)estimated_size > (unsigned int) maxsizeb )
     {
-      cdoWarning("Estimated file size of appended file is : '%f'gb and exceeds maximal allowed file size: '%d'gb.\nA new file will be written.", estimated_size/1024.0/1024.0/1024.0, maxsizegb);
+      cdoWarning("In checking whether append mode is valid:\n          Estimated file size of appended file is : '%f'gb and exceeds maximal allowed file size: '%d'gb.\n          Switched to replace mode for this variable.", estimated_size/1024.0/1024.0/1024.0, maxsizegb);
       pstreamClose(streamID2);
       return 0;
     }
   pstreamClose(streamID2);
-  if ( cdoVerbose) printf("*******Succesfully checked file size of chunk + working file.******\n");
+  if ( cdoVerbose) cdoPrint("Successfully checked file size of chunk + working file.");
   return 1;
 }
 
 static char *use_chunk_des_files(list_t *kvl, int vlistID, int var_id, char *chunk_des_file, int ifreq, int calendar)
 {
-  char *chunk_file = Malloc(4096 * sizeof(char));
-  if ( file_exist(chunk_des_file, 0) )
+  char *chunk_file = (char *) Malloc(4096 * sizeof(char));
+  if ( file_exist(chunk_des_file, 0, "chunk_description") )
     {
       FILE *fp = fopen(chunk_des_file, "r");
       size_t filesize = fileSize(chunk_des_file);
       char *buffer = (char*) Malloc(filesize);
       size_t nitems = fread(buffer, 1, filesize, fp);
-      buffer = readLineFromBuffer(buffer, &filesize, chunk_file, 4096);
+      char *eof = readLineFromBuffer(buffer, &filesize, chunk_file, 4096);
+      if ( eof != NULL )
+        cdoWarning("In checking the last chunk:\n          Chunk description file contains more than one line.\n          All lines after line 1 are ignored.");
       fclose(fp);
-      if ( file_exist(chunk_file, 0) && check_append_and_size(kvl, vlistID, chunk_file, ifreq, calendar) )
+      Free(buffer);
+      if ( file_exist(chunk_file, 0, "chunk_description") && check_append_and_size(kvl, vlistID, chunk_file, ifreq, calendar) )
         return chunk_file;
       else
-        cdoWarning("Chunk '%s' configured via chunk description file could either not be opened or is not suitable to be appended.\nSwitched to replace mode.", chunk_file);
+        cdoWarning("In checking the last chunk:\n          Chunk '%s' configured via chunk description file could either not be opened or is not suitable to be appended.\n          Switched to replace mode for this variable.", chunk_file);
     }
   else
     cdoWarning("Chunk description file '%s' could not be opened.\nSwitched to replace mode.", chunk_des_file);
@@ -3090,11 +3916,11 @@ static char **empty_array(struct mapping vars[], char ***chunk_files)
 
 static char **get_chunk_des_files(list_t *kvl, struct mapping vars[], char *miptab_freqptr, int nreq, int vlistID, char *charname)
 {
-  char **chunk_des_files = Malloc((nreq+1) * sizeof(char *));
+  char **chunk_des_files = (char **) Malloc((nreq+1) * sizeof(char *));
   chunk_des_files[nreq] = NULL;
 
-  char *trunk = Malloc(CMOR_MAX_STRING * sizeof(char));
-  char *description_atts[] = {"model_id", "experiment_id", "member", NULL};
+  char trunk[CMOR_MAX_STRING];
+  const char *description_atts[] = {"model_id", "experiment_id", "member", NULL};
   strcpy(trunk, miptab_freqptr);
   for ( int i = 0; description_atts[i]; i++ )
     {
@@ -3104,12 +3930,12 @@ static char **get_chunk_des_files(list_t *kvl, struct mapping vars[], char *mipt
 
   for ( int j = 0; vars[j].cdi_varID != CDI_UNDEFID; j++)
     {
-      char *name = Malloc(CDI_MAX_NAME * sizeof(char));
+      char *name = (char *) Malloc(CDI_MAX_NAME * sizeof(char));
       if ( charname )
         strcpy(name, charname);
       else
         vlistInqVarName(vlistID, vars[j].cdi_varID, name);
-      chunk_des_files[j] = Malloc(CMOR_MAX_STRING * sizeof(char));
+      chunk_des_files[j] = (char *) Malloc(CMOR_MAX_STRING * sizeof(char));
       sprintf(chunk_des_files[j], "CHUNK_FILE_%s_%s.txt\0", name, trunk);
       Free(name);
     }
@@ -3120,27 +3946,27 @@ static char **get_chunk_files(list_t *kvl, struct mapping vars[], int vlistID, i
 {
   int i = 0;
   for ( i = 0; vars[i].cdi_varID != CDI_UNDEFID; i++ );
-  char **chunk_files = Malloc((i+1) * sizeof(char *));
+  char **chunk_files = (char **) Malloc((i+1) * sizeof(char *));
   chunk_files[i] = NULL;
   
   char *dummy = kv_get_a_val(kvl, "om", NULL);
   if ( !dummy || strcmp(dummy, "a") != 0 )
     return empty_array(vars, &chunk_files);
-  else if ( time_axis == 3 )
+  else if ( time_axis == 4 )
     {
-      printf("CMOR APPEND mode not possible for time independent variables.\nSwitched to replace mode");
+      cdoWarning("In validating append mode:\n          CMOR APPEND mode not possible for time independent variables.\n          Switched to replace mode for this variable");
       return empty_array(vars, &chunk_files);
     }
 
   if ( cdoVerbose )
-    printf("\n*******Start to retrieve chunk files to append .******\n");
+    cdoPrint("Start to retrieve chunk files to append.\n");
 
   int num_aaf = 0;
   char **chunk_att_files = kv_get_vals(kvl, "lc", &num_aaf);
   char **chunk_des_files = NULL;
   if ( num_aaf != i && num_aaf > 0 )
     {
-      printf("Number of chunk files '%d' disagree with number of requested variables '%d'.\n Switched to replace mode.\n", num_aaf, i); 
+      cdoPrint("Number of chunk files '%d' disagree with number of requested variables '%d'.\n Switched to replace mode.\n", num_aaf, i); 
       return empty_array(vars, &chunk_files);
     }  
   else if ( num_aaf == 0 )
@@ -3149,9 +3975,9 @@ static char **get_chunk_files(list_t *kvl, struct mapping vars[], int vlistID, i
 /* For chunk description file : */
       if ( nd[0] == 'y' )
         chunk_des_files = get_chunk_des_files(kvl, vars, miptab_freqptr, i, vlistID, NULL);
-      else if ( cdoVerbose )
+      else
         {
-          printf("Automatic chunk configuration via file not possible if DRS is not created.\nSwichted to replace mode.");
+          cdoWarning("In getting chunk files:\n          Automatic chunk configuration via file not possible if DRS is not created.\n          Swichted to replace mode.");
           return empty_array(vars, &chunk_files);
         }
     }
@@ -3160,31 +3986,38 @@ static char **get_chunk_files(list_t *kvl, struct mapping vars[], int vlistID, i
     {
       if ( num_aaf != 0 )
         {
-          if ( file_exist(chunk_att_files[j], 0) && check_append_and_size(kvl, vlistID, chunk_att_files[j], ifreq, calendar) )
+          if ( file_exist(chunk_att_files[j], 0, "chunk file") && check_append_and_size(kvl, vlistID, chunk_att_files[j], ifreq, calendar) )
             chunk_files[j] = strdup(chunk_att_files[j]);
           else
             {
-              cdoWarning("Chunk '%s' could not be used.\nSwitched to replace mode for this variable.\n", chunk_att_files[j]);
+              cdoWarning("Chunk '%s' could not be used.\n          Switched to replace mode for this variable.", chunk_att_files[j]);
               chunk_files[j] = strdup(" ");
             }   
         }
       else 
         {
           if ( cdoVerbose )
-            printf("It is tried to open a chunk description file for varID: '%d': '%s'.\n", vars[j].cdi_varID, chunk_des_files[j]);
+            cdoPrint("It is tried to open a chunk description file for varID: '%d': '%s'.", vars[j].cdi_varID, chunk_des_files[j]);
           chunk_files[j] = use_chunk_des_files(kvl, vlistID, vars[j].cdi_varID, chunk_des_files[j], ifreq, calendar);  
         }
       if ( cdoVerbose && strcmp(chunk_files[j], " ") != 0 )
-        printf("\n*******Chunk file to append on var with CDI ID %d is: '%s' .******\n", vars[j].cdi_varID, chunk_files[j]);
+        cdoPrint("Chunk file to append on var with CDI ID %d is: '%s'.", vars[j].cdi_varID, chunk_files[j]);
     }
   if ( chunk_des_files ) free_array(chunk_des_files);
   if ( cdoVerbose )
-    printf("\n*******Successfully processed chunk file retrieval.******\n");
+    cdoPrint("Successfully processed chunk file retrieval.");
   return chunk_files;
 }
 
+static void sigfunc(int sig)
+{
+  if ( sig == SIGTERM )
+    cdoAbort("Program terminated by CMOR. A temporary ofile can outlive which needs to be deleted manually.");
+}
+
 static void write_variables(list_t *kvl, int *streamID, struct mapping vars[], int miptab_freq, int time_axis, int calendar, char *miptab_freqptr)
 {
+  int cmf = 0;
   int vlistID = pstreamInqVlist(*streamID);
   int taxisID = vlistInqTaxis(vlistID);
   int tsID = 0;
@@ -3192,16 +4025,19 @@ static void write_variables(list_t *kvl, int *streamID, struct mapping vars[], i
   size_t gridsize = vlistGridsizeMax(vlistID);
 
   if ( cdoVerbose )
-    printf("\n*******Start to retrieve relative start time value from 'required_time_units' and file and start to retrieve frequency.******\n");
+    cdoPrint("10. Start to write variables via cmor_write.");
+  if ( cdoVerbose )
+    cdoPrint("10.1. Start to get frequency.");
   int sdate, stime, time_unit;
   get_taxis(kv_get_a_val(kvl, "rtu", NULL), &sdate, &stime, &time_unit);
   int tunitsec = get_tunitsec(time_unit);
   juldate_t ref_date = juldate_encode(calendar, sdate, stime);
   char *frequency = NULL;
-  if ( time_axis != 3 )
+  if ( time_axis != 4 )
     frequency = get_frequency(kvl, *streamID, vlistID, taxisID, miptab_freq);
   if ( cdoVerbose )
-    printf("\n*******Succesfully retrieved time value from 'required_time_units' and frequency.******\n");
+    cdoPrint("10.1. Successfully retrieved frequency.");
+
 
   int ifreq = 0;
   if ( frequency )
@@ -3214,10 +4050,11 @@ static void write_variables(list_t *kvl, int *streamID, struct mapping vars[], i
         ifreq = 3;
     }
 
+  if ( cdoVerbose )
+    cdoPrint("10.2. Start to get chunk files.");
   char **chunk_files = get_chunk_files(kvl, vars, vlistID, ifreq, time_axis, calendar, miptab_freqptr);
-
   if ( cdoVerbose )
-    printf("\n*******Start to write variables via cmor_write.******\n");
+    cdoPrint("10.2. Successfully retrieved chunk files.");
   int i = 0;
 
   int zaxisID, zsize, pscheck = 1;
@@ -3225,28 +4062,36 @@ static void write_variables(list_t *kvl, int *streamID, struct mapping vars[], i
   for ( i = 0; vars[i].cdi_varID != CDI_UNDEFID; i++ )
     if ( vars[i].charvars )
       {
+        if ( cdoVerbose )
+          cdoPrint("10.3. Start to get auxiliary variables.");
         zaxisID = vlistInqVarZaxis(vlistID, vars[i].cdi_varID);
         zsize = zaxisInqSize(zaxisID);
-        charname = Malloc(CDI_MAX_NAME * sizeof(char));
+        charname = (char *) Malloc(CDI_MAX_NAME * sizeof(char));
         vlistInqVarName(vlistID, vars[i].cdi_varID, charname);
         
         pstreamClose(*streamID);
         *streamID = pstreamOpenRead(cdoStreamName(0));
         pscheck = 0;
+        if ( cdoVerbose )
+          cdoPrint("10.3. Successfully retrieved auxiliary variables.");
         break;
       }
-  if ( !pscheck )
-    cdoWarning("Since you defined a variable with character coordinate axis you cannot write another variable with zaxis of type ZAXIS_HYBRID.");
+  if ( pscheck == 0 )
+    cdoPrint("Since you defined a variable with character coordinate axis you cannot write another variable with zaxis of type ZAXIS_HYBRID.");
 
+  if ( cdoVerbose )
+    cdoPrint("10.4. Start to loop over time steps.");
   while ( (nrecs = pstreamInqTimestep(*streamID, tsID++)) )
     { 
       double time_bnds[2];
       double *time_bndsp;
+      juldate_t jtime_val;
       double time_val;
-      if ( time_axis != 3 )
+      if ( time_axis != 4 )
         {
-          time_val = get_cmor_time_val(taxisID, ref_date, tunitsec, calendar);
-          time_bndsp = ( time_axis != 1 ) ? get_time_bounds(taxisID, frequency, ref_date, time_val, calendar, tunitsec, time_bnds) : 0;
+          jtime_val = get_cmor_time_val(taxisID, ref_date, tunitsec, calendar, frequency, tsID);
+          time_val = juldate_to_seconds(juldate_sub(jtime_val, ref_date)) / tunitsec;
+          time_bndsp = ( time_axis != 1 ) ? get_time_bounds(kvl, taxisID, frequency, ref_date, jtime_val, calendar, tunitsec, time_bnds, time_axis) : 0;
         }
       while ( nrecs-- )
         read_record(*streamID, vars, vlistID);
@@ -3260,14 +4105,15 @@ static void write_variables(list_t *kvl, int *streamID, struct mapping vars[], i
           vlistInqVarName(vlistID, vars[i].cdi_varID, name); */
           if ( !vars[i].help_var )
             {
-              if ( time_axis != 3 )
+              if ( time_axis != 4 )
                 {
                   if ( vars[i].charvars )
                     {
-                      void *dataslice = Malloc(gridsize * zsize * sizeof(double));
+                      void *dataslice = (void *) Malloc(gridsize * zsize * sizeof(double));
                       for ( int j = 0; j < gridsize * zsize; j++ )
                         ((double *)dataslice)[j] = ((double *)vars[i].data)[(tsID-1)*gridsize*zsize+j];
-                      cmor_write(vars[i].cmor_varID,
+                      #if ( CMOR_VERSION_MAJOR == 2 )
+                        cmf = cmor_write(vars[i].cmor_varID,
                        dataslice,
                        vars[i].datatype,
                        chunk_files[i],
@@ -3276,9 +4122,21 @@ static void write_variables(list_t *kvl, int *streamID, struct mapping vars[], i
                        time_bndsp,
                        NULL);
                       Free(dataslice);
+                      #elif ( CMOR_VERSION_MAJOR == 3 )
+                        cmf = cmor_write(vars[i].cmor_varID,
+                       dataslice,
+                       vars[i].datatype,
+                       1,
+                       &time_val,
+                       time_bndsp,
+                       NULL);
+                      Free(dataslice);
+                      #endif
                     } 
                   else
-                    cmor_write(vars[i].cmor_varID,
+                    {
+                      #if ( CMOR_VERSION_MAJOR == 2 )
+                        cmf = cmor_write(vars[i].cmor_varID,
                      vars[i].data,
                      vars[i].datatype,
                      chunk_files[i],
@@ -3286,8 +4144,20 @@ static void write_variables(list_t *kvl, int *streamID, struct mapping vars[], i
                      &time_val,
                      time_bndsp,
                      NULL); 
+                      #elif ( CMOR_VERSION_MAJOR == 3 )
+                        cmf = cmor_write(vars[i].cmor_varID,
+                     vars[i].data,
+                     vars[i].datatype,
+                     1,
+                     &time_val,
+                     time_bndsp,
+                     NULL); 
+                      #endif
+                    }
                   if ( vars[i].zfactor_id > 0 )
-                    cmor_write(vars[i].zfactor_id,
+                    {
+                      #if ( CMOR_VERSION_MAJOR == 2 )
+                        cmf = cmor_write(vars[i].zfactor_id,
                        vars[ps_index].data,
                        vars[ps_index].datatype,
                        chunk_files[i],
@@ -3295,19 +4165,42 @@ static void write_variables(list_t *kvl, int *streamID, struct mapping vars[], i
                        &time_val,
                        time_bndsp,
                        &vars[i].cmor_varID);
+                     #elif ( CMOR_VERSION_MAJOR == 3 )
+                        cmf = cmor_write(vars[i].zfactor_id,
+                       vars[ps_index].data,
+                       vars[ps_index].datatype,
+                       1,
+                       &time_val,
+                       time_bndsp,
+                       &vars[i].cmor_varID);
+                     #endif
+                    }
                 }
               else
-                cmor_write(vars[i].cmor_varID,
+                {
+                  #if ( CMOR_VERSION_MAJOR == 2 )
+                    cmf = cmor_write(vars[i].cmor_varID,
                    vars[i].data,
                    vars[i].datatype,
                    chunk_files[i], 0, 0, 0, NULL);
+                  #elif ( CMOR_VERSION_MAJOR == 3 )
+                    cmf = cmor_write(vars[i].cmor_varID,
+                   vars[i].data,
+                   vars[i].datatype,
+                   0, 0, 0, NULL);
+                  #endif 
+                }
             }
         }
     }
+  if ( cmf != 0 )
+    cdoAbort("Function cmor_write failed!");
+  if ( cdoVerbose )
+    cdoPrint("10.4. Successfully looped over time steps.");
   if ( cdoVerbose )
-    printf("\n*******Succesfully written variables via cmor_write.******\n");
+    cdoPrint("10. Successfully written variables via cmor_write.");
   if ( cdoVerbose )
-    printf("\n*******Start to close files and free allocated memory.******\n");
+    cdoPrint("11. Start to close files, free allocated memory and, if necessary, write chunk files.");
   char **chunkdf = NULL;
   if ( strcmp(kv_get_a_val(kvl, "om", ""), "a") == 0 && strcmp(kv_get_a_val(kvl, "d", "y"), "y") == 0 )
     chunkdf = get_chunk_des_files(kvl, vars, miptab_freqptr, i, vlistID, charname);
@@ -3317,36 +4210,42 @@ static void write_variables(list_t *kvl, int *streamID, struct mapping vars[], i
     {
       if ( !vars[i].help_var )
         {
-          cmor_close_variable(vars[i].cmor_varID, file_name, NULL);
-          printf("*******File stored in:  '%s' with cmor!*******\n", file_name);
+          cmf = cmor_close_variable(vars[i].cmor_varID, file_name, NULL);
+          cdoPrint("     File stored in:  '%s' with cmor!", file_name);
           if ( chunkdf )
             {
               if ( cdoVerbose )
-                printf("*******Start to write a chunk description file.******\n");
+                cdoPrint("11.2. Start to write a chunk description file.");
               FILE *fp = fopen(chunkdf[i], "w+"); 
               if ( fp )
                 fprintf(fp, "%s", file_name);
               else
                 {
-                  if ( cdoVerbose )
-                    printf("Could not open a chunk description file '%s'.\n", chunkdf[i]);
+                  cdoPrint("Could not open a chunk description file '%s'.", chunkdf[i]);
                   continue;
                 }
               fclose(fp);  
               if ( cdoVerbose )
-                printf("*******Succesfully written a chunk description file '%s'******\n" , chunkdf[i]);            
+                cdoPrint("11.2. Successfully written a chunk description file '%s'." , chunkdf[i]);            
             }         
         }
     }
+  if ( cmf != 0 )
+    cdoAbort("Function cmor_close_variable failed!");
 
 
   if (frequency) Free(frequency); if (chunk_files) free_array(chunk_files); if (chunkdf) free_array(chunkdf); if (charname) Free(charname);
   if ( cdoVerbose )
-    printf("\n*******Succesfully closed files and freed allocated memory.******\n");
+    cdoPrint("11. Successfully closed files and freed allocated memory.");
 }
 
-static list_t *check_for_charvars(list_t *maptab, char *key)
+static list_t *check_for_charvars(list_t *maptab, const char *key)
 {
+/***/
+/* If a mapping table variable selector (name or code) has more than one value, it must be a character coordinate*/
+/* If it is given as a string and the string contains a ',', */
+/* it must be divided into several values and is a variable with character coordinate */
+/***/
   listNode_t *node = maptab->head;
   while ( node )
     {
@@ -3364,11 +4263,13 @@ static list_t *check_for_charvars(list_t *maptab, char *key)
             }
           if ( kvn && kvn->nvalues > 1 )
             return kvlist;
+
           if ( kvn && strstr(kvn->values[0], ",") && kvn->nvalues == 1 )
             {
-              char *workchar = strdup(kvn->values[0]);
+              char *workchar2 = strdup(kvn->values[0]);
               Free(kvn->values[0]); Free(kvn->values);
-              char *thepoint = workchar;
+              char *workchar = workchar2;
+              char *thepoint = workchar2;
               int i = 0, j = 0;
               while ( *thepoint != '\0' )
                 {
@@ -3385,7 +4286,7 @@ static list_t *check_for_charvars(list_t *maptab, char *key)
                 {
                   if ( *thepoint == ',')
                     {
-                      kvn->values[j] = Malloc( (i+1) * sizeof(char) );
+                      kvn->values[j] = (char *)Malloc( (i+1) * sizeof(char) );
                       strncpy(kvn->values[j], workchar, i);
                       kvn->values[j][i] = '\0';
                       j++; thepoint++; workchar+=i+1; i = 0;
@@ -3397,16 +4298,18 @@ static list_t *check_for_charvars(list_t *maptab, char *key)
                 }
               if ( i > 0 )
                 {
-                  kvn->values[j] = Malloc( (i+1) * sizeof(char) );
+                  kvn->values[j] = (char *)Malloc( (i+1) * sizeof(char) );
                   strncpy(kvn->values[j], workchar, i);
                   kvn->values[j][i] = '\0';
                   workchar+=i; i = 0; j++; 
                 }
               else
                 {
-                  cdoWarning("Names in String for key '%s' could not be interpreted correctly due to a comma at end of line.");
+                  Free(workchar2);
+                  cdoWarning("In checking for variables with character coordinate:\n          Names in String for key '%s' could not be interpreted correctly due to a comma at end of line.", key);
                   return NULL;
                 }
+              Free(workchar2);
               return kvlist;
             }
         }
@@ -3417,16 +4320,23 @@ static list_t *check_for_charvars(list_t *maptab, char *key)
 
 static void read_maptab(list_t *kvl, int streamID, char *miptabfreq, struct mapping vars[])
 {
+/***/
+/* Build mapping table from a combination of two attributes if mt does not begin with / and a directory path is given */
+/***/
+  if ( cdoVerbose )
+    cdoPrint("5. Start to find, read and apply mapping table.");
   char *maptab = kv_get_a_val(kvl, "mt", NULL);
   char *maptabdir = kv_get_a_val(kvl, "mapping_table_dir", NULL);
   char *maptabbuild = NULL;
   keyValues_t *kvn = kvlist_search(kvl, "n");
   keyValues_t *kvc = kvlist_search(kvl, "c");
   keyValues_t *kvcn = kvlist_search(kvl, "cn");
+  int byteorder;
+  int filetype = cdiGetFiletype(cdoStreamName(0)->args, &byteorder);
 
   if ( maptab && maptabdir ) if ( maptab[0] != '/' )
     {
-      maptabbuild = Malloc((strlen(maptab)+strlen(maptabdir)+2) * sizeof(char));
+      maptabbuild = (char *) Malloc((strlen(maptab)+strlen(maptabdir)+2) * sizeof(char));
       sprintf(maptabbuild, "%s/%s\0", maptabdir, maptab);
     }
   if ( maptab )
@@ -3434,20 +4344,41 @@ static void read_maptab(list_t *kvl, int streamID, char *miptabfreq, struct mapp
       if ( maptabbuild ) maptab = maptabbuild;
       int vlistID = pstreamInqVlist(streamID);
 
+/***/
+/* Parse the table as a fortran namelist wich contains lists (=lines) of keyvalues */
+/***/
       if ( cdoVerbose )
-        printf("*******Try to apply mapping table: '%s'*******\n", maptab);
-      list_t *pml = cdo_parse_cmor_file(maptab);
+        cdoPrint("5.1 Try to read mapping table: '%s'", maptab);
+      kv_insert_a_val(kvl, "workfile4err", maptab, 1);
+      list_t *pml = cdo_parse_cmor_file(maptab, kvl);
       if ( pml == NULL )
         {
-          cdoWarning("Mapping table: '%s' could not be parsed. Operator continues.", maptab);
+          cdoWarning("5.1. In parsing the mapping table '%s':\n          Mapping table could not be parsed. Operator continues.", maptab);
           return;
         }
       const char *ventry[] = {"&parameter"};
       int nventry = (int) sizeof(ventry)/sizeof(ventry[0]);
-
       list_t *charvarlist = NULL; 
+/***/
+/* If a variable selector name or code is given in cmdline, the corresponding variable is picked from Infile and mapped. */
+/* Only the first value of name/code given in the cmdline is processed */
+/* If no variable selector is given, process all variables and map via name and code */
+/***/
+/* However, if the mapping table contains a keyvalue pair for name or code with more than one value, */
+/* the corresponding variable has a character coordinate and requires special treatment */
+/* This is tested once before mapping. If the special variable equals the variable which is to map,
+/* the special treatment begins with fct addcharvar */
+/***/
+/* Different CMOR variables are built with one model variable. */
+/* Consequently, for one model variable more than one mapping table entry can exist */
+/* As a second identification argument, the mapping table name (miptabfreq) is used */
+/***/
+/* If no variable selector is given in the mapping table, it is assumed that the infile variable is already named like cmor_name */
+/***/
       if ( kvn )
         {
+          if ( filetype == FILETYPE_GRB || filetype ==  FILETYPE_GRB2 )
+            cdoPrint("5.1. In applying the mapping table:\n          Note that you use 'name' as selector keyword allthough the type of infile is GRB.");
           if ( charvarlist = check_for_charvars(pml, "name") )
             {
               keyValues_t *charkvn = kvlist_search(charvarlist, "name");
@@ -3457,10 +4388,10 @@ static void read_maptab(list_t *kvl, int streamID, char *miptabfreq, struct mapp
                 addcharvar(charkvn, vlistID, "name", vars);
             }
           if ( kvn->nvalues > 1 )
-            cdoWarning("Only the first value of variable selection key 'name' is processed.");
+            cdoWarning("5.1. In applying the mapping table '%s':\n          Only the first value of commandline variable selection key 'name' is processed.", maptab);
           maptab_via_cmd(pml, kvn->values[0], vlistID, vlistNvars(vlistID),  "name", kvcn->values[0], miptabfreq);
           if ( cdoVerbose )
-            printf("*******Successfully read mapping '%s' table.*******\n", maptab);
+            cdoPrint("5. Successfully found, read and applied mapping table '%s'.", maptab);
         }
       else if ( kvc )
         {
@@ -3473,10 +4404,10 @@ static void read_maptab(list_t *kvl, int streamID, char *miptabfreq, struct mapp
                 addcharvar(charkvc, vlistID, "code", vars);
             }
           if ( kvc->nvalues > 1 )
-            cdoWarning("Only the first value of variable selection key 'code' is processed.");
+            cdoWarning("5.1. In applying the mapping table '%s':\n          Only the first value of commandline variable selection key 'code' is processed.", maptab);
           maptab_via_cmd(pml, kvc->values[0], vlistID, vlistNvars(vlistID), "code", kvcn->values[0], miptabfreq);
           if ( cdoVerbose )
-            printf("*******Successfully read mapping '%s' table.*******\n", maptab);
+            cdoPrint("5. Successfully found, read and applied mapping table '%s'.", maptab);
         }
       else if ( kvcn )
         { 
@@ -3488,9 +4419,9 @@ static void read_maptab(list_t *kvl, int streamID, char *miptabfreq, struct mapp
               else if ( strcmp(charkvcn->values[0], kvcn->values[0]) == 0 )
                 addcharvar(charkvn, vlistID, "name", vars);
             }
-          maptab_via_cn(pml, kvcn->values, vlistID, vlistNvars(vlistID), kvcn->nvalues, miptabfreq); 
+          maptab_via_cn(pml, kvcn->values, vlistID, vlistNvars(vlistID), kvcn->nvalues, miptabfreq, filetype); 
           if ( cdoVerbose )
-            printf("*******Successfully read mapping '%s' table.*******\n", maptab);
+            cdoPrint("5. Successfully found, read and applied mapping table '%s'.", maptab);
         }
       else
         {
@@ -3504,59 +4435,53 @@ static void read_maptab(list_t *kvl, int streamID, char *miptabfreq, struct mapp
             }
           for ( int varID = 0; varID < vlistNvars(vlistID); varID++ )
             {
+/***/
+/* Begin with Code in case infile is of type GRB */
+/***/
+              if ( filetype == FILETYPE_GRB || filetype ==  FILETYPE_GRB2 )
+                if ( maptab_via_key(pml, vlistID, varID, nventry, ventry, "code", miptabfreq) )
+                  {
+                    if ( cdoVerbose )
+                      cdoPrint("5.1. Successfully mapped varID '%d' via code.", varID);
+                    continue;
+                  }
               if ( maptab_via_key(pml, vlistID, varID, nventry, ventry, "name", miptabfreq) )
                 {
-                  printf("*******Successfully mapped varID '%d' via name.*******\n", varID);
+                  if ( cdoVerbose )
+                    cdoPrint("5.1. Successfully mapped varID '%d' via name.", varID);
                   continue;
                 }
               if ( maptab_via_key(pml, vlistID, varID, nventry, ventry, "code", miptabfreq) )
                 {
-                  printf("*******Successfully mapped varID '%d' via code.*******\n", varID);
+                  if ( cdoVerbose )
+                    cdoPrint("5.1. Successfully mapped varID '%d' via code.", varID);
+                  continue;
+                }
+/***/
+/* In case corresponding mapping table entry does not contain a variable selector attribute */
+/***/
+              if ( maptab_via_key(pml, vlistID, varID, nventry, ventry, "cmor_name", miptabfreq) )
+                {
+                  if ( cdoVerbose )
+                    cdoPrint("5.1. Successfully mapped varID '%d' via cmor_name.", varID);
                   continue;
                 }
-              cdoWarning("Could not map variable with id '%d'.", varID);
+              cdoWarning("5.1. In applying the mapping table '%s':\n          Could not map variable with id '%d'.", maptab, varID);
             }
         }
+/***/
+/* In case a requested variable needs an auxilliary variable, the latter may be mapped later. */
+/* If a mapping table exists is saved here */
+/***/
       kv_insert_a_val(kvl, "mtproof", maptab, 1);
       list_destroy(pml);
       if ( maptabbuild ) Free(maptabbuild);
     }
   else if ( cdoVerbose )
-    printf("*******No mapping table found.*******\n");
-}
-
-static char *check_short_key(char *key)
-{
-  char *short_keys[]={"cn", "n", "c", "u", "cm", "vc", "p", "szc", "i", "ca", "gi", "rtu", "mt", "om", "ms", "dr", "d", "lc", NULL};
-  char *long_keys[]={"cmor_name", "name", "code", "units", "cell_methods", "variable_comment", "positive", "scalar_z_coordinate", "info", "character_axis", "grid_info", "required_time_units", "mapping_table", "output_mode", "max_size", "drs_root", "drs", "last_chunk", NULL};
-
-  for ( int i = 0; short_keys[i]; i++ )
-    if ( strcmp(key, short_keys[i]) == 0 || strcmp(key, long_keys[i]) == 0 )
-      return short_keys[i];
-/*  if ( strcmp(key, "cmor_name") == 0 ) short_key = strdup("cn");
-  else if ( strcmp(key, "name") == 0 ) short_key = strdup("n");
-  else if ( strcmp(key, "code") == 0 ) short_key = strdup("c");
-  else if ( strcmp(key, "units") == 0 ) short_key = strdup("u");
-  else if ( strcmp(key, "cell_methods") == 0 ) short_key = strdup("cm");
-  else if ( strcmp(key, "comment") == 0 ) short_key = strdup("k");
-  else if ( strcmp(key, "positive") == 0 ) short_key = strdup("p");
-  else if ( strcmp(key, "scalar_z_coordinate") == 0 ) short_key = strdup("szc");
-  else if ( strcmp(key, "info") == 0 ) short_key = strdup("i");
-  else if ( strcmp(key, "character_axis") == 0 ) short_key = strdup("ca");
-  else if ( strcmp(key, "grid_info") == 0 ) short_key = strdup("gi");
-  else if ( strcmp(key, "required_time_units") == 0 ) short_key = strdup("rtu");
-  else if ( strcmp(key, "mapping_table") == 0 ) short_key = strdup("mt");
-  else if ( strcmp(key, "calendar") == 0 ) short_key = strdup("l");
-  else if ( strcmp(key, "output_mode") == 0 ) short_key = strdup("om");
-  else if ( strcmp(key, "max_size") == 0 ) short_key = strdup("ms");
-  else if ( strcmp(key, "drs_root") == 0 ) short_key = strdup("dr");
-  else if ( strcmp(key, "no_drs") == 0 ) short_key = strdup("d");
-  else if ( strcmp(key, "last_chunk") == 0 ) short_key = strdup("lc"); */
-  cdoWarning("Unknown commandline keyword: '%s'\n", key);
-  return NULL;
+    cdoPrint("5. No mapping table found.");
 }
 
-static void parse_cmdline(list_t *pml, char **params, int nparams, char *ventry)
+static void parse_cmdline(list_t *pml, char **params, int nparams, const char *ventry)
 {
   list_t *kvl = NULL;
   kvl = list_new(sizeof(keyValues_t *), free_keyval, ventry);
@@ -3565,13 +4490,13 @@ static void parse_cmdline(list_t *pml, char **params, int nparams, char *ventry)
   char *key = NULL, *eqpos = NULL;
   char **values = NULL;
   int i = 1, j = 0;
-  while ( params[i] )
+  for ( i = 1; i < nparams; i++ )
     {
       if ( eqpos = strchr(params[i], '=')  )
         {
           if ( key && values[0] )
             {
-              char *short_key = check_short_key(key);
+              const char *short_key = check_short_key(key);
               if ( short_key )
                 {
                   if ( strcmp(short_key, key) != 0 )
@@ -3581,30 +4506,37 @@ static void parse_cmdline(list_t *pml, char **params, int nparams, char *ventry)
                     }
                   kvlist_append(kvl, (const char *)key, (const char **) values, j);
                 }
+              else
+                cdoWarning("Unknown commandline keyword: '%s'\n", key);
               Free(key);
               free_array(values);
             }
           else if ( key )
-            cdoAbort("Found no value for key '%s'.", key);
+            cdoAbort("Could not find values for commandline keyword: '%s'.", key);
           if ( strlen(eqpos) == 1 )
-            cdoAbort("Could not find values for commandline parameter: '%s'\n", params[i]);
+            cdoAbort("Could not find values for commandline parameter: '%s'.", params[i]);
           key = strdup(strtok(params[i], "="));
-          values = Malloc(100 * sizeof(char *));
+          values = (char **) Malloc(100 * sizeof(char *));
           j = 0;   
-          copy_value(strtok(NULL, ""), values, &j);  
+          int errh = copy_value(strtok(NULL, ""), values, &j);
+          if ( errh > 0 )
+            handleError(NULL, errh, NULL);
         }
       else
         {
           if ( !key )
             cdoAbort("Found no key for value '%s'.", params[i]);
           else
-            copy_value(params[i], values, &j);
+            {
+              int errh = copy_value(params[i], values, &j);
+              if ( errh > 0 )
+                handleError(NULL, errh, NULL);
+            }
         }
-      i++;
     }
   if ( key && values )
     {
-      char *short_key = check_short_key(key);
+      const char *short_key = check_short_key(key);
       if ( short_key )
         {
           if ( strcmp(short_key, key) != 0 )
@@ -3618,31 +4550,48 @@ static void parse_cmdline(list_t *pml, char **params, int nparams, char *ventry)
       free_array(values);
     }
   else if ( values )
-    cdoAbort("Found no key for value '%s'.", params[i-1]);
+    cdoAbort("Found no commandline keyword for value '%s'.", params[i-1]);
 }
 
 static char *get_mip_table(char *params, list_t *kvl, char *project_id)
 {
+  char *miptab;
+  if ( cdoVerbose )
+    cdoPrint("2.2. Start to find a MIP table file.");
   if ( !params )
-    cdoAbort("A mip table name or path is required as first argument. No first argument found.");
-  if ( file_exist(params, 0) )
-    return params;
+    cdoAbort("In finding the MIP table:\n          A mip table name or path is required as first argument. No first argument found.");
+  if ( file_exist(params, 0, "MIP table") )
+    {
+      miptab = strdup(params);
+      if ( cdoVerbose )
+        cdoPrint("2.2. MIP table file '%s' exists.", miptab);
+      return miptab;
+    }
   else
     {
-      cdoWarning("Your first argument is not an existing file. It is tried to build a path with additional configuration attributes 'mip_table_dir' and 'project_id'");
+      cdoPrint("In finding the MIP table:\n          Your first argument is not an existing mip table file.\n          It is tried to build a path with additional configuration attributes 'mip_table_dir' and 'project_id'");
       char *miptabdir = kv_get_a_val(kvl, "mip_table_dir", NULL);
       if ( miptabdir && project_id )
         {
-          char *miptab = Malloc((strlen(miptabdir)+strlen(project_id)+strlen(params)+3) * sizeof(char));
+#if ( CMOR_VERSION_MAJOR == 2 )
+          {
+          miptab = (char *)Malloc((strlen(miptabdir)+strlen(project_id)+strlen(params)+3) * sizeof(char));
           sprintf(miptab, "%s/%s_%s\0", miptabdir, project_id, params);
-          if ( file_exist(miptab, 0) )
-            return miptab;
-          else
-            cdoAbort("Could not open mip table '%s'.", miptab);
+          }
+#elif ( CMOR_VERSION_MAJOR == 3 )
+          {
+          miptab = (char *)Malloc((strlen(miptabdir)+strlen(project_id)+strlen(params)+8) * sizeof(char));
+          sprintf(miptab, "%s/%s_%s.json\0", miptabdir, project_id, params);
+          }
+#endif
+          file_exist(miptab, 1, "MIP table");
+          if ( cdoVerbose )
+            cdoPrint("2.2. MIP table file '%s' exists.", miptab);
+          return miptab;
         }
       else
-        cdoAbort("Could not build a mip table path.");
-    }        
+        cdoAbort("In finding the MIP table:\n          Could not find attribute 'mip_table_dir'.");
+    }   
 }
 
 static char *freq_from_path(char *mip_table)
@@ -3663,37 +4612,120 @@ static char *freq_from_path(char *mip_table)
   return freq;
 }
 
-static void save_miptab_freq(list_t *kvl, char *mip_table, int *miptab_freq)
+static int get_miptab_freq(list_t *kvl, char *mip_table, char *project_id)
 {
+  int miptab_freq = 0;
   char *freq = freq_from_path(mip_table);
   if ( freq != NULL )
     {
       if ( strstr(freq, "yr") || strstr(freq, "Yr") )
-        *miptab_freq = 11;
+        miptab_freq = 11;
       else if ( strstr(freq, "mon") || strstr(freq, "Mon") )
-        *miptab_freq = 12;
+        miptab_freq = 12;
       else if ( strstr(freq, "day") || strstr(freq, "Day") )
-        *miptab_freq = 13;
+        miptab_freq = 13;
       else if ( strstr(freq, "6hr") )
-        *miptab_freq = 14;
+        miptab_freq = 14;
       else if ( strstr(freq, "3hr") )
-        *miptab_freq = 15;
+        miptab_freq = 15;
 
       if ( strcmp(freq, "Oclim") == 0 )
-        *miptab_freq = 1;
+        miptab_freq = 1;
       else if ( strcmp(freq, "Oyr") == 0 )
-        *miptab_freq = 2;
+        miptab_freq = 2;
       else if ( strcmp(freq, "cfMon") == 0 )
-        *miptab_freq = 3;
+        miptab_freq = 3;
       else if ( strcmp(freq, "day") == 0 )
-        *miptab_freq = 4;
-      else if ( strcmp(freq, "6hrPlev") == 0 )
-        *miptab_freq = 5;
+        miptab_freq = 4;
+      else if ( strcmp(freq, "6hrPlev") == 0 && strcmp(project_id, "CMIP5") == 0 )
+        miptab_freq = 5;
+      else if ( strcmp(freq, "6hrPlevPt") == 0 )
+        miptab_freq = 5;
       else if ( strcmp(freq, "6hrLev") == 0 )
-        *miptab_freq = 6;
+        miptab_freq = 6;
+      else if ( strcmp(freq, "E1hrClimMon") == 0 )
+        miptab_freq = 7;
+    }
+  return miptab_freq;
+}
+
+static void check_cmdline_mapping(list_t *kvl)
+{
+  char *name = kv_get_a_val(kvl, "n", NULL);
+  char *code = kv_get_a_val(kvl, "c", NULL);
+  char *cn = kv_get_a_val(kvl, "cn", NULL);
+  if ( ( name && code ) )
+    cdoAbort("Mapping via command line failed. Only one variable selector of 'name' and 'code' is allowed.");
+  if ( ( name && !cn ) || ( code && !cn ) )
+    cdoAbort("Mapping via command line failed. A corresponding 'cmor_name' is needed.");
+}
+
+static char *get_project_id(list_t *kvl)
+{
+  if ( cdoVerbose )
+    cdoPrint("2.1. Start to check whether 'project_id' or 'mip_era' is denoted.");
+  char *project_id, *dummy, *dummy2;
+  dummy = kv_get_a_val(kvl, "project_id", NULL);
+  dummy2 = kv_get_a_val(kvl, "mip_era", NULL);
+#if defined(CMOR_VERSION_MAJOR)
+#if ( CMOR_VERSION_MAJOR == 2 )
+{
+  if ( !dummy && !dummy2)
+    cdoAbort("Attribute 'project_id' is required.");
+  else if ( !dummy )
+    cdoAbort("Cannot produce CMIP6 standard with CMOR2.\n          Value for attribute 'project_id' is required.");
+  else
+    project_id = strdup(dummy);
+}
+#elif ( CMOR_VERSION_MAJOR == 3 )
+{
+  if ( !dummy && !dummy2)
+    cdoAbort("Attribute 'mip_era' or 'project_id' is required.");
+  else if ( !dummy2 )
+    {
+      cdoWarning("You try to produce CMIP5 standard with CMOR3.\n          It is recommended to use CMOR2 for this job instead.");
+      project_id = strdup(dummy);
     }
+  else
+    project_id = strdup(dummy2);
+}
+#endif
+#else
+  cdoAbort("Cannot check CMOR version: Missing makro CMOR_VERSION_MAJOR");
+#endif
+
+  if ( cdoVerbose )
+    cdoPrint("2.1. Successfully found project_id / mip_era: '%s'.", project_id);
+  return project_id;
+}
+
+
+static int cmor_load_and_set_table(list_t *kvl, char *param0, char *project_id, char **mip_table)
+{
+  int table_id = 0, cmf = 0;
+#if ( CMOR_VERSION_MAJOR == 3 )
+  Free(*mip_table);
+  cdoPrint("Need to get the mip_table once more.");
+  *mip_table = get_mip_table(param0, kvl, project_id);
+#endif
+  cmf = cmor_load_table(*mip_table, &table_id);
+  if ( cmf != 0 )
+    cdoAbort("Function cmor_load_table failed!");
+  cmf = cmor_set_table(table_id);
+  if ( cmf != 0 )
+    cdoAbort("Function cmor_set_table failed!");
+  return table_id;
 }
 
+static void removeDataset()
+{
+  char cwd[1024];
+  getcwd(cwd, sizeof(cwd));
+  int procID = getpid();
+  char *dataset_path = (char *) Malloc( (strlen(cwd) + 1 + strlen("dataset.json") + 3) * sizeof(char));;
+  sprintf(dataset_path, "%s/dataset%d.json\0", cwd, procID);
+  remove(dataset_path);
+}
 #endif
 
 void *CMOR(void *argument)
@@ -3701,8 +4733,10 @@ void *CMOR(void *argument)
   cdoInitialize(argument);
 
 #if defined(HAVE_LIBCMOR)
+  signal(SIGTERM, sigfunc);
   int nparams = operatorArgc();
   char **params = operatorArgv();
+  char *miptableInput = strdup(params[0]);
 
   /* Definition of pml: */
   list_t *pml = list_new(sizeof(list_t *), free_kvlist, "pml");
@@ -3715,76 +4749,69 @@ void *CMOR(void *argument)
   const char *pmlistHelper[] = {"cmdline"};
   /* Get kvl and use it from now on instead of pml */
   list_t *kvl = pmlist_get_kvlist_ventry(pml, 1, pmlistHelper);
-  char *name = kv_get_a_val(kvl, "n", NULL);
-  char *code = kv_get_a_val(kvl, "c", NULL);
-  char *cn = kv_get_a_val(kvl, "cn", NULL);
-  if ( ( name && code ) )
-    cdoAbort("Mapping via command line failed. Only one variable selector of 'name' and 'code' is allowed.");
-  if ( ( name && !cn ) || ( code && !cn ) )
-    cdoAbort("Mapping via command line failed. A corresponding 'cmor_name' is needed.");
+
+  /* Check whether a command line mapping is active */
+  check_cmdline_mapping(kvl);
 
   /* Config files are read with descending priority. */
-  if ( cdoVerbose )
-    printf("*******Start to read configuration files.*******\n");
   read_config_files(kvl);
-  if ( cdoVerbose )
-    printf("*******Successfully read configuration files.*******\n");
 
-  /* check MIP table, MIP table frequency and project_id*/
+  /* Get project_id, mip_table and mip_table frequency*/
   if ( cdoVerbose )
-    printf("*******Start to check MIP table, MIP table frequency and project_id.*******\n");
-  int miptab_freq = 0, time_axis = 0, calendar = 0;
-  char *project_id, *dummy;
-  if ( !(dummy = kv_get_a_val(kvl, "project_id", NULL) ) )
-    cdoAbort("Value for attribute 'project_id' is required.");
-  else
-    project_id = strdup(dummy);
-  char *mip_table = get_mip_table(params[0], kvl, project_id);
-  save_miptab_freq(kvl, mip_table, &miptab_freq);
+    cdoPrint("2. Start to find a MIP table and to deduce a frequency from MIP table file.");
+  char *project_id = get_project_id(kvl);
+  char *mip_table  = get_mip_table(miptableInput, kvl, project_id);
+#if ( CMOR_VERSION_MAJOR == 3 )
+  mip_table[strlen(mip_table)-5] = '\0';
+#endif
+  int miptab_freq  = get_miptab_freq(kvl, mip_table, project_id);
+
   char *miptab_freqptr = strdup(freq_from_path(mip_table));
   kv_insert_a_val(kvl, "miptab_freq", miptab_freqptr, 1);
 
   if ( cdoVerbose )
-    printf("*******Successfully checked MIP table, MIP table frequency and project_id.*******\n");
-
+    cdoPrint("2. Successfully found a MIP table '%s' and deduced a MIP table frequency '%s'.", mip_table, miptab_freqptr);
 
+  if ( cdoVerbose )
+    cdoPrint("3. Start to open infile '%s'.", cdoStreamName(0)->args);
   int streamID = pstreamOpenRead(cdoStreamName(0));
-  /* Existing attributes have lowest priority. */
-  dump_special_attributes(kvl, streamID);
+  if ( cdoVerbose )
+    cdoPrint("3. Successfully opened infile '%s'.", cdoStreamName(0)->args);
+  /* Short keys from rtu, mt, gi must be included similar to global atts */
+  add_globalhybrids(kvl);
 
   /* Check for attributes and member name */
   if ( cdoVerbose )
-    printf("*******Start to check attributes.*******\n");
+    cdoPrint("4. Start to check attributes.");
   check_attr(kvl, project_id);
   check_mem(kvl, project_id);
   if ( cdoVerbose )
-    printf("*******Successfully checked global attributes.*******\n");
+    cdoPrint("4. Successfully checked global attributes.");
 
  /* dump_global_attributes(pml, streamID); */
 
   struct mapping *vars = construct_var_mapping(streamID);
 
  /* read mapping table */
-  if ( cdoVerbose )
-    printf("*******Start to read mapping table.*******\n");
   read_maptab(kvl, streamID, miptab_freqptr, vars);
 
-  if ( cdoVerbose )
-    printf("*******Start to use cmor_setup.*******\n");
+  int time_axis = 0, calendar = 0;
+
   setup_dataset(kvl, streamID, &calendar);
-  if ( cdoVerbose )
-    printf("*******Succesfully used cmor_setup.*******\n");
 
-  int table_id;
-  cmor_load_table(mip_table, &table_id);
-  cmor_set_table(table_id);
+  int table_id = cmor_load_and_set_table(kvl, miptableInput, project_id, &mip_table);
 
   register_all_dimensions(kvl, streamID, vars, table_id, project_id, miptab_freq, &time_axis);
   write_variables(kvl, &streamID, vars, miptab_freq, time_axis, calendar, miptab_freqptr);
 
+#if ( CMOR_VERSION_MAJOR == 3 )
+  removeDataset();  
+#endif
   destruct_var_mapping(vars);
   Free(mip_table);
   Free(project_id); 
+  Free(miptab_freqptr);
+ /* Free(miptableInput); */
   list_destroy(pml); 
 
   pstreamClose(streamID);
diff --git a/src/Cat.cc b/src/Cat.cc
index 1c3f691..5868b88 100644
--- a/src/Cat.cc
+++ b/src/Cat.cc
@@ -67,7 +67,7 @@ void *Cat(void *argument)
           if ( ntsteps == 1 )
             {
               for ( varID = 0; varID < nvars; ++varID )
-                if ( vlistInqVarTsteptype(vlistID1, varID) != TSTEP_CONSTANT ) break;
+                if ( vlistInqVarTimetype(vlistID1, varID) != TIME_CONSTANT ) break;
 		  
               if ( varID == nvars ) ntsteps = 0;
             }
@@ -102,7 +102,7 @@ void *Cat(void *argument)
 		{
                   lconstvars = false;
 		  for ( varID = 0; varID < nvars; ++varID )
-		    vlistDefVarTsteptype(vlistID2, varID, TSTEP_INSTANT);
+		    vlistDefVarTimetype(vlistID2, varID, TIME_VARYING);
 		}
 
 	      pstreamDefVlist(streamID2, vlistID2);
@@ -136,7 +136,7 @@ void *Cat(void *argument)
 	      pstreamInqRecord(streamID1, &varID, &levelID);
 
               if ( lconstvars && tsID2 > 0 && tsID1 == 0 )
-                if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT )
+                if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT )
                   continue;
 
 	      pstreamDefRecord(streamID2, varID, levelID);
diff --git a/src/Change_e5slm.cc b/src/Change_e5slm.cc
index 670dff9..a3d31b6 100644
--- a/src/Change_e5slm.cc
+++ b/src/Change_e5slm.cc
@@ -80,13 +80,7 @@ void *Change_e5slm(void *argument)
 
   pstreamClose(streamIDslm);
 
-  for ( long i = 0; i < gridsize; ++i )
-    {
-      if ( cland[i] > 0 )
-	lsea[i] = false;
-      else
-	lsea[i] = true;
-    }
+  for ( long i = 0; i < gridsize; ++i ) lsea[i] = !(cland[i] > 0);
 
 
   int nvars = vlistNvars(vlistID1);
diff --git a/src/Cloudlayer.cc b/src/Cloudlayer.cc
index 8a961cc..7cb8fdd 100644
--- a/src/Cloudlayer.cc
+++ b/src/Cloudlayer.cc
@@ -276,7 +276,7 @@ void *Cloudlayer(void *argument)
 
   if ( nvars2 == 1 )
     {
-      varID = vlistDefVar(vlistID2, gridID, surfaceID, TSTEP_INSTANT);
+      varID = vlistDefVar(vlistID2, gridID, surfaceID, TIME_VARYING);
       vlistDefVarParam(vlistID2, varID, cdiEncodeParam(33, 128, 255));
       vlistDefVarName(vlistID2, varID, "cld_lay");
       vlistDefVarLongname(vlistID2, varID, "cloud layer");
@@ -284,19 +284,19 @@ void *Cloudlayer(void *argument)
     }
   else
     {
-      varID = vlistDefVar(vlistID2, gridID, surfaceID, TSTEP_INSTANT);
+      varID = vlistDefVar(vlistID2, gridID, surfaceID, TIME_VARYING);
       vlistDefVarParam(vlistID2, varID, cdiEncodeParam(34, 128, 255));
       vlistDefVarName(vlistID2, varID, "low_cld");
       vlistDefVarLongname(vlistID2, varID, "low cloud");
       vlistDefVarMissval(vlistID2, varID, missval);
 
-      varID = vlistDefVar(vlistID2, gridID, surfaceID, TSTEP_INSTANT);
+      varID = vlistDefVar(vlistID2, gridID, surfaceID, TIME_VARYING);
       vlistDefVarParam(vlistID2, varID, cdiEncodeParam(35, 128, 255));
       vlistDefVarName(vlistID2, varID, "mid_cld");
       vlistDefVarLongname(vlistID2, varID, "mid cloud");
       vlistDefVarMissval(vlistID2, varID, missval);
 
-      varID = vlistDefVar(vlistID2, gridID, surfaceID, TSTEP_INSTANT);
+      varID = vlistDefVar(vlistID2, gridID, surfaceID, TIME_VARYING);
       vlistDefVarParam(vlistID2, varID, cdiEncodeParam(36, 128, 255));
       vlistDefVarName(vlistID2, varID, "hih_cld");
       vlistDefVarLongname(vlistID2, varID, "high cloud");
diff --git a/src/Consecstat.cc b/src/Consecstat.cc
index 7b78041..63a4dea 100644
--- a/src/Consecstat.cc
+++ b/src/Consecstat.cc
@@ -25,7 +25,7 @@
 
    =============================================================================
    Created:  04/08/2010 11:58:01 AM
-    Author:  Ralf Mueller (ram), ralf.mueller at zmaw.de
+    Author:  Ralf Mueller (ram), ralf.mueller at mpimet.mpg.de
    Company:  Max-Planck-Institute for Meteorology
    =============================================================================
  */
diff --git a/src/Copy.cc b/src/Copy.cc
index 3f1946b..a872280 100644
--- a/src/Copy.cc
+++ b/src/Copy.cc
@@ -102,7 +102,7 @@ void *Copy(void *argument)
 	  if ( ntsteps == 1 )
 	    {
 	      for ( varID = 0; varID < nvars; ++varID )
-		if ( vlistInqVarTsteptype(vlistID1, varID) != TSTEP_CONSTANT ) break;
+		if ( vlistInqVarTimetype(vlistID1, varID) != TIME_CONSTANT ) break;
 	      
 	      if ( varID == nvars ) ntsteps = 0;
 	    }
@@ -111,7 +111,7 @@ void *Copy(void *argument)
 	    {	      
               lconstvars = false;
 	      for ( varID = 0; varID < nvars; ++varID )
-		vlistDefVarTsteptype(vlistID2, varID, TSTEP_INSTANT);
+		vlistDefVarTimetype(vlistID2, varID, TIME_VARYING);
 	    }
 
 	  pstreamDefVlist(streamID2, vlistID2);
@@ -144,7 +144,7 @@ void *Copy(void *argument)
 		  pstreamInqRecord(streamID1, &varID, &levelID);
 
                   if ( lconstvars && tsID2 > 0 && tsID1 == 0 )
-                    if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT )
+                    if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT )
                       continue;
                   
 		  pstreamDefRecord(streamID2,  varID,  levelID);
@@ -164,7 +164,7 @@ void *Copy(void *argument)
 		      pstreamInqRecord(streamID1, &varID, &levelID);
 
                       if ( lconstvars && tsID2 > 0 && tsID1 == 0 )
-                        if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT )
+                        if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT )
                           continue;
 
 		      pstreamReadRecord(streamID1, array, &nmiss);
diff --git a/src/Derivepar.cc b/src/Derivepar.cc
index 62119db..aed1215 100644
--- a/src/Derivepar.cc
+++ b/src/Derivepar.cc
@@ -271,12 +271,12 @@ void *Derivepar(void *argument)
   if ( operatorID == GHEIGHT )
     {
       var_id = geopotential_height;
-      varID  = vlistDefVar(vlistID2, gridID, zaxisIDh, TSTEP_INSTANT);
+      varID  = vlistDefVar(vlistID2, gridID, zaxisIDh, TIME_VARYING);
     }
   else if ( operatorID == SEALEVELPRESSURE )
     {
       var_id = air_pressure_at_sea_level;
-      varID  = vlistDefVar(vlistID2, gridID, surfaceID, TSTEP_INSTANT);
+      varID  = vlistDefVar(vlistID2, gridID, surfaceID, TIME_VARYING);
     }
   else
     cdoAbort("Internal problem, invalid operatorID: %d!", operatorID);
diff --git a/src/Detrend.cc b/src/Detrend.cc
index 1d961d6..27eaec9 100644
--- a/src/Detrend.cc
+++ b/src/Detrend.cc
@@ -74,11 +74,6 @@ void *Detrend(void *argument)
   double missval;
   field_type ***vars = NULL;
   dtlist_type *dtlist = dtlist_new();
-  typedef struct
-  {
-    double *array1;
-    double *array2;
-  } memory_t;
 
   cdoInitialize(argument);
 
@@ -124,12 +119,8 @@ void *Detrend(void *argument)
 
   int nts = tsID;
 
-  memory_t *ompmem = (memory_t*) Malloc(ompNumThreads*sizeof(memory_t));
-  for ( i = 0; i < ompNumThreads; i++ )
-    {
-      ompmem[i].array1 = (double*) Malloc(nts*sizeof(double));
-      ompmem[i].array2 = (double*) Malloc(nts*sizeof(double));
-    }
+  NEW_2D(double, array1, ompNumThreads, nts);
+  NEW_2D(double, array2, ompNumThreads, nts);
 
   for ( varID = 0; varID < nvars; varID++ )
     {
@@ -140,29 +131,25 @@ void *Detrend(void *argument)
       for ( levelID = 0; levelID < nlevel; levelID++ )
 	{
 #if defined(_OPENMP)
-#pragma omp parallel for default(none) shared(ompmem, vars, varID, levelID, gridsize, nts, missval)
+#pragma omp parallel for default(none) shared(array1, array2, vars, varID, levelID, gridsize, nts, missval)
 #endif
 	  for ( i = 0; i < gridsize; i++ )
 	    {
               int ompthID = cdo_omp_get_thread_num();
 
 	      for ( int tsID = 0; tsID < nts; tsID++ )
-		ompmem[ompthID].array1[tsID] = vars[tsID][varID][levelID].ptr[i];
+		array1[ompthID][tsID] = vars[tsID][varID][levelID].ptr[i];
 
-	      detrend(nts, missval, ompmem[ompthID].array1, ompmem[ompthID].array2);
+	      detrend(nts, missval, array1[ompthID], array2[ompthID]);
 
 	      for ( int tsID = 0; tsID < nts; tsID++ )
-		vars[tsID][varID][levelID].ptr[i] = ompmem[ompthID].array2[tsID];
+		vars[tsID][varID][levelID].ptr[i] = array2[ompthID][tsID];
 	    }
 	}
     }
 
-  for ( i = 0; i < ompNumThreads; i++ )
-    {
-      Free(ompmem[i].array1);
-      Free(ompmem[i].array2);
-    }
-  Free(ompmem);
+  DELETE_2D(array1);
+  DELETE_2D(array2);
 
   for ( int tsID = 0; tsID < nts; tsID++ )
     {
diff --git a/src/Distgrid.cc b/src/Distgrid.cc
index 39982ef..c96882d 100644
--- a/src/Distgrid.cc
+++ b/src/Distgrid.cc
@@ -116,7 +116,7 @@ void genGrids(int gridID1, int *gridIDs, int nxvals, int nyvals, int nxblocks, i
 	gridDefYsize(gridID2, ylsize[iy]);
 
         gridDefNP(gridID2, gridInqNP(gridID1));
-        gridDefPrec(gridID2, gridInqPrec(gridID1));
+        gridDefDatatype(gridID2, gridInqDatatype(gridID1));
 
         grid_copy_attributes(gridID1, gridID2);
 
diff --git a/src/Duplicate.cc b/src/Duplicate.cc
index dbbfe0e..d9e10af 100644
--- a/src/Duplicate.cc
+++ b/src/Duplicate.cc
@@ -56,7 +56,7 @@ void *Duplicate(void *argument)
   if ( ntsteps == 1 )
     {
       for ( varID = 0; varID < nvars; ++varID )
-	if ( vlistInqVarTsteptype(vlistID1, varID) != TSTEP_CONSTANT ) break;
+	if ( vlistInqVarTimetype(vlistID1, varID) != TIME_CONSTANT ) break;
 
       if ( varID == nvars ) ntsteps = 0;
     }
@@ -64,7 +64,7 @@ void *Duplicate(void *argument)
   if ( ntsteps == 0 )
     {
       for ( varID = 0; varID < nvars; ++varID )
-	vlistDefVarTsteptype(vlistID2, varID, TSTEP_INSTANT);
+	vlistDefVarTimetype(vlistID2, varID, TIME_VARYING);
     }
  
   int streamID2 = pstreamOpenWrite(cdoStreamName(1), cdoFiletype());
diff --git a/src/EOFs.cc b/src/EOFs.cc
index d857380..3acf83b 100644
--- a/src/EOFs.cc
+++ b/src/EOFs.cc
@@ -43,20 +43,20 @@
 // NO MISSING VALUE SUPPORT ADDED SO FAR
 
 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)
+void scale_eigvec_grid(double *restrict out, int tsID, size_t npack, const size_t *restrict pack, const double *restrict weight, double **covar, double sum_w)
 {
-  for ( int i = 0; i < npack; ++i )
+  for ( size_t 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,
+void scale_eigvec_time(double *restrict out, int tsID, int nts, size_t npack, const size_t *restrict pack, const double *restrict weight,
 		       double **covar, double **data, double missval, double sum_w)
 {
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) shared(npack, nts, tsID, pack, data, covar, out)
 #endif
-  for ( int i = 0; i < npack; ++i )
+  for ( size_t i = 0; i < npack; ++i )
     {
       double sum = 0;
       for ( int j = 0; j < nts; ++j )
@@ -65,9 +65,9 @@ void scale_eigvec_time(double *restrict out, int tsID, int nts, int npack, const
       out[pack[i]] = sum;
     }
   /*
-  for ( int j = 0; j < nts; ++j )
+  for ( size_t j = 0; j < nts; ++j )
     {
-      for ( int i = 0; i < npack; ++i )
+      for ( size_t i = 0; i < npack; ++i )
 	out[pack[i]] += data[j][i] * covar[tsID][j];
     }
   */
@@ -79,7 +79,7 @@ void scale_eigvec_time(double *restrict out, int tsID, int nts, int npack, const
 #pragma omp parallel for default(none) reduction(+:sum)	\
   shared(out,weight,pack,npack)
 #endif
-  for ( int i = 0; i < npack; ++i )
+  for ( size_t 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]];
@@ -91,14 +91,14 @@ void scale_eigvec_time(double *restrict out, int tsID, int nts, int npack, const
 #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;
+      for ( size_t 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;
+      for ( size_t i = 0; i < npack; ++i ) out[pack[i]] = missval;
     }
 }
 
@@ -141,7 +141,7 @@ enum T_EIGEN_MODE get_eigenmode(void)
 
 enum T_WEIGHT_MODE get_weightmode(void)
 {  
-  enum T_WEIGHT_MODE weight_mode = WEIGHT_ON;
+  enum T_WEIGHT_MODE weight_mode = WEIGHT_OFF;
 
   char *envstr = getenv("CDO_WEIGHT_MODE");
   if ( envstr )
@@ -171,14 +171,11 @@ void *EOFs(void * argument)
   int nmiss;
   int varID, levelID;
   int nts = 0;
-  int n = 0;
+  size_t n = 0;
   int grid_space = 0, time_space = 0;
   int timer_cov = 0, timer_eig = 0;
 
   int calendar = CALENDAR_STANDARD;
-  juldate_t juldate;
-
-  double missval = 0;
 
   typedef struct {
     bool init;
@@ -217,7 +214,7 @@ void *EOFs(void * argument)
   int vlistID1  = pstreamInqVlist(streamID1);
   int taxisID1  = vlistInqTaxis(vlistID1);
   int gridID1   = vlistInqVarGrid(vlistID1, 0);
-  int gridsize  = vlistGridsizeMax(vlistID1);
+  size_t gridsize  = vlistGridsizeMax(vlistID1);
   int nvars     = vlistNvars(vlistID1);
   int nrecs;
 
@@ -226,19 +223,6 @@ void *EOFs(void * argument)
     if ( vlistGrid(vlistID1, 0) != vlistGrid(vlistID1, index))
       cdoAbort("Too many different grids!");
 
-  double *weight = (double *) Malloc(gridsize*sizeof(double));
-  for ( int 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!");
-	}
-    }
-
   /* eigenvalues */
 
   /* COUNT NUMBER OF TIMESTEPS if EOF_ or EOF_TIME */
@@ -253,17 +237,17 @@ void *EOFs(void * argument)
 	  while ( pstreamInqTimestep(streamID1, nts) ) nts++;
 
 	  if ( cdoVerbose ) cdoPrint("Counted %i timeSteps", nts);
+
+          pstreamClose(streamID1);
+
+          streamID1 = pstreamOpenRead(cdoStreamName(0));
+          vlistID1  = pstreamInqVlist(streamID1);
+          taxisID1  = vlistInqTaxis(vlistID1);
 	}
       else
         if ( cdoVerbose ) cdoPrint("Found %i timeSteps", nts);
 
-      pstreamClose(streamID1);
-
-      streamID1 = pstreamOpenRead(cdoStreamName(0));
-      vlistID1  = pstreamInqVlist(streamID1);
-      taxisID1  = vlistInqTaxis(vlistID1);
-
-      if ( nts < gridsize || operfunc == EOF_TIME )
+      if ( (size_t)nts < gridsize || operfunc == EOF_TIME )
 	{
 	  time_space = 1;
 	  grid_space = 0;
@@ -297,11 +281,11 @@ void *EOFs(void * argument)
     {
       if ( ((double)gridsize)*gridsize > (double)LONG_MAX ) cdoAbort("Grid space too large!");
 
-      if ( n_eig > gridsize )
+      if ( (size_t)n_eig > gridsize )
         {
           cdoWarning("Solving in spatial space");
           cdoWarning("Number of eigen-functions to write out is bigger than grid size");
-          cdoWarning("Setting n_eig to %d", gridsize);
+          cdoWarning("Setting n_eig to %zu", gridsize);
           cdoWarning("If You want to force a solution in time-space use operator eoftime");
           n_eig = gridsize;
         }
@@ -312,17 +296,28 @@ void *EOFs(void * argument)
     cdoPrint("Calculating %d eigenvectors and %d eigenvalues in %s",
 	     n_eig, n, grid_space==1?"grid_space" : "time_space");
 
+  double *weight = (double *) Malloc(gridsize*sizeof(double));
+  for ( size_t 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!");
+	}
+    }
+
   /* allocation of temporary fields and output structures */
-  int npack = -1;
-  int *pack            = (int *) Malloc(gridsize*sizeof(int));
+  size_t npack = ULONG_MAX;
+  size_t *pack         = (size_t *) Malloc(gridsize*sizeof(size_t));
   double *in           = (double *) Malloc(gridsize*sizeof(double));
   eofdata_t **eofdata  = (eofdata_t **) Malloc(nvars*sizeof(eofdata_t*));
 
   for ( varID = 0; varID < nvars; ++varID )
     {
-      gridsize = vlistGridsizeMax(vlistID1);
-      nlevs    = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-      missval  = vlistInqVarMissval(vlistID1, varID);
+      nlevs = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
 
       eofdata[varID] = (eofdata_t *) Malloc(nlevs*sizeof(eofdata_t));
 
@@ -341,7 +336,7 @@ void *EOFs(void * argument)
     }
 
   if ( cdoVerbose )
-    cdoPrint("Allocated eigenvalue/eigenvector structures with nts=%d gridsize=%d", nts, gridsize);
+    cdoPrint("Allocated eigenvalue/eigenvector structures with nts=%d gridsize=%zu", nts, gridsize);
 
   double *covar_array = NULL;
   double **covar = NULL;
@@ -360,12 +355,12 @@ void *EOFs(void * argument)
           pstreamInqRecord(streamID1, &varID, &levelID);
           pstreamReadRecord(streamID1, in, &nmiss);
 
-	  gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
-          missval = vlistInqVarMissval(vlistID1, varID);
-	  if ( npack == -1 )
+	  size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
+          double missval = vlistInqVarMissval(vlistID1, varID);
+	  if ( npack == ULONG_MAX )
 	    {
 	      npack = 0;
-	      for ( int i = 0; i < gridsize; ++i )
+	      for ( size_t i = 0; i < gridsize; ++i )
 		{
 		  if ( !DBL_IS_EQUAL(weight[i], 0.0) && !DBL_IS_EQUAL(weight[i], missval) &&
 		       !DBL_IS_EQUAL(in[i], missval) )
@@ -378,12 +373,12 @@ void *EOFs(void * argument)
 	      if ( weight_mode == WEIGHT_ON )
 		{
 		  sum_w = 0;
-		  for ( int i = 0; i < npack; i++ ) sum_w += weight[pack[i]];
+		  for ( size_t i = 0; i < npack; i++ ) sum_w += weight[pack[i]];
 		}
 	    }
 
-	  int ipack = 0;
-	  for ( int i = 0; i < gridsize; ++i )
+	  size_t ipack = 0;
+	  for ( size_t i = 0; i < gridsize; ++i )
 	    {
 	      if ( !DBL_IS_EQUAL(weight[i], 0.0) && !DBL_IS_EQUAL(weight[i], missval) &&
 		   !DBL_IS_EQUAL(in[i], missval) )
@@ -392,17 +387,18 @@ void *EOFs(void * argument)
                   ipack++;
 		}
 	    }
+          if ( ipack != npack ) cdoAbort("Missing values unsupported!");
 
 	  if ( grid_space )
             {
 	      if ( !eofdata[varID][levelID].init )
 		{
                   n = npack;
-		  double *covar_array = (double *) Malloc(((size_t)npack)*npack*sizeof(double));
+		  double *covar_array = (double *) Malloc(npack*npack*sizeof(double));
 		  covar = (double **) Malloc(npack*sizeof(double *));
-		  for ( int i = 0; i < npack; ++i ) covar[i] = covar_array + ((size_t)npack)*i;
-		  for ( int i = 0; i < npack; ++i )
-                    for ( int j = 0; j < npack; ++j ) covar[i][j] = 0;
+		  for ( size_t i = 0; i < npack; ++i ) covar[i] = covar_array + npack*i;
+		  for ( size_t i = 0; i < npack; ++i )
+                    for ( size_t j = 0; j < npack; ++j ) covar[i][j] = 0;
 
 		  eofdata[varID][levelID].covar_array = covar_array;
 		  eofdata[varID][levelID].covar       = covar;
@@ -414,18 +410,16 @@ void *EOFs(void * argument)
 #if defined(_OPENMP)
 #pragma omp parallel for default(shared)
 #endif
-	      for ( int ipack = 0; ipack < npack; ++ipack )
-		{
-		  for ( int jpack = ipack; jpack < npack; ++jpack )
-		    covar[ipack][jpack] += in[pack[ipack]] * in[pack[jpack]];
-		}
+	      for ( size_t ipack = 0; ipack < npack; ++ipack )
+                for ( size_t 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;
 
-	      for ( int ipack = 0; ipack < npack; ipack++ )
+	      for ( size_t ipack = 0; ipack < npack; ipack++ )
 		data[ipack] = in[pack[ipack]];
 	    }
 
@@ -473,13 +467,13 @@ void *EOFs(void * argument)
 
   int vdate = 10101;
   int vtime = 0;
-  juldate = juldate_encode(calendar, vdate, vtime);
+  juldate_t juldate = juldate_encode(calendar, vdate, vtime);
 
   double *out = in;
   double *eig_val = NULL;
 
   int nts_out = nts;
-  if ( npack < nts ) nts_out = npack;
+  if ( npack < (size_t)nts ) nts_out = npack;
 
   for ( tsID = 0; tsID < nts_out; tsID++ )
     {
@@ -501,8 +495,9 @@ void *EOFs(void * argument)
 	{
 	  char vname[256];
 	  vlistInqVarName(vlistID1, varID, vname);
-	  gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
+	  size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
 	  nlevs    = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
+          double missval = vlistInqVarMissval(vlistID1, varID);
 
 	  for ( levelID = 0; levelID < nlevs; levelID++ )
 	    {
@@ -529,11 +524,11 @@ void *EOFs(void * argument)
 
 		      covar = eofdata[varID][levelID].covar;
 
-		      for ( int ipack = 0; ipack < npack; ++ipack )
+		      for ( size_t ipack = 0; ipack < npack; ++ipack )
 			{
-                          int j;
-			  int i = pack[ipack];
-			  for ( int jpack = 0; jpack < npack; ++jpack )
+                          size_t j;
+			  size_t i = pack[ipack];
+			  for ( size_t jpack = 0; jpack < npack; ++jpack )
 			    {
 			      if ( jpack < ipack )
 				{
@@ -553,7 +548,7 @@ void *EOFs(void * argument)
 		  else if ( time_space )
 		    {		      
 		      if ( cdoVerbose )
-			cdoPrint("allocating covar with %i x %i elements | npack=%i", nts, nts, npack);
+			cdoPrint("allocating covar with %i x %i elements | npack=%zu", nts, nts, npack);
 
 		      covar_array = (double *) Malloc(nts*nts*sizeof(double));
 		      covar = (double **) Malloc(nts*sizeof(double *));
@@ -575,7 +570,7 @@ void *EOFs(void * argument)
 			    {
 			      double *df2p = data[j2];
 			      double sum = 0;
-			      for ( int i = 0; i < npack; i++ )
+			      for ( size_t i = 0; i < npack; i++ )
 				sum += weight[pack[i]]*df1p[i]*df2p[i];
 			      covar[j1][j2] = sum / sum_w / nts;
 			    }
@@ -599,7 +594,7 @@ void *EOFs(void * argument)
 		  if ( cdoTimer ) timer_stop(timer_eig);
 		  /* NOW: covar contains the eigenvectors, eig_val the eigenvalues */
 
-		  for ( int i = 0; i < gridsize; ++i ) out[i] = missval;
+		  for ( size_t i = 0; i < gridsize; ++i ) out[i] = missval;
 	  
 		  // for ( int i = 0; i < n; i++ ) eig_val[i] *= sum_w;
 		} // first_call
@@ -615,14 +610,14 @@ void *EOFs(void * argument)
 		  else if ( time_space ) scale_eigvec_time(out, tsID, nts, npack, pack, weight, covar, data, missval, sum_w);
 
                   nmiss = 0;
-                  for ( int i = 0; i < gridsize; i++ ) if ( DBL_IS_EQUAL(out[i], missval) ) nmiss++;
+                  for ( size_t i = 0; i < gridsize; i++ ) if ( DBL_IS_EQUAL(out[i], missval) ) nmiss++;
 
                   pstreamDefRecord(streamID3, varID, levelID);
                   pstreamWriteRecord(streamID3, out, nmiss);
 		} // loop n_eig
 
-	      nmiss = 0;
-              if ( DBL_IS_EQUAL(eig_val[tsID], missval) ) nmiss = 1;
+              nmiss = (DBL_IS_EQUAL(eig_val[tsID], missval)) ? 1 : 0;
+
               pstreamDefRecord(streamID2, varID, levelID);
               pstreamWriteRecord(streamID2, &eig_val[tsID], nmiss);
 	    } // loop nlevs
diff --git a/src/Echam5ini.cc b/src/Echam5ini.cc
index f609848..b768c83 100644
--- a/src/Echam5ini.cc
+++ b/src/Echam5ini.cc
@@ -1448,7 +1448,7 @@ void *Echam5ini(void *argument)
   int operatorID = cdoOperatorID();
   int operfunc = cdoOperatorF1(operatorID);
 
-  if ( operatorID == EXPORT_E5ML && processSelf() != 0 )
+  if ( operatorID == EXPORT_E5ML && processSelf().m_ID != 0 )
     cdoAbort("This operator can't be linked with other operators!");
 
   if ( operfunc == func_read )
@@ -1475,7 +1475,7 @@ void *Echam5ini(void *argument)
 	{/*
 	  fprintf(stderr, "%d %s %d %d %d %d\n", iv, vars[iv].name, vars[iv].gridID, vars[iv].zaxisID, gridInqSize(vars[iv].gridID), zaxisInqSize(vars[iv].zaxisID));
 	 */
-	  varID = vlistDefVar(vlistID2, vars[iv].gridID, vars[iv].zaxisID, TSTEP_CONSTANT);
+	  varID = vlistDefVar(vlistID2, vars[iv].gridID, vars[iv].zaxisID, TIME_CONSTANT);
 	  if ( vars[iv].code > 0 ) vlistDefVarCode(vlistID2, varID, vars[iv].code);
 	  if ( vars[iv].name )     vlistDefVarName(vlistID2, varID, vars[iv].name);
 	  if ( vars[iv].longname ) vlistDefVarLongname(vlistID2, varID, vars[iv].longname);
diff --git a/src/Enlarge.cc b/src/Enlarge.cc
index 95bd050..478e73f 100644
--- a/src/Enlarge.cc
+++ b/src/Enlarge.cc
@@ -36,6 +36,7 @@ void *Enlarge(void *argument)
 
   operatorCheckArgc(1);
 
+  // open stream before calling cdoDefineGrid!!!
   int streamID1 = pstreamOpenRead(cdoStreamName(0));
 
   int gridID2 = cdoDefineGrid(operatorArgv()[0]);
diff --git a/src/Enlargegrid.cc b/src/Enlargegrid.cc
index 66abc32..1b0690a 100644
--- a/src/Enlargegrid.cc
+++ b/src/Enlargegrid.cc
@@ -166,6 +166,7 @@ void *Enlargegrid(void *argument)
   if ( operatorArgc() < 1 ) cdoAbort("Too few arguments!");
   if ( operatorArgc() > 2 ) cdoAbort("Too many arguments!");
 
+  // open stream before calling cdoDefineGrid!!!
   int streamID1 = pstreamOpenRead(cdoStreamName(0));
 
   int gridID2 = cdoDefineGrid(operatorArgv()[0]);
diff --git a/src/Ensstat.cc b/src/Ensstat.cc
index fc4c628..9472f5c 100644
--- a/src/Ensstat.cc
+++ b/src/Ensstat.cc
@@ -236,8 +236,8 @@ void *Ensstat(void *argument)
 	  strcat(name, "_count");
 	  int gridID = vlistInqVarGrid(vlistID2, varID);
 	  int zaxisID = vlistInqVarZaxis(vlistID2, varID);
-	  int tsteptype = vlistInqVarTsteptype(vlistID2, varID);
-	  int cvarID = vlistDefVar(vlistID2, gridID, zaxisID, tsteptype);
+	  int timetype = vlistInqVarTimetype(vlistID2, varID);
+	  int cvarID = vlistDefVar(vlistID2, gridID, zaxisID, timetype);
 	  vlistDefVarName(vlistID2, cvarID, name);
 	  vlistDefVarDatatype(vlistID2, cvarID, CDI_DATATYPE_INT16);
 	  if ( cvarID != (varID+nvars) ) cdoAbort("Internal error, varIDs do not match!");
diff --git a/src/Ensstat3.cc b/src/Ensstat3.cc
index 2afe886..e732a73 100644
--- a/src/Ensstat3.cc
+++ b/src/Ensstat3.cc
@@ -149,7 +149,7 @@ void *Ensstat3(void *argument)
   zaxisDefLevels(zaxisID2,levs);
   zaxisDefName(zaxisID2, "histogram_binID");
 
-  int time_mode = datafunc == TIME? TSTEP_INSTANT : TSTEP_CONSTANT;
+  int time_mode = datafunc == TIME? TIME_VARYING : TIME_CONSTANT;
 
   for ( varID=0; varID<nvars; varID++) {
 
diff --git a/src/Eof3d.cc b/src/Eof3d.cc
index c8f90cf..dda6230 100644
--- a/src/Eof3d.cc
+++ b/src/Eof3d.cc
@@ -52,15 +52,14 @@ void *EOF3d(void * argument)
 
   size_t temp_size = 0, npack = 0;
   int varID, levelID;
-  int missval_warning = 0;
-  int nmiss, ngrids, n = 0, nlevs = 0;
-  int offset;
+  bool missval_warning = false;
+  int nmiss, ngrids;
+  int n = 0;
+  size_t nlevs = 0;
   int timer_cov = 0, timer_eig = 0;
 
   int calendar = CALENDAR_STANDARD;
-  juldate_t juldate;
 
-  double missval = 0;
   double sum_w;
   double **cov = NULL;                                /* TODO: covariance matrix / eigenvectors after solving */
   double *eigv;
@@ -88,31 +87,14 @@ void *EOF3d(void * argument)
   enum T_EIGEN_MODE eigen_mode = get_eigenmode();
   enum T_WEIGHT_MODE weight_mode = get_weightmode();
 
-  int streamID1  = pstreamOpenRead(cdoStreamName(0));
-  int vlistID1   = pstreamInqVlist(streamID1);
-  int gridID1    = vlistInqVarGrid(vlistID1, 0);
-  long gridsize  = vlistGridsizeMax(vlistID1);
-  int nvars      = vlistNvars(vlistID1);
-  int nrecs;
-
-  double *weight = (double *) Malloc(gridsize*sizeof(double));
-  for ( int 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!");
-	}
-    }
-
   /*  eigenvalues */
 
   if ( operfunc == EOF3D_SPATIAL )
     cdoAbort("Operator not Implemented - use eof3d or eof3dtime instead");
 
+  int streamID1  = pstreamOpenRead(cdoStreamName(0));
+  int vlistID1   = pstreamInqVlist(streamID1);
+
   /* COUNT NUMBER OF TIMESTEPS if EOF3D_ or EOF3D_TIME */
   int nts = vlistNtsteps(vlistID1);
   if ( nts == -1 )
@@ -121,14 +103,15 @@ void *EOF3d(void * argument)
       while ( pstreamInqTimestep(streamID1, nts) ) nts++;
 
       if ( cdoVerbose ) cdoPrint("Counted %i timeSteps", nts);
+
+      pstreamClose(streamID1);
+
+      streamID1 = pstreamOpenRead(cdoStreamName(0));
+      vlistID1  = pstreamInqVlist(streamID1);
     }
   else
     if ( cdoVerbose ) cdoPrint("Found %i timeSteps", nts);
 
-  pstreamClose(streamID1);
-
-  streamID1 = pstreamOpenRead(cdoStreamName(0));
-  vlistID1  = pstreamInqVlist(streamID1);
   int taxisID1  = vlistInqTaxis(vlistID1);
 
   /* reset the requested number of eigen-function to the maximum if neccessary */
@@ -144,19 +127,28 @@ void *EOF3d(void * argument)
 
   if ( cdoVerbose )  cdoPrint("counted %i timesteps",n);
 
+  int nvars      = vlistNvars(vlistID1);
+  int nrecs;
+
+  int gridID1    = vlistInqVarGrid(vlistID1, 0);
+  size_t gridsizemax  = vlistGridsizeMax(vlistID1);
+
   /* allocation of temporary fields and output structures */
-  double *in       = (double *) Malloc(gridsize*sizeof(double));
+  double *in     = (double *) Malloc(gridsizemax*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 **));
 
+  size_t maxlevs = 0;
   for ( varID = 0; varID < nvars; ++varID )
     {
-      gridsize            = vlistGridsizeMax(vlistID1);
-      nlevs               = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-      temp_size           = ((size_t)gridsize) * nlevs;
-      missval             = vlistInqVarMissval(vlistID1, varID);
+      size_t gridsize = vlistGridsizeMax(vlistID1);
+      nlevs     = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
+      temp_size = gridsize * nlevs;
+      double missval = vlistInqVarMissval(vlistID1, varID);
+
+      if ( nlevs > maxlevs ) maxlevs = nlevs;
 
       datacounts[varID]   = (int*) Malloc(nlevs*sizeof(int));
       datafields[varID]   = (double **) Malloc(nts*sizeof(double *));
@@ -187,9 +179,28 @@ void *EOF3d(void * argument)
     }
 
   if ( cdoVerbose)
-    cdoPrint("allocated eigenvalue/eigenvector with nts=%i, n=%i, gridsize=%i for processing in %s",
-	     nts,n,gridsize,"time_space");
+    cdoPrint("Allocated eigenvalue/eigenvector with nts=%i, n=%i, gridsize=%zu for processing in %s",
+	     nts, n, gridsizemax, "time_space");
   
+  double *weight = (double *) Malloc(maxlevs*gridsizemax*sizeof(double));
+  for ( size_t i = 0; i < maxlevs*gridsizemax; ++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!");
+	}
+      else
+        {
+          for ( size_t k = 1; k < maxlevs; ++k )
+            for ( size_t i = 0; i < gridsizemax; ++i )
+              weight[k*gridsizemax+i] =  weight[i];
+        }
+    }
+
   int tsID = 0;
 
   /* read the data and create covariance matrices for each var & level */
@@ -202,13 +213,13 @@ void *EOF3d(void * argument)
         {
           pstreamInqRecord(streamID1, &varID, &levelID);
 
-          gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
+          size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
+          double missval = vlistInqVarMissval(vlistID1, varID);
 
-          missval = vlistInqVarMissval(vlistID1, varID);
           pstreamReadRecord(streamID1, in, &nmiss);
 
-	  offset = gridsize * levelID;
-	  for ( int i = 0; i < gridsize; ++i )
+	  size_t offset = gridsize * levelID;
+	  for ( size_t i = 0; i < gridsize; ++i )
 	    {
 	      if ( ! DBL_IS_EQUAL(in[i], missval ) )
 		{
@@ -217,11 +228,12 @@ void *EOF3d(void * argument)
 		}
 	      else
 		{
-		  if ( missval_warning == 0 )
+                  if ( datacounts[varID][offset + i] != 0 ) cdoAbort("Missing values unsupported!");
+		  if ( missval_warning == false )
 		    {
-		      cdoWarning("Missing Value Support not checked for this Operator!");
-		      cdoWarning("Does not work with changing locations of missing values in time.");
-		      missval_warning = 1;
+		      // cdoWarning("Missing Value Support not checked for this Operator!");
+		      // cdoWarning("Does not work with changing locations of missing values in time.");
+		      missval_warning = true;
 		    }
 		  datafields[varID][tsID][i+offset] = 0;
 		}
@@ -233,13 +245,14 @@ void *EOF3d(void * argument)
   if ( cdoVerbose ) 
     cdoPrint("Read data for %i variables",nvars);
   
-  int *pack = (int*) Malloc(temp_size*sizeof(int)); //TODO
+  size_t *pack = (size_t*) Malloc(temp_size*sizeof(size_t)); //TODO
 
   for ( varID = 0; varID < nvars; varID++ )
     {
-      gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
+      size_t gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
       nlevs    = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-      temp_size = ((size_t)gridsize) * nlevs;
+      temp_size = gridsize * nlevs;
+      double missval = vlistInqVarMissval(vlistID1, varID);
 
       if ( cdoVerbose )
         {
@@ -273,7 +286,7 @@ void *EOF3d(void * argument)
         {
           char vname[64];
           vlistInqVarName(vlistID1,varID,&vname[0]);
-          cdoWarning("Refusing to calculate EOF from a single time step for var%i (%s)",varID,&vname[0]);
+          cdoWarning("Refusing to calculate EOF from a single time step for var%i (%s)", varID+1, &vname[0]);
           continue;
         }
 
@@ -301,7 +314,7 @@ void *EOF3d(void * argument)
               double *df2p = datafields[varID][j2];
               double sum = 0;
               for ( size_t i = 0; i < npack; i++ )
-                sum += weight[pack[i]%gridsize]*df1p[pack[i]]*df2p[pack[i]];
+                sum += weight[pack[i]%gridsizemax]*df1p[pack[i]]*df2p[pack[i]];
               cov[j2][j1] = cov[j1][j2] = sum / sum_w / nts;
             }
         }
@@ -324,7 +337,7 @@ void *EOF3d(void * argument)
       /* 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);
+	cdoPrint("Processed SVD decomposition for var %i from %zu x %zu matrix",varID,n,n);
 
       for( int eofID = 0; eofID < n; eofID++ )
 	eigenvalues[varID][eofID][0] = eigv[eofID];
@@ -351,10 +364,10 @@ void *EOF3d(void * argument)
 	  double sum = 0;
 
 #if defined(_OPENMP)
-#pragma omp parallel for default(none)  shared(eigenvec,weight,pack,npack,gridsize) reduction(+:sum)
+#pragma omp parallel for default(none)  shared(eigenvec,weight,pack,npack,gridsizemax) reduction(+:sum)
 #endif 
 	  for ( size_t i = 0; i < npack; i++ )
-	    sum +=  weight[pack[i]%gridsize] *
+	    sum +=  weight[pack[i]%gridsizemax] *
 	            eigenvec[pack[i]] * eigenvec[pack[i]];
 
 	  if ( sum > 0 )
@@ -371,7 +384,7 @@ void *EOF3d(void * argument)
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) shared(eigenvec,pack,missval,npack)
 #endif
-	      for( size_t i = 0; i < npack; i++ )
+	      for ( size_t i = 0; i < npack; i++ )
 		eigenvec[pack[i]] = missval;
 	    }
 	}     /* for ( eofID = 0; eofID < n_eig; eofID++ )     */
@@ -386,7 +399,11 @@ void *EOF3d(void * argument)
   /*  eigenvalues */
   int streamID2 = pstreamOpenWrite(cdoStreamName(1), cdoFiletype());
 
+  int vlistID2 = vlistDuplicate(vlistID1);
   int taxisID2 = taxisDuplicate(taxisID1);
+  taxisDefRdate(taxisID2, 0);
+  taxisDefRtime(taxisID2, 0);
+  vlistDefTaxis(vlistID2, taxisID2);
 
   int gridID2 = gridCreate(GRID_LONLAT, 1);
   gridDefXsize(gridID2, 1);
@@ -395,24 +412,21 @@ void *EOF3d(void * argument)
   gridDefXvals(gridID2, &xvals);
   gridDefYvals(gridID2, &yvals);
 
+  ngrids = vlistNgrids(vlistID2);
+  for ( int i = 0; i < ngrids; i++ )
+    vlistChangeGridIndex(vlistID2, i, gridID2);
+
   int zaxisID2 = zaxisCreate(ZAXIS_GENERIC, 1);
   double zvals = 0;
   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);
-
-  int *varID2 = (int*) Malloc(nvars*sizeof(int));
-  for ( varID=0; varID<nvars; varID++ )
-    varID2[varID] = vlistDefVar(vlistID2, gridID2, zaxisID2, TSTEP_INSTANT);
-  ngrids = vlistNgrids(vlistID2);
-  for ( int i = 0; i < ngrids; i++ )
-    vlistChangeGridIndex(vlistID2, i, gridID2);
+  int nzaxis = vlistNzaxis(vlistID2);
+  for ( int i = 0; i < nzaxis; i++ )
+    vlistChangeZaxisIndex(vlistID2, i, zaxisID2);
 
+  /*  eigenvectors */
   int streamID3 = pstreamOpenWrite(cdoStreamName(2), cdoFiletype());
 
   int vlistID3 = vlistDuplicate(vlistID1);
@@ -426,7 +440,7 @@ void *EOF3d(void * argument)
 
   int vdate = 10101;
   int vtime = 0;
-  juldate = juldate_encode(calendar, vdate, vtime);
+  juldate_t juldate = juldate_encode(calendar, vdate, vtime);
   for ( tsID = 0; tsID < n; tsID++ )
     {
       juldate = juldate_add_seconds(60, juldate);
@@ -445,22 +459,24 @@ void *EOF3d(void * argument)
 
       for ( varID = 0; varID < nvars; varID++ )
         {
+          double missval = vlistInqVarMissval(vlistID1, varID);
           nlevs = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-          for ( levelID = 0; levelID < nlevs; levelID++ )
+          for ( levelID = 0; levelID < (int)nlevs; levelID++ )
             {
-	      offset = levelID * gridsize;
+	      size_t offset = levelID * gridsizemax;
               if ( tsID < n_eig )
                 {
                   nmiss = 0;
-                  for ( int i = 0; i < gridsize; i++ )
+                  for ( size_t i = 0; i < gridsizemax; i++ )
                     if ( DBL_IS_EQUAL(eigenvectors[varID][tsID][offset + i], missval) ) nmiss++;
 
                   pstreamDefRecord(streamID3, varID, levelID);
                   pstreamWriteRecord(streamID3, &eigenvectors[varID][tsID][offset], nmiss);
                 }
 	    }
-	  if ( DBL_IS_EQUAL(eigenvalues[varID][tsID][0], missval) ) nmiss = 1;
-	  else nmiss = 0;
+
+	  nmiss = (DBL_IS_EQUAL(eigenvalues[varID][tsID][0], missval)) ? 1 : 0;
+
 	  pstreamDefRecord(streamID2, varID, 0);
 	  pstreamWriteRecord(streamID2, eigenvalues[varID][tsID],nmiss);
         } // for ( varID = 0; ... )
@@ -487,7 +503,6 @@ void *EOF3d(void * argument)
   Free(eigenvectors);
   Free(eigenvalues);
   Free(in);
-  Free(varID2);
 
   Free(pack);
   Free(weight);
diff --git a/src/Eofcoeff.cc b/src/Eofcoeff.cc
index 6cd8b3b..cf33af6 100644
--- a/src/Eofcoeff.cc
+++ b/src/Eofcoeff.cc
@@ -32,7 +32,7 @@
 
 void *Eofcoeff(void * argument)
 {
-  char eof_name[8], oname[1024], filesuffix[32];
+  char eof_name[16], oname[1024], filesuffix[32];
   double missval1 = -999, missval2;
   field_type in;  
   field_type out;
@@ -41,7 +41,7 @@ void *Eofcoeff(void * argument)
    
   cdoInitialize(argument);
 
-  if ( processSelf() != 0 ) cdoAbort("This operator can't be combined with other operators!");
+  if ( processSelf().m_ID != 0 ) cdoAbort("This operator can't be combined with other operators!");
 
   cdoOperatorAdd("eofcoeff",  0,  0, NULL);
      
@@ -101,6 +101,7 @@ void *Eofcoeff(void * argument)
          eof[varID][levelID][eofID].missval= missval1;
          eof[varID][levelID][eofID].ptr    = (double*) Malloc(gridsize*sizeof(double));
          memset(&eof[varID][levelID][eofID].ptr[0], missval1, gridsize*sizeof(double));
+
          if ( varID >= nvars )
            cdoAbort("Internal error - too high varID");
          if ( levelID >= nlevs )
@@ -111,6 +112,7 @@ void *Eofcoeff(void * argument)
        }
      eofID++;
    }
+
   int neof = eofID;  
   
   if ( cdoVerbose ) cdoPrint("%s contains %i eof's", cdoStreamName(0)->args, neof);
@@ -118,30 +120,27 @@ void *Eofcoeff(void * argument)
   int gridID3 = gridCreate(GRID_LONLAT, 1);
   gridDefXsize(gridID3, 1);
   gridDefYsize(gridID3, 1);
-  double *xvals = (double*) Malloc(1*sizeof(double));
-  double *yvals = (double*) Malloc(1*sizeof(double));
-  xvals[0]=0;
-  yvals[0]=0;
-  gridDefXvals(gridID3, xvals);
-  gridDefYvals(gridID3, yvals);
-  
+  double xvals = 0;
+  double yvals = 0;
+  gridDefXvals(gridID3, &xvals);
+  gridDefYvals(gridID3, &yvals);
+ 
   // Create var-list and time-axis for output
       
   int ngrids = vlistNgrids(vlistID3);
-  
   for ( i = 0; i < ngrids; i++ )
     vlistChangeGridIndex(vlistID3, i, gridID3);     
   
   vlistDefTaxis(vlistID3, taxisID3);
-  for (varID =0; varID<nvars; varID++)
-    vlistDefVarTsteptype(vlistID3, varID, TSTEP_INSTANT);
+  for (varID = 0; varID<nvars; varID++)
+    vlistDefVarTimetype(vlistID3, varID, TIME_VARYING);
   
   // open streams for eofcoeff output
   int *streamIDs = (int*) Malloc(neof*sizeof(int)); 
   for ( eofID = 0; eofID < neof; eofID++)
     {
       oname[nchars] = '\0';                       
-      for(varID=0; varID<nvars; varID++) 
+
       sprintf(eof_name, "%5.5i", eofID);
       strcat(oname, eof_name);
       if ( filesuffix[0] )
diff --git a/src/Eofcoeff3d.cc b/src/Eofcoeff3d.cc
index ddfa901..b4e1d8e 100644
--- a/src/Eofcoeff3d.cc
+++ b/src/Eofcoeff3d.cc
@@ -32,7 +32,7 @@
 
 void *Eofcoeff3d(void * argument)
 {
-  char eof_name[6], oname[1024], filesuffix[32];
+  char eof_name[16], oname[1024], filesuffix[32];
   double missval1 = -999, missval2 = -999;
   field_type in;  
   int i, varID, levelID;    
@@ -40,7 +40,7 @@ void *Eofcoeff3d(void * argument)
    
   cdoInitialize(argument);
 
-  if ( processSelf() != 0 ) cdoAbort("This operator can't be combined with other operators!");
+  if ( processSelf().m_ID != 0 ) cdoAbort("This operator can't be combined with other operators!");
 
   cdoOperatorAdd("eofcoeff3d",  0,  0, NULL);
      
@@ -62,7 +62,7 @@ void *Eofcoeff3d(void * argument)
     cdoAbort("Gridsize of input files does not match!");     
   
   if ( vlistNgrids(vlistID2) > 1 || vlistNgrids(vlistID1) > 1 )
-    cdoAbort("Too many grids in input");
+    cdoAbort("Too many different grids in input");
   
   int nvars = vlistNvars(vlistID1)==vlistNvars(vlistID2) ? vlistNvars(vlistID1) : -1;
   int nlevs = zaxisInqSize(vlistInqVarZaxis(vlistID1, 0));
@@ -110,6 +110,7 @@ void *Eofcoeff3d(void * argument)
        }
      eofID++;
    }
+
   int neof = eofID;  
   
   if ( cdoVerbose ) cdoPrint("%s contains %i eof's", cdoStreamName(0)->args, neof);
@@ -117,25 +118,32 @@ void *Eofcoeff3d(void * argument)
   int gridID3 = gridCreate(GRID_LONLAT, 1);
   gridDefXsize(gridID3, 1);
   gridDefYsize(gridID3, 1);
-  double *xvals= (double*) Malloc(1*sizeof(double));
-  double *yvals= (double*) Malloc(1*sizeof(double));
-  xvals[0]=0;
-  yvals[0]=0;
-  gridDefXvals(gridID3, xvals);
-  gridDefYvals(gridID3, yvals);
+  double xvals = 0;
+  double yvals = 0;
+  gridDefXvals(gridID3, &xvals);
+  gridDefYvals(gridID3, &yvals);
   
-  double *zvals = (double *) Malloc( 1* sizeof(double ));
-  zvals[0] = 0.;
+  double zvals = 0.;
   int zaxisID3 = zaxisCreate(ZAXIS_GENERIC,1);
-  zaxisDefLevels(zaxisID3,zvals);
+  zaxisDefLevels(zaxisID3, &zvals);
   zaxisDefName(zaxisID3,"zaxis_Reduced");
   zaxisDefLongname(zaxisID3,"Reduced zaxis from EOF3D - only one coefficient per 3D eigenvector and time step");
   
-  int vlistID3 = vlistCreate();
+  // Create var-list and time-axis for output
+
+  int vlistID3 = vlistDuplicate(vlistID2);   
+
+  int ngrids = vlistNgrids(vlistID3);
+  for ( i = 0; i < ngrids; i++ )
+    vlistChangeGridIndex(vlistID3, i, gridID3);     
+      
+  int nzaxis = vlistNzaxis(vlistID3);
+  for ( i = 0; i < nzaxis; i++ )
+    vlistChangeZaxisIndex(vlistID3, i, zaxisID3);
+  
   vlistDefTaxis(vlistID3,taxisID3);
-  int *varID3 = (int*) Malloc(nvars * sizeof(int));
-  for ( varID=0; varID<nvars; varID++ )
-    varID3[varID] = vlistDefVar(vlistID3, gridID3, zaxisID3, TSTEP_INSTANT);
+  for (varID =0; varID<nvars; varID++)
+    vlistDefVarTimetype(vlistID3, varID, TIME_VARYING);
   
   // open streams for eofcoeff output
   int *streamIDs = (int*) Malloc(neof*sizeof(int)); 
@@ -157,7 +165,7 @@ void *Eofcoeff3d(void * argument)
       
       pstreamDefVlist(streamIDs[eofID], vlistID3);
     }
-  
+
   // ALLOCATE temporary fields for data read and write
   in.ptr = (double*) Malloc(gridsize*sizeof(double));
   in.grid = gridID1;  
@@ -210,11 +218,12 @@ void *Eofcoeff3d(void * argument)
 		  else
 		    nmiss += 1;
                 }            
-
+              /*
               if ( nmiss ) {
 		out[varID][eofID].nmiss=1;
 		out[varID][eofID].ptr[0]=missval2;
 	      }
+              */
             }
 
           if ( varID >= nvars )
diff --git a/src/EstFreq.cc b/src/EstFreq.cc
new file mode 100644
index 0000000..4a423e4
--- /dev/null
+++ b/src/EstFreq.cc
@@ -0,0 +1,161 @@
+/*
+  This file is part of CDO. CDO is a collection of Operators to
+  manipulate and analyse Climate model Data.
+
+  Copyright (C) 2003-2017 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.
+*/
+
+#include <cdi.h>
+#include "cdo.h"
+#include "cdo_int.h"
+#include "pstream.h"
+
+
+void *EstFreq(void *argument)
+{
+  int nrecs;
+  int varID, levelID;
+  int gridsize, nmiss;
+
+  cdoInitialize(argument);
+
+  bool lcopy = UNCHANGED_RECORD;
+
+  int streamID1 = pstreamOpenRead(cdoStreamName(0));
+
+  int vlistID1 = streamInqVlist(streamID1);
+  int vlistID2 = vlistDuplicate(vlistID1);
+
+  int taxisID1 = vlistInqTaxis(vlistID1);
+  int taxisID2 = taxisDuplicate(taxisID1);
+  vlistDefTaxis(vlistID2, taxisID2);
+
+  int streamID2 = pstreamOpenWrite(cdoStreamName(1), cdoFiletype());
+
+  streamDefVlist(streamID2, vlistID2);
+
+  int ntsteps = vlistNtsteps(vlistID1);
+
+  double *array = NULL;
+  if ( ! lcopy )
+    {
+      gridsize = vlistGridsizeMax(vlistID1);
+      array = (double*) Malloc(gridsize*sizeof(double));
+    }
+
+  int tsID = 0;
+  int fyear, lyear, fmonth, lmonth, lymonth, dummy;
+  int step_per_year = 0, step_per_month, currentyear, currentmon;
+
+  while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
+    {
+      if ( tsID == 0 )
+        {
+          cdiDecodeDate(taxisInqVdate(taxisID1), &fyear, &fmonth, &dummy);
+          currentyear = fyear;
+          currentmon = fmonth;
+        }
+      else
+        cdiDecodeDate(taxisInqVdate(taxisID1), &currentyear, &currentmon, &dummy);
+      if ( currentyear == fyear )
+        {
+          lymonth = currentmon;
+          step_per_year++;
+        }
+      taxisCopyTimestep(taxisID2, taxisID1);
+      streamDefTimestep(streamID2, tsID);
+	       
+      for ( int recID = 0; recID < nrecs; recID++ )
+	{
+	  streamInqRecord(streamID1, &varID, &levelID);
+	  streamDefRecord(streamID2,  varID,  levelID);
+	  
+	  if ( lcopy )
+	    {
+	      streamCopyRecord(streamID2, streamID1);
+	    }
+	  else
+	    {
+	      streamReadRecord(streamID1, array, &nmiss);
+	      streamWriteRecord(streamID2, array, nmiss);
+	    }
+	}
+
+      tsID++;
+    }
+
+  char frequency[CDI_MAX_NAME];
+
+  if ( ntsteps > 2 )
+    {
+      int reclast = streamInqTimestep(streamID2, ntsteps);    
+      cdiDecodeDate(taxisInqVdate(taxisID2), &lyear, &lmonth, &dummy);
+/* First, estimation by maximal number of time steps divided by covered years between last and first time step */
+      if ( cdoVerbose )
+        printf("Frequency is calculated by dividing the number of time steps '%d' included in the time axis by the covered years of the time axis\ncomputed by the difference of the year of the last time stamp '%d' and the year of the first time stamp '%d'.\n", ntsteps, lyear, fyear);
+      double covered_years = lyear-fyear + 1.0;
+      if ( DBL_IS_EQUAL(ntsteps / covered_years, 1.) )
+        strcpy(frequency, "yr");
+      else if ( DBL_IS_EQUAL(ntsteps / covered_years, 12.) )
+        strcpy(frequency, "mon");
+      else if ( DBL_IS_EQUAL(ntsteps / covered_years, 365.) ||
+                DBL_IS_EQUAL(ntsteps / covered_years, 365.25) ||
+                DBL_IS_EQUAL(ntsteps / covered_years, 366.) )
+        strcpy(frequency, "day");
+      else if ( DBL_IS_EQUAL(ntsteps / covered_years, 365.*4) ||
+                DBL_IS_EQUAL(ntsteps / covered_years, 365.25*4) ||
+                DBL_IS_EQUAL(ntsteps / covered_years, 366.*4) )
+        strcpy(frequency, "6hr");
+      else if ( DBL_IS_EQUAL(ntsteps / covered_years, 365.*8) ||
+                DBL_IS_EQUAL(ntsteps / covered_years, 365.25*8) ||
+                DBL_IS_EQUAL(ntsteps / covered_years, 366.*8) )
+        strcpy(frequency, "3hr");
+      else 
+        {
+          int covered_months = lmonth-fmonth+1;
+          if ( cdoVerbose )
+            printf("The fraction ntsteps / covered_years = '%f' is neither 1, 12, 365, 365.25, 366 nor a multiple of 365 which would correspond to frequencies yearly, monthly, daily or subdaily respectively.\n Next try:\n\nFrequency is calculated by dividing the number of time steps '%d' in year '%d' by the covered months in that year '%d'.\n", ntsteps/covered_years, step_per_year, fyear, covered_months);
+          if ( step_per_year > 366*8 )
+            cdoAbort("Step per year '%d' in year '%d' is bigger than 366*8 which corresponds to a frequency of sub-3hourly! This is not yet enabled.", step_per_year, fyear);
+          else
+            {
+              if ( (double)step_per_year / (double)covered_months > 31*8 )
+                cdoAbort("Frequency is sub-3hourly! Not yet enabled.");
+              else if ( (double)step_per_year / (double)covered_months > 31*4 )
+                strcpy(frequency, "3hr");
+              else if ( (double)step_per_year / (double)covered_months > 31 )
+                strcpy(frequency, "6hr");
+              else if ( (double)step_per_year / (double)covered_months > 1 )
+                strcpy(frequency, "day");
+              else
+                strcpy(frequency, "mon");
+            }
+        }
+    }
+  else
+    cdoAbort("For %d found timesteps no frequency can be computed - at least 3 timesteps are required.", ntsteps);
+  if ( cdoVerbose )
+    printf("Your file indicates a frequency of '%s'.\n", frequency);
+  cdiDefAttTxt(vlistID2, CDI_GLOBAL, "frequency", 3, frequency);
+
+  streamClose(streamID1);
+  streamClose(streamID2);
+
+  vlistDestroy(vlistID2);
+
+  if ( array ) Free(array);
+
+  cdoFinish();
+
+  return 0;
+}
diff --git a/src/Exprf.cc b/src/Exprf.cc
index 18f3c44..11ca484 100644
--- a/src/Exprf.cc
+++ b/src/Exprf.cc
@@ -104,7 +104,7 @@ paramType *params_new(int vlistID)
     {
       int gridID     = vlistInqVarGrid(vlistID, varID);
       int zaxisID    = vlistInqVarZaxis(vlistID, varID);
-      int steptype   = vlistInqVarTsteptype(vlistID, varID);
+      int steptype   = vlistInqVarTimetype(vlistID, varID);
       int ngp        = gridInqSize(gridID);
       int nlev       = zaxisInqSize(zaxisID);
       double missval = vlistInqVarMissval(vlistID, varID);
@@ -214,7 +214,7 @@ int params_add_ts(parse_param_t *parse_arg)
       params[varID].name     = strdup("_ts");
       params[varID].gridID   = parse_arg->pointID;
       params[varID].zaxisID  = parse_arg->surfaceID;
-      params[varID].steptype = TSTEP_INSTANT;
+      params[varID].steptype = TIME_VARYING;
       params[varID].ngp      = 1;
       params[varID].nlev     = 1;
       
diff --git a/src/Filedes.cc b/src/Filedes.cc
index 079cb3a..d75d729 100644
--- a/src/Filedes.cc
+++ b/src/Filedes.cc
@@ -258,6 +258,7 @@ void filedes(int streamID)
     case CDI_FILETYPE_NC2:  printf("  NetCDF2 data\n"); break;
     case CDI_FILETYPE_NC4:  printf("  NetCDF4 data\n"); break;
     case CDI_FILETYPE_NC4C: printf("  NetCDF4 classic data\n"); break;
+    case CDI_FILETYPE_NC5:  printf("  NetCDF5 data\n"); break;
     case CDI_FILETYPE_SRV:  printf("  SERVICE data\n"); break;
     case CDI_FILETYPE_EXT:  printf("  EXTRA data\n"); break;
     case CDI_FILETYPE_IEG:  printf("  IEG data\n"); break;
diff --git a/src/Fillmiss.cc b/src/Fillmiss.cc
index 99f5626..d8897fe 100644
--- a/src/Fillmiss.cc
+++ b/src/Fillmiss.cc
@@ -27,8 +27,8 @@
 #include "cdo_int.h"
 #include "pstream.h"
 #include "grid.h"
-
 #include "grid_search.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -277,9 +277,9 @@ void fillmiss_one_step(field_type *field1, field_type *field2, int maxfill)
 }
 
 
-int grid_search_nbr(struct gridsearch *gs, int num_neighbors, int *restrict nbr_add, double *restrict nbr_dist, double plon, double plat);
-double nbr_compute_weights(unsigned num_neighbors, const int *restrict src_grid_mask, bool *restrict nbr_mask, const int *restrict nbr_add, double *restrict nbr_dist);
-unsigned nbr_normalize_weights(unsigned num_neighbors, double dist_tot, const bool *restrict nbr_mask, int *restrict nbr_add, double *restrict nbr_dist);
+int grid_search_nbr(struct gridsearch *gs, size_t num_neighbors, size_t *restrict nbr_add, double *restrict nbr_dist, double plon, double plat);
+double nbr_compute_weights(size_t num_neighbors, const int *restrict src_grid_mask, bool *restrict nbr_mask, const size_t *restrict nbr_add, double *restrict nbr_dist);
+size_t nbr_normalize_weights(size_t num_neighbors, double dist_tot, const bool *restrict nbr_mask, size_t *restrict nbr_add, double *restrict nbr_dist);
 
 static
 void setmisstodis(field_type *field1, field_type *field2, int num_neighbors)
@@ -313,8 +313,8 @@ void setmisstodis(field_type *field1, field_type *field2, int num_neighbors)
   gridInqYunits(gridID, units);
   grid_to_radian(units, gridsize, yvals, "grid center lat");
 
-  unsigned *mindex = nmiss ? (unsigned *) Calloc(1, nmiss*sizeof(unsigned)) : NULL;
-  unsigned *vindex = nvals ? (unsigned *) Calloc(1, nvals*sizeof(unsigned)) : NULL;
+  size_t *mindex = nmiss ? (size_t *) Calloc(1, nmiss*sizeof(size_t)) : NULL;
+  size_t *vindex = nvals ? (size_t *) Calloc(1, nvals*sizeof(size_t)) : NULL;
   double *lons = nvals ? (double *) Malloc(nvals*sizeof(double)) : NULL;
   double *lats = nvals ? (double *) Malloc(nvals*sizeof(double)) : NULL;
   
@@ -338,9 +338,10 @@ void setmisstodis(field_type *field1, field_type *field2, int num_neighbors)
 
   if ( nv != nvals ) cdoAbort("Internal problem, number of valid values differ!");
   
-  bool nbr_mask[num_neighbors];   /* mask at nearest neighbors                   */
-  int nbr_add[num_neighbors];     /* source address at nearest neighbors         */
-  double nbr_dist[num_neighbors]; /* angular distance four nearest neighbors     */
+
+  NEW_2D(bool, nbr_mask, ompNumThreads, num_neighbors);   // mask at nearest neighbors
+  NEW_2D(size_t, nbr_add, ompNumThreads, num_neighbors);  // source address at nearest neighbors
+  NEW_2D(double, nbr_dist, ompNumThreads, num_neighbors); // angular distance four nearest neighbors
 
   clock_t start, finish;
   start = clock();
@@ -365,8 +366,10 @@ void setmisstodis(field_type *field1, field_type *field2, int num_neighbors)
 
   double findex = 0;
 
-#pragma omp parallel for default(none) shared(findex, mindex, vindex, array1, array2, xvals, yvals, gs, nmiss, num_neighbors) \
-                                      private(nbr_mask, nbr_add, nbr_dist)
+#if defined(_OPENMP)
+#pragma omp parallel for default(none) shared(nbr_mask, nbr_add, nbr_dist)  \
+  shared(findex, mindex, vindex, array1, array2, xvals, yvals, gs, nmiss, num_neighbors)
+#endif
   for ( unsigned i = 0; i < nmiss; ++i )
     {
 #if defined(_OPENMP)
@@ -375,17 +378,19 @@ void setmisstodis(field_type *field1, field_type *field2, int num_neighbors)
       findex++;
       if ( cdo_omp_get_thread_num() == 0 ) progressStatus(0, 1, findex/nmiss);
 
-      grid_search_nbr(gs, num_neighbors, nbr_add, nbr_dist, xvals[mindex[i]], yvals[mindex[i]]);
+      int ompthID = cdo_omp_get_thread_num();
+
+      grid_search_nbr(gs, num_neighbors, nbr_add[ompthID], nbr_dist[ompthID], xvals[mindex[i]], yvals[mindex[i]]);
 
       /* Compute weights based on inverse distance if mask is false, eliminate those points */
-      double dist_tot = nbr_compute_weights(num_neighbors, NULL, nbr_mask, nbr_add, nbr_dist);
+      double dist_tot = nbr_compute_weights(num_neighbors, NULL, nbr_mask[ompthID], nbr_add[ompthID], nbr_dist[ompthID]);
 
       /* Normalize weights and store the link */
-      unsigned nadds = nbr_normalize_weights(num_neighbors, dist_tot, nbr_mask, nbr_add, nbr_dist);
+      size_t nadds = nbr_normalize_weights(num_neighbors, dist_tot, nbr_mask[ompthID], nbr_add[ompthID], nbr_dist[ompthID]);
       if ( nadds )
         {
           double result = 0;
-          for ( unsigned n = 0; n < nadds; ++n ) result += array1[vindex[nbr_add[n]]]*nbr_dist[n];
+          for ( size_t n = 0; n < nadds; ++n ) result += array1[vindex[nbr_add[ompthID][n]]]*nbr_dist[ompthID][n];
           array2[mindex[i]] = result;
         }
     }
@@ -397,6 +402,10 @@ void setmisstodis(field_type *field1, field_type *field2, int num_neighbors)
 
   if ( cdoVerbose ) printf("gridsearch nearest: %.2f seconds\n", ((double)(finish-start))/CLOCKS_PER_SEC);
 
+  DELETE_2D(nbr_mask);
+  DELETE_2D(nbr_add);
+  DELETE_2D(nbr_dist);
+
   if ( gs ) gridsearch_delete(gs);
 
   if ( gridID0 != gridID ) gridDestroy(gridID);
diff --git a/src/Filter.cc b/src/Filter.cc
index 283c0f8..33a9a89 100644
--- a/src/Filter.cc
+++ b/src/Filter.cc
@@ -143,7 +143,6 @@ void *Filter(void *argument)
     fftw_plan p_S2T;
 #endif
   } memory_t;
-  memory_t *ompmem = NULL;
   
   cdoInitialize(argument);
 
@@ -250,10 +249,11 @@ void *Filter(void *argument)
   int nts = tsID;
   if ( nts <= 1 ) cdoAbort("Number of time steps <= 1!");
 
+  memory_t *ompmem = (memory_t*) Malloc(ompNumThreads*sizeof(memory_t));
+
   if ( use_fftw )
     {
 #if defined(HAVE_LIBFFTW3) 
-      ompmem = (memory_t*) Malloc(ompNumThreads*sizeof(memory_t));
       for ( int i = 0; i < ompNumThreads; i++ )
 	{
 	  ompmem[i].in_fft  = (fftw_complex*) Malloc(nts*sizeof(fftw_complex));
@@ -265,7 +265,6 @@ void *Filter(void *argument)
     }
   else
     {
-      ompmem = (memory_t*) Malloc(ompNumThreads*sizeof(memory_t));
       for ( int i = 0; i < ompNumThreads; i++ )
 	{
 	  ompmem[i].array1 = (double*) Malloc(nts*sizeof(double));
@@ -368,7 +367,6 @@ void *Filter(void *argument)
 	  Free(ompmem[i].in_fft);
 	  Free(ompmem[i].out_fft);
 	}
-      Free(ompmem);
 #endif
     }
   else
@@ -378,9 +376,10 @@ void *Filter(void *argument)
 	  Free(ompmem[i].array1);
 	  Free(ompmem[i].array2);
 	}
-      Free(ompmem);
     }
 
+  Free(ompmem);
+
   int streamID2 = pstreamOpenWrite(cdoStreamName(1), cdoFiletype());
   
   pstreamDefVlist(streamID2, vlistID2);
diff --git a/src/Fldstat.cc b/src/Fldstat.cc
index 46e11d4..2eb6a9d 100644
--- a/src/Fldstat.cc
+++ b/src/Fldstat.cc
@@ -145,22 +145,13 @@ void *Fldstat(void *argument)
   int taxisID2 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
-  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);
-    }
+  double slon = 0;
+  double slat = 0;
+  gridID2 = gridCreate(GRID_LONLAT, 1);
+  gridDefXsize(gridID2, 1);
+  gridDefYsize(gridID2, 1);
+  gridDefXvals(gridID2, &slon);
+  gridDefYvals(gridID2, &slat);
 
   int ngrids = vlistNgrids(vlistID1);
 
diff --git a/src/Fldstat2.cc b/src/Fldstat2.cc
index 0d40577..71c2a6b 100644
--- a/src/Fldstat2.cc
+++ b/src/Fldstat2.cc
@@ -123,22 +123,13 @@ void *Fldstat2(void *argument)
   int taxisID3 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID3, taxisID3);
 
-  if ( CDO_Reduce_Dim )
-    {
-      gridID3 = gridCreate(GRID_GENERIC, 1);
-      gridDefXsize(gridID3, 0);
-      gridDefYsize(gridID3, 0);
-    }
-  else
-    {
-      double slon = 0;
-      double slat = 0;
-      gridID3 = gridCreate(GRID_LONLAT, 1);
-      gridDefXsize(gridID3, 1);
-      gridDefYsize(gridID3, 1);
-      gridDefXvals(gridID3, &slon);
-      gridDefYvals(gridID3, &slat);
-    }
+  double slon = 0;
+  double slat = 0;
+  gridID3 = gridCreate(GRID_LONLAT, 1);
+  gridDefXsize(gridID3, 1);
+  gridDefYsize(gridID3, 1);
+  gridDefXvals(gridID3, &slon);
+  gridDefYvals(gridID3, &slat);
 
   int ngrids = vlistNgrids(vlistID1);
 
diff --git a/src/Gengrid.cc b/src/Gengrid.cc
index 682688a..63ef912 100644
--- a/src/Gengrid.cc
+++ b/src/Gengrid.cc
@@ -79,9 +79,9 @@ void *Gengrid(void *argument)
   gridDefYvals(gridID3, array2);
 
   if ( datatype == CDI_DATATYPE_FLT64 )
-    gridDefPrec(gridID3, CDI_DATATYPE_FLT64);
+    gridDefDatatype(gridID3, CDI_DATATYPE_FLT64);
   else
-    gridDefPrec(gridID3, CDI_DATATYPE_FLT32);
+    gridDefDatatype(gridID3, CDI_DATATYPE_FLT32);
 
   double xminval = array1[0];
   double xmaxval = array1[0];
@@ -117,7 +117,7 @@ void *Gengrid(void *argument)
   int zaxisID3 = zaxisCreate(ZAXIS_SURFACE, 1);
 
   int vlistID3 = vlistCreate();
-  vlistDefVar(vlistID3, gridID3, zaxisID3, TSTEP_CONSTANT);
+  vlistDefVar(vlistID3, gridID3, zaxisID3, TIME_CONSTANT);
   vlistDefVarMissval(vlistID3, 0, missval);
   vlistDefVarName(vlistID3, 0, "dummy");
   vlistDefVarDatatype(vlistID3, 0, CDI_DATATYPE_INT8);
diff --git a/src/Gradsdes.cc b/src/Gradsdes.cc
index cb0826b..92aaa60 100644
--- a/src/Gradsdes.cc
+++ b/src/Gradsdes.cc
@@ -737,7 +737,7 @@ void ctl_vars(FILE *gdp, int filetype, int vlistID, int nvarsout, int *vars)
               int xyz = vlistInqVarXYZ(vlistID, varID);
 
               fprintf(gdp, "  ");
-              if ( vlistInqVarTsteptype(vlistID, varID) != TSTEP_CONSTANT )
+              if ( vlistInqVarTimetype(vlistID, varID) != TIME_CONSTANT )
                 fprintf(gdp, "t,");
               if ( xyz == 321 )
                 {
@@ -955,7 +955,7 @@ void *Gradsdes(void *argument)
   bool bigendian = false, littleendian = false;
   bool sequential = false;
   bool flt64 = false;
-  char Time[30], Incr[10] = {"1mn"};
+  char Time[30], Incr[12] = {"1mn"};
   const char *IncrKey[] = {"mn","hr","dy","mo","yr"};
   int isd, imn, ihh, iyy, imm, idd;
   int isds = 0, imns = 0, ihhs = 0, iyys = 0, imms = 0, idds = 0;
@@ -963,7 +963,6 @@ void *Gradsdes(void *argument)
   int idmn, idhh, idmm, idyy, iddd;
   int dt=1, iik=0, mdt = 0;
   int gridsize = 0;
-  long checksize = 0;
   int nmiss;
   int prec;
   int map_version = 2;
@@ -1031,7 +1030,8 @@ void *Gradsdes(void *argument)
   int filetype  = pstreamInqFiletype(streamID);
   int byteorder = pstreamInqByteorder(streamID);
 
-  if ( filetype == CDI_FILETYPE_NC2 || filetype == CDI_FILETYPE_NC4 ) filetype = CDI_FILETYPE_NC;
+  if ( filetype == CDI_FILETYPE_NC2 || filetype == CDI_FILETYPE_NC4 ||
+       filetype == CDI_FILETYPE_NC4C || filetype == CDI_FILETYPE_NC5 ) filetype = CDI_FILETYPE_NC;
 
   if ( filetype != CDI_FILETYPE_SRV &&
        filetype != CDI_FILETYPE_EXT &&
@@ -1082,7 +1082,7 @@ void *Gradsdes(void *argument)
           recoffset[varID] = nrecsout;
           nvarsout++;
           nrecsout += zaxisInqSize(vlistInqVarZaxis(vlistID, varID));
-          if ( ntsteps != 1 && ntsteps != 0 && vlistInqVarTsteptype(vlistID, varID) == TSTEP_CONSTANT )
+          if ( ntsteps != 1 && ntsteps != 0 && vlistInqVarTimetype(vlistID, varID) == TIME_CONSTANT )
             cdoAbort("Unsupported GrADS record structure! Variable %d has only 1 time step.",
                      vlistInqVarCode(vlistID, varID));
         }
@@ -1320,7 +1320,7 @@ void *Gradsdes(void *argument)
 
                   if ( map_version != 4 )
                     {
-                      checksize = (long)bignum[index*2] + (long)gridsize*intnum[index]/8;
+                      long checksize = (long)bignum[index*2] + (long)gridsize*intnum[index]/8;
                       if ( checksize < 0L || checksize > 2147483647L )
                         {
                           nrecords -= nrecsout;
diff --git a/src/Gridcell.cc b/src/Gridcell.cc
index 6e2e7c6..081ddf6 100644
--- a/src/Gridcell.cc
+++ b/src/Gridcell.cc
@@ -125,7 +125,7 @@ void *Gridcell(void *argument)
   int zaxisID = zaxisCreate(ZAXIS_SURFACE, 1);
 
   int vlistID2 = vlistCreate();
-  int varID    = vlistDefVar(vlistID2, gridID, zaxisID, TSTEP_CONSTANT);
+  int varID    = vlistDefVar(vlistID2, gridID, zaxisID, TIME_CONSTANT);
   vlistDefNtsteps(vlistID2, 0);
 
   if ( operatorID == GRIDAREA )
diff --git a/src/Hi.cc b/src/Hi.cc
index 2b1d438..9b7bb93 100644
--- a/src/Hi.cc
+++ b/src/Hi.cc
@@ -128,7 +128,7 @@ void *Hi(void *argument)
   int vlistID4 = vlistCreate();
   int gridID   = vlistInqVarGrid(vlistID1, FIRST_VAR);
   int zaxisID  = vlistInqVarZaxis(vlistID1, FIRST_VAR);
-  int varID4   = vlistDefVar(vlistID4, gridID, zaxisID, TSTEP_INSTANT);
+  int varID4   = vlistDefVar(vlistID4, gridID, zaxisID, TIME_VARYING);
 
   int taxisID4 = taxisCreate(TAXIS_RELATIVE);
   taxisDefTunit(taxisID4, TUNIT_MINUTE);
diff --git a/src/Importamsr.cc b/src/Importamsr.cc
index bf3dda2..cdc22fb 100644
--- a/src/Importamsr.cc
+++ b/src/Importamsr.cc
@@ -53,7 +53,7 @@ void init_amsr_day(int vlistID, int gridID, int zaxisID, int nvars)
 
   for ( i = 0; i < nvars; ++i )
     {
-      varID = vlistDefVar(vlistID, gridID, zaxisID, TSTEP_INSTANT);
+      varID = vlistDefVar(vlistID, gridID, zaxisID, TIME_VARYING);
       vlistDefVarName(vlistID, varID, name[i]);
       vlistDefVarUnits(vlistID, varID, units[i]);
       vlistDefVarDatatype(vlistID, varID, CDI_DATATYPE_INT16);
@@ -99,8 +99,8 @@ void init_amsr_averaged(int vlistID, int gridID, int zaxisID, int nvars)
 
   for ( i = 0; i < nvars; ++i )
     {
-      /* varID = vlistDefVar(vlistID, gridID, zaxisID, TSTEP_CONSTANT); */
-      varID = vlistDefVar(vlistID, gridID, zaxisID, TSTEP_INSTANT);
+      /* varID = vlistDefVar(vlistID, gridID, zaxisID, TIME_CONSTANT); */
+      varID = vlistDefVar(vlistID, gridID, zaxisID, TIME_VARYING);
       vlistDefVarName(vlistID, varID, name[i]);
       vlistDefVarUnits(vlistID, varID, units[i]);
       vlistDefVarDatatype(vlistID, varID, CDI_DATATYPE_INT16);
diff --git a/src/Importbinary.cc b/src/Importbinary.cc
index 4bd0ce2..97d3725 100644
--- a/src/Importbinary.cc
+++ b/src/Importbinary.cc
@@ -16,11 +16,7 @@
 */
 
 #if defined(HAVE_CONFIG_H)
-#  include "config.h"
-#endif
-
-#ifndef _XOPEN_SOURCE
-#define _XOPEN_SOURCE 600 /* fseeko */
+#include "config.h"
 #endif
 
 
@@ -256,7 +252,7 @@ void *Importbinary(void *argument)
       if ( nlevels == 0 )
 	{
 	  nlevels = 1;
-	  varID = vlistDefVar(vlistID, gridID, zaxisIDsfc, TSTEP_INSTANT);
+	  varID = vlistDefVar(vlistID, gridID, zaxisIDsfc, TIME_VARYING);
 	}
       else
 	{
@@ -273,10 +269,10 @@ void *Importbinary(void *argument)
 		}
 
 	      if ( vid == ivar ) zid = define_level(&pfi, nlevels);
-	      varID = vlistDefVar(vlistID, gridID, zid, TSTEP_INSTANT);
+	      varID = vlistDefVar(vlistID, gridID, zid, TIME_VARYING);
 	    }
 	  else
-	    varID = vlistDefVar(vlistID, gridID, zaxisID, TSTEP_INSTANT);
+	    varID = vlistDefVar(vlistID, gridID, zaxisID, TIME_VARYING);
 	}
 
       var_zaxisID[varID] = vlistInqVarZaxis(vlistID, varID);
diff --git a/src/Importcmsaf.cc b/src/Importcmsaf.cc
index f69c3c1..85919e2 100644
--- a/src/Importcmsaf.cc
+++ b/src/Importcmsaf.cc
@@ -1518,9 +1518,9 @@ void *Importcmsaf(void *argument)
   for ( ivar = 0; ivar < dsets.nsets; ++ivar )
     {
       if ( dsets.obj[ivar].nt > 1 )
-	varID = vlistDefVar(vlistID, gridID, zaxisID, TSTEP_INSTANT);
+	varID = vlistDefVar(vlistID, gridID, zaxisID, TIME_VARYING);
       else
-	varID = vlistDefVar(vlistID, gridID, zaxisID, TSTEP_INSTANT);
+	varID = vlistDefVar(vlistID, gridID, zaxisID, TIME_VARYING);
 
       vlistDefVarName(vlistID, varID,  dsets.obj[ivar].name);
       if ( dsets.obj[ivar].description )
@@ -1529,7 +1529,7 @@ void *Importcmsaf(void *argument)
 	vlistDefVarUnits(vlistID, varID,  dsets.obj[ivar].units);
       if ( dsets.obj[ivar].title )
 	cdiDefAttTxt(vlistID, varID, "title", (int)strlen(dsets.obj[ivar].title),
-		       dsets.obj[ivar].title);
+                     dsets.obj[ivar].title);
 
       /*
       vlistDefVarUnits(vlistID, varID, units[i]);
diff --git a/src/Importobs.cc b/src/Importobs.cc
index e379d0b..96b0b48 100644
--- a/src/Importobs.cc
+++ b/src/Importobs.cc
@@ -36,7 +36,7 @@ void init_vars(int vlistID, int gridID, int zaxisID, int nvars)
 
   for ( int i = 0; i < nvars; ++i )
     {
-      varID = vlistDefVar(vlistID, gridID, zaxisID, TSTEP_INSTANT);
+      varID = vlistDefVar(vlistID, gridID, zaxisID, TIME_VARYING);
       vlistDefVarParam(vlistID, varID, cdiEncodeParam(code[i], 255, 255));
       vlistDefVarName(vlistID, varID, name[i]);
       vlistDefVarUnits(vlistID, varID, units[i]);
diff --git a/src/Input.cc b/src/Input.cc
index 2b5d645..e8372a1 100644
--- a/src/Input.cc
+++ b/src/Input.cc
@@ -221,7 +221,7 @@ void *Input(void *argument)
             }
 
 	  vlistID = vlistCreate();
-	  varID = vlistDefVar(vlistID, gridID, zaxisID, TSTEP_INSTANT);
+	  varID = vlistDefVar(vlistID, gridID, zaxisID, TIME_VARYING);
 	  vlistDefVarParam(vlistID, varID, cdiEncodeParam(code, 255, 255));
 
 	  missval = vlistInqVarMissval(vlistID, varID);
diff --git a/src/Intgrid.cc b/src/Intgrid.cc
index 5d5a4ff..7c03a86 100644
--- a/src/Intgrid.cc
+++ b/src/Intgrid.cc
@@ -304,6 +304,7 @@ void *Intgrid(void *argument)
 
   int operatorID = cdoOperatorID();
 
+  // open stream before calling cdoDefineGrid!!!
   int streamID1 = pstreamOpenRead(cdoStreamName(0));
 
   if ( operatorID == INTGRIDBIL || operatorID == INTERPOLATE )
diff --git a/src/Intgridtraj.cc b/src/Intgridtraj.cc
index 9a383a5..065a28f 100644
--- a/src/Intgridtraj.cc
+++ b/src/Intgridtraj.cc
@@ -28,16 +28,16 @@
 #include "interpol.h"
 
 
+static
 int readnextpos(FILE *fp, int calendar, juldate_t *juldate, double *xpos, double *ypos)
 {
   int year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0;
-  int stat;
 
   *xpos = 0;
   *ypos = 0;
 
-  stat = fscanf(fp, "%d-%d-%d %d:%d:%d %lf %lf",
-		&year, &month, &day, &hour, &minute, &second, xpos, ypos);
+  int stat = fscanf(fp, "%d-%d-%d %d:%d:%d %lf %lf",
+                    &year, &month, &day, &hour, &minute, &second, xpos, ypos);
 
   if ( stat != EOF )
     {
@@ -53,16 +53,11 @@ int readnextpos(FILE *fp, int calendar, juldate_t *juldate, double *xpos, double
 void *Intgridtraj(void *argument)
 {
   int gridID1;
-  int nlevel;
   int varID, levelID;
   int vdate, vtime;
-  int offset;
   int nmiss;
   double point;
-  double *single1, *single2;
-  double *vardatap;
   double xpos, ypos;
-  double missval;
   int calendar = CALENDAR_STANDARD;
 
   cdoInitialize(argument);
@@ -91,7 +86,7 @@ void *Intgridtraj(void *argument)
   int *recVarID   = (int*) Malloc(nrecords*sizeof(int));
   int *recLevelID = (int*) Malloc(nrecords*sizeof(int));
 
-  int gridsize = vlistGridsizeMax(vlistID1);
+  size_t gridsize = vlistGridsizeMax(vlistID1);
   double *array = (double*) Malloc(gridsize*sizeof(double));
 
   double **vardata1 = (double**) Malloc(nvars*sizeof(double*));
@@ -100,7 +95,7 @@ void *Intgridtraj(void *argument)
   for ( varID = 0; varID < nvars; varID++ )
     {
       gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
-      nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
+      size_t nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
       vardata1[varID] = (double*) Malloc(gridsize*nlevel*sizeof(double));
       vardata2[varID] = (double*) Malloc(gridsize*nlevel*sizeof(double));
     }
@@ -139,8 +134,8 @@ void *Intgridtraj(void *argument)
     {
       pstreamInqRecord(streamID1, &varID, &levelID);
       gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
-      offset   = gridsize*levelID;
-      single1  = vardata1[varID] + offset;
+      size_t offset = gridsize*levelID;
+      double *single1 = vardata1[varID] + offset;
       pstreamReadRecord(streamID1, single1, &nmiss);
       if ( nmiss ) cdoAbort("Missing values unsupported for this operator!");
     }
@@ -160,8 +155,8 @@ void *Intgridtraj(void *argument)
 	  recLevelID[recID] = levelID;
 
 	  gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
-	  offset   = gridsize*levelID;
-	  single2  = vardata2[varID] + offset;
+	  size_t offset = gridsize*levelID;
+	  double *single2  = vardata2[varID] + offset;
 	  pstreamReadRecord(streamID1, single2, &nmiss);
 	  if ( nmiss ) cdoAbort("Missing values unsupported for this operator!");
 	}
@@ -189,14 +184,14 @@ void *Intgridtraj(void *argument)
 		{
 		  varID    = recVarID[recID];
 		  levelID  = recLevelID[recID];
-		  missval  = vlistInqVarMissval(vlistID1, varID);
+		  double missval = vlistInqVarMissval(vlistID1, varID);
 		  gridID1  = vlistInqVarGrid(vlistID1, varID);
 		  gridsize = gridInqSize(gridID1);
-		  offset   = gridsize*levelID;
-		  single1  = vardata1[varID] + offset;
-		  single2  = vardata2[varID] + offset;
+		  size_t offset = gridsize*levelID;
+		  double *single1 = vardata1[varID] + offset;
+		  double *single2 = vardata2[varID] + offset;
 
-		  for ( int i = 0; i < gridsize; i++ )
+		  for ( size_t i = 0; i < gridsize; i++ )
 		    array[i] = single1[i]*fac1 + single2[i]*fac2;
 
 		  field1.grid    = gridID1;
@@ -221,7 +216,7 @@ void *Intgridtraj(void *argument)
       juldate1 = juldate2;
       for ( varID = 0; varID < nvars; varID++ )
 	{
-	  vardatap        = vardata1[varID];
+	  double *vardatap = vardata1[varID];
 	  vardata1[varID] = vardata2[varID];
 	  vardata2[varID] = vardatap;
 	}
diff --git a/src/Intlevel.cc b/src/Intlevel.cc
index 8f73436..902f741 100644
--- a/src/Intlevel.cc
+++ b/src/Intlevel.cc
@@ -276,7 +276,7 @@ void *Intlevel(void *argument)
     zaxisInqUnits(zaxisID1, str);
     if ( str[0] ) zaxisDefUnits(zaxisID2, str);
 
-    zaxisDefPrec(zaxisID2, zaxisInqPrec(zaxisID1));
+    zaxisDefDatatype(zaxisID2, zaxisInqDatatype(zaxisID1));
   }
 
   for ( int i = 0; i < nzaxis; i++ )
diff --git a/src/Intlevel3d.cc b/src/Intlevel3d.cc
index 1f70fb3..5d23e93 100644
--- a/src/Intlevel3d.cc
+++ b/src/Intlevel3d.cc
@@ -299,7 +299,7 @@ void *Intlevel3d(void *argument)
     if ( zaxisID1 == vlistZaxis(vlistID1, i) )
       vlistChangeZaxisIndex(vlistID3, i, zaxisID3);
   /* add the vertical output field to the output stream */
-  int oz3dvarID = vlistDefVar(vlistID3, gridID3, zaxisID3, TSTEP_INSTANT);
+  int oz3dvarID = vlistDefVar(vlistID3, gridID3, zaxisID3, TIME_VARYING);
   {
     char str[256];
     str[0] = 0;
diff --git a/src/Makefile.am b/src/Makefile.am
index 9824110..4b002b2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -243,6 +243,7 @@ cdo_SOURCES += Adisit.cc        \
                Ensval.cc        \
                Eofcoeff.cc      \
 	       Eofcoeff3d.cc    \
+               EstFreq.cc       \
                Exprf.cc         \
                FC.cc            \
                Filedes.cc       \
@@ -331,6 +332,8 @@ cdo_SOURCES += Adisit.cc        \
                Setzaxis.cc      \
                Shiftxy.cc       \
                Showinfo.cc      \
+               Showattribute.h  \
+               Showattribute.cc \
                Sinfo.cc         \
                Smooth.cc        \
                Sort.cc          \
diff --git a/src/Makefile.in b/src/Makefile.in
index a91bd9b..476d28e 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -189,28 +189,28 @@ am_cdo_OBJECTS = cdo-cdo.$(OBJEXT) cdo-Adisit.$(OBJEXT) \
 	cdo-Enlarge.$(OBJEXT) cdo-Enlargegrid.$(OBJEXT) \
 	cdo-Ensstat.$(OBJEXT) cdo-Ensstat3.$(OBJEXT) \
 	cdo-Ensval.$(OBJEXT) cdo-Eofcoeff.$(OBJEXT) \
-	cdo-Eofcoeff3d.$(OBJEXT) cdo-Exprf.$(OBJEXT) cdo-FC.$(OBJEXT) \
-	cdo-Filedes.$(OBJEXT) cdo-Fillmiss.$(OBJEXT) \
-	cdo-Filter.$(OBJEXT) cdo-Fldrms.$(OBJEXT) \
-	cdo-Fldstat.$(OBJEXT) cdo-Fldstat2.$(OBJEXT) \
-	cdo-Fourier.$(OBJEXT) cdo-Gengrid.$(OBJEXT) \
-	cdo-Gradsdes.$(OBJEXT) cdo-Gridboxstat.$(OBJEXT) \
-	cdo-Gridcell.$(OBJEXT) cdo-Gridsearch.$(OBJEXT) \
-	cdo-Harmonic.$(OBJEXT) cdo-Hi.$(OBJEXT) \
-	cdo-Histogram.$(OBJEXT) cdo-Importamsr.$(OBJEXT) \
-	cdo-Importbinary.$(OBJEXT) cdo-Importcmsaf.$(OBJEXT) \
-	cdo-Importobs.$(OBJEXT) cdo-Info.$(OBJEXT) cdo-Input.$(OBJEXT) \
-	cdo-Intgrid.$(OBJEXT) cdo-Intgridtraj.$(OBJEXT) \
-	cdo-Intlevel.$(OBJEXT) cdo-Intlevel3d.$(OBJEXT) \
-	cdo-Intntime.$(OBJEXT) cdo-Inttime.$(OBJEXT) \
-	cdo-Intyear.$(OBJEXT) cdo-Invert.$(OBJEXT) \
-	cdo-Invertlev.$(OBJEXT) cdo-Isosurface.$(OBJEXT) \
-	cdo-Log.$(OBJEXT) cdo-MapReduce.$(OBJEXT) \
-	cdo-Maskbox.$(OBJEXT) cdo-Mastrfu.$(OBJEXT) cdo-Math.$(OBJEXT) \
-	cdo-Merge.$(OBJEXT) cdo-Mergegrid.$(OBJEXT) \
-	cdo-Mergetime.$(OBJEXT) cdo-Merstat.$(OBJEXT) \
-	cdo-Monarith.$(OBJEXT) cdo-Mrotuv.$(OBJEXT) \
-	cdo-Mrotuvb.$(OBJEXT) cdo-Ninfo.$(OBJEXT) \
+	cdo-Eofcoeff3d.$(OBJEXT) cdo-EstFreq.$(OBJEXT) \
+	cdo-Exprf.$(OBJEXT) cdo-FC.$(OBJEXT) cdo-Filedes.$(OBJEXT) \
+	cdo-Fillmiss.$(OBJEXT) cdo-Filter.$(OBJEXT) \
+	cdo-Fldrms.$(OBJEXT) cdo-Fldstat.$(OBJEXT) \
+	cdo-Fldstat2.$(OBJEXT) cdo-Fourier.$(OBJEXT) \
+	cdo-Gengrid.$(OBJEXT) cdo-Gradsdes.$(OBJEXT) \
+	cdo-Gridboxstat.$(OBJEXT) cdo-Gridcell.$(OBJEXT) \
+	cdo-Gridsearch.$(OBJEXT) cdo-Harmonic.$(OBJEXT) \
+	cdo-Hi.$(OBJEXT) cdo-Histogram.$(OBJEXT) \
+	cdo-Importamsr.$(OBJEXT) cdo-Importbinary.$(OBJEXT) \
+	cdo-Importcmsaf.$(OBJEXT) cdo-Importobs.$(OBJEXT) \
+	cdo-Info.$(OBJEXT) cdo-Input.$(OBJEXT) cdo-Intgrid.$(OBJEXT) \
+	cdo-Intgridtraj.$(OBJEXT) cdo-Intlevel.$(OBJEXT) \
+	cdo-Intlevel3d.$(OBJEXT) cdo-Intntime.$(OBJEXT) \
+	cdo-Inttime.$(OBJEXT) cdo-Intyear.$(OBJEXT) \
+	cdo-Invert.$(OBJEXT) cdo-Invertlev.$(OBJEXT) \
+	cdo-Isosurface.$(OBJEXT) cdo-Log.$(OBJEXT) \
+	cdo-MapReduce.$(OBJEXT) cdo-Maskbox.$(OBJEXT) \
+	cdo-Mastrfu.$(OBJEXT) cdo-Math.$(OBJEXT) cdo-Merge.$(OBJEXT) \
+	cdo-Mergegrid.$(OBJEXT) cdo-Mergetime.$(OBJEXT) \
+	cdo-Merstat.$(OBJEXT) cdo-Monarith.$(OBJEXT) \
+	cdo-Mrotuv.$(OBJEXT) cdo-Mrotuvb.$(OBJEXT) cdo-Ninfo.$(OBJEXT) \
 	cdo-Nmldump.$(OBJEXT) cdo-Output.$(OBJEXT) \
 	cdo-Outputgmt.$(OBJEXT) cdo-Pack.$(OBJEXT) \
 	cdo-Pardup.$(OBJEXT) cdo-Pinfo.$(OBJEXT) \
@@ -231,7 +231,8 @@ am_cdo_OBJECTS = cdo-cdo.$(OBJEXT) cdo-Adisit.$(OBJEXT) \
 	cdo-Setpartab.$(OBJEXT) cdo-Setrcaname.$(OBJEXT) \
 	cdo-Settime.$(OBJEXT) cdo-Setzaxis.$(OBJEXT) \
 	cdo-Shiftxy.$(OBJEXT) cdo-Showinfo.$(OBJEXT) \
-	cdo-Sinfo.$(OBJEXT) cdo-Smooth.$(OBJEXT) cdo-Sort.$(OBJEXT) \
+	cdo-Showattribute.$(OBJEXT) cdo-Sinfo.$(OBJEXT) \
+	cdo-Smooth.$(OBJEXT) cdo-Sort.$(OBJEXT) \
 	cdo-Sorttimestamp.$(OBJEXT) cdo-Specinfo.$(OBJEXT) \
 	cdo-Spectral.$(OBJEXT) cdo-Spectrum.$(OBJEXT) \
 	cdo-Split.$(OBJEXT) cdo-Splitrec.$(OBJEXT) \
@@ -599,27 +600,28 @@ cdo_SOURCES = cdo.cc Adisit.cc Afterburner.cc Arith.cc Arithc.cc \
 	Detrend.cc Diff.cc Distgrid.cc Duplicate.cc EOFs.cc Eof3d.cc \
 	EcaIndices.cc Echam5ini.cc Enlarge.cc Enlargegrid.cc \
 	Ensstat.cc Ensstat3.cc Ensval.cc Eofcoeff.cc Eofcoeff3d.cc \
-	Exprf.cc FC.cc Filedes.cc Fillmiss.cc Filter.cc Fldrms.cc \
-	Fldstat.cc Fldstat2.cc Fourier.cc Gengrid.cc Gradsdes.cc \
-	Gridboxstat.cc Gridcell.cc Gridsearch.cc Harmonic.cc Hi.cc \
-	Histogram.cc Importamsr.cc Importbinary.cc Importcmsaf.cc \
-	Importobs.cc Info.cc Input.cc Intgrid.cc Intgridtraj.cc \
-	Intlevel.cc Intlevel3d.cc Intntime.cc Inttime.cc Intyear.cc \
-	Invert.cc Invertlev.cc Isosurface.cc Log.cc MapReduce.cc \
-	Maskbox.cc Mastrfu.cc Math.cc Merge.cc Mergegrid.cc \
-	Mergetime.cc Merstat.cc Monarith.cc Mrotuv.cc Mrotuvb.cc \
-	Ninfo.cc Nmldump.cc Output.cc Outputgmt.cc Pack.cc Pardup.cc \
-	Pinfo.cc Pressure.cc Regres.cc Remap.cc Remapeta.cc Replace.cc \
-	Replacevalues.cc Rhopot.cc Rotuv.cc Runpctl.cc Runstat.cc \
-	Samplegrid.cc Samplegridicon.cc Seascount.cc Seaspctl.cc \
-	Seasstat.cc Selbox.cc Selgridcell.cc Select.cc Selmulti.cc \
-	Seloperator.cc Selrec.cc Seltime.cc Selvar.cc Set.cc \
-	Setattribute.cc Setbox.cc Setgatt.cc Setgrid.cc Sethalo.cc \
-	Setmiss.cc Setpartab.cc Setrcaname.cc Settime.cc Setzaxis.cc \
-	Shiftxy.cc Showinfo.cc Sinfo.cc Smooth.cc Sort.cc \
-	Sorttimestamp.cc Specinfo.cc Spectral.cc Spectrum.cc Split.cc \
-	Splitrec.cc Splitsel.cc Splittime.cc Splityear.cc Subtrend.cc \
-	Tee.cc Templates.cc Test.cc Tests.cc Timcount.cc Timcumsum.cc \
+	EstFreq.cc Exprf.cc FC.cc Filedes.cc Fillmiss.cc Filter.cc \
+	Fldrms.cc Fldstat.cc Fldstat2.cc Fourier.cc Gengrid.cc \
+	Gradsdes.cc Gridboxstat.cc Gridcell.cc Gridsearch.cc \
+	Harmonic.cc Hi.cc Histogram.cc Importamsr.cc Importbinary.cc \
+	Importcmsaf.cc Importobs.cc Info.cc Input.cc Intgrid.cc \
+	Intgridtraj.cc Intlevel.cc Intlevel3d.cc Intntime.cc \
+	Inttime.cc Intyear.cc Invert.cc Invertlev.cc Isosurface.cc \
+	Log.cc MapReduce.cc Maskbox.cc Mastrfu.cc Math.cc Merge.cc \
+	Mergegrid.cc Mergetime.cc Merstat.cc Monarith.cc Mrotuv.cc \
+	Mrotuvb.cc Ninfo.cc Nmldump.cc Output.cc Outputgmt.cc Pack.cc \
+	Pardup.cc Pinfo.cc Pressure.cc Regres.cc Remap.cc Remapeta.cc \
+	Replace.cc Replacevalues.cc Rhopot.cc Rotuv.cc Runpctl.cc \
+	Runstat.cc Samplegrid.cc Samplegridicon.cc Seascount.cc \
+	Seaspctl.cc Seasstat.cc Selbox.cc Selgridcell.cc Select.cc \
+	Selmulti.cc Seloperator.cc Selrec.cc Seltime.cc Selvar.cc \
+	Set.cc Setattribute.cc Setbox.cc Setgatt.cc Setgrid.cc \
+	Sethalo.cc Setmiss.cc Setpartab.cc Setrcaname.cc Settime.cc \
+	Setzaxis.cc Shiftxy.cc Showinfo.cc Showattribute.h \
+	Showattribute.cc Sinfo.cc Smooth.cc Sort.cc Sorttimestamp.cc \
+	Specinfo.cc Spectral.cc Spectrum.cc Split.cc Splitrec.cc \
+	Splitsel.cc Splittime.cc Splityear.cc Subtrend.cc Tee.cc \
+	Templates.cc Test.cc Tests.cc Timcount.cc Timcumsum.cc \
 	Timpctl.cc Timselpctl.cc Timselstat.cc Timsort.cc Timstat.cc \
 	Timstat2.cc Timstat3.cc Tinfo.cc Tocomplex.cc Transpose.cc \
 	Trend.cc Trms.cc Tstepcount.cc Vargen.cc Varrms.cc \
@@ -884,6 +886,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Eof3d.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Eofcoeff.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Eofcoeff3d.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-EstFreq.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Exprf.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-FC.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Filedes.Po at am__quote@
@@ -974,6 +977,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Settime.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Setzaxis.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Shiftxy.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Showattribute.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Showinfo.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Sinfo.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Smooth.Po at am__quote@
@@ -2609,6 +2613,20 @@ cdo-Eofcoeff3d.obj: Eofcoeff3d.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cdo-Eofcoeff3d.obj `if test -f 'Eofcoeff3d.cc'; then $(CYGPATH_W) 'Eofcoeff3d.cc'; else $(CYGPATH_W) '$(srcdir)/Eofcoeff3d.cc'; fi`
 
+cdo-EstFreq.o: EstFreq.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cdo-EstFreq.o -MD -MP -MF $(DEPDIR)/cdo-EstFreq.Tpo -c -o cdo-EstFreq.o `test -f 'EstFreq.cc' || echo '$(srcdir)/'`EstFreq.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-EstFreq.Tpo $(DEPDIR)/cdo-EstFreq.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='EstFreq.cc' object='cdo-EstFreq.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cdo-EstFreq.o `test -f 'EstFreq.cc' || echo '$(srcdir)/'`EstFreq.cc
+
+cdo-EstFreq.obj: EstFreq.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cdo-EstFreq.obj -MD -MP -MF $(DEPDIR)/cdo-EstFreq.Tpo -c -o cdo-EstFreq.obj `if test -f 'EstFreq.cc'; then $(CYGPATH_W) 'EstFreq.cc'; else $(CYGPATH_W) '$(srcdir)/EstFreq.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-EstFreq.Tpo $(DEPDIR)/cdo-EstFreq.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='EstFreq.cc' object='cdo-EstFreq.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cdo-EstFreq.obj `if test -f 'EstFreq.cc'; then $(CYGPATH_W) 'EstFreq.cc'; else $(CYGPATH_W) '$(srcdir)/EstFreq.cc'; fi`
+
 cdo-Exprf.o: Exprf.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cdo-Exprf.o -MD -MP -MF $(DEPDIR)/cdo-Exprf.Tpo -c -o cdo-Exprf.o `test -f 'Exprf.cc' || echo '$(srcdir)/'`Exprf.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-Exprf.Tpo $(DEPDIR)/cdo-Exprf.Po
@@ -3841,6 +3859,20 @@ cdo-Showinfo.obj: Showinfo.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cdo-Showinfo.obj `if test -f 'Showinfo.cc'; then $(CYGPATH_W) 'Showinfo.cc'; else $(CYGPATH_W) '$(srcdir)/Showinfo.cc'; fi`
 
+cdo-Showattribute.o: Showattribute.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cdo-Showattribute.o -MD -MP -MF $(DEPDIR)/cdo-Showattribute.Tpo -c -o cdo-Showattribute.o `test -f 'Showattribute.cc' || echo '$(srcdir)/'`Showattribute.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-Showattribute.Tpo $(DEPDIR)/cdo-Showattribute.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='Showattribute.cc' object='cdo-Showattribute.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cdo-Showattribute.o `test -f 'Showattribute.cc' || echo '$(srcdir)/'`Showattribute.cc
+
+cdo-Showattribute.obj: Showattribute.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cdo-Showattribute.obj -MD -MP -MF $(DEPDIR)/cdo-Showattribute.Tpo -c -o cdo-Showattribute.obj `if test -f 'Showattribute.cc'; then $(CYGPATH_W) 'Showattribute.cc'; else $(CYGPATH_W) '$(srcdir)/Showattribute.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-Showattribute.Tpo $(DEPDIR)/cdo-Showattribute.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='Showattribute.cc' object='cdo-Showattribute.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o cdo-Showattribute.obj `if test -f 'Showattribute.cc'; then $(CYGPATH_W) 'Showattribute.cc'; else $(CYGPATH_W) '$(srcdir)/Showattribute.cc'; fi`
+
 cdo-Sinfo.o: Sinfo.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT cdo-Sinfo.o -MD -MP -MF $(DEPDIR)/cdo-Sinfo.Tpo -c -o cdo-Sinfo.o `test -f 'Sinfo.cc' || echo '$(srcdir)/'`Sinfo.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cdo-Sinfo.Tpo $(DEPDIR)/cdo-Sinfo.Po
diff --git a/src/MapReduce.cc b/src/MapReduce.cc
index 56aa261..f40132d 100644
--- a/src/MapReduce.cc
+++ b/src/MapReduce.cc
@@ -79,6 +79,7 @@ void *MapReduce(void *argument)
 
   cdoInitialize(argument);
 
+  // open stream before calling cdoDefineGrid!!!
   int streamID1 = pstreamOpenRead(cdoStreamName(0));
 
   /* check input grid type and size - this will be used for selecting relevant
diff --git a/src/Merge.cc b/src/Merge.cc
index 223848e..e0fb869 100644
--- a/src/Merge.cc
+++ b/src/Merge.cc
@@ -113,7 +113,7 @@ int vlistConstVars(int vlistID)
   int nvars = vlistNvars(vlistID);
 
   for ( int varID = 0; varID < nvars; ++varID )
-    if ( vlistInqVarTsteptype(vlistID, varID) != TSTEP_CONSTANT ) return 0;
+    if ( vlistInqVarTimetype(vlistID, varID) != TIME_CONSTANT ) return 0;
 
   return 1;
 }
@@ -199,7 +199,7 @@ void *Merge(void *argument)
 	    for ( int varID = 0; varID < nvars; ++varID )
 	      {
 		varID2 = vlistMergedVar(vlistID1, varID);
-		vlistDefVarTsteptype(vlistID2, varID2, TSTEP_CONSTANT);
+		vlistDefVarTimetype(vlistID2, varID2, TIME_CONSTANT);
 	      }
 	  }
       }
diff --git a/src/Mergetime.cc b/src/Mergetime.cc
index 5097e81..f987eed 100644
--- a/src/Mergetime.cc
+++ b/src/Mergetime.cc
@@ -174,7 +174,7 @@ void *Mergetime(void *argument)
 	      pstreamInqRecord(sf[fileID].streamID, &varID, &levelID);
 
               if ( tsID2 > 0 && sf[fileID].tsID == 0 )
-                if ( vlistInqVarTsteptype(sf[fileID].vlistID, varID) == TSTEP_CONSTANT )
+                if ( vlistInqVarTimetype(sf[fileID].vlistID, varID) == TIME_CONSTANT )
                   continue;
 
               pstreamDefRecord(streamID2, varID, levelID);
diff --git a/src/Mrotuv.cc b/src/Mrotuv.cc
index 3f6ab7c..bbb9f6a 100644
--- a/src/Mrotuv.cc
+++ b/src/Mrotuv.cc
@@ -268,14 +268,14 @@ void *Mrotuv(void *argument)
   p_to_uv_grid(nlon, nlat, grid1x, grid1y, gridux, griduy, gridvx, gridvy);
 
   int gridIDu = gridCreate(GRID_CURVILINEAR, nlon*nlat);
-  gridDefPrec(gridIDu, gridInqPrec(gridID1));
+  gridDefDatatype(gridIDu, gridInqDatatype(gridID1));
   gridDefXsize(gridIDu, nlon);
   gridDefYsize(gridIDu, nlat);
   gridDefXvals(gridIDu, gridux);
   gridDefYvals(gridIDu, griduy);
 
   int gridIDv = gridCreate(GRID_CURVILINEAR, nlon*nlat);
-  gridDefPrec(gridIDv, gridInqPrec(gridID1));
+  gridDefDatatype(gridIDv, gridInqDatatype(gridID1));
   gridDefXsize(gridIDv, nlon);
   gridDefYsize(gridIDv, nlat);
   gridDefXvals(gridIDv, gridvx);
diff --git a/src/Mrotuvb.cc b/src/Mrotuvb.cc
index 56e971e..8fdd986 100644
--- a/src/Mrotuvb.cc
+++ b/src/Mrotuvb.cc
@@ -349,7 +349,7 @@ void *Mrotuvb(void *argument)
   if ( grid2y ) Free(grid2y);
 
   int gridID3 = gridCreate(GRID_CURVILINEAR, gridsize);
-  gridDefPrec(gridID3, gridInqPrec(gridID1));
+  gridDefDatatype(gridID3, gridInqDatatype(gridID1));
   gridDefXsize(gridID3, nlon);
   gridDefYsize(gridID3, nlat);
   gridDefXvals(gridID3, grid3x);
diff --git a/src/Pressure.cc b/src/Pressure.cc
index 14ab63c..221e5a5 100644
--- a/src/Pressure.cc
+++ b/src/Pressure.cc
@@ -213,7 +213,7 @@ void *Pressure(void *argument)
   double *pdata = (double*) Malloc(gridsize*sizeof(double));
 
   int vlistID2 = vlistCreate();
-  varID = vlistDefVar(vlistID2, gridID, zaxisIDp, TSTEP_INSTANT);
+  varID = vlistDefVar(vlistID2, gridID, zaxisIDp, TIME_VARYING);
   vlistDefVarParam(vlistID2, varID, cdiEncodeParam(1, 255, 255));
   vlistDefVarName(vlistID2, varID, "pressure");
   vlistDefVarStdname(vlistID2, varID, "air_pressure");
diff --git a/src/Remap.cc b/src/Remap.cc
index 7bfdaf5..c0f622e 100644
--- a/src/Remap.cc
+++ b/src/Remap.cc
@@ -439,16 +439,16 @@ void get_remap_env(void)
 }
 
 static
-void set_halo_to_missval(int nx, int ny, double *array, double missval)
+void set_halo_to_missval(size_t nx, size_t ny, double *array, double missval)
 {
-  for ( int j = 0; j < ny+4; j++ ) array[j*(nx+4)+0]      = missval;
-  for ( int j = 0; j < ny+4; j++ ) array[j*(nx+4)+1]      = missval;
-  for ( int j = 0; j < ny+4; j++ ) array[j*(nx+4)+nx+2]   = missval;
-  for ( int j = 0; j < ny+4; j++ ) array[j*(nx+4)+nx+3]   = missval;
-  for ( int i = 0; i < nx+4; i++ ) array[     0*(nx+4)+i] = missval;
-  for ( int i = 0; i < nx+4; i++ ) array[     1*(nx+4)+i] = missval;
-  for ( int i = 0; i < nx+4; i++ ) array[(ny+2)*(nx+4)+i] = missval;
-  for ( int i = 0; i < nx+4; i++ ) array[(ny+3)*(nx+4)+i] = missval;
+  for ( size_t j = 0; j < ny+4; j++ ) array[j*(nx+4)+0]      = missval;
+  for ( size_t j = 0; j < ny+4; j++ ) array[j*(nx+4)+1]      = missval;
+  for ( size_t j = 0; j < ny+4; j++ ) array[j*(nx+4)+nx+2]   = missval;
+  for ( size_t j = 0; j < ny+4; j++ ) array[j*(nx+4)+nx+3]   = missval;
+  for ( size_t i = 0; i < nx+4; i++ ) array[     0*(nx+4)+i] = missval;
+  for ( size_t i = 0; i < nx+4; i++ ) array[     1*(nx+4)+i] = missval;
+  for ( size_t i = 0; i < nx+4; i++ ) array[(ny+2)*(nx+4)+i] = missval;
+  for ( size_t i = 0; i < nx+4; i++ ) array[(ny+3)*(nx+4)+i] = missval;
 }
 
 static
@@ -470,15 +470,15 @@ bool is_global_grid(int gridID)
 }
 
 static
-void scale_gridbox_area(long gridsize, const double *restrict array1, long gridsize2, double *restrict array2, const double *restrict grid2_area)
+void scale_gridbox_area(size_t gridsize, const double *restrict array1, size_t gridsize2, double *restrict array2, const double *restrict grid2_area)
 {
   double array1sum = 0;
-  for ( long i = 0; i < gridsize; i++ ) array1sum += array1[i];
+  for ( size_t i = 0; i < gridsize; i++ ) array1sum += array1[i];
 
   double array2sum = 0;
-  for ( long i = 0; i < gridsize2; i++ ) array2sum += grid2_area[i];
+  for ( size_t i = 0; i < gridsize2; i++ ) array2sum += grid2_area[i];
 
-  for ( long i = 0; i < gridsize2; i++ ) array2[i] = grid2_area[i]/array2sum*array1sum;
+  for ( size_t i = 0; i < gridsize2; i++ ) array2[i] = grid2_area[i]/array2sum*array1sum;
 
   static bool lgridboxinfo = true;
   if ( lgridboxinfo )
@@ -499,8 +499,10 @@ int set_remapgrids(int filetype, int vlistID, int ngrids, std::vector<bool>& rem
       int gridID = vlistGrid(vlistID, index);
       int gridtype = gridInqType(gridID);
       int projtype = (gridtype == GRID_PROJECTION) ? gridInqProjType(gridID) : -1;
+      bool lproj4param = (gridtype == GRID_PROJECTION) && grid_has_proj4param(gridID);
   
       if ( gridtype != GRID_LONLAT      &&
+           !lproj4param                 &&
            projtype != CDI_PROJ_RLL     &&
            projtype != CDI_PROJ_LAEA    &&
            projtype != CDI_PROJ_SINU    &&
@@ -513,9 +515,9 @@ int set_remapgrids(int filetype, int vlistID, int ngrids, std::vector<bool>& rem
 	  if ( gridtype == GRID_GAUSSIAN_REDUCED )
 	    {
 	      if ( !cdoRegulargrid && filetype == CDI_FILETYPE_GRB )
-		cdoAbort("Unsupported grid type: %s, use CDO option -R to convert reduced to regular grid!", gridNamePtr(gridtype));
+		cdoAbort("Unsupported grid type: %s, use CDO option -R to convert reduced to regular Gaussian grid!", gridNamePtr(gridtype));
 	      else
-		cdoAbort("Unsupported grid type: %s, use CDO operator -setgridtype,regular to convert reduced to regular grid!", gridNamePtr(gridtype));
+		cdoAbort("Unsupported grid type: %s, use CDO operator -setgridtype,regular to convert reduced to regular Gaussian grid!", gridNamePtr(gridtype));
 	    }
 	  else if ( gridtype == GRID_GENERIC && gridInqSize(gridID) <= 2 )
             {
@@ -523,13 +525,15 @@ int set_remapgrids(int filetype, int vlistID, int ngrids, std::vector<bool>& rem
             }
 	  else
             {
-              int nvars = vlistNvars(vlistID);
-              int varID;
-              for ( varID = 0; varID < nvars; ++varID )
-                if ( gridID == vlistInqVarGrid(vlistID, varID) ) break;
               char varname[CDI_MAX_NAME];
-              vlistInqVarName(vlistID, varID, varname);
-              cdoAbort("Variable %s has an unsupported %s grid!", varname, gridNamePtr(gridtype));
+              int nvars = vlistNvars(vlistID);
+              for ( int varID = 0; varID < nvars; ++varID )
+                if ( gridID == vlistInqVarGrid(vlistID, varID) )
+                  {
+                    vlistInqVarName(vlistID, varID, varname);
+                    break;
+                  }
+              cdoAbort("Unsupported %s coordinates (Variable: %s)!", gridNamePtr(gridtype), varname);
             }
 	}
     }
@@ -599,14 +603,14 @@ int get_norm_opt(void)
 }
 
 static
-void remap_normalize(int norm_opt, int gridsize, double *array, double missval, remapgrid_t *tgt_grid)
+void remap_normalize(int norm_opt, size_t gridsize, double *array, double missval, remapgrid_t *tgt_grid)
 {
   /* used only to check the result of remapcon */
   double grid_err;
 
   if ( norm_opt == NORM_OPT_NONE )
     {
-      for ( int i = 0; i < gridsize; i++ )
+      for ( size_t i = 0; i < gridsize; i++ )
 	{
 	  if ( !DBL_IS_EQUAL(array[i], missval) )
 	    {
@@ -621,7 +625,7 @@ void remap_normalize(int norm_opt, int gridsize, double *array, double missval,
     }
   else if ( norm_opt == NORM_OPT_DESTAREA )
     {
-      for ( int i = 0; i < gridsize; i++ )
+      for ( size_t i = 0; i < gridsize; i++ )
 	{
 	  if ( !DBL_IS_EQUAL(array[i], missval) )
 	    {
@@ -635,13 +639,13 @@ void remap_normalize(int norm_opt, int gridsize, double *array, double missval,
 }
 
 static
-void remap_set_frac_min(int gridsize, double *array, double missval, remapgrid_t *tgt_grid)
+void remap_set_frac_min(size_t gridsize, double *array, double missval, remapgrid_t *tgt_grid)
 {
   if ( remap_frac_min > 0 )
     {
-      for ( int i = 0; i < gridsize; i++ )
+      for ( size_t i = 0; i < gridsize; i++ )
 	{
-	  //printf("%d %g %g\n", i, remaps[r].tgt_grid.cell_frac[i], remaps[r].tgt_grid.cell_area[i]);
+	  //printf("%zu %g %g\n", i, remaps[r].tgt_grid.cell_frac[i], remaps[r].tgt_grid.cell_area[i]);
 	  if ( tgt_grid->cell_frac[i] < remap_frac_min ) array[i] = missval;
 	}
     }
@@ -668,79 +672,81 @@ void init_remap_timer(void)
 static
 void links_per_value(remapvars_t *remapvars)
 {
-  long num_links = remapvars->num_links;
-  int lpv = -1;
+  long lpv = -1;
 
   remapvars->links_per_value = lpv;
   return;
+  /*
+  size_t num_links = remapvars->num_links;
 
   if ( num_links > 0 )
     {
       lpv = 1;
-      const int *restrict dst_add = remapvars->tgt_cell_add;
-      long n = 0;
-      int ival = dst_add[n];
+      const size_t *restrict dst_add = remapvars->tgt_cell_add;
+      size_t n = 0;
+      size_t ival = dst_add[n];
       for ( n = 1; n < num_links; ++n )
         if ( dst_add[n] == ival ) lpv++;
         else break;
 
-    printf("lpv %d\n", lpv);
+    printf("lpv %zu\n", lpv);
 
-      if ( num_links%lpv != 0 ) lpv = -1;
+      if ( num_links%lpv != 0 ) lpv = 0;
 
       n++;
       if ( n < num_links )
         {
-          int lpv2 = -1;
-          int ival2 = dst_add[n];
+          size_t lpv2 = 0;
+          size_t ival2 = dst_add[n];
           for ( ; n < num_links; ++n )
             if ( dst_add[n] == ival2 ) lpv2++;
             else if ( lpv == lpv2 )
               {
-                lpv2 = -1;
+                lpv2 = 0;
                 ival2 = dst_add[n];
               }
             else
               {
-                lpv = -1;
+                lpv = 0;
                 break;
               }
         }
       
-  printf("lpv %d\n", lpv);
+  printf("lpv %zu\n", lpv);
 
       if ( lpv == 1 )
         {
-          for ( long n = 1; n < num_links; ++n )
+          for ( size_t n = 1; n < num_links; ++n )
             {
               if ( dst_add[n] == dst_add[n-1] )
                 {
-                  lpv = -1;
+                  lpv = 0;
                   break;
                 }
             }
         }
       else if ( lpv > 1 )
         {
-          for ( long n = 1; n < num_links/lpv; ++n )
+          for ( size_t n = 1; n < num_links/lpv; ++n )
             {
               ival = dst_add[n*lpv];
-              for ( int k = 1; k < lpv; ++k )
+              for ( size_t k = 1; k < lpv; ++k )
                 {
                   if ( dst_add[n*lpv+k] != ival )
                     {
-                      lpv = -1;
+                      lpv = 0;
                       break;
                     }
                 }
-              if ( lpv == -1 ) break;
+              if ( lpv == 0 ) break;
             }
         }
     }
 
-  printf("lpv %d\n", lpv);
+  printf("lpv %zu\n", lpv);
 
   remapvars->links_per_value = lpv;
+  */
 }
 
 static
@@ -772,9 +778,11 @@ void *Remap(void *argument)
   int streamID2 = -1;
   int nrecs;
   int varID, levelID;
-  int gridsize, gridsize2;
+  size_t gridsize, gridsize2;
   int gridID1 = -1, gridID2;
-  int nmiss1, nmiss2, i, j, r = -1;
+  int nmiss1, nmiss2;
+  size_t i, j;
+  int r = -1;
   int nremaps = 0;
   int norm_opt = NORM_OPT_NONE;
   int map_type = -1;
@@ -832,6 +840,7 @@ void *Remap(void *argument)
 	cdoPrint("Extrapolation disabled!");
     }
 
+  // open stream before calling cdoDefineGrid!!!
   int streamID1 = pstreamOpenRead(cdoStreamName(0));
 
   if ( lremapxxx )
@@ -897,12 +906,12 @@ void *Remap(void *argument)
 
   if ( lremapxxx )
     {
-      int gridsize2;
+      size_t gridsize2;
 
       read_remap_scrip(remap_file, gridID1, gridID2, &map_type, &submap_type, &num_neighbors,
 		       &remap_order, &remaps[0].src_grid, &remaps[0].tgt_grid, &remaps[0].vars);
 
-      if ( remaps[0].vars.links_per_value == -1 ) links_per_value(&remaps[0].vars);
+      if ( remaps[0].vars.links_per_value == 0 ) links_per_value(&remaps[0].vars);
             
       nremaps = 1;
       gridsize = remaps[0].src_grid.size;
@@ -936,13 +945,13 @@ void *Remap(void *argument)
 	  remaps[0].tgt_grid.vgpm = (int*) Realloc(remaps[0].tgt_grid.vgpm, gridInqSize(gridID2)*sizeof(int));
 	  int gridID2_gme = gridToUnstructured(gridID2, 1);
 	  gridInqMaskGME(gridID2_gme, remaps[0].tgt_grid.vgpm);
-	  int isize = 0;
-	  for ( int i = 0; i < gridsize2; ++i )
+	  size_t isize = 0;
+	  for ( size_t i = 0; i < gridsize2; ++i )
 	    if ( remaps[0].tgt_grid.vgpm[i] ) isize++;
 	  gridsize2 = isize;
 	}
       /*
-      printf("grid2 %d %d %d\n", gridsize2, remaps[0].tgt_grid.nvgp, remaps[0].tgt_grid.size);
+      printf("grid2 %zu %d %zu\n", gridsize2, remaps[0].tgt_grid.nvgp, remaps[0].tgt_grid.size);
       */
       if ( remaps[0].tgt_grid.size != gridsize2 )
 	cdoAbort("Size of target grid and weights from %s differ!", remap_file);
@@ -965,7 +974,7 @@ void *Remap(void *argument)
 
   if ( map_type == MAP_TYPE_CONSERV || map_type == MAP_TYPE_CONSERV_YAC ) norm_opt = get_norm_opt();
 
-  int grid1sizemax = vlistGridsizeMax(vlistID1);
+  size_t grid1sizemax = vlistGridsizeMax(vlistID1);
 
   if ( map_type == MAP_TYPE_BICUBIC ) need_gradiants = TRUE;
   if ( map_type == MAP_TYPE_CONSERV && remap_order == 2 )
@@ -1028,9 +1037,9 @@ void *Remap(void *argument)
 	  if ( gridIsCircular(gridID1) && !lextrapolate ) remap_extrapolate = true;
 	  if ( map_type == MAP_TYPE_DISTWGT && !remap_extrapolate && gridInqSize(gridID1) > 1 && !is_global_grid(gridID1) )
 	    {
-	      int nx = gridInqXsize(gridID1);
-	      int ny = gridInqYsize(gridID1);
-	      int gridsize_new = gridsize + 4*(nx+2) + 4*(ny+2);
+	      long nx = gridInqXsize(gridID1);
+	      long ny = gridInqYsize(gridID1);
+	      size_t gridsize_new = gridsize + 4*(nx+2) + 4*(ny+2);
 	      if ( gridsize_new > grid1sizemax )
 		{
 		  grid1sizemax = gridsize_new;
@@ -1045,8 +1054,8 @@ void *Remap(void *argument)
 		    }
 		}
 	      
-	      for ( j = ny-1; j >= 0; j-- )
-		for ( i = nx-1; i >= 0; i-- )
+	      for ( long j = ny-1; j >= 0; j-- )
+		for ( long i = nx-1; i >= 0; i-- )
 		  array1[(j+2)*(nx+4)+i+2] = array1[j*nx+i];
 
 	      set_halo_to_missval(nx, ny, array1, missval);
@@ -1235,13 +1244,13 @@ void *Remap(void *argument)
 	  if ( operfunc == REMAPSUM )
 	    {
 	      for ( i = 0; i < gridsize; i++ )
-		printf("1 %d %g %g %g %g\n", i, array1[i], remaps[r].src_grid.cell_frac[i], remaps[r].src_grid.cell_area[i],remaps[r].src_grid.cell_frac[i]);
+		printf("1 %zd %g %g %g %g\n", i, array1[i], remaps[r].src_grid.cell_frac[i], remaps[r].src_grid.cell_area[i],remaps[r].src_grid.cell_frac[i]);
 	      double array1sum = 0;
 	      for ( i = 0; i < gridsize; i++ )
 		array1sum += remaps[r].src_grid.cell_area[i];
 
 	      for ( i = 0; i < gridsize2; i++ )
-		printf("2 %d %g %g %g %g\n", i, array2[i], remaps[r].tgt_grid.cell_frac[i],remaps[r].tgt_grid.cell_area[i],remaps[r].tgt_grid.cell_frac[i]);
+		printf("2 %zd %g %g %g %g\n", i, array2[i], remaps[r].tgt_grid.cell_frac[i],remaps[r].tgt_grid.cell_area[i],remaps[r].tgt_grid.cell_frac[i]);
 	      double array2sum = 0;
 	      for ( i = 0; i < gridsize2; i++ )
 		array2sum += remaps[r].tgt_grid.cell_area[i];
@@ -1266,8 +1275,8 @@ void *Remap(void *argument)
  	      gridInqParamGME(gridID2, &nd, &ni, &ni2, &ni3);
 	      j = remaps[r].tgt_grid.size;
 
-	      for ( i = gridsize2-1; i >=0 ; i-- )
-		if ( remaps[r].tgt_grid.vgpm[i] ) array2[i] = array2[--j];
+	      for ( i = gridsize2; i > 0 ; i-- )
+		if ( remaps[r].tgt_grid.vgpm[i-1] ) array2[i-1] = array2[--j];
 
 	      gme_grid_restore(array2, ni, nd);
 	    }
diff --git a/src/Remapeta.cc b/src/Remapeta.cc
index fdaf5f8..83ce4d5 100644
--- a/src/Remapeta.cc
+++ b/src/Remapeta.cc
@@ -20,7 +20,6 @@
       Remapeta     remapeta          Model to model level interpolation
 */
 
-
 #include "hetaeta.h"
 #include <cdi.h>
 #include "cdo.h"
@@ -30,35 +29,36 @@
 #include "listarray.h"
 #include "stdnametable.h"
 
-
-static 
-void setmissval(long nvals, int *imiss, double missval, double *array)
+static void
+setmissval(long nvals, int *imiss, double missval, double *array)
 {
-  if ( imiss )
+  if (imiss)
     {
-      for ( long i = 0; i < nvals; ++i )
-	if ( imiss[i] ) array[i] = missval;
+      for (long i = 0; i < nvals; ++i)
+        if (imiss[i])
+          array[i] = missval;
     }
 }
 
-static
-void corr_hum(long gridsize, double *q, double q_min)
+static void
+corr_hum(long gridsize, double *q, double q_min)
 {
-  for ( long i = 0; i < gridsize; ++i )
+  for (long i = 0; i < gridsize; ++i)
     {
-      if ( q[i] < q_min ) q[i] = q_min;
+      if (q[i] < q_min)
+        q[i] = q_min;
     }
 }
- 
-static
-long ncctop(double cptop, long nlev, long nlevp1, double *vct_a, double *vct_b)
+
+static long
+ncctop(double cptop, long nlev, long nlevp1, double *vct_a, double *vct_b)
 {
   /*
     Description:
     Defines highest level *ncctop* where condensation is allowed.
-    
+
     Author:
-  
+
     E. Roeckner, MPI, October 2001
   */
   /* local variables */
@@ -69,105 +69,117 @@ long ncctop(double cptop, long nlev, long nlevp1, double *vct_a, double *vct_b)
 
   /* half level pressure values, assuming 101320. Pa surface pressure */
 
-  for ( long jk = 0; jk < nlevp1; ++jk )
+  for (long jk = 0; jk < nlevp1; ++jk)
     {
       za = vct_a[jk];
       zb = vct_b[jk];
-      zph[jk] = za + zb*101320.;
+      zph[jk] = za + zb * 101320.;
     }
 
   /* full level pressure */
 
-  for ( long jk = 0; jk < nlev; ++jk )
-    zp[jk] = (zph[jk] + zph[jk+1])*0.5;
+  for (long jk = 0; jk < nlev; ++jk)
+    zp[jk] = (zph[jk] + zph[jk + 1]) * 0.5;
 
   /* search for pressure level cptop (Pa) */
 
-  for ( long jk = 0; jk < nlev; ++jk )
+  for (long jk = 0; jk < nlev; ++jk)
     {
       nctop = jk;
-      if ( zp[jk] >= cptop ) break;
+      if (zp[jk] >= cptop)
+        break;
     }
 
   return nctop;
 }
 
-
-double *vctFromFile(const char *filename, int *nvct)
+double *
+vctFromFile(const char *filename, int *nvct)
 {
   char line[1024], *pline;
   int num, i = 0;
   int maxvct = 8192;
 
   FILE *fp = fopen(filename, "r");
-  if ( fp == NULL ) { perror(filename); exit(EXIT_FAILURE); }
+  if (fp == NULL)
+    {
+      perror(filename);
+      exit(EXIT_FAILURE);
+    }
 
-  double *vct2 = (double*) Malloc(maxvct*sizeof(double));
+  double *vct2 = (double *) Malloc(maxvct * sizeof(double));
 
-  while ( readline(fp, line, 1024) )
+  while (readline(fp, line, 1024))
     {
-      if ( line[0] == '#' || line[0] == '\0' ) continue;
+      if (line[0] == '#' || line[0] == '\0')
+        continue;
 
       pline = line;
       num = (int) strtod(pline, &pline);
-      if ( pline == NULL ) cdoAbort("Format error in VCT file %s!", filename);
-      if ( num != i ) cdoWarning("Inconsistent VCT file, entry %d is %d.", i, num);
-      
-      if ( i+maxvct/2 >= maxvct-1 ) cdoAbort("Too many values in VCT file!");
+      if (pline == NULL)
+        cdoAbort("Format error in VCT file %s!", filename);
+      if (num != i)
+        cdoWarning("Inconsistent VCT file, entry %d is %d.", i, num);
+
+      if (i + maxvct / 2 >= maxvct - 1)
+        cdoAbort("Too many values in VCT file!");
 
       vct2[i] = strtod(pline, &pline);
-      if ( pline == NULL ) cdoAbort("Format error in VCT file %s!", filename);
+      if (pline == NULL)
+        cdoAbort("Format error in VCT file %s!", filename);
 
-      vct2[i+maxvct/2] = strtod(pline, &pline);
+      vct2[i + maxvct / 2] = strtod(pline, &pline);
 
       i++;
     }
 
   fclose(fp);
 
-  int nvct2 = 2*i;
+  int nvct2 = 2 * i;
   int nlevh2 = i - 1;
 
-  for ( i = 0; i < nlevh2+1; ++i )
-    vct2[i+nvct2/2] = vct2[i+maxvct/2];
-  
-  vct2 = (double*) Realloc(vct2, nvct2*sizeof(double));
+  for (i = 0; i < nlevh2 + 1; ++i)
+    vct2[i + nvct2 / 2] = vct2[i + maxvct / 2];
+
+  vct2 = (double *) Realloc(vct2, nvct2 * sizeof(double));
 
   *nvct = nvct2;
 
   return vct2;
 }
 
-static
-void vert_sum(double *sum, double *var3d, long gridsize, long nlevel)
+static void
+vert_sum(double *sum, double *var3d, long gridsize, long nlevel)
 {
   long i, k;
 
-  for ( i = 0; i < gridsize; ++i ) sum[i] = 0;
+  for (i = 0; i < gridsize; ++i)
+    sum[i] = 0;
 
-  for ( k = 0; k < nlevel; ++k )
-    for ( i = 0; i < gridsize; ++i )
+  for (k = 0; k < nlevel; ++k)
+    for (i = 0; i < gridsize; ++i)
       {
-	sum[i] += var3d[k*gridsize + i];
+        sum[i] += var3d[k * gridsize + i];
       }
 }
 
-static
-void vert_sumw(double *sum, double *var3d, long gridsize, long nlevel, double *deltap)
+static void
+vert_sumw(double *sum, double *var3d, long gridsize, long nlevel, double *deltap)
 {
   long i, k;
 
-  for ( i = 0; i < gridsize; ++i ) sum[i] = 0;
+  for (i = 0; i < gridsize; ++i)
+    sum[i] = 0;
 
-  for ( k = 0; k < nlevel; ++k )
-    for ( i = 0; i < gridsize; ++i )
+  for (k = 0; k < nlevel; ++k)
+    for (i = 0; i < gridsize; ++i)
       {
-	sum[i] += var3d[k*gridsize + i]*deltap[k*gridsize + i];
+        sum[i] += var3d[k * gridsize + i] * deltap[k * gridsize + i];
       }
 }
 
-
-double *vlist_hybrid_vct(int vlistID, int *rzaxisIDh, int *rnvct, int *rnhlevf)
+double *
+vlist_hybrid_vct(int vlistID, int *rzaxisIDh, int *rnvct, int *rnhlevf)
 {
   int zaxisIDh = -1;
   int nhlevf = 0;
@@ -176,47 +188,48 @@ double *vlist_hybrid_vct(int vlistID, int *rzaxisIDh, int *rnvct, int *rnhlevf)
 
   bool lhavevct = false;
   int nzaxis = vlistNzaxis(vlistID);
-  for ( int i = 0; i < nzaxis; i++ )
+  for (int i = 0; i < nzaxis; i++)
     {
       int zaxisID = vlistZaxis(vlistID, i);
-      int nlevel  = zaxisInqSize(zaxisID);
+      int nlevel = zaxisInqSize(zaxisID);
 
-      if ( zaxisInqType(zaxisID) == ZAXIS_HYBRID && nlevel > 1 )
-	{
+      if (zaxisInqType(zaxisID) == ZAXIS_HYBRID && nlevel > 1)
+        {
           nvct = zaxisInqVctSize(zaxisID);
 
-          if ( nlevel == (nvct/2 - 1) )
+          if (nlevel == (nvct / 2 - 1))
             {
-	      if ( lhavevct == false )
-		{
-		  lhavevct = true;
+              if (lhavevct == false)
+                {
+                  lhavevct = true;
                   zaxisIDh = zaxisID;
-                  nhlevf  = nlevel;
- 
-                  vct = (double*) Malloc(nvct*sizeof(double));
+                  nhlevf = nlevel;
+
+                  vct = (double *) Malloc(nvct * sizeof(double));
                   zaxisInqVct(zaxisID, vct);
                 }
             }
-          else 
+          else
             {
-              if ( cdoVerbose )
+              if (cdoVerbose)
                 cdoPrint("nlevel = (nvct1/2 - 1): nlevel = %d", nlevel);
-              if ( nlevel < (nvct/2 - 1) )
-                cdoPrint("z-axis %d has only %d of %d hybrid sigma pressure levels!", i+1, nlevel, (nvct/2 - 1));
+              if (nlevel < (nvct / 2 - 1))
+                cdoPrint("z-axis %d has only %d of %d hybrid sigma pressure levels!", i + 1, nlevel, (nvct / 2 - 1));
             }
-	}
+        }
     }
 
   *rzaxisIDh = zaxisIDh;
-  *rnvct   = nvct;
+  *rnvct = nvct;
   *rnhlevf = nhlevf;
-  
+
   return vct;
 }
 
-#define  MAX_VARS3D  1024
+#define MAX_VARS3D 1024
 
-void *Remapeta(void *argument)
+void *
+Remapeta(void *argument)
 {
   int nfis2gp = 0;
   int nrecs;
@@ -244,9 +257,10 @@ void *Remapeta(void *argument)
   double minval, maxval;
   double missval = 0;
   double cconst = 1.E-6;
-  double cptop  = 0; /* min. pressure level for cond. */
+  double cptop = 0; /* min. pressure level for cond. */
 
-  if ( cdoTimer ) timer_hetaeta = timer_new("Remapeta_hetaeta");
+  if (cdoTimer)
+    timer_hetaeta = timer_new("Remapeta_hetaeta");
 
   cdoInitialize(argument);
 
@@ -261,31 +275,31 @@ void *Remapeta(void *argument)
   operatorInputArg(cdoOperatorEnter(operatorID));
 
   char *envstr = getenv("REMAPETA_PTOP");
-  if ( envstr )
+  if (envstr)
     {
       double fval = atof(envstr);
-      if ( fval > 0 )
-	{
-	  cptop = fval;
-	  //	  if ( cdoVerbose )
-	  cdoPrint("Set REMAPETA_PTOP to %g", cptop);
-	}
-    }  
+      if (fval > 0)
+        {
+          cptop = fval;
+          //	  if ( cdoVerbose )
+          cdoPrint("Set REMAPETA_PTOP to %g", cptop);
+        }
+    }
 
   int nvct2 = 0;
   double *vct2 = vctFromFile(operatorArgv()[0], &nvct2);
-  int nhlevf2 = nvct2/2 - 1;
+  int nhlevf2 = nvct2 / 2 - 1;
 
   double *a2 = vct2;
-  double *b2 = vct2 + nvct2/2;
+  double *b2 = vct2 + nvct2 / 2;
 
-  if ( cdoVerbose )
-    for ( i = 0; i < nhlevf2+1; ++i )
-      cdoPrint("vct2: %5d %25.17f %25.17f", i, vct2[i], vct2[nvct2/2+i]);
+  if (cdoVerbose)
+    for (i = 0; i < nhlevf2 + 1; ++i)
+      cdoPrint("vct2: %5d %25.17f %25.17f", i, vct2[i], vct2[nvct2 / 2 + i]);
 
   int streamID1 = pstreamOpenRead(cdoStreamName(0));
 
-  if ( operatorArgc() == 2 )
+  if (operatorArgc() == 2)
     {
       lfis2 = true;
 
@@ -297,37 +311,37 @@ void *Remapeta(void *argument)
       int vlistID1 = pstreamInqVlist(streamID);
 
       pstreamInqRecord(streamID, &varID, &levelID);
-      int gridID  = vlistInqVarGrid(vlistID1, varID);
+      int gridID = vlistInqVarGrid(vlistID1, varID);
       nfis2gp = gridInqSize(gridID);
 
-      fis2 = (double*) Malloc(nfis2gp*sizeof(double));
+      fis2 = (double *) Malloc(nfis2gp * sizeof(double));
 
       pstreamReadRecord(streamID, fis2, &nmiss);
 
-      if ( nmiss )
-	{
-	  missval = vlistInqVarMissval(vlistID1, varID);
-	  imiss = (int*) Malloc(nfis2gp*sizeof(int));
-	  for ( i = 0; i < nfis2gp; ++i )
-	    {
-	      if ( DBL_IS_EQUAL(fis2[i], missval) )
-		imiss[i] = 1;
-	      else 
-		imiss[i] = 0;
-	    }
-
-	  nmissout = nmiss;
-	}
+      if (nmiss)
+        {
+          missval = vlistInqVarMissval(vlistID1, varID);
+          imiss = (int *) Malloc(nfis2gp * sizeof(int));
+          for (i = 0; i < nfis2gp; ++i)
+            {
+              if (DBL_IS_EQUAL(fis2[i], missval))
+                imiss[i] = 1;
+              else
+                imiss[i] = 0;
+            }
+
+          nmissout = nmiss;
+        }
 
       /* check range of surface_geopotential */
       minmaxval(nfis2gp, fis2, imiss, &minval, &maxval);
-      if ( minval < MIN_FIS || maxval > MAX_FIS )
-	cdoWarning("%s out of range (min=%g max=%g)!", var_stdname(surface_geopotential), minval, maxval);
+      if (minval < MIN_FIS || maxval > MAX_FIS)
+        cdoWarning("%s out of range (min=%g max=%g)!", var_stdname(surface_geopotential), minval, maxval);
 
-      if ( minval < -1.e10 || maxval > 1.e10 )
-	cdoAbort("%s out of range!", var_stdname(surface_geopotential));
+      if (minval < -1.e10 || maxval > 1.e10)
+        cdoAbort("%s out of range!", var_stdname(surface_geopotential));
 
-      pstreamClose(streamID); 
+      pstreamClose(streamID);
     }
 
   int vlistID1 = pstreamInqVlist(streamID1);
@@ -338,18 +352,20 @@ void *Remapeta(void *argument)
   vlistDefTaxis(vlistID2, taxisID2);
 
   int gridID = vlistGrid(vlistID1, 0);
-  if ( gridInqType(gridID) == GRID_SPECTRAL )
+  if (gridInqType(gridID) == GRID_SPECTRAL)
     cdoAbort("Spectral data unsupported!");
 
   int gridsize = vlist_check_gridsize(vlistID1);
 
   int zaxisID2 = zaxisCreate(ZAXIS_HYBRID, nhlevf2);
-  double *lev2 = (double*) Malloc(nhlevf2*sizeof(double));
-  for ( i = 0; i < nhlevf2; ++i ) lev2[i] = i+1;
+  double *lev2 = (double *) Malloc(nhlevf2 * sizeof(double));
+  for (i = 0; i < nhlevf2; ++i)
+    lev2[i] = i + 1;
   zaxisDefLevels(zaxisID2, lev2);
   Free(lev2);
 
-  if ( nvct2 == 0 ) cdoAbort("Internal problem, vct2 undefined!");
+  if (nvct2 == 0)
+    cdoAbort("Internal problem, vct2 undefined!");
   zaxisDefVct(zaxisID2, nvct2, vct2);
 
   int surfaceID = zaxisFromName("surface");
@@ -362,101 +378,118 @@ void *Remapeta(void *argument)
   vlist_change_hybrid_zaxis(vlistID1, vlistID2, zaxisIDh, zaxisID2);
 
   int nzaxis = vlistNzaxis(vlistID1);
-  for ( int i = 0; i < nzaxis; i++ )
+  for (int i = 0; i < nzaxis; i++)
     {
       int zaxisID = vlistZaxis(vlistID1, i);
-      int nlevel  = zaxisInqSize(zaxisID);
-      if ( zaxisInqType(zaxisID) == ZAXIS_HYBRID && nlevel == 1 )
+      int nlevel = zaxisInqSize(zaxisID);
+      if (zaxisInqType(zaxisID) == ZAXIS_HYBRID && nlevel == 1)
         vlistChangeZaxisIndex(vlistID2, i, surfaceID);
     }
-  
+
   double *a1 = vct1;
-  double *b1 = vct1 + nvct1/2;
-  if ( cdoVerbose )
-    for ( i = 0; i < nvct1/2; ++i )
-      cdoPrint("vct1: %5d %25.17f %25.17f", i, vct1[i], vct1[nvct1/2+i]);
+  double *b1 = vct1 + nvct1 / 2;
+  if (cdoVerbose)
+    for (i = 0; i < nvct1 / 2; ++i)
+      cdoPrint("vct1: %5d %25.17f %25.17f", i, vct1[i], vct1[nvct1 / 2 + i]);
 
-  
   int streamID2 = pstreamOpenWrite(cdoStreamName(1), cdoFiletype());
   pstreamDefVlist(streamID2, vlistID2);
 
-
-  if ( zaxisIDh == -1 )
+  if (zaxisIDh == -1)
     cdoWarning("No 3D variable with hybrid sigma pressure coordinate found!");
 
   int nvars = vlistNvars(vlistID1);
 
-  for ( varID = 0; varID < nvars; varID++ )
+  for (varID = 0; varID < nvars; varID++)
     {
-      int gridID  = vlistInqVarGrid(vlistID1, varID);
+      int gridID = vlistInqVarGrid(vlistID1, varID);
       int zaxisID = vlistInqVarZaxis(vlistID1, varID);
-      int nlevel  = zaxisInqSize(zaxisID);
+      int nlevel = zaxisInqSize(zaxisID);
 
       int code = vlistInqVarCode(vlistID1, varID);
       /* code = -1; */
-      if ( code <= 0 || code == 255 )
-	{
-	  vlistInqVarName(vlistID1, varID, varname);
-	  strtolower(varname);
-
-	  vlistInqVarStdname(vlistID1, varID, stdname);
-	  strtolower(stdname);
-
-	  code = echamcode_from_stdname(stdname);
-
-	  if ( code == -1 )
-	    {
-	      /*                                  ECHAM                            ECMWF       */
-	      if      ( sgeopotID == -1 && (strcmp(varname, "geosp") == 0 || strcmp(varname, "z")    == 0) ) code = 129;
-	      else if ( tempID    == -1 && (strcmp(varname, "st")    == 0 || strcmp(varname, "t")    == 0) ) code = 130;
-	      else if ( psID      == -1 && (strcmp(varname, "aps")   == 0 || strcmp(varname, "ps"  ) == 0) ) code = 134;
-	      else if ( lnpsID    == -1 && (strcmp(varname, "lsp")   == 0 || strcmp(varname, "lnsp") == 0) ) code = 152;
-	      else if ( sqID      == -1 && (strcmp(varname, "q")     == 0 ) ) code = 133;
-	    }
-	}
-
-      if      ( code == 129 && nlevel == 1       ) sgeopotID = varID;
-      else if ( code == 130 && nlevel == nhlevf1 ) tempID    = varID;
-      else if ( code == 133 && nlevel == nhlevf1 ) sqID      = varID;
-      else if ( code == 134 && nlevel == 1       ) psID      = varID;
-      else if ( code == 152 && nlevel == 1       ) lnpsID    = 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!");
-
-      if ( zaxisInqType(zaxisID) == ZAXIS_HYBRID && zaxisIDh != -1 && nlevel == nhlevf1 )
-	{
-	  if ( ! (code == 130 || code == 133) )
-	    varids[nvars3D++] = varID;
-	}
+      if (code <= 0 || code == 255)
+        {
+          vlistInqVarName(vlistID1, varID, varname);
+          strtolower(varname);
+
+          vlistInqVarStdname(vlistID1, varID, stdname);
+          strtolower(stdname);
+
+          code = echamcode_from_stdname(stdname);
+
+          if (code == -1)
+            {
+              /*                                  ECHAM                            ECMWF       */
+              if (sgeopotID == -1 && (strcmp(varname, "geosp") == 0 || strcmp(varname, "z") == 0))
+                code = 129;
+              else if (tempID == -1 && (strcmp(varname, "st") == 0 || strcmp(varname, "t") == 0))
+                code = 130;
+              else if (psID == -1 && (strcmp(varname, "aps") == 0 || strcmp(varname, "ps") == 0))
+                code = 134;
+              else if (lnpsID == -1 && (strcmp(varname, "lsp") == 0 || strcmp(varname, "lnsp") == 0))
+                code = 152;
+              else if (sqID == -1 && (strcmp(varname, "q") == 0))
+                code = 133;
+            }
+        }
+
+      if (code == 129 && nlevel == 1)
+        sgeopotID = varID;
+      else if (code == 130 && nlevel == nhlevf1)
+        tempID = varID;
+      else if (code == 133 && nlevel == nhlevf1)
+        sqID = varID;
+      else if (code == 134 && nlevel == 1)
+        psID = varID;
+      else if (code == 152 && nlevel == 1)
+        lnpsID = 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!");
+
+      if (zaxisInqType(zaxisID) == ZAXIS_HYBRID && zaxisIDh != -1 && nlevel == nhlevf1)
+        {
+          if (!(code == 130 || code == 133))
+            varids[nvars3D++] = varID;
+        }
       else
-	{
-	  if ( code == 130 ) tempID = -1;
-	  if ( code == 133 ) sqID   = -1;
-	}
+        {
+          if (code == 130)
+            tempID = -1;
+          if (code == 133)
+            sqID = -1;
+        }
     }
 
-  if ( cdoVerbose )
+  if (cdoVerbose)
     {
       cdoPrint("Found:");
-      if ( tempID    != -1 ) cdoPrint("  %s", var_stdname(air_temperature));
-      if ( psID      != -1 ) cdoPrint("  %s", var_stdname(surface_air_pressure));
-      if ( lnpsID    != -1 ) cdoPrint("  LOG(%s)", var_stdname(surface_air_pressure));
-      if ( sgeopotID != -1 ) cdoPrint("  %s", var_stdname(surface_geopotential));
-      if ( sqID      != -1 ) cdoPrint("  %s", var_stdname(specific_humidity));
+      if (tempID != -1)
+        cdoPrint("  %s", var_stdname(air_temperature));
+      if (psID != -1)
+        cdoPrint("  %s", var_stdname(surface_air_pressure));
+      if (lnpsID != -1)
+        cdoPrint("  LOG(%s)", var_stdname(surface_air_pressure));
+      if (sgeopotID != -1)
+        cdoPrint("  %s", var_stdname(surface_geopotential));
+      if (sqID != -1)
+        cdoPrint("  %s", var_stdname(specific_humidity));
     }
 
-  if ( tempID != -1 && sqID != -1 )
+  if (tempID != -1 && sqID != -1)
     {
       ltq = true;
     }
   else
     {
-      if ( tempID != -1 ) cdoAbort("Temperature without humidity unsupported!");
-      if ( sqID   != -1 ) cdoAbort("Humidity without temperature unsupported!");
+      if (tempID != -1)
+        cdoAbort("Temperature without humidity unsupported!");
+      if (sqID != -1)
+        cdoAbort("Humidity without temperature unsupported!");
     }
   /*
   if ( ltq == false )
@@ -464,319 +497,343 @@ void *Remapeta(void *argument)
       cdoWarning("Temperature and Humidity not found!");
     }
   */
-  if ( operatorID == REMAPETA ) {}
+  if (operatorID == REMAPETA)
+    {
+    }
 
-  if ( operatorID == REMAPETAS || operatorID == REMAPETAZ )
+  if (operatorID == REMAPETAS || operatorID == REMAPETAZ)
     {
-      sum1 = (double*) Malloc(gridsize*sizeof(double));
-      sum2 = (double*) Malloc(gridsize*sizeof(double));
+      sum1 = (double *) Malloc(gridsize * sizeof(double));
+      sum2 = (double *) Malloc(gridsize * sizeof(double));
     }
 
-  if ( operatorID == REMAPETAZ )
+  if (operatorID == REMAPETAZ)
     {
-      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));
+      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));
     }
 
-  double *array = (double*) Malloc(gridsize*sizeof(double));
+  double *array = (double *) Malloc(gridsize * sizeof(double));
 
-  double *fis1  = (double*) Malloc(gridsize*sizeof(double));
-  double *ps1   = (double*) Malloc(gridsize*sizeof(double));
+  double *fis1 = (double *) Malloc(gridsize * sizeof(double));
+  double *ps1 = (double *) Malloc(gridsize * sizeof(double));
 
-  if ( lfis2 == false ) fis2 = (double*) Malloc(gridsize*sizeof(double));
-  if ( lfis2 == true && gridsize != 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!");
 
-  double *ps2   = (double*) Malloc(gridsize*sizeof(double));
+  double *ps2 = (double *) Malloc(gridsize * sizeof(double));
 
-  if ( ltq )
+  if (ltq)
     {
-      tscor = (double*) Malloc(gridsize*sizeof(double));
-      pscor = (double*) Malloc(gridsize*sizeof(double));
-      secor = (double*) Malloc(gridsize*sizeof(double));
+      tscor = (double *) Malloc(gridsize * sizeof(double));
+      pscor = (double *) Malloc(gridsize * sizeof(double));
+      secor = (double *) Malloc(gridsize * sizeof(double));
 
-      t1    = (double*) Malloc(gridsize*nhlevf1*sizeof(double));
-      q1    = (double*) Malloc(gridsize*nhlevf1*sizeof(double));
+      t1 = (double *) Malloc(gridsize * nhlevf1 * sizeof(double));
+      q1 = (double *) Malloc(gridsize * nhlevf1 * sizeof(double));
 
-      t2    = (double*) Malloc(gridsize*nhlevf2*sizeof(double));
-      q2    = (double*) Malloc(gridsize*nhlevf2*sizeof(double));
+      t2 = (double *) Malloc(gridsize * nhlevf2 * sizeof(double));
+      q2 = (double *) Malloc(gridsize * nhlevf2 * sizeof(double));
     }
 
-  if ( nvars3D )
+  if (nvars3D)
     {
-      vars1  = (double**) Malloc(nvars*sizeof(double*));
-      vars2  = (double**) Malloc(nvars*sizeof(double*));
-
-      for ( varID = 0; varID < nvars3D; ++varID )
-	{
-	  vars1[varID] = (double*) Malloc(gridsize*nhlevf1*sizeof(double));
-	  vars2[varID] = (double*) Malloc(gridsize*nhlevf2*sizeof(double));
-	}
+      vars1 = (double **) Malloc(nvars * sizeof(double *));
+      vars2 = (double **) Malloc(nvars * sizeof(double *));
+
+      for (varID = 0; varID < nvars3D; ++varID)
+        {
+          vars1[varID] = (double *) Malloc(gridsize * nhlevf1 * sizeof(double));
+          vars2[varID] = (double *) Malloc(gridsize * nhlevf2 * sizeof(double));
+        }
     }
 
-  if ( zaxisIDh != -1 && sgeopotID == -1 )
+  if (zaxisIDh != -1 && sgeopotID == -1)
     {
-      if ( ltq )
-	cdoWarning("%s not found - set to zero!", var_stdname(surface_geopotential));
+      if (ltq)
+        cdoWarning("%s not found - set to zero!", var_stdname(surface_geopotential));
 
-      memset(fis1, 0, gridsize*sizeof(double));
+      memset(fis1, 0, gridsize * sizeof(double));
     }
 
   int presID = lnpsID;
-  if ( zaxisIDh != -1 && lnpsID == -1 )
+  if (zaxisIDh != -1 && lnpsID == -1)
     {
-      if ( psID == -1 )
-	cdoAbort("%s not found!", var_stdname(surface_air_pressure));
+      if (psID == -1)
+        cdoAbort("%s not found!", var_stdname(surface_air_pressure));
       else
-	presID = psID;
+        presID = psID;
     }
 
-  if ( cdoVerbose )
+  if (cdoVerbose)
     {
-      if ( presID == lnpsID )
-	cdoPrint("using LOG(%s)", var_stdname(surface_air_pressure));      
+      if (presID == lnpsID)
+        cdoPrint("using LOG(%s)", var_stdname(surface_air_pressure));
       else
-	cdoPrint("using %s", var_stdname(surface_air_pressure));
+        cdoPrint("using %s", var_stdname(surface_air_pressure));
     }
 
-  if ( cdoVerbose ) cdoPrint("nvars3D = %d   ltq = %d", nvars3D, (int)ltq);
+  if (cdoVerbose)
+    cdoPrint("nvars3D = %d   ltq = %d", nvars3D, (int) ltq);
 
   int tsID = 0;
-  while ( (nrecs = pstreamInqTimestep(streamID1, tsID)) )
+  while ((nrecs = pstreamInqTimestep(streamID1, tsID)))
     {
       taxisCopyTimestep(taxisID2, taxisID1);
       pstreamDefTimestep(streamID2, tsID);
 
-      for ( int recID = 0; recID < nrecs; recID++ )
-	{
-	  pstreamInqRecord(streamID1, &varID, &levelID);
-	  int zaxisID = vlistInqVarZaxis(vlistID1, varID);
-	  int nlevel  = zaxisInqSize(zaxisID);
-	  int offset = gridsize*levelID;
-	  pstreamReadRecord(streamID1, array, &nmiss);
-
-	  if ( zaxisIDh != -1 )
-	    {
-	      if ( varID == sgeopotID )
-		memcpy(fis1, array, gridsize*sizeof(double));
-	      else if ( varID == presID )
-		{
-		  if ( lnpsID != -1 )
-		    for ( i = 0; i < gridsize; ++i ) ps1[i] = exp(array[i]);
-		  else if ( psID != -1 )
-		    memcpy(ps1, array, gridsize*sizeof(double));
-		}
-	      else if ( ltq && varID == tempID )
-		memcpy(t1+offset, array, gridsize*sizeof(double));
-	      else if ( ltq && varID == sqID )
-		memcpy(q1+offset, array, gridsize*sizeof(double));
-	      /* else if ( zaxisID == zaxisIDh ) */
-	      else if ( zaxisInqType(zaxisID) == ZAXIS_HYBRID && nlevel == nhlevf1 )
-		{
-		  for ( i = 0; i < nvars3D; ++i )
-		    if ( varID == varids[i] ) break;
-
-		  if ( i == nvars3D ) cdoAbort("Internal error, 3D variable not found!");
-
-		  memcpy(vars1[i]+offset, array, gridsize*sizeof(double));
-		}
-	      else
-		{
-		  pstreamDefRecord(streamID2, varID, levelID);
-		  pstreamWriteRecord(streamID2, array, nmiss);
-		}
-	    }
-	  else
-	    {
-	      pstreamDefRecord(streamID2, varID, levelID);
-	      pstreamWriteRecord(streamID2, array, nmiss);
-	    }
-	}
-
-      if ( zaxisIDh != -1 )
-	{
-	  /* check range of ps_prog */
-	  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(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 ( int i = 0; i < gridsize; i++ ) fis2[i] = fis1[i];
-
-      if ( ltq )
-	{
-	  varID = tempID;
-	  int nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-	  for ( levelID = 0; levelID < nlevel; levelID++ )
-	    {
-	      int offset = gridsize*levelID;
-	      single2  = t1 + offset;
-
-	      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);
-	    }
-
-	  varID = sqID;
-	  nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-	  for ( levelID = 0; levelID < nlevel; levelID++ )
-	    {
-	      int offset = gridsize*levelID;
-	      single2  = q1 + offset;
-
-	      corr_hum(gridsize, single2, MIN_Q);
-
-	      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);
-	    }
-	}
-
-      if ( nvars3D || ltq )
-	{
-	  if ( cdoTimer ) timer_start(timer_hetaeta);
-	  hetaeta(ltq, gridsize, imiss,
-		  nhlevf1, a1, b1,
-		  fis1, ps1,
-		  t1, q1,
-		  nhlevf2, a2, b2,
-		  fis2, ps2,
-		  t2, q2,
-		  nvars3D, vars1, vars2,
-		  tscor, pscor, secor);
-	  if ( cdoTimer ) timer_stop(timer_hetaeta);
-	}
-
-      if ( cptop > 0 )
-	nctop = ncctop(cptop, (long) nhlevf2, (long) nhlevf2+1, a2, b2);
-
-      if ( zaxisIDh != -1 && sgeopotID != -1 )
-	{
-	  varID   = sgeopotID;
-	  levelID = 0;
-	  setmissval(gridsize, imiss, missval, fis2);
-	  pstreamDefRecord(streamID2, varID, levelID);
-	  pstreamWriteRecord(streamID2, fis2, nmissout);
-	}
-
-      if ( zaxisIDh != -1 && lnpsID != -1 )
-	for ( i = 0; i < gridsize; ++i ) ps2[i] = log(ps2[i]);
-
-      if ( zaxisIDh != -1 && presID != -1 )
-	{
-	  varID   = presID;
-	  levelID = 0;
-	  setmissval(gridsize, imiss, missval, ps2);
-	  pstreamDefRecord(streamID2, varID, levelID);
-	  pstreamWriteRecord(streamID2, ps2, nmissout);
-	}
-
-      if ( ltq )
-	{
-	  varID = tempID;
-	  int nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
-	  for ( levelID = 0; levelID < nlevel; levelID++ )
-	    {
-	      int offset = gridsize*levelID;
-	      single2  = t2 + offset;
-
-	      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);
-
-	      setmissval(gridsize, imiss, missval, single2);
-	      pstreamDefRecord(streamID2, varID, levelID);
-	      pstreamWriteRecord(streamID2, single2, nmissout);
-	    }
-
-	  varID = sqID;
-	  nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
-	  for ( levelID = 0; levelID < nlevel; levelID++ )
-	    {
-	      int offset = gridsize*levelID;
-	      single2  = q2 + offset;
-
-	      corr_hum(gridsize, single2, MIN_Q);
-
-	      if ( levelID < nctop )
-		for ( i = 0; i < gridsize; ++i ) single2[i] = cconst;
-
-	      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);
-
-	      setmissval(gridsize, imiss, missval, single2);
-	      pstreamDefRecord(streamID2, varID, levelID);
-	      pstreamWriteRecord(streamID2, single2, nmissout);
-	    }
-	}
-
-      for ( iv = 0; iv < nvars3D; ++iv )
-	{
-	  varID = varids[iv];
-
-	  int nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
-
-	  if ( operatorID == REMAPETAS )
-	    {
-	      vert_sum(sum1, vars1[iv], gridsize, nhlevf1);
-	      vert_sum(sum2, vars2[iv], gridsize, nhlevf2);
-	    }
-	  else if ( operatorID == REMAPETAZ )
-	    {
-	      int k;
-
-	      presh(NULL, half_press1, vct1, ps1, nhlevf1, gridsize);
-	      for ( k = 0; k < nhlevf1; ++k )
-		for ( i = 0; i < gridsize; ++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);
-
-	      presh(NULL, half_press2, vct2, ps1, nhlevf2, gridsize);
-	      for ( k = 0; k < nhlevf2; ++k )
-		for ( i = 0; i < gridsize; ++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);
-	    }
-
-	  for ( levelID = 0; levelID < nlevel; levelID++ )
-	    {
-	      int offset = gridsize*levelID;
-	      single2  = vars2[iv] + offset;
-
-	      if ( operatorID == REMAPETAS || operatorID == REMAPETAZ )
-		{
-		  /*
-		  for ( i = 0; i < gridsize; ++i )
-		    if ( i %100 == 0 )
-		      printf("%d %g %g %g %g %g\n",i, single2[i], sum1[i], sum2[i], sum1[i]/sum2[i], single2[i]*sum1[i]/sum2[i]);
-		  */
-		  for ( i = 0; i < gridsize; ++i )
-		    single2[i] = single2[i]*sum1[i]/sum2[i];
-		}
-
-	      setmissval(gridsize, imiss, missval, single2);
-	      pstreamDefRecord(streamID2, varID, levelID);
-	      pstreamWriteRecord(streamID2, single2, nmissout);
-	    }
-	}
+      for (int recID = 0; recID < nrecs; recID++)
+        {
+          pstreamInqRecord(streamID1, &varID, &levelID);
+          int zaxisID = vlistInqVarZaxis(vlistID1, varID);
+          int nlevel = zaxisInqSize(zaxisID);
+          int offset = gridsize * levelID;
+          pstreamReadRecord(streamID1, array, &nmiss);
+
+          if (zaxisIDh != -1)
+            {
+              if (varID == sgeopotID)
+                memcpy(fis1, array, gridsize * sizeof(double));
+              else if (varID == presID)
+                {
+                  if (lnpsID != -1)
+                    for (i = 0; i < gridsize; ++i)
+                      ps1[i] = exp(array[i]);
+                  else if (psID != -1)
+                    memcpy(ps1, array, gridsize * sizeof(double));
+                }
+              else if (ltq && varID == tempID)
+                memcpy(t1 + offset, array, gridsize * sizeof(double));
+              else if (ltq && varID == sqID)
+                memcpy(q1 + offset, array, gridsize * sizeof(double));
+              /* else if ( zaxisID == zaxisIDh ) */
+              else if (zaxisInqType(zaxisID) == ZAXIS_HYBRID && nlevel == nhlevf1)
+                {
+                  for (i = 0; i < nvars3D; ++i)
+                    if (varID == varids[i])
+                      break;
+
+                  if (i == nvars3D)
+                    cdoAbort("Internal error, 3D variable not found!");
+
+                  memcpy(vars1[i] + offset, array, gridsize * sizeof(double));
+                }
+              else
+                {
+                  pstreamDefRecord(streamID2, varID, levelID);
+                  pstreamWriteRecord(streamID2, array, nmiss);
+                }
+            }
+          else
+            {
+              pstreamDefRecord(streamID2, varID, levelID);
+              pstreamWriteRecord(streamID2, array, nmiss);
+            }
+        }
+
+      if (zaxisIDh != -1)
+        {
+          /* check range of ps_prog */
+          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(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 (int i = 0; i < gridsize; i++)
+          fis2[i] = fis1[i];
+
+      if (ltq)
+        {
+          varID = tempID;
+          int nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
+          for (levelID = 0; levelID < nlevel; levelID++)
+            {
+              int offset = gridsize * levelID;
+              single2 = t1 + offset;
+
+              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);
+            }
+
+          varID = sqID;
+          nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
+          for (levelID = 0; levelID < nlevel; levelID++)
+            {
+              int offset = gridsize * levelID;
+              single2 = q1 + offset;
+
+              corr_hum(gridsize, single2, MIN_Q);
+
+              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);
+            }
+        }
+
+      if (nvars3D || ltq)
+        {
+          if (cdoTimer)
+            timer_start(timer_hetaeta);
+          hetaeta(ltq,
+                  gridsize,
+                  imiss,
+                  nhlevf1,
+                  a1,
+                  b1,
+                  fis1,
+                  ps1,
+                  t1,
+                  q1,
+                  nhlevf2,
+                  a2,
+                  b2,
+                  fis2,
+                  ps2,
+                  t2,
+                  q2,
+                  nvars3D,
+                  vars1,
+                  vars2,
+                  tscor,
+                  pscor,
+                  secor);
+          if (cdoTimer)
+            timer_stop(timer_hetaeta);
+        }
+
+      if (cptop > 0)
+        nctop = ncctop(cptop, (long) nhlevf2, (long) nhlevf2 + 1, a2, b2);
+
+      if (zaxisIDh != -1 && sgeopotID != -1)
+        {
+          varID = sgeopotID;
+          levelID = 0;
+          setmissval(gridsize, imiss, missval, fis2);
+          pstreamDefRecord(streamID2, varID, levelID);
+          pstreamWriteRecord(streamID2, fis2, nmissout);
+        }
+
+      if (zaxisIDh != -1 && lnpsID != -1)
+        for (i = 0; i < gridsize; ++i)
+          ps2[i] = log(ps2[i]);
+
+      if (zaxisIDh != -1 && presID != -1)
+        {
+          varID = presID;
+          levelID = 0;
+          setmissval(gridsize, imiss, missval, ps2);
+          pstreamDefRecord(streamID2, varID, levelID);
+          pstreamWriteRecord(streamID2, ps2, nmissout);
+        }
+
+      if (ltq)
+        {
+          varID = tempID;
+          int nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
+          for (levelID = 0; levelID < nlevel; levelID++)
+            {
+              int offset = gridsize * levelID;
+              single2 = t2 + offset;
+
+              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);
+
+              setmissval(gridsize, imiss, missval, single2);
+              pstreamDefRecord(streamID2, varID, levelID);
+              pstreamWriteRecord(streamID2, single2, nmissout);
+            }
+
+          varID = sqID;
+          nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
+          for (levelID = 0; levelID < nlevel; levelID++)
+            {
+              int offset = gridsize * levelID;
+              single2 = q2 + offset;
+
+              corr_hum(gridsize, single2, MIN_Q);
+
+              if (levelID < nctop)
+                for (i = 0; i < gridsize; ++i)
+                  single2[i] = cconst;
+
+              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);
+
+              setmissval(gridsize, imiss, missval, single2);
+              pstreamDefRecord(streamID2, varID, levelID);
+              pstreamWriteRecord(streamID2, single2, nmissout);
+            }
+        }
+
+      for (iv = 0; iv < nvars3D; ++iv)
+        {
+          varID = varids[iv];
+
+          int nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
+
+          if (operatorID == REMAPETAS)
+            {
+              vert_sum(sum1, vars1[iv], gridsize, nhlevf1);
+              vert_sum(sum2, vars2[iv], gridsize, nhlevf2);
+            }
+          else if (operatorID == REMAPETAZ)
+            {
+              int k;
+
+              presh(NULL, half_press1, vct1, ps1, nhlevf1, gridsize);
+              for (k = 0; k < nhlevf1; ++k)
+                for (i = 0; i < gridsize; ++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);
+
+              presh(NULL, half_press2, vct2, ps1, nhlevf2, gridsize);
+              for (k = 0; k < nhlevf2; ++k)
+                for (i = 0; i < gridsize; ++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);
+            }
+
+          for (levelID = 0; levelID < nlevel; levelID++)
+            {
+              int offset = gridsize * levelID;
+              single2 = vars2[iv] + offset;
+
+              if (operatorID == REMAPETAS || operatorID == REMAPETAZ)
+                {
+                  /*
+                  for ( i = 0; i < gridsize; ++i )
+                    if ( i %100 == 0 )
+                      printf("%d %g %g %g %g %g\n",i, single2[i], sum1[i], sum2[i], sum1[i]/sum2[i],
+                  single2[i]*sum1[i]/sum2[i]);
+                  */
+                  for (i = 0; i < gridsize; ++i)
+                    single2[i] = single2[i] * sum1[i] / sum2[i];
+                }
+
+              setmissval(gridsize, imiss, missval, single2);
+              pstreamDefRecord(streamID2, varID, levelID);
+              pstreamWriteRecord(streamID2, single2, nmissout);
+            }
+        }
 
       tsID++;
     }
@@ -784,18 +841,18 @@ void *Remapeta(void *argument)
   pstreamClose(streamID2);
   pstreamClose(streamID1);
 
-  if ( nvars3D )
+  if (nvars3D)
     {
-      for ( varID = 0; varID < nvars3D; varID++ )
-	{
-	  Free(vars2[varID]);
-	  Free(vars1[varID]);
-	}
+      for (varID = 0; varID < nvars3D; varID++)
+        {
+          Free(vars2[varID]);
+          Free(vars1[varID]);
+        }
       Free(vars2);
       Free(vars1);
     }
 
-  if ( ltq )
+  if (ltq)
     {
       Free(q2);
       Free(t2);
@@ -806,25 +863,33 @@ void *Remapeta(void *argument)
       Free(tscor);
     }
 
-  if ( imiss ) Free(imiss);
+  if (imiss)
+    Free(imiss);
 
   Free(ps2);
   Free(fis2);
   Free(ps1);
   Free(fis1);
 
-  if ( sum1 ) Free(sum1);
-  if ( sum2 ) Free(sum2);
+  if (sum1)
+    Free(sum1);
+  if (sum2)
+    Free(sum2);
 
-  if ( deltap1 ) Free(deltap1);
-  if ( deltap2 ) Free(deltap2);
+  if (deltap1)
+    Free(deltap1);
+  if (deltap2)
+    Free(deltap2);
 
-  if ( half_press1 ) Free(half_press1);
-  if ( half_press2 ) Free(half_press2);
+  if (half_press1)
+    Free(half_press1);
+  if (half_press2)
+    Free(half_press2);
 
   Free(array);
   Free(vct2);
-  if ( vct1 ) Free(vct1);
+  if (vct1)
+    Free(vct1);
 
   cdoFinish();
 
diff --git a/src/Rhopot.cc b/src/Rhopot.cc
index 0d6df6f..694e118 100644
--- a/src/Rhopot.cc
+++ b/src/Rhopot.cc
@@ -253,7 +253,7 @@ void *Rhopot(void *argument)
     datatype = CDI_DATATYPE_FLT64;
 
   int vlistID2 = vlistCreate();
-  varID = vlistDefVar(vlistID2, gridID, zaxisID, TSTEP_INSTANT);
+  varID = vlistDefVar(vlistID2, gridID, zaxisID, TIME_VARYING);
   vlistDefVarParam(vlistID2, varID, cdiEncodeParam(18, 255, 255));
   vlistDefVarName(vlistID2, varID, "rhopoto");
   vlistDefVarLongname(vlistID2, varID, "Sea water potential density");
diff --git a/src/Runpctl.cc b/src/Runpctl.cc
index 64fdb7a..d1418ef 100644
--- a/src/Runpctl.cc
+++ b/src/Runpctl.cc
@@ -52,6 +52,7 @@ void *Runpctl(void *argument)
 
   int taxisID1 = vlistInqTaxis(vlistID1);
   int taxisID2 = taxisDuplicate(taxisID1);
+  taxisWithBounds(taxisID2);
   vlistDefTaxis(vlistID2, taxisID2);
 
   int streamID2 = pstreamOpenWrite(cdoStreamName(1), cdoFiletype());
@@ -101,7 +102,7 @@ void *Runpctl(void *argument)
     {
       for ( varID = 0; varID < nvars; varID++ )
         {
-          if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+          if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
           
           int gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
           double missval  = vlistInqVarMissval(vlistID1, varID);
@@ -141,7 +142,7 @@ void *Runpctl(void *argument)
           varID    = recVarID[recID];
           levelID  = recLevelID[recID];
 
-	  if ( otsID && vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+	  if ( otsID && vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
 
 	  pstreamDefRecord(streamID2, varID, levelID);
 	  pstreamWriteRecord(streamID2, vars1[0][varID][levelID].ptr, vars1[0][varID][levelID].nmiss);
diff --git a/src/Runstat.cc b/src/Runstat.cc
index ac98600..2f82511 100644
--- a/src/Runstat.cc
+++ b/src/Runstat.cc
@@ -85,6 +85,7 @@ void *Runstat(void *argument)
 
   int taxisID1 = vlistInqTaxis(vlistID1);
   int taxisID2 = taxisDuplicate(taxisID1);
+  taxisWithBounds(taxisID2);
   vlistDefTaxis(vlistID2, taxisID2);
   /*  Number of timestep will be reduced compared to the input
    *  error handling in case of not enough timesteps is done per record */
@@ -140,7 +141,7 @@ void *Runstat(void *argument)
 	    {
               recinfo[recID].varID   = varID;
               recinfo[recID].levelID = levelID;
-              recinfo[recID].lconst  = vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT;
+              recinfo[recID].lconst  = vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT;
 	    }
 	  
           field_type *psamp1 = samp1 ? &samp1[tsID][varID][levelID] : NULL;
diff --git a/src/Samplegridicon.cc b/src/Samplegridicon.cc
index 13fbd89..d635608 100644
--- a/src/Samplegridicon.cc
+++ b/src/Samplegridicon.cc
@@ -1,6 +1,15 @@
 #include <cdi.h>
 #include "cdo_int.h"
 #include "grid.h"
+#include "grid_search.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include "clipping/geometry.h"
+#ifdef __cplusplus
+}
+#endif
 
 constexpr int MAX_CHILDS = 9;
 
@@ -188,15 +197,11 @@ int cmpsinfo(const void *s1, const void *s2)
 }
 
 static
-void compute_child(cellindex_type *cellindex1, cellindex_type *cellindex2)
+void compute_child_from_parent(cellindex_type *cellindex1, cellindex_type *cellindex2)
 {
   int ncells1 = cellindex1->ncells;
   int *parent1 = cellindex1->parent;
-  {
-    int i;
-    for ( i = 0; i < ncells1; ++i ) if ( parent1[i] >= 0 ) break;
-    if ( i == ncells1 ) cdoAbort("Missing parent index of %s!", cellindex1->filename);
-  }
+
   int *idx1 = (int*) Malloc(ncells1*sizeof(int));
   for ( int i = 0; i < ncells1; ++i ) idx1[i] = i;
   for ( int i = 1; i < ncells1; ++i )
@@ -239,6 +244,219 @@ void compute_child(cellindex_type *cellindex1, cellindex_type *cellindex2)
 }
 
 static
+void read_coordinates(const char *filename, int n, double *lon, double *lat, int nv, double *lon_bnds, double *lat_bnds)
+{
+  openLock();
+  int streamID = streamOpenRead(filename);
+  openUnlock();
+
+  if ( streamID < 0 ) cdiOpenError(streamID, "Open failed on >%s<", filename);
+
+  int vlistID = streamInqVlist(streamID);
+  int ngrids = vlistNgrids(vlistID);
+  int gridID = -1;
+  for ( int index = 0; index < ngrids; ++index )
+    {
+      gridID = vlistGrid(vlistID, index);
+      if ( gridInqType(gridID) == GRID_UNSTRUCTURED &&
+           gridInqSize(gridID) == n &&
+           gridInqNvertex(gridID) == 3 ) break;
+    }
+
+  if ( gridID == -1 ) cdoAbort("No ICON grid with %d cells found in %s!", filename, n);
+
+  gridInqXvals(gridID, lon);
+  gridInqYvals(gridID, lat);
+
+  char units[CDI_MAX_NAME];
+  /* Convert lat/lon units if required */
+  gridInqXunits(gridID, units);
+  grid_to_radian(units, n, lon, "grid center lon");
+  gridInqYunits(gridID, units);
+  grid_to_radian(units, n, lat, "grid center lat");
+
+  if ( nv == 3 && lon_bnds && lat_bnds )
+    {
+      gridInqXbounds(gridID, lon_bnds);
+      gridInqYbounds(gridID, lat_bnds);
+
+      gridInqXunits(gridID, units);
+      grid_to_radian(units, n*3, lon_bnds, "grid corner lon");
+      gridInqYunits(gridID, units);
+      grid_to_radian(units, n*3, lat_bnds, "grid corner lat");
+    }
+
+  streamClose(streamID);
+}
+
+int grid_search_nbr(struct gridsearch *gs, size_t num_neighbors, size_t *restrict nbr_add, double *restrict nbr_dist, double plon, double plat);
+
+int find_coordinate_to_ignore(double *cell_corners_xyz);
+double calculate_the_polygon_area(double cell_corners[], int number_corners);
+bool are_polygon_vertices_arranged_in_clockwise_order(double cell_area);
+int winding_numbers_algorithm(double cell_corners[], int number_corners, double point[]);
+
+#define MAX_SEARCH 128 // the triangles are distorted!
+
+static
+void compute_child_from_bounds(cellindex_type *cellindex2, int ncells2, double *grid_center_lon2, double *grid_center_lat2, double *grid_corner_lon2,
+                               double *grid_corner_lat2, int ncells1, double *grid_center_lon1, double *grid_center_lat1)
+{
+  struct gridsearch *gs = gridsearch_create(ncells1, grid_center_lon1, grid_center_lat1);
+  size_t nbr_add[MAX_SEARCH];  // source address at nearest neighbors
+  double nbr_dist[MAX_SEARCH]; // angular distance four nearest neighbors
+
+  int ncorner = 3;
+  double corner_coordinates[3];
+  double center_point_xyz[3];
+  double cell_corners_xyz[12];
+  double cell_corners_plane_projection[8];
+  double center_point_plane_projection[2];
+
+  int *child2 = (int*) Malloc(MAX_CHILDS*ncells2*sizeof(int));
+  cellindex2->child = child2;
+  for ( int cell_no2 = 0; cell_no2 < ncells2; ++cell_no2 )
+    {
+      for ( int k = 0; k < MAX_CHILDS; ++k ) child2[cell_no2*MAX_CHILDS+k] = -1;
+
+      for ( int corner_no = 0; corner_no < ncorner; corner_no++ )
+	{	  
+	  /* Conversion of corner spherical coordinates to Cartesian coordinates. */
+
+          LLtoXYZ(grid_corner_lon2[cell_no2 * ncorner + corner_no], grid_corner_lat2[cell_no2 * ncorner + corner_no], corner_coordinates);
+
+          /* The components of the result vector are appended to the list of cell corner coordinates. */
+
+          int off = corner_no * 3;
+	  cell_corners_xyz[off + 0] = corner_coordinates[0];	  
+	  cell_corners_xyz[off + 1] = corner_coordinates[1];	  
+	  cell_corners_xyz[off + 2] = corner_coordinates[2];	  
+        }
+      cell_corners_xyz[ncorner * 3 + 0] = cell_corners_xyz[0];
+      cell_corners_xyz[ncorner * 3 + 1] = cell_corners_xyz[1];
+      cell_corners_xyz[ncorner * 3 + 2] = cell_corners_xyz[2];
+
+      int coordinate_to_ignore = find_coordinate_to_ignore(cell_corners_xyz);
+
+      bool invert_result = false;
+      if ( cell_corners_xyz[coordinate_to_ignore - 1] < 0 ) invert_result = true;
+
+      switch(coordinate_to_ignore){
+      case 1:
+	for ( int corner_no = 0; corner_no <= ncorner; corner_no++ )
+          {
+            cell_corners_plane_projection[corner_no * 2 + 0] = cell_corners_xyz[corner_no * 3 + 1];
+            cell_corners_plane_projection[corner_no * 2 + 1] = cell_corners_xyz[corner_no * 3 + 2];
+          }
+	break;
+      case 2:
+	for ( int corner_no = 0; corner_no <= ncorner; corner_no++ )
+          {
+            cell_corners_plane_projection[corner_no * 2 + 0] = cell_corners_xyz[corner_no * 3 + 2];
+            cell_corners_plane_projection[corner_no * 2 + 1] = cell_corners_xyz[corner_no * 3 + 0];
+          }
+	break;
+      case 3:
+	for ( int corner_no = 0; corner_no <= ncorner; corner_no++ )
+          {
+            cell_corners_plane_projection[corner_no * 2 + 0] = cell_corners_xyz[corner_no * 3 + 0];
+            cell_corners_plane_projection[corner_no * 2 + 1] = cell_corners_xyz[corner_no * 3 + 1];
+          }
+	break;
+      }
+
+      double polygon_area = calculate_the_polygon_area(cell_corners_plane_projection, ncorner + 1);
+      bool is_clockwise = are_polygon_vertices_arranged_in_clockwise_order(polygon_area);
+
+      if ( invert_result ) is_clockwise = !is_clockwise;
+      if ( is_clockwise ) continue;
+      
+      grid_search_nbr(gs, MAX_SEARCH, nbr_add, nbr_dist, grid_center_lon2[cell_no2], grid_center_lat2[cell_no2]);
+      int k = 0;
+
+      for ( int i = 0; i < MAX_SEARCH; ++i )
+        {
+          size_t cell_no1 = nbr_add[i];
+          if ( cell_no1 < ULONG_MAX )
+            {
+              LLtoXYZ(grid_center_lon1[cell_no1], grid_center_lat1[cell_no1], center_point_xyz);
+
+              switch(coordinate_to_ignore){
+              case 1:
+                center_point_plane_projection[0] = center_point_xyz[1];
+                center_point_plane_projection[1] = center_point_xyz[2];		
+                break;
+              case 2:
+                center_point_plane_projection[0] = center_point_xyz[2];
+                center_point_plane_projection[1] = center_point_xyz[0];	
+                break;
+              case 3:
+                center_point_plane_projection[0] = center_point_xyz[0];
+                center_point_plane_projection[1] = center_point_xyz[1];	
+                break;
+              }
+
+              int winding_number = winding_numbers_algorithm(cell_corners_plane_projection, ncorner + 1, center_point_plane_projection);
+              //printf("%d %g %g %g %g %d\n", cell_no2, RAD2DEG*grid_center_lon2[cell_no2], RAD2DEG*grid_center_lat2[cell_no2], RAD2DEG*grid_center_lon1[cell_no1], RAD2DEG*grid_center_lat1[cell_no1], winding_number);
+              if ( winding_number != 0 )
+                {
+                  if ( k >= MAX_CHILDS ) cdoAbort("Internal problem, limit of MAX_CHILDS reached (limit=9).");
+                  child2[cell_no2*MAX_CHILDS+k++] = (int)cell_no1;
+                }
+            }
+        }
+      // printf("%d k = %d\n", cell_no2, k);
+    }
+}
+
+static
+void compute_child_from_coordinates(cellindex_type *cellindex1, cellindex_type *cellindex2)
+{
+  int ncells1 = cellindex1->ncells;
+  int ncells2 = cellindex2->ncells;
+
+  double *lon1 = (double*) Malloc(ncells1*sizeof(double));
+  double *lat1 = (double*) Malloc(ncells1*sizeof(double));
+  double *lon2 = (double*) Malloc(ncells2*sizeof(double));
+  double *lat2 = (double*) Malloc(ncells2*sizeof(double));
+  double *lon2_bnds = (double*) Malloc(3*ncells2*sizeof(double));
+  double *lat2_bnds = (double*) Malloc(3*ncells2*sizeof(double));
+
+  read_coordinates(cellindex1->filename, ncells1, lon1, lat1, 0, NULL, NULL);
+  read_coordinates(cellindex2->filename, ncells2, lon2, lat2, 3, lon2_bnds, lat2_bnds);
+
+  compute_child_from_bounds(cellindex2, ncells2, lon2, lat2, lon2_bnds, lat2_bnds, ncells1, lon1, lat1);
+
+  Free(lon1);
+  Free(lat1);
+  Free(lon2);
+  Free(lat2);
+  Free(lon2_bnds);
+  Free(lat2_bnds);
+}
+
+static
+void compute_child(cellindex_type *cellindex1, cellindex_type *cellindex2)
+{
+  bool lparent = true;
+  int ncells1 = cellindex1->ncells;
+  int *parent1 = cellindex1->parent;
+  {
+    int i;
+    for ( i = 0; i < ncells1; ++i ) if ( parent1[i] >= 0 ) break;
+    if ( i == ncells1 ) lparent = false;
+  }
+
+  if ( lparent )
+    compute_child_from_parent(cellindex1, cellindex2);
+  else
+    {
+      compute_child_from_coordinates(cellindex1, cellindex2);
+      // cdoAbort("Missing parent index of %s!", cellindex1->filename);
+    }
+}
+
+static
 void compute_sum(int i, int *n, double *sum, double *sumq, int kci, cellindex_type **cellindex, double *array)
 {
   // printf("compute: i, kci %d %d\n", i, kci);
diff --git a/src/Seascount.cc b/src/Seascount.cc
index 1f69388..c504ec0 100644
--- a/src/Seascount.cc
+++ b/src/Seascount.cc
@@ -144,7 +144,7 @@ void *Seascount(void *argument)
           varID   = recVarID[recID];
           levelID = recLevelID[recID];
 
-	  if ( otsID && vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+	  if ( otsID && vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
 
 	  pstreamDefRecord(streamID2, varID, levelID);
 	  pstreamWriteRecord(streamID2, vars1[varID][levelID].ptr, (int)vars1[varID][levelID].nmiss);
diff --git a/src/Seaspctl.cc b/src/Seaspctl.cc
index 7e0d643..8cd136b 100644
--- a/src/Seaspctl.cc
+++ b/src/Seaspctl.cc
@@ -70,6 +70,7 @@ void *Seaspctl(void *argument)
   /* TODO - check that time axes 2 and 3 are equal */
 
   int taxisID4 = taxisDuplicate(taxisID1);
+  taxisWithBounds(taxisID4);
   vlistDefTaxis(vlistID4, taxisID4);
 
   int streamID4 = pstreamOpenWrite(cdoStreamName(3), cdoFiletype());
@@ -195,7 +196,7 @@ void *Seaspctl(void *argument)
 
       for ( varID = 0; varID < nvars; varID++ )
 	{
-	  if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+	  if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
 	  nlevels = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
 	  
 	  for ( levelID = 0; levelID < nlevels; levelID++ )
@@ -210,7 +211,7 @@ void *Seaspctl(void *argument)
 	  varID   = recVarID[recID];
 	  levelID = recLevelID[recID];
 
-	  if ( otsID && vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+	  if ( otsID && vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
 
 	  pstreamDefRecord(streamID4, varID, levelID);
 	  pstreamWriteRecord(streamID4, vars1[varID][levelID].ptr, vars1[varID][levelID].nmiss);
diff --git a/src/Seasstat.cc b/src/Seasstat.cc
index 4671ed1..4a7aeb0 100644
--- a/src/Seasstat.cc
+++ b/src/Seasstat.cc
@@ -84,6 +84,7 @@ void *Seasstat(void *argument)
 
   int taxisID1 = vlistInqTaxis(vlistID1);
   int taxisID2 = taxisDuplicate(taxisID1);
+  taxisWithBounds(taxisID2);
   if ( taxisInqType(taxisID2) == TAXIS_FORECAST ) taxisDefType(taxisID2, TAXIS_RELATIVE);
   vlistDefTaxis(vlistID2, taxisID2);
 
@@ -151,7 +152,7 @@ void *Seasstat(void *argument)
 		{
                   recinfo[recID].varID   = varID;
                   recinfo[recID].levelID = levelID;
-                  recinfo[recID].lconst  = vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT;
+                  recinfo[recID].lconst  = vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT;
 		}
 
               field_type *psamp1 = &samp1[varID][levelID];
diff --git a/src/Selbox.cc b/src/Selbox.cc
index e8597f0..6b001d6 100644
--- a/src/Selbox.cc
+++ b/src/Selbox.cc
@@ -144,7 +144,7 @@ int gengrid(int gridID1, int lat1, int lat2, int lon11, int lon12, int lon21, in
   gridDefYsize(gridID2, nlat2);
 
   gridDefNP(gridID2, gridInqNP(gridID1));
-  gridDefPrec(gridID2, gridInqPrec(gridID1));
+  gridDefDatatype(gridID2, gridInqDatatype(gridID1));
 
   grid_copy_attributes(gridID1, gridID2);
 
@@ -249,7 +249,7 @@ int gengridcell(int gridID1, int gridsize2, int *cellidx)
   int gridID2 = -1;
   int gridtype  = gridInqType(gridID1);
   int gridsize1 = gridInqSize(gridID1);
-  int prec      = gridInqPrec(gridID1);
+  int prec      = gridInqDatatype(gridID1);
 
   if ( gridtype == GRID_CURVILINEAR ) gridtype = GRID_UNSTRUCTURED;
 
@@ -258,7 +258,7 @@ int gengridcell(int gridID1, int gridsize2, int *cellidx)
   else
     return gridID2;
 
-  gridDefPrec(gridID2, prec);
+  gridDefDatatype(gridID2, prec);
 
   grid_copy_attributes(gridID1, gridID2);
 
diff --git a/src/Select.cc b/src/Select.cc
index 0c4a55f..03cd35c 100644
--- a/src/Select.cc
+++ b/src/Select.cc
@@ -143,6 +143,7 @@ void *Select(void *argument)
 
   sellist_t *sellist = sellist_create(kvlist);
 
+  // clang-format off
   SELLIST_ADD_INT(timestep_of_year, "Timestep of year");
   SELLIST_ADD_INT(timestep,         "Timestep");
   SELLIST_ADD_INT(year,             "Year");
@@ -166,6 +167,7 @@ void *Select(void *argument)
   SELLIST_ADD_WORD(season,          "Season");
   SELLIST_ADD_WORD(date,            "Date");
   SELLIST_ADD_WORD(timestepmask,    "Timestep mask");
+  // clang-format on
 
   if ( cdoVerbose ) sellist_print(sellist);
 
@@ -177,6 +179,8 @@ void *Select(void *argument)
   int streamCnt = cdoStreamCnt();
   int nfiles = streamCnt - 1;
 
+  dtlist_type *dtlist = dtlist_new();
+
   if ( !cdoVerbose && nfiles > 1 ) progressInit();
 
   timestep = 0;
@@ -253,8 +257,7 @@ void *Select(void *argument)
               gridname = gname;
 
               int tsteptype = vlistInqVarTsteptype(vlistID1, varID);
-              if      ( tsteptype == TSTEP_CONSTANT ) steptype = "constant";
-              else if ( tsteptype == TSTEP_INSTANT  ) steptype = "instant";
+              if      ( tsteptype == TSTEP_INSTANT  ) steptype = "instant";
               else if ( tsteptype == TSTEP_INSTANT2 ) steptype = "instant";
               else if ( tsteptype == TSTEP_INSTANT3 ) steptype = "instant";
               else if ( tsteptype == TSTEP_MIN      ) steptype = "min";
@@ -405,7 +408,7 @@ void *Select(void *argument)
                 {
                   for ( varID = 0; varID < nvars; ++varID )
                     {
-                      if ( vars[varID] == true && vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT )
+                      if ( vars[varID] == true && vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT )
                         {
                           lcopy_const = true;
                           break;
@@ -442,18 +445,18 @@ void *Select(void *argument)
 	  if ( ntsteps == 1 && nfiles == 1 )
 	    {
 	      for ( varID = 0; varID < nvars2; ++varID )
-		if ( vlistInqVarTsteptype(vlistID2, varID) != TSTEP_CONSTANT ) break;
+		if ( vlistInqVarTimetype(vlistID2, varID) != TIME_CONSTANT ) break;
 
 	      if ( varID == nvars2 ) ntsteps = 0;
 	    }
 
 	  ntsteps2 = (operatorID == SELECT && SELLIST_NVAL(timestep) == 1) ? 1 : ntsteps;
-	  
+
 	  if ( ntsteps2 == 0 && nfiles > 1 )
 	    {
               lconstvars = false;
 	      for ( varID = 0; varID < nvars2; ++varID )
-		vlistDefVarTsteptype(vlistID2, varID, TSTEP_INSTANT);
+		vlistDefVarTimetype(vlistID2, varID, TIME_VARYING);
 	    }
 
 	  // support for negative timestep values
@@ -525,8 +528,9 @@ void *Select(void *argument)
                     }
                 }
 
-	      int vdate = taxisInqVdate(taxisID1);
-	      int vtime = taxisInqVtime(taxisID1);
+              dtlist_taxisInqTimestep(dtlist, taxisID1, 0);
+              int vdate = dtlist_get_vdate(dtlist, 0);
+              int vtime = dtlist_get_vtime(dtlist, 0);
               int second;
 	      cdiDecodeDate(vdate, &year, &month, &day);
 	      cdiDecodeTime(vtime, &hour, &minute, &second);
@@ -602,7 +606,6 @@ void *Select(void *argument)
 		  streamID2 = pstreamOpenWrite(cdoStreamName(nfiles), cdoFiletype());
 		  pstreamDefVlist(streamID2, vlistID2);
 		}
-
 	      taxisCopyTimestep(taxisID2, taxisID1);
 	      pstreamDefTimestep(streamID2, tsID2);
               
@@ -612,7 +615,7 @@ void *Select(void *argument)
 		  if ( vlistInqFlag(vlistID0, varID, levelID) == TRUE )
 		    {
                       if ( lconstvars && tsID2 > 0 && tsID1 == 0 )
-                        if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT )
+                        if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT )
                           continue;
 
 		      int varID2   = vlistFindVar(vlistID2, varID);
@@ -649,7 +652,7 @@ void *Select(void *argument)
 		  if ( vlistInqFlag(vlistID0, varID, levelID) == TRUE )
 		    {
 		      int varID2 = vlistFindVar(vlistID2, varID);
-                      if ( vlistInqVarTsteptype(vlistID2, varID2) == TSTEP_CONSTANT )
+                      if ( vlistInqVarTimetype(vlistID2, varID2) == TIME_CONSTANT )
                         {
                           int levelID2 = vlistFindLevel(vlistID2, varID, levelID);
                           int gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID2));
@@ -667,7 +670,7 @@ void *Select(void *argument)
 
 	  tsID1++;
 	}
-      
+
       pstreamClose(streamID1);
 
       if ( lstop ) break;
@@ -691,6 +694,8 @@ void *Select(void *argument)
 
   if ( streamID2 != CDI_UNDEFID ) pstreamClose(streamID2);
 
+  dtlist_delete(dtlist);
+
   vlistDestroy(vlistID0);
   vlistDestroy(vlistID2);
 
diff --git a/src/Selmulti.cc b/src/Selmulti.cc
index bf998e8..bbaf01a 100644
--- a/src/Selmulti.cc
+++ b/src/Selmulti.cc
@@ -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-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2012 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
@@ -332,7 +332,7 @@ void *Selmulti(void *argument)
 
   nvars = vlistNvars(vlistID2);
   for ( varID = 0; varID < nvars; ++varID )
-    if ( vlistInqVarTsteptype(vlistID2, varID) != TSTEP_CONSTANT ) break;
+    if ( vlistInqVarTimetype(vlistID2, varID) != TIME_CONSTANT ) break;
   if ( varID == nvars ) vlistDefNtsteps(vlistID2, 0);
 
   int taxisID1 = vlistInqTaxis(vlistID1);
diff --git a/src/Selrec.cc b/src/Selrec.cc
index 5eac316..8700a3e 100644
--- a/src/Selrec.cc
+++ b/src/Selrec.cc
@@ -35,7 +35,7 @@ void *Selrec(void *argument)
 
   cdoInitialize(argument);
 
-  if ( processSelf() != 0 ) cdoAbort("This operator can't be combined with other operators!");
+  if ( processSelf().m_ID != 0 ) cdoAbort("This operator can't be combined with other operators!");
 
   operatorInputArg("records");
 
@@ -53,7 +53,8 @@ void *Selrec(void *argument)
 
   int filetype = pstreamInqFiletype(streamID1);
 
-  if ( filetype == CDI_FILETYPE_NC || filetype == CDI_FILETYPE_NC2 || filetype == CDI_FILETYPE_NC4 || filetype == CDI_FILETYPE_NC4C )
+  if ( filetype == CDI_FILETYPE_NC || filetype == CDI_FILETYPE_NC2 || filetype == CDI_FILETYPE_NC4 ||
+       filetype == CDI_FILETYPE_NC4C || filetype == CDI_FILETYPE_NC5 )
     cdoAbort("This operator does not work on NetCDF data!");
 
   int vlistID1 = pstreamInqVlist(streamID1);
diff --git a/src/Seltime.cc b/src/Seltime.cc
index aaf7a63..7a2a08c 100644
--- a/src/Seltime.cc
+++ b/src/Seltime.cc
@@ -314,7 +314,7 @@ void *Seltime(void *argument)
   int nvars = vlistNvars(vlistID1);
   int nconst = 0;
   for ( varID = 0; varID < nvars; varID++ )
-    if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) nconst++;
+    if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) nconst++;
       
   bool lnts1 = (operatorID == SELSMON) && (nts1 > 0);
 
@@ -338,7 +338,7 @@ void *Seltime(void *argument)
 
 	  for ( varID = 0; varID < nvars; varID++ )
 	    {
-	      if ( lnts1 || (vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT) )
+	      if ( lnts1 || (vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT) )
 		{
 		  int gridID  = vlistInqVarGrid(vlistID1, varID);
 		  int nlevel  = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
@@ -457,7 +457,7 @@ void *Seltime(void *argument)
 		  
 		  for ( varID = 0; varID < nvars; varID++ )
 		    {
-		      if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT && tsID2 > 1 ) continue;
+		      if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT && tsID2 > 1 ) continue;
 		      int nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
 		      for ( levelID = 0; levelID < nlevel; levelID++ )
 			{
@@ -488,7 +488,7 @@ void *Seltime(void *argument)
 	      nts = nts1 - 1;
 	      for ( varID = 0; varID < nvars; varID++ )
 		{
-		  if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT )
+		  if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT )
 		    {
 		      int nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
 		      for ( levelID = 0; levelID < nlevel; levelID++ )
@@ -537,7 +537,7 @@ void *Seltime(void *argument)
 			vtime_list[it] = vtime_list[it+1];
 			for ( varID = 0; varID < nvars; varID++ )
 			  {
-			    if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+			    if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
 			    int gridID   = vlistInqVarGrid(vlistID1, varID);
 			    int gridsize = gridInqSize(gridID);
 			    int nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
@@ -560,7 +560,7 @@ void *Seltime(void *argument)
 	      for ( int recID = 0; recID < nrecs; recID++ )
 		{
 		  pstreamInqRecord(streamID1, &varID, &levelID);
-		  if ( lnts1 || (vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT) )
+		  if ( lnts1 || (vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT) )
 		    {
 		      single = vars[nts][varID][levelID].ptr;
 		      pstreamReadRecord(streamID1, single, &nmiss);
diff --git a/src/Selvar.cc b/src/Selvar.cc
index c5ddd0e..43c7d1d 100644
--- a/src/Selvar.cc
+++ b/src/Selvar.cc
@@ -291,7 +291,7 @@ void *Selvar(void *argument)
 
   nvars = vlistNvars(vlistID2);
   for ( varID = 0; varID < nvars; ++varID )
-    if ( vlistInqVarTsteptype(vlistID2, varID) != TSTEP_CONSTANT ) break;
+    if ( vlistInqVarTimetype(vlistID2, varID) != TIME_CONSTANT ) break;
   if ( varID == nvars ) vlistDefNtsteps(vlistID2, 0);
 
   int taxisID1 = vlistInqTaxis(vlistID1);
diff --git a/src/Setgrid.cc b/src/Setgrid.cc
index 5924b87..fbc5dc4 100644
--- a/src/Setgrid.cc
+++ b/src/Setgrid.cc
@@ -67,6 +67,9 @@ void *Setgrid(void *argument)
 
   int operatorID = cdoOperatorID();
 
+  // open stream before calling cdoDefineGrid!!!
+  int streamID1 = pstreamOpenRead(cdoStreamName(0));
+
   if ( operatorID != UNSETGRIDMASK )
     operatorInputArg(cdoOperatorEnter(operatorID));  
 
@@ -177,8 +180,6 @@ void *Setgrid(void *argument)
       griduri = operatorArgv()[0];
     }
 
-  int streamID1 = pstreamOpenRead(cdoStreamName(0));
-
   int vlistID1 = pstreamInqVlist(streamID1);
   int vlistID2 = vlistDuplicate(vlistID1);
 
diff --git a/src/Sethalo.cc b/src/Sethalo.cc
index e8bd0a7..3f539e5 100644
--- a/src/Sethalo.cc
+++ b/src/Sethalo.cc
@@ -47,13 +47,13 @@ int gentpngrid(int gridID1)
   nlat2 = nlat1+2;
 
   gridtype = gridInqType(gridID1);
-  prec     = gridInqPrec(gridID1);
+  prec     = gridInqDatatype(gridID1);
 
   gridID2 = gridCreate(gridtype, nlon2*nlat2);
   gridDefXsize(gridID2, nlon2);
   gridDefYsize(gridID2, nlat2);
 
-  gridDefPrec(gridID2, prec);
+  gridDefDatatype(gridID2, prec);
 
   grid_copy_attributes(gridID1, gridID2);
 
@@ -199,13 +199,13 @@ int gengrid(int gridID1, int lhalo, int rhalo)
 	 nlon1, nlon2, lhalo, rhalo, nmin, nmax);
   */
   gridtype = gridInqType(gridID1);
-  prec     = gridInqPrec(gridID1);
+  prec     = gridInqDatatype(gridID1);
 
   gridID2 = gridCreate(gridtype, nlon2*nlat2);
   gridDefXsize(gridID2, nlon2);
   gridDefYsize(gridID2, nlat2);
 
-  gridDefPrec(gridID2, prec);
+  gridDefDatatype(gridID2, prec);
 
   grid_copy_attributes(gridID1, gridID2);
 
diff --git a/src/Settime.cc b/src/Settime.cc
index d6c825f..2b84354 100644
--- a/src/Settime.cc
+++ b/src/Settime.cc
@@ -134,6 +134,7 @@ void gen_bounds(int calendar, int tunit, int incperiod, int vdate, int vtime, in
     {
       if ( incperiod == 0 ) incperiod = 1;
       if ( incperiod > 24 ) cdoAbort("Time period must be less equal 24!");
+
       if      ( tunit == TUNIT_3HOURS  ) incperiod = 3;
       else if ( tunit == TUNIT_6HOURS  ) incperiod = 6;
       else if ( tunit == TUNIT_12HOURS ) incperiod = 12;
@@ -212,7 +213,7 @@ void *Settime(void *argument)
 	}
       else
 	{
-	  sdate = parameter2int(datestr);
+	  sdate = *datestr ? parameter2int(datestr) : 10101;
 	}
 
       if ( operatorArgc() > 1 )
@@ -309,7 +310,7 @@ void *Settime(void *argument)
       size_t len = strlen(cname);
       if ( len < 3 ) len = 7;
       if      ( strcmp(cname, "standard")  == 0 ) newcalendar = CALENDAR_STANDARD;
-      else if ( strcmp(cname, "gregorian") == 0 ) newcalendar = CALENDAR_STANDARD;
+      else if ( strcmp(cname, "gregorian") == 0 ) newcalendar = CALENDAR_GREGORIAN;
       else if ( strcmp(cname, "proleptic") == 0 ) newcalendar = CALENDAR_PROLEPTIC;
       else if ( strcmp(cname, "proleptic_gregorian") == 0 ) newcalendar = CALENDAR_PROLEPTIC;
       else if ( strncmp(cname, "360days", len) == 0 ) newcalendar = CALENDAR_360DAYS;
@@ -332,14 +333,14 @@ void *Settime(void *argument)
   int vlistID2 = vlistDuplicate(vlistID1);
 
   int taxisID1 = vlistInqTaxis(vlistID1);
-  int taxis_has_bounds = taxisHasBounds(taxisID1);
+  bool taxis_has_bounds = taxisHasBounds(taxisID1) > 0;
   int ntsteps  = vlistNtsteps(vlistID1);
   int nvars    = vlistNvars(vlistID1);
 
   if ( ntsteps == 1 )
     {
       for ( varID = 0; varID < nvars; ++varID )
-	if ( vlistInqVarTsteptype(vlistID1, varID) != TSTEP_CONSTANT ) break;
+	if ( vlistInqVarTimetype(vlistID1, varID) != TIME_CONSTANT ) break;
 
       if ( varID == nvars ) ntsteps = 0;
     }
@@ -347,7 +348,7 @@ void *Settime(void *argument)
   if ( ntsteps == 0 )
     {
       for ( varID = 0; varID < nvars; ++varID )
-	vlistDefVarTsteptype(vlistID2, varID, TSTEP_INSTANT);
+	vlistDefVarTimetype(vlistID2, varID, TIME_VARYING);
     }
 
   int calendar = taxisInqCalendar(taxisID1);
@@ -420,13 +421,17 @@ void *Settime(void *argument)
     {
       taxisDefCalendar(taxisID2, newcalendar);
     }
+  else if ( operatorID == SETTBOUNDS )
+    {
+      taxisWithBounds(taxisID2);
+    }
 
   if ( operatorID != SHIFTTIME )
     if ( taxis_has_bounds && !copy_timestep )
       {
 	cdoWarning("Time bounds unsupported by this operator, removed!");
 	taxisDeleteBounds(taxisID2);
-	taxis_has_bounds = FALSE;
+	taxis_has_bounds = false;
       }
 
   vlistDefTaxis(vlistID2, taxisID2);
@@ -461,10 +466,7 @@ void *Settime(void *argument)
 		  while ( month > 12 ) { month -= 12; year++; }
 		  while ( month <  1 ) { month += 12; year--; }
 
-		  if ( day0 == 31 )
-		    day = days_per_month(calendar, year, month);
-		  else
-		    day = day0;
+                  day = (day0 == 31) ? days_per_month(calendar, year, month) : day0;
 
 		  vdate = cdiEncodeDate(year, month, day);
 		}
@@ -535,6 +537,7 @@ void *Settime(void *argument)
 
 	  taxisDefVdate(taxisID2, vdate);
 	  taxisDefVtime(taxisID2, vtime);
+
 	  if ( taxis_has_bounds || operatorID == SETTBOUNDS )
 	    {
 	      taxisDefVdateBounds(taxisID2, vdateb[0], vdateb[1]);
diff --git a/src/Showattribute.cc b/src/Showattribute.cc
new file mode 100644
index 0000000..38e98c4
--- /dev/null
+++ b/src/Showattribute.cc
@@ -0,0 +1,192 @@
+/*
+  This file is part of CDO. CDO is a collection of Operators to
+  manipulate and analyse Climate model Data.
+
+  Copyright (C) 2003-2017 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.
+*/
+
+#include <cdi.h>
+#include "cdo.h"
+#include "cdo_int.h"
+#include "pstream.h"
+
+void printAtts(int vlistID, int varOrGlobal, int natts, char *argument)
+{
+  char stdname[CDI_MAX_NAME], longname[CDI_MAX_NAME], units[CDI_MAX_NAME];
+  int found = 0;
+  if ( varOrGlobal != CDI_GLOBAL ) 
+    {
+      vlistInqVarStdname(vlistID, varOrGlobal, stdname);
+      vlistInqVarLongname(vlistID, varOrGlobal, longname);
+      vlistInqVarUnits(vlistID, varOrGlobal, units);
+      double misval = vlistInqVarMissval(vlistID, varOrGlobal);
+      if ( argument )
+        {
+          if ( STR_IS_EQ("standard_name", argument) && stdname[0] )
+            {
+              fprintf(stdout, "  standard_name = \"%s\"\n", stdname);       
+              found++;
+            }
+          else if ( STR_IS_EQ("long_name", argument) && longname[0] )
+            {
+              fprintf(stdout, "  long_name = \"%s\"\n", longname);       
+              found++;
+            }
+          else if ( STR_IS_EQ("units", argument) && units[0] )
+            {
+              fprintf(stdout, "  units = \"%s\"\n", units);       
+              found++;
+            }
+          else if ( STR_IS_EQ("missing_value", argument) )
+            {
+              fprintf(stdout, "  missing_value = \"%e\"\n", misval);       
+              found++;
+            }
+        }
+      else
+        {
+          if ( stdname[0] )
+            fprintf(stdout, "  standard_name = \"%s\"\n", stdname);  
+          if ( longname[0] )     
+            fprintf(stdout, "  long_name = \"%s\"\n", longname);  
+          if ( units[0] )    
+            fprintf(stdout, "  units = \"%s\"\n", units);       
+          fprintf(stdout, "  missing_value = \"%e\"\n", misval); 
+        }      
+    }
+  if ( found == 0 )
+    {
+      for ( int i = 0; i < natts; i++ )
+        {
+          char name[CDI_MAX_NAME];
+          char *value = (char *)Malloc(4*CDI_MAX_NAME * sizeof(char));
+          int type, len;
+          cdiInqAtt(vlistID, varOrGlobal, i, name, &type, &len);
+          if ( argument )
+            {
+              if ( !STR_IS_EQ(argument, name) )
+                continue;
+              else
+                found++;
+            }
+          switch ( type )
+	    {
+	    case CDI_DATATYPE_TXT:
+	      cdiInqAttTxt(vlistID, varOrGlobal, name, len, value);
+	      value[len] = '\0';
+	      fprintf(stdout, "  %s = \"%s\"\n", name, value);
+	      break;
+	    case CDI_DATATYPE_INT32:
+	      cdiInqAttInt(vlistID, varOrGlobal, name, len, (int *)value);
+	      fprintf(stdout, "  %s = %i\n", name, *(int *)value);
+	      break;
+	    case CDI_DATATYPE_FLT64:
+	      cdiInqAttFlt(vlistID, varOrGlobal, name, len, (double *)value);
+	      fprintf(stdout, "  %s = %e\n", name, *(double *)value);
+    	      break;
+    	    default:
+    	      cdoWarning("Unsupported type %i name %s\n", type, name);
+    	    }
+          Free(value);
+        }
+    }
+  if ( argument && found == 0 )
+    {
+      if ( varOrGlobal != CDI_GLOBAL )
+        cdoAbort("Could not find variable attribute %s in infile.", argument);
+      else
+        cdoAbort("Could not find global attribute %s in infile.", argument);
+    }
+}
+
+void check_varname_and_print(int vlistID, int nvars, char *checkvarname, char *attname)
+{
+  int varID = 0;
+  for ( varID = 0; varID < nvars; varID++ )
+    {
+      char filevarname[CDI_MAX_NAME];
+      vlistInqVarName(vlistID, varID, filevarname);  
+      if ( !checkvarname || STR_IS_EQ(checkvarname, filevarname) )
+        {
+          fprintf(stdout, "%s:\n", filevarname);
+	  int nfileattsvar;
+          cdiInqNatts(vlistID, varID, &nfileattsvar);
+          printAtts(vlistID, varID, nfileattsvar, attname);
+          break;
+        }
+    } 
+  if ( nvars == varID && checkvarname )
+    cdoAbort("Could not find variable %s in infile.", checkvarname);
+}
+
+void *Showattribute(void *argument)
+{
+  const int delim = '@';
+  cdoInitialize(argument);
+
+  int SHOWATTRIBUTE = cdoOperatorAdd("showattribute",   0, 0, NULL);
+  int SHOWATTSVAR   = cdoOperatorAdd("showattsvar",   0, 0, NULL);
+
+  int operatorID = cdoOperatorID();
+
+  int streamID = pstreamOpenRead(cdoStreamName(0));
+  int vlistID = pstreamInqVlist(streamID);
+  int nvars   = vlistNvars(vlistID);
+
+  int natts = operatorArgc();
+  if ( natts == 0 && operatorID != SHOWATTSVAR)
+    cdoAbort("Parameter missing!");
+  else if ( natts == 0 )
+    check_varname_and_print(vlistID, nvars, NULL, NULL);
+  else
+    {
+      char **params = operatorArgv();
+      char buffer[CDI_MAX_NAME];
+      for ( int i = 0; i < natts; i++)
+        {
+          strcpy(buffer, params[i]);
+          char *varname = NULL, *input = NULL;
+          char *result = strrchr(buffer, delim);
+          input = buffer;
+          if ( result == NULL )
+            {
+              if ( operatorID == SHOWATTRIBUTE )
+                {
+                  fprintf(stdout, "Global:\n");
+                  int nfileatts;
+                  cdiInqNatts(vlistID, CDI_GLOBAL, &nfileatts);
+                  printAtts(vlistID, CDI_GLOBAL, nfileatts, input);
+                }
+              else if (operatorID == SHOWATTSVAR )
+                check_varname_and_print(vlistID, nvars, input, NULL);
+            }
+          else
+            {
+              if ( operatorID == SHOWATTRIBUTE )
+                {
+                  input = result+1;
+                  *result = 0;
+                  varname = buffer;
+                  check_varname_and_print(vlistID, nvars, varname, input);
+                }
+              else if ( operatorID == SHOWATTSVAR )
+                check_varname_and_print(vlistID, nvars, input, NULL);
+            }
+        }
+    }
+  pstreamClose(streamID);
+
+  cdoFinish();
+
+  return 0;
+}
diff --git a/src/Showattribute.h b/src/Showattribute.h
new file mode 100644
index 0000000..1563cf5
--- /dev/null
+++ b/src/Showattribute.h
@@ -0,0 +1 @@
+void *printAtts(int vlistID, int varOrGlobal, int natts, char *argument); 
diff --git a/src/Showinfo.cc b/src/Showinfo.cc
index 5f60117..ac8fe10 100644
--- a/src/Showinfo.cc
+++ b/src/Showinfo.cc
@@ -37,7 +37,7 @@
 #include "cdo.h"
 #include "cdo_int.h"
 #include "pstream.h"
-
+#include "Showattribute.h"
 
 void *Showinfo(void *argument)
 {
@@ -62,6 +62,8 @@ void *Showinfo(void *argument)
   int SHOWLTYPE     = cdoOperatorAdd("showltype",     0, 0, NULL);
   int SHOWFORMAT    = cdoOperatorAdd("showformat",    0, 0, NULL);
   int SHOWGRID      = cdoOperatorAdd("showgrid",      0, 0, NULL); 
+  int SHOWATTS      = cdoOperatorAdd("showatts",      0, 0, NULL);
+  int SHOWATTSGLOB  = cdoOperatorAdd("showattsglob",  0, 0, NULL);
   // clang-format on
 
   int operatorID = cdoOperatorID();
@@ -258,7 +260,38 @@ void *Showinfo(void *argument)
     {
       printFiletype(streamID, vlistID);
     }
-
+  else if ( operatorID == SHOWSTDNAME )
+    {
+      char stdname[CDI_MAX_NAME];
+      for ( int varID = 0; varID < nvars; varID++ )
+	{
+	  vlistInqVarStdname(vlistID, varID, stdname);
+          fprintf(stdout, " %s", stdname[0] != 0 ? stdname : "unknown");
+	}
+      fprintf(stdout, "\n");
+    }
+  else if ( operatorID == SHOWATTS || operatorID == SHOWATTSGLOB )
+    {
+      if ( operatorID == SHOWATTS )
+        {
+          int vlistID = pstreamInqVlist(streamID);
+          int nvars = vlistNvars(vlistID);
+          for ( int varID = 0; varID < nvars; varID++ )
+            {
+              char varname[CDI_MAX_NAME];
+              vlistInqVarName(vlistID, varID, varname);
+              fprintf(stdout, "%s:\n", varname);
+
+    	      int nattsvar;
+    	      cdiInqNatts(vlistID, varID, &nattsvar);
+    	      printAtts(vlistID, varID, nattsvar, NULL);
+    	    }
+        }
+      fprintf(stdout, "Global:\n");
+      int natts;
+      cdiInqNatts(vlistID, CDI_GLOBAL, &natts);
+      printAtts(vlistID, CDI_GLOBAL, natts, NULL);
+    }
   pstreamClose(streamID);
 
   cdoFinish();
diff --git a/src/Sinfo.cc b/src/Sinfo.cc
index cf43224..0d60ce8 100644
--- a/src/Sinfo.cc
+++ b/src/Sinfo.cc
@@ -32,6 +32,7 @@
 
 const char *tunit2str(int tunits)
 {
+  // clang-format off
   if      ( tunits == TUNIT_YEAR )       return ("years");
   else if ( tunits == TUNIT_MONTH )      return ("months");
   else if ( tunits == TUNIT_DAY )        return ("days");
@@ -44,17 +45,21 @@ const char *tunit2str(int tunits)
   else if ( tunits == TUNIT_MINUTE )     return ("minutes");
   else if ( tunits == TUNIT_SECOND )     return ("seconds");
   else                                   return ("unknown");
+  // clang-format on
 }
 
 
 const char *calendar2str(int calendar)
 {
+  // clang-format off
   if      ( calendar == CALENDAR_STANDARD )  return ("standard");
+  else if ( calendar == CALENDAR_GREGORIAN ) return ("gregorian");
   else if ( calendar == CALENDAR_PROLEPTIC ) return ("proleptic_gregorian");
   else if ( calendar == CALENDAR_360DAYS )   return ("360_day");
   else if ( calendar == CALENDAR_365DAYS )   return ("365_day");
   else if ( calendar == CALENDAR_366DAYS )   return ("366_day");
   else                                       return ("unknown");
+  // clang-format on
 }
 
 static
@@ -105,7 +110,6 @@ void *Sinfo(void *argument)
   for ( int indf = 0; indf < cdoStreamCnt(); indf++ )
     {
       int streamID = pstreamOpenRead(cdoStreamName(indf));
-
       int vlistID = pstreamInqVlist(streamID);
 
       set_text_color(stdout, BRIGHT, BLACK);
@@ -119,11 +123,11 @@ void *Sinfo(void *argument)
 
       set_text_color(stdout, BRIGHT, BLACK);
       if ( lensemble )
-	fprintf(stdout, "%6d : Institut Source   Steptype Einfo Levels Num    Points Num Dtype : ",  -(indf+1));
+	fprintf(stdout, "%6d : Institut Source   T Steptype Einfo Levels Num    Points Num Dtype : ",  -(indf+1));
       else if ( nsubtypes > 1 )
-	fprintf(stdout, "%6d : Institut Source   Steptype Subtypes Levels Num    Points Num Dtype : ",  -(indf+1));
+	fprintf(stdout, "%6d : Institut Source   T Steptype Subtypes Levels Num    Points Num Dtype : ",  -(indf+1));
       else
-	fprintf(stdout, "%6d : Institut Source   Steptype Levels Num    Points Num Dtype : ",  -(indf+1));
+	fprintf(stdout, "%6d : Institut Source   T Steptype Levels Num    Points Num Dtype : ",  -(indf+1));
 
       if      ( operfunc == func_name ) fprintf(stdout, "Parameter name");
       else if ( operfunc == func_code ) fprintf(stdout, "Table Code");
@@ -149,24 +153,28 @@ void *Sinfo(void *argument)
 	  reset_text_color(stdout);
 	      
 	  set_text_color(stdout, RESET, BLUE);
-	  /* institute info */
+	  // institute info
 	  const char *instptr = institutInqNamePtr(vlistInqVarInstitut(vlistID, varID));
 	  strcpy(tmpname, "unknown");
 	  if ( instptr ) strncpy(tmpname, instptr, CDI_MAX_NAME);
 	  limit_string_length(tmpname, CDI_MAX_NAME);
 	  fprintf(stdout, "%-8s ", tmpname);
 
-	  /* source info */
+	  // source info
 	  const char *modelptr = modelInqNamePtr(vlistInqVarModel(vlistID, varID));
 	  strcpy(tmpname, "unknown");
 	  if ( modelptr ) strncpy(tmpname, modelptr, CDI_MAX_NAME);
 	  limit_string_length(tmpname, CDI_MAX_NAME);
 	  fprintf(stdout, "%-8s ", tmpname);
 
-	  /* tsteptype */
+          // timetype
+          int timetype = vlistInqVarTimetype(vlistID, varID);
+          fprintf(stdout, "%c ", timetype==TIME_CONSTANT ? 'c' : 'v');
+               
+	  // tsteptype
 	  int tsteptype = vlistInqVarTsteptype(vlistID, varID);
-	  if      ( tsteptype == TSTEP_CONSTANT ) fprintf(stdout, "%-8s ", "constant");
-	  else if ( tsteptype == TSTEP_INSTANT  ) fprintf(stdout, "%-8s ", "instant");
+          // clang-format off
+	  if      ( tsteptype == TSTEP_INSTANT  ) fprintf(stdout, "%-8s ", "instant");
 	  else if ( tsteptype == TSTEP_INSTANT2 ) fprintf(stdout, "%-8s ", "instant");
 	  else if ( tsteptype == TSTEP_INSTANT3 ) fprintf(stdout, "%-8s ", "instant");
 	  else if ( tsteptype == TSTEP_MIN      ) fprintf(stdout, "%-8s ", "min");
@@ -176,6 +184,7 @@ void *Sinfo(void *argument)
 	  else if ( tsteptype == TSTEP_RANGE    ) fprintf(stdout, "%-8s ", "range");
 	  else if ( tsteptype == TSTEP_DIFF     ) fprintf(stdout, "%-8s ", "diff");
 	  else                                    fprintf(stdout, "%-8s ", "unknown");
+          // clang-format on
 
 	  /* ensemble information */
 	  if ( lensemble )
diff --git a/src/Smooth.cc b/src/Smooth.cc
index f19a158..da71c1e 100644
--- a/src/Smooth.cc
+++ b/src/Smooth.cc
@@ -46,19 +46,19 @@ typedef struct {
 
 double intlin(double x, double y1, double x1, double y2, double x2);
 
-double smooth_knn_compute_weights(unsigned num_neighbors, const bool *restrict src_grid_mask, struct gsknn *knn, double search_radius, double weight0, double weightR)
+double smooth_knn_compute_weights(size_t num_neighbors, const bool *restrict src_grid_mask, struct gsknn *knn, double search_radius, double weight0, double weightR)
 {
   bool *restrict nbr_mask = knn->mask;
-  const int *restrict nbr_add = knn->add;
+  const size_t *restrict nbr_add = knn->add;
   double *restrict nbr_dist = knn->dist;
 
   // Compute weights based on inverse distance if mask is false, eliminate those points
   double dist_tot = 0.; // sum of neighbor distances (for normalizing)
 
-  for ( unsigned n = 0; n < num_neighbors; ++n )
+  for ( size_t n = 0; n < num_neighbors; ++n )
     {
       nbr_mask[n] = false;
-      if ( nbr_add[n] >= 0 && src_grid_mask[nbr_add[n]] )
+      if ( nbr_add[n] < ULONG_MAX && src_grid_mask[nbr_add[n]] )
         {
           nbr_dist[n] = intlin(nbr_dist[n], weight0, 0, weightR, search_radius);
           dist_tot += nbr_dist[n];
@@ -70,16 +70,16 @@ double smooth_knn_compute_weights(unsigned num_neighbors, const bool *restrict s
 }
 
 
-unsigned smooth_knn_normalize_weights(unsigned num_neighbors, double dist_tot, struct gsknn *knn)
+size_t smooth_knn_normalize_weights(unsigned num_neighbors, double dist_tot, struct gsknn *knn)
 {
   const bool *restrict nbr_mask = knn->mask;
-  int *restrict nbr_add = knn->add;
+  size_t *restrict nbr_add = knn->add;
   double *restrict nbr_dist = knn->dist;
 
   // Normalize weights and store the link
   unsigned nadds = 0;
 
-  for ( unsigned n = 0; n < num_neighbors; ++n )
+  for ( size_t n = 0; n < num_neighbors; ++n )
     {
       if ( nbr_mask[n] )
         {
@@ -97,12 +97,12 @@ void smooth(int gridID, double missval, const double *restrict array1, double *r
 {
   *nmiss = 0;
   int gridID0 = gridID;
-  unsigned gridsize = gridInqSize(gridID);
-  unsigned num_neighbors = spoint.maxpoints;
+  size_t gridsize = gridInqSize(gridID);
+  size_t num_neighbors = spoint.maxpoints;
   if ( num_neighbors > gridsize ) num_neighbors = gridsize;
 
   bool *mask = (bool*) Malloc(gridsize*sizeof(bool));
-  for ( unsigned i = 0; i < gridsize; ++i )
+  for ( size_t i = 0; i < gridsize; ++i )
     mask[i] = !DBL_IS_EQUAL(array1[i], missval);
   
   double *xvals = (double*) Malloc(gridsize*sizeof(double));
@@ -153,7 +153,7 @@ void smooth(int gridID, double missval, const double *restrict array1, double *r
 #if defined(_OPENMP)
 #pragma omp parallel for schedule(dynamic) default(none) shared(cdoVerbose, knn, spoint, findex, mask, array1, array2, xvals, yvals, gs, gridsize, nmiss, missval)
 #endif
-  for ( unsigned i = 0; i < gridsize; ++i )
+  for ( size_t i = 0; i < gridsize; ++i )
     {
       int ompthID = cdo_omp_get_thread_num();
       
@@ -163,7 +163,7 @@ void smooth(int gridID, double missval, const double *restrict array1, double *r
       findex++;
       if ( cdoVerbose && cdo_omp_get_thread_num() == 0 ) progressStatus(0, 1, findex/gridsize);
      
-      unsigned nadds = gridsearch_knn(gs, knn[ompthID], xvals[i], yvals[i]);
+      size_t nadds = gridsearch_knn(gs, knn[ompthID], xvals[i], yvals[i]);
 
       // Compute weights based on inverse distance if mask is false, eliminate those points
       double dist_tot = smooth_knn_compute_weights(nadds, mask, knn[ompthID], spoint.radius, spoint.weight0, spoint.weightR);
@@ -172,7 +172,7 @@ void smooth(int gridID, double missval, const double *restrict array1, double *r
       nadds = smooth_knn_normalize_weights(nadds, dist_tot, knn[ompthID]);
       if ( nadds )
         {
-          const int *restrict nbr_add = knn[ompthID]->add;
+          const size_t *restrict nbr_add = knn[ompthID]->add;
           const double *restrict nbr_dist = knn[ompthID]->dist;
           /*
           printf("n %u %d nadds %u dis %g\n", i, nbr_add[0], nadds, nbr_dist[0]);
@@ -180,7 +180,7 @@ void smooth(int gridID, double missval, const double *restrict array1, double *r
             printf("   n %u add %d dis %g\n", n, nbr_add[n], nbr_dist[n]);
           */
           double result = 0;
-          for ( unsigned n = 0; n < nadds; ++n ) result += array1[nbr_add[n]]*nbr_dist[n];
+          for ( size_t n = 0; n < nadds; ++n ) result += array1[nbr_add[n]]*nbr_dist[n];
           array2[i] = result;
         }
       else
diff --git a/src/Sort.cc b/src/Sort.cc
index 89477bb..b073ad6 100644
--- a/src/Sort.cc
+++ b/src/Sort.cc
@@ -290,7 +290,7 @@ void *Sort(void *argument)
 	      levelID = varInfo[vindex].levInfo[lindex].levelID;
 	      nmiss   = varInfo[vindex].levInfo[lindex].nmiss;
 
-	      if ( tsID == 0 || vlistInqVarTsteptype(vlistID1, varID) != TSTEP_CONSTANT )
+	      if ( tsID == 0 || vlistInqVarTimetype(vlistID1, varID) != TIME_CONSTANT )
 		{
 		  gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
 		  offset   = gridsize*levelID;
diff --git a/src/Split.cc b/src/Split.cc
index b068487..337c1c1 100644
--- a/src/Split.cc
+++ b/src/Split.cc
@@ -61,7 +61,7 @@ void *Split(void *argument)
 
   cdoInitialize(argument);
 
-  if ( processSelf() != 0 ) cdoAbort("This operator can't be combined with other operators!");
+  if ( processSelf().m_ID != 0 ) cdoAbort("This operator can't be combined with other operators!");
 
   bool lcopy = UNCHANGED_RECORD;
 
diff --git a/src/Splitrec.cc b/src/Splitrec.cc
index 9ff6a4b..044a3d4 100644
--- a/src/Splitrec.cc
+++ b/src/Splitrec.cc
@@ -40,7 +40,7 @@ void *Splitrec(void *argument)
 
   cdoInitialize(argument);
 
-  if ( processSelf() != 0 ) cdoAbort("This operator can't be combined with other operators!");
+  if ( processSelf().m_ID != 0 ) cdoAbort("This operator can't be combined with other operators!");
 
   bool lcopy = UNCHANGED_RECORD;
 
diff --git a/src/Splitsel.cc b/src/Splitsel.cc
index df7cedb..7b579fb 100644
--- a/src/Splitsel.cc
+++ b/src/Splitsel.cc
@@ -48,7 +48,7 @@ void *Splitsel(void *argument)
 
   cdoInitialize(argument);
 
-  if ( processSelf() != 0 ) cdoAbort("This operator can't be combined with other operators!");
+  if ( processSelf().m_ID != 0 ) cdoAbort("This operator can't be combined with other operators!");
 
   bool lcopy = UNCHANGED_RECORD;
 
@@ -98,7 +98,7 @@ void *Splitsel(void *argument)
   int nvars = vlistNvars(vlistID1);
   int nconst = 0;
   for ( varID = 0; varID < nvars; varID++ )
-    if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) nconst++;
+    if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) nconst++;
 
   if ( nconst )
     {
@@ -106,7 +106,7 @@ void *Splitsel(void *argument)
 
       for ( varID = 0; varID < nvars; varID++ )
 	{
-	  if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT )
+	  if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT )
 	    {
 	      gridID  = vlistInqVarGrid(vlistID1, varID);
 	      nlevel  = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
@@ -141,7 +141,7 @@ void *Splitsel(void *argument)
 	for ( int recID = 0; recID < nrecs; recID++ )
 	  {
 	    pstreamInqRecord(streamID1, &varID, &levelID);
-	    if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT )
+	    if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT )
               {
                 pstreamReadRecord(streamID1, vars[varID][levelID].ptr, &nmiss);
                 vars[varID][levelID].nmiss = (size_t) nmiss;
@@ -175,7 +175,7 @@ void *Splitsel(void *argument)
 	    {
 	      for ( varID = 0; varID < nvars; varID++ )
 		{
-		  if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT )
+		  if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT )
 		    {
 		      nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
 		      for ( levelID = 0; levelID < nlevel; levelID++ )
@@ -204,7 +204,7 @@ void *Splitsel(void *argument)
 
 		  if ( tsID == 0 && nconst )
 		    {
-		      if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT )
+		      if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT )
 			{
 			  gridID  = vlistInqVarGrid(vlistID1, varID);
 			  gridsize = gridInqSize(gridID);
@@ -248,7 +248,7 @@ void *Splitsel(void *argument)
     {
       for ( varID = 0; varID < nvars; varID++ )
 	{
-	  if ( vlistInqVarTsteptype(vlistID2, varID) == TSTEP_CONSTANT )
+	  if ( vlistInqVarTimetype(vlistID2, varID) == TIME_CONSTANT )
 	    {
 	      nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
 	      for ( levelID = 0; levelID < nlevel; levelID++ )
diff --git a/src/Splittime.cc b/src/Splittime.cc
index b2bcc80..3aedb5c 100644
--- a/src/Splittime.cc
+++ b/src/Splittime.cc
@@ -73,7 +73,7 @@ void *Splittime(void *argument)
 
   cdoInitialize(argument);
 
-  if ( processSelf() != 0 ) cdoAbort("This operator can't be combined with other operators!");
+  if ( processSelf().m_ID != 0 ) cdoAbort("This operator can't be combined with other operators!");
 
   bool lcopy = UNCHANGED_RECORD;
 
@@ -128,7 +128,7 @@ void *Splittime(void *argument)
   int nvars = vlistNvars(vlistID1);
   int nconst = 0;
   for ( varID = 0; varID < nvars; varID++ )
-    if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) nconst++;
+    if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) nconst++;
 
   if ( nconst )
     {
@@ -136,7 +136,7 @@ void *Splittime(void *argument)
 
       for ( varID = 0; varID < nvars; varID++ )
 	{
-	  if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT )
+	  if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT )
 	    {
 	      gridID  = vlistInqVarGrid(vlistID1, varID);
 	      nlevel  = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
@@ -222,7 +222,7 @@ void *Splittime(void *argument)
 	{
 	  for ( varID = 0; varID < nvars; varID++ )
 	    {
-	      if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT )
+	      if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT )
 		{
 		  nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
 		  for ( levelID = 0; levelID < nlevel; levelID++ )
@@ -251,7 +251,7 @@ void *Splittime(void *argument)
 
 	      if ( tsID == 0 && nconst )
 		{
-		  if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT )
+		  if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT )
 		    {
 		      gridID  = vlistInqVarGrid(vlistID1, varID);
 		      gridsize = gridInqSize(gridID);
@@ -274,7 +274,7 @@ void *Splittime(void *argument)
     {
       for ( varID = 0; varID < nvars; varID++ )
 	{
-	  if ( vlistInqVarTsteptype(vlistID2, varID) == TSTEP_CONSTANT )
+	  if ( vlistInqVarTimetype(vlistID2, varID) == TIME_CONSTANT )
 	    {
 	      nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
 	      for ( levelID = 0; levelID < nlevel; levelID++ )
diff --git a/src/Splityear.cc b/src/Splityear.cc
index 7b7c710..47d28a2 100644
--- a/src/Splityear.cc
+++ b/src/Splityear.cc
@@ -54,7 +54,7 @@ void *Splityear(void *argument)
 
   cdoInitialize(argument);
 
-  if ( processSelf() != 0 ) cdoAbort("This operator can't be combined with other operators!");
+  if ( processSelf().m_ID != 0 ) cdoAbort("This operator can't be combined with other operators!");
   
   bool lcopy = UNCHANGED_RECORD;
 
@@ -94,7 +94,7 @@ void *Splityear(void *argument)
   int nvars = vlistNvars(vlistID1);
   int nconst = 0;
   for ( varID = 0; varID < nvars; varID++ )
-    if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) nconst++;
+    if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) nconst++;
 
   if ( nconst )
     {
@@ -102,7 +102,7 @@ void *Splityear(void *argument)
 
       for ( varID = 0; varID < nvars; varID++ )
 	{
-	  if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT )
+	  if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT )
 	    {
 	      gridID  = vlistInqVarGrid(vlistID1, varID);
 	      nlevel  = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
@@ -199,7 +199,7 @@ void *Splityear(void *argument)
 	{
 	  for ( varID = 0; varID < nvars; varID++ )
 	    {
-	      if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT )
+	      if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT )
 		{
 		  nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
 		  for ( levelID = 0; levelID < nlevel; levelID++ )
@@ -228,7 +228,7 @@ void *Splityear(void *argument)
 
 	      if ( tsID == 0 && nconst )
 		{
-		  if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT )
+		  if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT )
 		    {
 		      gridID  = vlistInqVarGrid(vlistID1, varID);
 		      gridsize = gridInqSize(gridID);
@@ -252,7 +252,7 @@ void *Splityear(void *argument)
     {
       for ( varID = 0; varID < nvars; varID++ )
 	{
-	  if ( vlistInqVarTsteptype(vlistID2, varID) == TSTEP_CONSTANT )
+	  if ( vlistInqVarTimetype(vlistID2, varID) == TIME_CONSTANT )
 	    {
 	      nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
 	      for ( levelID = 0; levelID < nlevel; levelID++ )
diff --git a/src/Timcount.cc b/src/Timcount.cc
index 2feb50f..f4f6c53 100644
--- a/src/Timcount.cc
+++ b/src/Timcount.cc
@@ -146,7 +146,7 @@ void *Timcount(void *argument)
 	  varID   = recVarID[recID];
 	  levelID = recLevelID[recID];
 
-	  if ( otsID && vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+	  if ( otsID && vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
 
 	  pstreamDefRecord(streamID2, varID, levelID);
 	  pstreamWriteRecord(streamID2, vars1[varID][levelID].ptr,  (int)vars1[varID][levelID].nmiss);
diff --git a/src/Timpctl.cc b/src/Timpctl.cc
index 1099c24..75139bb 100644
--- a/src/Timpctl.cc
+++ b/src/Timpctl.cc
@@ -69,6 +69,7 @@ void timpctl(int operatorID)
   /* TODO - check that time axes 2 and 3 are equal */
 
   int taxisID4 = taxisDuplicate(taxisID1);
+  taxisWithBounds(taxisID4);
   vlistDefTaxis(vlistID4, taxisID4);
 
   int streamID4 = pstreamOpenWrite(cdoStreamName(3), cdoFiletype());
@@ -168,7 +169,7 @@ void timpctl(int operatorID)
       
       for ( varID = 0; varID < nvars; varID++ )
 	{
-	  if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+	  if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
 	  nlevels = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
 	  
 	  for ( levelID = 0; levelID < nlevels; levelID++ )
@@ -183,7 +184,7 @@ void timpctl(int operatorID)
 	  varID   = recVarID[recID];
 	  levelID = recLevelID[recID];
 
-	  if ( otsID && vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+	  if ( otsID && vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
 
 	  pstreamDefRecord(streamID4, varID, levelID);
 	  pstreamWriteRecord(streamID4, vars1[varID][levelID].ptr, vars1[varID][levelID].nmiss);
diff --git a/src/Timselpctl.cc b/src/Timselpctl.cc
index dfbb9a3..3bc179d 100644
--- a/src/Timselpctl.cc
+++ b/src/Timselpctl.cc
@@ -74,6 +74,7 @@ void *Timselpctl(void *argument)
   /* TODO - check that time axes 2 and 3 are equal */
 
   int taxisID4 = taxisDuplicate(taxisID1);
+  taxisWithBounds(taxisID4);
   vlistDefTaxis(vlistID4, taxisID4);
 
   int streamID4 = pstreamOpenWrite(cdoStreamName(3), cdoFiletype());
@@ -193,7 +194,7 @@ void *Timselpctl(void *argument)
 
       for ( varID = 0; varID < nvars; varID++ )
         {
-          if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+          if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
           nlevels = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
           
           for ( levelID = 0; levelID < nlevels; levelID++ )
@@ -208,7 +209,7 @@ void *Timselpctl(void *argument)
 	  varID   = recVarID[recID];
 	  levelID = recLevelID[recID];
 
-	  if ( otsID && vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+	  if ( otsID && vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
 
 	  pstreamDefRecord(streamID4, varID, levelID);
 	  pstreamWriteRecord(streamID4, vars1[varID][levelID].ptr,  vars1[varID][levelID].nmiss);
diff --git a/src/Timselstat.cc b/src/Timselstat.cc
index 6c2a857..e75a05c 100644
--- a/src/Timselstat.cc
+++ b/src/Timselstat.cc
@@ -86,6 +86,7 @@ void *Timselstat(void *argument)
 
   int taxisID1 = vlistInqTaxis(vlistID1);
   int taxisID2 = taxisDuplicate(taxisID1);
+  taxisWithBounds(taxisID2);
   vlistDefTaxis(vlistID2, taxisID2);
 
   int streamID2 = pstreamOpenWrite(cdoStreamName(1), cdoFiletype());
@@ -122,7 +123,7 @@ void *Timselstat(void *argument)
 	    {
               recinfo[recID].varID   = varID;
               recinfo[recID].levelID = levelID;
-              recinfo[recID].lconst  = vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT;
+              recinfo[recID].lconst  = vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT;
 	    }
 	}
     }
@@ -151,7 +152,7 @@ void *Timselstat(void *argument)
 		{
                   recinfo[recID].varID   = varID;
                   recinfo[recID].levelID = levelID;
-                  recinfo[recID].lconst  = vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT;
+                  recinfo[recID].lconst  = vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT;
 		}
 
               field_type *psamp1 = &samp1[varID][levelID];
diff --git a/src/Timsort.cc b/src/Timsort.cc
index 12a3ad7..0a7fe15 100644
--- a/src/Timsort.cc
+++ b/src/Timsort.cc
@@ -108,7 +108,7 @@ void *Timsort(void *argument)
 
   for ( varID = 0; varID < nvars; varID++ )
     {
-      if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+      if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
 
       gridID   = vlistInqVarGrid(vlistID1, varID);
       gridsize = gridInqSize(gridID);
diff --git a/src/Timstat.cc b/src/Timstat.cc
index db428cd..76206ad 100644
--- a/src/Timstat.cc
+++ b/src/Timstat.cc
@@ -184,15 +184,12 @@ void *Timstat(void *argument)
 
   int taxisID1 = vlistInqTaxis(vlistID1);
   int taxisID2 = taxisDuplicate(taxisID1);
+  taxisWithBounds(taxisID2);
   if ( taxisInqType(taxisID2) == TAXIS_FORECAST ) taxisDefType(taxisID2, TAXIS_RELATIVE);
   vlistDefTaxis(vlistID2, taxisID2);
 
   int nvars   = vlistNvars(vlistID1);
 
-  if ( cmplen == 0 && CDO_Reduce_Dim )
-    for ( varID = 0; varID < nvars; ++varID )
-      vlistDefVarTsteptype(vlistID2, varID, TSTEP_CONSTANT);
-
   const char *freq = NULL;
   if      ( comparelen == DAY_LEN )  freq = "day";
   else if ( comparelen == MON_LEN )  freq = "mon";
@@ -225,6 +222,7 @@ void *Timstat(void *argument)
 	}
 
       taxisID3 = taxisDuplicate(taxisID1);
+      taxisWithBounds(taxisID3);
       vlistDefTaxis(vlistID3, taxisID3);
 
       pstreamDefVlist(streamID3, vlistID3);
@@ -280,7 +278,7 @@ void *Timstat(void *argument)
 		{
                   recinfo[recID].varID   = varID;
                   recinfo[recID].levelID = levelID;
-                  recinfo[recID].lconst  = vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT;
+                  recinfo[recID].lconst  = vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT;
 		}
 
               field_type *psamp1 = &samp1[varID][levelID];
diff --git a/src/Trend.cc b/src/Trend.cc
index b3f743e..0e10ba8 100644
--- a/src/Trend.cc
+++ b/src/Trend.cc
@@ -99,9 +99,9 @@ void *Trend(void *argument)
 
 	  double missval  = vlistInqVarMissval(vlistID1, varID);
 	  int gridID   = vlistInqVarGrid(vlistID1, varID);
-	  int gridsize = gridInqSize(gridID);
+	  size_t gridsize = gridInqSize(gridID);
 
-	  for ( int i = 0; i < gridsize; i++ )
+	  for ( size_t i = 0; i < gridsize; i++ )
 	    if ( !DBL_IS_EQUAL(field1.ptr[i], missval) )
 	      {
 		work[0][varID][levelID].ptr[i] += zj;
@@ -128,12 +128,12 @@ void *Trend(void *argument)
 
       double missval  = vlistInqVarMissval(vlistID1, varID);
       int gridID   = vlistInqVarGrid(vlistID1, varID);
-      int gridsize = gridInqSize(gridID);
+      size_t gridsize = gridInqSize(gridID);
 
       double missval1  = missval;
       double missval2  = missval;
 
-      for ( int i = 0; i < gridsize; i++ )
+      for ( size_t i = 0; i < gridsize; i++ )
 	{
 	  temp1 = SUBMN(work[2][varID][levelID].ptr[i],
 		      DIVMN( MULMN(work[0][varID][levelID].ptr[i], work[3][varID][levelID].ptr[i]), work[4][varID][levelID].ptr[i]));
@@ -146,14 +146,14 @@ void *Trend(void *argument)
 	}
 
       nmiss = 0;
-      for ( int i = 0; i < gridsize; i++ )
+      for ( size_t i = 0; i < gridsize; i++ )
 	if ( DBL_IS_EQUAL(field1.ptr[i], missval) ) nmiss++;
 
       pstreamDefRecord(streamID2, varID, levelID);
       pstreamWriteRecord(streamID2, field1.ptr, nmiss);
 
       nmiss = 0;
-      for ( int i = 0; i < gridsize; i++ )
+      for ( size_t i = 0; i < gridsize; i++ )
 	if ( DBL_IS_EQUAL(field2.ptr[i], missval) ) nmiss++;
 
       pstreamDefRecord(streamID3, varID, levelID);
diff --git a/src/Vargen.cc b/src/Vargen.cc
index 4d79bd4..d72c0d5 100644
--- a/src/Vargen.cc
+++ b/src/Vargen.cc
@@ -358,17 +358,16 @@ void *Vargen(void *argument)
 
   int vlistID = vlistCreate();
 
-  int tsteptype = TSTEP_CONSTANT;
-  if ( operatorID == FOR ) tsteptype = TSTEP_INSTANT;
+  int timetype = (operatorID == FOR) ? TIME_VARYING : TIME_CONSTANT;
 
-  varID = vlistDefVar(vlistID, gridID, zaxisID, tsteptype);
+  varID = vlistDefVar(vlistID, gridID, zaxisID, timetype);
   /*
      For the standard atmosphere two output variables are generated: pressure and
      temperatur. The first (varID) is pressure, second (varID2) is temperatur.
      Add an additional variable for the standard atmosphere.
    */
   if ( operatorID == STDATM )
-    varID2 = vlistDefVar(vlistID, gridID, zaxisID, TSTEP_CONSTANT);
+    varID2 = vlistDefVar(vlistID, gridID, zaxisID, TIME_CONSTANT);
 
   if ( operatorID == MASK )
     vlistDefVarDatatype(vlistID, varID, CDI_DATATYPE_INT8);
diff --git a/src/Verifygrid.cc b/src/Verifygrid.cc
index a2103ab..c56142f 100644
--- a/src/Verifygrid.cc
+++ b/src/Verifygrid.cc
@@ -154,7 +154,7 @@ void find_unit_normal(double a[3], double b[3], double c[3], double *unit_normal
   unit_normal[2] = z / magnitude;
 }
 
-static
+
 int find_coordinate_to_ignore(double *cell_corners_xyz)
 {
   double corner_coordinates[3];
@@ -236,7 +236,7 @@ double is_point_left_of_edge(double point_on_line_1[2], double point_on_line_2[2
   return answer;
 }
 
-static
+
 int winding_numbers_algorithm(double cell_corners[], int number_corners, double point[])
 {  
   /* 
@@ -313,7 +313,6 @@ bool is_simple_polygon_convex(double cell_corners[], int number_corners)
 }
 
 
-static
 double calculate_the_polygon_area(double cell_corners[], int number_corners)
 {
   /* This algorithm is based on the calculation from Wolfram Mathworld Polygon Area. It results in the area of planar non-self-intersecting polygon. */
@@ -326,7 +325,7 @@ double calculate_the_polygon_area(double cell_corners[], int number_corners)
   return twice_the_polygon_area / 2;
 }
 
-static
+
 bool are_polygon_vertices_arranged_in_clockwise_order(double cell_area)
 {
   bool status = false;
@@ -616,7 +615,7 @@ void verify_grid(int gridtype, int gridsize, int gridno, int ngrids, int ncorner
 
       double polygon_area = calculate_the_polygon_area(cell_corners_plane_projection, actual_number_of_corners + 1);
       bool is_clockwise = are_polygon_vertices_arranged_in_clockwise_order(polygon_area);
-            
+
       /* If the direction of the vertices was flipped during the projection onto the two-dimensional plane, the previous result needs to be inverted now. */
 
       if ( invert_result ) is_clockwise = !is_clockwise;
diff --git a/src/Vertcum.cc b/src/Vertcum.cc
index fba71d5..f8d7696 100644
--- a/src/Vertcum.cc
+++ b/src/Vertcum.cc
@@ -114,7 +114,7 @@ void *Vertcum(void *argument)
                       zaxisDefVct(zaxisIDhl, nvct, vct);
                       vlistChangeZaxisIndex(vlistID2, i, zaxisIDhl);
                     }
-                  else
+                  else if ( vct )
                     {
                       if ( memcmp(vct, zaxisInqVctPtr(zaxisID), nvct*sizeof(double)) == 0 )
                         vlistChangeZaxisIndex(vlistID2, i, zaxisIDhl);
diff --git a/src/Vertintap.cc b/src/Vertintap.cc
index 5927ee8..0145f90 100644
--- a/src/Vertintap.cc
+++ b/src/Vertintap.cc
@@ -48,39 +48,37 @@ bool is_height_axis(int zaxisID, int nlevel)
     }
   return isheight;
 }
-/*
+
 static
-int is_hybrid_axis(int zaxisID, int nlevel)
+void change_height_zaxis(int vlistID1, int vlistID2, int zaxisID2)
 {
-  int ishybrid = FALSE;
-  if ( (zaxisInqType(zaxisID) == ZAXIS_HYBRID || zaxisInqType(zaxisID) == ZAXIS_HYBRID_HALF) &&
-       nlevel > 1 ) ishybrid = TRUE;
-  return ishybrid;
+  int nzaxis = vlistNzaxis(vlistID1);
+  for ( int iz = 0; iz < nzaxis; ++iz )
+    {
+      int zaxisID = vlistZaxis(vlistID1, iz);
+      int nlevel  = zaxisInqSize(zaxisID);
+
+      if ( is_height_axis(zaxisID, nlevel) && nlevel > 1 )
+	{
+          vlistChangeZaxisIndex(vlistID2, iz, zaxisID2);
+	}
+    }
 }
-*/
+
 
 void *Vertintap(void *argument)
 {
   enum {func_pl, func_hl};
   enum {type_lin, type_log};
   int nrecs;
-  int i, k, offset;
   int varID, levelID;
-  int zaxisIDp, zaxisIDh = -1;
+  int zaxisIDh = -1;
   int nhlev = 0, nhlevf = 0, nhlevh = 0, nlevel;
-  int *vert_index = NULL;
   int apressID = -1, dpressID = -1;
   int psID = -1, tempID = -1;
   //int sortlevels = TRUE;
-  int *pnmiss = NULL;
-  char paramstr[32];
-  char stdname[CDI_MAX_NAME];
-  char varname[CDI_MAX_NAME];
-  double *vct = NULL;
-  double *single1, *single2;
-  double *ps_prog = NULL, *full_press = NULL, *dpress = NULL;
-  double *hyb_press = NULL;
-  int Extrapolate = 0;
+  char varname[CDI_MAX_NAME], stdname[CDI_MAX_NAME];
+  bool extrapolate = false;
   lista_t *flista = lista_new(FLT_LISTA);
 
   cdoInitialize(argument);
@@ -104,14 +102,14 @@ void *Vertintap(void *argument)
 
       if ( envstr && isdigit((int) envstr[0]) )
 	{
-          Extrapolate = atoi(envstr);
-          if ( Extrapolate == 1 )
+          if ( atoi(envstr) == 1 ) extrapolate = true;
+          if ( extrapolate )
             cdoPrint("Extrapolation of missing values enabled!");
 	}
     }
   else if ( operatorID == AP2PLX ||  operatorID == AP2HLX || operatorID == AP2PLX_LP )
     {
-      Extrapolate = 1;
+      extrapolate = true;
     }
 
   operatorInputArg(cdoOperatorEnter(operatorID));
@@ -125,19 +123,15 @@ void *Vertintap(void *argument)
           double stdlev[] = { 10, 50, 100, 500, 1000, 5000, 10000, 15000, 20000, 25000, 30000 };
           nplev = sizeof(stdlev)/sizeof(*stdlev);
           plev  = (double *) Malloc(nplev*sizeof(double));
-          for ( i = 0; i < nplev; ++i ) plev[i] = stdlev[i];
+          for ( int i = 0; i < nplev; ++i ) plev[i] = stdlev[i];
         }
       else
         {
-          /*
-            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};
-          */
           double stdlev[] = {100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000,
                              10000,  7000,  5000,  3000,  2000, 1000 };
           nplev = sizeof(stdlev)/sizeof(*stdlev);
           plev  = (double *) Malloc(nplev*sizeof(double));
-          for ( i = 0; i < nplev; ++i ) plev[i] = stdlev[i];
+          for ( int i = 0; i < nplev; ++i ) plev[i] = stdlev[i];
         }
     }
   else
@@ -157,11 +151,8 @@ void *Vertintap(void *argument)
 
   int gridsize = vlist_check_gridsize(vlistID1);
 
-  if ( operfunc == func_hl )
-    zaxisIDp = zaxisCreate(ZAXIS_HEIGHT, nplev);
-  else
-    zaxisIDp = zaxisCreate(ZAXIS_PRESSURE, nplev);
-
+  int zaxistype = (operfunc == func_hl) ? ZAXIS_HEIGHT : ZAXIS_PRESSURE;
+  int zaxisIDp = zaxisCreate(zaxistype, nplev);
   zaxisDefLevels(zaxisIDp, plev);
 
   int nvars = vlistNvars(vlistID1);
@@ -195,7 +186,7 @@ void *Vertintap(void *argument)
       if ( zaxisID == vlistInqVarZaxis(vlistID1, apressID) )
         {
           bool mono_level = true;
-          nlevel  = zaxisInqSize(zaxisID);
+          nlevel = zaxisInqSize(zaxisID);
 
           if ( is_height_axis(zaxisID, nlevel) )
             {
@@ -217,30 +208,30 @@ void *Vertintap(void *argument)
               nhlevf   = nhlev;
               nhlevh   = nhlevf + 1;
 
-              vlistChangeZaxisIndex(vlistID2, i, zaxisIDp);
               break;
             }
         }
     }
+
+  change_height_zaxis(vlistID1, vlistID2, zaxisIDp);
   
-  bool *vars = (bool*) Malloc(nvars*sizeof(bool));
-  bool *varinterp = (bool*) Malloc(nvars*sizeof(bool));
-  double **vardata1 = (double**) Malloc(nvars*sizeof(double*));
-  double **vardata2 = (double**) Malloc(nvars*sizeof(double*));
-  int **varnmiss = (int**) Malloc(nvars*sizeof(int*));
+  std::vector<bool> vars(nvars);
+  std::vector<bool> varinterp(nvars);
+  std::vector<int *> varnmiss(nvars);
+  std::vector<double *> vardata1(nvars);
+  std::vector<double *> vardata2(nvars);
 
   int maxlev = nhlevh > nplev ? nhlevh : nplev;
 
-  if ( Extrapolate == 0 )
-    pnmiss = (int *) Malloc(nplev*sizeof(int));
+  int *pnmiss = extrapolate ? NULL : (int *) Malloc(nplev*sizeof(int));
 
   // check levels
   if ( zaxisIDh != -1 )
     {
       int nlev = zaxisInqSize(zaxisIDh);
       if ( nlev != nhlev ) cdoAbort("Internal error, wrong number of height level!");
-      double *levels = (double*) Malloc(nlev*sizeof(double));
-      zaxisInqLevels(zaxisIDh, levels);
+      std::vector<double> levels(nlev);
+      cdoZaxisInqLevels(zaxisIDh, levels.data());
 
       for ( int ilev = 0; ilev < nlev; ++ilev )
 	{
@@ -250,35 +241,34 @@ void *Vertintap(void *argument)
 	      break;
 	    }
 	}
-
-      Free(levels);
     }
 
+  int *vert_index = NULL;
+  double *ps_prog = NULL, *full_press = NULL, *half_press = NULL;
   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));
+      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 generalized height level found!");
 
   if ( operfunc == func_hl )
     {
-      double *phlev =(double*) Malloc(nplev*sizeof(double));
-      height2pressure(phlev, plev, nplev);
+      std::vector<double> phlev(nplev);
+      height2pressure(phlev.data(), plev, nplev);
 
       if ( cdoVerbose )
 	for ( int 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);
+      memcpy(plev, phlev.data(), nplev*sizeof(double));
     }
 
   if ( opertype == type_log )
-    for ( k = 0; k < nplev; k++ ) plev[k] = log(plev[k]);
+    for ( int k = 0; k < nplev; k++ ) plev[k] = log(plev[k]);
 
   for ( varID = 0; varID < nvars; varID++ )
     {
@@ -291,7 +281,8 @@ void *Vertintap(void *argument)
 
       vardata1[varID] = (double *) Malloc(gridsize*nlevel*sizeof(double));
            
-      if ( zaxisID == zaxisIDh )
+      if ( zaxisID == zaxisIDh ||
+	   (is_height_axis(zaxisID, nlevel) && zaxisIDh != -1 && (nlevel == nhlevh || nlevel == nhlevf)) )
 	{
 	  varinterp[varID] = true;
 	  vardata2[varID]  = (double *) Malloc(gridsize*nplev*sizeof(double));
@@ -300,25 +291,31 @@ void *Vertintap(void *argument)
 	}
       else
 	{
-          vlistInqVarName(vlistID1, varID, varname);
+	  if ( is_height_axis(zaxisID, nlevel) && zaxisIDh != -1 && nlevel > 1 )
+            {
+              vlistInqVarName(vlistID1, varID, varname);
+              cdoWarning("Parameter %d has wrong number of levels, skipped! (param=%s nlevel=%d)",
+                         varID+1, varname, nlevel);
+            }
 
-          if ( is_height_axis(zaxisID, nlevel) && nlevel == nhlevh )
-            cdoWarning("Interpolation from half level not supported, parameter %s not interpolated!", varname);
-          
 	  varinterp[varID] = false;
 	  vardata2[varID]  = vardata1[varID];
 	  varnmiss[varID]  = (int *) Malloc(nlevel*sizeof(int));
 	}
     }
   
-  if ( zaxisIDh != -1 && psID == -1 && dpressID )
-    cdoWarning("Surface pressure not found - set to vertical sum of %s!", var_stdname(pressure_thickness));
-  //  cdoWarning("Surface pressure not found - set to upper level of %s!", var_stdname(air_pressure));
+  if ( zaxisIDh != -1 && psID == -1 )
+    {
+      if ( dpressID != -1 )
+        cdoWarning("Surface pressure not found - set to vertical sum of %s!", var_stdname(pressure_thickness));
+      else
+        cdoWarning("Surface pressure not found - set to lower bound of %s!", var_stdname(air_pressure));
+    }
 
   for ( varID = 0; varID < nvars; ++varID )
     {
-      if ( varinterp[varID] && vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT )
-	vlistDefVarTsteptype(vlistID2, varID, TSTEP_INSTANT);
+      if ( varinterp[varID] && vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT )
+	vlistDefVarTimetype(vlistID2, varID, TIME_VARYING);
     }
 
   int streamID2 = pstreamOpenWrite(cdoStreamName(1), cdoFiletype());
@@ -351,10 +348,9 @@ void *Vertintap(void *argument)
 	      printf("levelID %d\n", levelID);
 	    }
 	  */
-	  offset   = gridsize*levelID;
-	  single1  = vardata1[varID] + offset;
-
-	  pstreamReadRecord(streamID1, single1, &varnmiss[varID][levelID]);
+	  size_t offset = gridsize*levelID;
+	  double *single1 = vardata1[varID] + offset;
+ 	  pstreamReadRecord(streamID1, single1, &varnmiss[varID][levelID]);
 
 	  vars[varID] = true;
 	}
@@ -370,16 +366,15 @@ void *Vertintap(void *argument)
 	    }
           else 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];
+	      for ( int i = 0; i < gridsize; i++ )  ps_prog[i] = 0;
+	      for ( int k = 0; k < nhlevf; ++k )
+		for ( int i = 0; i < gridsize; i++ )
+		  ps_prog[i] += vardata1[dpressID][k*gridsize+i];
 	    }
 	  else
 	    {
 	      memcpy(ps_prog, vardata1[apressID]+gridsize*(nhlevf-1), gridsize*sizeof(double)); 
-	      //for ( i = 0; i < gridsize; i++ )  ps_prog[i] = 110000;
+	      //for ( int i = 0; i < gridsize; i++ )  ps_prog[i] = 110000;
 	    }
 
 	  /* check range of ps_prog */
@@ -390,39 +385,46 @@ void *Vertintap(void *argument)
 
 	  memcpy(full_press, vardata1[apressID], gridsize*nhlevf*sizeof(double)); 
 
+          for ( int i = 0; i < gridsize; i++ ) half_press[i] = 0;
+          for ( int k = 1; k < nhlevf; k++ )
+            for ( int i = 0; i < gridsize; i++ )
+              half_press[k*gridsize+i] = 0.5*(full_press[(k-1)*gridsize+i]+full_press[k*gridsize+i]);
+          for ( int i = 0; i < gridsize; i++ ) half_press[(nhlevh-1)*gridsize+i] = full_press[(nhlevf-1)*gridsize+i];
+          
 	  if ( opertype == type_log )
 	    {
-	      for ( i = 0; i < gridsize; i++ ) ps_prog[i] = log(ps_prog[i]);
+	      for ( int i = 0; i < gridsize; i++ ) ps_prog[i] = log(ps_prog[i]);
 
-	      for ( k = 0; k < nhlevf; k++ )
-		for ( i = 0; i < gridsize; i++ )
+	      for ( int k = 0; k < nhlevh; k++ )
+		for ( int i = 0; i < gridsize; i++ )
+		  half_press[k*gridsize+i] = log(half_press[k*gridsize+i]);
+
+	      for ( int k = 0; k < nhlevf; k++ )
+		for ( int 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);
+	  if ( !extrapolate ) genindmiss(vert_index, plev, gridsize, nplev, ps_prog, pnmiss);
 	}
 
       for ( varID = 0; varID < nvars; varID++ )
 	{
 	  if ( vars[varID] )
 	    {
-	      int zaxisID  = vlistInqVarZaxis(vlistID1, varID);
-	      int nlevel   = zaxisInqSize(zaxisID);
-	      double missval  = vlistInqVarMissval(vlistID1, varID);
+	      int zaxisID = vlistInqVarZaxis(vlistID1, varID);
+	      int nlevel  = zaxisInqSize(zaxisID);
+	      double missval = vlistInqVarMissval(vlistID1, varID);
 	      if ( varinterp[varID] )
 		{
-		  if ( nlevel == nhlevf )
-		    {
-		      hyb_press = full_press;
-		    }
+                  double *hyb_press = NULL;
+		  if      ( nlevel == nhlevf ) hyb_press = full_press;
+		  else if ( nlevel == nhlevh ) hyb_press = half_press;
 		  else
 		    {
-		      int param = vlistInqVarParam(vlistID1, varID);
-		      cdiParamToString(param, paramstr, sizeof(paramstr));
-		      cdoAbort("Number of generalized height level differ from full/half level (param=%s)!", paramstr);
+                      vlistInqVarName(vlistID1, varID, varname);
+		      cdoAbort("Number of generalized height level differ from full/half level (param=%s)!", varname);
 		    }
 
 		  for ( levelID = 0; levelID < nlevel; levelID++ )
@@ -434,8 +436,7 @@ void *Vertintap(void *argument)
 		  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));
+		  if ( !extrapolate ) memcpy(varnmiss[varID], pnmiss, nplev*sizeof(int));
 		}
 	    }
 	}
@@ -447,8 +448,8 @@ void *Vertintap(void *argument)
 	      int nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
 	      for ( levelID = 0; levelID < nlevel; levelID++ )
 		{
-		  offset   = gridsize*levelID;
-		  single2  = vardata2[varID] + offset;
+		  size_t offset = gridsize*levelID;
+		  double *single2 = vardata2[varID] + offset;
 		  pstreamDefRecord(streamID2, varID, levelID);
 		  pstreamWriteRecord(streamID2, single2, varnmiss[varID][levelID]);
 		}
@@ -472,14 +473,7 @@ void *Vertintap(void *argument)
   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);
-
-  Free(vars);
-  Free(varinterp);
-  Free(vardata1);
-  Free(vardata2);
-  Free(varnmiss);
+  if ( half_press ) Free(half_press);
 
   lista_destroy(flista);
 
diff --git a/src/Vertintml.cc b/src/Vertintml.cc
index 0fcb757..b955e37 100644
--- a/src/Vertintml.cc
+++ b/src/Vertintml.cc
@@ -122,10 +122,6 @@ void *Vertintml(void *argument)
         }
       else
         {
-          /*
-            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};
-          */
           double stdlev[] = {100000, 92500, 85000, 70000, 60000, 50000, 40000, 30000, 25000, 20000, 15000,
                              10000,  7000,  5000,  3000,  2000, 1000 };
           nplev = sizeof(stdlev)/sizeof(*stdlev);
@@ -150,7 +146,8 @@ void *Vertintml(void *argument)
 
   int gridsize = vlist_check_gridsize(vlistID1);
 
-  int zaxisIDp = (operfunc == func_hl) ? zaxisCreate(ZAXIS_HEIGHT, nplev) : zaxisCreate(ZAXIS_PRESSURE, nplev);
+  int zaxistype = (operfunc == func_hl) ? ZAXIS_HEIGHT : ZAXIS_PRESSURE;
+  int zaxisIDp = zaxisCreate(zaxistype, nplev);
   zaxisDefLevels(zaxisIDp, plev);
 
   int nvct = 0;
@@ -371,8 +368,12 @@ void *Vertintml(void *argument)
       else
 	{
 	  if ( zaxis_is_hybrid(zaxistype) && zaxisIDh != -1 && nlevel > 1 )
-	    cdoWarning("Parameter %d has wrong number of levels, skipped! (param=%s nlevel=%d)",
-		       varID+1, paramstr, nlevel);
+            {
+              vlistInqVarName(vlistID1, varID, varname);
+              cdoWarning("Parameter %d has wrong number of levels, skipped! (param=%s nlevel=%d)",
+                         varID+1, varname, nlevel);
+            }
+
 	  varinterp[varID] = false;
 	  vardata2[varID]  = vardata1[varID];
 	  varnmiss[varID]  = (int*) Malloc(nlevel*sizeof(int));
@@ -555,13 +556,12 @@ void *Vertintml(void *argument)
 		    }
 		  */
                   double *hyb_press = NULL;
-		  if      ( nlevel == nhlevh ) hyb_press = half_press;
-		  else if ( nlevel == nhlevf ) hyb_press = full_press;
+		  if      ( nlevel == nhlevf ) hyb_press = full_press;
+		  else if ( nlevel == nhlevh ) hyb_press = half_press;
 		  else
 		    {
-		      int param = vlistInqVarParam(vlistID1, varID);
-		      cdiParamToString(param, paramstr, sizeof(paramstr));
-		      cdoAbort("Number of hybrid level differ from full/half level (param=%s)!", paramstr);
+                      vlistInqVarName(vlistID1, varID, varname);
+		      cdoAbort("Number of hybrid level differ from full/half level (param=%s)!", varname);
 		    }
 
 		  for ( levelID = 0; levelID < nlevel; levelID++ )
diff --git a/src/Wct.cc b/src/Wct.cc
index 9760f47..71e26ba 100644
--- a/src/Wct.cc
+++ b/src/Wct.cc
@@ -114,7 +114,7 @@ void *Wct(void *argument)
   int vlistID3 = vlistCreate();
   int gridID   = vlistInqVarGrid(vlistID1, FIRST_VAR);
   int zaxisID  = vlistInqVarZaxis(vlistID1, FIRST_VAR);
-  int varID3   = vlistDefVar(vlistID3, gridID, zaxisID, TSTEP_INSTANT);
+  int varID3   = vlistDefVar(vlistID3, gridID, zaxisID, TIME_VARYING);
 
   int taxisID3 = taxisCreate(TAXIS_RELATIVE);
   taxisDefTunit(taxisID3, TUNIT_MINUTE);
diff --git a/src/WindTrans.cc b/src/WindTrans.cc
index 151dcc4..5fdf79a 100644
--- a/src/WindTrans.cc
+++ b/src/WindTrans.cc
@@ -7,7 +7,7 @@
   CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2012 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/XTimstat.cc b/src/XTimstat.cc
index c5048af..e2e6b00 100644
--- a/src/XTimstat.cc
+++ b/src/XTimstat.cc
@@ -233,15 +233,12 @@ void *XTimstat(void *argument)
 
   int taxisID1 = vlistInqTaxis(vlistID1);
   int taxisID2 = taxisDuplicate(taxisID1);
+  taxisWithBounds(taxisID2);
   if ( taxisInqType(taxisID2) == TAXIS_FORECAST ) taxisDefType(taxisID2, TAXIS_RELATIVE);
   vlistDefTaxis(vlistID2, taxisID2);
 
   int nvars = vlistNvars(vlistID1);
 
-  if ( cmplen == 0 && CDO_Reduce_Dim )
-    for ( varID = 0; varID < nvars; ++varID )
-      vlistDefVarTsteptype(vlistID2, varID, TSTEP_CONSTANT);
-
   const char *freq = NULL;
   if      ( comparelen == DAY_LEN )  freq = "day";
   else if ( comparelen == MON_LEN )  freq = "mon";
@@ -273,6 +270,7 @@ void *XTimstat(void *argument)
 	}
 
       taxisID3 = taxisDuplicate(taxisID1);
+      taxisWithBounds(taxisID3);
       vlistDefTaxis(vlistID3, taxisID3);
 
       pstreamDefVlist(streamID3, vlistID3);
@@ -297,7 +295,7 @@ void *XTimstat(void *argument)
   readarg.streamID = streamID1;
   readarg.vars = input_vars;
 
-  int lparallelread = CDO_Parallel_Read;
+  bool lparallelread = CDO_Parallel_Read > 0;
   bool ltsfirst = true;
   void *read_task = NULL;
   void *readresult = NULL;
@@ -307,7 +305,7 @@ void *XTimstat(void *argument)
       read_task = cdo_task_new();
       if ( read_task == NULL )
         {
-          lparallelread = FALSE;
+          lparallelread = false;
           cdoWarning("CDO tasks not available!");
         }
     }
@@ -337,7 +335,7 @@ void *XTimstat(void *argument)
           readarg.nrecs    = nrecs;
           readarg.recinfo  = recinfo;
 
-          if ( ltsfirst || lparallelread == FALSE )
+          if ( ltsfirst || lparallelread == false )
             {
               ltsfirst = false;
               readresult = cdoReadTimestep(&readarg);
@@ -438,7 +436,7 @@ void *XTimstat(void *argument)
                 field_type *pvars1 = &vars1[varID][levelID];
                 field_type *pvars2 = &vars2[varID][levelID];
 
-		if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+		if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
 
                 farmoq(pvars2, *pvars1);
 	      }
@@ -462,7 +460,7 @@ void *XTimstat(void *argument)
               int levelID = recinfo[recID].levelID;
               field_type *pvars1 = &vars1[varID][levelID];
 
-              if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+              if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
 
               if ( samp1[varID][levelID].ptr == NULL )
                 farcdiv(pvars1, (double)nsets);
@@ -479,7 +477,7 @@ void *XTimstat(void *argument)
               field_type *pvars1 = &vars1[varID][levelID];
               field_type *pvars2 = &vars2[varID][levelID];
 
-              if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+              if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
 
               if ( samp1[varID][levelID].ptr == NULL )
                 {
@@ -509,7 +507,7 @@ void *XTimstat(void *argument)
             int levelID = recinfo[recID].levelID;
             field_type *pvars1 = &vars1[varID][levelID];
 
-	    if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+	    if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
 
             nwpv     = pvars1->nwpv;
             int gridsize = pvars1->size;
@@ -551,7 +549,7 @@ void *XTimstat(void *argument)
           int levelID = recinfo[recID].levelID;
           field_type *pvars1 = &vars1[varID][levelID];
 
-	  if ( otsID && vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+	  if ( otsID && vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
 
           pstreamDefRecord(streamID2, varID, levelID);
 	  pstreamWriteRecord(streamID2, pvars1->ptr,  pvars1->nmiss);
diff --git a/src/YAR.cc b/src/YAR.cc
index face097..8776a68 100644
--- a/src/YAR.cc
+++ b/src/YAR.cc
@@ -96,45 +96,6 @@ void yar_store_link_cnsrv(remapvars_t *rv, long add1, long add2, double weight)
   rv->wts[nlink] = weight;
 }
 
-static
-void gen_xbounds(int nx, double *xvals, double *xbounds)
-{
-  int i;
-
-  for ( i = 0; i < nx-1; i++ )
-    {
-      xbounds[i+1]   = 0.5*(xvals[i] + xvals[i+1]);
-    }
-
-  xbounds[0]  = 2*xvals[0] - xbounds[1];
-  xbounds[nx] = 2*xvals[nx-1] - xbounds[nx-1];
-}
-
-static
-void gen_ybounds(int ny, double *yvals, double *ybounds)
-{
-  int i;
-
-  for ( i = 0; i < ny-1; i++ )
-    {
-      ybounds[i+1]   = 0.5*(yvals[i] + yvals[i+1]);
-    }
-
-  ybounds[0]  = 2*yvals[0] - ybounds[1];
-  ybounds[ny] = 2*yvals[ny-1] - ybounds[ny-1];
-
-  if ( yvals[0] > yvals[ny-1] )
-    {
-      if ( ybounds[0]  >  88 ) ybounds[0]  =  90;
-      if ( ybounds[ny] < -88 ) ybounds[ny] = -90;
-    }
-  else
-    {
-      if ( ybounds[0]  < -88 ) ybounds[0]  = -90;
-      if ( ybounds[ny] >  88 ) ybounds[ny] =  90;
-    }
-}
-
 
 void set_source_data(double * source_data, double init_value,
                      unsigned size_x, unsigned size_y) {
@@ -149,6 +110,7 @@ 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.
 */
+#if defined(HAVE_LIBYAC)
 static
 void store_link_bilin(remapvars_t *rv, int dst_add, int src_add[4], double weights[4])
 {
@@ -177,34 +139,16 @@ void store_link_bilin(remapvars_t *rv, int dst_add, int src_add[4], double weigh
     }
 
 } /* store_link_bilin */
+#endif
 
 void yar_remap_bil(field_type *field1, field_type *field2)
 {
-  int nlonIn, nlatIn;
-  int nlonOut, nlatOut;
-  int ilat, ilon;
-  int gridIDin, gridIDout;
-  int i, nmiss;
-  int gridsize1, gridsize2;
-  double *lonIn, *latIn;
-  double *lonOut, *latOut;
-  double *xlonIn, *xlatIn;
-  double *xlonOut, *xlatOut;
-  double **fieldIn;
-  double **field;
-  double *array = NULL;
-  double *array1, *array2;
-  double missval;
-  int testit = 1;
   double dxIn, dxOut;
   remap_t remap;
   /* static int index = 0; */
 
-  gridIDin  = field1->grid;
-  gridIDout = field2->grid;
-  array1    = field1->ptr;
-  array2    = field2->ptr;
-  missval   = field1->missval;
+  int gridIDin  = field1->grid;
+  int gridIDout = field2->grid;
 
   if ( ! (gridInqXvals(gridIDin, NULL) && gridInqYvals(gridIDin, NULL)) )
     cdoAbort("Source grid has no values");
@@ -220,18 +164,18 @@ void yar_remap_bil(field_type *field1, field_type *field2)
 
 
   if ( cdoTimer ) timer_start(timer_yar_remap_init);
-  nlonIn = gridInqXsize(gridIDin);
-  nlatIn = gridInqYsize(gridIDin);
-  gridsize1 = gridInqSize(gridIDin);
-  lonIn = (double*) Malloc(nlonIn*sizeof(double));
-  latIn = (double*) Malloc(nlatIn*sizeof(double));
+  int nlonIn = gridInqXsize(gridIDin);
+  int nlatIn = gridInqYsize(gridIDin);
+  // int gridsize1 = gridInqSize(gridIDin);
+  double *lonIn = (double*) Malloc(nlonIn*sizeof(double));
+  double *latIn = (double*) Malloc(nlatIn*sizeof(double));
   gridInqXvals(gridIDin, lonIn);
   gridInqYvals(gridIDin, latIn);
   for ( int i = 0; i < nlonIn; ++i ) lonIn[i] *= DEG2RAD;
   for ( int i = 0; i < nlatIn; ++i ) latIn[i] *= DEG2RAD;
 
-  xlonIn = (double*) Malloc((nlonIn+1)*sizeof(double));
-  xlatIn = (double*) Malloc((nlatIn+1)*sizeof(double));
+  double *xlonIn = (double*) Malloc((nlonIn+1)*sizeof(double));
+  double *xlatIn = (double*) Malloc((nlatIn+1)*sizeof(double));
   gridInqXvals(gridIDin, xlonIn);
   gridInqYvals(gridIDin, xlatIn);
   dxIn = xlonIn[1] - xlonIn[0];
@@ -245,18 +189,18 @@ void yar_remap_bil(field_type *field1, field_type *field2)
   if ( ! (gridInqXvals(gridIDout, NULL) && gridInqYvals(gridIDout, NULL)) )
     cdoAbort("Target grid has no values");
 
-  nlonOut = gridInqXsize(gridIDout);
-  nlatOut = gridInqYsize(gridIDout);
-  gridsize2 = gridInqSize(gridIDout);
-  lonOut = (double*) Malloc(nlonOut*sizeof(double));
-  latOut = (double*) Malloc(nlatOut*sizeof(double));
+  int nlonOut = gridInqXsize(gridIDout);
+  int nlatOut = gridInqYsize(gridIDout);
+  // int gridsize2 = gridInqSize(gridIDout);
+  double *lonOut = (double*) Malloc(nlonOut*sizeof(double));
+  double *latOut = (double*) Malloc(nlatOut*sizeof(double));
   gridInqXvals(gridIDout, lonOut);
   gridInqYvals(gridIDout, latOut);
   for ( int i = 0; i < nlonOut; ++i ) lonOut[i] *= DEG2RAD;
   for ( int i = 0; i < nlatOut; ++i ) latOut[i] *= DEG2RAD;
 
-  xlonOut = (double*) Malloc((nlonOut+1)*sizeof(double));
-  xlatOut = (double*) Malloc((nlatOut+1)*sizeof(double));
+  double *xlonOut = (double*) Malloc((nlonOut+1)*sizeof(double));
+  double *xlatOut = (double*) Malloc((nlatOut+1)*sizeof(double));
   gridInqXvals(gridIDout, xlonOut);
   gridInqYvals(gridIDout, xlatOut);
   dxOut = xlonOut[1] - xlonOut[0];
@@ -408,12 +352,16 @@ void yar_remap_bil(field_type *field1, field_type *field2)
 
   if ( cdoTimer ) timer_stop(timer_yar_remap_bil);
 
+  double *array1 = field1->ptr;
+  double *array2 = field2->ptr;
+  double missval = field1->missval;
+
   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_cell_add, remap.vars.src_cell_add, array1);
   if ( cdoTimer ) timer_stop(timer_yar_remap);
 
-  nmiss = 0;
+  int nmiss = 0;
   for ( int i = 0; i < gridInqSize(gridIDout); ++i )
     if ( DBL_IS_EQUAL(array2[i], missval) ) nmiss++;
 
@@ -424,7 +372,6 @@ void yar_remap_bil(field_type *field1, field_type *field2)
   //free(latIn);
   //free(lonOut);
   //free(latOut);
-  //free(fieldIn);
 #endif
 }
 
@@ -433,27 +380,17 @@ void yar_remap_con(field_type *field1, field_type *field2)
 {
   int nlonIn, nlatIn;
   int nlonOut, nlatOut;
-  int ilat, ilon;
   int gridIDin, gridIDout;
-  int i, nmiss;
-  int gridsize1, gridsize2;
   double *lonIn, *latIn;
   double *lonOut, *latOut;
   double *xlonIn, *xlatIn;
   double *xlonOut, *xlatOut;
-  double **fieldIn;
-  double **field;
-  double *array1, *array2;
-  double missval;
   double dxIn, dxOut;
   remap_t remap;
   /* static int index = 0; */
 
   gridIDin  = field1->grid;
   gridIDout = field2->grid;
-  array1    = field1->ptr;
-  array2    = field2->ptr;
-  missval   = field1->missval;
 
   if ( ! (gridInqXvals(gridIDin, NULL) && gridInqYvals(gridIDin, NULL)) )
     cdoAbort("Source grid has no values");
@@ -471,7 +408,7 @@ void yar_remap_con(field_type *field1, field_type *field2)
   if ( cdoTimer ) timer_start(timer_yar_remap_init);
   nlonIn = gridInqXsize(gridIDin);
   nlatIn = gridInqYsize(gridIDin);
-  gridsize1 = gridInqSize(gridIDin);
+  // int gridsize1 = gridInqSize(gridIDin);
   lonIn = (double*) Malloc((nlonIn+1)*sizeof(double));
   latIn = (double*) Malloc((nlatIn+1)*sizeof(double));
   gridInqXvals(gridIDin, lonIn);
@@ -493,7 +430,7 @@ void yar_remap_con(field_type *field1, field_type *field2)
 
   nlonOut = gridInqXsize(gridIDout);
   nlatOut = gridInqYsize(gridIDout);
-  gridsize2 = gridInqSize(gridIDout);
+  // int gridsize2 = gridInqSize(gridIDout);
   lonOut = (double*) Malloc((nlonOut+1)*sizeof(double));
   latOut = (double*) Malloc((nlatOut+1)*sizeof(double));
   gridInqXvals(gridIDout, lonOut);
@@ -712,12 +649,16 @@ void yar_remap_con(field_type *field1, field_type *field2)
   //polygon_destroy ( &polygons );
   if ( cdoTimer ) timer_stop(timer_yar_remap_con);
 
+  double *array1 = field1->ptr;
+  double *array2 = field2->ptr;
+  double missval = field1->missval;
+
   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_cell_add, remap.vars.src_cell_add, array1);
   if ( cdoTimer ) timer_stop(timer_yar_remap);
 
-  nmiss = 0;
+  int nmiss = 0;
   for ( int i = 0; i < gridInqSize(gridIDout); ++i )
     if ( DBL_IS_EQUAL(array2[i], missval) ) nmiss++;
 
@@ -738,7 +679,6 @@ void yar_remap_con(field_type *field1, field_type *field2)
   //free(latIn);
   //free(lonOut);
   //free(latOut);
-  //free(fieldIn);
 #endif
 }
 
@@ -750,9 +690,7 @@ void *YAR(void *argument)
   int varID, levelID;
   int gridID1 = -1;
   int nmiss;
-  int xinc = 0, yinc = 0;
   double missval;
-  double slon, slat;
 
   if ( cdoTimer )
     {
@@ -776,6 +714,7 @@ void *YAR(void *argument)
   field_init(&field1);
   field_init(&field2);
 
+  // open stream before calling cdoDefineGrid!!!
   int streamID1 = pstreamOpenRead(cdoStreamName(0));
 
   int gridID2 = cdoDefineGrid(operatorArgv()[0]);
diff --git a/src/Ydaypctl.cc b/src/Ydaypctl.cc
index 0469ed7..2869b12 100644
--- a/src/Ydaypctl.cc
+++ b/src/Ydaypctl.cc
@@ -212,7 +212,7 @@ void *Ydaypctl(void *argument)
         
 	for ( varID = 0; varID < nvars; varID++ )
 	  {
-	    if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+	    if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
 	    nlevels = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
 	      
 	    for ( levelID = 0; levelID < nlevels; levelID++ )
@@ -228,7 +228,7 @@ void *Ydaypctl(void *argument)
 	    varID    = recVarID[recID];
 	    levelID  = recLevelID[recID];
 
-	    if ( otsID && vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+	    if ( otsID && vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
 
 	    pstreamDefRecord(streamID4, varID, levelID);
 	    pstreamWriteRecord(streamID4, vars1[dayoy][varID][levelID].ptr, vars1[dayoy][varID][levelID].nmiss);
diff --git a/src/Ydaystat.cc b/src/Ydaystat.cc
index e124124..0c976f6 100644
--- a/src/Ydaystat.cc
+++ b/src/Ydaystat.cc
@@ -139,7 +139,7 @@ void *Ydaystat(void *argument)
 	    {
               recinfo[recID].varID   = varID;
               recinfo[recID].levelID = levelID;
-              recinfo[recID].lconst  = vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT;
+              recinfo[recID].lconst  = vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT;
 	    }
 
           field_type *psamp1 = &samp1[dayoy][varID][levelID];
diff --git a/src/Ydrunpctl.cc b/src/Ydrunpctl.cc
index dbf8f44..8c83906 100644
--- a/src/Ydrunpctl.cc
+++ b/src/Ydrunpctl.cc
@@ -230,7 +230,7 @@ void *Ydrunpctl(void *argument)
 
       for ( varID = 0; varID < nvars; varID++ )
 	{
-	  if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+	  if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
 	  nlevels = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
 	      
 	  for ( levelID = 0; levelID < nlevels; levelID++ )
@@ -292,7 +292,7 @@ void *Ydrunpctl(void *argument)
 
 	for ( varID = 0; varID < nvars; varID++ )
 	  {
-	    if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+	    if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
 	    nlevels = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
 	      
 	    for ( levelID = 0; levelID < nlevels; levelID++ )
@@ -308,7 +308,7 @@ void *Ydrunpctl(void *argument)
 	    varID    = recVarID[recID];
 	    levelID  = recLevelID[recID];
 
-	    if ( otsID && vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+	    if ( otsID && vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
 
 	    pstreamDefRecord(streamID4, varID, levelID);
 	    pstreamWriteRecord(streamID4, vars2[dayoy][varID][levelID].ptr,
diff --git a/src/Ydrunstat.cc b/src/Ydrunstat.cc
index 3dc6892..1083e88 100644
--- a/src/Ydrunstat.cc
+++ b/src/Ydrunstat.cc
@@ -139,7 +139,7 @@ void *Ydrunstat(void *argument)
 	    {
               recinfo[recID].varID   = varID;
               recinfo[recID].levelID = levelID;
-              recinfo[recID].lconst  = vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT;
+              recinfo[recID].lconst  = vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT;
 	    }
 	  
           field_type *pvars1 = &vars1[tsID][varID][levelID];
@@ -384,7 +384,7 @@ void ydstatUpdate(YDAY_STATS *stats, int vdate, int vtime,
 
   for ( varID = 0; varID  < nvars; varID++ )
     {
-      if ( vlistInqVarTsteptype(stats->vlist, varID) == TSTEP_CONSTANT ) continue;
+      if ( vlistInqVarTimetype(stats->vlist, varID) == TIME_CONSTANT ) continue;
         
       gridsize = gridInqSize(vlistInqVarGrid(stats->vlist, varID));
       nlevels  = zaxisInqSize(vlistInqVarZaxis(stats->vlist, varID));
@@ -438,7 +438,7 @@ void ydstatFinalize(YDAY_STATS *stats, int operfunc)
 	    case func_mean:
 	      for ( varID = 0; varID < nvars; varID++ )
 	        {
-	          if ( vlistInqVarTsteptype(stats->vlist, varID) == TSTEP_CONSTANT ) continue;
+	          if ( vlistInqVarTimetype(stats->vlist, varID) == TIME_CONSTANT ) continue;
 	          nlevels = zaxisInqSize(vlistInqVarZaxis(stats->vlist, varID));
 	          for ( levelID = 0; levelID < nlevels; levelID++ )
 		    farcdiv(&stats->vars1[dayoy][varID][levelID], (double) stats->nsets[dayoy]);
@@ -449,7 +449,7 @@ void ydstatFinalize(YDAY_STATS *stats, int operfunc)
 	    case func_std1:
 	      for ( varID = 0; varID < nvars; varID++ )
 	        {
-	          if ( vlistInqVarTsteptype(stats->vlist, varID) == TSTEP_CONSTANT ) continue;
+	          if ( vlistInqVarTimetype(stats->vlist, varID) == TIME_CONSTANT ) continue;
 	          nlevels = zaxisInqSize(vlistInqVarZaxis(stats->vlist, varID));
 	          for ( levelID = 0; levelID < nlevels; levelID++ )
 		    farcstd(&stats->vars1[dayoy][varID][levelID], stats->vars2[dayoy][varID][levelID],
@@ -461,7 +461,7 @@ void ydstatFinalize(YDAY_STATS *stats, int operfunc)
 	    case func_var1:
 	      for ( varID = 0; varID < nvars; varID++ )
 	        {
-	          if ( vlistInqVarTsteptype(stats->vlist, varID) == TSTEP_CONSTANT ) continue;
+	          if ( vlistInqVarTimetype(stats->vlist, varID) == TIME_CONSTANT ) continue;
 	          nlevels = zaxisInqSize(vlistInqVarZaxis(stats->vlist, varID));
 	          for ( levelID = 0; levelID < nlevels; levelID++ )
 		    farcvar(&stats->vars1[dayoy][varID][levelID], stats->vars2[dayoy][varID][levelID],
diff --git a/src/Yearmonstat.cc b/src/Yearmonstat.cc
index 71091ab..daa8b59 100644
--- a/src/Yearmonstat.cc
+++ b/src/Yearmonstat.cc
@@ -64,6 +64,7 @@ void *Yearmonstat(void *argument)
 
   int taxisID1 = vlistInqTaxis(vlistID1);
   int taxisID2 = taxisDuplicate(taxisID1);
+  taxisWithBounds(taxisID2);
   vlistDefTaxis(vlistID2, taxisID2);
 
   int streamID2 = pstreamOpenWrite(cdoStreamName(1), cdoFiletype());
@@ -189,8 +190,8 @@ void *Yearmonstat(void *argument)
 
       for ( varID = 0; varID < nvars; varID++ )
 	{
-	  if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
-	  nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
+	  if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
+	  nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
 	  for ( levelID = 0; levelID < nlevel; levelID++ )
 	    {
 	      if ( samp1[varID][levelID].ptr == NULL )
@@ -215,7 +216,7 @@ void *Yearmonstat(void *argument)
 	  varID   = recVarID[recID];
 	  levelID = recLevelID[recID];
 
-	  if ( otsID && vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+	  if ( otsID && vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
 
 	  pstreamDefRecord(streamID2, varID, levelID);
 	  pstreamWriteRecord(streamID2, vars1[varID][levelID].ptr,  (int)vars1[varID][levelID].nmiss);
diff --git a/src/Yhourstat.cc b/src/Yhourstat.cc
index 422a1e5..3ecdb10 100644
--- a/src/Yhourstat.cc
+++ b/src/Yhourstat.cc
@@ -159,7 +159,7 @@ void *Yhourstat(void *argument)
 	    {
               recinfo[recID].varID   = varID;
               recinfo[recID].levelID = levelID;
-              recinfo[recID].lconst  = vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT;
+              recinfo[recID].lconst  = vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT;
 	    }
 
           field_type *psamp1 = &samp1[houroy][varID][levelID];
diff --git a/src/Ymonpctl.cc b/src/Ymonpctl.cc
index 39ffa1e..a5d5dd9 100644
--- a/src/Ymonpctl.cc
+++ b/src/Ymonpctl.cc
@@ -205,7 +205,7 @@ void *Ymonpctl(void *argument)
 
 	for ( varID = 0; varID < nvars; varID++ )
 	  {
-	    if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+	    if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
 	    nlevels = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
 	      
 	    for ( levelID = 0; levelID < nlevels; levelID++ )
@@ -221,7 +221,7 @@ void *Ymonpctl(void *argument)
 	    varID    = recVarID[recID];
 	    levelID  = recLevelID[recID];
 
-	    if ( otsID && vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+	    if ( otsID && vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
 
 	    pstreamDefRecord(streamID4, varID, levelID);
 	    pstreamWriteRecord(streamID4, vars1[month][varID][levelID].ptr, vars1[month][varID][levelID].nmiss);
diff --git a/src/Ymonstat.cc b/src/Ymonstat.cc
index 90312a5..88fd8f3 100644
--- a/src/Ymonstat.cc
+++ b/src/Ymonstat.cc
@@ -155,7 +155,7 @@ void *Ymonstat(void *argument)
 	    {
               recinfo[recID].varID   = varID;
               recinfo[recID].levelID = levelID;
-              recinfo[recID].lconst  = vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT;
+              recinfo[recID].lconst  = vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT;
 	    }
 
           field_type *psamp1 = &samp1[month][varID][levelID];
diff --git a/src/Yseaspctl.cc b/src/Yseaspctl.cc
index b764f8f..24b6739 100644
--- a/src/Yseaspctl.cc
+++ b/src/Yseaspctl.cc
@@ -216,7 +216,7 @@ void *Yseaspctl(void *argument)
 
 	for ( varID = 0; varID < nvars; varID++ )
 	  {
-	    if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+	    if ( vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
 	    nlevels = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
 	    
 	    for ( levelID = 0; levelID < nlevels; levelID++ )
@@ -232,7 +232,7 @@ void *Yseaspctl(void *argument)
 	    varID    = recVarID[recID];
 	    levelID  = recLevelID[recID];
 
-	    if ( otsID && vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+	    if ( otsID && vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT ) continue;
 
 	    pstreamDefRecord(streamID4, varID, levelID);
 	    pstreamWriteRecord(streamID4, vars1[seas][varID][levelID].ptr, vars1[seas][varID][levelID].nmiss);
diff --git a/src/Yseasstat.cc b/src/Yseasstat.cc
index 3de307e..aa142ef 100644
--- a/src/Yseasstat.cc
+++ b/src/Yseasstat.cc
@@ -155,7 +155,7 @@ void *Yseasstat(void *argument)
 	    {
               recinfo[recID].varID   = varID;
               recinfo[recID].levelID = levelID;
-              recinfo[recID].lconst  = vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT;
+              recinfo[recID].lconst  = vlistInqVarTimetype(vlistID1, varID) == TIME_CONSTANT;
 	    }
 
           field_type *psamp1 = &samp1[seas][varID][levelID];
diff --git a/src/after_fctrans.cc b/src/after_fctrans.cc
index a00d9ad..55507bd 100644
--- a/src/after_fctrans.cc
+++ b/src/after_fctrans.cc
@@ -1,25 +1,19 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-
-#if defined(HAVE_CONFIG_H)
+#ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
 #ifndef _DMEMORY_H
-#  include "dmemory.h"
+#include "dmemory.h"
 #endif
 
-#define  OPENMP4  201307
-#if defined(_OPENMP) && defined(OPENMP4) && _OPENMP >= OPENMP4
-#define  HAVE_OPENMP4  1
-#endif
 
+#include "cdo_int.h"
 
-#if defined(SX)
-#  define  NFFT  1024
+
+#ifdef SX
+#define  NFFT  1024
 #else
-#  define  NFFT  64
+#define  NFFT     8
 #endif
 
 #ifndef  M_SQRT2
@@ -168,9 +162,6 @@ 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];
@@ -203,9 +194,6 @@ 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];
@@ -236,9 +224,6 @@ 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];
@@ -259,9 +244,6 @@ 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]);
@@ -296,9 +278,6 @@ 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];
@@ -338,9 +317,6 @@ 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]);
@@ -381,9 +357,6 @@ 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];
@@ -408,9 +381,6 @@ 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];
@@ -450,9 +420,6 @@ 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];
@@ -497,9 +464,6 @@ 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];
@@ -549,9 +513,6 @@ 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];
@@ -578,9 +539,6 @@ 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];
@@ -621,9 +579,6 @@ 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]);
@@ -681,9 +636,6 @@ 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]) +
@@ -748,9 +700,6 @@ 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];
@@ -786,9 +735,6 @@ 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]);
@@ -838,9 +784,6 @@ 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]);
@@ -900,9 +843,6 @@ 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];
@@ -963,9 +903,6 @@ 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]);
@@ -994,9 +931,6 @@ 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])) +
@@ -1056,9 +990,6 @@ 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];
@@ -1162,9 +1093,6 @@ 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];
@@ -1196,9 +1124,6 @@ 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];
@@ -1226,9 +1151,6 @@ 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];
@@ -1250,9 +1172,6 @@ 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]);
@@ -1286,9 +1205,6 @@ 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];
@@ -1325,9 +1241,6 @@ 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] +
@@ -1369,9 +1282,6 @@ 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 */
@@ -1396,9 +1306,6 @@ 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]);
@@ -1436,9 +1343,6 @@ 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];
@@ -1484,9 +1388,6 @@ 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];
@@ -1534,9 +1435,6 @@ 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]);
@@ -1560,9 +1458,6 @@ 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];
@@ -1607,9 +1502,6 @@ 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];
@@ -1664,9 +1556,6 @@ 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] + 
@@ -1735,9 +1624,6 @@ 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];
@@ -1775,9 +1661,6 @@ 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];
@@ -1836,9 +1719,6 @@ 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];
@@ -1899,9 +1779,6 @@ 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];
@@ -1972,9 +1849,6 @@ 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];
@@ -2006,9 +1880,6 @@ 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];
@@ -2069,9 +1940,6 @@ 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];
@@ -2109,13 +1977,6 @@ int qpassc(double *a, double *b, double *c, double *d, double *trigs,
 /* ====================== */
 void fc2gp(double *restrict trig, long *restrict ifax, double *restrict fc, double *restrict gp, long nlat, long nlon, long nlev, long nfc)
 {
-  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                 */
   /*                                                                */
@@ -2136,59 +1997,58 @@ void fc2gp(double *restrict trig, long *restrict ifax, double *restrict fc, doub
   long jump = (nlon + 2);
   long lot  = nlev * nlat;
 
-  double *restrict wfc = (double*) Malloc(lot*jump*sizeof(double));
-#if ! defined(_OPENMP)
-  double *restrict wgp = (double*) Malloc(lot*jump*sizeof(double));
-#endif
+  long nx = (nlon%2 == 1) ? nlon : nlon+1;
+  long nblox = 1 + (lot-1)/NFFT;
+  long nvex  = lot - (nblox-1)*NFFT;
+  long nvex0 = nvex;
+
+  long nthmax = (nblox < ompNumThreads) ? nblox : ompNumThreads;
+  long nvals = lot*jump;
+
+  double *restrict wfc = (double*) Malloc(nvals*sizeof(double));
+  NEW_2D(double, wgp2d, nthmax, nvals);
 
-  for ( lev = 0; lev < nlev; ++lev )
-    {
 #if defined(_OPENMP)
-#pragma omp parallel for default(shared) private(lat, fou, wix, rix)
+#pragma omp parallel for default(shared)
 #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;
-	  /*	  wfc[wix + 1] = 0.5 * wfc[wix]; */
+  for ( long lat = 0; lat < nlat; ++lat )
+    {
+      for ( long lev = 0; lev < nlev; ++lev )
+        {
+	  double *restrict wfcx = wfc + jump * (lat + lev*nlat);
+	  double *restrict fcx = fc + (lat + lev*nlat*nfc);
+	  for ( long fou = 0;   fou < nfc;  ++fou ) wfcx[fou] = fcx[fou*nlat];
+	  for ( long fou = nfc; fou < jump; ++fou ) wfcx[fou] = 0.0;
 	}
     }
 
-  nx = nlon + 1;
-  if ( nlon%2 == 1 ) nx = nlon;
-  nblox = 1 + (lot-1)/NFFT;
-  nvex  = lot - (nblox-1)*NFFT;
-  nvex0 = nvex;
-
-  istartv = (long*) Malloc(nblox*sizeof(long));
+  long *istartv = (long*) Malloc(nblox*sizeof(long));
 
-  istart = 0;
-  for ( nb = 0; nb < nblox; nb++ )
+  long istart = 0;
+  for ( long nb = 0; nb < nblox; nb++ )
     {
       istartv[nb] = istart;
       istart = istart + nvex*jump;
       nvex = NFFT;
     }
 
+  // printf("nblox %ld nvex0 %ld  lot %ld\n",nblox, nvex0, lot);
 #if defined(_OPENMP)
-#pragma omp parallel for default(shared) private(istart, nvex, ix, ii, jj, i, j, k, ia, la, ifac, ibase, jbase)
+#pragma omp parallel for default(shared)
 #endif
-  for ( nb = 0; nb < nblox; nb++ )
+  for ( long nb = 0; nb < nblox; nb++ )
     {
-#if defined(_OPENMP)
-      double *restrict wgp = (double*) Malloc(lot*jump*sizeof(double));
-#endif
-      istart = istartv[nb];
-      if ( nb == 0 ) nvex = nvex0;
-      else           nvex = NFFT;
+      int ompthID = cdo_omp_get_thread_num();
+      double *restrict wgp = wgp2d[ompthID];
+
+      long istart = istartv[nb];
+      long nvex = (nb == 0) ? nvex0 : NFFT;
 
-      i = istart;
+      long i = istart;
 #if defined(SX)
 #pragma vdir nodep
 #endif
-      for ( j = 0; j < nvex; j++ )
+      for ( long j = 0; j < nvex; j++ )
 	{
 	  wfc[i+1] = 0.5*wfc[i];
 	  i += jump;
@@ -2196,18 +2056,18 @@ void fc2gp(double *restrict trig, long *restrict ifax, double *restrict fc, doub
       if ( nlon%2 != 1 )
 	{
 	  i = istart + nlon;
-	  for ( j = 0; j < nvex; j++ )
+	  for ( long j = 0; j < nvex; j++ )
 	    {
 	      wfc[i] = 0.5*wfc[i];
 	      i += jump;
 	    }
 	}
 
-      ia = istart + 1;
-      la = 1;
-      for ( k = 0; k < nfax; ++k )
+      long ia = istart + 1;
+      long la = 1;
+      for ( long k = 0; k < nfax; ++k )
 	{
-	  ifac = ifax[k + 1];
+	  long ifac = ifax[k + 1];
 
 	  if ( k & 1 )
 	    rpassc(wgp, wgp+la, wfc+ia, wfc+ia+ifac*la, trig,
@@ -2224,16 +2084,13 @@ void fc2gp(double *restrict trig, long *restrict ifax, double *restrict fc, doub
 
       if ( nfax%2 != 0 )
 	{
-	  ibase = 0;
-	  jbase = ia;
-	  for ( jj = 0; jj < nvex; jj++ )
+	  long ibase = 0;
+	  long jbase = ia;
+	  for ( long jj = 0; jj < nvex; jj++ )
 	    {
-	      i = ibase;
-	      j = jbase;
-	      for ( ii = 0; ii < nlon; ii++ )
-		{
-		  wfc[j++] = wgp[i++];
-		}
+	      long i = ibase;
+	      long j = jbase;
+	      for ( long ii = 0; ii < nlon; ii++ ) wfc[j++] = wgp[i++];
 	      ibase = ibase + nx;
 	      jbase = jbase + jump;
 	    }
@@ -2241,36 +2098,30 @@ void fc2gp(double *restrict trig, long *restrict ifax, double *restrict fc, doub
 
       /* Fill in zeros at end */
 
-      ix = istart + nlon;
+      long ix = istart + nlon;
 #if defined(SX)
 #pragma vdir nodep
 #endif
-      for ( j = 0; j < nvex; j++ )
+      for ( long j = 0; j < nvex; j++ )
 	{
           wfc[ix]   = 0.0;
           wfc[ix+1] = 0.0;
           ix = ix + jump;
 	}
-
-#if defined(_OPENMP)
-      Free(wgp);
-#endif
     }
 
-  wpt = wfc;
+  double *restrict wpt = wfc;
 
 #if defined(_OPENMP)
-#pragma omp parallel for default(shared) private(j, lon)
+#pragma omp parallel for default(shared)
 #endif
-  for ( j = 0; j < lot; ++j )
-    for ( lon = 0; lon < nlon; ++lon )
+  for ( long j = 0; j < lot; ++j )
+    for ( long lon = 0; lon < nlon; ++lon )
       gp[lon + j*nlon] = wpt[lon + j*jump];
 
   Free(istartv);
-#if ! defined(_OPENMP)
-  Free(wgp);
-#endif
   Free(wfc);
+  DELETE_2D(wgp2d);
 }
 
 
diff --git a/src/after_sptrans.cc b/src/after_sptrans.cc
index 89be7bc..5fe1e58 100644
--- a/src/after_sptrans.cc
+++ b/src/after_sptrans.cc
@@ -417,26 +417,25 @@ void after_legini(int ntr, int nlat, double *restrict poli, double *restrict pol
 
 
 /* to slow for nec, 2.0 instead of 2.3 GFlops ( vector length too small ) */
-void sp2fctest(const double *sa, double *fa, const double *poli, int nlev, int nlat, int nfc, int nt)
+void sp2fctest(const double *sa, double *fa, const double *poli, long nlev, long nlat, long nfc, long nt)
 {
-  int lev, jm, jn, latn, lats, is;
+  long lats, is;
   double sar, sai;
   double saris, saiis;
-  double pval;
   double *restrict far, *restrict fai;
 
   long nsp2 = (nt+1)*(nt+2);
 
-  for ( lev = 0; lev < nlev; lev++ )
+  for ( long lev = 0; lev < nlev; lev++ )
     {
       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++ )
+      for ( long jm = 0; jm <= nt; jm++ )
 	{
-	  for ( jn = 0; jn <= nt - jm; jn++ )
+	  for ( long jn = 0; jn <= nt - jm; jn++ )
 	    {
 	      is = (jn+1)%2 * 2 - 1;
 	      sar = *sal++;
@@ -451,14 +450,13 @@ void sp2fctest(const double *sa, double *fa, const double *poli, int nlev, int n
 #if defined(HAVE_OPENMP4)
 #pragma omp simd
 #endif
-	      for ( latn = 0; latn < nlat/2; latn++ )
+	      for ( long latn = 0; latn < nlat/2; latn++ )
 		{
 		  lats = nlat - latn - 1;
-		  pval = pol[latn];
-		  far[latn] += pval * sar;
-		  fai[latn] += pval * sai;
-		  far[lats] += pval * saris;
-		  fai[lats] += pval * saiis;
+		  far[latn] += pol[latn] * sar;
+		  fai[latn] += pol[latn] * sai;
+		  far[lats] += pol[latn] * saris;
+		  fai[lats] += pol[latn] * saiis;
 		}
 	      pol += nlat;
 	    }
@@ -484,11 +482,10 @@ void sp2fc(const double *sa, double *fa, const double *poli, long nlev, long nla
 
       double *restrict far, *restrict fai;
       double sar, sai;
-      long jmm, jfc, lat;
 
-      for ( jmm = 0; jmm <= nt; jmm++ )
+      for ( long jmm = 0; jmm <= nt; jmm++ )
 	{
-	  for ( jfc = jmm; jfc <= nt; jfc++ )
+	  for ( long jfc = jmm; jfc <= nt; jfc++ )
 	    {
 	      sar = *sal++;
 	      sai = *sal++;
@@ -499,7 +496,7 @@ void sp2fc(const double *sa, double *fa, const double *poli, long nlev, long nla
 #pragma omp simd
 #endif
               */
-	      for ( lat = 0; lat < nlat; lat++ )
+	      for ( long lat = 0; lat < nlat; lat++ )
 		{
 		  far[lat] += pol[lat] * sar;
 		  fai[lat] += pol[lat] * sai;
diff --git a/src/after_vertint.cc b/src/after_vertint.cc
index f512b13..26eaae1 100644
--- a/src/after_vertint.cc
+++ b/src/after_vertint.cc
@@ -85,14 +85,16 @@ void genind(int *nx, const double *restrict plev, const double *restrict fullp,
 #endif
   for ( long lp = 0; lp < nplev; lp++ )
     {
-      long i, lh;
       const double pres = plev[lp];
       int *restrict 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;
-	   }
+      for ( long lh = 0; lh < nhlev; lh++ )
+        {
+          const double *restrict fullpx = fullp + lh*ngp;
+          for ( long i = 0; i < ngp ; i++ )
+            {
+              if ( pres > fullpx[i] ) nxl[i] = lh;
+            }
+        }
     }
 
 }  /* genind */
@@ -263,12 +265,10 @@ void interp_X(const double *restrict gt, double *pt, const double *restrict hyb_
 	    {
 	      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]);
+              ptl[i] = (nh >= ngp*nhlev) ? gt[nl] :
+                        gt[nl] + (pres-hyb_press[nl])
+		     * (gt[nh] - gt[nl])
+                     / (hyb_press[nh] - hyb_press[nl]);
 	    }
 	}
     }
diff --git a/src/afterburner.h b/src/afterburner.h
index a5c98cf..29884be 100644
--- a/src/afterburner.h
+++ b/src/afterburner.h
@@ -242,6 +242,7 @@ 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);
+double *after_get_dataptr(struct Variable *vars, int code, int gridID, int zaxisID, int levelID);
 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);
diff --git a/src/afterburnerlib.cc b/src/afterburnerlib.cc
index 450e724..5190630 100644
--- a/src/afterburnerlib.cc
+++ b/src/afterburnerlib.cc
@@ -1665,8 +1665,7 @@ void after_processML(struct Control *globs, struct Variable *vars)
 	    if ( vars[code].fourier == NULL )
 	      {
 		fieldSize = vars[code].hlev * globs->DimFC;
-		vars[code].fourier = alloc_dp(fieldSize,
-						FieldName(code,"fourier"));
+		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);
 	      }
@@ -1766,8 +1765,7 @@ void after_processML(struct Control *globs, struct Variable *vars)
 	    if ( vars[code].hybrid == NULL )
 	      {
 		fieldSize = globs->DimGP * vars[code].hlev;
-		vars[code].hybrid = alloc_dp(fieldSize,
-					       FieldName(code,"hybrid"));
+		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);
 	      }
@@ -1795,7 +1793,7 @@ void after_processML(struct Control *globs, struct Variable *vars)
       
       if ( globs->Orography == NULL )
 	{
-	  globs-> Orography = alloc_dp(globs->DimGP , "Orography");
+	  globs->Orography = alloc_dp(globs->DimGP , "Orography");
 	  if ( vars[GEOPOTENTIAL].hybrid )
 	    after_copy_array(globs->Orography, vars[GEOPOTENTIAL].hybrid, globs->DimGP);
 	  else
@@ -2221,11 +2219,9 @@ void after_processML(struct Control *globs, struct Variable *vars)
 	   vars[VELOPOT].needed    || vars[STREAM].needed )
 	{
 	  if ( vars[DIVERGENCE].spectral == NULL )
-	    vars[DIVERGENCE].spectral = alloc_dp(globs->DimSP*globs->NumLevelRequest,
-						   "vars[DIVERGENCE].spectral");
+	    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");
+	    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,
@@ -2481,28 +2477,48 @@ void after_AnalysisAddRecord(struct Control *globs, struct Variable *vars, int c
 }
 
 
-void after_EchamAddRecord(struct Control *globs, struct Variable *vars, int code, int gridID, int zaxisID, int levelID, int nmiss)
+double *after_get_dataptr(struct Variable *vars, int code, int gridID, int zaxisID, int levelID)
 {
-  int dataSize;
-  int dataOffset;
-  int nlevel;
-  int gridSize;
-  int gridtype, leveltype;
+  int gridtype   = gridInqType(gridID);
+  int nlevel     = zaxisInqSize(zaxisID);
+  int gridSize   = gridInqSize(gridID);
+  int dataSize   = gridSize*nlevel;
+  int dataOffset = gridSize*levelID;
 
-  gridtype   = gridInqType(gridID);
-  leveltype  = zaxisInqType(zaxisID);
-  nlevel     = zaxisInqSize(zaxisID);
-  gridSize   = gridInqSize(gridID);
-  dataSize   = gridSize*nlevel;
-  dataOffset = gridSize*levelID;
+  double *dataptr = NULL;
+
+  if ( gridtype == GRID_SPECTRAL )
+    {
+      if ( vars[code].spectral0 == NULL )
+	vars[code].spectral0 = alloc_dp(dataSize, FieldName(code, "spectral0"));
+
+      dataptr = vars[code].spectral0+dataOffset;
+    }
+  else
+    {
+      if ( vars[code].hybrid0 == NULL )
+	vars[code].hybrid0 = alloc_dp(dataSize, FieldName(code, "hybrid0"));
+
+      dataptr = vars[code].hybrid0+dataOffset;
+    }
+
+  return dataptr;
+}
+
+
+void after_EchamAddRecord(struct Control *globs, struct Variable *vars, int code, int gridID, int zaxisID, int levelID, int nmiss)
+{
+  int gridtype   = gridInqType(gridID);
+  int leveltype  = zaxisInqType(zaxisID);
+  int nlevel     = zaxisInqSize(zaxisID);
+  int gridSize   = gridInqSize(gridID);
+  int dataSize   = gridSize*nlevel;
+  int 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;
@@ -2511,11 +2527,6 @@ void after_EchamAddRecord(struct Control *globs, struct Variable *vars, int code
 
       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
     {
@@ -2537,14 +2548,10 @@ void after_EchamAddRecord(struct Control *globs, struct Variable *vars, int code
 	      for ( i = 0; i < dataSize; i++ ) vars[code].samp[i] = globs->MeanCount0;
 	    }
 
+          double *dataptr = vars[code].hybrid0+dataOffset;
 	  for ( i = 0; i < gridSize; i++ )
-	    if ( IS_NOT_EQUAL(globs->Field[i], vars[code].missval) ) vars[code].samp[i+dataOffset]++;
+	    if ( IS_NOT_EQUAL(dataptr[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);
     }
 }
 
diff --git a/src/argument.cc b/src/argument.cc
index 6cb69a1..34e0f03 100644
--- a/src/argument.cc
+++ b/src/argument.cc
@@ -1,6 +1,7 @@
 
 #include "argument.h"
 #include "dmemory.h"
+#include "util.h"
 
 #include <string>
 #include <iostream>
@@ -10,16 +11,40 @@
 
 argument_t *file_argument_new(const char *filename)
 {
-  argument_t *argument = (argument_t*) Calloc(1, sizeof(argument_t));
+  argument_t *argument = new argument_t();
 
   argument->argc = 1;
-  argument->argv = (char **) Calloc(1, sizeof(char *));
+  argument->argv.resize(argument->argc);
   argument->argv[0] = (char *) filename;
   argument->args = (char *) filename;
 
   return argument;
 }
 
+
+argument_t * pipe_argument_new(const argument_t *argument,  char *pipename, int pnlen)
+{
+  // struct sched_param param;
+
+  argument_t *newargument = argument_new(argument->argc + 1, argument->argc *sizeof(char *));
+  newargument->operatorName = "";
+  newargument->argv = argument->argv;
+
+  char *operatorArg = argument->argv[0];
+  const char *operatorName = getOperatorName(operatorArg);
+
+  size_t len = strlen(argument->args);
+  char *newarg = (char *) Malloc(len + pnlen);
+  strcpy(newarg, argument->args);
+  newarg[len] = ' ';
+  strcpy(&newarg[len + 1], pipename);
+
+  newargument->argv[argument->argc] = pipename;
+  newargument->args = newarg;
+  newargument->operatorName = std::string(operatorName, strlen(operatorName));
+  return newargument;
+}
+
 void file_argument_free(argument_t *argument)
 {
   if ( argument )
@@ -27,20 +52,19 @@ void file_argument_free(argument_t *argument)
       if ( argument->argc )
         {
           assert(argument->argc == 1);
-          Free(argument->argv);
         }
-      Free(argument);
+      delete(argument);
     }
 }
 
 argument_t *argument_new(size_t argc, size_t len)
 {
-  argument_t *argument = (argument_t*) Calloc(1, sizeof(argument_t));
+  argument_t *argument = new argument_t();
 
   if ( argc > 0 )
     {
       argument->argc = argc;
-      argument->argv = (char **) Calloc(argc, sizeof(char *));
+      argument->argv.resize(argc);
     }
 
   if ( len > 0 )
@@ -60,13 +84,10 @@ void argument_free(argument_t *argument)
             {
               if ( argument->argv[i] )
                 {
-                  Free(argument->argv[i]);
-                  argument->argv[i] = NULL;
+                    argument->argv[i] = NULL;
                 }
             }
 
-          Free(argument->argv);
-          argument->argv = NULL;
           argument->argc = 0;
         }
 
diff --git a/src/argument.h b/src/argument.h
index 986b31f..f45cdc3 100644
--- a/src/argument.h
+++ b/src/argument.h
@@ -2,18 +2,20 @@
 #define ARGUMENT_H
 
 #include <string>
+#include <vector>
 
 struct argument_t
 {
   //argument_t();
   int process_id;
   int    argc;
-  char **argv;
+  std::vector<char *> argv;
   char  *args;
   std::string operatorName;
   char * operatorArguments;
 };
 
+argument_t * pipe_argument_new(const argument_t *argument,  char *pipename, int pnlen);
 argument_t makeArgument(int argc, char *argv[]);
 argument_t *file_argument_new(const char *filename);
 void        file_argument_free(argument_t *argument);
diff --git a/src/cdo.cc b/src/cdo.cc
index de95408..2b3902b 100644
--- a/src/cdo.cc
+++ b/src/cdo.cc
@@ -16,11 +16,7 @@
 */
 
 #if defined(HAVE_CONFIG_H)
-#  include "config.h"
-#endif
-
-#ifndef _XOPEN_SOURCE
-//#define _XOPEN_SOURCE 600 /* gethostname */
+#include "config.h"
 #endif
 
 #if defined (HAVE_EXECINFO_H)
@@ -191,8 +187,8 @@ void cdo_set_digits(const char *optarg)
 static
 void cdo_version(void)
 {
-  const int   filetypes[] = {CDI_FILETYPE_SRV, CDI_FILETYPE_EXT, CDI_FILETYPE_IEG, CDI_FILETYPE_GRB, CDI_FILETYPE_GRB2, CDI_FILETYPE_NC, CDI_FILETYPE_NC2, CDI_FILETYPE_NC4, CDI_FILETYPE_NC4C};
-  const char* typenames[] = {        "srv",        "ext",        "ieg",       "grb1",        "grb2",       "nc1",        "nc2",        "nc4",        "nc4c"};
+  const int   filetypes[] = {CDI_FILETYPE_SRV, CDI_FILETYPE_EXT, CDI_FILETYPE_IEG, CDI_FILETYPE_GRB, CDI_FILETYPE_GRB2, CDI_FILETYPE_NC, CDI_FILETYPE_NC2, CDI_FILETYPE_NC4, CDI_FILETYPE_NC4C, CDI_FILETYPE_NC5};
+  const char* typenames[] = {        "srv",        "ext",        "ieg",       "grb1",        "grb2",       "nc1",        "nc2",        "nc4",        "nc4c",        "nc5"};
 
   fprintf(stderr, "%s\n", CDO_Version);
 #if defined(USER_NAME) && defined(HOST_NAME) && defined(SYSTEM_TYPE)
@@ -238,14 +234,14 @@ void cdo_usage(void)
   set_text_color(stderr, RESET, BLUE);
   fprintf(stderr, "    -a             Generate an absolute time axis\n");
   fprintf(stderr, "    -b <nbits>     Set the number of bits for the output precision\n");
-  fprintf(stderr, "                   (I8/I16/I32/F32/F64 for nc1/nc2/nc4/nc4c; F32/F64 for grb2/srv/ext/ieg; P1 - P24 for grb1/grb2)\n");
+  fprintf(stderr, "                   (I8/I16/I32/F32/F64 for nc1/nc2/nc4/nc4c/nc5; F32/F64 for grb2/srv/ext/ieg; P1 - P24 for grb1/grb2)\n");
   fprintf(stderr, "                   Add L or B to set the byteorder to Little or Big endian\n");
   fprintf(stderr, "    --cmor         CMOR conform NetCDF output\n");
   fprintf(stderr, "    -C, --color    Colorized output messages\n");
   fprintf(stderr, "    --enableexcept <except>\n");
   fprintf(stderr, "                   Set individual floating-point traps (DIVBYZERO, INEXACT, INVALID, OVERFLOW, UNDERFLOW, ALL_EXCEPT)\n");
   fprintf(stderr, "    -f, --format <format>\n");
-  fprintf(stderr, "                   Format of the output file. (grb1/grb2/nc1/nc2/nc4/nc4c/srv/ext/ieg)\n");
+  fprintf(stderr, "                   Format of the output file. (grb1/grb2/nc1/nc2/nc4/nc4c/nc5/srv/ext/ieg)\n");
   fprintf(stderr, "    -g <grid>      Set default grid name or file. Available grids: \n");
   fprintf(stderr, "                   n<N>, t<RES>, tl<RES>, global_<DXY>, r<NX>x<NY>, g<NX>x<NY>, gme<NI>, lon=<LON>/lat=<LAT>\n");
   fprintf(stderr, "    -h, --help     Help information for the operators\n");
@@ -275,7 +271,7 @@ void cdo_usage(void)
   fprintf(stderr, "                   Percentile method: nrank, nist, numpy, numpy_lower, numpy_higher, numpy_nearest\n");
   fprintf(stderr, "    --precision <float_digits[,double_digits]>\n");
   fprintf(stderr, "                   Precision to use in displaying floating-point data (default: 7,15)\n");
-  fprintf(stderr, "    --reduce_dim   Reduce NetCDF dimensions (module: TIMSTAT, FLDSTAT)\n");
+  fprintf(stderr, "    --reduce_dim   Reduce NetCDF dimensions\n");
   if ( ITSME )
     fprintf(stderr, "    --remap_genweights 0/1\n");
   fprintf(stderr, "    -R, --regular  Convert GRIB1 data from reduced to regular grid (cgribex only)\n");
@@ -283,7 +279,7 @@ void cdo_usage(void)
   fprintf(stderr, "    -S             Create an extra output stream for the module TIMSTAT. This stream\n");
   fprintf(stderr, "                   contains the number of non missing values for each output period.\n");
   fprintf(stderr, "    -s, --silent   Silent mode\n");
-  fprintf(stderr, "    --sort         Alphanumeric sorting of NetCDF parameter names\n");
+  fprintf(stderr, "    --sortname     Alphanumeric sorting of NetCDF parameter names\n");
   fprintf(stderr, "    -t <codetab>   Set GRIB1 default parameter code table name or file (cgribex only)\n");
   fprintf(stderr, "                   Predefined tables: ");
   for ( int id = 0; id < tableInqNumber(); id++ )
@@ -438,7 +434,7 @@ void setDefaultDataType(const char *datatypestr)
           else
             {
               fprintf(stderr, "Unsupported number of bits %d!\n", nbits);
-              fprintf(stderr, "Use I8/I16/I32/F32/F64 for nc1/nc2/nc4/nc4c; F32/F64 for grb2/srv/ext/ieg; P1 - P24 for grb1/grb2.\n");
+              fprintf(stderr, "Use I8/I16/I32/F32/F64 for nc1/nc2/nc4/nc4c/nc5; F32/F64 for grb2/srv/ext/ieg; P1 - P24 for grb1/grb2.\n");
               exit(EXIT_FAILURE);
             }
         }
@@ -561,12 +557,14 @@ void setDefaultFileType(const char *filetypestr, int labort)
       const char *ftstr = filetypestr;
       size_t len;
 
+      // clang-format off
       if      ( cmpstrlen(filetypestr, "grb2", len)  == 0 ) { ftstr += len; cdoDefaultFileType = CDI_FILETYPE_GRB2;}
       else if ( cmpstrlen(filetypestr, "grb1", len)  == 0 ) { ftstr += len; cdoDefaultFileType = CDI_FILETYPE_GRB; }
       else if ( cmpstrlen(filetypestr, "grb",  len)  == 0 ) { ftstr += len; cdoDefaultFileType = CDI_FILETYPE_GRB; }
       else if ( cmpstrlen(filetypestr, "nc2",  len)  == 0 ) { ftstr += len; cdoDefaultFileType = CDI_FILETYPE_NC2; }
       else if ( cmpstrlen(filetypestr, "nc4c", len)  == 0 ) { ftstr += len; cdoDefaultFileType = CDI_FILETYPE_NC4C;}
       else if ( cmpstrlen(filetypestr, "nc4",  len)  == 0 ) { ftstr += len; cdoDefaultFileType = CDI_FILETYPE_NC4; }
+      else if ( cmpstrlen(filetypestr, "nc5",  len)  == 0 ) { ftstr += len; cdoDefaultFileType = CDI_FILETYPE_NC5; }
       else if ( cmpstrlen(filetypestr, "nc1",  len)  == 0 ) { ftstr += len; cdoDefaultFileType = CDI_FILETYPE_NC;  }
       else if ( cmpstrlen(filetypestr, "nc",   len)  == 0 ) { ftstr += len; cdoDefaultFileType = CDI_FILETYPE_NC2; }
       else if ( cmpstrlen(filetypestr, "srv",  len)  == 0 ) { ftstr += len; cdoDefaultFileType = CDI_FILETYPE_SRV; }
@@ -577,7 +575,7 @@ void setDefaultFileType(const char *filetypestr, int labort)
           if ( labort )
             {
               fprintf(stderr, "Unsupported filetype %s!\n", filetypestr);
-              fprintf(stderr, "Available filetypes: grb1/grb2/nc1/nc2/nc4/nc4c/srv/ext/ieg\n");
+              fprintf(stderr, "Available filetypes: grb1/grb2/nc1/nc2/nc4/nc4c/nc5/srv/ext/ieg\n");
               exit(EXIT_FAILURE);
             }
           else
@@ -585,6 +583,7 @@ void setDefaultFileType(const char *filetypestr, int labort)
               return;
             }
         }
+      // clang-format on
 
       if ( cdoDefaultFileType != CDI_UNDEFID && *ftstr != 0 )
         {
@@ -598,8 +597,8 @@ void setDefaultFileType(const char *filetypestr, int labort)
             {
               fprintf(stderr, "Unexpected character >%c< in file type >%s<!\n", *ftstr, filetypestr);
               fprintf(stderr, "Use format[_nbits] with:\n");
-              fprintf(stderr, "    format = grb1, grb2, nc1, nc2, nc4, nc4c, srv, ext or ieg\n");
-              fprintf(stderr, "    nbits  = 32/64 for grb2/nc1/nc2/nc4/nc4c/srv/ext/ieg; 1 - 24 for grb1/grb2\n");
+              fprintf(stderr, "    format = grb1, grb2, nc1, nc2, nc4, nc4c, nc5, srv, ext or ieg\n");
+              fprintf(stderr, "    nbits  = 32/64 for grb2/nc1/nc2/nc4/nc4c/nc5/srv/ext/ieg; 1 - 24 for grb1/grb2\n");
               exit(EXIT_FAILURE);
             }
         }
@@ -1010,7 +1009,6 @@ void check_stacksize()
   {
     struct rlimit rlim;
     int status = getrlimit(RLIMIT_STACK, &rlim);
-
     if ( status == 0 )
       {
 #define  MIN_STACK_SIZE  67108864L  /* 64MB */
@@ -1030,6 +1028,7 @@ void check_stacksize()
                   }
                 else
                   fprintf(stderr, "Set stack size to %ld failed!\n", (long) min_stack_size);
+                fprintf(stderr, "\n");
               }
           }
       }
@@ -1049,6 +1048,7 @@ void cdo_set_options(void)
     }
   
   if ( CDO_CMOR_Mode )          cdiDefGlobal("CMOR_MODE", CDO_CMOR_Mode);
+  if ( CDO_Reduce_Dim )         cdiDefGlobal("REDUCE_DIM", CDO_Reduce_Dim);
   if ( CDO_netcdf_hdr_pad > 0 ) cdiDefGlobal("NETCDF_HDR_PAD", CDO_netcdf_hdr_pad);  
 }
 
@@ -1104,6 +1104,7 @@ int parse_options_long(int argc, char *argv[])
   int ldebLevel;
   int lscmode;
 
+  // clang-format off
   struct cdo_option opt_long[] =
     {
       { "precision",         required_argument,        &lprecision,   1  },
@@ -1142,6 +1143,7 @@ int parse_options_long(int argc, char *argv[])
       { "outputGribDataScanningMode", required_argument,  &lscmode,   1  },
       { NULL,                                0,                NULL,  0  }
     };
+  // clang-format on
 
   CDO_opterr = 1;
 
diff --git a/src/cdo_int.h b/src/cdo_int.h
index d5716b1..8ba955c 100644
--- a/src/cdo_int.h
+++ b/src/cdo_int.h
@@ -103,6 +103,12 @@ enum T_EIGEN_MODE  {JACOBI, DANIELSON_LANCZOS};
 #endif
 
 
+#define NEW_2D(T, P2D, N, M)     T **P2D = (N)?new T*[(N)]:nullptr;                          \
+                                 if ((N)) { P2D[0] = (M)?new T[(N)*(M)]:nullptr;             \
+                                            for ( size_t i = 1; i < (size_t) (N); ++i ) P2D[i] = P2D[0] + i*(M); }
+#define DELETE_2D(P2D) if (P2D) { if (P2D[0]) delete[] P2D[0]; delete[] P2D; P2D = nullptr; }
+
+
 #define  IX2D(y,x,nx)  ((y)*(nx)+(x))
 
 #define  MEMTYPE_DOUBLE  1
diff --git a/src/cdo_task.h b/src/cdo_task.h
index 9c8b9bc..c131df4 100644
--- a/src/cdo_task.h
+++ b/src/cdo_task.h
@@ -8,4 +8,4 @@ void *cdo_task_wait(void *task);
 void *cdo_task_new();
 void cdo_task_delete(void *task);
 
-#endif  // CDO_TASK_H
+#endif  /* CDO_TASK_H */
diff --git a/src/cdo_vlist.cc b/src/cdo_vlist.cc
index 470bdeb..a7874d4 100644
--- a/src/cdo_vlist.cc
+++ b/src/cdo_vlist.cc
@@ -274,7 +274,9 @@ void vlistCompare(int vlistID1, int vlistID2, int flag)
 
   if ( lchecknames )
     {
-      char names1[nvars][CDI_MAX_NAME], names2[nvars][CDI_MAX_NAME];
+      NEW_2D(char, names1, nvars, CDI_MAX_NAME);
+      NEW_2D(char, names2, nvars, CDI_MAX_NAME);
+
       for ( varID = 0; varID < nvars; varID++ )
 	vlistInqVarName(vlistID1, varID, names1[varID]);
       for ( varID = 0; varID < nvars; varID++ )
@@ -288,6 +290,9 @@ void vlistCompare(int vlistID1, int vlistID2, int flag)
 
       if ( varID == nvars )
 	cdoPrint("Use CDO option --sortname to sort the parameter by name (NetCDF only)!");
+
+      DELETE_2D(names1);
+      DELETE_2D(names2);
     }
 }
 
diff --git a/src/cdotest.cc b/src/cdotest.cc
index 686a766..3b2516e 100644
--- a/src/cdotest.cc
+++ b/src/cdotest.cc
@@ -108,7 +108,7 @@ void writeNcFile(const char path[], const double array[], int length)
   zaxisID = zaxisCreate(ZAXIS_SURFACE, 1);
   vlistID = vlistCreate();
   
-  varID = vlistDefVar(vlistID, gridID, zaxisID, TSTEP_INSTANT);
+  varID = vlistDefVar(vlistID, gridID, zaxisID, TIME_VARYING);
   vlistDefVarName(vlistID, varID, "test_values");
   vlistDefVarDatatype(vlistID, varID, CDI_DATATYPE_FLT64);
   vlistDefVarMissval(vlistID, varID, MISSVAL);
diff --git a/src/clipping/area.c b/src/clipping/area.c
index 2fa0e5c..d9be5b7 100644
--- a/src/clipping/area.c
+++ b/src/clipping/area.c
@@ -12,7 +12,7 @@
  * 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
+ * URL: https://doc.redmine.dkrz.de/YAC/html/index.html
  *
  * This file is part of YAC.
  *
@@ -180,7 +180,7 @@ double yac_cell_area ( struct grid_cell cell ) {
   double * p[cell.num_corners];
   double u[cell.num_corners][3];
 
-  for (int i = 0; i < cell.num_corners; ++i)
+  for (unsigned i = 0; i < cell.num_corners; ++i)
     p[i] = cell.coordinates_xyz + i * 3;
 
   /* First, compute cross products Uij = Vi x Vj. */
@@ -376,7 +376,7 @@ static inline int compute_norm_vector(double a[], double b[], double norm[]) {
 }
 
 static double
-lat_edge_correction(double base_point[3], double a[3], double b[3],
+lat_edge_correction(double base_vec[3], double a[3], double b[3],
                     double lon_a, double lon_b) {
 
   double const tol = 1e-8;
@@ -413,7 +413,7 @@ lat_edge_correction(double base_point[3], double a[3], double b[3],
   // if the angle between a and b is to small to compute a norm vector
   if (compute_norm_vector(a, b, norm_ab)) return 0.0;
 
-  double scalar_base = scalar_product(norm_ab, base_point);
+  double scalar_base = scalar_product(norm_ab, base_vec);
   double scalar_middle_lat = scalar_product(norm_ab, middle_lat);
 
   // if the base point is on the same plane as a and b
@@ -527,7 +527,7 @@ double yac_planar_3dcell_area (struct grid_cell cell) {
 
   if (cell.num_corners < 3) return area;
 
-  for ( int i0=cell.num_corners-1, i1=0;  i1<cell.num_corners; i0=i1, ++i1) {
+  for ( unsigned 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];
@@ -551,7 +551,7 @@ double yac_huiliers_area (struct grid_cell cell) {
 
   int lat_flag = 0;
 
-  for (int i = 0; i < cell.num_corners; i++)
+  for (unsigned i = 0; i < cell.num_corners; i++)
     lat_flag |= cell.edge_type[i] == LAT_CIRCLE;
 
   if (cell.num_corners == 3 && !lat_flag)
@@ -563,7 +563,7 @@ double yac_huiliers_area (struct grid_cell cell) {
   // sum areas around cell
   double area = 0.0;
 
-  for (int i = 2; i < cell.num_corners; ++i) {
+  for (unsigned i = 2; i < cell.num_corners; ++i) {
 
     double tmp_area = tri_area(cell.coordinates_xyz + 0*3,
                                cell.coordinates_xyz + (i-1)*3,
@@ -585,11 +585,11 @@ double yac_huiliers_area (struct grid_cell cell) {
   // if there is at least one latitude circle edge
   if (lat_flag) {
 
-    for (int i = 0; i < cell.num_corners; ++i) {
+    for (unsigned i = 0; i < cell.num_corners; ++i) {
 
       if (cell.edge_type[i] == LAT_CIRCLE) {
 
-        int i_ = (i+1)%cell.num_corners;
+        unsigned i_ = (i+1)%cell.num_corners;
 
         area += lat_edge_correction(cell.coordinates_xyz + 0 * 3,
                                     cell.coordinates_xyz + i * 3,
diff --git a/src/clipping/area.h b/src/clipping/area.h
index 7882a56..238ac17 100644
--- a/src/clipping/area.h
+++ b/src/clipping/area.h
@@ -9,7 +9,7 @@
 /*
  * Keywords:
  * Maintainer: Rene Redler <rene.redler at mpimet.mpg.de>
- * URL: https://redmine.dkrz.de/doc/YAC/html/index.html
+ * URL: https://doc.redmine.dkrz.de/YAC/html/index.html
  *
  * This file is part of YAC.
  *
diff --git a/src/clipping/clipping.c b/src/clipping/clipping.c
index b86ad0b..76fdce8 100644
--- a/src/clipping/clipping.c
+++ b/src/clipping/clipping.c
@@ -12,7 +12,7 @@
  * 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
+ * URL: https://doc.redmine.dkrz.de/YAC/html/index.html
  *
  * This file is part of YAC.
  *
@@ -155,17 +155,6 @@ void yac_compute_concave_overlap_areas (unsigned N,
                                "(x_coordinates == NULL || y_coordinates == NULL)",
                                __FILE__ , __LINE__);
 
-#ifdef __cplusplus
-  double init_value[3] = {-1};
-  double init_2d_array_value[3*3] = {-1};
-  enum yac_edge_type edge_type_init_value[3]= {GREAT_CIRCLE};
-  struct grid_cell target_partial_cell;
-    target_partial_cell.coordinates_x    = init_value;
-     target_partial_cell.coordinates_y   = init_value;
-     target_partial_cell.coordinates_xyz = init_2d_array_value;
-     target_partial_cell.edge_type       = edge_type_init_value;
-     target_partial_cell.num_corners     = 3;
-#else
   struct grid_cell target_partial_cell =
     {.coordinates_x   = (double[3]){-1},
      .coordinates_y   = (double[3]){-1},
@@ -173,7 +162,6 @@ void yac_compute_concave_overlap_areas (unsigned N,
      .edge_type       = (enum yac_edge_type[3]) {GREAT_CIRCLE},
      .num_corners     = 3};
 
-#endif
   static struct grid_cell * overlap_buffer = NULL;
   static unsigned overlap_buffer_size = 0;
 
@@ -477,11 +465,11 @@ static void point_list_clipping (struct point_list * source_list, int source_ord
   // target lat-circle edges at the end
   {
 
-    int count = 0;
+    unsigned count = 0;
 
     struct point_list_element * curr_tgt_point = target_list.first;
 
-    for (int i = 0; i < nct; ++i, curr_tgt_point = curr_tgt_point->next) {
+    for (unsigned i = 0; i < nct; ++i, curr_tgt_point = curr_tgt_point->next) {
 
       if (curr_tgt_point->edge_type == LAT_CIRCLE) continue;
 
@@ -490,7 +478,7 @@ static void point_list_clipping (struct point_list * source_list, int source_ord
     }
 
     if (count != nct) {
-      for (int i = 0; i < nct; ++i, curr_tgt_point = curr_tgt_point->next) {
+      for (unsigned i = 0; i < nct; ++i, curr_tgt_point = curr_tgt_point->next) {
 
         if (curr_tgt_point->edge_type != LAT_CIRCLE) continue;
 
@@ -500,7 +488,7 @@ static void point_list_clipping (struct point_list * source_list, int source_ord
     }
   }
 
-  for (int i = 0; i < nct; ++i) {
+  for (unsigned i = 0; i < nct; ++i) {
 
     struct point_list_element * curr_src_point = source_list->first;
     struct point_list_element * prev_src_point = source_list->last;
@@ -914,7 +902,7 @@ void yac_cell_clipping (unsigned N,
   if (tgt_cell_type == MIXED_CELL)
     yac_internal_abort_message("invalid target cell type (cell contains edges consisting "
                                "of great circles and circles of latitude)\n",
-			       __FILE__, __LINE__);
+                               __FILE__, __LINE__);
 
   init_point_list(&temp_list);
 
@@ -931,6 +919,17 @@ void yac_cell_clipping (unsigned N,
     return;
   }
 
+  // compute target direction
+  target_ordering = get_cell_points_ordering(&target_list);
+
+  // if all corners of the target cell are on the same great circle
+  if (target_ordering == -1) {
+    free_point_list(&target_list);
+    for (unsigned n = 0; n < N; n++ )
+      overlap_buffer[n].num_corners = 0;
+    return;
+  }
+
   struct point_list_element * prev_tgt_point = target_list.first;
   struct point_list_element * curr_tgt_point = target_list.first->next;
 
@@ -964,9 +963,6 @@ void yac_cell_clipping (unsigned N,
     curr_tgt_point = curr_tgt_point->next;
   }
 
-  // compute target direction
-  target_ordering = get_cell_points_ordering(&target_list);
-
   init_point_list(&source_list);
 
   // for all source cells
@@ -1000,6 +996,9 @@ void yac_cell_clipping (unsigned N,
     // compute source direction
     source_ordering = get_cell_points_ordering(&source_list);
 
+    // if all corners of the source cell are on the same great circle
+    if (source_ordering == -1) continue;
+
     struct point_list * overlap;
 
     // in this case the source an target cell are both LAT_CELL's than the
@@ -1072,6 +1071,9 @@ void yac_correct_weights ( unsigned nSourceCells, double * weight ) {
   unsigned iter;
 
   double weight_diff;
+#ifdef VERBOSE
+  double weight_sum;
+#endif
 
   for ( iter = 1; iter < maxIter; iter++ ) {
 
@@ -1081,6 +1083,9 @@ void yac_correct_weights ( unsigned nSourceCells, double * weight ) {
       weight_diff -= weight[n];
 
 #ifdef VERBOSE
+    for ( n = 0; n < nSourceCells; n++ )
+      weight_sum += weight[n];
+
     printf ("weight sum is %.15f \n", weight_sum);
     printf ("weights are  ");
     for (unsigned i = 0; i < nSourceCells; ++i)
@@ -1126,9 +1131,6 @@ static unsigned get_cell_points_ordering(struct point_list * cell) {
 
   } while (curr != cell->first);
 
-  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 bec14fd..e6a3548 100644
--- a/src/clipping/clipping.h
+++ b/src/clipping/clipping.h
@@ -13,7 +13,7 @@
  * 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
+ * URL: https://doc.redmine.dkrz.de/YAC/html/index.html
  *
  * This file is part of YAC.
  *
diff --git a/src/clipping/dep_list.h b/src/clipping/dep_list.h
index 885cca5..85131f8 100644
--- a/src/clipping/dep_list.h
+++ b/src/clipping/dep_list.h
@@ -15,7 +15,7 @@
  * Keywords:
  * Maintainer: Moritz Hanke <hanke at dkrz.de>
  *             Thomas Jahns <jahns at dkrz.de>
- * URL: https://redmine.dkrz.de/doc/YAC/html/index.html
+ * URL: https://doc.redmine.dkrz.de/YAC/html/index.html
  *
  * This file is part of YAC.
  *
diff --git a/src/clipping/ensure_array_size.c b/src/clipping/ensure_array_size.c
index d680ca5..06da204 100644
--- a/src/clipping/ensure_array_size.c
+++ b/src/clipping/ensure_array_size.c
@@ -9,7 +9,7 @@
 /*
  * Keywords:
  * Maintainer: Moritz Hanke <hanke at dkrz.de>
- * URL: https://redmine.dkrz.de/doc/YAC/html/index.html
+ * URL: https://doc.redmine.dkrz.de/YAC/html/index.html
  *
  * This file is part of YAC.
  *
diff --git a/src/clipping/ensure_array_size.h b/src/clipping/ensure_array_size.h
index 894a81b..c9ae440 100644
--- a/src/clipping/ensure_array_size.h
+++ b/src/clipping/ensure_array_size.h
@@ -12,7 +12,7 @@
  * Keywords:
  * Maintainer: Moritz Hanke <hanke at dkrz.de>
  *             Thomas Jahns <jahns at dkrz.de>
- * URL: https://redmine.dkrz.de/doc/YAC/html/index.html
+ * URL: https://doc.redmine.dkrz.de/YAC/html/index.html
  *
  * This file is part of YAC.
  *
diff --git a/src/clipping/geometry.h b/src/clipping/geometry.h
index e8e4134..0cfe2f4 100644
--- a/src/clipping/geometry.h
+++ b/src/clipping/geometry.h
@@ -19,7 +19,7 @@
  * 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
+ * URL: https://doc.redmine.dkrz.de/YAC/html/index.html
  *
  * This file is part of YAC.
  *
@@ -74,14 +74,23 @@ struct edge {
  */
 struct bounding_circle {
 
-   //! the middle point of the spherical cap in spherical coordinates (in rad)
-   double base_point[2];
    //! the middle point of the spherical cap in cartesian coordinates (is a unit vector)
    double base_vector[3];
    //! angle between the middle point and the boundary of the spherical cap
    double inc_angle; // height >= pi -> everything
 };
 
+/**
+ * defines a spherical cap, which is used as a convex hull to describe the extents of subdomain
+ */
+struct reduced_bounding_circle {
+
+   //! the middle point of the spherical cap in cartesian coordinates (is a unit vector)
+   double base_vector[3];
+   //! cosine of angle between the middle point and the boundary of the spherical cap
+   double cos_inc_angle;
+};
+
 /** \example test_check_overlap.c
  * This contains examples on how to use check_overlap_cells.
  */
diff --git a/src/clipping/grid.h b/src/clipping/grid.h
index cf26ebe..775e721 100644
--- a/src/clipping/grid.h
+++ b/src/clipping/grid.h
@@ -19,7 +19,7 @@
  * 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
+ * URL: https://doc.redmine.dkrz.de/YAC/html/index.html
  *
  * This file is part of YAC.
  *
@@ -129,7 +129,7 @@ void yac_get_2d_grid_extent(struct grid * grid, double (* extent)[2]);
  * @param[in] grid
  * @param[in] cell_index local cell index of the requested cell
  * @param[out] cell requested cell (grid_cell object has be initialised once before)
- * @see init_grid_cell
+ * @see \ref yac_init_grid_cell
  */
 void yac_get_grid_cell (struct grid * grid, unsigned cell_index,
                         struct grid_cell * cell);
@@ -141,7 +141,7 @@ void yac_get_grid_cell (struct grid * grid, unsigned cell_index,
  * @param[in] cell_index local cell index of the requested cell
  * @param[out] cell requested cell (grid_cell object has be initialised once before)
  * @param[out] bnd_circle bounding circle of input cell
- * @see init_grid_cell
+ * @see \ref yac_init_grid_cell
  */
 void yac_get_grid_cell2 (struct grid * grid, unsigned cell_index,
                          struct grid_cell * cell,
diff --git a/src/clipping/grid_cell.c b/src/clipping/grid_cell.c
index ce15c64..b2e0bdc 100644
--- a/src/clipping/grid_cell.c
+++ b/src/clipping/grid_cell.c
@@ -15,7 +15,7 @@
  * Maintainer: Moritz Hanke <hanke at dkrz.de>
  *             Rene Redler <rene.redler at mpimet.mpg.de>
  *             Thomas Jahns <jahns at dkrz.de>
- * URL: https://redmine.dkrz.de/doc/YAC/html/index.html
+ * URL: https://doc.redmine.dkrz.de/YAC/html/index.html
  *
  * This file is part of YAC.
  *
@@ -91,3 +91,43 @@ void yac_free_grid_cell(struct grid_cell * cell) {
 
    yac_init_grid_cell(cell);
 }
+
+#ifdef DEBUG
+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);
+}
+#endif
diff --git a/src/clipping/grid_cell.h b/src/clipping/grid_cell.h
index dc1c5e6..30f5051 100644
--- a/src/clipping/grid_cell.h
+++ b/src/clipping/grid_cell.h
@@ -13,7 +13,7 @@
  * 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
+ * URL: https://doc.redmine.dkrz.de/YAC/html/index.html
  *
  * This file is part of YAC.
  *
@@ -76,4 +76,16 @@ void yac_copy_grid_cell(struct grid_cell in_cell, struct grid_cell * out_cell);
  */
 void yac_free_grid_cell(struct grid_cell * cell);
 
+#ifdef DEBUG
+/**
+ * prints out info about a grid_cell object and reinitialised, used for debugging
+ * interpolation_method_conserv and interpolation_method_patch
+ * the cell
+ * @param[in] stream
+ * @param[in] cell
+ * @param[in] name
+ */
+void print_grid_cell(FILE * stream, struct grid_cell cell, char * name);
+#endif
+
 #endif // GRID_CELL_H
diff --git a/src/clipping/intersection.c b/src/clipping/intersection.c
index 0c906a5..1b800cc 100644
--- a/src/clipping/intersection.c
+++ b/src/clipping/intersection.c
@@ -16,7 +16,7 @@
  * 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
+ * URL: https://doc.redmine.dkrz.de/YAC/html/index.html
  *
  * This file is part of YAC.
  *
@@ -218,9 +218,9 @@ static int vector_is_between_lat (double a[], double b[], double p[]) {
 
          // dot product is most accurate for angles around half PI
          // (for angles very close to half PI: alpha = fabs(acos(alpha))
-         double angle = fabs(cross_cd[0] * a[0] +
+         double angle = fabs((double)(cross_cd[0] * a[0] +
                              cross_cd[1] * a[1] +
-                             cross_cd[2] * a[2]) / length_cross_cd ;
+                             cross_cd[2] * a[2])) / length_cross_cd ;
 
          // if ab is on the plane of cd
          if (fabs(angle) < tol) {
@@ -250,7 +250,7 @@ static int vector_is_between_lat (double a[], double b[], double p[]) {
 
          // dot product is most accurate for angles around half PI
          // (for angles very close to half PI: alpha = fabs(acos(alpha))
-         double angle = fabs(cross_ab[0] * c[0] +
+         double angle = (double)fabsl(cross_ab[0] * c[0] +
                              cross_ab[1] * c[1] +
                              cross_ab[2] * c[2]) / length_cross_ab;
 
@@ -439,7 +439,7 @@ int gcxgc_vec_ (double a[3], double b[3], double c[3], double d[3]) {
 
          // dot product is most accurate for angles around half PI
          // (for angles very close to half PI: alpha = fabs(acos(alpha))
-         double angle = fabs(cross_cd[0] * a[0] +
+         double angle = (double)fabsl(cross_cd[0] * a[0] +
                              cross_cd[1] * a[1] +
                              cross_cd[2] * a[2]) / length_cross_cd ;
 
@@ -459,7 +459,7 @@ int gcxgc_vec_ (double a[3], double b[3], double c[3], double d[3]) {
 
          // dot product is most accurate for angles around half PI
          // (for angles very close to half PI: alpha = fabs(acos(alpha))
-         double angle = fabs(cross_ab[0] * c[0] +
+         double angle = (double) fabsl(cross_ab[0] * c[0] +
                              cross_ab[1] * c[1] +
                              cross_ab[2] * c[2]) / length_cross_ab;
 
@@ -1030,7 +1030,6 @@ int yac_loncxlonc_vec (double a[3], double b[3], double c[3], double d[3],
    return ret_value;
 }
 
-#if !defined(CDO) 
 static
 int loncxlonc_ (struct edge edge_a, struct edge edge_b) {
 
@@ -1103,7 +1102,6 @@ int loncxlonc_ (struct edge edge_a, struct edge edge_b) {
           ((angle_ac + angle_ad) < angle_cd) ||
           ((angle_bc + angle_bd) < angle_cd);
 }
-#endif
 
 /** \brief compute the intersection point of a meridian and a parallel
  *
@@ -1261,10 +1259,10 @@ int yac_loncxlatc_vec (double a[3], double b[3], double c[3], double d[3],
           ((fabs(a[2] - c[2]) < tol)) || (fabs(b[2] - c[2]) < tol))
          ret_value |= 1;
 
-         if (p != NULL)
-            p[0] = c[0], p[1] = c[1], p[2] = c[2];
-         if (q != NULL)
-            q[0] = c[0], q[1] = c[1], q[2] = c[2];
+      if (p != NULL)
+         p[0] = c[0], p[1] = c[1], p[2] = c[2];
+      if (q != NULL)
+         q[0] = c[0], q[1] = c[1], q[2] = c[2];
 
       ret_value |= 4;
 
@@ -1370,23 +1368,25 @@ static int loncxlatc_ (struct edge edge_a, struct edge edge_b) {
    if (fabs(get_angle(edge_a.points[0].lon, edge_a.points[1].lon)) > tol) {
 
       double lat = (edge_a.points[0].lat > 0)?M_PI_2:-M_PI_2;
-    
-      struct edge edge_new_1;
-      edge_new_1.edge_type = LON_CIRCLE;
-      edge_new_1.points[0] = edge_a.points[0];
-      edge_new_1.points[1].lon = edge_a.points[0].lon;
-      edge_new_1.points[1].lat = lat;
-      
-      struct edge edge_new_2;
-      edge_new_2.edge_type = LON_CIRCLE;
-      edge_new_2.points[0] = edge_a.points[1];
-      edge_new_2.points[1].lon = edge_a.points[1].lon;
-      edge_new_2.points[1].lat = lat;
+
       return
-         loncxlatc_(edge_new_1, edge_b)
+         loncxlatc_(
+            (struct edge){
+               .edge_type = LON_CIRCLE,
+               .points = {{.lon = edge_a.points[0].lon,
+                           .lat = edge_a.points[0].lat},
+                          {.lon = edge_a.points[0].lon,
+                           .lat = lat}}}, edge_b)
          ||
-         loncxlatc_(edge_new_2, edge_b);
+         loncxlatc_(
+            (struct edge){
+               .edge_type = LON_CIRCLE,
+               .points = {{.lon = edge_a.points[1].lon,
+                           .lat = edge_a.points[1].lat},
+                          {.lon = edge_a.points[1].lon,
+                           .lat = lat}}}, edge_b);
    }
+
    // if edge b is at the pole
    if (fabs(fabs(edge_b.points[0].lat) - M_PI_2) < tol) {
 
@@ -1905,11 +1905,7 @@ int yac_do_intersect (struct edge edge_a, double a[3], double b[3],
       case ((1 << 1) | (1 << 3)):
          return loncxlatc_(edge_a, edge_b);
       case ((1 << 1) | (1 << 4)):
-#if defined(CDO)
-         yac_internal_abort_message ( "flag not supported in CDO.", __FILE__, __LINE__ );
-#else
          return loncxlonc_(edge_a, edge_b);
-#endif
       case ((1 << 1) | (1 << 5)):
       case ((1 << 2) | (1 << 4)):
       case ((1 << 2) | (1 << 5)):
diff --git a/src/clipping/points.h b/src/clipping/points.h
index 6d4e23b..bfc1444 100644
--- a/src/clipping/points.h
+++ b/src/clipping/points.h
@@ -13,7 +13,7 @@
  * 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
+ * URL: https://doc.redmine.dkrz.de/YAC/html/index.html
  *
  * This file is part of YAC.
  *
@@ -40,11 +40,15 @@
 
 #include "grid.h"
 
+#define YAC_MAX_LOC_STR_LEN 10
+
 enum yac_location {
 
    CELL =   0,
    CORNER = 1,
    EDGE =   2,
+   LOC_UNDEFINED = 3,
+   LOC_INVALID = 4,
 };
 
 struct points {
@@ -56,11 +60,39 @@ struct points {
    struct grid * base_grid;
 
    struct grid * point_grid;
+
+   unsigned unique_id;
 };
 
+/**
+ * converts integer value into enum yac_location
+ * @param[in] location integer value containing a location
+ * @returns location as enum yac_location
+ * @remark if location does not contain a valid value,
+ *         \ref yac_internal_abort_message is called by this routine
+ */
 enum yac_location yac_get_location(int const location);
 
 /**
+ * convertes a string into a enum yac_location
+ * @param[in] location string containing a location
+ * @returns location as enum yac_location
+ * @remark if location does not contain a valid value
+ *         \ref yac_internal_abort_message is called by this routine
+ */
+enum yac_location yac_str2loc(char const * location);
+
+/**
+ * convertes a enum yac_location into a string
+ * @param[in] location location
+ * @returns pointer to location string
+ * @remark if location does not contain a valid value
+ *         \ref yac_internal_abort_message is called by this routine
+ * @remark the user is not allowed to alter or free the returned string
+ */
+char const * yac_loc2str(enum yac_location location);
+
+/**
  * initialises a struct points
  * @param[in,out] points        points to be initialised
  * @param[in]     base_grid     grid on which the points situated
diff --git a/src/clipping/utils.c b/src/clipping/utils.c
index b0ee9a5..2183f89 100644
--- a/src/clipping/utils.c
+++ b/src/clipping/utils.c
@@ -12,7 +12,7 @@
  * 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
+ * URL: https://doc.redmine.dkrz.de/YAC/html/index.html
  *
  * This file is part of YAC.
  *
diff --git a/src/clipping/utils.h b/src/clipping/utils.h
index 0de753f..5c9bebf 100644
--- a/src/clipping/utils.h
+++ b/src/clipping/utils.h
@@ -18,7 +18,7 @@
  * 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
+ * URL: https://doc.redmine.dkrz.de/YAC/html/index.html
  *
  * This file is part of YAC.
  *
@@ -171,10 +171,4 @@ if (!(c)) {\
    abort ();\
 }
 
-#define ASSERT2(c, a, b) \
-if (!(c)) {\
-   fprintf(stderr, "### Assertion violation: %s (%s = %d, %s = %d) in %s:%d\n", #c, #a, a, #b, b, __FILE__, __LINE__);\
-   abort();\
-}
-
 #endif // UTILS_H
diff --git a/src/ecacore.cc b/src/ecacore.cc
index 4ca931e..244c098 100644
--- a/src/ecacore.cc
+++ b/src/ecacore.cc
@@ -67,7 +67,7 @@ void eca1(const ECA_REQUEST_1 *request)
   zaxisID = vlistInqVarZaxis(ivlistID, FIRST_VAR_ID);
   missval = vlistInqVarMissval(ivlistID, FIRST_VAR_ID);
 
-  varID   = vlistDefVar(ovlistID, gridID, zaxisID, TSTEP_INSTANT);
+  varID   = vlistDefVar(ovlistID, gridID, zaxisID, TIME_VARYING);
 
   vlistDefVarMissval(ovlistID, varID, missval);
   
@@ -80,7 +80,7 @@ void eca1(const ECA_REQUEST_1 *request)
 
   if ( IS_SET(request->var2.h2) || IS_SET(request->var2.h3) )
     {
-      varID = vlistDefVar(ovlistID, gridID, zaxisID, TSTEP_INSTANT);
+      varID = vlistDefVar(ovlistID, gridID, zaxisID, TIME_VARYING);
   
       vlistDefVarMissval(ovlistID, varID, missval);
 
@@ -322,7 +322,7 @@ void eca1(const ECA_REQUEST_1 *request)
       taxisDefVtime(otaxisID, ovtime);
       pstreamDefTimestep(ostreamID, otsID);
 
-      if ( otsID && vlistInqVarTsteptype(ivlistID, FIRST_VAR_ID) == TSTEP_CONSTANT ) continue;
+      if ( otsID && vlistInqVarTimetype(ivlistID, FIRST_VAR_ID) == TIME_CONSTANT ) continue;
 
       varID = 0;
       for ( levelID = 0; levelID < nlevels; levelID++ )
@@ -439,7 +439,7 @@ void eca2(const ECA_REQUEST_2 *request)
   missval1 = vlistInqVarMissval(ivlistID1, FIRST_VAR_ID);
   missval2 = vlistInqVarMissval(ivlistID2, FIRST_VAR_ID);
 
-  varID   = vlistDefVar(ovlistID, gridID, zaxisID, TSTEP_INSTANT);
+  varID   = vlistDefVar(ovlistID, gridID, zaxisID, TIME_VARYING);
   
   vlistDefVarMissval(ovlistID, varID, missval1);
 
@@ -452,7 +452,7 @@ void eca2(const ECA_REQUEST_2 *request)
 
   if ( IS_SET(request->var2.h2) )
     {
-      varID = vlistDefVar(ovlistID, gridID, zaxisID, TSTEP_INSTANT);
+      varID = vlistDefVar(ovlistID, gridID, zaxisID, TIME_VARYING);
   
       vlistDefVarMissval(ovlistID, varID, missval1);
 
@@ -710,7 +710,7 @@ void eca2(const ECA_REQUEST_2 *request)
       taxisDefVtime(otaxisID, ovtime);
       pstreamDefTimestep(ostreamID, otsID);
 
-      if ( otsID && vlistInqVarTsteptype(ivlistID1, FIRST_VAR_ID) == TSTEP_CONSTANT ) continue;
+      if ( otsID && vlistInqVarTimetype(ivlistID1, FIRST_VAR_ID) == TIME_CONSTANT ) continue;
 
       varID = 0;
       for ( levelID = 0; levelID < nlevels; levelID++ )
@@ -828,7 +828,7 @@ void eca3(const ECA_REQUEST_3 *request)
   zaxisID = vlistInqVarZaxis(ivlistID1, FIRST_VAR_ID);
   missval = vlistInqVarMissval(ivlistID1, FIRST_VAR_ID);
 
-  varID   = vlistDefVar(ovlistID, gridID, zaxisID, TSTEP_INSTANT);
+  varID   = vlistDefVar(ovlistID, gridID, zaxisID, TIME_VARYING);
 
   vlistDefVarMissval(ovlistID, varID, missval);
   
@@ -962,7 +962,7 @@ void eca3(const ECA_REQUEST_3 *request)
       taxisDefVtime(otaxisID, ovtime);
       pstreamDefTimestep(ostreamID, otsID);
 
-      if ( otsID && vlistInqVarTsteptype(ivlistID1, FIRST_VAR_ID) == TSTEP_CONSTANT ) continue;
+      if ( otsID && vlistInqVarTimetype(ivlistID1, FIRST_VAR_ID) == TIME_CONSTANT ) continue;
 
       varID = 0;
       for ( levelID = 0; levelID < nlevels; levelID++ )
@@ -1026,7 +1026,7 @@ void eca4(const ECA_REQUEST_4 *request)
   int zaxisID = vlistInqVarZaxis(ivlistID1, FIRST_VAR_ID);
   double missval = vlistInqVarMissval(ivlistID1, FIRST_VAR_ID);
 
-  int ovarID1 = vlistDefVar(ovlistID, gridID, zaxisID, TSTEP_INSTANT);
+  int ovarID1 = vlistDefVar(ovlistID, gridID, zaxisID, TIME_VARYING);
 
   vlistDefVarMissval(ovlistID, ovarID1, missval);
 
@@ -1034,7 +1034,7 @@ void eca4(const ECA_REQUEST_4 *request)
   if ( IS_SET(request->longname) )  vlistDefVarLongname(ovlistID, ovarID1, request->longname);
   if ( IS_SET(request->units) )     vlistDefVarUnits(ovlistID, ovarID1, request->units);
 
-  int ovarID2 = vlistDefVar(ovlistID, gridID, zaxisID, TSTEP_INSTANT);
+  int ovarID2 = vlistDefVar(ovlistID, gridID, zaxisID, TIME_VARYING);
   
   vlistDefVarMissval(ovlistID, ovarID2, missval);
 
diff --git a/src/exception.cc b/src/exception.cc
index 70c71a5..2c749c7 100644
--- a/src/exception.cc
+++ b/src/exception.cc
@@ -1,5 +1,5 @@
 #if defined(HAVE_CONFIG_H)
-#  include "config.h"
+#include "config.h"
 #endif
 
 #include <stdarg.h>
@@ -47,8 +47,11 @@ void cdiOpenError(int cdiErrno, const char *fmt, const char *path)
 	case CDI_FILETYPE_NC2:
 	case CDI_FILETYPE_NC4:
 	case CDI_FILETYPE_NC4C:
+	case CDI_FILETYPE_NC5:
           {
-            const char *ncv = (filetype == CDI_FILETYPE_NC4 || filetype == CDI_FILETYPE_NC4C) ? "4" : ((filetype == CDI_FILETYPE_NC2) ? "2" : "");
+            const char *ncv = (filetype == CDI_FILETYPE_NC4 || filetype == CDI_FILETYPE_NC4C) ? "4" :
+              ((filetype == CDI_FILETYPE_NC2) ? "2" :
+               ((filetype == CDI_FILETYPE_NC5) ? "5" : ""));
 #if defined HAVE_LIBNETCDF
             fprintf(stderr, "CDO was build with a NetCDF version which doesn't support NetCDF%s data!\n", ncv);
 #else
@@ -61,8 +64,11 @@ void cdiOpenError(int cdiErrno, const char *fmt, const char *path)
 	}
     }
   
-  if ( _ExitOnError ) pstreamCloseAll();
-  if ( _ExitOnError ) exit(EXIT_FAILURE);
+  if ( _ExitOnError )
+    {
+      pstreamCloseAll();
+      exit(EXIT_FAILURE);
+    }
 }
 
 void cdoAbort(const char *fmt, ...)
@@ -80,8 +86,11 @@ void cdoAbort(const char *fmt, ...)
   reset_text_color(stderr);
   fprintf(stderr, "\n");
 
-  if ( _ExitOnError ) pstreamCloseAll();
-  if ( _ExitOnError ) exit(EXIT_FAILURE);
+  if ( _ExitOnError )
+    {
+      pstreamCloseAll();
+      exit(EXIT_FAILURE);
+    }
 }
 
 
diff --git a/src/expr.cc b/src/expr.cc
index 513cbcb..0fdbdab 100644
--- a/src/expr.cc
+++ b/src/expr.cc
@@ -286,6 +286,7 @@ void oper_expr_con_var(int oper, bool nmiss, size_t n, double missval1, double m
     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]);
+      break;
     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]);
@@ -574,11 +575,11 @@ nodeType *expr_var_var(int init, int oper, nodeType *p1, nodeType *p2)
   int steptype1 = p1->param.steptype;
   int steptype2 = p2->param.steptype;
 
-  if ( p->param.steptype == TSTEP_CONSTANT )
+  if ( p->param.steptype == TIME_CONSTANT )
     {
-      if ( steptype1 != TSTEP_CONSTANT )
+      if ( steptype1 != TIME_CONSTANT )
         p->param.steptype = steptype1;
-      else if ( steptype2 != TSTEP_CONSTANT )
+      else if ( steptype2 != TIME_CONSTANT )
         p->param.steptype = steptype2;
     }
 
diff --git a/src/features.cc b/src/features.cc
index ecddc48..07713c8 100644
--- a/src/features.cc
+++ b/src/features.cc
@@ -23,7 +23,13 @@
 #endif
 
 #if defined(HAVE_LIBCMOR)
+#ifdef __cplusplus
+  extern "C" {
+#endif
 #include "cmor.h"
+#ifdef __cplusplus
+  }
+#endif
 #endif
 
 #include <stdio.h>
diff --git a/src/field.h b/src/field.h
index 952bb6f..1c33abc 100644
--- a/src/field.h
+++ b/src/field.h
@@ -212,6 +212,7 @@ void farcstd(field_type *field1, field_type field2, int nsets, int divisor);
 void farmoq(field_type *field1, field_type field2);
 void farmoqw(field_type *field1, field_type field2, double w);
 void faratan2(field_type *field1, field_type field2);
+void farsetmiss(field_type *field1, field_type field2);
 
 void farcount(field_type *field1, field_type field2);
 
diff --git a/src/field2.cc b/src/field2.cc
index 9845ea6..c1a2058 100644
--- a/src/field2.cc
+++ b/src/field2.cc
@@ -22,20 +22,23 @@
 
 void farfun(field_type *field1, field_type field2, int function)
 {
+  // clang-format off
   switch (function)
     {
-    case func_add:   faradd(field1, field2);   break;
-    case func_min:   farmin(field1, field2);   break;
-    case func_max:   farmax(field1, field2);   break;
-    case func_sum:   farsum(field1, field2);   break;
-    case func_mean:  farsum(field1, field2);   break;
-    case func_avg:   faradd(field1, field2);   break;
-    case func_sub:   farsub(field1, field2);   break;
-    case func_mul:   farmul(field1, field2);   break;
-    case func_div:   fardiv(field1, field2);   break;
-    case func_atan2: faratan2(field1, field2); break;
+    case func_add:     faradd(field1, field2);   break;
+    case func_min:     farmin(field1, field2);   break;
+    case func_max:     farmax(field1, field2);   break;
+    case func_sum:     farsum(field1, field2);   break;
+    case func_mean:    farsum(field1, field2);   break;
+    case func_avg:     faradd(field1, field2);   break;
+    case func_sub:     farsub(field1, field2);   break;
+    case func_mul:     farmul(field1, field2);   break;
+    case func_div:     fardiv(field1, field2);   break;
+    case func_atan2:   faratan2(field1, field2); break;
+    case func_setmiss: farsetmiss(field1, field2); break;
     default: cdoAbort("%s: function %d not implemented!", __func__, function);
     }
+  // clang-format on
 }
 
 static
@@ -426,7 +429,6 @@ void farmul(field_type *field1, field_type field2)
   if ( nwpv != 2 ) nwpv = 1;
 
   int len = nwpv*gridInqSize(grid1);
-
   if ( len != (nwpv*gridInqSize(grid2)) )
     cdoAbort("Fields have different gridsize (%s)", __func__);
 
@@ -460,7 +462,6 @@ void fardiv(field_type *field1, field_type field2)
   if ( nwpv != 2 ) nwpv = 1;
 
   int len = nwpv*gridInqSize(grid1);
-
   if ( len != (nwpv*gridInqSize(grid2)) )
     cdoAbort("Fields have different gridsize (%s)", __func__);
 
@@ -499,6 +500,34 @@ void faratan2(field_type *field1, field_type field2)
 }
 
 
+void farsetmiss(field_type *field1, field_type field2)
+{
+  int nwpv  = field1->nwpv;
+  int grid1 = field1->grid;
+  int grid2 = field2.grid;
+  int nmiss1 = field1->nmiss;
+  double missval1 = field1->missval;
+  double *restrict array1 = field1->ptr;
+  const double *restrict array2 = field2.ptr;
+
+  if ( nwpv != 2 ) nwpv = 1;
+
+  int len = nwpv*gridInqSize(grid1);
+  if ( len != (nwpv*gridInqSize(grid2)) )
+    cdoAbort("Fields have different gridsize (%s)", __func__);
+
+  if ( nmiss1 )
+    {
+      for ( int i = 0; i < len; i++ ) 
+        array1[i] = DBL_IS_EQUAL(array1[i],missval1) ? array2[i] : array1[i];
+
+      field1->nmiss = 0;
+      for ( int i = 0; i < len; i++ )
+        if ( DBL_IS_EQUAL(array1[i], missval1) ) field1->nmiss++;
+    }
+}
+
+
 void farmin(field_type *field1, field_type field2)
 {
   int nwpv   = field1->nwpv;
diff --git a/src/functs.h b/src/functs.h
index 82f67b8..09b2df5 100644
--- a/src/functs.h
+++ b/src/functs.h
@@ -37,6 +37,7 @@
 #define  func_mod      45
 
 #define  func_atan2    50
+#define  func_setmiss  51
 
 #define  func_read     60
 #define  func_write    61
diff --git a/src/gradsdeslib.cc b/src/gradsdeslib.cc
index a14bb51..9d03492 100644
--- a/src/gradsdeslib.cc
+++ b/src/gradsdeslib.cc
@@ -8,7 +8,7 @@
 #include "gradsdeslib.h"
 
 
-static char pout[512];
+static char pout[1024];
 FILE *descr;             /* File descriptor pointer */
 int cal365 = -1;
 int fullyear = -999;
diff --git a/src/grid.cc b/src/grid.cc
index af88889..486cce7 100644
--- a/src/grid.cc
+++ b/src/grid.cc
@@ -160,6 +160,8 @@ void grid_copy_attributes(int gridID1, int gridID2)
   if ( string[0] ) cdiGridDefKeyStr(gridID2, CDI_KEY_XUNITS, strlen(string)+1, string);
   string[0] = 0;   cdiGridInqKeyStr(gridID1, CDI_KEY_YUNITS, CDI_MAX_NAME, string);
   if ( string[0] ) cdiGridDefKeyStr(gridID2, CDI_KEY_YUNITS, strlen(string)+1, string);
+
+  if ( gridInqUvRelativeToGrid(gridID1) ) gridDefUvRelativeToGrid(gridID2, 1);
 }
 
 
@@ -812,6 +814,47 @@ bool check_range(long n, double *vals, double valid_min, double valid_max)
 }
 
 
+bool grid_has_proj4param(int gridID)
+{
+  bool has_proj4param = false;
+
+  int gridtype = gridInqType(gridID);
+  if ( gridtype == GRID_PROJECTION )
+    {
+      int atttype, attlen, atttxtlen = 0;
+      char *atttxt = NULL;
+      char attname[CDI_MAX_NAME+1];
+
+      int natts;
+      cdiInqNatts(gridID, CDI_GLOBAL, &natts);
+
+      for ( int iatt = 0; iatt < natts; ++iatt )
+        {
+          cdiInqAtt(gridID, CDI_GLOBAL, iatt, attname, &atttype, &attlen);
+
+          if ( atttype == CDI_DATATYPE_TXT )
+            {
+              if ( attlen > atttxtlen )
+                {
+                  atttxt = (char*) Realloc(atttxt, (attlen+1));
+                  atttxtlen = attlen;
+                }
+              cdiInqAttTxt(gridID, CDI_GLOBAL, attname, attlen, atttxt);
+              atttxt[attlen] = 0;
+              if ( strcmp(attname, "proj4_params") == 0 )
+                {
+                  has_proj4param = true;
+                  break;
+                }
+            }
+        }
+      if ( atttxt ) Free(atttxt);
+    }
+
+  return has_proj4param;
+}
+
+static
 char *grid_get_proj4param(int gridID)
 {
   char *proj4param = NULL;
@@ -866,7 +909,7 @@ int gridToCurvilinear(int gridID1, int lbounds)
 
   size_t gridsize = gridInqSize(gridID1);
   int gridID2 = gridCreate(GRID_CURVILINEAR, gridsize);
-  gridDefPrec(gridID2, CDI_DATATYPE_FLT32);
+  gridDefDatatype(gridID2, CDI_DATATYPE_FLT32);
 
   char *proj4param = NULL;
   bool lproj4     = false;
@@ -1197,7 +1240,7 @@ int gridToUnstructured(int gridID1, int lbounds)
   int gridtype = gridInqType(gridID1);
   size_t gridsize = gridInqSize(gridID1);
   int gridID2  = gridCreate(GRID_UNSTRUCTURED, gridsize);
-  gridDefPrec(gridID2, CDI_DATATYPE_FLT32);
+  gridDefDatatype(gridID2, CDI_DATATYPE_FLT32);
 	  
   bool lproj_rll = false;
   if ( gridtype == GRID_PROJECTION && gridInqProjType(gridID1) == CDI_PROJ_RLL )
@@ -1461,7 +1504,7 @@ int gridCurvilinearToRegular(int gridID1)
       gridDefXsize(gridID2, nx);
       gridDefYsize(gridID2, ny);
       
-      //  gridDefPrec(gridID2, CDI_DATATYPE_FLT32);
+      //  gridDefDatatype(gridID2, CDI_DATATYPE_FLT32);
 
       char xunits[CDI_MAX_NAME]; xunits[0] = 0;
       char yunits[CDI_MAX_NAME]; yunits[0] = 0;
diff --git a/src/grid.h b/src/grid.h
index 4dbfaca..a8a52b9 100644
--- a/src/grid.h
+++ b/src/grid.h
@@ -94,6 +94,8 @@ void usvs_to_uv(double us, double vs, double phi, double rla,
 
 void cdo_print_grid(int gridID, int opt);
 
+bool grid_has_proj4param(int gridID);
+
 // Define a de-staggered grid for U and V
 int cdo_define_destagered_grid(int gridID_u_stag, int gridID_v_stag, double *destagGridOffsets);
 
diff --git a/src/grid_define.cc b/src/grid_define.cc
index b2ddd28..474ae18 100644
--- a/src/grid_define.cc
+++ b/src/grid_define.cc
@@ -194,7 +194,7 @@ int cdo_define_sample_grid(int gridSrcID, int sampleFactor)
   gridDefYsize(gridID_sampled, ysize);
 
   gridDefNP(gridID_sampled, gridInqNP(gridSrcID));
-  gridDefPrec(gridID_sampled, gridInqPrec(gridSrcID));
+  gridDefDatatype(gridID_sampled, gridInqDatatype(gridSrcID));
   if ( gridInqUvRelativeToGrid(gridSrcID) ) gridDefUvRelativeToGrid(gridID_sampled, 1);
 
   grid_copy_attributes(gridSrcID, gridID_sampled);
@@ -375,7 +375,7 @@ int cdo_define_subgrid_grid(int gridSrcID, int subI0, int subI1, int subJ0, int
     }
 
   gridDefNP(gridID_sampled, gridInqNP(gridSrcID));
-  gridDefPrec(gridID_sampled, gridInqPrec(gridSrcID));
+  gridDefDatatype(gridID_sampled, gridInqDatatype(gridSrcID));
   if ( gridInqUvRelativeToGrid(gridSrcID) ) gridDefUvRelativeToGrid(gridID_sampled, 1);
 
   grid_copy_attributes(gridSrcID, gridID_sampled);
diff --git a/src/grid_print.cc b/src/grid_print.cc
index 3866002..c805616 100644
--- a/src/grid_print.cc
+++ b/src/grid_print.cc
@@ -152,7 +152,7 @@ void grid_print_kernel(int gridID, int opt, FILE *fp)
   int xsize    = gridInqXsize(gridID);
   int ysize    = gridInqYsize(gridID);
   int nvertex  = gridInqNvertex(gridID);
-  int prec     = gridInqPrec(gridID);
+  int prec     = gridInqDatatype(gridID);
   int xstrlen  = gridInqXIsc(gridID);
   int ystrlen  = gridInqYIsc(gridID);
 
diff --git a/src/grid_proj.cc b/src/grid_proj.cc
index 9868a31..8911b0f 100644
--- a/src/grid_proj.cc
+++ b/src/grid_proj.cc
@@ -56,7 +56,7 @@ char *gen_param(const char *fmt, ...)
 }
 
 static
-void verify_lcc_parameter(double missval, double lon_0, double lat_0, double lat_1, double lat_2, double a, double rf, double x_0, double y_0)
+void verify_lcc_parameter(double lon_0, double lat_0, double lat_1, double lat_2, double a, double rf, double x_0, double y_0)
 {
   const char *projection = "lambert_conformal_conic";
 
@@ -246,7 +246,7 @@ int cdo_lcc_to_lonlat(int gridID, size_t nvals, double *xvals, double *yvals)
 
   if ( status ) cdoAbort("%s mapping parameter missing!", projection);
 
-  verify_lcc_parameter(grid_missval, lon_0, lat_0, lat_1, lat_2, a, rf, x_0, y_0);
+  verify_lcc_parameter(lon_0, lat_0, lat_1, lat_2, a, rf, x_0, y_0);
 
   lcc_to_lonlat(grid_missval, lon_0, lat_0, lat_1, lat_2, a, rf, x_0, y_0, nvals, xvals, yvals);
 
@@ -325,8 +325,8 @@ bool cdiInqAttConvertedToFloat(int gridID, int atttype, const char *attname, int
 
   if ( atttype == CDI_DATATYPE_INT32 )
     {
-      int attint[attlen];
-      cdiInqAttInt(gridID, CDI_GLOBAL, attname, attlen, attint);
+      std::vector<int> attint(attlen);
+      cdiInqAttInt(gridID, CDI_GLOBAL, attname, attlen, attint.data());
       for ( int i = 0; i < attlen; ++i ) attflt[i] = (double)attint[i];
     }
   else if ( atttype == CDI_DATATYPE_FLT32 || atttype == CDI_DATATYPE_FLT64 )
diff --git a/src/grid_read.cc b/src/grid_read.cc
index 1af751d..b2c44c9 100644
--- a/src/grid_read.cc
+++ b/src/grid_read.cc
@@ -93,7 +93,14 @@ void grid_read_data(size_t ikv, size_t nkv, kvmap_t *kvmap, griddes_t *grid, siz
           if ( grid->type == GRID_LONLAT || grid->type == GRID_GAUSSIAN ) grid->nvertex = 2;
           else if ( grid->type == GRID_CURVILINEAR ) grid->nvertex = 4;
         }
-      else if ( STR_IS_EQ(key, "gridprec") )       grid->prec = parameter2int(value);
+      else if ( STR_IS_EQ(key, "datatype") )
+        {
+          const char *datatype = parameter2word(value);
+
+          if      ( STR_IS_EQ(datatype, "double") )  grid->datatype = CDI_DATATYPE_FLT64;
+          else if ( STR_IS_EQ(datatype, "float") )   grid->datatype = CDI_DATATYPE_FLT32;
+	  else cdoAbort("Invalid datatype : %s (zaxis description file: %s)", datatype, dname);
+        }
       else if ( STR_IS_EQ(key, "gridsize") )       grid->size = parameter2int(value);
       else if ( STR_IS_EQ(key, "xsize") )          grid->xsize = parameter2int(value);
       else if ( STR_IS_EQ(key, "nlon") )           grid->xsize = parameter2int(value);
@@ -211,7 +218,7 @@ void grid_read_data(size_t ikv, size_t nkv, kvmap_t *kvmap, griddes_t *grid, siz
         }
       else if ( STR_IS_EQ(key, "grid_mapping_name") ) { *igmap = ik; break; }
       else if ( STR_IS_EQ(key, "grid_mapping") ) { *igmap = ik; break; }
-      else cdoAbort("Invalid parameter : >%s< (grid description file: %s)", key, dname);
+      else cdoAbort("Invalid key word >%s< (grid description file: %s)", key, dname);
     }
 }
 
@@ -281,11 +288,11 @@ int grid_read(FILE *gfp, const char *dname)
     {
       keyValues_t *kv = *(keyValues_t **)kvnode->data;
       if ( ik == 0 && !STR_IS_EQ(kv->key, "gridtype") )
-        cdoAbort("First grid description parameter must be >gridtype< (found: %s)!", kv->key);
+        cdoAbort("First grid description key word must be >gridtype< (found: %s)!", kv->key);
 
       if ( kv->nvalues == 0 )
         {
-          cdoWarning("Grid description parameter %s has no values, skipped!", kv->key);
+          cdoWarning("Grid description key word %s has no values, skipped!", kv->key);
         }
       else
         {
diff --git a/src/grid_search.cc b/src/grid_search.cc
index ff7cb1c..e3e24e1 100644
--- a/src/grid_search.cc
+++ b/src/grid_search.cc
@@ -35,7 +35,8 @@ double cdo_default_search_radius(void)
   return search_radius;
 }
 
-static inline void LLtoXYZ_f(double lon, double lat, float *restrict xyz)
+static inline
+void LLtoXYZ_f(double lon, double lat, float *restrict xyz)
 {
    double cos_lat = cos(lat);
    xyz[0] = cos_lat * cos(lon);
@@ -43,7 +44,8 @@ static inline void LLtoXYZ_f(double lon, double lat, float *restrict xyz)
    xyz[2] = sin(lat);
 }
 
-static inline void LLtoXYZ_kd(double lon, double lat, kdata_t *restrict xyz)
+static inline
+void LLtoXYZ_kd(double lon, double lat, kdata_t *restrict xyz)
 {
    double cos_lat = cos(lat);
    xyz[0] = KDATA_SCALE(cos_lat * cos(lon));
@@ -51,13 +53,13 @@ static inline void LLtoXYZ_kd(double lon, double lat, kdata_t *restrict xyz)
    xyz[2] = KDATA_SCALE(sin(lat));
 }
 
-static
+static constexpr
 float square(const float x)
 {
   return x*x;
 }
 
-static
+static constexpr
 float distance(const float *restrict a, const float *restrict b)
 {
   return (square((a[0]-b[0]))+square((a[1]-b[1]))+square((a[2]-b[2])));
@@ -74,7 +76,7 @@ void gridsearch_set_method(const char *methodstr)
 }
 
 
-struct gridsearch *gridsearch_create_reg2d(bool lcyclic, unsigned nx, unsigned ny, const double *restrict lons, const double *restrict lats)
+struct gridsearch *gridsearch_create_reg2d(bool lcyclic, size_t nx, size_t ny, const double *restrict lons, const double *restrict lats)
 {
   struct gridsearch *gs = (struct gridsearch *) Calloc(1, sizeof(struct gridsearch));
 
@@ -95,7 +97,7 @@ struct gridsearch *gridsearch_create_reg2d(bool lcyclic, unsigned nx, unsigned n
   double *coslat = (double *) Malloc(ny*sizeof(double));
   double *sinlat = (double *) Malloc(ny*sizeof(double));
 
-  for ( unsigned n = 0; n < nx; ++n )
+  for ( size_t n = 0; n < nx; ++n )
     {
       double rlon = lons[n];
       if ( rlon > PI2 ) rlon -= PI2;
@@ -103,7 +105,7 @@ struct gridsearch *gridsearch_create_reg2d(bool lcyclic, unsigned nx, unsigned n
       coslon[n] = cos(rlon);
       sinlon[n] = sin(rlon);
     }
-  for ( unsigned n = 0; n < ny; ++n )
+  for ( size_t n = 0; n < ny; ++n )
     {
       coslat[n] = cos(lats[n]);
       sinlat[n] = sin(lats[n]);
@@ -123,11 +125,11 @@ struct gridsearch *gridsearch_create_reg2d(bool lcyclic, unsigned nx, unsigned n
 }
 
 
-struct kdNode *gs_create_kdtree(unsigned n, const double *restrict lons, const double *restrict lats)
+struct kdNode *gs_create_kdtree(size_t n, const double *restrict lons, const double *restrict lats)
 {
   struct kd_point *pointlist = (struct kd_point *) Malloc(n * sizeof(struct kd_point));  
   // see  example_cartesian.c
-  if ( cdoVerbose ) printf("kdtree lib init 3D: n=%d  nthreads=%d\n", n, ompNumThreads);
+  if ( cdoVerbose ) printf("kdtree lib init 3D: n=%zu  nthreads=%d\n", n, ompNumThreads);
   kdata_t min[3], max[3];
   min[0] = min[1] = min[2] =  1e9;
   max[0] = max[1] = max[2] = -1e9;
@@ -135,11 +137,11 @@ struct kdNode *gs_create_kdtree(unsigned n, const double *restrict lons, const d
 #if defined(HAVE_OPENMP4)
 #pragma omp simd
 #endif
-  for ( unsigned i = 0; i < n; i++ ) 
+  for ( size_t i = 0; i < n; i++ ) 
     {
       point = pointlist[i].point;
       LLtoXYZ_kd(lons[i], lats[i], point);
-      for ( unsigned j = 0; j < 3; ++j )
+      for ( size_t j = 0; j < 3; ++j )
         {
           min[j] = point[j] < min[j] ? point[j] : min[j];
           max[j] = point[j] > max[j] ? point[j] : max[j];
@@ -172,20 +174,20 @@ void gs_destroy_nearpt3(struct gsNear *near)
 }
 
 
-struct gsNear *gs_create_nearpt3(unsigned n, const double *restrict lons, const double *restrict lats)
+struct gsNear *gs_create_nearpt3(size_t n, const double *restrict lons, const double *restrict lats)
 {
   struct gsNear *near = (struct gsNear *) Calloc(1, sizeof(struct gsNear));
 
   Coord_T **p = (Coord_T **) Malloc(n*sizeof(Coord_T *));
   p[0] = (Coord_T *) Malloc(3*n*sizeof(Coord_T));
-  for ( unsigned i = 1; i < n; i++ ) p[i] = p[0] + i*3;
+  for ( size_t i = 1; i < n; i++ ) p[i] = p[0] + i*3;
 
   float point[3];
 
 #if defined(HAVE_OPENMP4)
 #pragma omp simd
 #endif
-  for ( unsigned i = 0; i < n; i++ )
+  for ( size_t i = 0; i < n; i++ )
     {
       LLtoXYZ_f(lons[i], lats[i], point);
 
@@ -223,18 +225,18 @@ void gs_destroy_full(struct gsFull *full)
 }
 
 
-struct gsFull *gs_create_full(unsigned n, const double *restrict lons, const double *restrict lats)
+struct gsFull *gs_create_full(size_t n, const double *restrict lons, const double *restrict lats)
 {
   struct gsFull *full = (struct gsFull *) Calloc(1, sizeof(struct gsFull));
 
   float **p = (float **) Malloc(n*sizeof(float *));
   p[0] = (float *) Malloc(3*n*sizeof(float));
-  for ( unsigned i = 1; i < n; i++ ) p[i] = p[0] + i*3;
+  for ( size_t i = 1; i < n; i++ ) p[i] = p[0] + i*3;
 
 #if defined(HAVE_OPENMP4)
 #pragma omp simd
 #endif
-  for ( unsigned i = 0; i < n; i++ )
+  for ( size_t i = 0; i < n; i++ )
     {
       LLtoXYZ_f(lons[i], lats[i], p[i]);
     }
@@ -248,7 +250,7 @@ struct gsFull *gs_create_full(unsigned n, const double *restrict lons, const dou
 }
 
 
-struct gridsearch *gridsearch_create(unsigned n, const double *restrict lons, const double *restrict lats)
+struct gridsearch *gridsearch_create(size_t n, const double *restrict lons, const double *restrict lats)
 {
   struct gridsearch *gs = (struct gridsearch *) Calloc(1, sizeof(struct gridsearch));
 
@@ -263,7 +265,7 @@ struct gridsearch *gridsearch_create(unsigned n, const double *restrict lons, co
 }
 
 
-struct gridsearch *gridsearch_create_nn(unsigned n, const double *restrict lons, const double *restrict lats)
+struct gridsearch *gridsearch_create_nn(size_t n, const double *restrict lons, const double *restrict lats)
 {
   struct gridsearch *gs = (struct gridsearch *) Calloc(1, sizeof(struct gridsearch));
 
@@ -341,7 +343,7 @@ kdNode *gs_nearest_kdtree(kdNode *kdt, double lon, double lat, double *prange)
 
 unsigned gs_nearest_nearpt3(struct gsNear *near, double lon, double lat, double *prange)
 {
-  unsigned index = GS_NOT_FOUND;
+  size_t index = GS_NOT_FOUND;
   if ( near == NULL ) return index;
   
 #if defined(ENABLE_NEARPT3)
@@ -379,9 +381,9 @@ unsigned gs_nearest_nearpt3(struct gsNear *near, double lon, double lat, double
 }
 
 
-unsigned gs_nearest_full(struct  gsFull *full, double lon, double lat, double *prange)
+size_t gs_nearest_full(struct  gsFull *full, double lon, double lat, double *prange)
 {
-  unsigned index = GS_NOT_FOUND;
+  size_t index = GS_NOT_FOUND;
   if ( full == NULL ) return index;
   
   float range0 = gs_set_range(prange);
@@ -389,26 +391,26 @@ unsigned gs_nearest_full(struct  gsFull *full, double lon, double lat, double *p
   float point[3];
   LLtoXYZ_f(lon, lat, point);
 
-  int n = full->n;
+  size_t n = full->n;
   float **pts = full->pts;
-  int closestpt = -1;
+  size_t closestpt = n;
   float dist = FLT_MAX;
-  for ( int i = 0; i < n; i++ )
+  for ( size_t i = 0; i < n; i++ )
     {
       float d = distance(point, pts[i]);
-      if ( closestpt < 0 || d < dist || (d<=dist && i < closestpt) )
+      if ( closestpt >=n || d < dist || (d<=dist && i < closestpt) )
         {
           dist = d;
           closestpt = i;
         }
     }
 
-  if ( closestpt >= 0 )
+  if ( closestpt < n )
     {
       if ( dist < range0 )
         {
           *prange = dist;
-          index = (unsigned) closestpt;
+          index = closestpt;
         }
     }
   
@@ -416,9 +418,9 @@ unsigned gs_nearest_full(struct  gsFull *full, double lon, double lat, double *p
 }
 
 
-unsigned gridsearch_nearest(struct gridsearch *gs, double lon, double lat, double *prange)
+size_t gridsearch_nearest(struct gridsearch *gs, double lon, double lat, double *prange)
 {
-  unsigned index = GS_NOT_FOUND;
+  size_t index = GS_NOT_FOUND;
 
   if ( gs )
     {
@@ -445,7 +447,7 @@ unsigned gridsearch_nearest(struct gridsearch *gs, double lon, double lat, doubl
 }
 
 
-struct pqueue *gridsearch_qnearest(struct gridsearch *gs, double lon, double lat, double *prange, unsigned nnn)
+struct pqueue *gridsearch_qnearest(struct gridsearch *gs, double lon, double lat, double *prange, size_t nnn)
 {
   if ( gs->kdt == NULL ) return NULL;
   
@@ -485,7 +487,7 @@ struct pqueue *gridsearch_qnearest(struct gridsearch *gs, double lon, double lat
 #define  TINY     1.e-14
 
 static
-void knn_store_distance(int nadd, double distance, int num_neighbors, int *restrict nbr_add, double *restrict nbr_dist)
+void knn_store_distance(size_t nadd, double distance, size_t num_neighbors, size_t *restrict nbr_add, double *restrict nbr_dist)
 {
   if ( num_neighbors == 1 )
     {
@@ -497,11 +499,11 @@ void knn_store_distance(int nadd, double distance, int num_neighbors, int *restr
     }
   else
     {
-      for ( int nchk = 0; nchk < num_neighbors; ++nchk )
+      for ( size_t nchk = 0; nchk < num_neighbors; ++nchk )
 	{
 	  if ( distance < nbr_dist[nchk] || (distance <= nbr_dist[nchk] && nadd < nbr_add[nchk]) )
 	    {
-	      for ( int n = num_neighbors-1; n > nchk; --n )
+	      for ( size_t n = num_neighbors-1; n > nchk; --n )
 		{
 		  nbr_add[n]  = nbr_add[n-1];
 		  nbr_dist[n] = nbr_dist[n-1];
@@ -515,36 +517,36 @@ void knn_store_distance(int nadd, double distance, int num_neighbors, int *restr
 }
 
 static
-void knn_check_distance(int num_neighbors, const int *restrict nbr_add, double *restrict nbr_dist)
+void knn_check_distance(size_t num_neighbors, const size_t *restrict nbr_add, double *restrict nbr_dist)
 {
   // If distance is zero, set to small number
-  for ( int nchk = 0; nchk < num_neighbors; ++nchk )
-    if ( nbr_add[nchk] >= 0 && nbr_dist[nchk] <= 0. ) nbr_dist[nchk] = TINY;
+  for ( size_t nchk = 0; nchk < num_neighbors; ++nchk )
+    if ( nbr_add[nchk] != GS_NOT_FOUND && nbr_dist[nchk] <= 0. ) nbr_dist[nchk] = TINY;
 }
 
 
 void gridsearch_knn_init(struct gsknn *knn)
 {
   unsigned ndist = knn->ndist;
-  int *restrict add = knn->add;
+  size_t *restrict add = knn->add;
   double *restrict dist = knn->dist;
 
-  for ( unsigned i = 0; i < ndist; ++i )
+  for ( size_t i = 0; i < ndist; ++i )
     {
-      add[i]  = -1;
+      add[i]  = GS_NOT_FOUND;
       dist[i] = BIGNUM;
     }
 }
 
 
-struct gsknn *gridsearch_knn_new(unsigned size)
+struct gsknn *gridsearch_knn_new(size_t size)
 {
   struct gsknn *knn = (struct gsknn *) Malloc(sizeof(struct gsknn));
   
   knn->ndist   = size;
   knn->size    = size;
   knn->mask    = (bool*) Malloc(size*sizeof(bool));     // mask at nearest neighbors
-  knn->add     = (int*) Malloc(size*sizeof(int));       // source address at nearest neighbors
+  knn->add     = (size_t*) Malloc(size*sizeof(size_t)); // source address at nearest neighbors
   knn->dist    = (double*) Malloc(size*sizeof(double)); // angular distance of the nearest neighbors
   knn->tmpadd  = NULL;
   knn->tmpdist = NULL;
@@ -570,7 +572,7 @@ void gridsearch_knn_delete(struct gsknn *knn)
 }
 
 
-int gridsearch_knn(struct gridsearch *gs, struct gsknn *knn, double plon, double plat)
+size_t gridsearch_knn(struct gridsearch *gs, struct gsknn *knn, double plon, double plat)
 {
   /*
     Output variables:
@@ -589,30 +591,30 @@ int gridsearch_knn(struct gridsearch *gs, struct gsknn *knn, double plon, double
   // Initialize distance and address arrays
   gridsearch_knn_init(knn);
 
-  int num_neighbors = knn->size;
-  int *restrict nbr_add = knn->add;
+  size_t num_neighbors = knn->size;
+  size_t *restrict nbr_add = knn->add;
   double *restrict nbr_dist = knn->dist;
 
-  int ndist = num_neighbors;
+  size_t ndist = num_neighbors;
   // check some more points if distance is the same use the smaller index (nadd)
   if ( ndist > 8 ) ndist += 8;
   else             ndist *= 2; 
-  if ( ndist > (int)gs->n ) ndist = gs->n;
+  if ( ndist > gs->n ) ndist = gs->n;
 
-  if ( knn->tmpadd  == NULL ) knn->tmpadd  = (int*) Malloc(ndist*sizeof(int));
+  if ( knn->tmpadd  == NULL ) knn->tmpadd  = (size_t*) Malloc(ndist*sizeof(size_t));
   if ( knn->tmpdist == NULL ) knn->tmpdist = (double*) Malloc(ndist*sizeof(double));
 
-  int *adds = knn->tmpadd;
+  size_t *adds = knn->tmpadd;
   double *dist = knn->tmpdist;
   
   const double range0 = SQR(search_radius);
   double range = range0;
 
-  int j = 0;
+  size_t j = 0;
 
   if ( num_neighbors == 1 )
     {
-      unsigned nadd = gridsearch_nearest(gs, plon, plat, &range);
+      size_t nadd = gridsearch_nearest(gs, plon, plat, &range);
       if ( nadd != GS_NOT_FOUND )
         {
           //if ( range < range0 )
@@ -628,7 +630,7 @@ int gridsearch_knn(struct gridsearch *gs, struct gsknn *knn, double plon, double
       struct pqueue *gs_result = gridsearch_qnearest(gs, plon, plat, &range, ndist);
       if ( gs_result )
         {
-          unsigned nadd;
+          size_t nadd;
           struct resItem *p;
           while ( pqremove_min(gs_result, &p) )
             {
@@ -649,7 +651,7 @@ int gridsearch_knn(struct gridsearch *gs, struct gsknn *knn, double plon, double
     }
 
   ndist = j;
-  int max_neighbors = ( ndist < num_neighbors ) ? ndist : num_neighbors;
+  size_t max_neighbors = (ndist < num_neighbors) ? ndist : num_neighbors;
 
   for ( j = 0; j < ndist; ++j )
     knn_store_distance(adds[j], dist[j], max_neighbors, nbr_add, nbr_dist);
diff --git a/src/grid_search.h b/src/grid_search.h
index e070234..a9eaf92 100644
--- a/src/grid_search.h
+++ b/src/grid_search.h
@@ -6,7 +6,7 @@
 #include "kdtreelib/kdtree.h"
 #include "nearpt3c.h"
 
-#define GS_NOT_FOUND  INT_MAX
+#define GS_NOT_FOUND  ULONG_MAX
 
 
 enum T_GRIDSEARCH_METHOD_NN  {GS_FULL=1, GS_KDTREE, GS_NEARPT3};
@@ -28,8 +28,8 @@ struct gsNear {
 
 struct gridsearch {
   int method_nn;
-  unsigned n;
-  unsigned nx, ny;
+  size_t n;
+  size_t nx, ny;
 
   struct gsNear *near;
   struct kdNode *kdt;
@@ -47,21 +47,21 @@ struct gsknn {
   unsigned ndist;
   unsigned size;
   bool    *mask;
-  int     *add;
-  int     *tmpadd;
+  size_t  *add;
+  size_t  *tmpadd;
   double  *dist;
   double  *tmpdist;
 };
 
-struct gsknn *gridsearch_knn_new(unsigned size);
+struct gsknn *gridsearch_knn_new(size_t size);
 void gridsearch_knn_delete(struct gsknn *knn);
-int gridsearch_knn(struct gridsearch *gs, struct gsknn *knn, double plon, double plat);
+size_t gridsearch_knn(struct gridsearch *gs, struct gsknn *knn, double plon, double plat);
 
-struct gridsearch *gridsearch_create_reg2d(bool lcyclic, unsigned nx, unsigned ny, const double *restrict lons, const double *restrict lats);
-struct gridsearch *gridsearch_create(unsigned n, const double *restrict lons, const double *restrict lats);
-struct gridsearch *gridsearch_create_nn(unsigned n, const double *restrict lons, const double *restrict lats);
+struct gridsearch *gridsearch_create_reg2d(bool lcyclic, size_t nx, size_t ny, const double *restrict lons, const double *restrict lats);
+struct gridsearch *gridsearch_create(size_t n, const double *restrict lons, const double *restrict lats);
+struct gridsearch *gridsearch_create_nn(size_t n, const double *restrict lons, const double *restrict lats);
 void gridsearch_delete(struct gridsearch *gs);
-unsigned gridsearch_nearest(struct gridsearch *gs, double lon, double lat, double *range);
-struct pqueue *gridsearch_qnearest(struct gridsearch *gs, double lon, double lat, double *prange, unsigned nnn);
+size_t gridsearch_nearest(struct gridsearch *gs, double lon, double lat, double *range);
+struct pqueue *gridsearch_qnearest(struct gridsearch *gs, double lon, double lat, double *prange, size_t nnn);
 
 #endif
diff --git a/src/griddes.cc b/src/griddes.cc
index d20855c..70d5b66 100644
--- a/src/griddes.cc
+++ b/src/griddes.cc
@@ -40,12 +40,12 @@ void gridInit(griddes_t *grid)
   grid->ybounds       = NULL;
   grid->area          = NULL;
   grid->type          = CDI_UNDEFID;
+  grid->datatype      = CDI_UNDEFID;
   grid->size          = 0;
   grid->xsize         = 0;
   grid->ysize         = 0;
   grid->np            = 0;
   grid->lcomplex      = 1;
-  grid->prec          = 0;
   grid->ntr           = 0;
   grid->nvertex       = 0;
   grid->genBounds     = false;
@@ -154,8 +154,6 @@ int gridDefine(griddes_t grid)
 	if ( grid.ysize > 0 ) gridDefYsize(gridID, grid.ysize);
 	if ( grid.np    > 0 ) gridDefNP(gridID, grid.np);
 
-	gridDefPrec(gridID, grid.prec);
-
         if ( grid.uvRelativeToGrid ) gridDefUvRelativeToGrid(gridID, 1);
 	if ( grid.nvertex ) gridDefNvertex(gridID, grid.nvertex);
 
@@ -223,8 +221,6 @@ int gridDefine(griddes_t grid)
 
 	gridID = gridCreate(grid.type, grid.size);
 
-	gridDefPrec(gridID, grid.prec);
-
 	if ( grid.type == GRID_CURVILINEAR )
 	  {
 	    if ( grid.xsize == 0 ) Error("xsize undefined!");
@@ -261,7 +257,6 @@ int gridDefine(griddes_t grid)
 
 	gridID = gridCreate(grid.type, grid.size);
 
-	gridDefPrec(gridID, grid.prec);
 	gridDefTrunc(gridID, grid.ntr);
 	gridDefComplexPacking(gridID, grid.lcomplex);
 
@@ -275,7 +270,6 @@ int gridDefine(griddes_t grid)
 
 	gridID = gridCreate(grid.type, grid.size);
 
-	gridDefPrec(gridID, grid.prec);
 	gridDefParamGME(gridID, grid.nd, grid.ni, grid.ni2, grid.ni3);
 	
 	if ( grid.mask ) { gridDefMask(gridID, grid.mask); Free(grid.mask); }
@@ -293,6 +287,8 @@ int gridDefine(griddes_t grid)
       }
     }
 
+  if ( grid.datatype != CDI_UNDEFID ) gridDefDatatype(gridID, grid.datatype);
+
   if ( grid.uuid[0] )      gridDefUUID(gridID, grid.uuid);
 
   if ( grid.xname[0]     ) cdiGridDefKeyStr(gridID, CDI_KEY_XNAME,     strlen(grid.xname)+1, grid.xname);
diff --git a/src/griddes.h b/src/griddes.h
index 8d62b64..99f3da7 100644
--- a/src/griddes.h
+++ b/src/griddes.h
@@ -23,7 +23,7 @@ typedef struct {
                         i and j scan positively, i points are consecutive (row-major)        */
   bool    uvRelativeToGrid;
   double  a;
-  int     prec;
+  int     datatype;
   int     isRotated;              /* TRUE for rotated grids         */
   int     type;
   int     ntr;
diff --git a/src/griddes_h5.cc b/src/griddes_h5.cc
index 5f7ea50..9839715 100644
--- a/src/griddes_h5.cc
+++ b/src/griddes_h5.cc
@@ -392,7 +392,7 @@ int gridFromH5file(const char *gridfile)
       fill_gridvals(grid.xsize, grid.ysize, grid.xvals, grid.yvals);
 
       grid.type = GRID_CURVILINEAR;
-      grid.prec = CDI_DATATYPE_FLT32;
+      grid.datatype = CDI_DATATYPE_FLT32;
 
       gridID = gridDefine(grid);
     }
@@ -515,7 +515,7 @@ int gridFromH5file(const char *gridfile)
 	  for ( i = 0; i < grid.size; ++i ) grid.yvals[i] = grid.yvals[i]*yscale + yoffset;
 
 	  grid.type = GRID_CURVILINEAR;
-	  grid.prec = CDI_DATATYPE_FLT32;
+	  grid.datatype = CDI_DATATYPE_FLT32;
 
 	  gridID = gridDefine(grid);
 	}
diff --git a/src/griddes_nc.cc b/src/griddes_nc.cc
index 0f2eb5f..488bec3 100644
--- a/src/griddes_nc.cc
+++ b/src/griddes_nc.cc
@@ -88,7 +88,7 @@ int gridFromNCfile(const char *gridfile)
       if ( grid_rank == 1 )
 	{
 	  grid.type = GRID_UNSTRUCTURED;
-	  if ( (size_t)grid_dims[0] != grid_size ) return(gridID);
+	  if ( (size_t)grid_dims[0] != grid_size ) return gridID;
 	}
       else
 	{
@@ -98,7 +98,7 @@ int gridFromNCfile(const char *gridfile)
 
 	  grid.xsize = grid_dims[0];
 	  grid.ysize = grid_dims[1];
-	  if ( (size_t)grid_dims[0]*grid_dims[1] != grid_size ) return(gridID);
+	  if ( (size_t)grid_dims[0]*grid_dims[1] != grid_size ) return gridID;
 	}
 
       /* allocate grid coordinates and read data */
@@ -109,8 +109,7 @@ int gridFromNCfile(const char *gridfile)
       grid.ybounds = (double*) Malloc(grid.nvertex*grid.size*sizeof(double));
 
       nce(nc_inq_vartype(nc_file_id, nc_gridlat_id, &xtype));
-      if ( xtype == NC_FLOAT )  grid.prec = CDI_DATATYPE_FLT32;
-      else                      grid.prec = CDI_DATATYPE_FLT64;
+      grid.datatype = (xtype == NC_FLOAT) ? CDI_DATATYPE_FLT32 : CDI_DATATYPE_FLT64;
 
       nce(nc_get_var_double(nc_file_id, nc_gridlon_id, grid.xvals));
       nce(nc_get_var_double(nc_file_id, nc_gridlat_id, grid.yvals));
@@ -166,21 +165,17 @@ void writeNCgrid(const char *gridfile, int gridID, int *grid_imask)
   int nc_gridlon_id;   /* NetCDF grid center lon var id */
   int nc_gridxsize_id, nc_gridysize_id, nc_grdimask_id;
 
-  nc_type xtype;
   size_t grid_rank = 0, len;
   int grid_dims[2];
   int nc_dims_id[3], ndims;
-  int gridtype;
-  int gridsize;
   double *vals;
   char units[CDI_MAX_NAME];
 
 
-  gridtype = gridInqType(gridID);
-  gridsize = gridInqSize(gridID);
+  int gridtype = gridInqType(gridID);
+  int gridsize = gridInqSize(gridID);
 
-  if ( gridInqPrec(gridID) == CDI_DATATYPE_FLT64 ) xtype = NC_DOUBLE;
-  else                                         xtype = NC_FLOAT;
+  nc_type xtype = (gridInqDatatype(gridID) == CDI_DATATYPE_FLT64) ? NC_DOUBLE : NC_FLOAT;
 
   if ( gridtype == GRID_CURVILINEAR )
     {
diff --git a/src/hetaeta.cc b/src/hetaeta.cc
index 6dd9863..f93ea57 100644
--- a/src/hetaeta.cc
+++ b/src/hetaeta.cc
@@ -456,25 +456,8 @@ void hetaeta(bool ltq, int ngp, const int *imiss,
   double epsm1i;
   long jblt;
   long jlev = 0;
-  double *zt2 = NULL, *zq2 = NULL;
-  double /* *etah1,*/ *ph1, *lnph1, *fi1;
-  double *pf1, *lnpf1;
-  double *tv1, *theta1, *rh1;
-  double *ph2, *lnph2, *fi2;
-  double *pf2/*, *lnpf2*/;
-  double *zvar;
-  double *rh_pbl = NULL;
-  double *theta_pbl = NULL;
-  double *rh2;
-  double *wgt;
-  long *idx;
   int lpsmod = 1;
-#if defined(_OPENMP)
-  extern int ompNumThreads;
   double *vars_pbl[MAX_VARS];
-#else
-  double **vars_pbl = NULL;
-#endif
 #if defined(OUTPUT)
   double t, q, fi;
 
@@ -485,131 +468,63 @@ void hetaeta(bool ltq, int ngp, const int *imiss,
   long nlev1p1 = nlev1+1;
   long nlev2p1 = nlev2+1;
 
-#if defined(_OPENMP)
-  double **ph1_2 = (double**) Malloc(ompNumThreads*sizeof(double*));
-  double **lnph1_2 = (double**) Malloc(ompNumThreads*sizeof(double*));
-  double **fi1_2 = (double**) Malloc(ompNumThreads*sizeof(double*));
-
-  double **pf1_2 = (double**) Malloc(ompNumThreads*sizeof(double*));
-  double **lnpf1_2 = (double**) Malloc(ompNumThreads*sizeof(double*));
-  double **tv1_2 = (double**) Malloc(ompNumThreads*sizeof(double*));
-  double **theta1_2 = (double**) Malloc(ompNumThreads*sizeof(double*));
-  double **rh1_2 = (double**) Malloc(ompNumThreads*sizeof(double*));
-  double **zvar_2 = (double**) Malloc(ompNumThreads*sizeof(double*));
-
-  double **ph2_2 = (double**) Malloc(ompNumThreads*sizeof(double*));
-  double **lnph2_2 = (double**) Malloc(ompNumThreads*sizeof(double*));
-  double **fi2_2 = (double**) Malloc(ompNumThreads*sizeof(double*));
-
-  double **pf2_2 = (double**) Malloc(ompNumThreads*sizeof(double*));
-  double **rh2_2 = (double**) Malloc(ompNumThreads*sizeof(double*));
-  double **wgt_2 = (double**) Malloc(ompNumThreads*sizeof(double*));
-  long   **idx_2 = (long**) Malloc(ompNumThreads*sizeof(long*));
-
-  // if ( ltq )
-  double **zt2_2 = (double**) Malloc(ompNumThreads*sizeof(double*));
-  double **zq2_2 = (double**) Malloc(ompNumThreads*sizeof(double*));
-  double **rh_pbl_2 = (double**) Malloc(ompNumThreads*sizeof(double*));
-  double **theta_pbl_2 = (double**) Malloc(ompNumThreads*sizeof(double*));
+  NEW_2D(double, ph1, ompNumThreads, nlev1p1);
+  NEW_2D(double, lnph1, ompNumThreads, nlev1p1);
+  NEW_2D(double, fi1, ompNumThreads, nlev1p1);
 
-  // if ( nvars > 0 )
-  double ***vars_pbl_2 = (double***) Malloc(ompNumThreads*sizeof(double**));
+  NEW_2D(double, pf1, ompNumThreads, nlev1);
+  NEW_2D(double, lnpf1, ompNumThreads, nlev1);
+  NEW_2D(double, tv1, ompNumThreads, nlev1);
+  NEW_2D(double, theta1, ompNumThreads, nlev1);
+  NEW_2D(double, rh1, ompNumThreads, nlev1);
+  NEW_2D(double, zvar, ompNumThreads, nlev1);
 
-  for ( int i = 0; i < ompNumThreads; i++ )
-    {
-      ph1_2[i]    = (double*) Malloc(nlev1p1*sizeof(double));
-      lnph1_2[i]  = (double*) Malloc(nlev1p1*sizeof(double));
-      fi1_2[i]    = (double*) Malloc(nlev1p1*sizeof(double));
-
-      pf1_2[i]    = (double*) Malloc(nlev1*sizeof(double));
-      lnpf1_2[i]  = (double*) Malloc(nlev1*sizeof(double));
-      tv1_2[i]    = (double*) Malloc(nlev1*sizeof(double));
-      theta1_2[i] = (double*) Malloc(nlev1*sizeof(double));
-      rh1_2[i]    = (double*) Malloc(nlev1*sizeof(double));
-      zvar_2[i]   = (double*) Malloc(nlev1*sizeof(double));
-
-      ph2_2[i]    = (double*) Malloc(nlev2p1*sizeof(double));
-      lnph2_2[i]  = (double*) Malloc(nlev2p1*sizeof(double));
-      fi2_2[i]    = (double*) Malloc(nlev2p1*sizeof(double));
-
-      pf2_2[i]    = (double*) Malloc(nlev2*sizeof(double));
-      rh2_2[i]    = (double*) Malloc(nlev2*sizeof(double));
-      wgt_2[i]    = (double*) Malloc(nlev2*sizeof(double));
-      idx_2[i]    = (long*) Malloc(nlev2*sizeof(long));
-
-      if ( ltq )
-	{
-	  zt2_2[i]       = (double*) Malloc(nlev2*sizeof(double));
-	  zq2_2[i]       = (double*) Malloc(nlev2*sizeof(double));
-	  rh_pbl_2[i]    = (double*) Malloc(nlev2*sizeof(double));
-	  theta_pbl_2[i] = (double*) Malloc(nlev2*sizeof(double));
-	}
+  NEW_2D(double, ph2, ompNumThreads, nlev2p1);
+  NEW_2D(double, lnph2, ompNumThreads, nlev2p1);
+  NEW_2D(double, fi2, ompNumThreads, nlev2p1);
 
-      if ( nvars > 0 )
-	{
-	  if ( nvars > MAX_VARS )
-	    {
-	      fprintf(stderr, "Too many vars (max = %d)!\n", MAX_VARS);
-	      exit(-1);
-	    }
-	  vars_pbl_2[i]  = (double **) Malloc(nvars*sizeof(double *));
-	  for ( int iv = 0; iv < nvars; ++iv )
-	    vars_pbl_2[i][iv] = (double*) Malloc(nlev2*sizeof(double));
-	}
-    }
-#else
-  /* etah1  = (double*) Malloc(nlev1p1*sizeof(double)); */
-  ph1    = (double*) Malloc(nlev1p1*sizeof(double));
-  lnph1  = (double*) Malloc(nlev1p1*sizeof(double));
-  fi1    = (double*) Malloc(nlev1p1*sizeof(double));
-
-  pf1    = (double*) Malloc(nlev1*sizeof(double));
-  lnpf1  = (double*) Malloc(nlev1*sizeof(double));
-  tv1    = (double*) Malloc(nlev1*sizeof(double));
-  theta1 = (double*) Malloc(nlev1*sizeof(double));
-  rh1    = (double*) Malloc(nlev1*sizeof(double));
-  zvar   = (double*) Malloc(nlev1*sizeof(double));
-
-  ph2    = (double*) Malloc(nlev2p1*sizeof(double));
-  lnph2  = (double*) Malloc(nlev2p1*sizeof(double));
-  fi2    = (double*) Malloc(nlev2p1*sizeof(double));
-
-  pf2    = (double*) Malloc(nlev2*sizeof(double));
-  /* lnpf2  = (double*) Malloc(nlev2*sizeof(double)); */
-  rh2    = (double*) Malloc(nlev2*sizeof(double));
-  wgt    = (double*) Malloc(nlev2*sizeof(double));
-  idx    = (long*) Malloc(nlev2*sizeof(long));
+  NEW_2D(double, pf2, ompNumThreads, nlev2);
+  NEW_2D(double, rh2, ompNumThreads, nlev2);
+  NEW_2D(double, wgt, ompNumThreads, nlev2);
+  NEW_2D(long, idx, ompNumThreads, nlev2);
 
-  if ( ltq )
+  NEW_2D(double, zt2, ompNumThreads, ltq?nlev2:0);
+  NEW_2D(double, zq2, ompNumThreads, ltq?nlev2:0);
+  NEW_2D(double, rh_pbl, ompNumThreads, ltq?nlev2:0);
+  NEW_2D(double, theta_pbl, ompNumThreads, ltq?nlev2:0);
+
+  if ( nvars > MAX_VARS )
     {
-      zt2       = (double*) Malloc(nlev2*sizeof(double));
-      zq2       = (double*) Malloc(nlev2*sizeof(double));
-      rh_pbl    = (double*) Malloc(nlev2*sizeof(double));
-      theta_pbl = (double*) Malloc(nlev2*sizeof(double));
+      fprintf(stderr, "Too many vars (max = %d)!\n", MAX_VARS);
+      exit(-1);
     }
+  // if ( nvars > 0 )
+  double ***vars_pbl_2 = (double***) Malloc(ompNumThreads*sizeof(double**));
 
   if ( nvars > 0 )
     {
-      vars_pbl  = (double **) Malloc(nvars*sizeof(double *));
-      for ( int iv = 0; iv < nvars; ++iv )
-	vars_pbl[iv] = (double*) Malloc(nlev2*sizeof(double));
+      for ( int i = 0; i < ompNumThreads; i++ )
+        {
+	  vars_pbl_2[i]  = (double **) Malloc(nvars*sizeof(double *));
+	  for ( int iv = 0; iv < nvars; ++iv )
+	    vars_pbl_2[i][iv] = (double*) Malloc(nlev2*sizeof(double));
+	}
     }
-#endif
   
-  double *af1 = (double*) Malloc(nlev1*sizeof(double));
-  double *bf1 = (double*) Malloc(nlev1*sizeof(double));
-  double *etaf1 = (double*) Malloc(nlev1*sizeof(double));
+  double *af1 = new double[nlev1];
+  double *bf1 = new double[nlev1];
+  double *etaf1 = new double[nlev1];
 
-  double *etah2 = (double*) Malloc(nlev2p1*sizeof(double));
+  double *etah2 = new double[nlev2p1];
 
-  double *af2 = (double*) Malloc(nlev2*sizeof(double));
-  double *bf2 = (double*) Malloc(nlev2*sizeof(double));
-  double *etaf2 = (double*) Malloc(nlev2*sizeof(double));
+  double *af2 = new double[nlev2];
+  double *bf2 = new double[nlev2];
+  double *etaf2 = new double[nlev2];
 
-  double *w1 = (double*) Malloc(nlev2*sizeof(double));
-  double *w2 = (double*) Malloc(nlev2*sizeof(double));
-  long *jl1 = (long*) Malloc(nlev2*sizeof(long));
-  long *jl2 = (long*) Malloc(nlev2*sizeof(long));
+  double *w1 = new double[nlev2];
+  double *w2 = new double[nlev2];
+  long *jl1 = new long[nlev2];
+  long *jl2 = new long[nlev2];
 
   /******* set coordinate system ETA's, A's, B's
 	   calculate half and full level ETA
@@ -623,10 +538,10 @@ void hetaeta(bool ltq, int ngp, const int *imiss,
       bf1[k] = 0.5*(bh1[k]+bh1[k+1]);
     }
 
-  /* etah1[nlev1] = ah1[nlev1]*aipr+bh1[nlev1]; */
+  // etah1[nlev1] = ah1[nlev1]*aipr+bh1[nlev1];
   for ( int k = 0; k < nlev1; ++k )
     { 
-      /* etah1[k] = ah1[k]*aipr+bh1[k]; */
+      // etah1[k] = ah1[k]*aipr+bh1[k];
       etaf1[k] = af1[k]*aipr+bf1[k];
     }
 
@@ -684,72 +599,29 @@ void hetaeta(bool ltq, int ngp, const int *imiss,
 
 
 #if defined(_OPENMP)
-#pragma omp parallel for default(none) \
-  shared(ngp, ph1_2, lnph1_2, fi1_2, pf1_2, lnpf1_2, tv1_2, theta1_2, rh1_2, zvar_2, ph2_2, lnph2_2, \
-	 fi2_2, pf2_2, rh_pbl_2, zt2_2, zq2_2, theta_pbl_2, rh2_2, wgt_2, idx_2, vars_pbl_2, \
+#pragma omp parallel for default(none) firstprivate(lpsmod)  private(vars_pbl)  schedule(dynamic,1) \
+  shared(ngp, ph1, lnph1, fi1, pf1, lnpf1, tv1, theta1, rh1, zvar, ph2, lnph2, \
+	 fi2, pf2, rh_pbl, zt2, zq2, theta_pbl, rh2, wgt, idx, vars_pbl_2, \
 	 af1, bf1, etah2, af2, bf2, w1, w2, jl1, jl2,	\
 	 ltq, nvars, imiss, ah1, bh1, ps1, nlev1, epsm1i, q1, t1, fis1, fis2, ps2, \
-	 ah2, bh2, nlev2, vars1, vars2, t2, q2, tscor, pscor, secor, jblt) \
-  firstprivate(lpsmod) \
-  private(ph1, lnph1, fi1, pf1, lnpf1, tv1, theta1, rh1, zvar, ph2, lnph2, fi2, pf2, rh_pbl, \
-          theta_pbl, rh2, wgt, idx, vars_pbl, zt2, zq2) \
-  schedule(dynamic,1)
+	 ah2, bh2, nlev2, vars1, vars2, t2, q2, tscor, pscor, secor, jblt)
 #endif
   for ( int ij = 0; ij < ngp; ++ij )
     {
-#if defined(_OPENMP)
-      int ompthID = omp_get_thread_num();
-
-      ph1    = ph1_2[ompthID];
-      lnph1  = lnph1_2[ompthID];
-      fi1    = fi1_2[ompthID];
-
-      pf1    = pf1_2[ompthID];
-      lnpf1  = lnpf1_2[ompthID];
-      tv1    = tv1_2[ompthID];
-      theta1 = theta1_2[ompthID];
-      rh1    = rh1_2[ompthID];
-      zvar   = zvar_2[ompthID];
-
-      ph2    = ph2_2[ompthID];
-      lnph2  = lnph2_2[ompthID];
-      fi2    = fi2_2[ompthID];
-
-      pf2    = pf2_2[ompthID];
-      rh2    = rh2_2[ompthID];
-      wgt    = wgt_2[ompthID];
-      idx    = idx_2[ompthID];
-
-      zt2       = NULL;
-      zq2       = NULL;
-      rh_pbl    = NULL;
-      theta_pbl = NULL;
-
-      if ( ltq )
-	{
-	  zt2       = zt2_2[ompthID];
-	  zq2       = zq2_2[ompthID];
-	  rh_pbl    = rh_pbl_2[ompthID];
-	  theta_pbl = theta_pbl_2[ompthID];
-	}
+      int ompthID = cdo_omp_get_thread_num();
 
-      if ( nvars > 0 )
-	{
-	  for ( int iv = 0; iv < nvars; ++iv )
-	    vars_pbl[iv] = vars_pbl_2[ompthID][iv];
-	}
-#endif
+      for ( int iv = 0; iv < nvars; ++iv )
+        vars_pbl[iv] = vars_pbl_2[ompthID][iv];
 
-      if ( imiss )
-	if ( imiss[ij] ) continue;
+      if ( imiss && imiss[ij] ) continue;
 
       hetaeta_sc(ltq, lpsmod, ij, ngp, nlev1, nlev2, nvars,
 		 af1, bf1, etah2, af2, bf2, w1, w2, jl1, jl2,
 		 ah1, bh1, ps1, epsm1i, q1, t1, fis1, fis2, ps2,
 		 ah2, bh2, vars1, vars2, t2, q2, tscor, pscor, secor, jblt,
-		 ph1, lnph1, fi1, pf1, lnpf1, tv1, theta1, rh1, zvar, 
-                 ph2, lnph2, fi2, pf2, rh2, wgt, idx,
-		 rh_pbl, theta_pbl, vars_pbl, zt2, zq2);
+		 ph1[ompthID], lnph1[ompthID], fi1[ompthID], pf1[ompthID], lnpf1[ompthID], tv1[ompthID], theta1[ompthID], rh1[ompthID], zvar[ompthID], 
+                 ph2[ompthID], lnph2[ompthID], fi2[ompthID], pf2[ompthID], rh2[ompthID], wgt[ompthID], idx[ompthID],
+		 rh_pbl[ompthID], theta_pbl[ompthID], vars_pbl, zt2[ompthID], zq2[ompthID]);
 
     } /* end for ij */
 
@@ -758,119 +630,55 @@ void hetaeta(bool ltq, int ngp, const int *imiss,
   fclose(new);
 #endif
 
+  DELETE_2D(ph1);
+  DELETE_2D(lnph1);
+  DELETE_2D(fi1);
 
-#if defined(_OPENMP)
-  for ( int i = 0; i < ompNumThreads; i++ )
-    {
-      Free(ph1_2[i]);    
-      Free(lnph1_2[i]);  
-      Free(fi1_2[i]);    
-
-      Free(pf1_2[i]);    
-      Free(lnpf1_2[i]);  
-      Free(tv1_2[i]);    
-      Free(theta1_2[i]); 
-      Free(rh1_2[i]);    
-      Free(zvar_2[i]);    
-
-      Free(ph2_2[i]);       
-      Free(lnph2_2[i]);     
-      Free(fi2_2[i]);
-
-      Free(pf2_2[i]);       
-      /* Free(lnpf2_2[i]); */
-      Free(rh2_2[i]);      
-      Free(wgt_2[i]); 
-      Free(idx_2[i]); 
-
-      if ( ltq )
-	{
-	  Free(zt2_2[i]); 
-	  Free(zq2_2[i]); 
-	  Free(rh_pbl_2[i]); 
-	  Free(theta_pbl_2[i]); 
-	}   
+  DELETE_2D(pf1);
+  DELETE_2D(lnpf1);
+  DELETE_2D(tv1);
+  DELETE_2D(theta1);
+  DELETE_2D(rh1);
+  DELETE_2D(zvar);
 
-      if ( nvars > 0 )
-	{
+  DELETE_2D(ph2);
+  DELETE_2D(lnph2);
+  DELETE_2D(fi2);
+
+  DELETE_2D(pf2);
+  // DELETE_2D(lnpf2);
+  DELETE_2D(rh2);
+  DELETE_2D(wgt);
+  DELETE_2D(idx);
+
+  DELETE_2D(zt2); 
+  DELETE_2D(zq2); 
+  DELETE_2D(rh_pbl); 
+  DELETE_2D(theta_pbl); 
+
+  if ( nvars > 0 )
+    {
+      for ( int i = 0; i < ompNumThreads; i++ )
+        {
 	  for ( int iv = 0; iv < nvars; ++iv )
 	    Free(vars_pbl_2[i][iv]);
 	  
 	  Free(vars_pbl_2[i]);
 	}
     }
-  Free(ph1_2);
-  Free(lnph1_2);
-  Free(fi1_2);
-  Free(pf1_2);
-  Free(lnpf1_2);
-  Free(tv1_2);
-  Free(theta1_2);
-  Free(rh1_2);
-  Free(zvar_2);
-  Free(ph2_2);
-  Free(lnph2_2);
-  Free(fi2_2);
-  Free(pf2_2);
-  Free(rh2_2);
-  Free(wgt_2);
-  Free(idx_2);
-  Free(zt2_2);
-  Free(zq2_2);
-  Free(rh_pbl_2);
-  Free(theta_pbl_2);
   Free(vars_pbl_2);
-#else
-  /* Free(etah1); */     
-  Free(ph1);    
-  Free(lnph1);  
-  Free(fi1);    
-
-  Free(pf1);    
-  Free(lnpf1);  
-  Free(tv1);    
-  Free(theta1); 
-  Free(rh1);    
-  Free(zvar);    
-
-  Free(ph2);       
-  Free(lnph2);     
-  Free(fi2);
-
-  Free(pf2);       
-  /* Free(lnpf2); */
-  Free(rh2);      
-  Free(wgt); 
-  Free(idx); 
-
-  if ( ltq )
-    {
-      Free(zt2); 
-      Free(zq2); 
-      Free(rh_pbl); 
-      Free(theta_pbl); 
-    }   
-
-  if ( nvars > 0 )
-    {
-      for ( int iv = 0; iv < nvars; ++iv )
-        Free(vars_pbl[iv]);
-
-      Free(vars_pbl);
-    }
-#endif
 
-  Free(af1);
-  Free(bf1);
-  Free(etaf1);
-  Free(etah2);
-  Free(af2);
-  Free(bf2);
-  Free(etaf2);
-  Free(w1);
-  Free(w2);
-  Free(jl1);
-  Free(jl2);
+  delete[] af1;
+  delete[] bf1;
+  delete[] etaf1;
+  delete[] etah2;
+  delete[] af2;
+  delete[] bf2;
+  delete[] etaf2;
+  delete[] w1;
+  delete[] w2;
+  delete[] jl1;
+  delete[] jl2;
 
   return;
 }
diff --git a/src/interpol.cc b/src/interpol.cc
index b6f80f6..b300e39 100644
--- a/src/interpol.cc
+++ b/src/interpol.cc
@@ -105,7 +105,7 @@ long find_element(double x, long nelem, const double *array)
 }
 */
 
-int rect_grid_search(long *ii, long *jj, double x, double y, long nxm, long nym, const double *restrict xm, const double *restrict ym)
+int rect_grid_search(size_t *ii, size_t *jj, double x, double y, size_t nxm, size_t nym, const double *restrict xm, const double *restrict ym)
 {
   int lfound = 0;
 
@@ -236,7 +236,7 @@ void intlinarr2(double missval, int lon_is_circular,
       findex++;
       if ( lprogress ) progressStatus(0, 1, findex/gridsize2);
 
-      long ii, jj;
+      size_t ii, jj;
       int lfound = rect_grid_search(&ii, &jj, x[i], y[i], nxm, nym, xm, ym); 
 
       if ( lfound )
diff --git a/src/job.cc b/src/job.cc
index 40d0e5d..9ae1418 100644
--- a/src/job.cc
+++ b/src/job.cc
@@ -1,9 +1,5 @@
 #if defined(HAVE_CONFIG_H)
-#  include "config.h"
-#endif
-
-#ifndef _XOPEN_SOURCE
-#define _XOPEN_SOURCE 600 /* gethostname */
+#include "config.h"
 #endif
 
 #include "cdo_int.h"
@@ -14,7 +10,7 @@
 
 
 #if defined(HAVE_LIBDRMAA)
-#  include "drmaa.h"
+#include "drmaa.h"
 #endif
 
 #define  GRID_TMPDIR  "/opt/griddata/tmp"
diff --git a/src/kdtreelib/kdtree_cartesian.cc b/src/kdtreelib/kdtree_cartesian.cc
index 6b21877..faef76a 100644
--- a/src/kdtreelib/kdtree_cartesian.cc
+++ b/src/kdtreelib/kdtree_cartesian.cc
@@ -15,31 +15,20 @@
 
    ********************************************************************* */
 
-static
+static constexpr
 kdata_t square(const kdata_t x)
 {
   return x*x;
 }
 
-static
-kdata_t kd_dist_sq(const kdata_t *restrict a, const kdata_t *restrict b, int dim)
+static constexpr
+kdata_t kd_dist_sq(const kdata_t *restrict a, const kdata_t *restrict b)
 {
   return (square((a[0]-b[0]))+square((a[1]-b[1]))+square((a[2]-b[2])));
 }
 
-inline kdata_t
-kd_dist_sq_ori(kdata_t *x, kdata_t *y, int dim)
-{
-    if (!x || !y) return -1;
-
-    kdata_t dsq = 0;
-    for(int i = 0; i < dim; i++)
-        dsq += kd_sqr(x[i] - y[i]);
-    return dsq;
-}
-
-inline kdata_t
-kd_min(kdata_t x, kdata_t y)
+inline
+kdata_t kd_min(kdata_t x, kdata_t y)
 {
     return x < y ? x : y;
 }
@@ -259,7 +248,7 @@ kd_nearest(struct kdNode *node, kdata_t *p, kdata_t *max_dist_sq, int dim)
     else
         nearest = node;
 
-    kdata_t dist_sq = kd_dist_sq(nearest->location, p, dim);
+    kdata_t dist_sq = kd_dist_sq(nearest->location, p);
     if (*max_dist_sq > dist_sq)
 	*max_dist_sq = dist_sq;
 
@@ -280,7 +269,7 @@ kd_nearest(struct kdNode *node, kdata_t *p, kdata_t *max_dist_sq, int dim)
         else
             tmp_nearest = further;
 
-        kdata_t tmp_dist_sq = kd_dist_sq(tmp_nearest->location, p, dim);
+        kdata_t tmp_dist_sq = kd_dist_sq(tmp_nearest->location, p);
         if ( tmp_dist_sq < dist_sq ) {
             nearest = tmp_nearest;
             dist_sq = tmp_dist_sq;
@@ -342,9 +331,9 @@ kd_qnearest(struct kdNode *node, kdata_t *p,
 // Uwe Schulzweida: extract kd_check_dist() from kd_doQnearest()
 static int
 kd_check_dist(struct kdNode *node, kdata_t *p,
-              kdata_t *max_dist_sq, unsigned int q, int dim, struct pqueue *res)
+              kdata_t *max_dist_sq, unsigned int q, struct pqueue *res)
 {
-    kdata_t dist_sq = kd_dist_sq(node->location, p, dim);
+    kdata_t dist_sq = kd_dist_sq(node->location, p);
     if ( dist_sq < *max_dist_sq && kd_isleaf(node) ) {
         struct resItem *point = (struct resItem *) kd_malloc(sizeof(struct resItem), "kd_doQnearest: ");
         if ( point == NULL) return 0;
@@ -380,7 +369,7 @@ kd_doQnearest(struct kdNode *node, kdata_t *p,
 {
     if ( !node ) return 1;
 
-    if ( !kd_check_dist(node, p, max_dist_sq, q, dim, res) ) return 0;
+    if ( !kd_check_dist(node, p, max_dist_sq, q, res) ) return 0;
 
     struct kdNode *nearer, *further;
     if ( p[node->split] < node->location[node->split] ) {
@@ -404,7 +393,7 @@ kd_doQnearest(struct kdNode *node, kdata_t *p,
          */
         if (!kd_doQnearest(further, p, max_dist_sq, q, dim, res)) return 0;
 
-        if (!kd_check_dist(node, p, max_dist_sq, q, dim, res)) return 0;
+        if (!kd_check_dist(node, p, max_dist_sq, q, res)) return 0;
     }
     return 1;
 }
@@ -458,7 +447,7 @@ kd_doRange(struct kdNode *node, kdata_t *p, kdata_t *max_dist_sq,
     if (!node)
         return 1;
 
-    dist_sq = kd_dist_sq(node->location, p, dim);
+    dist_sq = kd_dist_sq(node->location, p);
     if (dist_sq < *max_dist_sq && kd_isleaf(node)) {
         if ((point = (struct resItem *)kd_malloc(sizeof(struct resItem), "kd_doRange:"))
             == NULL)
@@ -490,7 +479,7 @@ kd_doRange(struct kdNode *node, kdata_t *p, kdata_t *max_dist_sq,
          */
         if (!kd_doRange(further, p, max_dist_sq, dim, res, ordered))
             return 0;
-        dist_sq = kd_dist_sq(node->location, p, dim);
+        dist_sq = kd_dist_sq(node->location, p);
 
         if (dist_sq < *max_dist_sq && kd_isleaf(node)) {
             if ((point = (struct resItem *)kd_malloc(sizeof(struct resItem), "kd_doRange: "))
diff --git a/src/magics_template_parser.cc b/src/magics_template_parser.cc
index 63759a5..5b98954 100644
--- a/src/magics_template_parser.cc
+++ b/src/magics_template_parser.cc
@@ -105,7 +105,11 @@ int magics_template_parser( void *node )
 }
 
 
+#if defined(HAVE_LIBMAGICS)
 int SetMagicsParameterValue( const char *param_name, const char *param_type, const char *param_value )
+#else
+int SetMagicsParameterValue( const char *, const char *, const char * )
+#endif  
 {
 	int ret_flag = 0;
 #if defined(HAVE_LIBMAGICS)
diff --git a/src/modules.cc b/src/modules.cc
index dcec4d4..18ef3fc 100644
--- a/src/modules.cc
+++ b/src/modules.cc
@@ -78,6 +78,7 @@ void *Eofcoeff(void *argument);
 void *Eofcoeff3d(void *argument);
 void *EOFs(void *argument);
 void *EOF3d(void *argument);
+void *EstFreq(void *argument);
 void *Expr(void *argument);
 void *FC(void *argument);
 void *Filedes(void *argument);
@@ -163,6 +164,7 @@ void *Settime(void *argument);
 void *Setzaxis(void *argument);
 void *Shiftxy(void *argument);
 void *Showinfo(void *argument);
+void *Showattribute(void *argument);
 void *Sinfo(void *argument);
 void *Smooth(void *argument);
 void *Sort(void *argument);
@@ -284,7 +286,7 @@ void *Samplegrid(void *argument); // "samplegrid", "subgrid"
 /* clang-format off */
 #define  AdisitOperators        {"adisit", "adipot"}
 #define  AfterburnerOperators   {"after"}
-#define  ArithOperators         {"add",  "sub",  "mul",  "div", "min", "max", "atan2"}
+#define  ArithOperators         {"add",  "sub",  "mul",  "div", "min", "max", "atan2", "setmiss"}
 #define  ArithcOperators        {"addc", "subc", "mulc", "divc", "mod"}
 #define  ArithdaysOperators     {"muldpm", "divdpm", "muldpy", "divdpy", "muldoy"}
 #define  ArithlatOperators      {"mulcoslat", "divcoslat"}
@@ -325,6 +327,7 @@ void *Samplegrid(void *argument); // "samplegrid", "subgrid"
 #define  Eofcoeff3dOperators    {"eofcoeff3d"}
 #define  EOFsOperators          {"eof", "eofspatial", "eoftime"}
 #define  EOF3dOperators         {"eof3d","eof3dspatial","eof3dtime"}
+#define  EstFreqOperators       {"estfreq"}
 #define  ExprOperators          {"expr", "exprf", "aexpr", "aexprf"}
 #define  FCOperators            {"fc2sp", "sp2fc", "fc2gp", "gp2fc"}
 #define  FiledesOperators       {"filedes", "griddes", "griddes2", "zaxisdes", "vct", "vct2", "codetab", \
@@ -431,7 +434,8 @@ void *Samplegrid(void *argument); // "samplegrid", "subgrid"
 #define  SetzaxisOperators      {"setzaxis", "genlevelbounds"}
 #define  ShiftxyOperators       {"shiftx", "shifty"}
 #define  ShowinfoOperators      {"showyear", "showmon", "showdate", "showtime", "showtimestamp", "showcode", "showunit", \
-                                 "showparam", "showname", "showstdname", "showlevel", "showltype", "showformat", "showgrid"}
+                                 "showparam", "showname", "showstdname", "showlevel", "showltype", "showformat", "showgrid", "showatts", "showattsglob"}
+#define  ShowattributeOperators {"showattribute", "showattsvar"}
 #define  SinfoOperators         {"sinfo", "sinfop", "sinfon", "sinfoc", "seinfo", "seinfop", "seinfon", "seinfoc"}
 #define  SmoothOperators        {"smooth", "smooth9"}
 #define  SortOperators          {"sortcode", "sortparam", "sortname", "sortlevel"}
@@ -796,6 +800,7 @@ int add_alias(std::string alias, std::string original) {
  */
 void init_modules()
 {
+  
 /*                             function        help function      operator names          mode number     num streams
                                                                                                   type       in out      */
   add_module("Adisit"        , {Adisit        , AdisitHelp        , AdisitOperators        , 1 , CDI_REAL , 1  , 1  });
@@ -811,6 +816,7 @@ void init_modules()
   add_module("Change"        , {Change        , ChangeHelp        , ChangeOperators        , 1 , CDI_REAL , 1  , 1  });
   add_module("Change_e5slm"  , {Change_e5slm  , {}                , Change_e5slmOperators  , 0 , CDI_REAL , 1  , 1  });
   add_module("Cloudlayer"    , {Cloudlayer    , {}                , CloudlayerOperators    , 1 , CDI_REAL , 1  , 1  });
+  add_module("CMOR"          , {CMOR          , CMORHelp          , CMOROperators          , 1 , CDI_REAL , 1  , 0  });
   add_module("CMOR_lite"     , {CMOR_lite     , CMORliteHelp      , CMORliteOperators      , 1 , CDI_REAL , 1  , 1  });
   add_module("CMOR_table"    , {CMOR_table    , {}                , CMORtableOperators     , 1 , CDI_REAL , 0  , 0  });
   add_module("Collgrid"      , {Collgrid      , CollgridHelp      , CollgridOperators      , 1 , CDI_REAL , -1 , 1  });
@@ -840,6 +846,7 @@ void init_modules()
   add_module("Eofcoeff3d"    , {Eofcoeff3d    , EofcoeffHelp      , Eofcoeff3dOperators    , 1 , CDI_REAL , 2  , -1 });
   add_module("EOFs"          , {EOFs          , EOFsHelp          , EOFsOperators          , 1 , CDI_REAL , 1  , 2  });
   add_module("EOF3d"         , {EOF3d         , EOFsHelp          , EOF3dOperators         , 1 , CDI_REAL , 1  , 2  });
+  add_module("EstFreq"       , {EstFreq       , {}                , EstFreqOperators       , 1 , CDI_REAL , 1  , 1  });
   add_module("Expr"          , {Expr          , ExprHelp          , ExprOperators          , 1 , CDI_REAL , 1  , 1  });
   add_module("FC"            , {FC            , {}                , FCOperators            , 1 , CDI_REAL , 1  , 1  });
   add_module("Filedes"       , {Filedes       , FiledesHelp       , FiledesOperators       , 1 , CDI_BOTH , 1  , 0  });
@@ -939,6 +946,7 @@ void init_modules()
   add_module("Setzaxis"      , {Setzaxis      , SetzaxisHelp      , SetzaxisOperators      , 1 , CDI_BOTH , 1  , 1  });
   add_module("Shiftxy"       , {Shiftxy       , {}                , ShiftxyOperators       , 1 , CDI_REAL , 1  , 1  });
   add_module("Showinfo"      , {Showinfo      , ShowinfoHelp      , ShowinfoOperators      , 1 , CDI_BOTH , 1  , 0  });
+  add_module("Showattribute" , {Showattribute , ShowattributeHelp , ShowattributeOperators , 1 , CDI_REAL , 1  , 0  });
   add_module("Sinfo"         , {Sinfo         , SinfoHelp         , SinfoOperators         , 1 , CDI_BOTH , -1 , 0  });
   add_module("Smooth"        , {Smooth        , SmoothHelp        , SmoothOperators        , 1 , CDI_REAL , 1  , 1  });
   add_module("Sort"          , {Sort          , {}                , SortOperators          , 1 , CDI_REAL , 1  , 1  });
@@ -952,7 +960,7 @@ void init_modules()
   add_module("Splittime"     , {Splittime     , SplittimeHelp     , SplittimeOperators     , 1 , CDI_BOTH , 1  , -1 });
   add_module("Splityear"     , {Splityear     , SplittimeHelp     , SplityearOperators     , 1 , CDI_BOTH , 1  , -1 });
   add_module("Subtrend"      , {Subtrend      , SubtrendHelp      , SubtrendOperators      , 1 , CDI_REAL , 3  , 1  });
-  add_module("Tee"           , {Tee           , {}                , TeeOperators           , 1 , CDI_REAL , 2  , 1  });
+  add_module("Tee"           , {Tee           , TeeHelp           , TeeOperators           , 1 , CDI_REAL , 2  , 1  });
   add_module("Template1"     , {Template1     , {}                , Template1Operators     , 0 , CDI_REAL , 1  , 1  });
   add_module("Template2"     , {Template2     , {}                , Template2Operators     , 0 , CDI_REAL , 1  , 1  });
   add_module("Test"          , {Test          , {}                , TestOperators          , 0 , CDI_REAL , 1  , 1  });
@@ -1229,6 +1237,30 @@ std::vector<std::string> get_sorted_operator_name_list() {
     return names;
 }
 
+std::vector<std::string> get_no_output_operator_list()
+{
+ std::vector<std::string> names;
+    for (std::pair<std::string, std::string> operator_module_names_pair : modules_map) {
+        if (modules[operator_module_names_pair.second].mode == 1 
+                && modules[operator_module_names_pair.second].streamOutCnt == 0) 
+        {
+            names.push_back(operator_module_names_pair.first);
+        }
+    }
+    // adding operators names from alias_map
+    std::string original;
+    for (std::pair<std::string, std::string> alias : aliases) {
+        original = alias.second;
+        if(modules[modules_map[original]].mode == 1
+                && modules[modules_map[original]].streamOutCnt == 0){
+            names.push_back(alias.first);
+        }
+    }
+    std::sort(names.begin(), names.end());
+    return names;
+
+}
+
 void operatorPrintAll(void) {
     int number_of_chars = 0;
     std::string tab = "   ";
@@ -1330,7 +1362,15 @@ std::string get_spacing_for(std::string str) {
  * If the operator is not documented the description is empty
  */
 void operatorPrintList(bool print_no_output) {
-    std::vector<std::string> output_list = get_sorted_operator_name_list();
+    std::vector<std::string> output_list ;
+    if(print_no_output)
+    {
+        output_list = get_no_output_operator_list();
+    }
+    else
+    {
+        output_list = get_sorted_operator_name_list();
+    }
     std::vector<std::string> help;
     unsigned long list_length = output_list.size();
     unsigned long cur_help_idx;
@@ -1410,14 +1450,22 @@ bool is_alias(char * operatorName)
     return (aliases.find(std::string(operatorName)) != aliases.end());
 }
 
-void get_original(char * operatorName)
+char* get_original(char * operatorName)
 {
+    char* original = NULL;
     if(is_alias(operatorName)){
         std::string opName = aliases[std::string(operatorName)];
-        operatorName = (char*)realloc(operatorName, opName.size());
-        strcpy(operatorName, opName.c_str());
+        original = (char*)realloc(operatorName, opName.size());
+        strcpy(original, opName.c_str());
     }
     else{
         Error("%s is not an alias", operatorName);
     }
+    return original; 
+}
+
+
+modules_t &getModule(const std::string &operator_name)
+{
+    return modules[get_module_name_to(operator_name)];
 }
diff --git a/src/modules.h b/src/modules.h
index 93a4de6..7bfe4a3 100644
--- a/src/modules.h
+++ b/src/modules.h
@@ -17,6 +17,7 @@
 #ifndef MODULES_H
 #define MODULES_H
 
+
 #include <iostream>
 #include <map>
 #include <stdbool.h>
@@ -60,6 +61,8 @@ static std::map<std::string, std::string> aliases;
 
 void *(*operatorModule(std::string operatorName))(void *);
 void *(*operatorModule(const char *operatorName))(void *);
+
+modules_t &getModule(const std::string &operatorName);
 void init_modules();
 
 void init_aliases();
@@ -72,7 +75,7 @@ int operatorStreamNumber(const char *operatorName);
 void operatorPrintAll(void);
 void operatorPrintList(bool print_no_output);
 bool is_alias(char * operatorName);
-void get_original(char* operatorName);
+char* get_original(char* operatorName);
 #ifdef CUSTOM_MODULES
 void load_custom_module(std::string path);
 void load_custom_modules(std::string folder_path);
diff --git a/src/operator_help.h b/src/operator_help.h
index 24fe228..c519612 100644
--- a/src/operator_help.h
+++ b/src/operator_help.h
@@ -50,7 +50,8 @@ std::vector<std::string> SinfoHelp = {
     "            4 sections. Section 1 prints one line per parameter with the following ",
     "            information:",
     "            - institute and source",
-    "            - timestep type",
+    "            - time c=constant v=varying",
+    "            - type of statistical processing",
     "            - number of levels and z-axis number",
     "            - horizontal grid size and number",
     "            - data type",
@@ -123,8 +124,9 @@ std::vector<std::string> NinfoHelp = {
 
 std::vector<std::string> ShowinfoHelp = {
     "NAME",
-    "    showformat, showcode, showname, showstdname, showlevel, showltype, showyear, ",
-    "    showmon, showdate, showtime, showtimestamp - Show variables, levels or times",
+    "    showformat, showcode, showname, showstdname, showatts, showattsglob, ",
+    "    showlevel, showltype, showyear, showmon, showdate, showtime, showtimestamp - ",
+    "    Show variables, levels or times",
     "",
     "SYNOPSIS",
     "    <operator>  infile",
@@ -141,6 +143,10 @@ std::vector<std::string> ShowinfoHelp = {
     "                   Prints the name of all variables.",
     "    showstdname    Show standard names",
     "                   Prints the standard name of all variables.",
+    "    showatts       Show all attributes",
+    "                   Prints all variable and global attributes.",
+    "    showattsglob   Show all global attributes",
+    "                   Prints all global attributes.",
     "    showlevel      Show levels",
     "                   Prints all levels for each variable.",
     "    showltype      Show GRIB level types",
@@ -157,6 +163,36 @@ std::vector<std::string> ShowinfoHelp = {
     "                   Prints timestamp of all timesteps (format YYYY-MM-DDThh:mm:ss).",
 };
 
+std::vector<std::string> ShowattributeHelp = {
+    "NAME",
+    "    showattribute, showattsvar - ",
+    "    Show a global attribute, a variable attribute or all attributes of one variable",
+    "",
+    "SYNOPSIS",
+    "    showattribute,attribute  infile",
+    "    showattsvar[,var_nm]  infile",
+    "",
+    "DESCRIPTION",
+    "    This operator prints attributes of a dataset.",
+    "    If a global attribute should be printed, the attribute name can be specified as a parameter directly.",
+    "    If a variable attribute should be printed, the following format is requested:",
+    "    ",
+    "      var_nm at att_nm",
+    "    ",
+    "       var_nm  Variable name. Example: pressure",
+    "       att_nm  Attribute name. Example: units",
+    "    ",
+    "",
+    "OPERATORS",
+    "    showattribute  Show a global attribute or a variable attribute",
+    "    showattsvar    Show all variable attributes.",
+    "                   If var_nm is specified, only for a subset of variables.",
+    "",
+    "PARAMETER",
+    "    attribute  STRING  Attribute in the format [var_nm@]att_nm",
+    "    var_nm     STRING  Variable name",
+};
+
 std::vector<std::string> FiledesHelp = {
     "NAME",
     "    partab, codetab, griddes, zaxisdes, vct - Dataset description",
@@ -203,6 +239,18 @@ std::vector<std::string> CopyHelp = {
     "          of outfile. If outfile does not exist it will be created.",
 };
 
+std::vector<std::string> TeeHelp = {
+    "NAME",
+    "    tee - Duplicate a data stream",
+    "",
+    "SYNOPSIS",
+    "    tee  infile outfile1 outfile2",
+    "",
+    "DESCRIPTION",
+    "    This operator copies the input datasets to outfile1 and outfile2.",
+    "    It can be used to store intermediate results to a file.",
+};
+
 std::vector<std::string> ReplaceHelp = {
     "NAME",
     "    replace - Replace variables",
@@ -3538,7 +3586,7 @@ std::vector<std::string> EOFsHelp = {
     "        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.",
+    "        It is used to set the weight mode. The default is 'off'. Set it to 'on' for a 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.",
@@ -4123,16 +4171,17 @@ std::vector<std::string> SpectralHelp = {
     "    sp2sp,trunc  infile outfile",
     "",
     "DESCRIPTION",
-    "    This module transforms fields on Gaussian grids to spectral coefficients and vice versa.",
+    "    This module transforms fields on a global regular Gaussian grids to spectral coefficients and vice versa.",
+    "    Missing values are not supported.",
     "",
     "OPERATORS",
     "    sp2gp   Spectral to gridpoint",
-    "            Convert all fields with spectral coefficients to a regular Gaussian grid. The number of ",
+    "            Convert all fields with spectral coefficients to a global regular Gaussian grid. The number of ",
     "            latitudes of the resulting Gaussian grid is calculated from the triangular truncation by:",
     "            ",
     "               nlat = NINT((trunc*3 + 1.)/2.)",
     "    sp2gpl  Spectral to gridpoint (linear)",
-    "            Convert all fields with spectral coefficients to a regular Gaussian grid. The number of ",
+    "            Convert all fields with spectral coefficients to a global regular Gaussian grid. The number of ",
     "            latitudes of the resulting Gaussian grid is calculated from the triangular truncation by:",
     "            ",
     "               nlat = NINT((trunc*2 + 1.)/2.)",
@@ -4168,8 +4217,8 @@ std::vector<std::string> 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. The Gaussian latitudes need to be ordered from",
-    "    north to south.",
+    "    U and V are on a global regular Gaussian grid. The Gaussian latitudes need to be ordered from",
+    "    north to south. Missing values are not supported.",
     "",
     "OPERATORS",
     "    dv2uv   Divergence and vorticity to U and V wind",
@@ -5097,6 +5146,82 @@ std::vector<std::string> CMORliteHelp = {
     "    convert  STRING   Converts the units if necessary",
 };
 
+std::vector<std::string> CMORHelp = {
+    "NAME",
+    "    cmor - Climate Model Output Rewriting to produce CMIP-compliant data",
+    "",
+    "SYNOPSIS",
+    "    cmor,MIPtable[,cmor_name=VarList,[key=value,...]]  infile",
+    "",
+    "DESCRIPTION",
+    "    ",
+    "    ",
+    "    The CDO operator cmor converts an infile into a CMIP-compliant format",
+    "    by using the CMOR library. Each output file contains a single output variable.",
+    "    The name of the output files are generated by CMOR based on the DRS (Data reference",
+    "    Syntax) of the project. CMOR checks and applies the information delivered",
+    "    through the project dependend MIPtable on the infile. Additional information",
+    "    which is required for the conversion can be configured via keyvalues as optional parameters.",
+    "    ",
+    "    By specifying a variable selector keyvalue, e.g. cmor_name=tas, the user can",
+    "    pre-select a subset of infile variables. If name or code is specified, a",
+    "    corresponding cmor_name which can also be found in the MIPtable is also",
+    "    required to map the infile variable to the CMOR-variable. For mapping more",
+    "    variables at the operator call, one can specify a mapping table via keyword mapping_table.",
+    "    ",
+    "    Global attributes must be collected in info files and can be specified via keyword",
+    "    info. All required and optional global attributes as well as information",
+    "    about table file formats are given in the 'cdo cmor manual'.",
+    "    ",
+    "    If questions remain, do not hesitate to ask and send an email to wachsmannATdkrz.de.",
+    "    ",
+    "",
+    "PARAMETER",
+    "    MIPtable                   STRING    Name of the MIP table as used by CMOR.",
+    "                               --------------------------------------------------------------------------------------------",
+    "    cmor_name           | cn   STRING    Variable selector and specified in the MIP table.",
+    "                                         Comma separated list of CMOR variable names.",
+    "                                         Default is to process all variables.",
+    "    name                | n    STRING    Variable selector.",
+    "                                         Name of a selected @file{infile} variable.",
+    "    code                | c    INTEGER   Variable selector. ",
+    "                                         Three digits (GRIB) Code of a selected @file{infile} variable.",
+    "                               --------------------------------------------------------------------------------------------",
+    "    info                | i    STRING    Preprozessing.",
+    "                                         List of filenames containing global attributes and information.",
+    "                                         Default: CWD/.cdocmorinfo",
+    "    grid_info           | gi   STRING    Preprozessing.",
+    "                                         NetCDF file with model grid description.",
+    "    mapping_table       | mt   STRING    Preprozessing.",
+    "                                         Fortran Namelist containing variable information for e.g. renaming.",
+    "                               --------------------------------------------------------------------------------------------",
+    "    drs                 | d    CHARACTER Output control.",
+    "                                         Do(=y, default) or do not(=n) move output into the project DRS structure.",
+    "    drs_root            | dr   STRING    Output control. CMOR output root directory.",
+    "                                         Default: CWD.",
+    "    output_mode         | om   CHARACTER Output control.",
+    "                                         Either 'r' for replace (default) or 'a' for append mode.",
+    "    last_chunk          | lc   STRING    Output control. Filename of chunk to which shall be appended.  ",
+    "    maximum_size        | ms   INTEGER   Output control. Limit of output file sie in GigaByte.",
+    "                               --------------------------------------------------------------------------------------------",
+    "    required_time_units | rtu  STRING    Temporal description.",
+    "                                         Time axis reference date specified by the experiment.",
+    "                                         Format: 'days since YYYY-day-month hh:mm:ss'.",
+    "    cell_methods        | cm   CHARACTER Temporal description.",
+    "                                         Cell_methods of time axis.",
+    "                                         Value is one of 'm' (default)  , 'p', 'c', 'n'.",
+    "                               --------------------------------------------------------------------------------------------",
+    "    units               | u    STRING    Variable attrbiute. Units of the variable.",
+    "                                         Must be known by library UDunits.",
+    "    variable_comment    | vc   STRING    Variable attrbiute. Variable comment.",
+    "    positive            | p    CHARACTER Variable attrbiute.",
+    "                                         Positive flux direction, either 'u' for upward or 'd' for downward.",
+    "                               --------------------------------------------------------------------------------------------",
+    "    scalar_z_coordinate | szc  STRING    Scalar z-coordinate (=name_value).",
+    "    character_axis      | ca   STRING    CMOR name of a character axis.",
+    "                                         Valid axes are: basin, vegtype or oline. ",
+};
+
 std::vector<std::string> MagplotHelp = {
     "NAME",
     "    contour, shaded, grfill - Lat/Lon plot",
diff --git a/src/pipe.cc b/src/pipe.cc
index 7e9226a..b0797e8 100644
--- a/src/pipe.cc
+++ b/src/pipe.cc
@@ -38,11 +38,12 @@ pipe_t::pipe_t() { pipe_init(); }
 void
 pipe_t::pipe_init()
 {
-  pthread_mutexattr_t m_attr;
+/*  pthread_mutexattr_t m_attr;
   pthread_condattr_t c_attr;
 
   pthread_mutexattr_init(&m_attr);
   pthread_condattr_init(&c_attr);
+  */
   /*
 #if defined(_POSIX_THREAD_PROCESS_SHARED)
   if ( PipeDebug )
@@ -87,7 +88,7 @@ pipe_t::pipe_init()
   hasdata = false;
   usedata = true;
   // pstreamptr_in = 0;
-
+/*
   mutex = (pthread_mutex_t *) Malloc(sizeof(pthread_mutex_t));
   pthread_mutex_init(mutex, &m_attr);
 
@@ -114,12 +115,13 @@ pipe_t::pipe_init()
 
   pthread_mutexattr_destroy(&m_attr);
   pthread_condattr_destroy(&c_attr);
+  */
 }
 int
 pipe_t::pipeInqTimestep(int p_tsID)
 {
   // LOCK
-  pthread_mutex_lock(mutex);
+  std::unique_lock<std::mutex> locked_mutex(m_mutex);
   usedata = false;
   recIDr = -1;
   if (p_tsID != tsIDr + 1)
@@ -143,24 +145,24 @@ pipe_t::pipeInqTimestep(int p_tsID)
             Message("%s has data", name.c_str());
           hasdata = false;
           data = NULL;
-          pthread_cond_signal(readCond);
+          readCond.notify_all();
         }
       else if (PipeDebug)
         Message("%s has no data", name.c_str());
 
-      pthread_cond_signal(recInq); /* o.k. ??? */
+      recInq.notify_all(); /* o.k. ??? */
 
       if (PipeDebug)
         Message("%s wait of tsDef", name.c_str());
-      pthread_cond_wait(tsDef, mutex);
+      tsDef.wait(locked_mutex);
     }
 
   int numrecs = EOP ? 0 : nrecs;
 
-  pthread_mutex_unlock(mutex);
+  locked_mutex.unlock();
   // UNLOCK
 
-  pthread_cond_signal(tsInq);
+  tsInq.notify_all();
 
   return numrecs;
 }
@@ -170,16 +172,17 @@ pipe_t::pipeDefVlist(int &target_vlistID, int new_vlistID)
 {
 
   // LOCK
-  pthread_mutex_lock(mutex);
+  m_mutex.lock();
   target_vlistID = new_vlistID;
-  pthread_mutex_unlock(mutex);
+  m_mutex.unlock();
   // UNLOCK
 
   // lets the program know that the vlist is now defined
-  pthread_cond_signal(vlistDef);
+  vlistDef.notify_all();
 }
 
-#define TIMEOUT 1  // wait 1 seconds
+//#define TIMEOUT 1  // wait 1 seconds
+constexpr std::chrono::milliseconds TIMEOUT = std::chrono::milliseconds(1000);
 #define MIN_WAIT_CYCLES 10
 #define MAX_WAIT_CYCLES 3600
 int processNumsActive(void);
@@ -188,39 +191,35 @@ int
 pipe_t::pipeInqVlist(int &p_vlistID)
 {
   int vlistID = -1;
-  struct timespec time_to_wait;
-  int retcode = 0;
+  std::chrono::milliseconds time_to_wait(0);
+  std::cv_status retcode = std::cv_status::timeout;
   int nwaitcycles = 0;
 
-  time_to_wait.tv_sec = 0;
-  time_to_wait.tv_nsec = 0;
-
   // LOCK
-  pthread_mutex_lock(mutex);
-  time_to_wait.tv_sec = time(NULL);
-  while (p_vlistID == -1 && retcode == 0)
+  std::unique_lock<std::mutex> locked_mutex(m_mutex);
+  while (p_vlistID == -1 && retcode == std::cv_status::timeout)
     {
-      time_to_wait.tv_sec += TIMEOUT;
+      time_to_wait += TIMEOUT;
       // fprintf(stderr, "tvsec %g\n", (double) time_to_wait.tv_sec);
       if (PipeDebug)
         Message("%s wait of vlistDef", name.c_str());
       // pthread_cond_wait(pipe->vlistDef, pipe->mutex);
-      retcode = pthread_cond_timedwait(vlistDef, mutex, &time_to_wait);
+      retcode = vlistDef.wait_for(locked_mutex, time_to_wait);
       // fprintf(stderr, "self %d retcode %d %d %d\n", pstreamptr->self, retcode, processNumsActive(),
       // vlistID);
-      if (retcode != 0 && nwaitcycles++ < MAX_WAIT_CYCLES)
+      //if (retcode != 0 && nwaitcycles++ < MAX_WAIT_CYCLES)
+      if (retcode != std::cv_status::timeout && nwaitcycles++ < MAX_WAIT_CYCLES)
         {
           if (processNumsActive() > 1 || (processNumsActive() == 1 && nwaitcycles < MIN_WAIT_CYCLES))
-            retcode = 0;
+            retcode = std::cv_status::timeout;
         }
     }
 
-  if (retcode == 0)
+  if (retcode == std::cv_status::timeout)
     vlistID = p_vlistID;
   else if (PipeDebug)
     Message("%s timeout!", name.c_str());
 
-  pthread_mutex_unlock(mutex);
   // UNLOCK
 
   return vlistID;
@@ -232,7 +231,7 @@ pipe_t::pipeDefTimestep(int p_vlistID, int p_tsID)
   int numrecs;
 
   // LOCK
-  pthread_mutex_lock(mutex);
+  m_mutex.lock();
   recIDw = -1;
   tsIDw++;
   if (p_tsID != tsIDw)
@@ -246,15 +245,13 @@ pipe_t::pipeDefTimestep(int p_vlistID, int p_tsID)
       numrecs = 0;
       for (int varID = 0; varID < vlistNvars(vlistID); varID++)
         {
-          if (vlistInqVarTsteptype(vlistID, varID) != TSTEP_CONSTANT)
+          if (vlistInqVarTimetype(vlistID, varID) != TIME_CONSTANT)
             {
               numrecs += zaxisInqSize(vlistInqVarZaxis(vlistID, varID));
             }
         }
       if (PipeDebug)
-        {
-          Message("numrecs = %d nvars = %d", numrecs, vlistNvars(vlistID));
-        }
+        Message("%s numrecs = %d nvars = %d", name.c_str(), numrecs, vlistNvars(vlistID));
     }
 
   nrecs = numrecs;
@@ -262,14 +259,14 @@ pipe_t::pipeDefTimestep(int p_vlistID, int p_tsID)
     Message("%s numrecs %d p_tsID %d %d %d", name.c_str(), numrecs, p_tsID, tsIDw, tsIDr);
   if (numrecs == 0)
     EOP = true;
-  pthread_mutex_unlock(mutex);
+  m_mutex.unlock();
   // UNLOCK
 
-  pthread_cond_signal(tsDef);
+  tsDef.notify_all();
   // sleep(1);
 
   // LOCK
-  pthread_mutex_lock(mutex);
+  std::unique_lock<std::mutex> locked_mutex(m_mutex);
   while (tsIDr < p_tsID)
     {
       if (EOP)
@@ -280,9 +277,8 @@ pipe_t::pipeDefTimestep(int p_vlistID, int p_tsID)
         }
       if (PipeDebug)
         Message("%s wait of tsInq (p_tsID %d %d)", name.c_str(), p_tsID, tsIDr);
-      pthread_cond_wait(tsInq, mutex);
+      tsInq.wait(locked_mutex);
     }
-  pthread_mutex_unlock(mutex);
   // UNLOCK
 }
 
@@ -294,7 +290,7 @@ pipe_t::pipeInqRecord(int *p_varID, int *p_levelID)
   // if (PipeDebug)
 
   // LOCK
-  pthread_mutex_lock(mutex);
+  m_mutex.lock();
   if (PipeDebug)
     Message("%s has no data %d %d", name.c_str(), recIDr, recIDw);
   if (hasdata || usedata)
@@ -304,14 +300,14 @@ pipe_t::pipeInqRecord(int *p_varID, int *p_levelID)
       usedata = false;
       condSignal = true;
     }
-  pthread_mutex_unlock(mutex);
+  m_mutex.unlock();
   // UNLOCK
 
   if (condSignal)
-    pthread_cond_signal(readCond);
+    readCond.notify_all();
 
   // LOCK
-  pthread_mutex_lock(mutex);
+  std::unique_lock<std::mutex> locked_mutex(m_mutex);
   usedata = true;
   recIDr++;
 
@@ -328,7 +324,7 @@ pipe_t::pipeInqRecord(int *p_varID, int *p_levelID)
         }
       if (PipeDebug)
         Message("%s wait of recDef", name.c_str());
-      pthread_cond_wait(recDef, mutex);
+      recDef.wait(locked_mutex);
     }
 
   if (EOP)
@@ -342,10 +338,10 @@ pipe_t::pipeInqRecord(int *p_varID, int *p_levelID)
       *p_levelID = levelID;
     }
 
-  pthread_mutex_unlock(mutex);
+  locked_mutex.unlock();
   // UNLOCK
 
-  pthread_cond_signal(recInq);
+  recInq.notify_all();
 
   return 0;
 }
@@ -356,7 +352,7 @@ pipe_t::pipeDefRecord(int p_varID, int p_levelID)
   bool condSignal = false;
 
   // LOCK
-  pthread_mutex_lock(mutex);
+  m_mutex.lock();
   if (PipeDebug)
     Message("%s has data %d %d", name.c_str(), recIDr, recIDw);
   if (hasdata)
@@ -365,27 +361,27 @@ pipe_t::pipeDefRecord(int p_varID, int p_levelID)
       data = NULL;
       condSignal = true;
     }
-  pthread_mutex_unlock(mutex);
+  m_mutex.unlock();
   // UNLOCK
 
   if (condSignal)
-    pthread_cond_signal(readCond);
+    readCond.notify_all();
 
   // LOCK
-  pthread_mutex_lock(mutex);
+  m_mutex.lock();
   usedata = true;
   recIDw++;
   varID = p_varID;
   levelID = p_levelID;
   if (PipeDebug)
     Message("%s recID %d %d", name.c_str(), recIDr, recIDw);
-  pthread_mutex_unlock(mutex);
+  m_mutex.unlock();
   // UNLOCK
 
-  pthread_cond_signal(recDef);
+  recDef.notify_all();
 
   // LOCK
-  pthread_mutex_lock(mutex);
+  std::unique_lock<std::mutex> locked_mutex(m_mutex);
   while (recIDr < recIDw)
     {
       if (tsIDw != tsIDr)
@@ -394,9 +390,8 @@ pipe_t::pipeDefRecord(int p_varID, int p_levelID)
         break;
       if (PipeDebug)
         Message("%s wait of recInq %d", name.c_str(), recIDr);
-      pthread_cond_wait(recInq, mutex);
+      recInq.wait(locked_mutex);
     }
-  pthread_mutex_unlock(mutex);
   // UNLOCK
 }
 
@@ -453,12 +448,12 @@ pipe_t::pipeReadRecord(int p_vlistID, double *data, int *nmiss)
   *nmiss = 0;
 
   // LOCK
-  pthread_mutex_lock(mutex);
+  std::unique_lock<std::mutex> locked_mutex(m_mutex);
   while (!hasdata)
     {
       if (PipeDebug)
         Message("%s wait of writeCond", name.c_str());
-      pthread_cond_wait(writeCond, mutex);
+      writeCond.wait(locked_mutex);
     }
 
   if (hasdata)
@@ -475,10 +470,10 @@ pipe_t::pipeReadRecord(int p_vlistID, double *data, int *nmiss)
 
   hasdata = false;
   data = NULL;
-  pthread_mutex_unlock(mutex);
+  locked_mutex.unlock();
   // UNLOCK
 
-  pthread_cond_signal(readCond);
+  readCond.notify_all();
 }
 
 void
@@ -488,20 +483,20 @@ pipe_t::pipeWriteRecord(double *p_data, int p_nmiss)
   if ( ! usedata ) return;
   */
   // LOCK
-  pthread_mutex_lock(mutex);
+  m_mutex.lock();
   hasdata = true; /* data pointer */
   data = p_data;
   nmiss = p_nmiss;
-  pthread_mutex_unlock(mutex);
+  m_mutex.unlock();
   // UNLOCK
 
-  pthread_cond_signal(writeCond);
+  writeCond.notify_all();
 
   if (PipeDebug)
     Message("%s write record %d", name.c_str(), recIDw);
 
   // LOCK
-  pthread_mutex_lock(mutex);
+  std::unique_lock<std::mutex> locked_mutex(m_mutex);
   while (hasdata)
     {
       if (!usedata)
@@ -521,9 +516,8 @@ pipe_t::pipeWriteRecord(double *p_data, int p_nmiss)
         }
       if (PipeDebug)
         Message("%s wait of readCond", name.c_str());
-      pthread_cond_wait(readCond, mutex);
+      readCond.wait(locked_mutex);
     }
-  pthread_mutex_unlock(mutex);
   // UNLOCK
 }
 
diff --git a/src/pipe.h b/src/pipe.h
index 9552c63..4ace564 100644
--- a/src/pipe.h
+++ b/src/pipe.h
@@ -36,6 +36,9 @@
 
 #if defined(HAVE_LIBPTHREAD)
 
+#include <condition_variable>
+#include <mutex>
+
 struct pipe_t
 {
 
@@ -65,10 +68,10 @@ public:
   // pstream_t *pstreamptr_in;
   /* unsigned long */ off_t nvals;
 
-  pthread_mutex_t *mutex;
-  pthread_cond_t *tsDef, *tsInq, *vlistDef, *isclosed;
-  pthread_cond_t *recDef, *recInq;
-  pthread_cond_t *writeCond, *readCond;
+  std::mutex m_mutex;
+  std::condition_variable tsDef, tsInq, vlistDef, isclosed;
+  std::condition_variable recDef, recInq;
+  std::condition_variable writeCond, readCond;
 
   std::string name;
 };
diff --git a/src/pmlist.cc b/src/pmlist.cc
index d654135..d401ae3 100644
--- a/src/pmlist.cc
+++ b/src/pmlist.cc
@@ -139,13 +139,16 @@ int kvlist_parse_cmdline(list_t *kvlist, int nparams, char **params)
       while ( i + j < nparams && strchr(params[i + j], '=') == NULL ) j++;
 
       int nvalues = j;
-      const char *values[nvalues];
+
+      const char **values = nvalues ? (const char**) malloc(nvalues*sizeof(char*)) : NULL;
 
       values[0] = end + 1;
       if ( *values[0] == 0 ) nvalues = 0;
+
       for ( j = 1; j < nvalues; ++j ) values[j] = params[i + j];
-      
       kvlist_append(kvlist, key, values, nvalues);
+
+      if ( values ) free(values);
       
       i += j;
     }
diff --git a/src/printinfo.h b/src/printinfo.h
index 01b9b8d..052055b 100644
--- a/src/printinfo.h
+++ b/src/printinfo.h
@@ -62,52 +62,32 @@ void printFiletype(int streamID, int vlistID)
 {
   int filetype = streamInqFiletype(streamID);
 
+  // clang-format off
   switch ( filetype )
     {
-    case CDI_FILETYPE_GRB:
-      printf("GRIB");
-      break;
-    case CDI_FILETYPE_GRB2:
-      printf("GRIB2");
-      break;
-    case CDI_FILETYPE_NC:
-      printf("NetCDF");
-      break;
-    case CDI_FILETYPE_NC2:
-      printf("NetCDF2");
-      break;
-    case CDI_FILETYPE_NC4:
-      printf("NetCDF4");
-      break;
-    case CDI_FILETYPE_NC4C:
-      printf("NetCDF4 classic");
-      break;
-    case CDI_FILETYPE_SRV:
-      printf("SERVICE");
-      break;
-    case CDI_FILETYPE_EXT:
-      printf("EXTRA");
-      break;
-    case CDI_FILETYPE_IEG:
-      printf("IEG");
-      break;
-    default:
-      printf("  File format: unsupported filetype %d" , filetype);
-      break;
+    case CDI_FILETYPE_GRB:  printf("GRIB");  break;
+    case CDI_FILETYPE_GRB2: printf("GRIB2");  break;
+    case CDI_FILETYPE_NC:   printf("NetCDF");  break;
+    case CDI_FILETYPE_NC2:  printf("NetCDF2");  break;
+    case CDI_FILETYPE_NC4:  printf("NetCDF4");  break;
+    case CDI_FILETYPE_NC4C: printf("NetCDF4 classic");  break;
+    case CDI_FILETYPE_NC5:  printf("NetCDF5");  break;
+    case CDI_FILETYPE_SRV:  printf("SERVICE");  break;
+    case CDI_FILETYPE_EXT:  printf("EXTRA");  break;
+    case CDI_FILETYPE_IEG:  printf("IEG");  break;
+    default: printf("  File format: unsupported filetype %d" , filetype);  break;
     }
 
   if ( filetype == CDI_FILETYPE_SRV || filetype == CDI_FILETYPE_EXT || filetype == CDI_FILETYPE_IEG )
     {
       switch ( streamInqByteorder(streamID) )
 	{
-	case CDI_BIGENDIAN:
-	  printf("  BIGENDIAN"); break;
-	case CDI_LITTLEENDIAN:
-	  printf("  LITTLEENDIAN"); break;
-	default:
-	  printf("  byteorder: %d undefined", streamInqByteorder(streamID)); break;
+	case CDI_BIGENDIAN:    printf("  BIGENDIAN");  break;
+	case CDI_LITTLEENDIAN: printf("  LITTLEENDIAN");  break;
+	default: printf("  byteorder: %d undefined", streamInqByteorder(streamID));  break;
 	}
     }
+  // clang-format on
 
   if ( filetype == CDI_FILETYPE_GRB || filetype == CDI_FILETYPE_NC4 || filetype == CDI_FILETYPE_NC4C )
     {
@@ -282,7 +262,7 @@ void printGridInfoKernel(int gridID, int index, bool lproj)
   size_t ysize    = gridInqYsize(gridID);
   size_t xysize   = xsize*ysize;
 
-  // int prec     = gridInqPrec(gridID);
+  // int prec     = gridInqDatatype(gridID);
   // int dig = (prec == CDI_DATATYPE_FLT64) ? 15 : 7;
   int dig = 7;
 #ifdef CDO
@@ -482,7 +462,7 @@ void printZaxisInfo(int vlistID)
       int zaxistype = zaxisInqType(zaxisID);
       int ltype     = zaxisInqLtype(zaxisID);
       int levelsize = zaxisInqSize(zaxisID);
-      // int prec      = zaxisInqPrec(zaxisID);
+      // int prec      = zaxisInqDatatype(zaxisID);
       // int dig = (prec == CDI_DATATYPE_FLT64) ? 15 : 7;
       int dig = 7;
 #ifdef CDO
@@ -591,7 +571,7 @@ void printZaxisInfo(int vlistID)
           if ( number > 0 )
             {
               fprintf(stdout, "%33s : ", "zaxis");
-              fprintf(stdout, "number = %d\n", number);
+              fprintf(stdout, "number=%d\n", number);
             }
 
           unsigned char uuidOfVGrid[CDI_UUID_SIZE];
diff --git a/src/process.cc b/src/process.cc
index c82db39..21f9a10 100644
--- a/src/process.cc
+++ b/src/process.cc
@@ -16,11 +16,11 @@
 */
 
 #if defined(HAVE_CONFIG_H)
-#  include "config.h"
+#include "config.h"
 #endif
 
 #if defined(HAVE_PTHREAD_H)
-#  include <pthread.h>
+#include <pthread.h>
 #endif
 
 #include <stdio.h>
@@ -42,84 +42,109 @@
 #include "dmemory.h"
 #include "pthread.h"
 
+#include <map>
+
 #if defined(HAVE_LIBPTHREAD)
 pthread_mutex_t processMutex = PTHREAD_MUTEX_INITIALIZER;
 #endif
 
-static process_t Process[MAX_PROCESS];
+constexpr bool PROCESS_DEBUG = false;
+
+static std::map<int, process_t> Process;
 
 static int NumProcess = 0;
 static int NumProcessActive = 0;
 
-int processCreate(void)
+process_t::process_t(int p_ID) : m_ID(p_ID) { initProcess(); }
+
+void
+process_t::initProcess()
 {
 #if defined(HAVE_LIBPTHREAD)
-  pthread_mutex_lock(&processMutex);
+  threadID = pthread_self();
+  l_threadID = 1;
 #endif
+  nchild = 0;
 
-  int processID = NumProcess++;
-  NumProcessActive++;
+  cdoProcessTime(&s_utime, &s_stime);
+  a_utime = 0;
+  a_stime = 0;
+  cputime = 0;
+  nvals = NULL;
+  nvars = NULL;
+  ntimesteps = NULL;
 
-#if defined(HAVE_LIBPTHREAD)
-  pthread_mutex_unlock(&processMutex);  
-#endif
+  streamCnt = 0;
 
-  if ( processID >= MAX_PROCESS )
-    Error("Limit of %d processes reached!", MAX_PROCESS);
+  oargc = 0;
+  xoperator = "UNINITALIZED";
+  operatorName = "UNINITALIZED";
+  operatorArg = "UNINITALIZED";
+
+  noper = 0;
+}
+
+int
+process_t::getInStreamCnt()
+{
+  return inputStreams.size();
+}
+int
+process_t::getOutStreamCnt()
+{
+  return outputStreams.size();
+}
 
+int
+processCreate(void)
+{
 #if defined(HAVE_LIBPTHREAD)
-  Process[processID].threadID     = pthread_self();
-  Process[processID].l_threadID   = 1;
+  pthread_mutex_lock(&processMutex);
 #endif
-  Process[processID].nInStream      = 0;
-  Process[processID].nOutStream      = 0;
-  Process[processID].nchild       = 0;
 
-  cdoProcessTime(&Process[processID].s_utime, &Process[processID].s_stime);
-  Process[processID].a_utime      = 0;
-  Process[processID].a_stime      = 0;
-  Process[processID].cputime      = 0;
+  int processID = NumProcess++;
+  Process.insert(std::make_pair(processID, process_t(processID)));
 
-  Process[processID].oargc        = 0;
-  Process[processID].xoperator    = NULL;
-  Process[processID].operatorName = NULL;
-  Process[processID].operatorArg  = NULL;
+  NumProcessActive++;
 
-  Process[processID].noper        = 0;
+#if defined(HAVE_LIBPTHREAD)
+  pthread_mutex_unlock(&processMutex);
+#endif
+
+  if (processID >= MAX_PROCESS)
+    Error("Limit of %d processes reached!", MAX_PROCESS);
 
   return processID;
 }
 
-
-int processSelf(void)
+process_t &
+processSelf(void)
 {
-  int processID = 0;
 #if defined(HAVE_LIBPTHREAD)
   pthread_t thID = pthread_self();
 
   pthread_mutex_lock(&processMutex);
 
-  for ( processID = 0; processID < NumProcess; processID++ )
-    if ( Process[processID].l_threadID )
-      if ( pthread_equal(Process[processID].threadID, thID) ) break;
-
-  if ( processID == NumProcess )
-    {
-      if ( NumProcess > 0 )
-        Error("Internal problem, process not found!");
-      else
-        processID = 0;
-    }
+  for ( auto &id_process_pair : Process)
+    if (id_process_pair.second.l_threadID)
+      {
+        if (pthread_equal(id_process_pair.second.threadID, thID))
+          {
+            pthread_mutex_unlock(&processMutex);
+            return id_process_pair.second;
+          }
+      }
 
+  std::cout << "returning the 0th process" << std::endl;
   pthread_mutex_unlock(&processMutex);
 
 #endif
-
-  return processID;
+  std::cout << "returning the std process 0" << std::endl;
+  return Process.find(0)->second;
 }
 
-
-int processNums(void)
+int
+processNums(void)
 {
 #if defined(HAVE_LIBPTHREAD)
   pthread_mutex_lock(&processMutex);
@@ -128,14 +153,14 @@ int processNums(void)
   int pnums = NumProcess;
 
 #if defined(HAVE_LIBPTHREAD)
-  pthread_mutex_unlock(&processMutex);  
+  pthread_mutex_unlock(&processMutex);
 #endif
 
   return pnums;
 }
 
-
-int processNumsActive(void)
+int
+processNumsActive(void)
 {
 #if defined(HAVE_LIBPTHREAD)
   pthread_mutex_lock(&processMutex);
@@ -144,177 +169,171 @@ int processNumsActive(void)
   int pnums = NumProcessActive;
 
 #if defined(HAVE_LIBPTHREAD)
-  pthread_mutex_unlock(&processMutex);  
+  pthread_mutex_unlock(&processMutex);
 #endif
 
   return pnums;
 }
 
-
-void processAddNvals(off_t nvals)
+void
+processAddNvals(off_t nvals)
 {
-  int processID = processSelf();
-
-  Process[processID].nvals += nvals;
+  processSelf().nvals += nvals;
 }
 
-
-off_t processInqNvals(int processID)
+off_t
+processInqNvals(int processID)
 {
-  return Process[processID].nvals;
+  return Process.find(processID)->second.nvals;
 }
 
-void processAddOutputStream(pstream_t *p_pstream_ptr)
+void
+processAddOutputStream(pstream_t *p_pstream_ptr)
 {
-  int processID = processSelf();
+  process_t &process = processSelf();
 
-  int sindex = Process[processID].nOutStream++;
+  int sindex = process.getOutStreamCnt();
 
-  if ( sindex >= MAX_STREAM )
-    Error("Limit of %d output streams per process reached (processID = %d)!", MAX_STREAM, processID);
+  if (sindex >= MAX_STREAM)
+    Error("Limit of %d output streams per process reached (processID = %d)!", MAX_STREAM, process.m_ID);
 
-  Process[processID].outputStreams[sindex] = p_pstream_ptr->self;
+  process.outputStreams.push_back(p_pstream_ptr);
 }
 
-void processAddInputStream(pstream_t *p_pstream_ptr)
+void
+processAddInputStream(pstream_t *p_pstream_ptr)
 {
-  int processID = processSelf();
+  process_t &process = processSelf();
 
   if (p_pstream_ptr->isPipe())
-  {
-      Process[processID].nchild++;
-  }
-  int sindex = Process[processID].nInStream++;
+    {
+      process.nchild++;
+    }
+  int sindex = process.getInStreamCnt();
 
-  if ( sindex >= MAX_STREAM )
-    Error("Limit of %d input streams per process reached (processID = %d)!", MAX_STREAM, processID);
+  if (sindex >= MAX_STREAM)
+    Error("Limit of %d input streams per process reached (processID = %d)!", MAX_STREAM, process.m_ID);
 
-  Process[processID].inputStreams[sindex] = p_pstream_ptr->self;
+  process.inputStreams.push_back(p_pstream_ptr);
 }
 
-
-void processDelStream(int streamID)
+void
+processDelStream(int streamID)
 {
   UNUSED(streamID);
 }
 
-
-void processDefCputime(int processID, double cputime)
+void
+processDefCputime(int processID, double cputime)
 {
-  Process[processID].cputime = cputime;
+  Process.find(processID)->second.cputime = cputime;
 }
 
-
-double processInqCputime(int processID)
+double
+processInqCputime(int processID)
 {
-  return Process[processID].cputime;
+  return Process.find(processID)->second.cputime;
 }
 
-
-void processStartTime(double *utime, double *stime)
+void
+processStartTime(double *utime, double *stime)
 {
-  int processID = processSelf();
+  process_t &process = processSelf();
 
-  *utime = Process[processID].s_utime;
-  *stime = Process[processID].s_stime;
+  *utime = process.s_utime;
+  *stime = process.s_stime;
 }
 
-
-void processEndTime(double *utime, double *stime)
+void
+processEndTime(double *utime, double *stime)
 {
-  *utime = Process[0].a_utime;
-  *stime = Process[0].a_stime;
+  process_t &process = Process.find(0)->second;
+  *utime = process.a_utime;
+  *stime = process.a_stime;
 }
 
-
-void processAccuTime(double utime, double stime)
+void
+processAccuTime(double utime, double stime)
 {
-  Process[0].a_utime += utime;
-  Process[0].a_stime += stime;
+  process_t &process = Process.find(0)->second;
+  process.a_utime += utime;
+  process.a_stime += stime;
 }
 
-
-int processInqOutputStreamNum(void)
+int
+processInqOutputStreamNum(void)
 {
-  int processID = processSelf();
-
-  return Process[processID].nOutStream;
+  return processSelf().getOutStreamCnt();
 }
 
-int processInqInputStreamNum(void)
+int
+processInqInputStreamNum(void)
 {
-  int processID = processSelf();
-
-  return Process[processID].nInStream;
+  return processSelf().getInStreamCnt();
 }
 
-
-int processInqChildNum(void)
+int
+processInqChildNum(void)
 {
-  int processID = processSelf();
-
-  return Process[processID].nchild;
+  return processSelf().nchild;
 }
 
-
-int processInqOutputStreamID(int streamindex)
+pstream_t *
+processInqOutputStream(int streamindex)
 {
-  int processID = processSelf();
-
-  return (Process[processID].outputStreams[streamindex]);
+  return (processSelf().outputStreams[streamindex]);
 }
-int processInqInputStreamID(int streamindex)
+pstream_t *
+processInqInputStream(int streamindex)
 {
-  int processID = processSelf();
-
-  return (Process[processID].inputStreams[streamindex]);
+  return (processSelf().inputStreams[streamindex]);
 }
 
-const char *processInqOpername2(int processID)
+const char *
+processInqOpername2(process_t &process)
 {
-  return Process[processID].operatorName;
+  return process.operatorName;
 }
 
-
-const char *processInqOpername(void)
+const char *
+processInqOpername(void)
 {
-  int processID = processSelf();
-
-  return Process[processID].operatorName;
+  return processSelf().operatorName;
 }
 
-
-void processDefPrompt(const char *opername)
+void
+processDefPrompt(const char *opername)
 {
-  int processID = processSelf();
+  process_t &process = processSelf();
 
-  if ( processID == 0 )
-    sprintf(Process[processID].prompt, "%s %s", Progname, opername);
+  if (process.m_ID == 0)
+    sprintf(process.prompt, "%s %s", Progname, opername);
   else
-    sprintf(Process[processID].prompt, "%s(%d) %s", Progname, processID+1, opername);
+    sprintf(process.prompt, "%s(%d) %s", Progname, process.m_ID + 1, opername);
 }
 
-
-const char *processInqPrompt(void)
+const char *
+processInqPrompt(void)
 {
-  int processID = processSelf();
+  process_t &process = processSelf();
 
   const char *prompt = "cdo";
-  if (Process[processID].prompt[0] ) prompt = Process[processID].prompt;
+  if (process.prompt[0])
+    prompt = process.prompt;
 
   return prompt;
 }
 
 #if defined(HAVE_GLOB_H)
-static
-int get_glob_flags(void)
+static int
+get_glob_flags(void)
 {
   int glob_flags = 0;
 
-#if defined (GLOB_NOCHECK)
+#if defined(GLOB_NOCHECK)
   glob_flags |= GLOB_NOCHECK;
 #endif
-#if defined (GLOB_TILDE)
+#if defined(GLOB_TILDE)
   glob_flags |= GLOB_TILDE;
 #endif
 
@@ -324,8 +343,8 @@ int get_glob_flags(void)
 
 #if defined(HAVE_WORDEXP_H)
 /* Convert a shell pattern into a list of filenames. */
-static
-argument_t *glob_pattern(const char *restrict string)
+static argument_t *
+glob_pattern(const char *restrict string)
 {
   size_t cnt, length = 0;
   int flags = WRDE_UNDEF;
@@ -339,7 +358,7 @@ argument_t *glob_pattern(const char *restrict string)
   int status = wordexp(string, &glob_results, flags);
 
   // How much space do we need?
-  for ( p = glob_results.we_wordv, cnt = glob_results.we_wordc; cnt; p++, cnt-- )
+  for (p = glob_results.we_wordv, cnt = glob_results.we_wordc; cnt; p++, cnt--)
     {
       length += strlen(*p) + 1;
     }
@@ -348,84 +367,85 @@ argument_t *glob_pattern(const char *restrict string)
   argument = argument_new(glob_results.we_wordc, length);
 
   // put all generated filenames into the argument_t data structure
-  for ( cnt = 0; cnt < glob_results.we_wordc; cnt++ )
+  for (cnt = 0; cnt < glob_results.we_wordc; cnt++)
     {
       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, " ");
+      if (cnt < glob_results.we_wordc - 1)
+        strcat(argument->args, " ");
     }
 
-  if ( status == 0 ) wordfree(&glob_results);
+  if (status == 0)
+    wordfree(&glob_results);
 
   return argument;
 }
 #endif
 
-int cdoStreamCnt(void)
+int
+cdoStreamCnt(void)
 {
-  int processID = processSelf();
-
-  int cnt = Process[processID].streamCnt;
-
+  int cnt = processSelf().streamCnt;
   return cnt;
 }
 
-
-const argument_t *cdoStreamName(int cnt)
+const argument_t *
+cdoStreamName(int cnt)
 {
-  int processID = processSelf();
+  process_t &process = processSelf();
 
-  if ( cnt > Process[processID].streamCnt || cnt < 0 )
+  if (cnt > process.streamCnt || cnt < 0)
     Error("count %d out of range!", cnt);
 
-  return &(Process[processID].streamNames[cnt]);
+  return &(process.streamNames[cnt]);
 }
 
-
-const char *processOperator(void)
+const char *
+processOperator(void)
 {
-  int processID = processSelf();
-
-  return Process[processID].xoperator;
+  return processSelf().xoperator;
 }
 
-static int skipInputStreams(int argc, char *argv[], int globArgc, int nstreams);
+static int skipInputStreams(int argc,  std::vector<char *> &argv, int globArgc, int nstreams);
 
-static
-int getGlobArgc(int argc, char *argv[], int globArgc)
+static int
+getGlobArgc(int argc,  std::vector<char *> &argv, int globArgc)
 {
   char *opername = &argv[globArgc][1];
   char *comma_position = strchr(opername, ',');
-  if ( comma_position ) *comma_position = 0;
+  if (comma_position)
+    *comma_position = 0;
 
-  int streamInCnt  = operatorStreamInCnt(opername);
+  int streamInCnt = operatorStreamInCnt(opername);
   int streamOutCnt = operatorStreamOutCnt(opername);
 
-  if ( streamInCnt == -1 ) streamInCnt = 1;
+  if (streamInCnt == -1)
+    streamInCnt = 1;
 
-  if ( streamOutCnt > 1 )
+  if (streamOutCnt > 1)
     cdoAbort("More than one output stream not allowed in CDO pipes (Operator %s)!", opername);
 
   globArgc++;
 
-  if ( streamInCnt > 0 )
+  if (streamInCnt > 0)
     globArgc = skipInputStreams(argc, argv, globArgc, streamInCnt);
-  if ( comma_position ) *comma_position = ',';
+  if (comma_position)
+    *comma_position = ',';
 
   return globArgc;
 }
 
-static
-int skipInputStreams(int argc, char *argv[], int globArgc, int nstreams)
+static int
+skipInputStreams(int argc, std::vector<char*>& argv, int globArgc, int nstreams)
 {
-  while ( nstreams > 0 )
+  while (nstreams > 0)
     {
-      if ( globArgc >= argc )
+      if (globArgc >= argc)
         {
           cdoAbort("Too few arguments. Check command line!");
           break;
         }
-      if ( argv[globArgc][0] == '-' )
+      if (argv[globArgc][0] == '-')
         {
           globArgc = getGlobArgc(argc, argv, globArgc);
         }
@@ -438,15 +458,15 @@ int skipInputStreams(int argc, char *argv[], int globArgc, int nstreams)
   return globArgc;
 }
 
-static
-int getStreamCnt(int argc, char *argv[])
+static int
+getStreamCnt(int argc, std::vector<char *>& argv)
 {
   int streamCnt = 0;
   int globArgc = 1;
 
-  while ( globArgc < argc )
+  while (globArgc < argc)
     {
-      if ( argv[globArgc][0] == '-' )
+      if (argv[globArgc][0] == '-')
         {
           globArgc = getGlobArgc(argc, argv, globArgc);
         }
@@ -459,73 +479,78 @@ int getStreamCnt(int argc, char *argv[])
   return streamCnt;
 }
 
-static
-void setStreamNames(int argc, char *argv[])
+static void
+setStreamNames(int argc, std::vector<char *> &argv)
 {
-  int processID = processSelf();
+  process_t &process = processSelf();
   int i, ac;
   int globArgc = 1;
   int globArgcStart;
   char *streamname;
   int len;
 
-  while ( globArgc < argc )
+  while (globArgc < argc)
     {
-      if ( argv[globArgc][0] == '-' )
+      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++ )
+          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, " ");
+              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;
+          for (i = 1; i < len - 1; i++)
+            if (streamname[i] == '\0')
+              streamname[i] = ' ';
+          process.streamNames[process.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);
+          // printf("setStreamNames:  ac %d  streamname1: %s\n", ac, streamname);
+          process.streamNames[process.streamCnt].argv.resize(ac);
+          for (i = 0; i < ac; ++i)
+            process.streamNames[process.streamCnt].argv[i] = argv[i + globArgcStart];
+          process.streamNames[process.streamCnt].argc = ac;
+          process.streamCnt++;
+          // printf("setStreamNames:  streamname1: %s\n", streamname);
         }
       else
         {
           len = strlen(argv[globArgc]) + 1;
-          streamname = (char*) Malloc(len);
+          streamname = (char *) Malloc(len);
           strcpy(streamname, argv[globArgc]);
-          Process[processID].streamNames[Process[processID].streamCnt].args = streamname;
+          process.streamNames[process.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);
+          process.streamNames[process.streamCnt].argv.resize(ac);
+          process.streamNames[process.streamCnt].argv[0] = argv[globArgc];
+          process.streamNames[process.streamCnt].argc = ac;
+          process.streamNames[process.streamCnt].args = streamname;
+          process.streamCnt++;
+          // printf("setStreamNames:  streamname2: %s\n", streamname);
           globArgc++;
         }
     }
 }
 
-static
-int find_wildcard(const char *string, size_t len)
+static int
+find_wildcard(const char *string, size_t len)
 {
   int status = 0;
 
-  if ( len > 0 )
+  if (len > 0)
     {
-      if ( string[0] == '~' ) status = 1;
+      if (string[0] == '~')
+        status = 1;
 
-      if ( status == 0 )
+      if (status == 0)
         {
-          for ( size_t i = 0; i < len; ++i )
-            if ( string[i] == '?' || string[i] == '*' || string[i] == '[' )
+          for (size_t i = 0; i < len; ++i)
+            if (string[i] == '?' || string[i] == '*' || string[i] == '[')
               {
                 status = 1;
                 break;
@@ -536,12 +561,12 @@ int find_wildcard(const char *string, size_t len)
   return status;
 }
 
-
-char *expand_filename(const char *string)
+char *
+expand_filename(const char *string)
 {
   char *filename = NULL;
 
-  if ( find_wildcard(string, strlen(string)) )
+  if (find_wildcard(string, strlen(string)))
     {
 #if defined(HAVE_GLOB_H)
       int glob_flags = get_glob_flags();
@@ -549,7 +574,8 @@ char *expand_filename(const char *string)
 
       glob(string, glob_flags, 0, &glob_results);
 
-      if ( glob_results.gl_pathc == 1 ) filename = strdupx(glob_results.gl_pathv[0]);
+      if (glob_results.gl_pathc == 1)
+        filename = strdupx(glob_results.gl_pathv[0]);
 
       globfree(&glob_results);
 #endif
@@ -558,12 +584,13 @@ char *expand_filename(const char *string)
   return filename;
 }
 
-static
-int expand_wildcards(int processID, int streamCnt)
+static int
+expand_wildcards(process_t &process, int streamCnt)
 {
-  const char *streamname0 = Process[processID].streamNames[0].args;
+  const char *streamname0 = process.streamNames[0].args;
 
-  if ( streamname0[0] == '-' ) return 1;
+  if (streamname0[0] == '-')
+    return 1;
 
 #if defined(HAVE_WORDEXP_H)
   argument_t *glob_arg = glob_pattern(streamname0);
@@ -571,31 +598,33 @@ int expand_wildcards(int processID, int streamCnt)
   // 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 (glob_arg->argc > 1 && glob_arg->argv[0][0] != '-')
     {
-      if ( cdoVerbose ) cdoPrint("Replaced >%s< by", Process[processID].streamNames[0].args);
+      if (cdoVerbose)
+        cdoPrint("Replaced >%s< by", process.streamNames[0].args);
 
       streamCnt = streamCnt - 1 + glob_arg->argc;
 
-      Free(Process[processID].streamNames[0].argv);
-      Free(Process[processID].streamNames[0].args);
+      Free(process.streamNames[0].args);
 
-      Process[processID].streamNames.resize(streamCnt);
+      process.streamNames.resize(streamCnt);
 
       // move output streams to the end
-      for ( int i = 1; i < Process[processID].streamCnt; ++i )
-        Process[processID].streamNames[i+glob_arg->argc-1] = Process[processID].streamNames[i];
+      for (int i = 1; i < process.streamCnt; ++i)
+        process.streamNames[i + glob_arg->argc - 1] = process.streamNames[i];
 
-      for ( int i = 0; i < glob_arg->argc; ++i )
+      for (int 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]);
-          if ( cdoVerbose ) cdoPrint("         >%s<", glob_arg->argv[i]);
+          argument_t &current_argument = process.streamNames[i];
+          current_argument.argc = 1;
+          current_argument.argv.resize(current_argument.argc);
+          current_argument.argv[0] = strdupx(glob_arg->argv[i]);
+          current_argument.args = strdupx(glob_arg->argv[i]);
+          if (cdoVerbose)
+            cdoPrint("         >%s<", glob_arg->argv[i]);
         }
 
-      Process[processID].streamCnt = streamCnt;
+      process.streamCnt = streamCnt;
     }
 
   Free(glob_arg);
@@ -604,11 +633,10 @@ int expand_wildcards(int processID, int streamCnt)
   return 1;
 }
 
-
-static
-int checkStreamCnt(void)
+static int
+checkStreamCnt(void)
 {
-  int processID = processSelf();
+  process_t &process = processSelf();
   int streamInCnt, streamOutCnt;
   int streamInCnt0;
   int streamCnt = 0;
@@ -616,162 +644,164 @@ int checkStreamCnt(void)
   int obase = FALSE;
   int status = 0;
 
-  streamInCnt  = operatorStreamInCnt(Process[processID].operatorName);
-  streamOutCnt = operatorStreamOutCnt(Process[processID].operatorName);
+  streamInCnt = operatorStreamInCnt(process.operatorName);
+  streamOutCnt = operatorStreamOutCnt(process.operatorName);
 
   streamInCnt0 = streamInCnt;
 
-  if ( streamOutCnt == -1 )
+  if (streamOutCnt == -1)
     {
       streamOutCnt = 1;
       obase = TRUE;
     }
 
-  if ( streamInCnt == -1 && streamOutCnt == -1 )
+  if (streamInCnt == -1 && streamOutCnt == -1)
     cdoAbort("I/O stream counts unlimited no allowed!");
-    
+
   // printf(" streamInCnt, streamOutCnt %d %d\n", streamInCnt, streamOutCnt);
-  if ( streamInCnt == -1 )
+  if (streamInCnt == -1)
     {
-      streamInCnt = Process[processID].streamCnt - streamOutCnt;
-      if ( streamInCnt < 1 ) cdoAbort("Input streams missing!");
+      streamInCnt = process.streamCnt - streamOutCnt;
+      if (streamInCnt < 1)
+        cdoAbort("Input streams missing!");
     }
 
-  if ( streamOutCnt == -1 )
+  if (streamOutCnt == -1)
     {
-      streamOutCnt = Process[processID].streamCnt - streamInCnt;
-      if ( streamOutCnt < 1 ) cdoAbort("Output streams missing!");
+      streamOutCnt = process.streamCnt - streamInCnt;
+      if (streamOutCnt < 1)
+        cdoAbort("Output streams missing!");
     }
   // printf(" streamInCnt, streamOutCnt %d %d\n", streamInCnt, streamOutCnt);
 
   streamCnt = streamInCnt + streamOutCnt;
-  // printf(" streamCnt %d %d\n", Process[processID].streamCnt, streamCnt);
+  // printf(" streamCnt %d %d\n", process.streamCnt, streamCnt);
 
-  if ( Process[processID].streamCnt > streamCnt )
+  if (process.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 )
+  if (process.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++ )
+  for (i = streamInCnt; i < streamCnt; i++)
     {
-      if ( Process[processID].streamNames[i].args[0] == '-' )
+      if (process.streamNames[i].args[0] == '-')
         {
-          cdoAbort("Output file name %s must not begin with \"-\"!",
-                   Process[processID].streamNames[i].args);
+          cdoAbort("Output file name %s must not begin with \"-\"!", process.streamNames[i].args);
         }
-      else if ( !obase )
+      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 )
+          for (j = 0; j < streamInCnt; j++) /* does not work with files in pipes */
+            if (strcmp(process.streamNames[i].args, process.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);
+                       " on position %d!\n",
+                       process.streamNames[i].args,
+                       j + 1);
         }
     }
 
-  if ( streamInCnt == 1 && streamInCnt0 == -1 )
-    status = expand_wildcards(processID, streamCnt);
+  if (streamInCnt == 1 && streamInCnt0 == -1)
+    status = expand_wildcards(process, streamCnt);
 
   return status;
 }
 
-static
-void setStreams(int argc, char *argv[])
+static void
+setStreams(int argc, std::vector<char *> &argv)
 {
-  int processID = processSelf();
+  process_t &process = processSelf();
   int streamCnt = getStreamCnt(argc, argv);
 
-  Process[processID].nvals = 0;
-  Process[processID].nvars = 0;
-  Process[processID].ntimesteps = 0;
+  process.nvals = 0;
+  process.nvars = 0;
+  process.ntimesteps = 0;
 
-  Process[processID].streamCnt  = 0; /* filled in setStreamNames */
-  if ( streamCnt )
-    Process[processID].streamNames = std::vector<argument_t>(streamCnt);
-  for ( int i = 0; i < streamCnt; i++ )
+  process.streamCnt = 0; /* filled in setStreamNames */
+  if (streamCnt)
+    process.streamNames = std::vector<argument_t>(streamCnt);
+  for (int i = 0; i < streamCnt; i++)
     {
-      Process[processID].streamNames[i].argc = 0;
-      Process[processID].streamNames[i].argv = NULL;
-      Process[processID].streamNames[i].args = NULL;
+      process.streamNames[i].argc = 0;
+      process.streamNames[i].args = NULL;
     }
 
   setStreamNames(argc, argv);
 
   int status = checkStreamCnt();
 
-  if ( status == 0 && Process[processID].streamCnt != streamCnt )
-    Error("Internal problem with stream count %d %d", Process[processID].streamCnt, streamCnt);
+  if (status == 0 && process.streamCnt != streamCnt)
+    Error("Internal problem with stream count %d %d", process.streamCnt, streamCnt);
   /*
   for ( i = 0; i < streamCnt; i++ )
-    fprintf(stderr, "setStreams: stream %d %s\n", i+1, Process[processID].streamNames[i].args);
+    fprintf(stderr, "setStreams: stream %d %s\n", i+1, process.streamNames[i].args);
   */
 }
 
-
-void processDefArgument(void *vargument)
+void
+processDefArgument(void *vargument)
 {
-  int processID = processSelf();
+  process_t &process = processSelf();
   char *operatorArg;
   char *commapos;
-  int oargc = 0;
-  char **oargv = Process[processID].oargv;
+  std::vector<char*> &oargv = process.oargv;
   int argc = ((argument_t *) vargument)->argc;
-  char **argv = ((argument_t *) vargument)->argv;
+  std::vector<char *> &argv = ((argument_t *) vargument)->argv;
 
-  Process[processID].xoperator    = argv[0];
-  Process[processID].operatorName = getOperatorName(Process[processID].xoperator);
-  Process[processID].operatorArg  = getOperatorArg(Process[processID].xoperator);
-  operatorArg = Process[processID].operatorArg;
+  process.xoperator = argv[0];
+  process.operatorName = getOperatorName(process.xoperator);
+  process.operatorArg = getOperatorArg(process.xoperator);
+  operatorArg = process.operatorArg;
 
-  if ( operatorArg )
+  if (operatorArg)
     {
-      oargv[oargc++] = operatorArg;
-      //fprintf(stderr, "processDefArgument: %d %s\n", oargc, operatorArg);
+      oargv.push_back(operatorArg);
+      // fprintf(stderr, "processDefArgument: %d %s\n", oargc, operatorArg);
 
       commapos = operatorArg;
-      while ( (commapos = strchr(commapos, ',')) != NULL )
+      while ((commapos = strchr(commapos, ',')) != NULL)
         {
-          *commapos++ = '\0';
-          if ( strlen(commapos) )
+          *commapos = '\0';
+          *commapos++;
+          if (strlen(commapos))
             {
-              if ( oargc >= MAX_OARGC )
-                cdoAbort("Too many parameter (limit=%d)!", MAX_OARGC);
-
-              oargv[oargc++] = commapos;
+              oargv.push_back(commapos);
             }
         }
-      Process[processID].oargc = oargc;
+      process.oargc = oargv.size();
     }
 
-  processDefPrompt(Process[processID].operatorName);
+  processDefPrompt(process.operatorName);
+
+  process.module = getModule(process.operatorName);
 
   setStreams(argc, argv);
 }
 
-
-void processDefVarNum(int nvars)
+void
+processDefVarNum(int nvars)
 {
-  int processID = processSelf();
-
-  /*  if ( streamID == Process[processID].streams[0] ) */
-    Process[processID].nvars += nvars;
+  process_t &process = processSelf();
+  /*  if ( streamID == process.streams[0] ) */
+  process.nvars += nvars;
 }
 
-
-int processInqVarNum(void)
+int
+processInqVarNum(void)
 {
-  int processID = processSelf();
-
-  return Process[processID].nvars;
+  return processSelf().nvars;
 }
 
-
-void processDefTimesteps(int streamID)
+void
+processDefTimesteps(int streamID)
 {
-  int processID = processSelf();
-  
+  process_t &process = processSelf();
+
   UNUSED(streamID);
   /*
   int i;
@@ -781,78 +811,71 @@ void processDefTimesteps(int streamID)
     printf("streamID %d %d %d %d << \n", processID, Process[processID].nstream, i, Process[processID].streams[i]);
   */
   /*  if ( streamID == Process[processID].streams[0] )*/
-    Process[processID].ntimesteps++;
+  process.ntimesteps++;
 }
 
-
-int processInqTimesteps(void)
+int
+processInqTimesteps(void)
 {
-  int processID = processSelf();
-
-  return Process[processID].ntimesteps;
+  return processSelf().ntimesteps;
 }
 
-
-void processDelete(void)
+void
+processDelete(void)
 {
-  int processID = processSelf();
+  process_t &process = processSelf();
 
-  //fprintf(stderr, "delete processID %d\n", processID);
+// fprintf(stderr, "delete processID %d\n", processID);
 #if defined(HAVE_LIBPTHREAD)
   pthread_mutex_lock(&processMutex);
 
-  Process[processID].l_threadID = 0;
+  process.l_threadID = 0;
 #endif
   NumProcessActive--;
 
 #if defined(HAVE_LIBPTHREAD)
-  pthread_mutex_unlock(&processMutex);  
+  pthread_mutex_unlock(&processMutex);
 #endif
 }
 
-
-int operatorArgc(void)
+int
+operatorArgc(void)
 {
-  int processID = processSelf();
-
-  return Process[processID].oargc;
+  return processSelf().oargc;
 }
 
-
-char **operatorArgv(void)
+char **
+operatorArgv(void)
 {
-  int processID = processSelf();
-
-  return Process[processID].oargv;
+  return &processSelf().oargv[0];
 }
 
-
-void operatorCheckArgc(int numargs)
+void
+operatorCheckArgc(int numargs)
 {
-  int processID = processSelf();
-  int argc = Process[processID].oargc;
+  int argc = processSelf().oargc;
 
-  if ( argc < numargs )
+  if (argc < numargs)
     cdoAbort("Too few arguments! Need %d found %d.", numargs, argc);
-  else if ( argc > numargs )
+  else if (argc > numargs)
     cdoAbort("Too many arguments! Need %d found %d.", numargs, argc);
 }
 
-
-void operatorInputArg(const char *enter)
+void
+operatorInputArg(const char *enter)
 {
-  int processID = processSelf();
+  process_t &process = processSelf();
 
-  int oargc = Process[processID].oargc;
+  int oargc = process.oargc;
 
-  if ( oargc == 0 )
+  if (oargc == 0)
     {
       char line[1024];
       char *pline = line;
       size_t pos, len, linelen;
       int lreadline = 1;
 
-      if ( enter )
+      if (enter)
         {
           set_text_color(stderr, BRIGHT, MAGENTA);
           fprintf(stderr, "%-16s : ", processInqPrompt());
@@ -862,31 +885,32 @@ void operatorInputArg(const char *enter)
           // reset_text_color(stderr);
         }
 
-      while ( lreadline )
+      while (lreadline)
         {
           readline(stdin, pline, 1024);
 
           lreadline = 0;
-          while ( 1 )
+          while (1)
             {
               pos = 0;
-              while ( pline[pos] == ' ' || pline[pos] == ',' ) pos++;
+              while (pline[pos] == ' ' || pline[pos] == ',')
+                pos++;
               pline += pos;
               linelen = strlen(pline);
-              if ( linelen > 0 )
+              if (linelen > 0)
                 {
-                  if ( pline[0] == '\\' )
+                  if (pline[0] == '\\')
                     {
                       lreadline = 1;
                       break;
                     }
                   len = 0;
-                  while ( pline[len] != ' '  && pline[len] != ',' &&
-                          pline[len] != '\\' && len < linelen ) len++;
+                  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';
+                  process.oargv[oargc] = (char *) Malloc(len + 1);
+                  memcpy(process.oargv[oargc], pline, len);
+                  process.oargv[oargc][len] = '\0';
                   oargc++;
 
                   pline += len;
@@ -896,43 +920,44 @@ void operatorInputArg(const char *enter)
             }
         }
 
-      Process[processID].oargc = oargc;
+      process.oargc = oargc;
     }
 }
 
-
-int cdoOperatorAdd(const char *name, int f1, int f2, const char *enter)
+int
+cdoOperatorAdd(const char *name, int f1, int f2, const char *enter)
 {
-  int processID = processSelf();
-  int operID = Process[processID].noper;
+  process_t &process = processSelf();
+  int operID = process.noper;
 
-  if ( operID >= MAX_OPERATOR )
+  if (operID >= MAX_OPERATOR)
     cdoAbort("Maximum number of %d operators reached!", MAX_OPERATOR);
 
-  Process[processID].oper[operID].f1     = f1;
-  Process[processID].oper[operID].f2     = f2;
-  Process[processID].oper[operID].name   = name;
-  Process[processID].oper[operID].enter  = enter;
+  process.oper[operID].f1 = f1;
+  process.oper[operID].f2 = f2;
+  process.oper[operID].name = name;
+  process.oper[operID].enter = enter;
 
-  Process[processID].noper++;
+  process.noper++;
 
   return operID;
 }
 
-
-int cdoOperatorID(void)
+int
+cdoOperatorID(void)
 {
-  int processID = processSelf();
+  process_t &process = processSelf();
   int operID = -1;
 
-  if ( Process[processID].noper > 0 )
+  if (process.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 ( operID == Process[processID].noper )
+      for (operID = 0; operID < process.noper; operID++)
+        {
+          if (process.oper[operID].name)
+            if (strcmp(process.operatorName, process.oper[operID].name) == 0)
+              break;
+        }
+      if (operID == process.noper)
         cdoAbort("Operator not callable by this name!");
     }
   else
@@ -943,75 +968,273 @@ int cdoOperatorID(void)
   return operID;
 }
 
-
-int cdoOperatorF1(int operID)
+int
+cdoOperatorF1(int operID)
 {
-  int processID = processSelf();
-
-  return Process[processID].oper[operID].f1;
+  return processSelf().oper[operID].f1;
 }
 
+int
+cdoOperatorF2(int operID)
+{
+  return processSelf().oper[operID].f2;
+}
 
-int cdoOperatorF2(int operID)
+const char *
+cdoOperatorName(int operID)
 {
-  int processID = processSelf();
+  return processSelf().oper[operID].name;
+}
 
-  return Process[processID].oper[operID].f2;
+const char *
+cdoOperatorEnter(int operID)
+{
+  return processSelf().oper[operID].enter;
 }
 
+int
+cdoStreamNumber()
+{
+  return operatorStreamNumber(processSelf().operatorName);
+}
 
-const char *cdoOperatorName(int operID)
+void
+process_t::print_process()
 {
-  int processID = processSelf();
+#if defined(HAVE_LIBPTHREAD)
+  std::cout << " processID       : " << m_ID << std::endl;
+  std::cout << " threadID        : " << threadID << std::endl;
+  std::cout << " l_threadID      : " << l_threadID << std::endl;
+#endif
+  std::cout << " nchild          : " << nchild << std::endl;
+  int nInStream = getInStreamCnt();
+  int nOutStream = getOutStreamCnt();
+  std::cout << " nInStream       : " << nInStream << std::endl;
+  std::cout << " nOutStream      : " << nOutStream << std::endl;
+  for (int i = 0; i < nInStream; i++)
+    {
+      std::cout << "    " << inputStreams[i]->self << std::endl;
+    }
+  for (int i = 0; i < nOutStream; i++)
+    {
+      std::cout << "    " << outputStreams[i]->self << std::endl;
+    }
+  if (s_utime)
+    {
+      std::cout << " s_utime         : " << s_utime << std::endl;
+    }
+  else
+    {
+      std::cout << " s_utime         : "
+                << "UNINITALIZED" << std::endl;
+    }
+  if (s_stime)
+    {
+      std::cout << " s_stime         : " << s_stime << std::endl;
+    }
+  else
+    {
+      std::cout << " s_stime         : "
+                << "UNINITALIZED" << std::endl;
+    }
 
-  return Process[processID].oper[operID].name;
-}
+  std::cout << " a_utime         : " << a_utime << std::endl;
+  std::cout << " a_stime         : " << a_stime << std::endl;
+  std::cout << " cputime         : " << cputime << std::endl;
 
+  if (nvals)
+    {
+      std::cout << " nvals           : " << nvals << std::endl;
+    }
+  else
+    {
 
-const char *cdoOperatorEnter(int operID)
-{
-  int processID = processSelf();
+      std::cout << " nvals           : "
+                << "UNINITALIZED" << std::endl;
+    }
+  if (nvars)
+    {
+      std::cout << " nvars           : " << nvars << std::endl;
+    }
+  else
+    {
 
-  return Process[processID].oper[operID].enter;
-}
+      std::cout << " nvars           : "
+                << "UNINITALIZED" << std::endl;
+    }
+  if (ntimesteps)
+    {
+      std::cout << " ntimesteps      : " << ntimesteps << std::endl;
+    }
+  else
+    {
 
+      std::cout << " ntimesteps      : "
+                << "UNINITALIZED" << std::endl;
+    }
+  std::cout << " ntimesteps      : " << ntimesteps << std::endl;
+  std::cout << " streamCnt       : " << streamCnt << std::endl;
+  // std::cout << " streamNames     : " << streamNames                  <<  std::endl;
+  std::cout << " xoperator       : " << xoperator << std::endl;
+  std::cout << " operatorName    : " << operatorName << std::endl;
+  std::cout << " operatorArg     : " << operatorArg << std::endl;
+  std::cout << " oargc           : " << oargc << std::endl;
+  std::cout << " noper           : " << noper << std::endl;
+}
 
-int cdoStreamNumber()
+static void
+processClosePipes(void)
 {
-  int processID = processSelf();
+  int nstream = processInqInputStreamNum();
+  for (int sindex = 0; sindex < nstream; sindex++)
+    {
+      pstream_t *pstreamptr = processInqInputStream(sindex);
+
+      if (PROCESS_DEBUG)
+        Message("process %d  stream %d  close streamID %d", processSelf().m_ID, sindex, pstreamptr->self);
+
+      if (pstreamptr)
+        pstreamptr->close();
+    }
+
+  nstream = processInqOutputStreamNum();
+  for (int sindex = 0; sindex < nstream; sindex++)
+    {
+      pstream_t *pstreamptr = processInqOutputStream(sindex);
 
-  return operatorStreamNumber(Process[processID].operatorName);
+      if (PROCESS_DEBUG)
+        Message("process %d  stream %d  close streamID %d", processSelf().m_ID, sindex, pstreamptr->self);
+
+      if (pstreamptr)
+          pstreamptr->close();
+    }
 }
 
-void print_process(int p_process_id)
+
+void
+cdoFinish(void)
 {
+  int processID = processSelf().m_ID;
+  int nvars, ntimesteps;
+  char memstring[32] = { "" };
+  double s_utime, s_stime;
+  double e_utime, e_stime;
+  double c_cputime = 0, c_usertime = 0, c_systime = 0;
+  double p_cputime = 0, p_usertime = 0, p_systime = 0;
+
+#if defined(HAVE_LIBPTHREAD)
+  if (PROCESS_DEBUG)
+    Message("process %d  thread %ld", processID, pthread_self());
+#endif
+
+  int64_t nvals = processInqNvals(processID);
+  nvars = processInqVarNum();
+  ntimesteps = processInqTimesteps();
+
+  if (!cdoSilentMode)
+    {
+      set_text_color(stderr, RESET, GREEN);
+      fprintf(stderr, "%s: ", processInqPrompt());
+      reset_text_color(stderr);
+      if (nvals > 0)
+        {
+          if (sizeof(int64_t) > sizeof(long))
+#if defined(_WIN32)
+            fprintf(stderr,
+                    "Processed %I64d value%s from %d variable%s",
+#else
+            fprintf(stderr,
+                    "Processed %jd value%s from %d variable%s",
+#endif
+                    (intmax_t) nvals,
+                    ADD_PLURAL(nvals),
+                    nvars,
+                    ADD_PLURAL(nvars));
+          else
+            fprintf(stderr,
+                    "Processed %ld value%s from %d variable%s",
+                    (long) nvals,
+                    ADD_PLURAL(nvals),
+                    nvars,
+                    ADD_PLURAL(nvars));
+        }
+      else if (nvars > 0)
+        {
+          fprintf(stderr, "Processed %d variable%s", nvars, ADD_PLURAL(nvars));
+        }
+
+      if (ntimesteps > 0)
+        fprintf(stderr, " over %d timestep%s", ntimesteps, ADD_PLURAL(ntimesteps));
+
+      //  fprintf(stderr, ".");
+    }
+  /*
+    fprintf(stderr, "%s: Processed %d variable%s %d timestep%s.",
+            processInqPrompt(), nvars, nvars > 1 ? "s" : "",
+            ntimesteps, ntimesteps > 1 ? "s" : "");
+  */
+  processStartTime(&s_utime, &s_stime);
+  cdoProcessTime(&e_utime, &e_stime);
+
+  c_usertime = e_utime - s_utime;
+  c_systime = e_stime - s_stime;
+  c_cputime = c_usertime + c_systime;
+
 #if defined(HAVE_LIBPTHREAD)
-  std::cout << " threadID        : " << Process[p_process_id].threadID                     <<  std::endl;
-  std::cout << " l_threadID      : " << Process[p_process_id].l_threadID                   <<  std::endl;
+  if (getPthreadScope() == PTHREAD_SCOPE_PROCESS)
+    {
+      c_usertime /= processNums();
+      c_systime /= processNums();
+      c_cputime /= processNums();
+    }
 #endif
-  std::cout << " nchild          : " << Process[p_process_id].nchild                       <<  std::endl;
-  std::cout << " nInStream       : " << Process[p_process_id].nInStream                    <<  std::endl;
-  std::cout << " nOutStream      : " << Process[p_process_id].nOutStream                   <<  std::endl;
-  for(int i = 0; i < Process[p_process_id].nInStream; i++){
-    std::cout << "    " << Process[p_process_id].inputStreams[i]  <<  std::endl;
-  }
-  for(int i = 0; i < Process[p_process_id].nOutStream; i++){
-    std::cout << "    " << Process[p_process_id].outputStreams[i] <<  std::endl;
-  }
-  std::cout << " s_utime         : " << Process[p_process_id].s_utime                      <<  std::endl;
-  std::cout << " s_stime         : " << Process[p_process_id].s_stime                      <<  std::endl;
-  std::cout << " a_utime         : " << Process[p_process_id].a_utime                      <<  std::endl;
-  std::cout << " a_stime         : " << Process[p_process_id].a_stime                      <<  std::endl;
-  std::cout << " cputime         : " << Process[p_process_id].cputime                      <<  std::endl;
-
-  std::cout << " nvals           : " << Process[p_process_id].nvals                        <<  std::endl;
-  std::cout << " nvars           : " << Process[p_process_id].nvars                        <<  std::endl;
-  std::cout << " ntimesteps      : " << Process[p_process_id].ntimesteps                   <<  std::endl;
-  std::cout << " streamCnt       : " << Process[p_process_id].streamCnt                    <<  std::endl;
- // std::cout << " streamNames     : " << Process[p_process_id].streamNames                  <<  std::endl;
-  std::cout << " xoperator       : " << Process[p_process_id].xoperator                    <<  std::endl;
-  std::cout << " operatorName    : " << Process[p_process_id].operatorName                 <<  std::endl;
-  std::cout << " operatorArg     : " << Process[p_process_id].operatorArg                  <<  std::endl;
-  std::cout << " oargc           : " << Process[p_process_id].oargc                        <<  std::endl;
-  std::cout << " noper           : " << Process[p_process_id].noper                        <<  std::endl;
+
+  processDefCputime(processID, c_cputime);
+
+  processAccuTime(c_usertime, c_systime);
+
+  if (processID == 0)
+    {
+      int mu[] = { 'b', 'k', 'm', 'g', 't' };
+      int muindex = 0;
+      long memmax;
+
+      memmax = memTotal();
+      while (memmax > 9999)
+        {
+          memmax /= 1024;
+          muindex++;
+        }
+
+      if (memmax)
+        snprintf(memstring, sizeof(memstring), " %ld%c ", memmax, mu[muindex]);
+
+      processEndTime(&p_usertime, &p_systime);
+      p_cputime = p_usertime + p_systime;
+
+      if (cdoLogOff == 0)
+        {
+          cdologs(processNums());
+          cdologo(processNums());
+          cdolog(processInqPrompt(), p_cputime);
+        }
+    }
+
+#if defined(HAVE_SYS_TIMES_H)
+  if (cdoBenchmark)
+    fprintf(stderr, " ( %.2fs %.2fs %.2fs %s)\n", c_usertime, c_systime, c_cputime, memstring);
+  else
+    {
+      if (!cdoSilentMode)
+        fprintf(stderr, " ( %.2fs )\n", c_cputime);
+    }
+  if (cdoBenchmark && processID == 0)
+    fprintf(stderr, "total: user %.2fs  sys %.2fs  cpu %.2fs  mem%s\n", p_usertime, p_systime, p_cputime, memstring);
+#else
+  fprintf(stderr, "\n");
+#endif
+
+  processClosePipes();
+
+  processDelete();
 }
diff --git a/src/process.h b/src/process.h
index 3df48fb..509ae2f 100644
--- a/src/process.h
+++ b/src/process.h
@@ -22,6 +22,10 @@
 #include <vector>
 #include "util.h"
 #include "pstream.h"
+#include "modules.h"
+
+#include <vector>
+#include <iostream>
 
 constexpr int MAX_PROCESS  =   128;
 constexpr int MAX_STREAM   =    64;
@@ -38,16 +42,16 @@ typedef struct {
 }
 oper_t;
 
-typedef struct {
+class process_t {
+    public:
+   int m_ID;
 #if defined(HAVE_LIBPTHREAD)
   pthread_t   threadID;
   int         l_threadID;
 #endif
   short       nchild;
-  short       nInStream;
-  short       nOutStream;
-  short       inputStreams[MAX_STREAM];
-  short       outputStreams[MAX_STREAM];
+  std::vector<pstream_t*>       inputStreams;
+  std::vector<pstream_t*>       outputStreams;
   double      s_utime;
   double      s_stime;
   double      a_utime;
@@ -63,25 +67,35 @@ typedef struct {
   const char *operatorName;
   char       *operatorArg;
   int         oargc;
-  char       *oargv[MAX_OARGC];
+  std::vector<char *> oargv;
   char        prompt[64];
   short       noper;
   oper_t      oper[MAX_OPERATOR];
-}
-process_t;
 
-
-
-int  processSelf(void);
+  modules_t module;
+
+  int getInStreamCnt();
+  int getOutStreamCnt();
+  void initProcess();
+  void print_process();
+  process_t(int ID);
+ private: 
+  process_t();
+  void OpenRead(int p_input_idx);
+  void OpenWrite(int p_input_idx);
+  void OpenAppend(int p_input_idx);
+};
+
+  pstream_t*  processInqInputStream(int streamindex);
+  pstream_t*  processInqOutputStream(int streamindex);
+  process_t&  processSelf(void);
 int  processCreate(void);
 void processDelete(void);
 int  processInqTimesteps(void);
 void processDefTimesteps(int streamID);
 int  processInqVarNum(void);
-int  processInqInputStreamNum(void);
-int  processInqOutputStreamNum(void);
-int  processInqInputStreamID(int streamindex);
-int  processInqOutputStreamID(int streamindex);
+int processInqInputStreamNum(void);
+int processInqOutputStreamNum(void);
 void processAddInputStream(pstream_t *p_pstream_ptr);
 void processAddOutputStream(pstream_t *p_pstream_ptr);
 void processDelStream(int streamID);
@@ -106,7 +120,6 @@ const char *processInqOpername(void);
 const char *processInqOpername2(int processID);
 const char *processInqPrompt(void);
 
-void print_process(int p_process_id);
-
 const argument_t *cdoStreamName(int cnt);
+
 #endif  /* _PROCESS_H */
diff --git a/src/pstream.cc b/src/pstream.cc
index deeb3a9..f297795 100644
--- a/src/pstream.cc
+++ b/src/pstream.cc
@@ -15,6 +15,8 @@
   GNU General Public License for more details.
 */
 
+
+#include <thread>
 #if defined(HAVE_CONFIG_H)
 #include "config.h"
 #endif
@@ -38,21 +40,20 @@ int pclose(FILE *stream);
 #include "modules.h"
 #include "pstream.h"
 #include "pstream_int.h"
-#include "cdo_int.h"
 #include "util.h"
 #include "pipe.h"
 #include "error.h"
-#include "dmemory.h"
 
 static int PSTREAM_Debug = 0;
 
-#define MAX_PSTREAMS 4096
+//#define MAX_PSTREAMS 4096
 
-static int _pstream_max = MAX_PSTREAMS;
+//static int _pstream_max = MAX_PSTREAMS;
 
-static void pstream_initialize(void);
 
-static bool _pstream_init = false;
+//static void pstream_initialize(void);
+
+//static bool _pstream_init = false;
 
 #if defined(HAVE_LIBPTHREAD)
 #include <pthread.h>
@@ -65,15 +66,20 @@ static pthread_mutex_t streamOpenReadMutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t streamOpenWriteMutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t streamMutex = PTHREAD_MUTEX_INITIALIZER;
 
-static pthread_once_t _pstream_init_thread = PTHREAD_ONCE_INIT;
-static pthread_mutex_t _pstream_mutex;
+//static pthread_once_t _pstream_init_thread = PTHREAD_ONCE_INIT;
+//static pthread_mutex_t _pstream_mutex;
 
+static std::mutex _pstream_map_mutex;
+#define PSTREAM_LOCK() _pstream_map_mutex.lock();
+#define PSTREAM_UNLOCK() _pstream_map_mutex.unlock();
+/*
 #define PSTREAM_LOCK() pthread_mutex_lock(&_pstream_mutex)
 #define PSTREAM_UNLOCK() pthread_mutex_unlock(&_pstream_mutex)
 #define PSTREAM_INIT() \
   if (!_pstream_init)  \
   pthread_once(&_pstream_init_thread, pstream_initialize)
 
+*/
 #else
 
 #define PSTREAM_LOCK()
@@ -84,16 +90,21 @@ static pthread_mutex_t _pstream_mutex;
 
 #endif
 
+/*
 typedef struct _pstreamPtrToIdx
 {
   int idx;
   pstream_t *ptr;
   struct _pstreamPtrToIdx *next;
 } pstreamPtrToIdx;
-
+*/
+/*
 static pstreamPtrToIdx *_pstreamList = NULL;
 static pstreamPtrToIdx *_pstreamAvail = NULL;
-
+*/
+static std::map<int,pstream_t> _pstream_map;
+static int next_pstream_id = 1;
+/*
 static void
 pstream_list_new(void)
 {
@@ -101,7 +112,6 @@ pstream_list_new(void)
 
   _pstreamList = (pstreamPtrToIdx *) Malloc(_pstream_max * sizeof(pstreamPtrToIdx));
 }
-
 static void
 pstream_list_delete(void)
 {
@@ -123,7 +133,33 @@ pstream_init_pointer(void)
 
   _pstreamAvail = _pstreamList;
 }
+*/
+
+static pstream_t *create_pstream()
+{
+    PSTREAM_LOCK();
+    auto new_entry  = _pstream_map.insert(
+            std::make_pair(next_pstream_id, pstream_t(next_pstream_id))
+            );
+    next_pstream_id++;
+    PSTREAM_UNLOCK();
+
+    return &new_entry.first->second;
+}
+
+static pstream_t * pstream_to_pointer(int idx)
+{
+    PSTREAM_LOCK();
+    auto pstream_iterator = _pstream_map.find(idx);
+    PSTREAM_UNLOCK();
+    if(pstream_iterator == _pstream_map.end())
+    {
+        Error("pstream index %d undefined!", idx);
+    }
 
+    return &pstream_iterator->second;
+}
+/*
 static pstream_t *
 pstream_to_pointer(int idx)
 {
@@ -132,7 +168,7 @@ pstream_to_pointer(int idx)
   PSTREAM_INIT();
 
   if (idx >= 0 && idx < _pstream_max)
-    {
+    //{
       PSTREAM_LOCK();
 
       pstreamptr = _pstreamList[idx].ptr;
@@ -144,8 +180,9 @@ pstream_to_pointer(int idx)
 
   return pstreamptr;
 }
-
+*/
 /* Create an index from a pointer */
+/*
 static int
 pstream_from_pointer(pstream_t *ptr)
 {
@@ -176,34 +213,33 @@ pstream_from_pointer(pstream_t *ptr)
 
   return idx;
 }
+*/
 
-static void
-pstream_init_entry(pstream_t *pstreamptr)
+void pstream_t::init()
 {
-  pstreamptr->self = pstream_from_pointer(pstreamptr);
-
-  pstreamptr->isopen = true;
-  pstreamptr->ispipe = false;
-  pstreamptr->m_fileID = -1;
-  pstreamptr->m_vlistID = -1;
-  pstreamptr->tsID = -1;
-  pstreamptr->m_filetype = -1;
-  pstreamptr->name = NULL;
-  pstreamptr->tsID0 = 0;
-  pstreamptr->mfiles = 0;
-  pstreamptr->nfiles = 0;
-  pstreamptr->varID = -1;
-  pstreamptr->name = NULL;
-  pstreamptr->mfnames = NULL;
-  pstreamptr->m_varlist = NULL;
+  isopen = true;
+  ispipe = false;
+  m_fileID = -1;
+  m_vlistID = -1;
+  tsID = -1;
+  m_filetype = -1;
+  m_name = "";
+  tsID0 = 0;
+  mfiles = 0;
+  nfiles = 0;
+  varID = -1;
+  m_varlist = NULL;
 #if defined(HAVE_LIBPTHREAD)
-  pstreamptr->argument = NULL;
-  pstreamptr->pipe = NULL;
+  argument = NULL;
+  pipe = NULL;
 //  pstreamptr->rthreadID  = 0;
 //  pstreamptr->wthreadID  = 0;
 #endif
 }
-pstream_t::pstream_t() { pstream_init_entry(this); }
+pstream_t::pstream_t(int p_id) : self(p_id) { init(); }
+pstream_t::~pstream_t(){
+  //vlistDestroy(m_vlistID);
+}
 
 static void
 pstream_delete_entry(pstream_t *pstreamptr)
@@ -212,23 +248,19 @@ pstream_delete_entry(pstream_t *pstreamptr)
 
   PSTREAM_LOCK();
 
-  delete (pstreamptr);
-
-  _pstreamList[idx].next = _pstreamAvail;
-  _pstreamList[idx].ptr = 0;
-  _pstreamAvail = &_pstreamList[idx];
+  _pstream_map.erase(idx);
 
   PSTREAM_UNLOCK();
 
   if (PSTREAM_Debug)
     Message("Removed idx %d from pstream list", idx);
 }
-
+/*
 static void
 pstream_initialize(void)
 {
 #if defined(HAVE_LIBPTHREAD)
-  /* initialize global API mutex lock */
+  // initialize global API mutex lock 
   pthread_mutex_init(&_pstream_mutex, NULL);
 #endif
 
@@ -250,7 +282,23 @@ pstream_initialize(void)
 
   _pstream_init = true;
 }
-
+*/
+static int pstreamFindID(const char *p_name)
+{
+    std::string cur_name;
+    for(auto map_pair :  _pstream_map)
+    {
+        cur_name = map_pair.second.m_name;
+        if(!(cur_name.empty())){
+            if(cur_name.compare(p_name) == 0)
+            {
+                return map_pair.first;
+            }
+        }
+    }
+    return -1;
+}
+/*
 static int
 pstreamFindID(const char *name)
 {
@@ -262,8 +310,8 @@ pstreamFindID(const char *name)
       pstreamptr = pstream_to_pointer(pstreamID);
 
       if (pstreamptr)
-        if (pstreamptr->name)
-          if (strcmp(pstreamptr->name, name) == 0)
+        if (pstreamptr->m_name)
+          if (strcmp(pstreamptr->m_name, m_name) == 0)
             break;
     }
 
@@ -272,19 +320,13 @@ pstreamFindID(const char *name)
 
   return pstreamID;
 }
+*/
 bool
 pstream_t::isPipe()
 {
   return ispipe;
 }
 
-static void
-createPipeName(char *pipename, int pnlen)
-{
-
-  snprintf(pipename, pnlen, "(pipe%d.%d)", processSelf() + 1, processInqChildNum() + 1);
-}
-
 pthread_t
 pCreateReadThread(argument_t *argument)
 {
@@ -329,53 +371,18 @@ pCreateReadThread(argument_t *argument)
 }
 
 void
-pstream_t::pstreamOpenReadPipe(const argument_t *argument)
+pstream_t::pstreamOpenReadPipe(const char *pipename)
 {
 #if defined(HAVE_LIBPTHREAD)
   // int pstreamID = pstreamptr->self;
 
-  size_t pnlen = 16;
-  char *pipename = (char *) Malloc(pnlen);
-  createPipeName(pipename, pnlen);
-  // struct sched_param param;
-
-  argument_t *newargument = new argument_t();
-  newargument->argc = argument->argc + 1;
-  newargument->argv = (char **) Malloc(newargument->argc * sizeof(char *));
-  newargument->operatorName = "";
-  memcpy(newargument->argv, argument->argv, argument->argc * sizeof(char *));
-
-  char *operatorArg = argument->argv[0];
-  const char *operatorName = getOperatorName(operatorArg);
-
-  size_t len = strlen(argument->args);
-  char *newarg = (char *) Malloc(len + pnlen);
-  strcpy(newarg, argument->args);
-  newarg[len] = ' ';
-  strcpy(&newarg[len + 1], pipename);
-
-  newargument->argv[argument->argc] = pipename;
-  newargument->args = newarg;
-  newargument->operatorName = std::string(operatorName, strlen(operatorName));
-  /*
-    printf("pstreamOpenRead: new args >%s<\n", newargument->args);
-    for ( int i = 0; i < newargument->argc; ++i )
-    printf("pstreamOpenRead: new arg %d >%s<\n", i, newargument->argv[i]);
-  */
   ispipe = true;
-  name = pipename;
+  m_name = pipename;
   rthreadID = pthread_self();
   pipe = new pipe_t();
   pipe->name = std::string(pipename);
-  argument = newargument;
 
-  if (!cdoSilentMode)
-    {
-      cdoPrint("Started child process \"%s\".", newarg + 1);
-    }
-  pCreateReadThread(newargument);
-  /* Free(operatorName); */
-  processAddInputStream(this);
+    /* Free(operatorName); */
   /*      pipeInqInfo(pstreamID); */
   if (PSTREAM_Debug)
     Message("pipe %s", pipename);
@@ -384,23 +391,22 @@ pstream_t::pstreamOpenReadPipe(const argument_t *argument)
 #endif
 }
 
-static void
-pstreamCreateFilelist(const argument_t *argument, pstream_t *pstreamptr)
+void pstream_t::createFilelist(const char * p_args)
 {
   size_t i;
-  size_t len = strlen(argument->args);
+  size_t len = strlen(p_args);
 
   for (i = 0; i < len; i++)
-    if (argument->args[i] == ':')
+    if (p_args[i] == ':')
       break;
 
   if (i < len)
     {
       int nfiles = 1, j;
 
-      const char *pch = &argument->args[i + 1];
+      const char *pch = &p_args[i + 1];
       len -= (i + 1);
-      if (len && (strncmp(argument->args, "filelist:", 9) == 0 || strncmp(argument->args, "flist:", 6) == 0))
+      if (len && (strncmp(p_args, "filelist:", 9) == 0 || strncmp(p_args, "flist:", 6) == 0))
         {
           for (i = 0; i < len; i++)
             if (pch[i] == ',')
@@ -438,9 +444,8 @@ pstreamCreateFilelist(const argument_t *argument, pstream_t *pstreamptr)
               if (nfiles == 0)
                 cdoAbort("No imput file found in %s", pch);
 
-              pstreamptr->mfiles = nfiles;
-              pstreamptr->mfnames = (char **) Malloc(nfiles * sizeof(char *));
-
+              mfiles = nfiles;
+              m_mfnames.resize(nfiles);
               rewind(fp);
 
               nfiles = 0;
@@ -449,7 +454,7 @@ pstreamCreateFilelist(const argument_t *argument, pstream_t *pstreamptr)
                   if (line[0] == '#' || line[0] == '\0' || line[0] == ' ')
                     continue;
 
-                  pstreamptr->mfnames[nfiles] = strdupx(line);
+                  m_mfnames[nfiles] = line;
                   nfiles++;
                 }
 
@@ -459,8 +464,8 @@ pstreamCreateFilelist(const argument_t *argument, pstream_t *pstreamptr)
             {
               char line[65536];
 
-              pstreamptr->mfiles = nfiles;
-              pstreamptr->mfnames = (char **) Malloc(nfiles * sizeof(char *));
+              mfiles = nfiles;
+              m_mfnames.resize(nfiles);
 
               strcpy(line, pch);
               for (i = 0; i < len; i++)
@@ -473,12 +478,12 @@ pstreamCreateFilelist(const argument_t *argument, pstream_t *pstreamptr)
               i = 0;
               for (j = 0; j < nfiles; j++)
                 {
-                  pstreamptr->mfnames[j] = strdupx(&line[i]);
+                  m_mfnames[j] = line[i];
                   i += strlen(&line[i]) + 1;
                 }
             }
         }
-      else if (len && strncmp(argument->args, "ls:", 3) == 0)
+      else if (len && strncmp(p_args, "ls:", 3) == 0)
         {
           char line[4096];
           char command[4096];
@@ -502,38 +507,34 @@ pstreamCreateFilelist(const argument_t *argument, pstream_t *pstreamptr)
 
           pclose(pfp);
 
-          pstreamptr->mfiles = nfiles;
-          pstreamptr->mfnames = (char **) Malloc(nfiles * sizeof(char *));
+          mfiles = nfiles;
+          m_mfnames.resize(nfiles);
 
           for (j = 0; j < nfiles; j++)
-            pstreamptr->mfnames[j] = fnames[j];
+            m_mfnames[j] = std::string(fnames[j]);
         }
     }
 }
 
 void
-pstream_t::pstreamOpenReadFile(const argument_t *argument)
+pstream_t::pstreamOpenReadFile(const char* p_args)
 {
-  pstreamCreateFilelist(argument, this);
+  createFilelist(p_args);
 
-  char *filename = NULL;
+  std::string filename; 
 
   if (mfiles)
     {
-      size_t len = strlen(mfnames[0]);
-      filename = (char *) Malloc(len + 1);
-      strcpy(filename, mfnames[0]);
+      filename = m_mfnames[0];
       nfiles = 1;
     }
   else
     {
-      size_t len = strlen(argument->args);
-      filename = (char *) Malloc(len + 1);
-      strcpy(filename, argument->args);
+     filename = std::string(p_args);
     }
 
   if (PSTREAM_Debug)
-    Message("file %s", filename);
+    Message("file %s", filename.c_str());
 
 #if defined(HAVE_LIBPTHREAD)
   if (cdoLockIO)
@@ -541,11 +542,11 @@ pstream_t::pstreamOpenReadFile(const argument_t *argument)
   else
     pthread_mutex_lock(&streamOpenReadMutex);
 #endif
-  int fileID = streamOpenRead(filename);
+  int fileID = streamOpenRead(filename.c_str());
   if (fileID < 0)
     {
       isopen = false;
-      cdiOpenError(fileID, "Open failed on >%s<", filename);
+      cdiOpenError(fileID, "Open failed on >%s<", filename.c_str());
     }
 
   if (cdoDefaultFileType == CDI_UNDEFID)
@@ -563,16 +564,21 @@ pstream_t::pstreamOpenReadFile(const argument_t *argument)
 #endif
 
   mode = 'r';
-  name = filename;
+  m_name = filename;
   m_fileID = fileID;
 }
 
+void createPipeName(char *pipename, int pnlen)
+{
+
+  snprintf(pipename, pnlen, "(pipe%d.%d)", processSelf().m_ID + 1, processInqChildNum() + 1);
+}
+
 int
 pstreamOpenRead(const argument_t *argument)
 {
-  PSTREAM_INIT();
 
-  pstream_t *pstreamptr = new pstream_t();
+  pstream_t *pstreamptr = create_pstream();
   if (!pstreamptr)
     Error("No memory");
 
@@ -586,11 +592,22 @@ pstreamOpenRead(const argument_t *argument)
   */
   if (ispipe)
     {
-      pstreamptr->pstreamOpenReadPipe(argument);
+      size_t pnlen = 16;
+      char *pipename = (char *) Malloc(pnlen);
+      createPipeName(pipename, pnlen);
+      argument_t * newargument = pipe_argument_new(argument, pipename, pnlen);
+      pstreamptr->pstreamOpenReadPipe(pipename);
+      pCreateReadThread(newargument);
+      if (!cdoSilentMode)
+      {
+        cdoPrint("Started child process \"%s\".", newargument->args + 1);
+      }
+
+      processAddInputStream(pstreamptr);
     }
   else
     {
-      pstreamptr->pstreamOpenReadFile(argument);
+      pstreamptr->pstreamOpenReadFile(argument->args);
     }
 
   if (pstreamID < 0)
@@ -723,7 +740,7 @@ pstreamOpenWriteFile(const argument_t *argument, int filetype)
 {
   char *filename = (char *) Malloc(strlen(argument->args) + 1);
 
-  pstream_t *pstreamptr = new pstream_t();
+  pstream_t *pstreamptr = create_pstream();
   if (!pstreamptr)
     Error("No memory");
 
@@ -782,7 +799,7 @@ pstreamOpenWriteFile(const argument_t *argument, int filetype)
   strcpy(filename, argument->args);
 
   pstreamptr->mode = 'w';
-  pstreamptr->name = filename;
+  pstreamptr->m_name = filename;
   pstreamptr->m_fileID = fileID;
   pstreamptr->m_filetype = filetype;
 
@@ -794,7 +811,7 @@ pstreamOpenWrite(const argument_t *argument, int filetype)
 {
   int pstreamID = -1;
 
-  PSTREAM_INIT();
+  //PSTREAM_INIT();
 
   int ispipe = strncmp(argument->args, "(pipe", 5) == 0;
 
@@ -824,7 +841,7 @@ pstreamOpenAppend(const argument_t *argument)
       cdoAbort("this operator doesn't work with pipes!");
     }
 
-  pstream_t *pstreamptr = new pstream_t();
+  pstream_t *pstreamptr = create_pstream();
 
   if (!pstreamptr)
     Error("No memory");
@@ -881,11 +898,65 @@ pstream_t::openAppend(const char *p_filename)
   int filetype = streamInqFiletype(fileID);
   set_comp(fileID, filetype);
 
-  name = (char *) Malloc(strlen(p_filename) + 1);
-  strcpy(name, p_filename);
+  m_name = p_filename;
   mode = 'a';
   m_fileID = fileID;
 }
+void
+pstreamCloseChildStream(pstream_t *pstreamptr)
+{
+  pipe_t *pipe = pstreamptr->pipe;
+  pthread_mutex_lock(pipe->m_mutex);
+  pipe->EOP = true;
+  if (PSTREAM_Debug)
+    Message("%s read closed", pstreamptr->m_name.c_str());
+  pthread_mutex_unlock(pipe->m_mutex);
+  pthread_cond_signal(pipe->tsDef);
+  pthread_cond_signal(pipe->tsInq);
+
+  pthread_cond_signal(pipe->recInq);
+
+  pthread_mutex_lock(pipe->m_mutex);
+  pstreamptr->isopen = false;
+  pthread_mutex_unlock(pipe->m_mutex);
+  pthread_cond_signal(pipe->isclosed);
+
+  pthread_join(pstreamptr->wthreadID, NULL);
+
+  pthread_mutex_lock(pipe->m_mutex);
+    if (pstreamptr->argument)
+    {
+      argument_t *argument = (argument_t *) (pstreamptr->argument);
+      if (argument->args)
+        Free(argument->args);
+      delete (argument);
+    }
+  pthread_mutex_unlock(pipe->m_mutex);
+
+  processAddNvals(pipe->nvals);
+}
+void
+pstreamCloseParentStream(pstream_t *pstreamptr)
+{
+
+  pipe_t *pipe = pstreamptr->pipe;
+  pthread_mutex_lock(pipe->m_mutex);
+  pipe->EOP = true;
+  if (PSTREAM_Debug)
+    Message("%s write closed", pstreamptr->m_name.c_str());
+  pthread_mutex_unlock(pipe->m_mutex);
+  pthread_cond_signal(pipe->tsDef);
+  pthread_cond_signal(pipe->tsInq);
+
+  std::unique_lock<std::mutex> locked_mutex(pipe->m_mutex);
+  while (pstreamptr->isopen)
+    {
+      if (PSTREAM_Debug)
+        Message("wait of read close");
+      pthread_cond_wait(pipe->isclosed, locked_mutex);
+    }
+  locked_mutex.unlock();
+}
 
 void
 pstreamClose(int pstreamID)
@@ -895,81 +966,28 @@ pstreamClose(int pstreamID)
   if (pstreamptr == NULL)
     Error("Internal problem, stream %d not open!", pstreamID);
 
-  if (pstreamptr->ispipe)
+  pstreamptr->close();
+
+  if(!pstreamptr->ispipe)
+  {
+    pstream_delete_entry(pstreamptr);
+  }
+}
+
+void pstream_t::close(){
+  if (ispipe)
     {
 #if defined(HAVE_LIBPTHREAD)
-      pipe_t *pipe;
-      bool lread = false, lwrite = false;
       pthread_t threadID = pthread_self();
 
-      if (pthread_equal(threadID, pstreamptr->rthreadID))
-        lread = true;
-      else if (pthread_equal(threadID, pstreamptr->wthreadID))
-        lwrite = true;
+      if (pthread_equal(threadID, rthreadID))
+        pstreamCloseChildStream(this);
+      else if (pthread_equal(threadID, wthreadID))
+        pstreamCloseParentStream(this);
       else
-        Error("Internal problem! Close pipe %s", pstreamptr->name);
-
-      if (lread)
-        {
-          pipe = pstreamptr->pipe;
-          pthread_mutex_lock(pipe->mutex);
-          pipe->EOP = true;
-          if (PSTREAM_Debug)
-            Message("%s read closed", pstreamptr->name);
-          pthread_mutex_unlock(pipe->mutex);
-          pthread_cond_signal(pipe->tsDef);
-          pthread_cond_signal(pipe->tsInq);
-
-          pthread_cond_signal(pipe->recInq);
-
-          pthread_mutex_lock(pipe->mutex);
-          pstreamptr->isopen = false;
-          pthread_mutex_unlock(pipe->mutex);
-          pthread_cond_signal(pipe->isclosed);
-
-          pthread_join(pstreamptr->wthreadID, NULL);
-
-          pthread_mutex_lock(pipe->mutex);
-          if (pstreamptr->name)
-            Free(pstreamptr->name);
-          if (pstreamptr->argument)
-            {
-              argument_t *argument = (argument_t *) (pstreamptr->argument);
-              if (argument->argv)
-                Free(argument->argv);
-              if (argument->args)
-                Free(argument->args);
-              delete (argument);
-            }
-          vlistDestroy(pstreamptr->m_vlistID);
-          pthread_mutex_unlock(pipe->mutex);
-
-          processAddNvals(pipe->nvals);
-          delete (pipe);
-          pstream_delete_entry(pstreamptr);
-        }
-      else if (lwrite)
-        {
-          pipe = pstreamptr->pipe;
-          pthread_mutex_lock(pipe->mutex);
-          pipe->EOP = true;
-          if (PSTREAM_Debug)
-            Message("%s write closed", pstreamptr->name);
-          pthread_mutex_unlock(pipe->mutex);
-          pthread_cond_signal(pipe->tsDef);
-          pthread_cond_signal(pipe->tsInq);
-
-          pthread_mutex_lock(pipe->mutex);
-          while (pstreamptr->isopen)
-            {
-              if (PSTREAM_Debug)
-                Message("wait of read close");
-              pthread_cond_wait(pipe->isclosed, pipe->mutex);
-            }
-          pthread_mutex_unlock(pipe->mutex);
-        }
+        Error("Internal problem! Close pipe %s", m_name.c_str());
 
-      processDelStream(pstreamID);
+     // processDelStream(pstreamID);
 #else
       cdoAbort("Cannot use pipes, pthread support not compiled in!");
 #endif
@@ -977,18 +995,18 @@ pstreamClose(int pstreamID)
   else
     {
       if (PSTREAM_Debug)
-        Message("%s fileID %d", pstreamptr->name, pstreamptr->m_fileID);
+        Message("%s fileID %d", m_name.c_str(), m_fileID);
 
-      if (pstreamptr->mode == 'r')
+      if (mode == 'r')
         {
-          processAddNvals(streamNvals(pstreamptr->m_fileID));
+          processAddNvals(streamNvals(m_fileID));
         }
 
 #if defined(HAVE_LIBPTHREAD)
       if (cdoLockIO)
         pthread_mutex_lock(&streamMutex);
 #endif
-      streamClose(pstreamptr->m_fileID);
+      streamClose(m_fileID);
 #if defined(HAVE_LIBPTHREAD)
       if (cdoLockIO)
         pthread_mutex_unlock(&streamMutex);
@@ -996,28 +1014,21 @@ pstreamClose(int pstreamID)
 
       if (cdoExpMode == CDO_EXP_REMOTE)
         {
-          if (pstreamptr->mode == 'w')
+          if (mode == 'w')
             {
               extern const char *cdojobfiles;
               FILE *fp = fopen(cdojobfiles, "a");
-              fprintf(fp, "%s\n", pstreamptr->name);
+              fprintf(fp, "%s\n", m_name.c_str());
               fclose(fp);
             }
         }
 
-      if (pstreamptr->name)
+      if (m_varlist)
         {
-          Free(pstreamptr->name);
-          pstreamptr->name = NULL;
+          Free(m_varlist);
+          m_varlist = NULL;
         }
 
-      if (pstreamptr->m_varlist)
-        {
-          Free(pstreamptr->m_varlist);
-          pstreamptr->m_varlist = NULL;
-        }
-
-      pstream_delete_entry(pstreamptr);
     }
 }
 
@@ -1039,7 +1050,7 @@ pstream_t::inqVlist()
     {
       vlistID = pipe->pipeInqVlist(m_vlistID);
       if (vlistID == -1)
-        cdoAbort("Couldn't read data from input stream %s!", name);
+        cdoAbort("Couldn't read data from input stream %s!", m_name.c_str());
     }
   // read from file through cdi streamInqVlist
   else
@@ -1052,6 +1063,10 @@ pstream_t::inqVlist()
         pthread_mutex_lock(&streamMutex);
 #endif
       vlistID = streamInqVlist(m_fileID);
+    if (vlistID == -1){
+        cdoAbort("Couldn't read data from input fileID %d!", m_fileID);
+    }
+
 #if defined(HAVE_LIBPTHREAD)
       if (cdoLockIO)
         pthread_mutex_unlock(&streamMutex);
@@ -1080,29 +1095,28 @@ pstream_t::inqVlist()
   return vlistID;
 }
 
-static void
-pstreamDefVarlist(pstream_t *pstreamptr, int vlistID)
+void pstream_t::defVarList(int p_vlistID)
 {
-  int filetype = pstreamptr->m_filetype;
+  int filetype = m_filetype;
 
-  if (pstreamptr->m_vlistID != -1)
+  if (m_vlistID != -1)
     cdoAbort("Internal problem, vlist already defined!");
 
-  if (pstreamptr->m_varlist != NULL)
+  if (m_varlist != NULL)
     cdoAbort("Internal problem, varlist already allocated!");
 
-  int nvars = vlistNvars(vlistID);
+  int nvars = vlistNvars(p_vlistID);
   assert(nvars > 0);
 
   varlist_t *varlist = (varlist_t *) Malloc(nvars * sizeof(varlist_t));
 
   for (int varID = 0; varID < nvars; ++varID)
     {
-      varlist[varID].gridsize = gridInqSize(vlistInqVarGrid(vlistID, varID));
-      varlist[varID].datatype = vlistInqVarDatatype(vlistID, varID);
-      varlist[varID].missval = vlistInqVarMissval(vlistID, varID);
-      varlist[varID].addoffset = vlistInqVarAddoffset(vlistID, varID);
-      varlist[varID].scalefactor = vlistInqVarScalefactor(vlistID, varID);
+      varlist[varID].gridsize = gridInqSize(vlistInqVarGrid(p_vlistID, varID));
+      varlist[varID].datatype = vlistInqVarDatatype(p_vlistID, varID);
+      varlist[varID].missval = vlistInqVarMissval(p_vlistID, varID);
+      varlist[varID].addoffset = vlistInqVarAddoffset(p_vlistID, varID);
+      varlist[varID].scalefactor = vlistInqVarScalefactor(p_vlistID, varID);
 
       varlist[varID].check_datarange = false;
 
@@ -1112,15 +1126,17 @@ pstreamDefVarlist(pstream_t *pstreamptr, int vlistID)
       int datatype = varlist[varID].datatype;
 
       if (filetype == CDI_FILETYPE_NC || filetype == CDI_FILETYPE_NC2 || filetype == CDI_FILETYPE_NC4
-          || filetype == CDI_FILETYPE_NC4C)
+          || filetype == CDI_FILETYPE_NC4C || filetype == CDI_FILETYPE_NC5)
         {
-          if (datatype == CDI_DATATYPE_UINT8 && (filetype == CDI_FILETYPE_NC || filetype == CDI_FILETYPE_NC2))
+          if (datatype == CDI_DATATYPE_UINT8 &&
+              (filetype == CDI_FILETYPE_NC || filetype == CDI_FILETYPE_NC2 || filetype == CDI_FILETYPE_NC5))
             {
               datatype = CDI_DATATYPE_INT16;
               varlist[varID].datatype = datatype;
             }
 
-          if (datatype == CDI_DATATYPE_UINT16 && (filetype == CDI_FILETYPE_NC || filetype == CDI_FILETYPE_NC2))
+          if (datatype == CDI_DATATYPE_UINT16 &&
+              (filetype == CDI_FILETYPE_NC || filetype == CDI_FILETYPE_NC2 || filetype == CDI_FILETYPE_NC5))
             {
               datatype = CDI_DATATYPE_INT32;
               varlist[varID].datatype = datatype;
@@ -1139,66 +1155,69 @@ pstreamDefVarlist(pstream_t *pstreamptr, int vlistID)
         }
     }
 
-  pstreamptr->m_varlist = varlist;
-  pstreamptr->m_vlistID = vlistID; /* used for -r/-a */
+  m_varlist = varlist;
+  m_vlistID = p_vlistID; /* used for -r/-a */
 }
 
 void
 pstreamDefVlist(int pstreamID, int vlistID)
 {
   pstream_t *pstreamptr = pstream_to_pointer(pstreamID);
+  pstreamptr->defVlist(vlistID);
+}
 
+void pstream_t::defVlist(int p_vlistID){
 #if defined(HAVE_LIBPTHREAD)
-  if (pstreamptr->ispipe)
+  if (ispipe)
     {
       if (PSTREAM_Debug)
-        Message("%s pstreamID %d", pstreamptr->name, pstreamptr->self);
-      int vlistIDcp = vlistDuplicate(vlistID);
-      /*    pipeDefVlist(pstreamptr, vlistID);*/
-      pstreamptr->pipe->pipeDefVlist(pstreamptr->m_vlistID, vlistIDcp);
+        Message("%s pstreamID %d", m_name.c_str(), self);
+      int vlistIDcp = vlistDuplicate(p_vlistID);
+      /*    pipeDefVlist(pstreamptr, p_vlistID);*/
+      pipe->pipeDefVlist(m_vlistID, vlistIDcp);
     }
   else
 #endif
     {
       if (cdoDefaultDataType != CDI_UNDEFID)
         {
-          int varID, nvars = vlistNvars(vlistID);
+          int varID, nvars = vlistNvars(p_vlistID);
 
           for (varID = 0; varID < nvars; ++varID)
-            vlistDefVarDatatype(vlistID, varID, cdoDefaultDataType);
+            vlistDefVarDatatype(p_vlistID, varID, cdoDefaultDataType);
 
           if (cdoDefaultDataType == CDI_DATATYPE_FLT64 || cdoDefaultDataType == CDI_DATATYPE_FLT32)
             {
               for (varID = 0; varID < nvars; varID++)
                 {
-                  vlistDefVarAddoffset(vlistID, varID, 0.0);
-                  vlistDefVarScalefactor(vlistID, varID, 1.0);
+                  vlistDefVarAddoffset(p_vlistID, varID, 0.0);
+                  vlistDefVarScalefactor(p_vlistID, varID, 1.0);
                 }
             }
         }
 
       if (cdoChunkType != CDI_UNDEFID)
         {
-          int varID, nvars = vlistNvars(vlistID);
+          int varID, nvars = vlistNvars(p_vlistID);
 
           for (varID = 0; varID < nvars; ++varID)
-            vlistDefVarChunkType(vlistID, varID, cdoChunkType);
+            vlistDefVarChunkType(p_vlistID, varID, cdoChunkType);
         }
 
       if (CDO_CMOR_Mode)
         {
-          cdo_def_tracking_id(vlistID, "tracking_id");
-          cdo_def_creation_date(vlistID);
+          cdo_def_tracking_id(p_vlistID, "tracking_id");
+          cdo_def_creation_date(p_vlistID);
         }
 
       if (CDO_Version_Info)
-        cdiDefAttTxt(vlistID, CDI_GLOBAL, "CDO", (int) strlen(cdoComment()), cdoComment());
+        cdiDefAttTxt(p_vlistID, CDI_GLOBAL, "CDO", (int) strlen(cdoComment()), cdoComment());
 
 #if defined(_OPENMP)
       if (ompNumThreads > 1)
-        cdiDefAttInt(vlistID, CDI_GLOBAL, "cdo_openmp_thread_number", CDI_DATATYPE_INT32, 1, &ompNumThreads);
+        cdiDefAttInt(p_vlistID, CDI_GLOBAL, "cdo_openmp_thread_number", CDI_DATATYPE_INT32, 1, &ompNumThreads);
 #endif
-      pstreamDefVarlist(pstreamptr, vlistID);
+      defVarList(p_vlistID);
 
       if (processNums() == 1 && ompNumThreads == 1)
         timer_start(timer_write);
@@ -1206,7 +1225,7 @@ pstreamDefVlist(int pstreamID, int vlistID)
       if (cdoLockIO)
         pthread_mutex_lock(&streamMutex);
 #endif
-      streamDefVlist(pstreamptr->m_fileID, vlistID);
+      streamDefVlist(m_fileID, p_vlistID);
 #if defined(HAVE_LIBPTHREAD)
       if (cdoLockIO)
         pthread_mutex_unlock(&streamMutex);
@@ -1269,7 +1288,7 @@ pstreamDefRecord(int pstreamID, int varID, int levelID)
 
       if (PSTREAM_Debug)
         {
-          Message("%s pstreamid %d", pstreamptr->name, pstreamptr->self);
+          Message("%s pstreamid %d", pstreamptr->m_name.c_str(), pstreamptr->self);
         }
       pstreamptr->pipe->pipeDefRecord(varID, levelID);
     }
@@ -1561,9 +1580,8 @@ pstreamInqTimestep(int pstreamID, int tsID)
 
       if (nrecs == 0 && pstreamptr->mfiles && (pstreamptr->nfiles < pstreamptr->mfiles))
         {
-          size_t len;
           int nfile = pstreamptr->nfiles;
-          char *filename = NULL;
+          std::string filename; 
           int fileID;
           int vlistIDold, vlistIDnew;
 
@@ -1572,9 +1590,7 @@ pstreamInqTimestep(int pstreamID, int tsID)
           vlistIDold = vlistDuplicate(streamInqVlist(pstreamptr->m_fileID));
           streamClose(pstreamptr->m_fileID);
 
-          len = strlen(pstreamptr->mfnames[nfile]);
-          filename = (char *) Malloc(len + 1);
-          strcpy(filename, pstreamptr->mfnames[nfile]);
+          filename = pstreamptr->m_mfnames[nfile];
           pstreamptr->nfiles++;
 
 #if defined(HAVE_LIBPTHREAD)
@@ -1584,11 +1600,11 @@ pstreamInqTimestep(int pstreamID, int tsID)
             pthread_mutex_lock(&streamOpenReadMutex);
 #endif
           if (cdoVerbose)
-            cdoPrint("Continuation file: %s", filename);
+            cdoPrint("Continuation file: %s", filename.c_str());
 
           if (processNums() == 1 && ompNumThreads == 1)
             timer_start(timer_read);
-          fileID = streamOpenRead(filename);
+          fileID = streamOpenRead(filename.c_str());
           vlistIDnew = streamInqVlist(fileID);
           if (processNums() == 1 && ompNumThreads == 1)
             timer_stop(timer_read);
@@ -1602,11 +1618,9 @@ pstreamInqTimestep(int pstreamID, int tsID)
             pthread_mutex_unlock(&streamOpenReadMutex);
 #endif
           if (fileID < 0)
-            cdiOpenError(fileID, "Open failed on >%s<", filename);
-
-          Free(pstreamptr->name);
+            cdiOpenError(fileID, "Open failed on >%s<", filename.c_str());
 
-          pstreamptr->name = filename;
+          pstreamptr->m_name = filename;
           pstreamptr->m_fileID = fileID;
 
           if (processNums() == 1 && ompNumThreads == 1)
@@ -1725,13 +1739,27 @@ cdoInitialize(void *argument)
 
 #if defined(HAVE_LIBPTHREAD)
   if (PSTREAM_Debug)
-    Message("process %d  thread %ld", processSelf(), pthread_self());
+    Message("process %d  thread %ld", processSelf().m_ID, pthread_self());
 #endif
 
   processDefArgument(argument);
 }
 
 void
+pstreamCloseAll()
+{
+  for (auto pstream_iter : _pstream_map)
+    {
+      if ( pstream_iter.second.m_fileID != CDI_UNDEFID )
+        {
+          if (PSTREAM_Debug)
+            Message("Close file %s id %d", pstream_iter.second.m_name.c_str(), pstream_iter.second.m_fileID);
+          streamClose(pstream_iter.second.m_fileID);
+        }
+    }
+}
+/*
+void
 pstreamCloseAll(void)
 {
   if (_pstreamList == NULL)
@@ -1745,170 +1773,14 @@ pstreamCloseAll(void)
           if (!pstreamptr->ispipe && pstreamptr->m_fileID != CDI_UNDEFID)
             {
               if (PSTREAM_Debug)
-                Message("Close file %s id %d", pstreamptr->name, pstreamptr->m_fileID);
+                Message("Close file %s id %d", pstreamptr->m_name.c_str(), pstreamptr->m_fileID);
               streamClose(pstreamptr->m_fileID);
             }
         }
     }
 }
+*/
 
-static void
-processClosePipes(void)
-{
-  int nstream = processInqInputStreamNum();
-  for (int sindex = 0; sindex < nstream; sindex++)
-    {
-      int pstreamID = processInqInputStreamID(sindex);
-      pstream_t *pstreamptr = pstream_to_pointer(pstreamID);
-
-      if (PSTREAM_Debug)
-        Message("process %d  stream %d  close streamID %d", processSelf(), sindex, pstreamID);
-
-      if (pstreamptr)
-        pstreamClose(pstreamID);
-    }
-
-  nstream = processInqOutputStreamNum();
-  for (int sindex = 0; sindex < nstream; sindex++)
-    {
-      int pstreamID = processInqOutputStreamID(sindex);
-      pstream_t *pstreamptr = pstream_to_pointer(pstreamID);
-
-      if (PSTREAM_Debug)
-        Message("process %d  stream %d  close streamID %d", processSelf(), sindex, pstreamID);
-
-      if (pstreamptr)
-        pstreamClose(pstreamID);
-    }
-}
-
-void
-cdoFinish(void)
-{
-  int processID = processSelf();
-  int nvars, ntimesteps;
-  char memstring[32] = { "" };
-  double s_utime, s_stime;
-  double e_utime, e_stime;
-  double c_cputime = 0, c_usertime = 0, c_systime = 0;
-  double p_cputime = 0, p_usertime = 0, p_systime = 0;
-
-#if defined(HAVE_LIBPTHREAD)
-  if (PSTREAM_Debug)
-    Message("process %d  thread %ld", processID, pthread_self());
-#endif
-
-  int64_t nvals = processInqNvals(processID);
-  nvars = processInqVarNum();
-  ntimesteps = processInqTimesteps();
-
-  if (!cdoSilentMode)
-    {
-      set_text_color(stderr, RESET, GREEN);
-      fprintf(stderr, "%s: ", processInqPrompt());
-      reset_text_color(stderr);
-      if (nvals > 0)
-        {
-          if (sizeof(int64_t) > sizeof(long))
-#if defined(_WIN32)
-            fprintf(stderr,
-                    "Processed %I64d value%s from %d variable%s",
-#else
-            fprintf(stderr,
-                    "Processed %jd value%s from %d variable%s",
-#endif
-                    (intmax_t) nvals,
-                    ADD_PLURAL(nvals),
-                    nvars,
-                    ADD_PLURAL(nvars));
-          else
-            fprintf(stderr,
-                    "Processed %ld value%s from %d variable%s",
-                    (long) nvals,
-                    ADD_PLURAL(nvals),
-                    nvars,
-                    ADD_PLURAL(nvars));
-        }
-      else if (nvars > 0)
-        {
-          fprintf(stderr, "Processed %d variable%s", nvars, ADD_PLURAL(nvars));
-        }
-
-      if (ntimesteps > 0)
-        fprintf(stderr, " over %d timestep%s", ntimesteps, ADD_PLURAL(ntimesteps));
-
-      //  fprintf(stderr, ".");
-    }
-  /*
-    fprintf(stderr, "%s: Processed %d variable%s %d timestep%s.",
-            processInqPrompt(), nvars, nvars > 1 ? "s" : "",
-            ntimesteps, ntimesteps > 1 ? "s" : "");
-  */
-  processStartTime(&s_utime, &s_stime);
-  cdoProcessTime(&e_utime, &e_stime);
-
-  c_usertime = e_utime - s_utime;
-  c_systime = e_stime - s_stime;
-  c_cputime = c_usertime + c_systime;
-
-#if defined(HAVE_LIBPTHREAD)
-  if (pthreadScope == PTHREAD_SCOPE_PROCESS)
-    {
-      c_usertime /= processNums();
-      c_systime /= processNums();
-      c_cputime /= processNums();
-    }
-#endif
-
-  processDefCputime(processID, c_cputime);
-
-  processAccuTime(c_usertime, c_systime);
-
-  if (processID == 0)
-    {
-      int mu[] = { 'b', 'k', 'm', 'g', 't' };
-      int muindex = 0;
-      long memmax;
-
-      memmax = memTotal();
-      while (memmax > 9999)
-        {
-          memmax /= 1024;
-          muindex++;
-        }
-
-      if (memmax)
-        snprintf(memstring, sizeof(memstring), " %ld%c ", memmax, mu[muindex]);
-
-      processEndTime(&p_usertime, &p_systime);
-      p_cputime = p_usertime + p_systime;
-
-      if (cdoLogOff == 0)
-        {
-          cdologs(processNums());
-          cdologo(processNums());
-          cdolog(processInqPrompt(), p_cputime);
-        }
-    }
-
-#if defined(HAVE_SYS_TIMES_H)
-  if (cdoBenchmark)
-    fprintf(stderr, " ( %.2fs %.2fs %.2fs %s)\n", c_usertime, c_systime, c_cputime, memstring);
-  else
-    {
-      if (!cdoSilentMode)
-        fprintf(stderr, " ( %.2fs )\n", c_cputime);
-    }
-  if (cdoBenchmark && processID == 0)
-    fprintf(stderr, "total: user %.2fs  sys %.2fs  cpu %.2fs  mem%s\n", p_usertime, p_systime, p_cputime, memstring);
-#else
-  fprintf(stderr, "\n");
-#endif
-
-  processClosePipes();
-
-  processDelete();
-}
 
 int
 pstreamInqFiletype(int pstreamID)
@@ -2001,3 +1873,10 @@ openUnlock(void)
     pthread_mutex_unlock(&streamOpenReadMutex);
 #endif
 }
+
+//TODO remove when processes create the new threads
+const int &getPthreadScope()
+{
+    return pthreadScope;
+}
+
diff --git a/src/pstream.h b/src/pstream.h
index 160c520..ab7bbec 100644
--- a/src/pstream.h
+++ b/src/pstream.h
@@ -23,19 +23,25 @@
 #include "argument.h"
 
 #include <sys/types.h> /* off_t */
+#include <vector>
 
 class pstream_t
 {
 public:
-  pstream_t();
+  pstream_t(int id);
+  ~pstream_t();
   int inqVlist();
   int inqFileType();
   void defTimestep(int p_tsID);
   bool isPipe();
-  void pstreamOpenReadPipe(const argument_t *argument);
-  void pstreamOpenReadFile(const argument_t *argument);
+  void pstreamOpenReadPipe(const char* pipename);
+  void pstreamOpenReadFile(const char *argument);
   void openAppend(const char * p_filename);
-  int self;
+  void init();
+  void defVlist(int p_vlistID);
+  void close();
+  int self; //aka the id of the pstream
+  std::pair<int, int> m_id;
   int mode;
   int m_fileID;
   int m_vlistID;
@@ -47,14 +53,18 @@ public:
   int varID; /* next varID defined with streamDefVar */
   bool ispipe;
   bool isopen;
-  char *name;
-  char **mfnames;
+  std::string m_name;
+  std::vector<std::string> m_mfnames;
   varlist_t *m_varlist;
 #if defined(HAVE_LIBPTHREAD)
   void *argument;
   struct pipe_t *pipe;
   pthread_t rthreadID; /* read  thread ID */
   pthread_t wthreadID; /* write thread ID */
+private:
+   void createFilelist(const char *p_args);
+   pstream_t();
+   void defVarList(int vlistID);
 #endif
 };
 
@@ -81,4 +91,6 @@ int pstreamFileID(int pstreamID);
 
 void cdoVlistCopyFlag(int vlistID2, int vlistID1);
 
+const int &getPthreadScope();
+
 #endif /* PSTREAM_H */
diff --git a/src/pthread_debug.cc b/src/pthread_debug.cc
index 9c17dfa..247351a 100644
--- a/src/pthread_debug.cc
+++ b/src/pthread_debug.cc
@@ -9,6 +9,9 @@
 #include <pthread.h>
 #include <errno.h>
 #include "error.h"
+#include <mutex>
+#include <condition_variable>
+#include <iostream>
 
 
 #define POUT2(caller, x, a, b)     pout2(caller, #x, x, #a, a, #b, b)
@@ -193,7 +196,17 @@ void Pthread_mutex_lock(const char *caller, pthread_mutex_t *mutex)
 	}
     }
 }
-
+void Pthread_mutex_lock(const char *caller, std::mutex &p_mutex)
+{
+    try {
+      p_mutex.lock();
+    }
+    catch(const std::system_error& e)
+    {
+        std::cout << "locking failed in " << caller 
+                  << ". ErrorCode:" << e.code() << " " << e.what() << std::endl;
+    }
+}
 
 void Pthread_mutex_unlock(const char *caller, pthread_mutex_t *mutex)
 {
@@ -218,8 +231,25 @@ void Pthread_mutex_unlock(const char *caller, pthread_mutex_t *mutex)
 	}
     }
 }
+void Pthread_mutex_unlock(const char *caller, std::mutex &p_mutex)
+{
+    try {
+      p_mutex.unlock();
+    }
+    catch(const std::system_error& e)
+    {
+        std::cout << "unlocking failed in " << caller 
+                  << ". ErrorCode:" << e.code() << " " << e.what() << std::endl;
+    }
+}
 
 
+void Pthread_cond_signal(const char *caller,std::condition_variable &p_cond_var)
+{
+  if( PTHREAD_Debug)Message("+%s (cond = %p)", caller, (void *) &p_cond_var);
+    p_cond_var.notify_all();
+  if ( PTHREAD_Debug ) Message("-%s (cond = %p)", caller, (void *) &p_cond_var);
+}
 void Pthread_cond_signal(const char *caller, pthread_cond_t *cond)
 {
   if ( PTHREAD_Debug ) Message("+%s (cond = %p)", caller, (void *) cond);
@@ -229,6 +259,14 @@ void Pthread_cond_signal(const char *caller, pthread_cond_t *cond)
   if ( PTHREAD_Debug ) Message("-%s (cond = %p)", caller, (void *) cond);
 }
 
+void Pthread_cond_wait(const char *caller, std::condition_variable &p_cond, std::unique_lock<std::mutex> &p_locked_mutex)
+{
+  if ( PTHREAD_Debug ) std::cout << caller << "waiting for condition "<< &p_cond << std::endl;
+    p_cond.wait(p_locked_mutex);
+
+  if ( PTHREAD_Debug ) std::cout << caller << "finished waiting " << &p_cond << std::endl;
+}
+
 
 void Pthread_cond_wait(const char *caller, pthread_cond_t *cond, pthread_mutex_t *mutex)
 {
@@ -237,7 +275,7 @@ void Pthread_cond_wait(const char *caller, pthread_cond_t *cond, pthread_mutex_t
 
   pthread_cond_wait(cond, mutex);
 
-  if ( PTHREAD_Debug ) Message("-%s (cond = %p, mutex = %p)",
+   if ( PTHREAD_Debug ) Message("-%s (cond = %p, mutex = %p)",
 			       caller, (void *) cond, (void *) mutex);
 }
 
diff --git a/src/pthread_debug.h b/src/pthread_debug.h
index 9ca4f64..6436b85 100644
--- a/src/pthread_debug.h
+++ b/src/pthread_debug.h
@@ -1,6 +1,9 @@
 #ifndef _PTHREAD_DEBUG_H
 #define _PTHREAD_DEBUG_H
 
+#include <mutex>
+#include <condition_variable>
+
 void Pthread_debug(int debug);
 
 int Pthread_create(const char *caller, pthread_t *th,
@@ -9,10 +12,15 @@ int Pthread_create(const char *caller, pthread_t *th,
 int Pthread_join(const char *caller, pthread_t th, void **thread_return);
 
 void Pthread_mutex_lock(const char *caller, pthread_mutex_t *mutex);
+void Pthread_mutex_lock(const char *caller, std::mutex &p_mutex);
+
 void Pthread_mutex_unlock(const char *caller, pthread_mutex_t *mutex);
+void Pthread_mutex_unlock(const char *caller, std::mutex& p_mutex);
 
 void Pthread_cond_signal(const char *caller, pthread_cond_t *cond);
+void Pthread_cond_signal(const char *caller,std::condition_variable &p_cond_var);
 void Pthread_cond_wait(const char *caller, pthread_cond_t *cond, pthread_mutex_t *mutex);
+void Pthread_cond_wait(const char *caller, std::condition_variable &p_cond_var, std::unique_lock<std::mutex>& p_mutex);
 
 void print_pthread_attr(const char *caller, pthread_attr_t *attr);
 void print_pthread_mutexattr(const char *caller,  pthread_mutexattr_t *m_attr);
diff --git a/src/remap.h b/src/remap.h
index a4975ab..582217b 100644
--- a/src/remap.h
+++ b/src/remap.h
@@ -76,8 +76,8 @@ typedef struct {
   int      gridID;
   int      remap_grid_type;
   int      rank;                  /* rank of the grid */
-  long     size;                  /* total points on the grid */
-  long     num_cell_corners;      /* number of corners for each grid cell */
+  size_t   size;                  /* total points on the grid */
+  size_t   num_cell_corners;      /* number of corners for each grid cell */
 
   bool     lneed_cell_corners;
   bool     luse_cell_corners;     /* use corners for bounding boxes  */
@@ -110,7 +110,7 @@ typedef struct {
 
   int      num_srch_bins;         /* num of bins for restricted srch */
 
-  int*     bin_addr;              /* min,max adds for grid cells in this lat bin  */
+  size_t  *bin_addr;              /* min,max adds for grid cells in this lat bin  */
 
   restr_t* bin_lats;              /* min,max latitude for each search bin   */
 }
@@ -118,28 +118,28 @@ remapgrid_t;
 
 typedef struct {
   bool     option;
-  int      max_links;
-  int      num_blks;
-  int     *num_links;
-  int    **src_add;
-  int    **dst_add;
-  int    **w_index;
+  size_t   max_links;
+  size_t   num_blks;
+  size_t  *num_links;
+  size_t **src_add;
+  size_t **dst_add;
+  size_t **w_index;
 }
 remaplink_t;
 
 typedef struct {
-  int      links_per_value;
+  long     links_per_value;
   bool     sort_add;
   bool     pinit;            /* true: if the pointers are initialized    */
-  long     max_links;        /* current size of link arrays              */
-  long     num_links;        /* actual number of links for remapping     */
-  long     num_wts;          /* num of weights used in remapping         */
+  size_t   max_links;        /* current size of link arrays              */
+  size_t   num_links;        /* actual number of links for remapping     */
+  size_t   num_wts;          /* num of weights used in remapping         */
   int      map_type;         /* identifier for remapping method          */
   int      norm_opt;         /* option for normalization (conserv only)  */
-  int      resize_increment; /* default amount to increase array size    */
+  size_t   resize_increment; /* default amount to increase array size    */
 
-  int     *src_cell_add;     /* source grid address for each link        */
-  int     *tgt_cell_add;     /* target grid address for each link        */
+  size_t  *src_cell_add;     /* source grid address for each link        */
+  size_t  *tgt_cell_add;     /* target grid address for each link        */
 
   double  *wts;              /* map weights for each link [max_links*num_wts] */
 
@@ -150,7 +150,7 @@ remapvars_t;
 typedef struct {
   int      nused;
   int      gridID;
-  int      gridsize;
+  size_t   gridsize;
   int      nmiss;
   remapgrid_t src_grid;
   remapgrid_t tgt_grid;
@@ -169,31 +169,31 @@ void remap_set_int(int remapvar, int value);
 
 
 void remap_grids_init(int map_type, bool lextrapolate, int gridID1, remapgrid_t *src_grid, int gridID2, remapgrid_t *tgt_grid);
-void remap_vars_init(int map_type, long src_grid_size, long tgt_grid_size, remapvars_t *rv);
+void remap_vars_init(int map_type, size_t src_grid_size, size_t tgt_grid_size, remapvars_t *rv);
 
 void remapVarsFree(remapvars_t *rv);
 void remapGridFree(remapgrid_t *grid);
 
-void remap(double *restrict dst_array, double missval, long dst_size, long num_links, double *restrict map_wts, 
-	   long num_wts, const int *restrict dst_add, const int *restrict src_add, const double *restrict src_array, 
+void remap(double *restrict dst_array, double missval, size_t dst_size, size_t num_links, double *restrict map_wts, 
+	   size_t num_wts, const size_t *restrict dst_add, const size_t *restrict src_add, const double *restrict src_array, 
 	   const double *restrict src_grad1, const double *restrict src_grad2, const double *restrict src_grad3,
 	   remaplink_t links, long links_per_value);
 
-void remap_laf(double *restrict dst_array, double missval, long dst_size, long num_links, double *restrict map_wts,
-	       long num_wts, const int *restrict dst_add, const int *restrict src_add, const double *restrict src_array);
+void remap_laf(double *restrict dst_array, double missval, size_t dst_size, size_t num_links, double *restrict map_wts,
+	       size_t num_wts, const size_t *restrict dst_add, const size_t *restrict src_add, const double *restrict src_array);
 
-void remap_sum(double *restrict dst_array, double missval, long dst_size, long num_links, double *restrict map_wts,
-	       long num_wts, const int *restrict dst_add, const int *restrict src_add, const double *restrict src_array);
+void remap_sum(double *restrict dst_array, double missval, size_t dst_size, size_t num_links, double *restrict map_wts,
+	       size_t num_wts, const size_t *restrict dst_add, const size_t *restrict src_add, const double *restrict src_array);
 
 void scrip_remap_bilinear_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv);
 void scrip_remap_bicubic_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv);
-void remap_distwgt_weights(unsigned num_neighbors, remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv);
+void remap_distwgt_weights(size_t num_neighbors, remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv);
 void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv);
 void remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv);
 
 void scrip_remap_bilinear(remapgrid_t *src_grid, remapgrid_t *tgt_grid, const double *restrict src_array, double *restrict tgt_array, double missval);
 void scrip_remap_bicubic(remapgrid_t *src_grid, remapgrid_t *tgt_grid, const double *restrict src_array, double *restrict tgt_array, double missval);
-void remap_distwgt(unsigned num_neighbors, remapgrid_t *src_grid, remapgrid_t *tgt_grid, const double *restrict src_array, double *restrict tgt_array, double missval);
+void remap_distwgt(size_t num_neighbors, remapgrid_t *src_grid, remapgrid_t *tgt_grid, const double *restrict src_array, double *restrict tgt_array, double missval);
 void remap_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, const double *restrict src_array, double *restrict tgt_array, double missval);
 
 
@@ -206,8 +206,8 @@ void remap_gradients(remapgrid_t grid, const double *restrict array, double *res
 
 void reorder_links(remapvars_t *rv);
 
-void sort_add(long num_links, long num_wts, int *restrict add1, int *restrict add2, double *restrict weights);
-void sort_iter(long num_links, long num_wts, int *restrict add1, int *restrict add2, double *restrict weights, int parent);
+void sort_add(size_t num_links, size_t num_wts, size_t *restrict add1, size_t *restrict add2, double *restrict weights);
+void sort_iter(size_t num_links, size_t num_wts, size_t *restrict add1, size_t *restrict add2, double *restrict weights, int parent);
 
 void write_remap_scrip(const char *interp_file, int map_type, int submap_type, int num_neighbors,
 		       int remap_order, remapgrid_t src_grid, remapgrid_t tgt_grid, remapvars_t rv);
@@ -215,27 +215,27 @@ void read_remap_scrip(const char *interp_file, int gridID1, int gridID2, int *ma
 		      int *remap_order, remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv);
 
 void calc_lat_bins(remapgrid_t* src_grid, remapgrid_t* tgt_grid, int map_type);
-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);
+size_t get_srch_cells(size_t tgt_cell_add, size_t nbins, size_t *bin_addr1, size_t *bin_addr2,
+                      restr_t *tgt_cell_bound_box, restr_t *src_cell_bound_box, size_t src_grid_size, size_t *srch_add);
 
-int grid_search_reg2d_nn(long nx, long ny, int *restrict nbr_add, double *restrict nbr_dist, double plat, double plon,
-			 const double *restrict src_center_lat, const double *restrict src_center_lon);
+int grid_search_reg2d_nn(size_t nx, size_t ny, size_t *restrict nbr_add, double *restrict nbr_dist, double plat, double plon,
+                         const double *restrict src_center_lat, const double *restrict src_center_lon);
 
-int grid_search_reg2d(remapgrid_t *src_grid, int *restrict src_add, double *restrict src_lats, 
-		      double *restrict src_lons,  double plat, double plon, const int *restrict src_grid_dims,
-		      const double *restrict src_center_lat, const double *restrict src_center_lon);
+int grid_search_reg2d(remapgrid_t *src_grid, size_t *restrict src_add, double *restrict src_lats, 
+                      double *restrict src_lons,  double plat, double plon, const int *restrict src_grid_dims,
+                      const double *restrict src_center_lat, const double *restrict src_center_lon);
 
-int grid_search(remapgrid_t *src_grid, int *restrict src_add, double *restrict src_lats, 
+int grid_search(remapgrid_t *src_grid, size_t *restrict src_add, double *restrict src_lats, 
 		double *restrict src_lons,  double plat, double plon, const int *restrict src_grid_dims,
 		const double *restrict src_center_lat, const double *restrict src_center_lon,
-		const restr_t *restrict src_grid_bound_box, const int *restrict src_bin_add);
+		const restr_t *restrict src_grid_bound_box, const size_t *restrict src_bin_add);
 
 int find_ij_weights(double plon, double plat, double* restrict src_lats, double* restrict src_lons, double *ig, double *jg);
-int rect_grid_search(long *ii, long *jj, double x, double y, long nxm, long nym, const double *restrict xm, const double *restrict ym);
+int rect_grid_search(size_t *ii, size_t *jj, double x, double y, size_t nxm, size_t nym, const double *restrict xm, const double *restrict ym);
 
-void remapgrid_get_lonlat(remapgrid_t *grid, unsigned cell_add, double *plon, double *plat);
+void remapgrid_get_lonlat(remapgrid_t *grid, size_t cell_add, double *plon, double *plat);
 
-void remapCheckArea(int grid_size, double *restrict cell_area, const char *name);
-void remapCheckWeights(long num_links, int num_wts, int norm_opt, int *src_cell_add, int *tgt_cell_add, double *wts);
+void remapCheckArea(size_t grid_size, double *restrict cell_area, const char *name);
+void remapCheckWeights(size_t num_links, size_t num_wts, int norm_opt, size_t *src_cell_add, size_t *tgt_cell_add, double *wts);
 
 #endif  /* _REMAP_H */
diff --git a/src/remap_bicubic_scrip.cc b/src/remap_bicubic_scrip.cc
index 947904f..b793129 100644
--- a/src/remap_bicubic_scrip.cc
+++ b/src/remap_bicubic_scrip.cc
@@ -32,7 +32,7 @@ void set_bicubic_weights(double iw, double jw, double wgts[4][4])
   wgts[3][3] =     iw*(iw-1.)*(iw-1.) *     jw*jw*(jw-1.);
 }
 
-int num_src_points(const int* restrict mask, const int src_add[4], double src_lats[4]);
+int num_src_points(const int* restrict mask, const size_t src_add[4], double src_lats[4]);
 
 static
 void renormalize_weights(const double src_lats[4], double wgts[4][4])
@@ -61,7 +61,7 @@ void bicubic_warning(void)
 }
 
 static
-void bicubic_remap(double* restrict tgt_point, const double* restrict src_array, double wgts[4][4], const int src_add[4],
+void bicubic_remap(double* restrict tgt_point, const double* restrict src_array, double wgts[4][4], const size_t src_add[4],
 		   const double* restrict grad1, const double* restrict grad2, const double* restrict grad3)
 {
   *tgt_point = 0.;
@@ -83,7 +83,7 @@ void scrip_remap_bicubic_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 {
   /*   Local variables */
   int  search_result;
-  int src_add[4];      /*  address for the four source points     */
+  size_t 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       */
@@ -209,7 +209,7 @@ void scrip_remap_bicubic(remapgrid_t *src_grid, remapgrid_t *tgt_grid, const dou
 {
   /*   Local variables */
   int  search_result;
-  int src_add[4];      /*  address for the four source points   */
+  size_t 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     */
diff --git a/src/remap_bilinear_scrip.cc b/src/remap_bilinear_scrip.cc
index fbeba6b..a87649e 100644
--- a/src/remap_bilinear_scrip.cc
+++ b/src/remap_bilinear_scrip.cc
@@ -92,7 +92,7 @@ void set_bilinear_weights(double iw, double jw, double wgts[4])
 }
 
 
-int num_src_points(const int* restrict mask, const int src_add[4], double src_lats[4])
+int num_src_points(const int* restrict mask, const size_t src_add[4], double src_lats[4])
 {
   int icount = 0;
 
@@ -117,7 +117,7 @@ void renormalize_weights(const double src_lats[4], double wgts[4])
 }
 
 static
-void bilinear_warning(double plon, double plat, double iw, double jw, int* src_add, double* src_lons, double* src_lats, remapgrid_t* src_grid)
+void bilinear_warning(double plon, double plat, double iw, double jw, size_t* src_add, double* src_lons, double* src_lats, remapgrid_t* src_grid)
 {
   static bool lwarn = true;
 
@@ -126,7 +126,7 @@ void bilinear_warning(double plon, double plat, double iw, double jw, int* src_a
       cdoPrint("Point coords: %g %g", plat, plon);
       cdoPrint("Src grid lats: %g %g %g %g", src_lats[0], src_lats[1], src_lats[2], src_lats[3]);
       cdoPrint("Src grid lons: %g %g %g %g", src_lons[0], src_lons[1], src_lons[2], src_lons[3]);
-      cdoPrint("Src grid addresses: %d %d %d %d", src_add[0], src_add[1], src_add[2], src_add[3]);
+      cdoPrint("Src grid addresses: %zu %zu %zu %zu", src_add[0], src_add[1], src_add[2], src_add[3]);
       cdoPrint("Src grid lats: %g %g %g %g",
 	       src_grid->cell_center_lat[src_add[0]], src_grid->cell_center_lat[src_add[1]],
 	       src_grid->cell_center_lat[src_add[2]], src_grid->cell_center_lat[src_add[3]]);
@@ -145,7 +145,7 @@ void bilinear_warning(double plon, double plat, double iw, double jw, int* src_a
 }
 
 static
-void bilinear_remap(double* restrict tgt_point, const double *restrict src_array, const double wgts[4], const int src_add[4])
+void bilinear_remap(double* restrict tgt_point, const double *restrict src_array, const double wgts[4], const size_t src_add[4])
 {
   // *tgt_point = 0.;
   // for ( int n = 0; n < 4; ++n ) *tgt_point += src_array[src_add[n]]*wgts[n];
@@ -164,7 +164,7 @@ void scrip_remap_bilinear_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid,
 {
   /*   Local variables */
   int  search_result;
-  int src_add[4];                /*  address for the four source points     */
+  size_t 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      */
@@ -289,7 +289,7 @@ void scrip_remap_bilinear(remapgrid_t *src_grid, remapgrid_t *tgt_grid, const do
 {
   /*   Local variables */
   int  search_result;
-  int src_add[4];                /*  address for the four source points     */
+  size_t 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      */
diff --git a/src/remap_conserv.cc b/src/remap_conserv.cc
index 45f759d..d6cd51d 100644
--- a/src/remap_conserv.cc
+++ b/src/remap_conserv.cc
@@ -22,7 +22,7 @@ extern "C" {
 
 typedef struct {
   enum yac_edge_type *src_edge_type;
-  long srch_corners;
+  size_t srch_corners;
   size_t max_srch_cells;
   double *partial_areas;
   double *partial_weights;
@@ -110,9 +110,9 @@ int rect_grid_search2(long *imin, long *imax, double xmin, double xmax, long nxm
 static
 size_t get_srch_cells_reg2d(const int *restrict src_grid_dims, 
                             const double *restrict src_corner_lat, const double *restrict src_corner_lon,
-                            const double *restrict tgt_cell_bound_box, int *srch_add)
+                            const double *restrict tgt_cell_bound_box, size_t *srch_add)
 {
-  int debug = 0;
+  bool debug = false;
   long nx = src_grid_dims[0];
   long ny = src_grid_dims[1];
   size_t num_srch_cells = 0;  // num cells in restricted search arrays
@@ -219,12 +219,12 @@ void restrict_boundbox(const double *restrict grid_bound_box, double *restrict b
 }
 
 static
-void boundbox_from_corners_reg2d(long grid_add, const int *restrict grid_dims, const double *restrict corner_lon,
+void boundbox_from_corners_reg2d(size_t grid_add, const int *restrict grid_dims, const double *restrict corner_lon,
 				 const double *restrict corner_lat, double *restrict bound_box)
 {
-  long nx = grid_dims[0];
-  long iy = grid_add/nx;
-  long ix = grid_add - iy*nx;
+  size_t nx = grid_dims[0];
+  size_t iy = grid_add/nx;
+  size_t ix = grid_add - iy*nx;
 
   double clat1 = corner_lat[iy  ];
   double clat2 = corner_lat[iy+1];
@@ -245,10 +245,10 @@ void boundbox_from_corners_reg2d(long grid_add, const int *restrict grid_dims, c
 }
 
 static
-void boundbox_from_corners1(long ic, long nc, const double *restrict corner_lon,
+void boundbox_from_corners1(size_t ic, size_t nc, const double *restrict corner_lon,
 			    const double *restrict corner_lat, double *restrict bound_box)
 {
-  long inc = ic*nc;
+  size_t inc = ic*nc;
 
   double clat = corner_lat[inc];
   double clon = corner_lon[inc];
@@ -258,7 +258,7 @@ void boundbox_from_corners1(long ic, long nc, const double *restrict corner_lon,
   bound_box[2] = clon;
   bound_box[3] = clon;
 
-  for ( long j = 1; j < nc; ++j )
+  for ( size_t j = 1; j < nc; ++j )
     {
       clat = corner_lat[inc+j];
       clon = corner_lon[inc+j];
@@ -296,10 +296,10 @@ void boundbox_from_corners1(long ic, long nc, const double *restrict corner_lon,
 }
 
 static
-void boundbox_from_corners1r(long ic, long nc, const double *restrict corner_lon,
+void boundbox_from_corners1r(size_t ic, size_t nc, const double *restrict corner_lon,
 			     const double *restrict corner_lat, restr_t *restrict bound_box)
 {
-  long inc = ic*nc;
+  size_t inc = ic*nc;
 
   restr_t clat = RESTR_SCALE(corner_lat[inc]);
   restr_t clon = RESTR_SCALE(corner_lon[inc]);
@@ -309,7 +309,7 @@ void boundbox_from_corners1r(long ic, long nc, const double *restrict corner_lon
   bound_box[2] = clon;
   bound_box[3] = clon;
 
-  for ( long j = 1; j < nc; ++j )
+  for ( size_t j = 1; j < nc; ++j )
     {
       clat = RESTR_SCALE(corner_lat[inc+j]);
       clon = RESTR_SCALE(corner_lon[inc+j]);
@@ -542,13 +542,13 @@ int get_lonlat_circle_index(remapgrid_t *remap_grid)
 	{
 	  const double* cell_corner_lon = remap_grid->cell_corner_lon;
 	  const double* cell_corner_lat = remap_grid->cell_corner_lat;
-	  int gridsize = remap_grid->size;
-	  int num_i = 0, num_eq0 = 0, num_eq1 = 0;
-	  int iadd = gridsize/3-1;
+	  size_t gridsize = remap_grid->size;
+	  size_t num_i = 0, num_eq0 = 0, num_eq1 = 0;
+	  long iadd = gridsize/3-1;
 
 	  if ( iadd == 0 ) iadd++;
 
-	  for ( int i = 0; i < gridsize; i += iadd )
+	  for ( size_t i = 0; i < gridsize; i += iadd )
 	    {
 	      num_i++;
 
@@ -583,9 +583,9 @@ static
 void remapNormalizeWeights(remapgrid_t *tgt_grid, remapvars_t *rv)
 {
   // Include centroids in weights and normalize using destination area if requested
-  long num_links = rv->num_links;
-  int num_wts = rv->num_wts;
-  int tgt_cell_add;       // current linear address for target grid cell
+  size_t num_links = rv->num_links;
+  size_t num_wts = rv->num_wts;
+  size_t 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 )
@@ -598,7 +598,7 @@ void remapNormalizeWeights(remapgrid_t *tgt_grid, remapvars_t *rv)
   shared(num_wts, num_links, rv, tgt_grid) \
   private(tgt_cell_add, norm_factor)
 #endif
-      for ( long n = 0; n < num_links; ++n )
+      for ( size_t n = 0; n < num_links; ++n )
 	{
 	  tgt_cell_add = rv->tgt_cell_add[n];
 
@@ -620,7 +620,7 @@ void remapNormalizeWeights(remapgrid_t *tgt_grid, remapvars_t *rv)
   shared(num_wts, num_links, rv, tgt_grid) \
   private(tgt_cell_add, norm_factor)
 #endif
-      for ( long n = 0; n < num_links; ++n )
+      for ( size_t n = 0; n < num_links; ++n )
 	{
 	  tgt_cell_add = rv->tgt_cell_add[n];
 
@@ -638,13 +638,13 @@ void remapNormalizeWeights(remapgrid_t *tgt_grid, remapvars_t *rv)
 }
 
 static
-void set_yac_coordinates(int remap_grid_type, int cell_add, int num_cell_corners, remapgrid_t *remap_grid, struct grid_cell *yac_grid_cell)
+void set_yac_coordinates(int remap_grid_type, size_t cell_add, size_t num_cell_corners, remapgrid_t *remap_grid, struct grid_cell *yac_grid_cell)
 {
   if ( remap_grid_type == REMAP_GRID_TYPE_REG2D )
     {
-      int nx = remap_grid->dims[0];
-      int iy = cell_add/nx;
-      int ix = cell_add - iy*nx;
+      size_t nx = remap_grid->dims[0];
+      size_t iy = cell_add/nx;
+      size_t ix = cell_add - iy*nx;
       const double *restrict reg2d_corner_lon = remap_grid->reg2d_corner_lon;
       const double *restrict reg2d_corner_lat = remap_grid->reg2d_corner_lat;
       double *restrict coordinates_x = yac_grid_cell->coordinates_x;
@@ -665,7 +665,7 @@ void set_yac_coordinates(int remap_grid_type, int cell_add, int num_cell_corners
       const double *restrict cell_corner_lat = remap_grid->cell_corner_lat;
       double *restrict coordinates_x = yac_grid_cell->coordinates_x;
       double *restrict coordinates_y = yac_grid_cell->coordinates_y;
-      for ( int ic = 0; ic < num_cell_corners; ++ic )
+      for ( size_t ic = 0; ic < num_cell_corners; ++ic )
         {
           coordinates_x[ic] = cell_corner_lon[cell_add*num_cell_corners+ic];
           coordinates_y[ic] = cell_corner_lat[cell_add*num_cell_corners+ic];
@@ -675,15 +675,15 @@ void set_yac_coordinates(int remap_grid_type, int cell_add, int num_cell_corners
   const double *restrict coordinates_x = yac_grid_cell->coordinates_x;
   const double *restrict coordinates_y = yac_grid_cell->coordinates_y;
   double *restrict coordinates_xyz = yac_grid_cell->coordinates_xyz;
-  for ( int ic = 0; ic < num_cell_corners; ++ic )
+  for ( size_t ic = 0; ic < num_cell_corners; ++ic )
     LLtoXYZ(coordinates_x[ic], coordinates_y[ic], coordinates_xyz+ic*3);
 }
 
 static
 void reg2d_bound_box(remapgrid_t *remap_grid, double *grid_bound_box)
 {
-  int nx = remap_grid->dims[0];
-  int ny = remap_grid->dims[1];
+  size_t nx = remap_grid->dims[0];
+  size_t ny = remap_grid->dims[1];
   const double *restrict reg2d_corner_lon = remap_grid->reg2d_corner_lon;
   const double *restrict reg2d_corner_lat = remap_grid->reg2d_corner_lat;
 
@@ -702,7 +702,7 @@ void reg2d_bound_box(remapgrid_t *remap_grid, double *grid_bound_box)
 void remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv)
 {
   bool lcheck = true;
-  int srch_corners;  // num of corners of srch cells
+  size_t srch_corners;  // num of corners of srch cells
 
   /* Variables necessary if segment manages to hit pole */
   int src_remap_grid_type = src_grid->remap_grid_type;
@@ -715,22 +715,22 @@ void remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
 
   if ( cdoTimer ) timer_start(timer_remap_con);
 
-  int src_grid_size = src_grid->size;
-  int tgt_grid_size = tgt_grid->size;
+  size_t src_grid_size = src_grid->size;
+  size_t tgt_grid_size = tgt_grid->size;
 
-  int src_num_cell_corners = src_grid->num_cell_corners;
-  int tgt_num_cell_corners = tgt_grid->num_cell_corners;
+  size_t src_num_cell_corners = src_grid->num_cell_corners;
+  size_t tgt_num_cell_corners = tgt_grid->num_cell_corners;
 
-  int max_num_cell_corners = src_num_cell_corners;
+  size_t 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 yac_edge_type great_circle_type[max_num_cell_corners];
-  for ( int i = 0; i < max_num_cell_corners; ++i ) great_circle_type[i] = GREAT_CIRCLE;
+  std::vector<enum yac_edge_type> great_circle_type(max_num_cell_corners);
+  for ( size_t i = 0; i < max_num_cell_corners; ++i ) great_circle_type[i] = GREAT_CIRCLE;
 
   enum yac_edge_type lonlat_circle_type[] = {LON_CIRCLE, LAT_CIRCLE, LON_CIRCLE, LAT_CIRCLE, LON_CIRCLE};
 
-  enum yac_edge_type *src_edge_type = great_circle_type;
-  enum yac_edge_type *tgt_edge_type = great_circle_type;
+  enum yac_edge_type *src_edge_type = great_circle_type.data();
+  enum yac_edge_type *tgt_edge_type = great_circle_type.data();
 
   enum cell_type target_cell_type = UNDEF_CELL;
 
@@ -757,16 +757,15 @@ void remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
     }
 
 
-  std::vector<struct grid_cell *> tgt_grid_cell2(ompNumThreads);  
+  std::vector<struct grid_cell> tgt_grid_cell(ompNumThreads);  
   for ( int i = 0; i < ompNumThreads; ++i )
     {
-      tgt_grid_cell2[i] = (struct grid_cell*) Malloc(sizeof(struct grid_cell));
-      tgt_grid_cell2[i]->array_size      = tgt_num_cell_corners;
-      tgt_grid_cell2[i]->num_corners     = tgt_num_cell_corners;
-      tgt_grid_cell2[i]->edge_type       = tgt_edge_type;
-      tgt_grid_cell2[i]->coordinates_x   = (double*) Malloc(tgt_num_cell_corners*sizeof(double));
-      tgt_grid_cell2[i]->coordinates_y   = (double*) Malloc(tgt_num_cell_corners*sizeof(double));
-      tgt_grid_cell2[i]->coordinates_xyz = (double*) Malloc(3*tgt_num_cell_corners*sizeof(double));
+      tgt_grid_cell[i].array_size      = tgt_num_cell_corners;
+      tgt_grid_cell[i].num_corners     = tgt_num_cell_corners;
+      tgt_grid_cell[i].edge_type       = tgt_edge_type;
+      tgt_grid_cell[i].coordinates_x   = new double[tgt_num_cell_corners];
+      tgt_grid_cell[i].coordinates_y   = new double[tgt_num_cell_corners];
+      tgt_grid_cell[i].coordinates_xyz = new double[3*tgt_num_cell_corners];
     }
 
   std::vector<search_t> search(ompNumThreads);
@@ -781,9 +780,8 @@ void remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
       search[i].overlap_buffer  = NULL;
     }
 
-  std::vector<int *> srch_add2(ompNumThreads);
-  for ( int i = 0; i < ompNumThreads; ++i )
-    srch_add2[i] = (int*) Malloc(src_grid_size*sizeof(int));
+  std::vector<size_t *> srch_add(ompNumThreads);
+  for ( int i = 0; i < ompNumThreads; ++i ) srch_add[i] = new size_t[src_grid_size];
 
   srch_corners = src_num_cell_corners;
 
@@ -809,12 +807,12 @@ void remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
   shared(ompNumThreads, src_remap_grid_type, tgt_remap_grid_type, src_grid_bound_box, \
 	 rv, cdoVerbose, tgt_num_cell_corners, target_cell_type, \
          weightlinks,  srch_corners, src_grid, tgt_grid, tgt_grid_size, src_grid_size, \
-	 search, srch_add2, tgt_grid_cell2, findex, sum_srch_cells, sum_srch_cells2)
+	 search, srch_add, tgt_grid_cell, findex, sum_srch_cells, sum_srch_cells2)
 #endif
-  for ( long tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
+  for ( size_t tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
     {
       double partial_weight;
-      long src_cell_add;       // current linear address for source grid cell
+      size_t src_cell_add;       // current linear address for source grid cell
       size_t num_srch_cells;
       size_t n, num_weights, num_weights_old;
       int ompthID = cdo_omp_get_thread_num();
@@ -827,9 +825,6 @@ void remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
 
       weightlinks[tgt_cell_add].nlinks = 0;	
 
-      int *srch_add = srch_add2[ompthID];
-      struct grid_cell *tgt_grid_cell = tgt_grid_cell2[ompthID];
-
       // Get search cells
 #ifdef STIMER
       clock_t start = clock();
@@ -842,7 +837,7 @@ void remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
 	  restrict_boundbox(src_grid_bound_box, tgt_cell_bound_box);
 
 	  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);
+						tgt_cell_bound_box, srch_add[ompthID]);
 
 	  if ( num_srch_cells == 1 && src_grid->dims[0] == 1 && src_grid->dims[1] == 1 &&
 	       IS_EQUAL(src_grid->reg2d_corner_lat[0], src_grid->reg2d_corner_lat[1]) && 
@@ -855,7 +850,7 @@ void remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
 	  restrict_boundbox(src_grid_bound_box, tgt_cell_bound_box);
 
 	  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);
+						tgt_cell_bound_box, srch_add[ompthID]);
 
 	  if ( num_srch_cells == 1 && src_grid->dims[0] == 1 && src_grid->dims[1] == 1 &&
 	       IS_EQUAL(src_grid->reg2d_corner_lat[0], src_grid->reg2d_corner_lat[1]) && 
@@ -866,9 +861,9 @@ void remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
 	  restr_t tgt_cell_bound_box_r[4];
 	  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);
 
-          long nbins = src_grid->num_srch_bins;
+          size_t nbins = src_grid->num_srch_bins;
 	  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);
+					  tgt_cell_bound_box_r, src_grid->cell_bound_box, src_grid_size, srch_add[ompthID]);
 	}
 #ifdef STIMER
       clock_t finish = clock();
@@ -878,11 +873,11 @@ void remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
       if ( 0 && cdoVerbose ) sum_srch_cells += num_srch_cells;
 
       if ( 0 && cdoVerbose )
-	printf("tgt_cell_add %ld  num_srch_cells %zu\n", tgt_cell_add, num_srch_cells);
+	printf("tgt_cell_add %zu  num_srch_cells %zu\n", tgt_cell_add, num_srch_cells);
 
       if ( num_srch_cells == 0 ) continue;
 
-      set_yac_coordinates(tgt_remap_grid_type, tgt_cell_add, tgt_num_cell_corners, tgt_grid, tgt_grid_cell);
+      set_yac_coordinates(tgt_remap_grid_type, tgt_cell_add, tgt_num_cell_corners, tgt_grid, &tgt_grid_cell[ompthID]);
 
       // Create search arrays
 
@@ -894,31 +889,31 @@ void remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
 
       for ( n = 0; n < num_srch_cells; ++n )
 	{
-	  int srch_corners_new = srch_corners;
-	  src_cell_add = srch_add[n];
+	  size_t srch_corners_new = srch_corners;
+	  src_cell_add = srch_add[ompthID][n];
           set_yac_coordinates(src_remap_grid_type, src_cell_add, srch_corners_new, src_grid, &src_grid_cells[n]);
 	}
 
       if ( tgt_num_cell_corners < 4 || target_cell_type == LON_LAT_CELL )
 	{
-	  cdo_compute_overlap_areas(num_srch_cells, &search[ompthID], *tgt_grid_cell);
+	  cdo_compute_overlap_areas(num_srch_cells, &search[ompthID], tgt_grid_cell[ompthID]);
 	}
       else
 	{
 	  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, &search[ompthID], *tgt_grid_cell, cell_center_lon, cell_center_lat);
+	  cdo_compute_concave_overlap_areas(num_srch_cells, &search[ompthID], tgt_grid_cell[ompthID], cell_center_lon, cell_center_lat);
 	}
 
-      double tgt_area = gridcell_area(*tgt_grid_cell);
-      // double tgt_area = cell_area(tgt_grid_cell);
+      double tgt_area = gridcell_area(tgt_grid_cell[ompthID]);
+      // double tgt_area = cell_area(&tgt_grid_cell[ompthID]);
 
       for ( num_weights = 0, n = 0; n < num_srch_cells; ++n )
 	{
 	  if ( partial_areas[n] > 0 )
 	    {
 	      partial_areas[num_weights] = partial_areas[n];
-	      srch_add[num_weights] = srch_add[n];
+	      srch_add[ompthID][num_weights] = srch_add[ompthID][n];
 	      num_weights++;
 	    }
 	}
@@ -938,12 +933,12 @@ void remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
       num_weights = 0;
       for ( n = 0; n < num_weights_old; ++n )
 	{
-	  src_cell_add = srch_add[n];
-	  if ( partial_weights[n] <= 0. ) src_cell_add = -1;
-	  if ( src_cell_add != -1 )
+	  src_cell_add = srch_add[ompthID][n];
+	  if ( partial_weights[n] <= 0. ) src_cell_add = src_grid_size;
+	  if ( src_cell_add != src_grid_size )
 	    {
 	      partial_weights[num_weights] = partial_weights[n];
-	      srch_add[num_weights] = src_cell_add;
+	      srch_add[ompthID][num_weights] = src_cell_add;
 	      num_weights++;
 	    }
 	}
@@ -951,7 +946,7 @@ void remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
       for ( n = 0; n < num_weights; ++n )
 	{
 	  partial_weight = partial_weights[n];
-	  src_cell_add = srch_add[n];
+	  src_cell_add = srch_add[ompthID][n];
 
 #if defined(_OPENMP)
 #pragma omp atomic
@@ -963,7 +958,7 @@ void remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
       num_weights_old = num_weights;
       for ( num_weights = 0, n = 0; n < num_weights_old; ++n )
 	{
-	  src_cell_add = srch_add[n];
+	  src_cell_add = srch_add[ompthID][n];
 
 	  /*
 	    Store the appropriate addresses and weights. 
@@ -973,7 +968,7 @@ void remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
 	  if ( src_grid->mask[src_cell_add] )
 	    {
 	      partial_weights[num_weights] = partial_weights[n];
-	      srch_add[num_weights] = src_cell_add;
+	      srch_add[ompthID][num_weights] = src_cell_add;
 	      num_weights++;
 	    }
 	}
@@ -981,7 +976,7 @@ void remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
       for ( n = 0; n < num_weights; ++n )
 	{
 	  partial_weight = partial_weights[n];
-	  src_cell_add = srch_add[n];
+	  src_cell_add = srch_add[ompthID][n];
 
 #if defined(_OPENMP)
 #pragma omp atomic
@@ -991,7 +986,7 @@ void remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapva
 	  tgt_grid->cell_frac[tgt_cell_add] += partial_weight;
 	}
 
-      store_weightlinks(1, num_weights, srch_add, partial_weights, tgt_cell_add, weightlinks);
+      store_weightlinks(1, num_weights, srch_add[ompthID], 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);
@@ -1013,12 +1008,11 @@ printf("stime = %gs\n", stimer);
     {
       search_free(&search[ompthID]);
 
-      Free(tgt_grid_cell2[ompthID]->coordinates_x);
-      Free(tgt_grid_cell2[ompthID]->coordinates_y);
-      Free(tgt_grid_cell2[ompthID]->coordinates_xyz);
-      Free(tgt_grid_cell2[ompthID]);
+      delete[] tgt_grid_cell[ompthID].coordinates_x;
+      delete[] tgt_grid_cell[ompthID].coordinates_y;
+      delete[] tgt_grid_cell[ompthID].coordinates_xyz;
 
-      Free(srch_add2[ompthID]);
+      delete[] srch_add[ompthID];
     }
   
   weightlinks2remaplinks(1, tgt_grid_size, weightlinks, rv);
@@ -1028,12 +1022,12 @@ printf("stime = %gs\n", stimer);
   // Normalize weights using destination area if requested
   remapNormalizeWeights(tgt_grid, rv);
 
-  if ( cdoVerbose ) cdoPrint("Total number of links = %ld", rv->num_links);
+  if ( cdoVerbose ) cdoPrint("Total number of links = %zu", rv->num_links);
   
-  for ( int n = 0; n < src_grid_size; ++n )
+  for ( size_t n = 0; n < src_grid_size; ++n )
     if ( IS_NOT_EQUAL(src_grid->cell_area[n], 0) ) src_grid->cell_frac[n] /= src_grid->cell_area[n];
 
-  for ( int n = 0; n < tgt_grid_size; ++n )
+  for ( size_t n = 0; n < tgt_grid_size; ++n )
     if ( IS_NOT_EQUAL(tgt_grid->cell_area[n], 0) ) tgt_grid->cell_frac[n] /= tgt_grid->cell_area[n];
 
   // Perform some error checking on final weights
@@ -1050,6 +1044,7 @@ printf("stime = %gs\n", stimer);
 } // remap_weights_conserv
 
 
-void remap_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, const double* restrict src_array, double* restrict tgt_array, double missval)
+//void remap_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, const double* restrict src_array, double* restrict tgt_array, double missval)
+void remap_conserv(remapgrid_t *, remapgrid_t *, const double* restrict , double* restrict , double )
 {
 } // remap_conserv
diff --git a/src/remap_conserv_scrip.cc b/src/remap_conserv_scrip.cc
index c111f57..8b46c2c 100644
--- a/src/remap_conserv_scrip.cc
+++ b/src/remap_conserv_scrip.cc
@@ -43,25 +43,25 @@ void remap_set_threshhold(double threshhold)
     accurately.
 */
 static
-void pole_intersection(long *location, double *intrsct_lat, double *intrsct_lon, int *lcoinc,
-		       int *lthresh, double beglat, double beglon, double endlat, double endlon,
-		       double *begseg, int lrevers,
-		       long num_srch_cells, long srch_corners, const int *restrict srch_add,
+void pole_intersection(long *location, double *intrsct_lat, double *intrsct_lon, bool *lcoinc,
+		       bool *lthresh, double beglat, double beglon, double endlat, double endlon,
+		       double *begseg, bool lrevers,
+		       long num_srch_cells, long srch_corners, const size_t *restrict srch_add,
 		       const double *restrict srch_corner_lat, const double *restrict srch_corner_lon,
-		       int *luse_last, double *intrsct_x, double *intrsct_y,
+		       bool *luse_last, double *intrsct_x, double *intrsct_y,
 		       int *avoid_pole_count, double *avoid_pole_offset)
 {
   /*
     Intent(in): 
     double beglat, beglon,  ! beginning lat/lon endpoints for segment
     double endlat, endlon   ! ending    lat/lon endpoints for segment
-    int    lrevers          ! flag true if segment integrated in reverse
+    bool   lrevers          ! flag true if segment integrated in reverse
 
     Intent(inout) :
     double begseg[2] ! begin lat/lon of full segment
     int *location    ! address in destination array containing this
                      ! segment -- also may contain last location on entry
-    int *lthresh     ! flag segment crossing threshold boundary
+    bool *lthresh    ! flag segment crossing threshold boundary
 
     intent(out): 
     *int lcoinc      ! flag segment coincident with grid line
@@ -94,7 +94,7 @@ void pole_intersection(long *location, double *intrsct_lat, double *intrsct_lon,
   /* Initialize defaults, flags, etc. */
 
   if ( ! *lthresh ) *location = -1;
-  *lcoinc      = FALSE;
+  *lcoinc      = false;
   *intrsct_lat = endlat;
   *intrsct_lon = endlon;
 
@@ -126,7 +126,7 @@ void pole_intersection(long *location, double *intrsct_lat, double *intrsct_lon,
     {
       x1 = rns*TWO*sin(pi4 - HALF*beglat)*cos(beglon);
       y1 =     TWO*sin(pi4 - HALF*beglat)*sin(beglon);
-      *luse_last = TRUE;
+      *luse_last = true;
     }
 
   x2 = rns*TWO*sin(pi4 - HALF*endlat)*cos(endlon);
@@ -160,7 +160,7 @@ void pole_intersection(long *location, double *intrsct_lat, double *intrsct_lon,
       if ( *lthresh )
 	{
 	  for ( cell=0; cell < num_srch_cells; ++cell )
-	    if ( srch_add[cell] == *location )
+	    if ( srch_add[cell] == (size_t)*location )
 	      {
 		eps = TINY;
 		goto after_srch_loop;
@@ -222,7 +222,7 @@ void pole_intersection(long *location, double *intrsct_lat, double *intrsct_lon,
 
 		  if ( IS_EQUAL(cross_product, 0) )
 		    {
-		      *lcoinc = TRUE;
+		      *lcoinc = true;
 		      cross_product = vec1_x*vec2_x + vec1_y*vec2_y;
 		      if ( lrevers ) cross_product = -cross_product;
 		    }
@@ -277,7 +277,7 @@ void pole_intersection(long *location, double *intrsct_lat, double *intrsct_lon,
 	{
           Free(srch_corner_y);
           Free(srch_corner_x);
-          *luse_last = FALSE;
+          *luse_last = false;
           return;
 	}
     } /* srch_loop */
@@ -453,7 +453,7 @@ void pole_intersection(long *location, double *intrsct_lat, double *intrsct_lon,
         }
 
       *avoid_pole_count = *avoid_pole_count + 1;
-      *luse_last = FALSE;
+      *luse_last = false;
     }
   else
     {
@@ -471,7 +471,7 @@ void pole_intersection(long *location, double *intrsct_lat, double *intrsct_lon,
   if ( *lthresh )
     {
       if ( *intrsct_lat > north_thresh || *intrsct_lat < south_thresh )
-	*lthresh = FALSE;
+	*lthresh = false;
     }
   else if ( beglat > ZERO && *intrsct_lat < north_thresh )
     {
@@ -482,8 +482,8 @@ void pole_intersection(long *location, double *intrsct_lat, double *intrsct_lon,
       *intrsct_lat = north_thresh - TINY;
       s1 = (north_thresh - begseg[0])/mat4;
       *intrsct_lon = begseg[1] + s1*mat3;
-      *luse_last = FALSE;
-      *lthresh = TRUE;
+      *luse_last = false;
+      *lthresh = true;
     }
   else if ( beglat < ZERO && *intrsct_lat > south_thresh )
     {
@@ -494,13 +494,13 @@ void pole_intersection(long *location, double *intrsct_lat, double *intrsct_lon,
       *intrsct_lat = south_thresh + TINY;
       s1 = (south_thresh - begseg[0])/mat4;
       *intrsct_lon = begseg[1] + s1*mat3;
-      *luse_last = FALSE;
-      *lthresh = TRUE;
+      *luse_last = false;
+      *lthresh = true;
     }
 
   /* If reached end of segment, do not use x,y intersect on next entry */
 
-  if ( IS_EQUAL(*intrsct_lat, endlat) && IS_EQUAL(*intrsct_lon, endlon) ) *luse_last = FALSE;
+  if ( IS_EQUAL(*intrsct_lat, endlat) && IS_EQUAL(*intrsct_lon, endlon) ) *luse_last = false;
 
 }  /* pole_intersection */
 
@@ -512,19 +512,19 @@ void pole_intersection(long *location, double *intrsct_lat, double *intrsct_lon,
    have already been restricted in the calling routine.
 */
 static
-void intersection(long *location, double *intrsct_lat, double *intrsct_lon, int *lcoinc,
+void intersection(long *location, double *intrsct_lat, double *intrsct_lon, bool *lcoinc,
 		  double beglat, double beglon, double endlat, double endlon, double *begseg,
-		  int lbegin, int lrevers,
-		  long num_srch_cells, long srch_corners, const int *restrict srch_add,
+		  bool lbegin, bool lrevers,
+		  long num_srch_cells, long srch_corners, const size_t *restrict srch_add,
 		  const double *restrict srch_corner_lat, const double *restrict srch_corner_lon,
-		  int *last_loc, int *lthresh, double *intrsct_lat_off, double *intrsct_lon_off,
-		  int *luse_last, double *intrsct_x, double *intrsct_y,
+		  long *last_loc, bool *lthresh, double *intrsct_lat_off, double *intrsct_lon_off,
+		  bool *luse_last, double *intrsct_x, double *intrsct_y,
 		  int *avoid_pole_count, double *avoid_pole_offset)
 {
   /*
     Intent(in): 
-    int lbegin,             ! flag for first integration along this segment
-    int lrevers             ! flag whether segment integrated in reverse
+    bool lbegin,            ! flag for first integration along this segment
+    bool lrevers            ! flag whether segment integrated in reverse
     double beglat, beglon,  ! beginning lat/lon endpoints for segment
     double endlat, endlon   ! ending    lat/lon endpoints for segment
 
@@ -533,7 +533,7 @@ void intersection(long *location, double *intrsct_lat, double *intrsct_lon, int
 
     intent(out): 
     int *location           ! address in destination array containing this segment
-    int *lcoinc             ! flag segments which are entirely coincident with a grid line
+    bool *lcoinc            ! flag segments which are entirely coincident with a grid line
     double *intrsct_lat, *intrsct_lon ! lat/lon coords of next intersect.
   */
   /* Local variables */
@@ -556,7 +556,7 @@ void intersection(long *location, double *intrsct_lat, double *intrsct_lon, int
   /* Initialize defaults, flags, etc. */
 
   *location    = -1;
-  *lcoinc      = FALSE;
+  *lcoinc      = false;
   *intrsct_lat = endlat;
   *intrsct_lon = endlon;
 
@@ -612,7 +612,7 @@ void intersection(long *location, double *intrsct_lat, double *intrsct_lon, int
       if ( *lthresh )
        {
          for ( cell = 0; cell < num_srch_cells; ++cell )
-	   if ( srch_add[cell] == *last_loc )
+	   if ( srch_add[cell] == (size_t)*last_loc )
 	     {
                *location = *last_loc;
                eps = TINY;
@@ -688,7 +688,7 @@ void intersection(long *location, double *intrsct_lat, double *intrsct_lon, int
 
 		  if ( IS_EQUAL(cross_product, 0) )
 		    {
-		      *lcoinc = TRUE;
+		      *lcoinc = true;
 		      cross_product = vec1_lon*vec2_lon + vec1_lat*vec2_lat;
 		      if ( lrevers ) cross_product = -cross_product;
 		    }
@@ -873,7 +873,7 @@ void intersection(long *location, double *intrsct_lat, double *intrsct_lon, int
   if ( *lthresh )
     {
       if ( *intrsct_lat < north_thresh || *intrsct_lat > south_thresh )
-	*lthresh = FALSE;
+	*lthresh = false;
     }
   else if ( lat1 > ZERO && *intrsct_lat > north_thresh )
     {
@@ -883,7 +883,7 @@ void intersection(long *location, double *intrsct_lat, double *intrsct_lon, int
       *intrsct_lon     = begseg[1] + s1*mat3;
       *intrsct_lon_off = begseg[1] + (s1+eps)*mat3;
       *last_loc = *location;
-      *lthresh = TRUE;
+      *lthresh = true;
     }
   else if ( lat1 < ZERO && *intrsct_lat < south_thresh )
     {
@@ -893,7 +893,7 @@ void intersection(long *location, double *intrsct_lat, double *intrsct_lon, int
       *intrsct_lon     = begseg[1] + s1*mat3;
       *intrsct_lon_off = begseg[1] + (s1+eps)*mat3;
       *last_loc = *location;
-      *lthresh = TRUE;
+      *lthresh = true;
     }
 
 }  /* intersection */
@@ -991,7 +991,7 @@ static
 void correct_pole(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv,
 		  double *src_centroid_lat, double *src_centroid_lon,
 		  double *tgt_centroid_lat, double *tgt_centroid_lon,
-		  grid_store_t *grid_store, int *link_add1[2], int *link_add2[2])
+		  grid_store_t *grid_store, long *link_add1[2], long *link_add2[2])
 {
   /*
      Correct for situations where N/S pole not explicitly included in
@@ -1020,7 +1020,7 @@ void correct_pole(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv,
   weights[4] =  PI*PI;
   weights[5] =  ZERO;
 
-  src_cell_add = -1;
+  src_cell_add = src_grid_size;
   /* 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 )
@@ -1031,7 +1031,7 @@ void correct_pole(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv,
 #endif
       }
 
-  tgt_cell_add = -1;
+  tgt_cell_add = tgt_grid_size;
   /* 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 )
@@ -1042,21 +1042,21 @@ void correct_pole(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv,
 #endif
       }
 
-  if ( src_cell_add != -1 )
+  if ( src_cell_add != src_grid_size )
     {
       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_cell_add != -1 )
+  if ( tgt_cell_add != tgt_grid_size )
     {
       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_cell_add != -1 && tgt_cell_add != -1 )
+  if ( src_cell_add != src_grid_size && tgt_cell_add != tgt_grid_size )
     {
       if ( remap_store_link_fast )
 	store_link_cnsrv_fast(rv, src_cell_add, tgt_cell_add, num_wts, weights, grid_store);
@@ -1075,7 +1075,7 @@ void correct_pole(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv,
   weights[4] = -PI*PI;
   weights[5] =  ZERO;
 
-  src_cell_add = -1;
+  src_cell_add = src_grid_size;
   /* 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 )
@@ -1086,7 +1086,7 @@ void correct_pole(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv,
 #endif
       }
 
-  tgt_cell_add = -1;
+  tgt_cell_add = tgt_grid_size;
   /* 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 )
@@ -1097,21 +1097,21 @@ void correct_pole(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv,
 #endif
       }
 
-  if ( src_cell_add != -1 )
+  if ( src_cell_add != src_grid_size )
     {
       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_cell_add != -1 )
+  if ( tgt_cell_add != tgt_grid_size )
     {
       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_cell_add != -1 && tgt_cell_add != -1 )
+  if ( src_cell_add != src_grid_size && tgt_cell_add != tgt_grid_size )
     {
       if ( remap_store_link_fast )
 	store_link_cnsrv_fast(rv, src_cell_add, tgt_cell_add, num_wts, weights, grid_store);
@@ -1221,58 +1221,17 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 {
   /* local variables */
 
-  int lcheck = TRUE;
+  bool lcheck = true;
 
-  long ioffset;
   long max_subseg = 100000; /* max number of subsegments per segment to prevent infinite loop */
                             /* 1000 is too small!!! */
-  long src_grid_size;
-  long tgt_grid_size;
-  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     */
-  long nbins, num_links;
-  long num_subseg;      /* number of subsegments                   */
-
-  int lcoinc;           /* flag for coincident segments            */
-  int lrevers;          /* flag for reversing direction of segment */
-  int lbegin;           /* flag for first integration of a segment */
-
-  double intrsct_lat, intrsct_lon;         /* lat/lon of next intersect  */
-  double beglat, endlat, beglon, endlon;   /* endpoints of current seg.  */
-  double norm_factor = 0;                  /* factor for normalizing wts */
-
-  double begseg[2];         /* begin lat/lon for full segment */
-  double weights[6];        /* local wgt array */
-  long    num_wts;
-
-  long    max_srch_cells;   /* num cells in restricted search arrays  */
-  long    num_srch_cells;   /* num cells in restricted search arrays  */
-  long    srch_corners;     /* num of corners of srch cells           */
-  long    nsrch_corners;
-  int*    srch_add;         /* global address of cells in srch arrays */
-  std::vector<int *> srch_add2(ompNumThreads);
-  int     i;
-  double *srch_corner_lat;  /* lat of each corner of srch cells */
-  double *srch_corner_lon;  /* lon of each corner of srch cells */
-
-  int *link_add1[2];        /* min,max link add to restrict search */
-  int *link_add2[2];        /* min,max link add to restrict search */
-
-  /* Intersection */
-  int last_loc = -1;        /* save location when crossing threshold  */
-  int lthresh = FALSE;      /* flags segments crossing threshold bndy */
-  double intrsct_lat_off = 0, intrsct_lon_off = 0; /* lat/lon coords offset for next search */
+
+  long srch_corners;      /* num of corners of srch cells           */
+  long i;
 
   /* Pole_intersection */
   /* Save last intersection to avoid roundoff during coord transformation */
-  int luse_last = FALSE;
-  double intrsct_x, intrsct_y;      /* x,y for intersection */
   /* Variables necessary if segment manages to hit pole */
-  int avoid_pole_count = 0;         /* count attempts to avoid pole  */
-  double avoid_pole_offset = TINY;  /* endpoint offset to avoid pole */
   grid_store_t *grid_store = NULL;
   double findex = 0;
   extern int timer_remap_con, timer_remap_con_l1, timer_remap_con_l2;
@@ -1281,8 +1240,8 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 
   progressInit();
 
-  nbins = src_grid->num_srch_bins;
-  num_wts = rv->num_wts;
+  long nbins = src_grid->num_srch_bins;
+  long num_wts = rv->num_wts;
 
   if ( remap_store_link_fast )
     {
@@ -1298,23 +1257,25 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 
   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;
 
   long src_num_cell_corners = src_grid->num_cell_corners;
   long tgt_num_cell_corners = tgt_grid->num_cell_corners;
 
+  long *link_add1[2];  // min,max link add to restrict search
+  long *link_add2[2];  // min,max link add to restrict search
   if ( ! remap_store_link_fast )
     {
-      link_add1[0] = (int*) Malloc(src_grid_size*sizeof(int));
-      link_add1[1] = (int*) Malloc(src_grid_size*sizeof(int));
-      link_add2[0] = (int*) Malloc(tgt_grid_size*sizeof(int));
-      link_add2[1] = (int*) Malloc(tgt_grid_size*sizeof(int));
+      link_add1[0] = (long*) Malloc(src_grid_size*sizeof(long));
+      link_add1[1] = (long*) Malloc(src_grid_size*sizeof(long));
+      link_add2[0] = (long*) Malloc(tgt_grid_size*sizeof(long));
+      link_add2[1] = (long*) Malloc(tgt_grid_size*sizeof(long));
 
 #if defined(SX)
 #pragma vdir nodep
 #endif
-      for ( n = 0; n < src_grid_size; ++n )
+      for ( long n = 0; n < src_grid_size; ++n )
 	{
 	  link_add1[0][n] = -1;
 	  link_add1[1][n] = -1;
@@ -1323,7 +1284,7 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 #if defined(SX)
 #pragma vdir nodep
 #endif
-      for ( n = 0; n < tgt_grid_size; ++n )
+      for ( long n = 0; n < tgt_grid_size; ++n )
 	{
 	  link_add2[0][n] = -1;
 	  link_add2[1][n] = -1;
@@ -1337,35 +1298,33 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
   double *tgt_centroid_lat = (double*) Malloc(tgt_grid_size*sizeof(double));
   double *tgt_centroid_lon = (double*) Malloc(tgt_grid_size*sizeof(double));
 
-  for ( n = 0; n < src_grid_size; ++n )
+  for ( long n = 0; n < src_grid_size; ++n )
     {
       src_centroid_lat[n] = 0;
       src_centroid_lon[n] = 0;
     }
 
-  for ( n = 0; n < tgt_grid_size; ++n )
+  for ( long n = 0; n < tgt_grid_size; ++n )
     {
       tgt_centroid_lat[n] = 0;
       tgt_centroid_lon[n] = 0;
     }
 
-  std::vector<double *> srch_corner_lat2(ompNumThreads);
-  std::vector<double *> srch_corner_lon2(ompNumThreads);
-  std::vector<long> max_srch_cells2(ompNumThreads);
+  std::vector<double *> srch_corner_lat(ompNumThreads); // lat of each corner of srch cells
+  std::vector<double *> srch_corner_lon(ompNumThreads); // lon of each corner of srch cells
+  std::vector<long> max_srch_cells(ompNumThreads);      // num cells in restricted search arrays
 
   /*  Integrate around each cell on source grid */
 
   for ( i = 0; i < ompNumThreads; ++i )
     {
-      srch_corner_lat2[i] = NULL;
-      srch_corner_lon2[i] = NULL;
+      srch_corner_lat[i] = NULL;
+      srch_corner_lon[i] = NULL;
+      max_srch_cells[i] = 0;
     }
 
-  for ( i = 0; i < ompNumThreads; ++i )
-    max_srch_cells2[i] = 0;
-
-  for ( i = 0; i < ompNumThreads; ++i )
-    srch_add2[i] = (int*) Malloc(tgt_grid_size*sizeof(int));
+  std::vector<size_t *> srch_add(ompNumThreads);  // global address of cells in srch arrays
+  for ( i = 0; i < ompNumThreads; ++i ) srch_add[i] = new size_t[tgt_grid_size];
 
   srch_corners = tgt_num_cell_corners;
 
@@ -1375,15 +1334,10 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 #pragma omp parallel for default(none) \
   shared(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_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)
+	 srch_corner_lat, srch_corner_lon, max_srch_cells, 		\
+	 src_num_cell_corners,	srch_corners, src_grid, tgt_grid, tgt_grid_size, src_grid_size, srch_add, findex)
 #endif
-  for ( src_cell_add = 0; src_cell_add < src_grid_size; ++src_cell_add )
+  for ( long src_cell_add = 0; src_cell_add < src_grid_size; ++src_cell_add )
     {
       int ompthID = cdo_omp_get_thread_num();
 
@@ -1393,66 +1347,59 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
       findex++;
       if ( ompthID == 0 ) progressStatus(0, 0.5, findex/src_grid_size);
 
-      srch_add = srch_add2[ompthID];
-
-      lthresh   = FALSE;
-      luse_last = FALSE;
-      avoid_pole_count  = 0;
-      avoid_pole_offset = TINY;
-
-      /* Get search cells */
-      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);
+      bool lcoinc;                     // flag for coincident segments
+      bool lthresh   = false;
+      bool luse_last = false;
+      int avoid_pole_count  = 0;       // count attempts to avoid pole
+      double avoid_pole_offset = TINY; // endpoint offset to avoid pole
+      double intrsct_lat, intrsct_lon; // lat/lon of next intersect
+      double intrsct_lat_off = 0, intrsct_lon_off = 0; // lat/lon coords offset for next search
+      double intrsct_x, intrsct_y;     // x,y for intersection
+      long last_loc = -1;              // save location when crossing threshold
+      long tgt_cell_add;
+
+      // Get search cells
+      long 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[ompthID]);
 
       if ( num_srch_cells == 0 ) continue;
 
-      /* Create search arrays */
-
-      max_srch_cells  = max_srch_cells2[ompthID];
-      srch_corner_lat = srch_corner_lat2[ompthID];
-      srch_corner_lon = srch_corner_lon2[ompthID];
-
-      if ( num_srch_cells > max_srch_cells )
+      // Create search arrays
+      if ( num_srch_cells > max_srch_cells[ompthID] )
 	{
-          srch_corner_lat = (double*) realloc(srch_corner_lat, srch_corners*num_srch_cells*sizeof(double));
-	  srch_corner_lon = (double*) realloc(srch_corner_lon, srch_corners*num_srch_cells*sizeof(double));
-
-	  max_srch_cells  = num_srch_cells;
-
-	  max_srch_cells2[ompthID]  = max_srch_cells;
-	  srch_corner_lat2[ompthID] = srch_corner_lat;
-	  srch_corner_lon2[ompthID] = srch_corner_lon;
+          srch_corner_lat[ompthID] = (double*) realloc(srch_corner_lat[ompthID], srch_corners*num_srch_cells*sizeof(double));
+	  srch_corner_lon[ompthID] = (double*) realloc(srch_corner_lon[ompthID], srch_corners*num_srch_cells*sizeof(double));
+	  max_srch_cells[ompthID]  = num_srch_cells;
 	}
 
-      /* gather1 */
-      for ( n = 0; n < num_srch_cells; ++n )
+      // gather1
+      long ioffset;
+      for ( long n = 0; n < num_srch_cells; ++n )
 	{
-	  tgt_cell_add = srch_add[n];
+	  tgt_cell_add = srch_add[ompthID][n];
 	  ioffset = tgt_cell_add*srch_corners;
 
-	  nsrch_corners = n*srch_corners;
-	  for ( k = 0; k < srch_corners; k++ )
+	  long nsrch_corners = n*srch_corners;
+	  for ( long k = 0; k < srch_corners; k++ )
 	    {
-	      srch_corner_lat[nsrch_corners+k] = tgt_grid->cell_corner_lat[ioffset+k];
-	      srch_corner_lon[nsrch_corners+k] = tgt_grid->cell_corner_lon[ioffset+k];
+	      srch_corner_lat[ompthID][nsrch_corners+k] = tgt_grid->cell_corner_lat[ioffset+k];
+	      srch_corner_lon[ompthID][nsrch_corners+k] = tgt_grid->cell_corner_lon[ioffset+k];
 	    }
 	}
 
-      /* Integrate around this cell */
-
+      // Integrate around this cell
       ioffset = src_cell_add*src_num_cell_corners;
-
-      for ( corner = 0; corner < src_num_cell_corners; ++corner )
+      for ( long corner = 0; corner < src_num_cell_corners; ++corner )
 	{
-          next_corn = (corner+1)%src_num_cell_corners;
+          long next_corn = (corner+1)%src_num_cell_corners;
 
           /* Define endpoints of the current segment */
 
-          beglat = src_grid->cell_corner_lat[ioffset+corner];
-          beglon = src_grid->cell_corner_lon[ioffset+corner];
-          endlat = src_grid->cell_corner_lat[ioffset+next_corn];
-          endlon = src_grid->cell_corner_lon[ioffset+next_corn];
-          lrevers = FALSE;
+          double beglat = src_grid->cell_corner_lat[ioffset+corner];
+          double beglon = src_grid->cell_corner_lon[ioffset+corner];
+          double endlat = src_grid->cell_corner_lat[ioffset+next_corn];
+          double endlon = src_grid->cell_corner_lon[ioffset+next_corn];
+          bool lrevers = false;
 
 	  /*  To ensure exact path taken during both sweeps, always integrate segments in the same direction (SW to NE). */
           if ( (endlat < beglat) || (IS_EQUAL(endlat, beglat) && endlon < beglon) )
@@ -1461,7 +1408,7 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 	      beglon = src_grid->cell_corner_lon[ioffset+next_corn];
 	      endlat = src_grid->cell_corner_lat[ioffset+corner];
 	      endlon = src_grid->cell_corner_lon[ioffset+corner];
-	      lrevers = TRUE;
+	      lrevers = true;
 	    }
 
           /*
@@ -1470,11 +1417,13 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
           */
           if ( IS_EQUAL(endlon, beglon) ) continue;
 
+          double weights[6];        // local wgt array
+          double begseg[2];         // begin lat/lon for full segment
           begseg[0] = beglat;
           begseg[1] = beglon;
-          lbegin = TRUE;
+          bool lbegin = true;
 
-	  num_subseg = 0;
+	  long num_subseg = 0;
 	  /*
 	    Integrate along this segment, detecting intersections 
 	    and computing the line integral for each sub-segment
@@ -1504,13 +1453,13 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 	      intersection(&tgt_cell_add, &intrsct_lat, &intrsct_lon, &lcoinc,
 			   beglat, beglon, endlat, endlon, begseg, 
 			   lbegin, lrevers,
-			   num_srch_cells, srch_corners, srch_add,
-			   srch_corner_lat, srch_corner_lon,
+			   num_srch_cells, srch_corners, srch_add[ompthID],
+			   srch_corner_lat[ompthID], srch_corner_lon[ompthID],
 			   &last_loc, &lthresh, &intrsct_lat_off, &intrsct_lon_off,
 			   &luse_last, &intrsct_x, &intrsct_y,
 			   &avoid_pole_count, &avoid_pole_offset);
 
-	      lbegin = FALSE;
+	      lbegin = false;
 
 	      /* Compute line integral for this subsegment. */
 
@@ -1523,7 +1472,7 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 
 	      /* If integrating in reverse order, change sign of weights */
 
-	      if ( lrevers ) for ( k = 0; k < 6; ++k ) weights[k] = -weights[k];
+	      if ( lrevers ) for ( long k = 0; k < 6; ++k ) weights[k] = -weights[k];
 
 	      /*
 		Store the appropriate addresses and weights. 
@@ -1564,31 +1513,25 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 
   for ( i = 0; i < ompNumThreads; ++i )
     {
-      free(srch_corner_lon2[i]);
-      free(srch_corner_lat2[i]);
+      free(srch_corner_lon[i]);
+      free(srch_corner_lat[i]);
     }
 
-  for ( i = 0; i < ompNumThreads; ++i )
-    Free(srch_add2[i]);
+  for ( i = 0; i < ompNumThreads; ++i ) delete[] srch_add[i];
 
   /* Integrate around each cell on target grid */
 
   for ( i = 0; i < ompNumThreads; ++i )
     {
-      srch_corner_lat2[i] = NULL;
-      srch_corner_lon2[i] = NULL;
+      srch_corner_lat[i] = NULL;
+      srch_corner_lon[i] = NULL;
     }
 
-  for ( i = 0; i < ompNumThreads; ++i )
-    max_srch_cells2[i] = 0;
+  for ( i = 0; i < ompNumThreads; ++i ) max_srch_cells[i] = 0;
 
-  for ( i = 0; i < ompNumThreads; ++i )
-    srch_add2[i] = (int*) Malloc(src_grid_size*sizeof(int));
+  for ( i = 0; i < ompNumThreads; ++i ) srch_add[i] = new size_t[src_grid_size];
 
-  srch_corners    = src_num_cell_corners;
-  max_srch_cells  = 0;
-  srch_corner_lat = NULL;
-  srch_corner_lon = NULL;
+  srch_corners  = src_num_cell_corners;
 
   if ( cdoTimer ) timer_start(timer_remap_con_l2);
 
@@ -1598,15 +1541,10 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 #pragma omp parallel for default(none) \
   shared(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_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)
+	 srch_corner_lat, srch_corner_lon, max_srch_cells, 		\
+	 tgt_num_cell_corners, srch_corners, src_grid, tgt_grid, tgt_grid_size, src_grid_size, srch_add, findex)
 #endif
-  for ( tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
+  for ( long tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
     {
       int ompthID = cdo_omp_get_thread_num();
 
@@ -1616,66 +1554,58 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
       findex++;
       if ( ompthID == 0 ) progressStatus(0.5, 0.5, findex/tgt_grid_size);
 
-      srch_add = srch_add2[ompthID];
-
-      lthresh   = FALSE;
-      luse_last = FALSE;
-      avoid_pole_count  = 0;
-      avoid_pole_offset = TINY;
-
-      /* Get search cells */
-      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);
+      bool lcoinc;                     // flag for coincident segments
+      bool lthresh   = false;
+      bool luse_last = false;
+      int avoid_pole_count  = 0;       // count attempts to avoid pole
+      double avoid_pole_offset = TINY; // endpoint offset to avoid pole
+      double intrsct_lat, intrsct_lon; // lat/lon of next intersect
+      double intrsct_lat_off = 0, intrsct_lon_off = 0; // lat/lon coords offset for next search
+      double intrsct_x, intrsct_y;     // x,y for intersection
+      long last_loc = -1;              // save location when crossing threshold
+      long src_cell_add;
+
+      // Get search cells
+      long 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[ompthID]);
 
       if ( num_srch_cells == 0 ) continue;
 
-      /* Create search arrays */
-      
-      max_srch_cells  = max_srch_cells2[ompthID];
-      srch_corner_lat = srch_corner_lat2[ompthID];
-      srch_corner_lon = srch_corner_lon2[ompthID];
-
-      if ( num_srch_cells > max_srch_cells )
+      // Create search arrays
+      if ( num_srch_cells > max_srch_cells[ompthID] )
 	{
-	  srch_corner_lat = (double*) realloc(srch_corner_lat, srch_corners*num_srch_cells*sizeof(double));
-	  srch_corner_lon = (double*) realloc(srch_corner_lon, srch_corners*num_srch_cells*sizeof(double));
-
-	  max_srch_cells  = num_srch_cells;
-
-	  max_srch_cells2[ompthID]  = max_srch_cells;
-	  srch_corner_lat2[ompthID] = srch_corner_lat;
-	  srch_corner_lon2[ompthID] = srch_corner_lon;
+	  srch_corner_lat[ompthID] = (double*) realloc(srch_corner_lat[ompthID], srch_corners*num_srch_cells*sizeof(double));
+	  srch_corner_lon[ompthID] = (double*) realloc(srch_corner_lon[ompthID], srch_corners*num_srch_cells*sizeof(double));
+	  max_srch_cells[ompthID]  = num_srch_cells;
 	}
 
-      /* gather2 */
-      for ( n = 0; n < num_srch_cells; ++n )
+      // gather2
+      long ioffset;
+      for ( long n = 0; n < num_srch_cells; ++n )
 	{
-	  src_cell_add = srch_add[n];
+	  src_cell_add = srch_add[ompthID][n];
 	  ioffset = src_cell_add*srch_corners;
 
-	  nsrch_corners = n*srch_corners;
-	  for ( k = 0; k < srch_corners; ++k )
+	  long nsrch_corners = n*srch_corners;
+	  for ( long k = 0; k < srch_corners; ++k )
 	    {
-	      srch_corner_lat[nsrch_corners+k] = src_grid->cell_corner_lat[ioffset+k];
-	      srch_corner_lon[nsrch_corners+k] = src_grid->cell_corner_lon[ioffset+k];
+	      srch_corner_lat[ompthID][nsrch_corners+k] = src_grid->cell_corner_lat[ioffset+k];
+	      srch_corner_lon[ompthID][nsrch_corners+k] = src_grid->cell_corner_lon[ioffset+k];
 	    }
 	}
 
-      /* Integrate around this cell */
-
+      // Integrate around this cell
       ioffset = tgt_cell_add*tgt_num_cell_corners;
-
-      for ( corner = 0; corner < tgt_num_cell_corners; ++corner )
+      for ( long corner = 0; corner < tgt_num_cell_corners; ++corner )
 	{
-          next_corn = (corner+1)%tgt_num_cell_corners;
+          long next_corn = (corner+1)%tgt_num_cell_corners;
 
           /* Define endpoints of the current segment */
-
-          beglat = tgt_grid->cell_corner_lat[ioffset+corner];
-          beglon = tgt_grid->cell_corner_lon[ioffset+corner];
-          endlat = tgt_grid->cell_corner_lat[ioffset+next_corn];
-          endlon = tgt_grid->cell_corner_lon[ioffset+next_corn];
-          lrevers = FALSE;
+          double beglat = tgt_grid->cell_corner_lat[ioffset+corner];
+          double beglon = tgt_grid->cell_corner_lon[ioffset+corner];
+          double endlat = tgt_grid->cell_corner_lat[ioffset+next_corn];
+          double endlon = tgt_grid->cell_corner_lon[ioffset+next_corn];
+          bool lrevers = false;
 
 	  /* To ensure exact path taken during both sweeps, always integrate in the same direction */
           if ( (endlat < beglat) || (IS_EQUAL(endlat, beglat) && endlon < beglon) )
@@ -1684,7 +1614,7 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 	      beglon = tgt_grid->cell_corner_lon[ioffset+next_corn];
 	      endlat = tgt_grid->cell_corner_lat[ioffset+corner];
 	      endlon = tgt_grid->cell_corner_lon[ioffset+corner];
-	      lrevers = TRUE;
+	      lrevers = true;
 	    }
 
           /*
@@ -1693,11 +1623,13 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
           */
           if ( IS_EQUAL(endlon, beglon) ) continue;
 
+          double weights[6];        // local wgt array
+          double begseg[2];         // begin lat/lon for full segment
           begseg[0] = beglat;
           begseg[1] = beglon;
-          lbegin = TRUE;
+          bool lbegin = true;
 
-	  num_subseg = 0;
+	  long num_subseg = 0;
 	  /*
 	    Integrate along this segment, detecting intersections 
 	    and computing the line integral for each sub-segment
@@ -1727,13 +1659,13 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 	      intersection(&src_cell_add, &intrsct_lat, &intrsct_lon, &lcoinc,
 			   beglat, beglon, endlat, endlon, begseg,
 			   lbegin, lrevers,
-			   num_srch_cells, srch_corners, srch_add,
-			   srch_corner_lat, srch_corner_lon,
+			   num_srch_cells, srch_corners, srch_add[ompthID],
+			   srch_corner_lat[ompthID], srch_corner_lon[ompthID],
 			   &last_loc, &lthresh, &intrsct_lat_off, &intrsct_lon_off,
 			   &luse_last, &intrsct_x, &intrsct_y,
 			   &avoid_pole_count, &avoid_pole_offset);
 
-	      lbegin = FALSE;
+	      lbegin = false;
 
 	      /* Compute line integral for this subsegment. */
 
@@ -1746,7 +1678,7 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 
 	      /* If integrating in reverse order, change sign of weights */
 
-	      if ( lrevers ) for ( k = 0; k < 6; ++k ) weights[k] = -weights[k];
+	      if ( lrevers ) for ( long k = 0; k < 6; ++k ) weights[k] = -weights[k];
 
 	      /*
 		Store the appropriate addresses and weights. 
@@ -1790,12 +1722,11 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 
   for ( i = 0; i < ompNumThreads; ++i )
     {
-      free(srch_corner_lon2[i]);
-      free(srch_corner_lat2[i]);
+      free(srch_corner_lon[i]);
+      free(srch_corner_lat[i]);
     }
 
-  for ( i = 0; i < ompNumThreads; ++i )
-    Free(srch_add2[i]);
+  for ( i = 0; i < ompNumThreads; ++i ) delete[] srch_add[i];
 
   /*
      Correct for situations where N/S pole not explicitly included in
@@ -1818,14 +1749,14 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 
   /* Finish centroid computation */
 
-  for ( n = 0; n < src_grid_size; ++n )
+  for ( long n = 0; n < src_grid_size; ++n )
     if ( IS_NOT_EQUAL(src_grid->cell_area[n], 0) )
       {
         src_centroid_lat[n] /= src_grid->cell_area[n];
         src_centroid_lon[n] /= src_grid->cell_area[n];
       }
 
-  for ( n = 0; n < tgt_grid_size; ++n )
+  for ( long n = 0; n < tgt_grid_size; ++n )
     if ( IS_NOT_EQUAL(tgt_grid->cell_area[n], 0) )
       {
         tgt_centroid_lat[n] /= tgt_grid->cell_area[n];
@@ -1840,10 +1771,10 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
       num_links = rv->num_links;
 
       if ( cdoVerbose )
-	for ( n = 0; n < num_links; n++ )
+	for ( long n = 0; n < num_links; n++ )
 	  printf("wts1: %d %g\n", n, rv->wts[3*n]);
 
-      for ( n = 0; n < num_links; n++ )
+      for ( long n = 0; n < num_links; n++ )
 	{
 	  if ( rv->wts[3*n] < 0 )
 	    {
@@ -1866,7 +1797,7 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 	    }
 	}
 
-     if ( cdoVerbose ) cdoPrint("Removed number of links = %ld", rv->num_links - num_links);
+     if ( cdoVerbose ) cdoPrint("Removed number of links = %zu", rv->num_links - num_links);
 
       rv->num_links = num_links;
     }
@@ -1875,15 +1806,15 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
   /* Include centroids in weights and normalize using destination area if requested */
   normalize_weights(tgt_grid, rv, src_centroid_lat, src_centroid_lon);
 
-  num_links = rv->num_links;
+  long num_links = rv->num_links;
 
   if ( cdoVerbose )
-    cdoPrint("Total number of links = %ld", rv->num_links);
+    cdoPrint("Total number of links = %zu", rv->num_links);
 
-  for ( n = 0; n < src_grid_size; ++n )
+  for ( long n = 0; n < src_grid_size; ++n )
     if ( IS_NOT_EQUAL(src_grid->cell_area[n], 0) ) src_grid->cell_frac[n] /= src_grid->cell_area[n];
 
-  for ( n = 0; n < tgt_grid_size; ++n )
+  for ( long n = 0; n < tgt_grid_size; ++n )
     if ( IS_NOT_EQUAL(tgt_grid->cell_area[n], 0) ) tgt_grid->cell_frac[n] /= tgt_grid->cell_area[n];
 
   /* Perform some error checking on final weights  */
@@ -1893,7 +1824,7 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
       remapCheckArea(src_grid_size, src_grid->cell_area, "Source");
       remapCheckArea(tgt_grid_size, tgt_grid->cell_area, "Target");
 
-      for ( n = 0; n < src_grid_size; ++n )
+      for ( long n = 0; n < src_grid_size; ++n )
 	{
 	  if ( src_centroid_lat[n] < -PIH-.01 || src_centroid_lat[n] > PIH+.01 )
 	    cdoPrint("Source grid centroid lat error: %d %g", n, src_centroid_lat[n]);
@@ -1902,7 +1833,7 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 	  src_centroid_lon[n] = 0;
 	}
 
-      for ( n = 0; n < tgt_grid_size; ++n )
+      for ( long n = 0; n < tgt_grid_size; ++n )
 	{
 	  if ( tgt_centroid_lat[n] < -PIH-.01 || tgt_centroid_lat[n] > PIH+.01 )
 	    cdoPrint("Target grid centroid lat error: %d %g", n, tgt_centroid_lat[n]);
@@ -1913,14 +1844,15 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 
       remapCheckWeights(num_links, 3, rv->norm_opt, rv->src_cell_add, rv->tgt_cell_add, rv->wts);
 
-      for ( n = 0; n < num_links; ++n )
+      for ( long n = 0; n < num_links; ++n )
 	{
-	  tgt_cell_add = rv->tgt_cell_add[n];
+	  long 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_cell_add] to [n] (bug fix) */
-      for ( n = 0; n < tgt_grid_size; ++n )
+      double norm_factor = 0;    // factor for normalizing wts
+      for ( long n = 0; n < tgt_grid_size; ++n )
 	{
 	  if ( rv->norm_opt == NORM_OPT_DESTAREA )
 	    norm_factor = tgt_grid->cell_frac[n];
@@ -1949,4 +1881,4 @@ void scrip_remap_conserv_weights(remapgrid_t *src_grid, remapgrid_t *tgt_grid, r
 
   if ( cdoTimer ) timer_stop(timer_remap_con);
 
-} /* remap_conserv */
+} // remap_conserv_scrip
diff --git a/src/remap_distwgt.cc b/src/remap_distwgt.cc
index c2546b5..0a9407a 100644
--- a/src/remap_distwgt.cc
+++ b/src/remap_distwgt.cc
@@ -12,7 +12,7 @@
 //  Interpolation using a distance-weighted average
 
 static
-void nbr_store_distance(int nadd, double distance, int num_neighbors, int *restrict nbr_add, double *restrict nbr_dist)
+void nbr_store_distance(size_t nadd, double distance, size_t num_neighbors, size_t *restrict nbr_add, double *restrict nbr_dist)
 {
   if ( num_neighbors == 1 )
     {
@@ -24,11 +24,11 @@ void nbr_store_distance(int nadd, double distance, int num_neighbors, int *restr
     }
   else
     {
-      for ( int nchk = 0; nchk < num_neighbors; ++nchk )
+      for ( size_t nchk = 0; nchk < num_neighbors; ++nchk )
 	{
 	  if ( distance < nbr_dist[nchk] || (distance <= nbr_dist[nchk] && nadd < nbr_add[nchk]) )
 	    {
-	      for ( int n = num_neighbors-1; n > nchk; --n )
+	      for ( size_t n = num_neighbors-1; n > nchk; --n )
 		{
 		  nbr_add[n]  = nbr_add[n-1];
 		  nbr_dist[n] = nbr_dist[n-1];
@@ -42,15 +42,15 @@ void nbr_store_distance(int nadd, double distance, int num_neighbors, int *restr
 }
 
 static
-void nbr_check_distance(unsigned num_neighbors, const int *restrict nbr_add, double *restrict nbr_dist)
+void nbr_check_distance(size_t num_neighbors, const size_t *restrict nbr_add, double *restrict nbr_dist)
 {
   // If distance is zero, set to small number
-  for ( unsigned nchk = 0; nchk < num_neighbors; ++nchk )
-    if ( nbr_add[nchk] >= 0 && nbr_dist[nchk] <= 0. ) nbr_dist[nchk] = TINY;
+  for ( size_t nchk = 0; nchk < num_neighbors; ++nchk )
+    if ( nbr_add[nchk] < ULONG_MAX && nbr_dist[nchk] <= 0. ) nbr_dist[nchk] = TINY;
 }
 
 
-double nbr_compute_weights(unsigned num_neighbors, const int *restrict src_grid_mask, bool *restrict nbr_mask, const int *restrict nbr_add, double *restrict nbr_dist)
+double nbr_compute_weights(size_t num_neighbors, const int *restrict src_grid_mask, bool *restrict nbr_mask, const size_t *restrict nbr_add, double *restrict nbr_dist)
 {
   // Compute weights based on inverse distance if mask is false, eliminate those points
 
@@ -58,10 +58,10 @@ double nbr_compute_weights(unsigned num_neighbors, const int *restrict src_grid_
 
   if ( src_grid_mask )
     {
-      for ( unsigned n = 0; n < num_neighbors; ++n )
+      for ( size_t n = 0; n < num_neighbors; ++n )
         {
           nbr_mask[n] = false;
-          if ( nbr_add[n] >= 0 )
+          if ( nbr_add[n] < ULONG_MAX )
             if ( src_grid_mask[nbr_add[n]] )
               {
                 nbr_dist[n] = 1./nbr_dist[n];
@@ -72,10 +72,10 @@ double nbr_compute_weights(unsigned num_neighbors, const int *restrict src_grid_
     }
   else
     {
-      for ( unsigned n = 0; n < num_neighbors; ++n )
+      for ( size_t n = 0; n < num_neighbors; ++n )
         {
           nbr_mask[n] = false;
-          if ( nbr_add[n] >= 0 )
+          if ( nbr_add[n] < ULONG_MAX )
             {
               nbr_dist[n] = 1./nbr_dist[n];
               dist_tot += nbr_dist[n];
@@ -83,18 +83,19 @@ double nbr_compute_weights(unsigned num_neighbors, const int *restrict src_grid_
             }
         }
     }
+  
 
   return dist_tot;
 }
 
 
-unsigned nbr_normalize_weights(unsigned num_neighbors, double dist_tot, const bool *restrict nbr_mask, int *restrict nbr_add, double *restrict nbr_dist)
+size_t nbr_normalize_weights(size_t num_neighbors, double dist_tot, const bool *restrict nbr_mask, size_t *restrict nbr_add, double *restrict nbr_dist)
 {
   // Normalize weights and store the link
 
-  unsigned nadds = 0;
+  size_t nadds = 0;
 
-  for ( unsigned n = 0; n < num_neighbors; ++n )
+  for ( size_t n = 0; n < num_neighbors; ++n )
     {
       if ( nbr_mask[n] )
         {
@@ -112,7 +113,7 @@ unsigned nbr_normalize_weights(unsigned num_neighbors, double dist_tot, const bo
 
 #define MAX_SEARCH_CELLS 25
 static
-void grid_search_nbr_reg2d(struct gridsearch *gs, int num_neighbors, remapgrid_t *src_grid, int *restrict nbr_add, double *restrict nbr_dist, 
+void grid_search_nbr_reg2d(struct gridsearch *gs, size_t num_neighbors, remapgrid_t *src_grid, size_t *restrict nbr_add, double *restrict nbr_dist, 
 			   double plon, double plat, const int *restrict src_grid_dims)
 {
   /*
@@ -126,13 +127,13 @@ void grid_search_nbr_reg2d(struct gridsearch *gs, int num_neighbors, remapgrid_t
     double plat,         ! latitude  of the search point
     double plon,         ! longitude of the search point
   */
-  int n, nadd;
-  long ii, jj;
-  int i, j, ix;
-  int src_add[MAX_SEARCH_CELLS];
-  int *src_add_tmp = NULL;
-  int *psrc_add = src_add;
-  int num_add = 0;
+  size_t n, nadd;
+  size_t ii, jj;
+  long i, j, ix;
+  size_t src_add[MAX_SEARCH_CELLS];
+  size_t *src_add_tmp = NULL;
+  size_t *psrc_add = src_add;
+  size_t num_add = 0;
   double distance;   //  Angular distance
   double cos_search_radius = cos(gs->search_radius);
   double coslat_dst = cos(plat);  // cos(lat)  of the search point
@@ -149,7 +150,7 @@ void grid_search_nbr_reg2d(struct gridsearch *gs, int num_neighbors, remapgrid_t
   long nx = src_grid_dims[0];
   long ny = src_grid_dims[1];
 
-  long nxm = nx;
+  size_t nxm = nx;
   if ( src_grid->is_cyclic ) nxm++;
 
   if ( plon < src_center_lon[0]     ) plon += PI2;
@@ -165,14 +166,14 @@ void grid_search_nbr_reg2d(struct gridsearch *gs, int num_neighbors, remapgrid_t
       for ( k = 3; k < 10000; k+=2 )
         if ( num_neighbors <= ((k-2)*(k-2)) ) break;
 
-      if ( (k*k) > MAX_SEARCH_CELLS ) psrc_add = src_add_tmp = (int *) Malloc(k*k*sizeof(int));
+      if ( (k*k) > MAX_SEARCH_CELLS ) psrc_add = src_add_tmp = (size_t *) Malloc(k*k*sizeof(size_t));
 
       k /= 2;
 
-      int j0 = jj-k;
-      int jn = jj+k;
-      int i0 = ii-k;
-      int in = ii+k;
+      long j0 = jj-k;
+      long jn = jj+k;
+      long i0 = ii-k;
+      long in = ii+k;
       if ( j0 < 0 ) j0 = 0;
       if ( jn >= ny ) jn = ny-1;
       if ( (in-i0) > nx ) { i0 = 0; in = nx-1; }
@@ -196,15 +197,15 @@ void grid_search_nbr_reg2d(struct gridsearch *gs, int num_neighbors, remapgrid_t
   // Initialize distance and address arrays
   for ( n = 0; n < num_neighbors; ++n )
     {
-      nbr_add[n]  = -1;
+      nbr_add[n]  = ULONG_MAX;
       nbr_dist[n] = BIGNUM;
     }
 
   if ( lfound )
     {
-      int ix, iy;
+      size_t ix, iy;
 
-      for ( int na = 0; na < num_add; ++na )
+      for ( size_t na = 0; na < num_add; ++na )
 	{
 	  nadd = psrc_add[na];
 
@@ -237,14 +238,14 @@ void grid_search_nbr_reg2d(struct gridsearch *gs, int num_neighbors, remapgrid_t
 
       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);
+	  size_t nbr_add4[4];
+	  double nbr_dist4[4];
+	  for ( n = 0; n < num_neighbors; ++n ) nbr_add4[n] = ULONG_MAX;
+	  search_result = grid_search_reg2d_nn(nx, ny, nbr_add4, nbr_dist4, 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];
+	      for ( n = 0; n < num_neighbors; ++n ) nbr_add[n]  = nbr_add4[n];
+	      for ( n = 0; n < num_neighbors; ++n ) nbr_dist[n] = nbr_dist4[n];
 	    }
 	}
       else
@@ -253,12 +254,12 @@ void grid_search_nbr_reg2d(struct gridsearch *gs, int num_neighbors, remapgrid_t
 	}
 
       if ( search_result >= 0 )
-	for ( n = 0; n < num_neighbors; ++n ) nbr_add[n] = -1;
+	for ( n = 0; n < num_neighbors; ++n ) nbr_add[n] = ULONG_MAX;
     }
 } // grid_search_nbr_reg2d
 
 
-int grid_search_nbr(struct gridsearch *gs, int num_neighbors, int *restrict nbr_add, double *restrict nbr_dist, double plon, double plat)
+int grid_search_nbr(struct gridsearch *gs, size_t num_neighbors, size_t *restrict nbr_add, double *restrict nbr_dist, double plon, double plat)
 {
   /*
     Output variables:
@@ -275,33 +276,33 @@ int grid_search_nbr(struct gridsearch *gs, int num_neighbors, int *restrict nbr_
   double search_radius = gs->search_radius;
 
   // Initialize distance and address arrays
-  for ( int n = 0; n < num_neighbors; ++n ) nbr_add[n]  = -1;
-  for ( int n = 0; n < num_neighbors; ++n ) nbr_dist[n] = BIGNUM;
+  for ( size_t n = 0; n < num_neighbors; ++n ) nbr_add[n]  = ULONG_MAX;
+  for ( size_t n = 0; n < num_neighbors; ++n ) nbr_dist[n] = BIGNUM;
 
-  int ndist = num_neighbors;
+  size_t ndist = num_neighbors;
   // check some more points if distance is the same use the smaller index (nadd)
   if ( ndist > 8 ) ndist += 8;
   else             ndist *= 2; 
-  if ( ndist > (int)gs->n ) ndist = gs->n;
+  if ( ndist > gs->n ) ndist = gs->n;
 
   double zdist[32];
-  int zadds[32];
+  size_t zadds[32];
   double *dist = zdist;
-  int *adds = zadds;
+  size_t *adds = zadds;
   if ( num_neighbors > 16 )
     {
       dist = (double*) Malloc(ndist*sizeof(double));
-      adds = (int*) Malloc(ndist*sizeof(int));
+      adds = (size_t*) Malloc(ndist*sizeof(size_t));
     }
   
   const double range0 = SQR(search_radius);
   double range = range0;
 
-  int j = 0;
+  size_t j = 0;
 
   if ( num_neighbors == 1 )
     {
-      unsigned nadd = gridsearch_nearest(gs, plon, plat, &range);
+      size_t nadd = gridsearch_nearest(gs, plon, plat, &range);
       if ( nadd != GS_NOT_FOUND )
         {
           //if ( range < range0 )
@@ -317,7 +318,7 @@ int grid_search_nbr(struct gridsearch *gs, int num_neighbors, int *restrict nbr_
       struct pqueue *gs_result = gridsearch_qnearest(gs, plon, plat, &range, ndist);
       if ( gs_result )
         {
-          unsigned nadd;
+          size_t nadd;
           struct resItem *p;
           while ( pqremove_min(gs_result, &p) )
             {
@@ -338,7 +339,7 @@ int grid_search_nbr(struct gridsearch *gs, int num_neighbors, int *restrict nbr_
     }
 
   ndist = j;
-  int max_neighbors = ( ndist < num_neighbors ) ? ndist : num_neighbors;
+  size_t max_neighbors = (ndist < num_neighbors) ? ndist : num_neighbors;
 
   for ( j = 0; j < ndist; ++j )
     nbr_store_distance(adds[j], dist[j], max_neighbors, nbr_add, nbr_dist);
@@ -358,7 +359,7 @@ int grid_search_nbr(struct gridsearch *gs, int num_neighbors, int *restrict nbr_
 
 //  This routine computes the inverse-distance weights for a nearest-neighbor interpolation.
 
-void remap_distwgt_weights(unsigned num_neighbors, remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv)
+void remap_distwgt_weights(size_t num_neighbors, remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv)
 {
   int remap_grid_type = src_grid->remap_grid_type;
 
@@ -368,20 +369,20 @@ void remap_distwgt_weights(unsigned num_neighbors, remapgrid_t *src_grid, remapg
 
   // Compute mappings from source to target grid
 
-  unsigned src_grid_size = src_grid->size;
-  unsigned tgt_grid_size = tgt_grid->size;
-  unsigned nx = src_grid->dims[0];
-  unsigned ny = src_grid->dims[1];
+  size_t src_grid_size = src_grid->size;
+  size_t tgt_grid_size = tgt_grid->size;
+  size_t nx = src_grid->dims[0];
+  size_t ny = src_grid->dims[1];
   bool lcyclic = src_grid->is_cyclic;
 
   weightlinks_t *weightlinks = (weightlinks_t *) Malloc(tgt_grid_size*sizeof(weightlinks_t));
   weightlinks[0].addweights = (addweight_t *) Malloc(num_neighbors*tgt_grid_size*sizeof(addweight_t));
-  for ( unsigned tgt_cell_add = 1; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
+  for ( size_t tgt_cell_add = 1; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
     weightlinks[tgt_cell_add].addweights = weightlinks[0].addweights + num_neighbors*tgt_cell_add;
 
-  bool nbr_mask[num_neighbors];   // mask at nearest neighbors
-  int nbr_add[num_neighbors];     // source address at nearest neighbors
-  double nbr_dist[num_neighbors]; // angular distance four nearest neighbors
+  NEW_2D(bool, nbr_mask, ompNumThreads, num_neighbors);   // mask at nearest neighbors
+  NEW_2D(size_t, nbr_add, ompNumThreads, num_neighbors);  // source address at nearest neighbors
+  NEW_2D(double, nbr_dist, ompNumThreads, num_neighbors); // angular distance four nearest neighbors
 
 #if defined(_OPENMP)
   double start = 0;
@@ -408,9 +409,9 @@ void remap_distwgt_weights(unsigned num_neighbors, remapgrid_t *src_grid, remapg
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) \
   shared(gs, weightlinks, num_neighbors, remap_grid_type, src_grid, tgt_grid, tgt_grid_size, findex) \
-  private(nbr_mask, nbr_add, nbr_dist)
+  shared(nbr_mask, nbr_add, nbr_dist)
 #endif
-  for ( unsigned tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
+  for ( size_t tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
     {
 #if defined(_OPENMP)
 #include "pragma_omp_atomic_update.h"
@@ -418,6 +419,8 @@ void remap_distwgt_weights(unsigned num_neighbors, remapgrid_t *src_grid, remapg
       findex++;
       if ( cdo_omp_get_thread_num() == 0 ) progressStatus(0, 1, findex/tgt_grid_size);
       
+      int ompthID = cdo_omp_get_thread_num();
+
       weightlinks[tgt_cell_add].nlinks = 0;	
 
       if ( ! tgt_grid->mask[tgt_cell_add] ) continue;
@@ -427,25 +430,29 @@ void remap_distwgt_weights(unsigned num_neighbors, remapgrid_t *src_grid, remapg
 
       // Find nearest grid points on source grid and distances to each point
       if ( remap_grid_type == REMAP_GRID_TYPE_REG2D )
-	grid_search_nbr_reg2d(gs, num_neighbors, src_grid, nbr_add, nbr_dist, 
+	grid_search_nbr_reg2d(gs, num_neighbors, src_grid, nbr_add[ompthID], nbr_dist[ompthID], 
 			      plon, plat, src_grid->dims);
       else
-        grid_search_nbr(gs, num_neighbors, nbr_add, nbr_dist, plon, plat);
+        grid_search_nbr(gs, num_neighbors, nbr_add[ompthID], nbr_dist[ompthID], plon, plat);
 
       // Compute weights based on inverse distance if mask is false, eliminate those points
-      double dist_tot = nbr_compute_weights(num_neighbors, src_grid->mask, nbr_mask, nbr_add, nbr_dist);
+      double dist_tot = nbr_compute_weights(num_neighbors, src_grid->mask, nbr_mask[ompthID], nbr_add[ompthID], nbr_dist[ompthID]);
 
       // Normalize weights and store the link
-      unsigned nadds = nbr_normalize_weights(num_neighbors, dist_tot, nbr_mask, nbr_add, nbr_dist);
+      size_t nadds = nbr_normalize_weights(num_neighbors, dist_tot, nbr_mask[ompthID], nbr_add[ompthID], nbr_dist[ompthID]);
 
-      for ( unsigned n = 0; n < nadds; ++n )
-        if ( nbr_mask[n] ) tgt_grid->cell_frac[tgt_cell_add] = ONE;
+      for ( size_t n = 0; n < nadds; ++n )
+        if ( nbr_mask[ompthID][n] ) tgt_grid->cell_frac[tgt_cell_add] = ONE;
 
-      store_weightlinks(0, nadds, nbr_add, nbr_dist, tgt_cell_add, weightlinks);
+      store_weightlinks(0, nadds, nbr_add[ompthID], nbr_dist[ompthID], tgt_cell_add, weightlinks);
     }
 
   progressStatus(0, 1, 1);
 
+  DELETE_2D(nbr_mask);
+  DELETE_2D(nbr_add);
+  DELETE_2D(nbr_dist);
+
   if ( gs ) gridsearch_delete(gs);
 
   weightlinks2remaplinks(0, tgt_grid_size, weightlinks, rv);
@@ -459,14 +466,14 @@ void remap_distwgt_weights(unsigned num_neighbors, remapgrid_t *src_grid, remapg
 } // remap_distwgt_weights
 
 static
-void distwgt_remap(double* restrict tgt_point, const double* restrict src_array, long nadds, const double wgts[4], const int src_add[4])
+void distwgt_remap(double* restrict tgt_point, const double* restrict src_array, size_t nadds, const double wgts[4], const size_t src_add[4])
 {
   *tgt_point = 0.;
-  for ( int n = 0; n < nadds; ++n ) *tgt_point += src_array[src_add[n]]*wgts[n];
+  for ( size_t n = 0; n < nadds; ++n ) *tgt_point += src_array[src_add[n]]*wgts[n];
 }
 
 
-void remap_distwgt(unsigned num_neighbors, remapgrid_t *src_grid, remapgrid_t *tgt_grid, const double* restrict src_array, double* restrict tgt_array, double missval)
+void remap_distwgt(size_t num_neighbors, remapgrid_t *src_grid, remapgrid_t *tgt_grid, const double* restrict src_array, double* restrict tgt_array, double missval)
 {
   int src_remap_grid_type = src_grid->remap_grid_type;
 
@@ -476,15 +483,15 @@ void remap_distwgt(unsigned num_neighbors, remapgrid_t *src_grid, remapgrid_t *t
 
   // Compute mappings from source to target grid 
 
-  unsigned src_grid_size = src_grid->size;
-  unsigned tgt_grid_size = tgt_grid->size;
-  unsigned nx = src_grid->dims[0];
-  unsigned ny = src_grid->dims[1];
+  size_t src_grid_size = src_grid->size;
+  size_t tgt_grid_size = tgt_grid->size;
+  size_t nx = src_grid->dims[0];
+  size_t ny = src_grid->dims[1];
   bool lcyclic = src_grid->is_cyclic;
 
-  bool nbr_mask[num_neighbors];   // mask at nearest neighbors
-  int nbr_add[num_neighbors];     // source address at nearest neighbors
-  double nbr_dist[num_neighbors]; // angular distance four nearest neighbors
+  NEW_2D(bool, nbr_mask, ompNumThreads, num_neighbors);   // mask at nearest neighbors
+  NEW_2D(size_t, nbr_add, ompNumThreads, num_neighbors);  // source address at nearest neighbors
+  NEW_2D(double, nbr_dist, ompNumThreads, num_neighbors); // angular distance four nearest neighbors
 
 #if defined(_OPENMP)
   double start = 0;
@@ -511,10 +518,9 @@ void remap_distwgt(unsigned num_neighbors, remapgrid_t *src_grid, remapgrid_t *t
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) \
   shared(gs, num_neighbors, src_remap_grid_type, src_grid, tgt_grid, tgt_grid_size, findex) \
-  shared(src_array, tgt_array, missval) \
-  private(nbr_mask, nbr_add, nbr_dist)
+  shared(src_array, tgt_array, missval, nbr_mask, nbr_add, nbr_dist)
 #endif
-  for ( unsigned tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
+  for ( size_t tgt_cell_add = 0; tgt_cell_add < tgt_grid_size; ++tgt_cell_add )
     {
 #if defined(_OPENMP)
 #include "pragma_omp_atomic_update.h"
@@ -522,6 +528,8 @@ void remap_distwgt(unsigned num_neighbors, remapgrid_t *src_grid, remapgrid_t *t
       findex++;
       if ( cdo_omp_get_thread_num() == 0 ) progressStatus(0, 1, findex/tgt_grid_size);
       
+      int ompthID = cdo_omp_get_thread_num();
+
       tgt_array[tgt_cell_add] = missval;
 
       if ( ! tgt_grid->mask[tgt_cell_add] ) continue;
@@ -531,27 +539,31 @@ void remap_distwgt(unsigned num_neighbors, remapgrid_t *src_grid, remapgrid_t *t
 
       // Find nearest grid points on source grid and distances to each point
       if ( src_remap_grid_type == REMAP_GRID_TYPE_REG2D )
-	grid_search_nbr_reg2d(gs, num_neighbors, src_grid, nbr_add, nbr_dist, 
+	grid_search_nbr_reg2d(gs, num_neighbors, src_grid, nbr_add[ompthID], nbr_dist[ompthID], 
 			      plon, plat, src_grid->dims);
       else
-        grid_search_nbr(gs, num_neighbors, nbr_add, nbr_dist, plon, plat);
+        grid_search_nbr(gs, num_neighbors, nbr_add[ompthID], nbr_dist[ompthID], plon, plat);
       
       // Compute weights based on inverse distance if mask is false, eliminate those points
-      double dist_tot = nbr_compute_weights(num_neighbors, src_grid->mask, nbr_mask, nbr_add, nbr_dist);
+      double dist_tot = nbr_compute_weights(num_neighbors, src_grid->mask, nbr_mask[ompthID], nbr_add[ompthID], nbr_dist[ompthID]);
 
       // Normalize weights and store the link
-      unsigned nadds = nbr_normalize_weights(num_neighbors, dist_tot, nbr_mask, nbr_add, nbr_dist);
+      size_t nadds = nbr_normalize_weights(num_neighbors, dist_tot, nbr_mask[ompthID], nbr_add[ompthID], nbr_dist[ompthID]);
 
-      for ( unsigned n = 0; n < nadds; ++n )
-        if ( nbr_mask[n] ) tgt_grid->cell_frac[tgt_cell_add] = ONE;
+      for ( size_t n = 0; n < nadds; ++n )
+        if ( nbr_mask[ompthID][n] ) tgt_grid->cell_frac[tgt_cell_add] = ONE;
 
-      if ( nadds > 1 ) sort_add_and_wgts(nadds, nbr_add, nbr_dist);
+      if ( nadds > 1 ) sort_add_and_wgts(nadds, nbr_add[ompthID], nbr_dist[ompthID]);
 
-      if ( nadds ) distwgt_remap(&tgt_array[tgt_cell_add], src_array, nadds, nbr_dist, nbr_add);
+      if ( nadds ) distwgt_remap(&tgt_array[tgt_cell_add], src_array, nadds, nbr_dist[ompthID], nbr_add[ompthID]);
     }
 
   progressStatus(0, 1, 1);
 
+  DELETE_2D(nbr_mask);
+  DELETE_2D(nbr_add);
+  DELETE_2D(nbr_dist);
+
   if ( gs ) gridsearch_delete(gs);
 
 #if defined(_OPENMP)
diff --git a/src/remap_scrip_io.cc b/src/remap_scrip_io.cc
index 667ae7f..c38937c 100644
--- a/src/remap_scrip_io.cc
+++ b/src/remap_scrip_io.cc
@@ -26,6 +26,44 @@ void nce(int istat)
   // This routine provides a simple interface to NetCDF error message routine.
   if ( istat != NC_NOERR ) cdoAbort(nc_strerror(istat));
 }
+
+static
+void write_links(int nc_file_id, int nc_add_id, nc_type sizetype, size_t num_links, size_t *cell_add)
+{
+  if ( num_links == 0 ) return;
+
+  if ( sizetype == NC_INT )
+    {
+      int *intadd = (int*) Malloc(num_links*sizeof(int));
+      for ( size_t i = 0; i < num_links; ++i ) intadd[i] = (int)cell_add[i];
+      nce(nc_put_var_int(nc_file_id, nc_add_id, intadd));
+      Free(intadd);
+    }
+#if defined (HAVE_NETCDF4)
+  else
+    {
+      nce(nc_put_var_ulonglong(nc_file_id, nc_add_id, (unsigned long long*) cell_add));
+    }
+#endif
+}
+
+static
+void read_links(int nc_file_id, int nc_add_id, size_t num_links, size_t *cell_add)
+{
+  if ( num_links < 0x7FFFFC00 ) // 2GB
+    {
+      int *intadd = (int*) Malloc(num_links*sizeof(int));
+      nce(nc_get_var_int(nc_file_id, nc_add_id, intadd));
+      for ( size_t i = 0; i < num_links; ++i ) cell_add[i] = (size_t)intadd[i];
+      Free(intadd);
+    }
+#if defined (HAVE_NETCDF4)
+  else
+    {
+      nce(nc_get_var_ulonglong(nc_file_id, nc_add_id, (unsigned long long*) cell_add));
+    }
+#endif
+}
 #endif
 
 
@@ -83,6 +121,7 @@ void write_remap_scrip(const char *interp_file, int map_type, int submap_type, i
   const char *tgt_grid_units = "radians";
   bool lgridarea = false;
   int writemode = NC_CLOBBER;
+  nc_type sizetype = NC_INT;
 
   switch ( rv.norm_opt )
     {
@@ -149,8 +188,8 @@ void write_remap_scrip(const char *interp_file, int map_type, int submap_type, i
     size_t nele2 = 4*8 + 4;
     if ( src_grid.lneed_cell_corners ) nele1 += src_grid.num_cell_corners*2*8;
     if ( tgt_grid.lneed_cell_corners ) nele2 += tgt_grid.num_cell_corners*2*8;
-    size_t filesize = src_grid.size*(nele1) +
-                      tgt_grid.size*(nele2) +
+    size_t filesize = src_grid.size*nele1 +
+                      tgt_grid.size*nele2 +
                       nlinks*(4 + 4 + rv.num_wts*8);
 
     if ( cdoVerbose )
@@ -162,13 +201,18 @@ void write_remap_scrip(const char *interp_file, int map_type, int submap_type, i
     if ( filesize > 0x7FFFFC00 ) // 2**31 - 1024 (<2GB)
       {
         size_t maxlinks = 0x3FFFFFFF; // 1GB
-        if ( nlinks > maxlinks || filesize > 8*maxlinks )
+        size_t gridsize_max = (src_grid.size > tgt_grid.size) ? src_grid.size : tgt_grid.size;
+        if ( nlinks > maxlinks || filesize > 8*maxlinks || gridsize_max > 0x7FFFFC00 )
           {
 #if defined (HAVE_NETCDF4)
-            writemode |= NC_NETCDF4 | NC_CLASSIC_MODEL;
             if ( cdoVerbose ) cdoPrint("Store weights and links to NetCDF4!");
+            writemode |= NC_NETCDF4;
+            if ( gridsize_max > 0x7FFFFC00 )
+              sizetype = NC_UINT64;
+            else
+              writemode |= NC_CLASSIC_MODEL;
 #else
-            cdoPrint("Number of remap links %lz exceeds maximum of %lz and NetCDF 4 is not available!",
+            cdoPrint("Number of remap links %zu exceeds maximum of %zu and NetCDF 4 is not available!",
                      nlinks, maxlinks);
 #endif
           }
@@ -246,8 +290,8 @@ void write_remap_scrip(const char *interp_file, int map_type, int submap_type, i
   nce(nc_def_dim(nc_file_id, "num_wgts", rv.num_wts, &nc_numwgts_id));
        
   // Define grid dimensions
-  nce(nc_def_var(nc_file_id, "src_grid_dims", NC_INT, 1, &nc_srcgrdrank_id, &nc_srcgrddims_id));
-  nce(nc_def_var(nc_file_id, "dst_grid_dims", NC_INT, 1, &nc_dstgrdrank_id, &nc_dstgrddims_id));
+  nce(nc_def_var(nc_file_id, "src_grid_dims", sizetype, 1, &nc_srcgrdrank_id, &nc_srcgrddims_id));
+  nce(nc_def_var(nc_file_id, "dst_grid_dims", sizetype, 1, &nc_dstgrdrank_id, &nc_dstgrddims_id));
 
   // Define all arrays for NetCDF descriptors
 
@@ -325,8 +369,8 @@ void write_remap_scrip(const char *interp_file, int map_type, int submap_type, i
 
   // Define mapping arrays
 
-  nce(nc_def_var(nc_file_id, "src_address", NC_INT, 1, &nc_numlinks_id, &nc_srcadd_id));      
-  nce(nc_def_var(nc_file_id, "dst_address", NC_INT, 1, &nc_numlinks_id, &nc_dstadd_id));
+  nce(nc_def_var(nc_file_id, "src_address", sizetype, 1, &nc_numlinks_id, &nc_srcadd_id));      
+  nce(nc_def_var(nc_file_id, "dst_address", sizetype, 1, &nc_numlinks_id, &nc_dstadd_id));
 
   nc_dims2_id[0] = nc_numlinks_id;
   nc_dims2_id[1] = nc_numwgts_id;
@@ -379,14 +423,14 @@ void write_remap_scrip(const char *interp_file, int map_type, int submap_type, i
 
   nce(nc_put_var_double(nc_file_id, nc_dstgrdfrac_id, tgt_grid.cell_frac));
 
-  for ( long i = 0; i < rv.num_links; i++ )
+  for ( size_t i = 0; i < rv.num_links; i++ )
     {
       rv.src_cell_add[i]++;
       rv.tgt_cell_add[i]++;
     }
 
-  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));
+  write_links(nc_file_id, nc_srcadd_id, sizetype, rv.num_links, rv.src_cell_add);
+  write_links(nc_file_id, nc_dstadd_id, sizetype, rv.num_links, rv.tgt_cell_add);
 
   nce(nc_put_var_double(nc_file_id, nc_rmpmatrix_id, rv.wts));
 
@@ -659,8 +703,8 @@ void read_remap_scrip(const char *interp_file, int gridID1, int gridID2, int *ma
   rv->wts = NULL;
   if ( rv->num_links > 0 )
     {
-      rv->src_cell_add = (int*) Malloc(rv->num_links*sizeof(int));
-      rv->tgt_cell_add = (int*) Malloc(rv->num_links*sizeof(int));
+      rv->src_cell_add = (size_t*) Malloc(rv->num_links*sizeof(size_t));
+      rv->tgt_cell_add = (size_t*) Malloc(rv->num_links*sizeof(size_t));
 
       rv->wts = (double*) Malloc(rv->num_wts*rv->num_links*sizeof(double));
     }
@@ -769,10 +813,10 @@ void read_remap_scrip(const char *interp_file, int gridID1, int gridID2, int *ma
 
   if ( rv->num_links > 0 )
     {
-      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));
+      read_links(nc_file_id, nc_srcadd_id, rv->num_links, rv->src_cell_add);
+      read_links(nc_file_id, nc_dstadd_id, rv->num_links, rv->tgt_cell_add);
 
-      for ( long i = 0; i < rv->num_links; i++ )
+      for ( size_t i = 0; i < rv->num_links; ++i )
         {
           rv->src_cell_add[i]--;
           rv->tgt_cell_add[i]--;
diff --git a/src/remap_search_latbins.cc b/src/remap_search_latbins.cc
index 2ad919a..8d25ab3 100644
--- a/src/remap_search_latbins.cc
+++ b/src/remap_search_latbins.cc
@@ -4,11 +4,11 @@
 
 
 static
-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_bin_addr(size_t gridsize, size_t nbins, const restr_t* restrict bin_lats, const restr_t* restrict cell_bound_box, size_t* restrict bin_addr)
 {
-  long n2;
+  size_t n2;
 
-  for ( long n = 0; n < nbins; ++n )
+  for ( size_t n = 0; n < nbins; ++n )
     {
       n2 = n<<1;
       bin_addr[n2  ] = gridsize;
@@ -19,12 +19,12 @@ void calc_bin_addr(long gridsize, long nbins, const restr_t* restrict bin_lats,
 #pragma omp parallel for default(none) \
   private(n2)  shared(gridsize, nbins, bin_lats, bin_addr, cell_bound_box)
 #endif
-  for ( long nele = 0; nele < gridsize; ++nele )
+  for ( size_t nele = 0; nele < gridsize; ++nele )
     {
-      long nele4 = nele<<2;
+      size_t nele4 = nele<<2;
       restr_t cell_bound_box_lat1 = cell_bound_box[nele4  ];
       restr_t cell_bound_box_lat2 = cell_bound_box[nele4+1];
-      for ( long n = 0; n < nbins; ++n )
+      for ( size_t n = 0; n < nbins; ++n )
 	{
 	  n2 = n<<1;
 	  if ( cell_bound_box_lat1 <= bin_lats[n2+1] &&
@@ -45,9 +45,9 @@ void calc_bin_addr(long gridsize, long nbins, const restr_t* restrict bin_lats,
 
 void calc_lat_bins(remapgrid_t* src_grid, remapgrid_t* tgt_grid, int map_type)
 {
-  long nbins;
-  long n;      /* Loop counter                  */
-  long n2;
+  size_t nbins;
+  size_t n;      /* Loop counter                  */
+  size_t n2;
   double dlat;                /* lat/lon intervals for search bins  */
   restr_t *bin_lats = NULL;
 
@@ -67,13 +67,13 @@ void calc_lat_bins(remapgrid_t* src_grid, remapgrid_t* tgt_grid, int map_type)
 	  bin_lats[n2+1] = RESTR_SCALE((n+1)*dlat - PIH);
 	}
 
-      src_grid->bin_addr = (int*) Realloc(src_grid->bin_addr, 2*nbins*sizeof(int));
+      src_grid->bin_addr = (size_t*) Realloc(src_grid->bin_addr, 2*nbins*sizeof(size_t));
 
       calc_bin_addr(src_grid->size, nbins, bin_lats, src_grid->cell_bound_box, src_grid->bin_addr);
 
       if ( map_type == MAP_TYPE_CONSERV || map_type == MAP_TYPE_CONSERV_YAC )
 	{
-	  tgt_grid->bin_addr = (int*) Realloc(tgt_grid->bin_addr, 2*nbins*sizeof(int));
+	  tgt_grid->bin_addr = (size_t*) Realloc(tgt_grid->bin_addr, 2*nbins*sizeof(size_t));
 
 	  calc_bin_addr(tgt_grid->size, nbins, bin_lats, tgt_grid->cell_bound_box, tgt_grid->bin_addr);
 
@@ -93,15 +93,15 @@ void calc_lat_bins(remapgrid_t* src_grid, remapgrid_t* tgt_grid, int map_type)
 }
 
 
-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)
+size_t get_srch_cells(size_t tgt_cell_add, size_t nbins, size_t *bin_addr1, size_t *bin_addr2,
+                      restr_t *tgt_cell_bound_box, restr_t *src_cell_bound_box, size_t src_grid_size, size_t *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_cell_add;    /* current linear address for src cell     */
-  long src_cell_addm4;
+  size_t num_srch_cells;  /* num cells in restricted search arrays   */
+  size_t min_add;         /* addresses for restricting search of     */
+  size_t max_add;         /* destination grid                        */
+  size_t n, n2;           /* generic counters                        */
+  size_t src_cell_add;    /* current linear address for src cell     */
+  size_t src_cell_addm4;
   restr_t bound_box_lat1, bound_box_lat2, bound_box_lon1, bound_box_lon2;
 
   /* Restrict searches first using search bins */
@@ -164,7 +164,7 @@ long get_srch_cells(long tgt_cell_add, long nbins, int *bin_addr1, int *bin_addr
 	      if ( (src_cell_bound_box[src_cell_addm4  ] <= bound_box_lat2)  &&
 		   (src_cell_bound_box[src_cell_addm4+1] >= bound_box_lat1) )
 		{
-		  long ii;
+		  size_t ii;
 		  for ( ii = 0; ii < num_srch_cells; ++ii )
 		    if ( srch_add[ii] == src_cell_add ) break;
 		  
@@ -182,13 +182,13 @@ long get_srch_cells(long tgt_cell_add, long nbins, int *bin_addr1, int *bin_addr
 }
 
 static
-int grid_search_nn(long min_add, long max_add, int *restrict nbr_add, double *restrict nbr_dist, 
+int grid_search_nn(size_t min_add, size_t max_add, size_t *restrict nbr_add, double *restrict nbr_dist, 
 		   double plat, double plon,
 		   const double *restrict src_center_lat, const double *restrict src_center_lon)
 {
   int search_result = 0;
-  long n, srch_add;
-  long i;
+  size_t n, srch_add;
+  size_t i;
   double dist_min, distance; /* For computing dist-weighted avg */
   double coslat_dst = cos(plat);
   double sinlat_dst = sin(plat);
@@ -234,10 +234,10 @@ int grid_search_nn(long min_add, long max_add, int *restrict nbr_add, double *re
 }
 
 
-int grid_search(remapgrid_t *src_grid, int *restrict src_add, double *restrict src_lats, 
+int grid_search(remapgrid_t *src_grid, size_t *restrict src_add, double *restrict src_lats, 
 		double *restrict src_lons,  double plat, double plon, const int *restrict src_grid_dims,
 		const double *restrict src_center_lat, const double *restrict src_center_lon,
-		const restr_t *restrict src_grid_bound_box, const int *restrict src_bin_add)
+		const restr_t *restrict src_grid_bound_box, const size_t *restrict src_bin_add)
 {
   /*
     Output variables:
@@ -261,7 +261,7 @@ int grid_search(remapgrid_t *src_grid, int *restrict src_add, double *restrict s
     int src_bin_add[][2]           ! latitude bins for restricting
   */
   /*  Local variables */
-  long n, n2, next_n, srch_add, srch_add4;    /* dummy indices                    */
+  size_t n, n2, next_n, srch_add, srch_add4;    /* dummy indices                    */
   /* Vectors for cross-product check */
   double vec1_lat, vec1_lon;
   double vec2_lat, vec2_lon;
@@ -269,7 +269,7 @@ int grid_search(remapgrid_t *src_grid, int *restrict src_add, double *restrict s
   int search_result = 0;
   restr_t *bin_lats = src_grid->bin_lats;
 
-  long nbins = src_grid->num_srch_bins;
+  size_t nbins = src_grid->num_srch_bins;
 
   restr_t rlat = RESTR_SCALE(plat);
   restr_t rlon = RESTR_SCALE(plon);
@@ -279,10 +279,10 @@ int grid_search(remapgrid_t *src_grid, int *restrict src_add, double *restrict s
   for ( n = 0; n < 4; ++n ) src_add[n] = 0;
 
   // addresses for restricting search
-  long min_add = src_grid->size-1;
-  long max_add = 0;
+  size_t min_add = src_grid->size-1;
+  size_t max_add = 0;
 
-  for ( long  n = 0; n < nbins; ++n )
+  for ( size_t  n = 0; n < nbins; ++n )
     {
       n2 = n<<1;
       if ( rlat >= bin_lats[n2] && rlat <= bin_lats[n2+1] )
@@ -294,8 +294,8 @@ int grid_search(remapgrid_t *src_grid, int *restrict src_add, double *restrict s
  
   /* Now perform a more detailed search */
 
-  long nx = src_grid_dims[0];
-  long ny = src_grid_dims[1];
+  size_t nx = src_grid_dims[0];
+  size_t ny = src_grid_dims[1];
 
   /* srch_loop */
   for ( srch_add = min_add; srch_add <= max_add; ++srch_add )
@@ -310,15 +310,15 @@ int grid_search(remapgrid_t *src_grid, int *restrict src_add, double *restrict s
 	  /* We are within bounding box so get really serious */
 
           /* Determine neighbor addresses */
-          long j = srch_add/nx;
-          long i = srch_add - j*nx;
+          size_t j = srch_add/nx;
+          size_t i = srch_add - j*nx;
 
-          long ip1 = (i < (nx-1)) ? i + 1 : (src_grid->is_cyclic) ? 0 : i;
-          long jp1 = (j < (ny-1)) ? j + 1 : j;
+          size_t ip1 = (i < (nx-1)) ? i + 1 : (src_grid->is_cyclic) ? 0 : i;
+          size_t jp1 = (j < (ny-1)) ? j + 1 : j;
 
-          long n_add  = jp1*nx + i;
-          long e_add  = j  *nx + ip1;
-	  long ne_add = jp1*nx + ip1;
+          size_t n_add  = jp1*nx + i;
+          size_t e_add  = j  *nx + ip1;
+	  size_t ne_add = jp1*nx + ip1;
 
           src_lons[0] = src_center_lon[srch_add];
           src_lons[1] = src_center_lon[e_add];
diff --git a/src/remap_search_reg2d.cc b/src/remap_search_reg2d.cc
index 981ef8d..3aaea0e 100644
--- a/src/remap_search_reg2d.cc
+++ b/src/remap_search_reg2d.cc
@@ -2,17 +2,14 @@
 #include "remap.h"
 
 
-int rect_grid_search(long *ii, long *jj, double x, double y, long nxm, long nym, const double *restrict xm, const double *restrict ym);
-
-
-int grid_search_reg2d_nn(long nx, long ny, int *restrict nbr_add, double *restrict nbr_dist, double plat, double plon,
+int grid_search_reg2d_nn(size_t nx, size_t ny, size_t *restrict nbr_add, double *restrict nbr_dist, double plat, double plon,
 			 const double *restrict src_center_lat, const double *restrict src_center_lon)
 {
   int search_result = 0;
-  long n, srch_add;
-  long i;
-  long ii, jj;
-  long jjskip;
+  size_t n, srch_add;
+  size_t i;
+  size_t ii, jj;
+  size_t jjskip;
   double coslat, sinlat;
   double dist_min, distance; /* For computing dist-weighted avg */
   double *sincoslon;
@@ -24,7 +21,7 @@ int grid_search_reg2d_nn(long nx, long ny, int *restrict nbr_add, double *restri
   dist_min = BIGNUM;
   for ( n = 0; n < 4; ++n ) nbr_dist[n] = BIGNUM;  
 
-  long jjf = 0, jjl = ny-1;
+  size_t jjf = 0, jjl = ny-1;
   if ( plon >= src_center_lon[0] && plon <= src_center_lon[nx-1] )
     {
       if ( src_center_lat[0] < src_center_lat[ny-1] )
@@ -96,7 +93,7 @@ int grid_search_reg2d_nn(long nx, long ny, int *restrict nbr_add, double *restri
 }
 
 
-int grid_search_reg2d(remapgrid_t *src_grid, int *restrict src_add, double *restrict src_lats, 
+int grid_search_reg2d(remapgrid_t *src_grid, size_t *restrict src_add, double *restrict src_lats, 
 		      double *restrict src_lons,  double plat, double plon, const int *restrict src_grid_dims,
 		      const double *restrict src_center_lat, const double *restrict src_center_lon)
 {
@@ -120,14 +117,14 @@ int grid_search_reg2d(remapgrid_t *src_grid, int *restrict src_add, double *rest
   /*  Local variables */
   int search_result = 0;
   long n;
-  long ii, iix, jj;
+  size_t ii, iix, jj;
 
   for ( n = 0; n < 4; ++n ) src_add[n] = 0;
 
-  long nx = src_grid_dims[0];
-  long ny = src_grid_dims[1];
+  size_t nx = src_grid_dims[0];
+  size_t ny = src_grid_dims[1];
 
-  long nxm = nx;
+  size_t nxm = nx;
   if ( src_grid->is_cyclic ) nxm++;
 
   if ( /*plon < 0   &&*/ plon < src_center_lon[0]     ) plon += PI2;
diff --git a/src/remap_store_link.cc b/src/remap_store_link.cc
index aa06157..18a4f2e 100644
--- a/src/remap_store_link.cc
+++ b/src/remap_store_link.cc
@@ -30,9 +30,9 @@ int cmp_adds4(const void *s1, const void *s2)
 }
 
 static
-void sort_addweights(unsigned num_weights, addweight_t *addweights)
+void sort_addweights(size_t num_weights, addweight_t *addweights)
 {
-  unsigned n;
+  size_t n;
 
   for ( n = 1; n < num_weights; ++n )
     if ( addweights[n].add < addweights[n-1].add ) break;
@@ -42,9 +42,9 @@ void sort_addweights(unsigned num_weights, addweight_t *addweights)
 }
 
 static
-void sort_addweights4(unsigned num_weights, addweight4_t *addweights)
+void sort_addweights4(size_t num_weights, addweight4_t *addweights)
 {
-  unsigned n;
+  size_t n;
 
   for ( n = 1; n < num_weights; ++n )
     if ( addweights[n].add < addweights[n-1].add ) break;
@@ -54,9 +54,9 @@ void sort_addweights4(unsigned num_weights, addweight4_t *addweights)
 }
 
 
-void sort_add_and_wgts(unsigned num_weights, int *src_add, double *wgts)
+void sort_add_and_wgts(size_t num_weights, size_t *src_add, double *wgts)
 {
-  unsigned n;
+  size_t n;
 
   for ( n = 1; n < num_weights; ++n )
     if ( src_add[n] < src_add[n-1] ) break;
@@ -83,9 +83,9 @@ void sort_add_and_wgts(unsigned num_weights, int *src_add, double *wgts)
 }
 
 
-void sort_add_and_wgts4(unsigned num_weights, int *src_add, double wgts[4][4])
+void sort_add_and_wgts4(size_t num_weights, size_t *src_add, double wgts[4][4])
 {
-  unsigned n;
+  size_t n;
 
   for ( n = 1; n < num_weights; ++n )
     if ( src_add[n] < src_add[n-1] ) break;
@@ -114,7 +114,7 @@ void sort_add_and_wgts4(unsigned num_weights, int *src_add, double wgts[4][4])
 }
 
 
-void store_weightlinks(int lalloc, unsigned num_weights, int *srch_add, double *weights, size_t cell_add, weightlinks_t *weightlinks)
+void store_weightlinks(int lalloc, size_t num_weights, size_t *srch_add, double *weights, size_t cell_add, weightlinks_t *weightlinks)
 {
   weightlinks[cell_add].nlinks = 0;
   weightlinks[cell_add].offset = 0;
@@ -127,7 +127,7 @@ void store_weightlinks(int lalloc, unsigned num_weights, int *srch_add, double *
       else
         addweights = weightlinks[cell_add].addweights;
 
-      for ( unsigned n = 0; n < num_weights; ++n )
+      for ( size_t n = 0; n < num_weights; ++n )
 	{
 	  addweights[n].add    = srch_add[n];
 	  addweights[n].weight = weights[n];
@@ -142,7 +142,7 @@ void store_weightlinks(int lalloc, unsigned num_weights, int *srch_add, double *
 }
 
 
-void store_weightlinks4(unsigned num_weights, int *srch_add, double weights[4][4], size_t cell_add, weightlinks4_t *weightlinks)
+void store_weightlinks4(size_t num_weights, size_t *srch_add, double weights[4][4], size_t cell_add, weightlinks4_t *weightlinks)
 {
   weightlinks[cell_add].nlinks = 0;
   weightlinks[cell_add].offset = 0;
@@ -151,7 +151,7 @@ void store_weightlinks4(unsigned num_weights, int *srch_add, double weights[4][4
     {
       addweight4_t *addweights = weightlinks[cell_add].addweights;
 
-      for ( unsigned n = 0; n < num_weights; ++n )
+      for ( size_t n = 0; n < num_weights; ++n )
 	{
 	  addweights[n].add = srch_add[n];
 	  for ( unsigned k = 0; k < 4; ++k )
@@ -182,11 +182,11 @@ void weightlinks2remaplinks(int lalloc, size_t tgt_grid_size, weightlinks_t *wei
   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->src_cell_add = (size_t*) Malloc(nlinks*sizeof(size_t));
+      rv->tgt_cell_add = (size_t*) Malloc(nlinks*sizeof(size_t));
       rv->wts          = (double*) Malloc(nlinks*sizeof(double));
-      int *restrict src_cell_adds = rv->src_cell_add;
-      int *restrict tgt_cell_adds = rv->tgt_cell_add;
+      size_t *restrict src_cell_adds = rv->src_cell_add;
+      size_t *restrict tgt_cell_adds = rv->tgt_cell_add;
       double *restrict wts = rv->wts;
 
 #if defined(_OPENMP)
@@ -241,11 +241,11 @@ void weightlinks2remaplinks4(size_t tgt_grid_size, weightlinks4_t *weightlinks,
   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->src_cell_add = (size_t*) Malloc(nlinks*sizeof(size_t));
+      rv->tgt_cell_add = (size_t*) Malloc(nlinks*sizeof(size_t));
       rv->wts          = (double*) Malloc(4*nlinks*sizeof(double));
-      int *restrict src_cell_adds = rv->src_cell_add;
-      int *restrict tgt_cell_adds = rv->tgt_cell_add;
+      size_t *restrict src_cell_adds = rv->src_cell_add;
+      size_t *restrict tgt_cell_adds = rv->tgt_cell_add;
       double *restrict wts = rv->wts;
 
 #if defined(_OPENMP)
diff --git a/src/remap_store_link.h b/src/remap_store_link.h
index 608a393..973a215 100644
--- a/src/remap_store_link.h
+++ b/src/remap_store_link.h
@@ -4,35 +4,35 @@
 
 typedef struct
 {
-  int    add;
+  size_t add;
   double weight;
 } addweight_t;
 
 typedef struct
 {
-  int    add;
+  size_t add;
   double weight[4];
 } addweight4_t;
 
 typedef struct {
-  unsigned nlinks;
-  unsigned offset;
+  size_t nlinks;
+  size_t offset;
   addweight_t *addweights;
 } weightlinks_t;
 
 typedef struct {
-  unsigned nlinks;
-  unsigned offset;
+  size_t nlinks;
+  size_t offset;
   addweight4_t *addweights;
 } weightlinks4_t;
 
 
-void store_weightlinks(int lalloc, unsigned num_weights, int *srch_add, double *weights, size_t cell_add, weightlinks_t *weightlinks);
-void store_weightlinks4(unsigned num_weights, int *srch_add, double weights[4][4], size_t cell_add, weightlinks4_t *weightlinks);
+void store_weightlinks(int lalloc, size_t num_weights, size_t *srch_add, double *weights, size_t cell_add, weightlinks_t *weightlinks);
+void store_weightlinks4(size_t num_weights, size_t *srch_add, double weights[4][4], size_t cell_add, weightlinks4_t *weightlinks);
 void weightlinks2remaplinks(int lalloc, size_t tgt_grid_size, weightlinks_t *weightlinks, remapvars_t *rv);
 void weightlinks2remaplinks4(size_t tgt_grid_size, weightlinks4_t *weightlinks, remapvars_t *rv);
-void sort_add_and_wgts(unsigned num_weights, int *src_add, double *wgts);
-void sort_add_and_wgts4(unsigned num_weights, int *src_add, double wgts[4][4]);
+void sort_add_and_wgts(size_t num_weights, size_t *src_add, double *wgts);
+void sort_add_and_wgts4(size_t num_weights, size_t *src_add, double wgts[4][4]);
 
 
 #endif  /* REMAP_STORE_LINK */
diff --git a/src/remap_store_link_cnsrv.cc b/src/remap_store_link_cnsrv.cc
index 9a714ca..719425e 100644
--- a/src/remap_store_link_cnsrv.cc
+++ b/src/remap_store_link_cnsrv.cc
@@ -27,12 +27,12 @@ void grid_store_init(grid_store_t* grid_store, long gridsize)
   if ( grid_store->max_size%grid_store->blk_size > 0 ) grid_store->nblocks++;
 
   if ( cdoVerbose )
-    fprintf(stdout, "blksize = %d  lastblksize = %d  max_size = %d  nblocks = %d\n", 
+    fprintf(stdout, "blksize = %zu  lastblksize = %zu  max_size = %zu  nblocks = %zu\n", 
 	    grid_store->blk_size, grid_store->max_size%grid_store->blk_size, 
 	    grid_store->max_size, grid_store->nblocks);
 
-  grid_store->blksize = (int*) Malloc(grid_store->nblocks*sizeof(int));
-  grid_store->nlayers = (int*) Malloc(grid_store->nblocks*sizeof(int));
+  grid_store->blksize = (long*) Malloc(grid_store->nblocks*sizeof(long));
+  grid_store->nlayers = (long*) Malloc(grid_store->nblocks*sizeof(long));
   grid_store->layers  = (grid_layer_t **) Malloc(grid_store->nblocks*sizeof(grid_layer_t *));
 
   nblocks = grid_store->nblocks;
@@ -102,7 +102,7 @@ void store_link_cnsrv_fast(remapvars_t* rv, long add1, long add2, long num_wts,
   long nlink; /* link index */
   long ilayer, i, iblk, iadd2;
   long nlayer, blksize;
-  int lstore_link;
+  bool lstore_link;
   grid_layer_t *grid_layer = NULL, **grid_layer2;
 
   /*  If all weights are ZERO, do not bother storing the link */
@@ -121,7 +121,7 @@ void store_link_cnsrv_fast(remapvars_t* rv, long add1, long add2, long num_wts,
   iblk  = BLK_NUM(add2);
   iadd2 = BLK_IDX(add2);
 
-  lstore_link = FALSE;
+  lstore_link = false;
   grid_layer2 = &grid_store->layers[iblk];
   nlayer = grid_store->nlayers[iblk];
   for ( ilayer = 0; ilayer < nlayer; ++ilayer )
@@ -132,9 +132,9 @@ void store_link_cnsrv_fast(remapvars_t* rv, long add1, long add2, long num_wts,
 	{
 	  break;
 	}
-      else if ( add1 == rv->src_cell_add[nlink] )
+      else if ( (size_t)add1 == rv->src_cell_add[nlink] )
 	{
-	  lstore_link = TRUE;
+	  lstore_link = true;
 	  break;
 	}
       grid_layer2 = &(*grid_layer2)->next;
@@ -161,7 +161,7 @@ void store_link_cnsrv_fast(remapvars_t* rv, long add1, long add2, long num_wts,
     {
       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));
+      grid_layer->grid2_link = (long*) Malloc(grid_store->blksize[iblk]*sizeof(long));
 
       blksize = grid_store->blksize[iblk];
       for ( i = 0; i < blksize; ++i )
@@ -188,7 +188,7 @@ void store_link_cnsrv_fast(remapvars_t* rv, long add1, long add2, long num_wts,
     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_link_cnsrv(remapvars_t *rv, long add1, long add2, double *restrict weights, long *link_add1[2], long *link_add2[2])
 {
   /*
     Input variables:
@@ -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_cell_add[nlink] )
-	if ( add1 == rv->src_cell_add[nlink] ) break;
+      if ( (size_t)add2 == rv->tgt_cell_add[nlink] )
+	if ( (size_t)add1 == rv->src_cell_add[nlink] ) break;
     }
 #endif
 
@@ -283,9 +283,9 @@ void store_link_cnsrv(remapvars_t *rv, long add1, long add2, double *restrict we
   rv->wts[3*nlink+1] = weights[1];
   rv->wts[3*nlink+2] = weights[2];
 
-  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;
+  if ( link_add1[0][add1] == -1 ) link_add1[0][add1] = nlink;
+  if ( link_add2[0][add2] == -1 ) link_add2[0][add2] = nlink;
+  link_add1[1][add1] = nlink;
+  link_add2[1][add2] = nlink;
 
 }  /* store_link_cnsrv */
diff --git a/src/remap_store_link_cnsrv.h b/src/remap_store_link_cnsrv.h
index b8e9bb8..5930815 100644
--- a/src/remap_store_link_cnsrv.h
+++ b/src/remap_store_link_cnsrv.h
@@ -10,7 +10,7 @@ extern int  remap_store_link_fast;
 #define BLK_IDX(x) (x%grid_store->blk_size)
 struct grid_layer
 {
-  int *grid2_link;
+  long *grid2_link;
   struct grid_layer *next;
 };
 
@@ -18,11 +18,11 @@ typedef struct grid_layer grid_layer_t;
 
 typedef struct
 {
-  int blk_size;
-  int max_size;
-  int nblocks;
-  int *blksize;
-  int *nlayers;
+  long blk_size;
+  long max_size;
+  long nblocks;
+  long *blksize;
+  long *nlayers;
   grid_layer_t **layers;
 } grid_store_t;
 
@@ -30,6 +30,6 @@ 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]);
+void store_link_cnsrv(remapvars_t *rv, long add1, long add2, double *restrict weights, long *link_add1[2], long *link_add2[2]);
 
 #endif  /* _REMAP_STORE_LINK_CNSRV */
diff --git a/src/remaplib.cc b/src/remaplib.cc
index b93ffaf..9410e98 100644
--- a/src/remaplib.cc
+++ b/src/remaplib.cc
@@ -68,7 +68,7 @@ static bool remap_gen_weights     = true;
 static bool remap_write_remap     = false;
 static int  remap_num_srch_bins   = 180;
 #define  DEFAULT_MAX_ITER  100
-long remap_max_iter        = DEFAULT_MAX_ITER;  /* Max iteration count for i, j iteration */
+size_t remap_max_iter    = DEFAULT_MAX_ITER;  // Max iteration count for i, j iteration
 
 void remap_set_int(int remapvar, int value)
 {
@@ -127,8 +127,8 @@ void remapVarsFree(remapvars_t *rv)
 	  if ( rv->links.num_blks )
 	    {
 	      Free(rv->links.num_links);
-	      long num_blks = rv->links.num_blks;
-	      for ( long i = 0; i < num_blks; ++i )
+	      size_t num_blks = rv->links.num_blks;
+	      for ( size_t i = 0; i < num_blks; ++i )
 		{
 		  Free(rv->links.src_add[i]);
 		  Free(rv->links.dst_add[i]);
@@ -208,7 +208,7 @@ void remapgrid_alloc(int map_type, remapgrid_t *grid)
     {
       if ( grid->num_cell_corners > 0 )
         {
-	  long nalloc = grid->num_cell_corners*grid->size;
+	  size_t nalloc = grid->num_cell_corners*grid->size;
 
 	  grid->cell_corner_lon = (double*) Malloc(nalloc*sizeof(double));
 	  memset(grid->cell_corner_lon, 0, nalloc*sizeof(double));
@@ -221,23 +221,23 @@ void remapgrid_alloc(int map_type, remapgrid_t *grid)
 
 /*****************************************************************************/
 static
-void boundbox_from_corners(long size, long nc, const double *restrict corner_lon,
+void boundbox_from_corners(size_t size, size_t nc, const double *restrict corner_lon,
 			   const double *restrict corner_lat, restr_t *restrict bound_box)
 {
 #if defined(_OPENMP)
 #pragma omp parallel for default(none)  shared(bound_box, corner_lat, corner_lon, nc, size)
 #endif
-  for ( long i = 0; i < size; ++i )
+  for ( size_t i = 0; i < size; ++i )
     {
-      long i4 = i<<2; // *4
-      long inc = i*nc;
+      size_t i4 = i<<2; // *4
+      size_t inc = i*nc;
       restr_t clat = RESTR_SCALE(corner_lat[inc]);
       restr_t clon = RESTR_SCALE(corner_lon[inc]);
       bound_box[i4  ] = clat;
       bound_box[i4+1] = clat;
       bound_box[i4+2] = clon;
       bound_box[i4+3] = clon;
-      for ( long j = 1; j < nc; ++j )
+      for ( size_t j = 1; j < nc; ++j )
 	{
 	  clat = RESTR_SCALE(corner_lat[inc+j]);
 	  clon = RESTR_SCALE(corner_lon[inc+j]);
@@ -250,11 +250,11 @@ void boundbox_from_corners(long size, long nc, const double *restrict corner_lon
 }
 
 static
-void boundbox_from_center(bool lonIsCyclic, long size, long nx, long ny, const double *restrict center_lon,
+void boundbox_from_center(bool lonIsCyclic, size_t size, size_t nx, size_t ny, const double *restrict center_lon,
 			  const double *restrict center_lat, restr_t *restrict bound_box)
 {
-  long n4, i, j, k, ip1, jp1;
-  long n_add, e_add, ne_add;
+  size_t n4, i, j, k, ip1, jp1;
+  size_t n_add, e_add, ne_add;
   restr_t tmp_lats[4], tmp_lons[4];  /* temps for computing bounding boxes */
 
 #if defined(_OPENMP)
@@ -262,7 +262,7 @@ void boundbox_from_center(bool lonIsCyclic, long size, long nx, long ny, const d
   shared(lonIsCyclic, size, nx, ny, center_lon, center_lat, bound_box)	\
   private(n4, i, j, k, ip1, jp1, n_add, e_add, ne_add, tmp_lats, tmp_lons)
 #endif
-  for ( long n = 0; n < size; n++ )
+  for ( size_t n = 0; n < size; n++ )
     {
       n4 = n<<2;
 
@@ -319,13 +319,13 @@ void boundbox_from_center(bool lonIsCyclic, long size, long nx, long ny, const d
 }
 
 
-void remapgrid_get_lonlat(remapgrid_t *grid, unsigned cell_add, double *plon, double *plat)
+void remapgrid_get_lonlat(remapgrid_t *grid, size_t cell_add, double *plon, double *plat)
 {
   if ( grid->remap_grid_type == REMAP_GRID_TYPE_REG2D )
     {
-      unsigned nx = grid->dims[0];
-      unsigned iy = cell_add/nx;
-      unsigned ix = cell_add - iy*nx;
+      size_t nx = grid->dims[0];
+      size_t iy = cell_add/nx;
+      size_t ix = cell_add - iy*nx;
       *plat = grid->reg2d_center_lat[iy];
       *plon = grid->reg2d_center_lon[ix];
       if ( *plon < 0 ) *plon += PI2;
@@ -338,14 +338,14 @@ void remapgrid_get_lonlat(remapgrid_t *grid, unsigned cell_add, double *plon, do
 }
 
 
-void check_lon_range(long nlons, double *lons)
+void check_lon_range(size_t nlons, double *lons)
 {
   assert(lons != NULL);
 
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) shared(nlons, lons)
 #endif
-  for ( long n = 0; n < nlons; ++n )
+  for ( size_t n = 0; n < nlons; ++n )
     {
       // remove missing values
       if ( lons[n] < -PI2 ) lons[n] = 0;
@@ -357,14 +357,14 @@ void check_lon_range(long nlons, double *lons)
 }
 
 
-void check_lat_range(long nlats, double *lats)
+void check_lat_range(size_t nlats, double *lats)
 {
   assert(lats != NULL);
 
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) shared(nlats, lats)
 #endif
-  for ( long n = 0; n < nlats; ++n )
+  for ( size_t n = 0; n < nlats; ++n )
     {
       if ( lats[n] >  PIH ) lats[n] =  PIH;
       if ( lats[n] < -PIH ) lats[n] = -PIH;
@@ -372,16 +372,16 @@ void check_lat_range(long nlats, double *lats)
 }
 
 static
-void check_lon_boundbox_range(long nlons, restr_t *bound_box)
+void check_lon_boundbox_range(size_t nlons, restr_t *bound_box)
 {
-  long n4;
+  size_t n4;
 
   assert(bound_box != NULL);
 
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) shared(nlons, bound_box) private(n4)
 #endif
-  for ( long n = 0; n < nlons; ++n )
+  for ( size_t n = 0; n < nlons; ++n )
     {
       n4 = n<<2;
       if ( RESTR_ABS(bound_box[n4+3] - bound_box[n4+2]) > RESTR_SCALE(PI) )
@@ -393,16 +393,16 @@ void check_lon_boundbox_range(long nlons, restr_t *bound_box)
 }
 
 static
-void check_lat_boundbox_range(long nlats, restr_t *restrict bound_box, double *restrict lats)
+void check_lat_boundbox_range(size_t nlats, restr_t *restrict bound_box, double *restrict lats)
 {
-  long n4;
+  size_t n4;
 
   assert(bound_box != NULL);
 
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) shared(nlats, bound_box, lats) private(n4)
 #endif
-  for ( long n = 0; n < nlats; ++n )
+  for ( size_t n = 0; n < nlats; ++n )
     {
       n4 = n<<2;
       if ( RESTR_SCALE(lats[n]) < bound_box[n4  ] ) bound_box[n4  ] = RESTR_SCALE(-PIH);
@@ -413,10 +413,10 @@ void check_lat_boundbox_range(long nlats, restr_t *restrict bound_box, double *r
 static
 int expand_lonlat_grid(int gridID)
 {
-  long nx = gridInqXsize(gridID);
-  long ny = gridInqYsize(gridID);
-  long nxp4 = nx+4;
-  long nyp4 = ny+4;
+  size_t nx = gridInqXsize(gridID);
+  size_t ny = gridInqYsize(gridID);
+  size_t nxp4 = nx+4;
+  size_t nyp4 = ny+4;
 
   double *xvals = (double*) Malloc(nxp4*sizeof(double));
   double *yvals = (double*) Malloc(nyp4*sizeof(double));
@@ -459,14 +459,12 @@ int expand_lonlat_grid(int gridID)
 static
 int expand_curvilinear_grid(int gridID)
 {
-  long i, j;
-
-  long gridsize = gridInqSize(gridID);
-  long nx = gridInqXsize(gridID);
-  long ny = gridInqYsize(gridID);
+  size_t gridsize = gridInqSize(gridID);
+  long nx = (long) gridInqXsize(gridID);
+  long ny = (long) gridInqYsize(gridID);
   long nxp4 = nx+4;
   long nyp4 = ny+4;
-  int gridsize_new = gridsize + 4*(nx+2) + 4*(ny+2);
+  size_t gridsize_new = gridsize + 4*(nx+2) + 4*(ny+2);
 
   double *xvals = (double*) Malloc(gridsize_new*sizeof(double));
   double *yvals = (double*) Malloc(gridsize_new*sizeof(double));
@@ -479,15 +477,15 @@ int expand_curvilinear_grid(int gridID)
 
   grid_copy_attributes(gridID, gridIDnew);
 
-  for ( j = ny-1; j >= 0; j-- )
-    for ( i = nx-1; i >= 0; i-- )
+  for ( long j = ny-1; j >= 0; j-- )
+    for ( long i = nx-1; i >= 0; i-- )
       xvals[(j+2)*(nx+4)+i+2] = xvals[j*nx+i];
 
-  for ( j = ny-1; j >= 0; j-- )
-    for ( i = nx-1; i >= 0; i-- )
+  for ( long j = ny-1; j >= 0; j-- )
+    for ( long i = nx-1; i >= 0; i-- )
       yvals[(j+2)*(nx+4)+i+2] = yvals[j*nx+i];
 
-  for ( j = 2; j < nyp4-2; j++ )
+  for ( long j = 2; j < nyp4-2; j++ )
     {
       xvals[j*nxp4  ] = intlin(3.0, xvals[j*nxp4+3], 0.0, xvals[j*nxp4+2], 1.0);
       xvals[j*nxp4+1] = intlin(2.0, xvals[j*nxp4+3], 0.0, xvals[j*nxp4+2], 1.0); 
@@ -500,7 +498,7 @@ int expand_curvilinear_grid(int gridID)
       yvals[j*nxp4+nxp4-1] = intlin(3.0, yvals[j*nxp4+nxp4-4], 0.0, yvals[j*nxp4+nxp4-3], 1.0); 
     }
 
-  for ( i = 0; i < nxp4; i++ )
+  for ( long i = 0; i < nxp4; i++ )
     {
       xvals[0*nxp4+i] = intlin(3.0, xvals[3*nxp4+i], 0.0, xvals[2*nxp4+i], 1.0);
       xvals[1*nxp4+i] = intlin(2.0, xvals[3*nxp4+i], 0.0, xvals[2*nxp4+i], 1.0);
@@ -543,13 +541,13 @@ void grid_check_lat_borders_rad(int n, double *ybounds)
 static
 void remap_define_reg2d(int gridID, remapgrid_t *grid)
 {
-  long nx = grid->dims[0];
-  long ny = grid->dims[1];
+  size_t nx = grid->dims[0];
+  size_t ny = grid->dims[1];
 
-  long nxp1 = nx + 1;
-  long nyp1 = ny + 1;
+  size_t nxp1 = nx + 1;
+  size_t nyp1 = ny + 1;
 
-  long nxm = nx;
+  size_t nxm = nx;
   if ( grid->is_cyclic ) nxm++;
 
   if ( grid->size != nx*ny ) cdoAbort("Internal error, wrong dimensions!");
@@ -571,7 +569,7 @@ void remap_define_reg2d(int gridID, remapgrid_t *grid)
   grid_to_radian(yunits, ny, grid->reg2d_center_lat, "grid reg2d center lat");
 
   if ( grid->reg2d_center_lon[nx-1] < grid->reg2d_center_lon[0] )
-    for ( long i = 1; i < nx; ++i )
+    for ( size_t i = 1; i < nx; ++i )
       if ( grid->reg2d_center_lon[i] < grid->reg2d_center_lon[i-1] )
         grid->reg2d_center_lon[i] += PI2;
 
@@ -584,8 +582,8 @@ void remap_define_reg2d(int gridID, remapgrid_t *grid)
   grid_gen_corners(ny, grid->reg2d_center_lat, grid->reg2d_corner_lat);
   grid_check_lat_borders_rad(ny+1, grid->reg2d_corner_lat);
 
-  //for ( long i = 0; i < nxp1; ++i ) printf("lon %ld %g\n", i, grid->reg2d_corner_lon[i]);
-  //for ( long i = 0; i < nyp1; ++i ) printf("lat %ld %g\n", i, grid->reg2d_corner_lat[i]);
+  //for ( size_t i = 0; i < nxp1; ++i ) printf("lon %zu %g\n", i, grid->reg2d_corner_lon[i]);
+  //for ( size_t i = 0; i < nyp1; ++i ) printf("lat %zu %g\n", i, grid->reg2d_corner_lat[i]);
 
 }
 
@@ -614,7 +612,7 @@ void remap_define_grid(int map_type, int gridID, remapgrid_t *grid, const char *
 	}
     }
 
-  long gridsize = grid->size = gridInqSize(gridID);
+  size_t gridsize = grid->size = gridInqSize(gridID);
 
   grid->dims[0] = gridInqXsize(gridID);
   grid->dims[1] = gridInqYsize(gridID);
@@ -637,13 +635,13 @@ void remap_define_grid(int map_type, int gridID, remapgrid_t *grid, const char *
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) shared(gridsize, grid)
 #endif
-  for ( long i = 0; i < gridsize; ++i ) grid->mask[i] = TRUE;
+  for ( size_t i = 0; i < gridsize; ++i ) grid->mask[i] = TRUE;
 
   if ( gridInqMask(gridID, NULL) )
     {
       int *mask = (int*) Malloc(gridsize*sizeof(int));
       gridInqMask(gridID, mask);
-      for ( long i = 0; i < gridsize; ++i )
+      for ( size_t i = 0; i < gridsize; ++i )
 	if ( mask[i] == 0 ) grid->mask[i] = FALSE;
       Free(mask);
     }
@@ -728,8 +726,8 @@ void cell_bounding_boxes(remapgrid_t *grid, int remap_grid_basis)
 	}
       else /* full grid search */
 	{
-	  long gridsize;
-	  long i, i4;
+	  size_t gridsize;
+	  size_t i, i4;
 	  
 	  gridsize = grid->size;
   
@@ -749,8 +747,8 @@ void cell_bounding_boxes(remapgrid_t *grid, int remap_grid_basis)
     {
       if ( grid->rank != 2 ) cdoAbort("Internal problem, grid rank = %d!", grid->rank);
 
-      long nx = grid->dims[0];
-      long ny = grid->dims[1];
+      size_t nx = grid->dims[0];
+      size_t ny = grid->dims[1];
 
       if ( cdoVerbose ) cdoPrint("Grid: boundbox_from_center");
 
@@ -905,7 +903,7 @@ void remap_grids_init(int map_type, bool lextrapolate, int gridID1, remapgrid_t
     This routine initializes some variables and provides an initial
     allocation of arrays (fairly large so frequent resizing unnecessary).
 */
-void remap_vars_init(int map_type, long src_grid_size, long tgt_grid_size, remapvars_t *rv)
+void remap_vars_init(int map_type, size_t src_grid_size, size_t tgt_grid_size, remapvars_t *rv)
 {
   /* Initialize all pointer */
   if ( rv->pinit == false )
@@ -958,13 +956,13 @@ void remap_vars_init(int map_type, long src_grid_size, long tgt_grid_size, remap
   rv->num_links = 0;
   rv->max_links = 4 * tgt_grid_size;
 
-  rv->resize_increment = (int) (0.1 * MAX(src_grid_size, tgt_grid_size));
+  rv->resize_increment = (size_t) (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*) Malloc(rv->max_links*sizeof(int));
-      rv->tgt_cell_add = (int*) Malloc(rv->max_links*sizeof(int));
+      rv->src_cell_add = (size_t*) Malloc(rv->max_links*sizeof(size_t));
+      rv->tgt_cell_add = (size_t*) Malloc(rv->max_links*sizeof(size_t));
 
       rv->wts = (double*) Malloc(rv->num_wts*rv->max_links*sizeof(double));
     }
@@ -997,8 +995,8 @@ void resize_remap_vars(remapvars_t *rv, int increment)
 
   if ( rv->max_links )
     {
-      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_cell_add = (size_t*) Realloc(rv->src_cell_add, rv->max_links*sizeof(size_t));
+      rv->tgt_cell_add = (size_t*) Realloc(rv->tgt_cell_add, rv->max_links*sizeof(size_t));
 
       rv->wts = (double*) Realloc(rv->wts, rv->num_wts*rv->max_links*sizeof(double));
     }
@@ -1012,8 +1010,8 @@ void resize_remap_vars(remapvars_t *rv, int increment)
      
   -----------------------------------------------------------------------
 */
-void remap(double *restrict dst_array, double missval, long dst_size, long num_links, double *restrict map_wts, 
-	   long num_wts, const int *restrict dst_add, const int *restrict src_add, const double *restrict src_array, 
+void remap(double *restrict dst_array, double missval, size_t dst_size, size_t num_links, double *restrict map_wts, 
+	   size_t num_wts, const size_t *restrict dst_add, const size_t *restrict src_add, const double *restrict src_array, 
 	   const double *restrict src_grad1, const double *restrict src_grad2, const double *restrict src_grad3,
 	   remaplink_t links, long links_per_value)
 {
@@ -1046,7 +1044,7 @@ void remap(double *restrict dst_array, double missval, long dst_size, long num_l
 
   int iorder = (src_grad1 == NULL) ? 1 : 2;
 
-  for ( long n = 0; n < dst_size; ++n ) dst_array[n] = missval;
+  for ( size_t n = 0; n < dst_size; ++n ) dst_array[n] = missval;
 
   if ( cdoTimer ) timer_start(timer_remap);
 
@@ -1057,18 +1055,18 @@ void remap(double *restrict dst_array, double missval, long dst_size, long num_l
 #ifdef SX
 #pragma cdir nodep
 #endif
-          for ( long n = 0; n < num_links; ++n ) dst_array[dst_add[n]] = 0.;
+          for ( size_t n = 0; n < num_links; ++n ) dst_array[dst_add[n]] = 0.;
 
-	  for ( long j = 0; j < links.num_blks; ++j )
+	  for ( size_t j = 0; j < links.num_blks; ++j )
 	    {
-              const int *restrict dst_addx = links.dst_add[j];
-              const int *restrict src_addx = links.src_add[j];
-              const int *restrict windex = links.w_index[j];
+              const size_t *restrict dst_addx = links.dst_add[j];
+              const size_t *restrict src_addx = links.src_add[j];
+              const size_t *restrict windex = links.w_index[j];
 
 #if defined(HAVE_OPENMP4)
 #pragma omp simd
 #endif
-	      for ( long n = 0; n < links.num_links[j]; ++n )
+	      for ( size_t n = 0; n < links.num_links[j]; ++n )
 		{
 		  dst_array[dst_addx[n]] += src_array[src_addx[n]]*map_wts[num_wts*windex[n]];
 		}
@@ -1079,16 +1077,16 @@ void remap(double *restrict dst_array, double missval, long dst_size, long num_l
           long lpv = links_per_value;
           if ( lpv > 0 )
             {
-              long nlinks = num_links/lpv;
+              size_t nlinks = num_links/lpv;
 
               if ( lpv == 4 )
                 {
 #if defined(_OPENMP)
 #pragma omp parallel for default(none)  shared(dst_array, src_array, dst_add, src_add, map_wts, num_wts, nlinks, lpv)
 #endif
-                  for ( long n = 0; n < nlinks; ++n )
+                  for ( size_t n = 0; n < nlinks; ++n )
                     {
-                      long noff = n*lpv;
+                      size_t noff = n*lpv;
                       dst_array[dst_add[noff]] = src_array[src_add[noff]]*map_wts[num_wts*(noff)] +
                                                  src_array[src_add[noff+1]]*map_wts[num_wts*(noff+1)] +
                                                  src_array[src_add[noff+2]]*map_wts[num_wts*(noff+2)] +
@@ -1100,11 +1098,11 @@ void remap(double *restrict dst_array, double missval, long dst_size, long num_l
 #if defined(_OPENMP)
 #pragma omp parallel for default(none)  shared(dst_array, src_array, dst_add, src_add, map_wts, num_wts, nlinks, lpv)
 #endif
-                  for ( long n = 0; n < nlinks; ++n )
+                  for ( size_t n = 0; n < nlinks; ++n )
                     {
-                      long noff = n*lpv;
+                      size_t noff = n*lpv;
                       dst_array[dst_add[noff]] = src_array[src_add[noff]]*map_wts[num_wts*noff];
-                      for ( long k = 1; k < lpv; ++k )
+                      for ( size_t k = 1; k < (size_t)lpv; ++k )
                         dst_array[dst_add[noff]] += src_array[src_add[noff+k]]*map_wts[num_wts*(noff+k)];
                     }
                 }
@@ -1114,9 +1112,9 @@ void remap(double *restrict dst_array, double missval, long dst_size, long num_l
 #ifdef SX
 #pragma cdir nodep
 #endif
-              for ( long n = 0; n < num_links; ++n ) dst_array[dst_add[n]] = 0.;
+              for ( size_t n = 0; n < num_links; ++n ) dst_array[dst_add[n]] = 0.;
 
-              for ( long n = 0; n < num_links; ++n )
+              for ( size_t n = 0; n < num_links; ++n )
                 {
                   // printf("%5d %5d %5ld %g # dst_add src_add n\n", dst_add[n], src_add[n], n, map_wts[num_wts*n]);
                   dst_array[dst_add[n]] += src_array[src_add[n]]*map_wts[num_wts*n];
@@ -1129,11 +1127,11 @@ void remap(double *restrict dst_array, double missval, long dst_size, long num_l
 #ifdef SX
 #pragma cdir nodep
 #endif
-      for ( long n = 0; n < num_links; ++n ) dst_array[dst_add[n]] = 0.;
+      for ( size_t n = 0; n < num_links; ++n ) dst_array[dst_add[n]] = 0.;
 
       if ( num_wts == 3 )
 	{
-	  for ( long n = 0; n < num_links; ++n )
+	  for ( size_t n = 0; n < num_links; ++n )
 	    {
 	      dst_array[dst_add[n]] += src_array[src_add[n]]*map_wts[3*n] +
                                        src_grad1[src_add[n]]*map_wts[3*n+1] +
@@ -1142,7 +1140,7 @@ void remap(double *restrict dst_array, double missval, long dst_size, long num_l
 	}
       else if ( num_wts == 4 )
 	{
-      	  for ( long n = 0; n < num_links; ++n )
+      	  for ( size_t n = 0; n < num_links; ++n )
 	    {
               dst_array[dst_add[n]] += src_array[src_add[n]]*map_wts[4*n] +
                                        src_grad1[src_add[n]]*map_wts[4*n+1] +
@@ -1156,28 +1154,28 @@ void remap(double *restrict dst_array, double missval, long dst_size, long num_l
 }
 
 static
-long get_max_add(long num_links, long size, const int *restrict add)
+size_t get_max_add(size_t num_links, size_t size, const size_t *restrict add)
 {
-  int *isum = (int*) Malloc(size*sizeof(int));
-  memset(isum, 0, size*sizeof(int));
+  size_t *isum = (size_t*) Malloc(size*sizeof(size_t));
+  memset(isum, 0, size*sizeof(size_t));
 
-  for ( long n = 0; n < num_links; ++n ) isum[add[n]]++;
+  for ( size_t n = 0; n < num_links; ++n ) isum[add[n]]++;
 
-  long max_add = 0;
-  for ( long i = 0; i < size; ++i ) if ( isum[i] > max_add ) max_add = isum[i];
+  size_t max_add = 0;
+  for ( size_t i = 0; i < size; ++i ) if ( isum[i] > max_add ) max_add = isum[i];
   Free(isum);
 
   return max_add;
 }
 
 static 
-long binary_search_int(const int *array, long len, int value)
+size_t binary_search_int(const size_t *array, size_t len, size_t value)
 {       
   long low = 0, high = len - 1, midpoint = 0;
  
   while ( low <= high )
     {
-      midpoint = low + (high - low)/2;      
+      midpoint = low + (high - low)/2;
  
       // check to see if value is equal to item in array
       if ( value == array[midpoint] ) return midpoint;
@@ -1189,7 +1187,7 @@ long binary_search_int(const int *array, long len, int value)
     }
  
   // item was not found
-  return -1L;
+  return len;
 }
 
 /*
@@ -1199,8 +1197,8 @@ long binary_search_int(const int *array, long len, int value)
      
   -----------------------------------------------------------------------
 */
-void remap_laf(double *restrict dst_array, double missval, long dst_size, long num_links, double *restrict map_wts,
-	       long num_wts, const int *restrict dst_add, const int *restrict src_add, const double *restrict src_array)
+void remap_laf(double *restrict dst_array, double missval, size_t dst_size, size_t num_links, double *restrict map_wts,
+	       size_t num_wts, const size_t *restrict dst_add, const size_t *restrict src_add, const double *restrict src_array)
 {
   /*
     Input arrays:
@@ -1219,19 +1217,16 @@ void remap_laf(double *restrict dst_array, double missval, long dst_size, long n
     double *dst_array    ! array for remapped field on destination grid
   */
 
-  /* Local variables */
-  long n, k;
-
-  for ( long i = 0; i < dst_size; ++i ) dst_array[i] = missval;
+  for ( size_t i = 0; i < dst_size; ++i ) dst_array[i] = missval;
 
   if ( num_links == 0 ) return;
 
-  long max_cls = get_max_add(num_links, dst_size, dst_add);
+  size_t max_cls = get_max_add(num_links, dst_size, dst_add);
 
 #if defined(_OPENMP)
   double **src_cls2 = (double **) Malloc(ompNumThreads*sizeof(double *));
   double **src_wts2 = (double **) Malloc(ompNumThreads*sizeof(double *));
-  for ( long i = 0; i < ompNumThreads; ++i )
+  for ( int  i = 0; i < ompNumThreads; ++i )
     {
       src_cls2[i] = (double*) Malloc(max_cls*sizeof(double));
       src_wts2[i] = (double*) Malloc(max_cls*sizeof(double));
@@ -1241,18 +1236,18 @@ void remap_laf(double *restrict dst_array, double missval, long dst_size, long n
   double *src_wts = (double*) Malloc(max_cls*sizeof(double));
 #endif
 
-  for ( long n = 0; n < num_links; ++n )
+  for ( size_t n = 0; n < num_links; ++n )
     if ( DBL_IS_EQUAL(dst_array[dst_add[n]], missval) ) dst_array[dst_add[n]] = ZERO;
 
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) \
   shared(dst_size, src_cls2, src_wts2, num_links, dst_add, src_add, src_array, map_wts, num_wts, dst_array, max_cls)  \
-  private(n, k) \
   schedule(dynamic,1)
 #endif
-  for ( long i = 0; i < dst_size; ++i )
+  for ( size_t i = 0; i < dst_size; ++i )
     {
-      long ncls;
+      size_t k;
+      size_t ncls;
 #if defined(_OPENMP)
       int ompthID = cdo_omp_get_thread_num();
       double *src_cls = src_cls2[ompthID];
@@ -1281,11 +1276,11 @@ void remap_laf(double *restrict dst_array, double missval, long dst_size, long n
       */
       /* only for sorted dst_add! */
       {
-      long min_add = 1, max_add = 0;
+      size_t min_add = 1, max_add = 0;
 
-      n = binary_search_int(dst_add, num_links, (int)i);
+      size_t n = binary_search_int(dst_add, num_links, i);
 
-      if ( n >= 0 && n < num_links )
+      if ( n < num_links )
 	{
 	  min_add = n;
 	  
@@ -1318,7 +1313,7 @@ void remap_laf(double *restrict dst_array, double missval, long dst_size, long n
       
       if ( ncls )
 	{
-	  long imax = 0;
+	  size_t imax = 0;
 	  double wts = src_wts[0];
 	  for ( k = 1; k < ncls; ++k )
 	    {
@@ -1334,7 +1329,7 @@ void remap_laf(double *restrict dst_array, double missval, long dst_size, long n
     }
 
 #if defined(_OPENMP)
-  for ( long i = 0; i < ompNumThreads; ++i )
+  for ( int  i = 0; i < ompNumThreads; ++i )
     {
       Free(src_cls2[i]);
       Free(src_wts2[i]);
@@ -1355,8 +1350,8 @@ void remap_laf(double *restrict dst_array, double missval, long dst_size, long n
      
   -----------------------------------------------------------------------
 */
-void remap_sum(double *restrict dst_array, double missval, long dst_size, long num_links, double *restrict map_wts,
-	       long num_wts, const int *restrict dst_add, const int *restrict src_add, const double *restrict src_array)
+void remap_sum(double *restrict dst_array, double missval, size_t dst_size, size_t num_links, double *restrict map_wts,
+	       size_t num_wts, const size_t *restrict dst_add, const size_t *restrict src_add, const double *restrict src_array)
 {
   /*
     Input arrays:
@@ -1374,22 +1369,22 @@ void remap_sum(double *restrict dst_array, double missval, long dst_size, long n
     double *dst_array    ! array for remapped field on destination grid
   */
 
-  for ( long n = 0; n < dst_size; ++n ) dst_array[n] = missval;
+  for ( size_t n = 0; n < dst_size; ++n ) dst_array[n] = missval;
 
 #ifdef SX
 #pragma cdir nodep
 #endif
-  for ( long n = 0; n < num_links; ++n )
+  for ( size_t n = 0; n < num_links; ++n )
     if ( DBL_IS_EQUAL(dst_array[dst_add[n]], missval) ) dst_array[dst_add[n]] = ZERO;
 
-  for ( long n = 0; n < num_links; ++n )
+  for ( size_t n = 0; n < num_links; ++n )
     {
       /*
 	printf("%5d %5d %5d %g # dst_add src_add n\n", dst_add[n], src_add[n], n, map_wts[num_wts*n]);
       */
       //dst_array[dst_add[n]] += src_array[src_add[n]]*map_wts[num_wts*n];
       dst_array[dst_add[n]] += src_array[src_add[n]]*map_wts[num_wts*n];
-      printf("%ld %d %d %g %g %g\n", n, dst_add[n], src_add[n],
+      printf("%zu %zu %zu %g %g %g\n", n, dst_add[n], src_add[n],
 	     src_array[src_add[n]], map_wts[num_wts*n], dst_array[dst_add[n]]);
     }
 }
@@ -1405,11 +1400,11 @@ void remap_stat(int remap_order, remapgrid_t src_grid, remapgrid_t tgt_grid, rem
     cdoPrint("First order mapping from grid1 to grid2:");
   cdoPrint("----------------------------------------");
 
-  long ns = 0;
+  size_t ns = 0;
   double sum = 0;
   double minval =  DBL_MAX;
   double maxval = -DBL_MAX;
-  for ( long n = 0; n < src_grid.size; ++n )
+  for ( size_t n = 0; n < src_grid.size; ++n )
     {
       if ( !DBL_IS_EQUAL(array1[n], missval) )
 	{
@@ -1426,7 +1421,7 @@ void remap_stat(int remap_order, remapgrid_t src_grid, remapgrid_t tgt_grid, rem
   sum = 0;
   minval =  DBL_MAX;
   maxval = -DBL_MAX;
-  for ( long n = 0; n < tgt_grid.size; ++n )
+  for ( size_t n = 0; n < tgt_grid.size; ++n )
     {
       if ( !DBL_IS_EQUAL(array2[n], missval) )
 	{
@@ -1445,13 +1440,13 @@ void remap_stat(int remap_order, remapgrid_t src_grid, remapgrid_t tgt_grid, rem
     {
       cdoPrint("Conservation:");
       sum = 0;
-      for ( long n = 0; n < src_grid.size; ++n )
+      for ( size_t n = 0; n < src_grid.size; ++n )
 	if ( !DBL_IS_EQUAL(array1[n], missval) )
 	  sum += array1[n]*src_grid.cell_area[n]*src_grid.cell_frac[n];
       cdoPrint("Grid1 Integral = %g", sum);
 
       sum = 0;
-      for ( long n = 0; n < tgt_grid.size; ++n )
+      for ( size_t n = 0; n < tgt_grid.size; ++n )
 	if ( !DBL_IS_EQUAL(array2[n], missval) )
 	  sum += array2[n]*tgt_grid.cell_area[n]*tgt_grid.cell_frac[n];
       cdoPrint("Grid2 Integral = %g", sum);
@@ -1467,18 +1462,18 @@ void remap_stat(int remap_order, remapgrid_t src_grid, remapgrid_t tgt_grid, rem
   cdoPrint("Number of sparse matrix entries %d", rv.num_links);
   cdoPrint("Total number of dest cells %d", tgt_grid.size);
 
-  int *tgt_count = (int*) Malloc(tgt_grid.size*sizeof(int));
+  size_t *tgt_count = (size_t*) Malloc(tgt_grid.size*sizeof(size_t));
 
-  for ( long n = 0; n < tgt_grid.size; ++n ) tgt_count[n] = 0;
+  for ( size_t n = 0; n < tgt_grid.size; ++n ) tgt_count[n] = 0;
 
 #if defined(SX)
 #pragma vdir nodep
 #endif
-  for ( long n = 0; n < rv.num_links; ++n ) tgt_count[rv.tgt_cell_add[n]]++;
+  for ( size_t n = 0; n < rv.num_links; ++n ) tgt_count[rv.tgt_cell_add[n]]++;
 
-  long imin = INT_MAX;
-  long imax = INT_MIN;
-  for ( long n = 0; n < tgt_grid.size; ++n )
+  size_t imin = ULONG_MAX;
+  size_t imax = 0;
+  for ( size_t n = 0; n < tgt_grid.size; ++n )
     {
       if ( tgt_count[n] > 0 )
         {
@@ -1487,9 +1482,9 @@ void remap_stat(int remap_order, remapgrid_t src_grid, remapgrid_t tgt_grid, rem
         }
     }
 
-  long idiff =  (imax - imin)/10 + 1;
-  long icount = 0;
-  for ( long i = 0; i < tgt_grid.size; ++i )
+  size_t idiff =  (imax - imin)/10 + 1;
+  size_t icount = 0;
+  for ( size_t i = 0; i < tgt_grid.size; ++i )
     if ( tgt_count[i] > 0 ) icount++;
 
   cdoPrint("Number of cells participating in remap %d", icount);
@@ -1500,10 +1495,10 @@ void remap_stat(int remap_order, remapgrid_t src_grid, remapgrid_t tgt_grid, rem
       cdoPrint("Max no of entries/row = %d", imax);
 
       imax = imin + idiff;
-      for ( long n = 0; n < 10; ++n )
+      for ( size_t n = 0; n < 10; ++n )
 	{
 	  icount = 0;
-	  for ( long i = 0; i < tgt_grid.size; ++i )
+	  for ( size_t i = 0; i < tgt_grid.size; ++i )
 	    if ( tgt_count[i] >= imin && tgt_count[i] < imax ) icount++;
 
 	  if ( icount )
@@ -1525,23 +1520,23 @@ void remap_stat(int remap_order, remapgrid_t src_grid, remapgrid_t tgt_grid, rem
 void remap_gradients(remapgrid_t grid, const double *restrict array, double *restrict grad_lat,
 		     double *restrict grad_lon, double *restrict grad_latlon)
 {
-  long i, j, ip1, im1, jp1, jm1, in, is, ie, iw, ine, inw, ise, isw;
+  size_t i, j, ip1, im1, jp1, jm1, in, is, ie, iw, ine, inw, ise, isw;
   double delew, delns;
   double grad_lat_zero, grad_lon_zero;
 
   if ( grid.rank != 2 )
     cdoAbort("Internal problem (remap_gradients), grid rank = %d!", grid.rank);
 
-  long grid_size = grid.size;
-  long nx = grid.dims[0];
-  long ny = grid.dims[1];
+  size_t grid_size = grid.size;
+  size_t nx = grid.dims[0];
+  size_t ny = grid.dims[1];
 
 #if defined(_OPENMP)
 #pragma omp parallel for default(none)        \
   shared(grid_size, grad_lat, grad_lon, grad_latlon, grid, nx, ny, array) \
   private(i, j, ip1, im1, jp1, jm1, in, is, ie, iw, ine, inw, ise, isw, delew, delns, grad_lat_zero, grad_lon_zero)
 #endif
-  for ( long n = 0; n < grid_size; ++n )
+  for ( size_t n = 0; n < grid_size; ++n )
     {
       grad_lat[n] = ZERO;
       grad_lon[n] = ZERO;
@@ -1726,17 +1721,17 @@ void remap_gradients(remapgrid_t grid, const double *restrict array, double *res
 
 void reorder_links(remapvars_t *rv)
 {
-  long j, nval = 0, num_blks = 0;
-  long n;
+  size_t j, nval = 0, num_blks = 0;
+  size_t n;
 
-  long num_links = rv->num_links;
+  size_t num_links = rv->num_links;
 
   printf("reorder_links\n");
-  printf("  num_links %ld\n", num_links);
+  printf("  num_links %zu\n", num_links);
   rv->links.option = true;
 
-  long lastval = -1;
-  long max_links = 0;
+  size_t lastval = -1;
+  size_t max_links = 0;
   for ( n = 0; n < num_links; n++ )
     {
       if ( rv->tgt_cell_add[n] == lastval ) nval++;
@@ -1754,26 +1749,26 @@ void reorder_links(remapvars_t *rv)
       rv->links.max_links = max_links;
       rv->links.num_blks  = num_blks;
 
-      printf("num_links %ld  max_links %ld  num_blks %ld\n", rv->num_links, max_links, num_blks);
+      printf("num_links %zu  max_links %zu  num_blks %zu\n", rv->num_links, max_links, num_blks);
 
-      rv->links.num_links = (int*) Malloc(num_blks*sizeof(int));
-      rv->links.dst_add   = (int **) Malloc(num_blks*sizeof(int *));
-      rv->links.src_add   = (int **) Malloc(num_blks*sizeof(int *));
-      rv->links.w_index   = (int **) Malloc(num_blks*sizeof(int *));
+      rv->links.num_links = (size_t  *) Malloc(num_blks*sizeof(size_t));
+      rv->links.dst_add   = (size_t **) Malloc(num_blks*sizeof(size_t *));
+      rv->links.src_add   = (size_t **) Malloc(num_blks*sizeof(size_t *));
+      rv->links.w_index   = (size_t **) Malloc(num_blks*sizeof(size_t *));
     }
 
   for ( j = 0; j < num_blks; j++ )
     {
-      rv->links.dst_add[j] = (int*) Malloc(max_links*sizeof(int));
-      rv->links.src_add[j] = (int*) Malloc(max_links*sizeof(int));
-      rv->links.w_index[j] = (int*) Malloc(max_links*sizeof(int));
+      rv->links.dst_add[j] = (size_t*) Malloc(max_links*sizeof(size_t));
+      rv->links.src_add[j] = (size_t*) Malloc(max_links*sizeof(size_t));
+      rv->links.w_index[j] = (size_t*) Malloc(max_links*sizeof(size_t));
     }
 
   for ( j = 0; j < num_blks; j++ )
     {
       nval = 0;
       lastval = -1;
-      long nlinks = 0;
+      size_t nlinks = 0;
 
       for ( n = 0; n < num_links; n++ )
 	{
@@ -1794,14 +1789,14 @@ void reorder_links(remapvars_t *rv)
 	}
 
       rv->links.num_links[j] = nlinks;
-      printf("loop %ld  nlinks %ld\n", j+1, nlinks);
+      printf("loop %zu  nlinks %zu\n", j+1, nlinks);
     }
 }
 
 
-void remapCheckArea(int grid_size, double *restrict cell_area, const char *name)
+void remapCheckArea(size_t grid_size, double *restrict cell_area, const char *name)
 {
-  for ( int n = 0; n < grid_size; ++n )
+  for ( size_t n = 0; n < grid_size; ++n )
     {
       if ( cell_area[n] < -.01 )
         cdoPrint("%s grid area error: %d %g", name, n, cell_area[n]);
@@ -1809,9 +1804,9 @@ void remapCheckArea(int grid_size, double *restrict cell_area, const char *name)
 }
 
 
-void remapCheckWeights(long num_links, int num_wts, int norm_opt, int *src_cell_add, int *tgt_cell_add, double *wts)
+void remapCheckWeights(size_t num_links, size_t num_wts, int norm_opt, size_t *src_cell_add, size_t *tgt_cell_add, double *wts)
 {
-  for ( long n = 0; n < num_links; ++n )
+  for ( size_t n = 0; n < num_links; ++n )
     {
       if ( wts[n*num_wts] < -0.01 )
         cdoPrint("Map weight < 0! grid1idx=%d grid2idx=%d nlink=%d wts=%g",
diff --git a/src/remapsort.cc b/src/remapsort.cc
index b092ab3..e02093d 100644
--- a/src/remapsort.cc
+++ b/src/remapsort.cc
@@ -12,9 +12,9 @@
 /*****************************************************************************/
 
 static
-int isSorted(int *restrict array1, int *restrict array2, const long size)
+int isSorted(size_t *restrict array1, size_t *restrict array2, const size_t size)
 {
-  for ( long idx = 1; idx < size; ++idx )
+  for ( size_t idx = 1; idx < size; ++idx )
     {
       if (  (array1[idx-1] >  array1[idx]) ||
 	   ((array1[idx-1] == array1[idx]) &&
@@ -92,13 +92,13 @@ void remap_heapsort_recursiv(const long num_links, int *restrict arr1, int *rest
 */
 
 static
-void remap_heapsort(const long num_links, int *restrict add1, int *restrict add2, int *restrict idx)
+void remap_heapsort(const size_t num_links, size_t *restrict add1, size_t *restrict add2, size_t *restrict idx)
 {
-  int add1_tmp, add2_tmp;  /* temp for addresses during swap     */
-  int idx_tmp;
-  long lvl, final_lvl;     /* level indexes for heap sort levels */
-  long chk_lvl1, max_lvl;
-  long i;
+  size_t add1_tmp, add2_tmp;  /* temp for addresses during swap     */
+  size_t idx_tmp;
+  long lvl;     /* level indexes for heap sort levels */
+  size_t chk_lvl1, max_lvl, final_lvl;
+  size_t i;
 
   /*
     start at the lowest level (N/2) of the tree and shift lower 
@@ -196,7 +196,7 @@ void remap_heapsort(const long num_links, int *restrict add1, int *restrict add2
 
           chk_lvl1 = 2*final_lvl+1;
           max_lvl  = 2*final_lvl+2;
-          if ( max_lvl >= lvl ) max_lvl = chk_lvl1;
+          if ( max_lvl >= (size_t)lvl ) max_lvl = chk_lvl1;
 
           if ( (add1[chk_lvl1] >  add1[max_lvl]) ||
               ((add1[chk_lvl1] == add1[max_lvl]) &&
@@ -232,7 +232,7 @@ void remap_heapsort(const long num_links, int *restrict add1, int *restrict add2
 	      idx[final_lvl]  = idx[max_lvl];
 
 	      final_lvl = max_lvl;
-	      if ( 2*final_lvl+1 >= lvl )
+	      if ( 2*final_lvl+1 >= (size_t)lvl )
 		{
 		  add1[final_lvl] = add1_tmp;
 		  add2[final_lvl] = add2_tmp;
@@ -262,7 +262,7 @@ void remap_heapsort(const long num_links, int *restrict add1, int *restrict add2
 }
 
 
-void sort_add(long num_links, long num_wts, int *restrict add1, int *restrict add2, double *restrict weights)
+void sort_add(size_t num_links, size_t num_wts, size_t *restrict add1, size_t *restrict add2, double *restrict weights)
 {
   /*
     This routine sorts address and weight arrays based on the destination address with the 
@@ -278,24 +278,18 @@ void sort_add(long num_links, long num_wts, int *restrict add1, int *restrict ad
        weights         ! remapping weights [num_links*num_wts]
   */
 
-  /* Local variables */
-
-  int *idx;
-  long i, n;
-  double *wgt_tmp;
-
   if ( num_links <= 1 ) return;
 
-  idx = (int*) Malloc(num_links*sizeof(int));
-  for ( i = 0; i < num_links; ++i ) idx[i] = i;
+  size_t *idx = (size_t*) Malloc(num_links*sizeof(size_t));
+  for ( size_t i = 0; i < num_links; ++i ) idx[i] = i;
 
   remap_heapsort(num_links, add1, add2, idx);
 
-  wgt_tmp = (double*) Malloc(num_wts*num_links*sizeof(double));
+  double *wgt_tmp = (double*) Malloc(num_wts*num_links*sizeof(double));
   memcpy(wgt_tmp, weights, num_wts*num_links*sizeof(double));
 
-  for ( i = 0; i < num_links; ++i )
-    for ( n = 0; n < num_wts; ++n )
+  for ( size_t i = 0; i < num_links; ++i )
+    for ( size_t n = 0; n < num_wts; ++n )
       weights[num_wts*i+n] = wgt_tmp[num_wts*idx[i]+n];
 
   Free(wgt_tmp);
@@ -307,7 +301,7 @@ void sort_add(long num_links, long num_wts, int *restrict add1, int *restrict ad
 
 /*****************************************************************************/
 
-void sort_add_orig(long num_links, long num_wts, int *restrict add1, int *restrict add2, double *restrict weights)
+void sort_add_orig(size_t num_links, size_t num_wts, size_t *restrict add1, size_t *restrict add2, double *restrict weights)
 {
   /*
     This routine sorts address and weight arrays based on the
@@ -326,10 +320,10 @@ void sort_add_orig(long num_links, long num_wts, int *restrict add1, int *restri
 
   /* Local variables */
 
-  int add1_tmp, add2_tmp;  /* temp for addresses during swap     */
-  long lvl, final_lvl;     /* level indexes for heap sort levels */
-  long chk_lvl1, chk_lvl2, max_lvl;
-  long i, n;
+  size_t add1_tmp, add2_tmp;  /* temp for addresses during swap     */
+  long lvl;     /* level indexes for heap sort levels */
+  size_t chk_lvl1, chk_lvl2, max_lvl, final_lvl;
+  size_t i, n;
   double wgttmp[4];        /* temp for holding wts during swap   */
 
   if ( num_links <= 1 ) return;
@@ -441,7 +435,7 @@ void sort_add_orig(long num_links, long num_wts, int *restrict add1, int *restri
 
           chk_lvl1 = 2*final_lvl+1;
           chk_lvl2 = 2*final_lvl+2;
-          if ( chk_lvl2 >= lvl ) chk_lvl2 = chk_lvl1;
+          if ( chk_lvl2 >= (size_t)lvl ) chk_lvl2 = chk_lvl1;
 
           if ((add1[chk_lvl1] >  add1[chk_lvl2]) ||
              ((add1[chk_lvl1] == add1[chk_lvl2]) &&
@@ -479,7 +473,7 @@ void sort_add_orig(long num_links, long num_wts, int *restrict add1, int *restri
 		weights[num_wts*final_lvl+n] = weights[num_wts*max_lvl+n];
 
 	      final_lvl = max_lvl;
-	      if ( 2*final_lvl+1 >= lvl )
+	      if ( 2*final_lvl+1 >= (size_t)lvl )
 		{
 		  add1[final_lvl] = add1_tmp;
 		  add2[final_lvl] = add2_tmp;
@@ -541,7 +535,7 @@ void sort_add_orig(long num_links, long num_wts, int *restrict add1, int *restri
 
 
 static
-void merge_lists(int *nl, int *l11, int *l12, int *l21, int *l22, long *idx)
+void merge_lists(size_t *nl, size_t *l11, size_t *l12, size_t *l21, size_t *l22, size_t *idx)
 {      
   /*
     This routine writes to idx a list of indices relative to *l11 and *l12
@@ -551,8 +545,8 @@ void merge_lists(int *nl, int *l11, int *l12, int *l21, int *l22, long *idx)
                         OR (II) l11[idx[i]]==l11[idx[i+1]] && l21[idx[i]]<l21[idx[i+1]]
 		       where 0 <= i < nl
   */    		       
-  int i1=0, i2=0, i=0, ii;
-  const int n1=nl[0], n2=nl[1];
+  size_t i1=0, i2=0, i=0, ii;
+  const size_t n1=nl[0], n2=nl[1];
 
   i=0;
   while ( i2 < n2 && i1 < n1 ) 
@@ -570,7 +564,7 @@ void merge_lists(int *nl, int *l11, int *l12, int *l21, int *l22, long *idx)
 }
 
 static
-void sort_par(long num_links, long num_wts, int *restrict add1, int *restrict add2, 
+void sort_par(size_t num_links, size_t num_wts, size_t *restrict add1, size_t *restrict add2, 
 	      double *restrict weights, int parent, int par_depth)
 {
   /*
@@ -599,19 +593,18 @@ void sort_par(long num_links, long num_wts, int *restrict add1, int *restrict ad
   */
 
 
-  const int nsplit = 2;                      /* (only 2 allowed) number of segments to split the data */
-  int nl[nsplit];                            /* number of links in each sub-array              */
-  int who_am_i;                              /* current depth, depth of children and index
-						to be parent in next call to sort_par          */
-  int add_srt[nsplit]/*, add_end[nsplit]*/;  /* arrays for start and end index of sub array    */
-  int *add1s[nsplit], *add2s[nsplit];        /* pointers to sub arrays for sort and merge step */
-  int *tmp;                                  /* pointer to buffer for merging of address lists */
-  double *tmp2 = NULL;                       /* pointer to buffer for merging weight lists     */
-  double *wgttmp = NULL;                     /* pointer to buffer for swap weights             */
-  long *idx;                                 /* index list to merge sub-arrays                 */
-  long i,n,m;   
+  const int nsplit = 2;                         /* (only 2 allowed) number of segments to split the data */
+  size_t nl[nsplit];                            /* number of links in each sub-array              */
+  int who_am_i;                                 /* current depth, depth of children and index
+						   to be parent in next call to sort_par          */
+  size_t add_srt[nsplit]/*, add_end[nsplit]*/;  /* arrays for start and end index of sub array    */
+  size_t *add1s[nsplit], *add2s[nsplit];        /* pointers to sub arrays for sort and merge step */
+  size_t *tmp;                                  /* pointer to buffer for merging of address lists */
+  double *tmp2 = NULL;                          /* pointer to buffer for merging weight lists     */
+  double *wgttmp = NULL;                        /* pointer to buffer for swap weights             */
+  size_t i,n,m;   
 
-  // printf("sort_par: parent = %d numlinks = %ld\n", parent, num_links);
+  // printf("sort_par: parent = %d numlinks = %zu\n", parent, num_links);
   if ( nsplit != 2 )
     {
       fprintf(stderr,"Error: splitting into more than two subsegments not allowed\n"
@@ -619,7 +612,8 @@ void sort_par(long num_links, long num_wts, int *restrict add1, int *restrict ad
       exit(-1);
     }
 
-  idx = (long*) Malloc(num_links*sizeof(long));
+  // index list to merge sub-arrays
+  size_t *idx = (size_t*) Malloc(num_links*sizeof(size_t));
 
   /* SPLIT AND SORT THE DATA FRAGMENTS */
   /*
@@ -697,7 +691,7 @@ void sort_par(long num_links, long num_wts, int *restrict add1, int *restrict ad
                                                               /* ********************** */
   merge_lists(nl,add1s[0],add2s[0],add1s[1],add2s[1], idx);   /* MERGE THE SEGMENTS     */
                                                               /* ********************** */
-  tmp = (int*) Malloc(num_links*sizeof(int));
+  tmp = (size_t*) Malloc(num_links*sizeof(size_t));
   
 #if defined(_OPENMP)
 #pragma omp parallel for if ( depth < par_depth ) private(i) num_threads(2)
@@ -746,7 +740,7 @@ void sort_par(long num_links, long num_wts, int *restrict add1, int *restrict ad
 }
 
 
-void sort_iter(long num_links, long num_wts, int *restrict add1, int *restrict add2, double *restrict weights, int parent)
+void sort_iter(size_t num_links, size_t num_wts, size_t *restrict add1, size_t *restrict add2, double *restrict weights, int parent)
 {
   /*
     This routine is an interface between the parallelized (merge-sort) 
@@ -769,19 +763,19 @@ void sort_iter(long num_links, long num_wts, int *restrict add1, int *restrict a
 		     been called before
 		   + determines number of threads to use on first call of sort_iter(...)
   */
-  static int first_sort_iter_call = 1;
+  static bool first_sort_iter_call = true;
   static int par_depth = 1;
   static int nthreads = 1;
 
   if ( first_sort_iter_call )
     {
-      first_sort_iter_call = 0;
+      first_sort_iter_call = false;
       nthreads = parent;
       par_depth = (int)(log(parent)/log(2));
       parent = 1;
     }
 
-  // fprintf(stdout, "parent %d par_depth %d num_links %ld\n", parent, par_depth, num_links);
+  // fprintf(stdout, "parent %d par_depth %d num_links %zu\n", parent, par_depth, num_links);
 
   if ( num_links > MERGE_SORT_LIMIT_SIZE && parent <= (nthreads-1) )
     {
@@ -790,7 +784,7 @@ void sort_iter(long num_links, long num_wts, int *restrict add1, int *restrict a
     }
   else
     {
-      // printf("sort_add: parent %d, par_depth %d num_links %ld\n", parent, par_depth, num_links);
+      // printf("sort_add: parent %d, par_depth %d num_links %tz\n", parent, par_depth, num_links);
       sort_add(num_links, num_wts, add1, add2, weights);
     }
 }
diff --git a/src/specspace.cc b/src/specspace.cc
index 8ae0ef1..606a008 100644
--- a/src/specspace.cc
+++ b/src/specspace.cc
@@ -69,7 +69,7 @@ void spec2four(SPTRANS *sptrans, int gridIDin, double *arrayIn, int gridIDout, d
 {
   int nlev  = 1;
   int ntr   = gridInqTrunc(gridIDin);
-  int nfc   = gridInqSize(gridIDout);
+  size_t nfc = gridInqSize(gridIDout);
   int nlat  = nfc_to_nlat(nfc, ntr);
   int waves = ntr + 1;
   nfc   = waves * 2;
diff --git a/src/util.cc b/src/util.cc
index bb6bca4..790bdde 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -16,11 +16,11 @@
 */
 
 #if defined(HAVE_CONFIG_H)
-#  include "config.h"
+#include "config.h"
 #endif
 
 #if defined(_OPENMP)
-#  include <omp.h>
+#include <omp.h>
 #endif
 
 #if defined(HAVE_FNMATCH_H)
@@ -40,7 +40,7 @@
 
 
 #if ! defined(VERSION)
-#  define  VERSION  "0.0.1"
+#define  VERSION  "0.0.1"
 #endif
  
 
@@ -238,7 +238,7 @@ const char *getOperatorName(const char *operatorArg)
   /*  return operatorName; */
   if(is_alias(operatorName))
   {
-    get_original(operatorName);
+    operatorName = get_original(operatorName);
   }
     return operatorName;
 }
@@ -665,6 +665,7 @@ const char *filetypeext(int filetype)
     case CDI_FILETYPE_GRB2: return ".grb";
     case CDI_FILETYPE_NC:
     case CDI_FILETYPE_NC2:
+    case CDI_FILETYPE_NC5:
     case CDI_FILETYPE_NC4:
     case CDI_FILETYPE_NC4C: return ".nc";
     case CDI_FILETYPE_SRV:  return ".srv";
@@ -742,7 +743,8 @@ void cdoGenFileSuffix(char *filesuffix, size_t maxlen, int filetype, int vlistID
                           break;
                         case 'n':
                           if ( cdoDefaultFileType == CDI_FILETYPE_NC || cdoDefaultFileType == CDI_FILETYPE_NC2 ||
-                               cdoDefaultFileType == CDI_FILETYPE_NC4 || cdoDefaultFileType == CDI_FILETYPE_NC4C ) lready = true;
+                               cdoDefaultFileType == CDI_FILETYPE_NC4 || cdoDefaultFileType == CDI_FILETYPE_NC4C ||
+                               cdoDefaultFileType == CDI_FILETYPE_NC5 ) lready = true;
                           break;
                         case 's':
                           if ( cdoDefaultFileType == CDI_FILETYPE_SRV ) lready = true;
diff --git a/src/util.h b/src/util.h
index 2e0c793..702f07c 100644
--- a/src/util.h
+++ b/src/util.h
@@ -41,7 +41,7 @@
 
 #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 )
+#define  UNCHANGED_RECORD  (processSelf().m_ID == 0 && cdoStreamName(0)->argv[0][0] != '-' && cdoRegulargrid == FALSE && cdoDefaultFileType == -1 && cdoDefaultDataType == -1 && cdoDefaultByteorder == -1 )
 
 #include <string>
 extern char *Progname;
diff --git a/src/zaxis.cc b/src/zaxis.cc
index 881553b..ba027b7 100644
--- a/src/zaxis.cc
+++ b/src/zaxis.cc
@@ -18,7 +18,6 @@
 #include <cdi.h>
 #include "cdo_int.h"
 
-#define UNDEFID -1
 
 #define MAX_LINE_LEN 65536
 
@@ -28,9 +27,10 @@ typedef struct {
   double *lbounds;
   double *ubounds;
   double *vct;
-  int     vctsize;
+  size_t  vctsize;
   int     type;
-  int     size;
+  int     datatype;
+  size_t  size;
   bool    scalar;
   char    name[CDI_MAX_NAME];
   char    longname[CDI_MAX_NAME];
@@ -45,7 +45,8 @@ void zaxisInit(zaxis_t *zaxis)
   zaxis->lbounds     = NULL;
   zaxis->ubounds     = NULL;
   zaxis->vct         = NULL;
-  zaxis->type        = UNDEFID;
+  zaxis->type        = CDI_UNDEFID;
+  zaxis->datatype    = CDI_UNDEFID;
   zaxis->vctsize     = 0;
   zaxis->size        = 0;
   zaxis->scalar      = false;
@@ -85,13 +86,15 @@ int getoptname(char *optname, const char *optstring, int nopt)
 
 int zaxisDefine(zaxis_t zaxis)
 {
-  if ( zaxis.type == -1 ) cdoAbort("zaxistype undefined!");
+  if ( zaxis.type == CDI_UNDEFID ) cdoAbort("zaxistype undefined!");
   if ( zaxis.size ==  0 ) cdoAbort("zaxis size undefined!");
 
-  int zaxisID = zaxisCreate(zaxis.type, zaxis.size);
+  int zaxisID = zaxisCreate(zaxis.type, (int)zaxis.size);
 
   if ( zaxis.size == 1 && zaxis.scalar ) zaxisDefScalar(zaxisID);
 
+  if ( zaxis.datatype != CDI_UNDEFID ) zaxisDefDatatype(zaxisID, zaxis.datatype);
+
   if ( zaxis.vals )
     {
       zaxisDefLevels(zaxisID, zaxis.vals);
@@ -115,7 +118,7 @@ int zaxisDefine(zaxis_t zaxis)
   if ( zaxis.type == ZAXIS_HYBRID || zaxis.type == ZAXIS_HYBRID_HALF )
     {
       if ( zaxis.vctsize && zaxis.vct )
-	zaxisDefVct(zaxisID, zaxis.vctsize, zaxis.vct);
+	zaxisDefVct(zaxisID, (int)zaxis.vctsize, zaxis.vct);
       else
 	cdoWarning("vct undefined!");	    
     }
@@ -161,6 +164,14 @@ void zaxis_read_data(size_t nkv, kvmap_t *kvmap, zaxis_t *zaxis, size_t *iatt, c
           else if ( STR_IS_EQ(zaxistype, "generic") )           zaxis->type = ZAXIS_GENERIC;
 	  else cdoAbort("Invalid zaxisname : %s (zaxis description file: %s)", zaxistype, dname);
         }
+      else if ( STR_IS_EQ(key, "datatype") )
+        {
+          const char *datatype = parameter2word(value);
+
+          if      ( STR_IS_EQ(datatype, "double") )  zaxis->datatype = CDI_DATATYPE_FLT64;
+          else if ( STR_IS_EQ(datatype, "float") )   zaxis->datatype = CDI_DATATYPE_FLT32;
+	  else cdoAbort("Invalid datatype : %s (zaxis description file: %s)", datatype, dname);
+        }
       else if ( STR_IS_EQ(key, "size") ) zaxis->size = parameter2int(value);
       else if ( STR_IS_EQ(key, "scalar") ) zaxis->scalar = parameter2bool(value);
       else if ( STR_IS_EQ(key, "vctsize") ) zaxis->vctsize = parameter2int(value);
@@ -171,25 +182,25 @@ void zaxis_read_data(size_t nkv, kvmap_t *kvmap, zaxis_t *zaxis, size_t *iatt, c
         {
           if ( zaxis->size == 0 ) cdoAbort("size undefined (zaxis description file: %s)!", dname);
           zaxis->vals = (double*) Malloc(zaxis->size*sizeof(double));
-          for ( size_t i = 0; i < (size_t) zaxis->size; ++i ) zaxis->vals[i] = parameter2double(kv->values[i]);
+          for ( size_t i = 0; i < zaxis->size; ++i ) zaxis->vals[i] = parameter2double(kv->values[i]);
         }
       else if ( STR_IS_EQ(key, "lbounds") )
         {
           if ( zaxis->size == 0 ) cdoAbort("size undefined (zaxis description file: %s)!", dname);
           zaxis->lbounds = (double*) Malloc(zaxis->size*sizeof(double));
-          for ( size_t i = 0; i < (size_t) zaxis->size; ++i ) zaxis->lbounds[i] = parameter2double(kv->values[i]);
+          for ( size_t i = 0; i < zaxis->size; ++i ) zaxis->lbounds[i] = parameter2double(kv->values[i]);
         }
       else if ( STR_IS_EQ(key, "ubounds") )
         {
           if ( zaxis->size == 0 ) cdoAbort("size undefined (zaxis description file: %s)!", dname);
           zaxis->ubounds = (double*) Malloc(zaxis->size*sizeof(double));
-          for ( size_t i = 0; i < (size_t) zaxis->size; ++i ) zaxis->ubounds[i] = parameter2double(kv->values[i]);
+          for ( size_t i = 0; i < zaxis->size; ++i ) zaxis->ubounds[i] = parameter2double(kv->values[i]);
         }
       else if ( STR_IS_EQ(key, "vct") )
         {
           if ( zaxis->vctsize == 0 ) cdoAbort("vctsize undefined (zaxis description file: %s)!", dname);
           zaxis->vct = (double*) Malloc(zaxis->vctsize*sizeof(double));
-          for ( size_t i = 0; i < (size_t) zaxis->vctsize; ++i ) zaxis->vct[i] = parameter2double(kv->values[i]);
+          for ( size_t i = 0; i < zaxis->vctsize; ++i ) zaxis->vct[i] = parameter2double(kv->values[i]);
         }
       else
         {
@@ -201,6 +212,10 @@ void zaxis_read_data(size_t nkv, kvmap_t *kvmap, zaxis_t *zaxis, size_t *iatt, c
 static
 void zaxis_read_attributes(size_t iatt, size_t nkv, kvmap_t *kvmap, int zaxisID)
 {
+  const char *reserved_keys[] = {"zaxistype", "size", "scalar", "vctsize", "name", "units", "longname", "levels", "lbounds", "ubounds", "vct"};
+  int num_rkeys = sizeof(reserved_keys) / sizeof(char*);
+  const char *attkey0 = NULL;
+
   for ( size_t ik = iatt; ik < nkv; ++ik )
     {
       if ( !kvmap[ik].isValid ) continue;
@@ -209,6 +224,14 @@ void zaxis_read_attributes(size_t iatt, size_t nkv, kvmap_t *kvmap, int zaxisID)
       const char *key = kv->key;
       size_t nvalues = kv->nvalues;
       const char *value = (kv->nvalues > 0) ? kv->values[0] : NULL;
+
+      if ( ik == iatt ) attkey0 = key;
+      else
+        {
+          for ( int n = 0; n < num_rkeys; ++n )
+            if ( STR_IS_EQ(key, reserved_keys[n]) )
+              cdoAbort("Found reserved key word >%s< in attribute names! Check name or position of >%s<.", key, attkey0);
+        }
       
       int dtype = literals_find_datatype(nvalues, kv->values);
 
@@ -252,11 +275,11 @@ int zaxisFromFile(FILE *gfp, const char *dname)
     {
       keyValues_t *kv = *(keyValues_t **)kvnode->data;
       if ( ik == 0 && !STR_IS_EQ(kv->key, "zaxistype") )
-        cdoAbort("First zaxis description parameter must be >zaxistype< (found: %s)!", kv->key);
+        cdoAbort("First zaxis description key word must be >zaxistype< (found: %s)!", kv->key);
 
       if ( kv->nvalues == 0 )
         {
-          cdoWarning("Z-axis description parameter %s has no values, skipped!", kv->key);
+          cdoWarning("Z-axis description key word %s has no values, skipped!", kv->key);
         }
       else
         {
@@ -273,11 +296,7 @@ int zaxisFromFile(FILE *gfp, const char *dname)
   zaxis_read_data(nkv, kvmap, &zaxis, &iatt, dname);
 
   int zaxisID = (zaxis.type == CDI_UNDEFID) ? CDI_UNDEFID : zaxisDefine(zaxis);
-
-  if ( zaxisID != CDI_UNDEFID && iatt > 0 )
-    {
-      zaxis_read_attributes(iatt, nkv, kvmap, zaxisID);
-    }
+  if ( zaxisID != CDI_UNDEFID && iatt > 0 ) zaxis_read_attributes(iatt, nkv, kvmap, zaxisID);
 
   list_destroy(pmlist);
 
@@ -333,7 +352,7 @@ void gen_zaxis_height(zaxis_t *zaxis, const char *pline)
 
 int zaxisFromName(const char *zaxisnameptr)
 {
-  int zaxisID = UNDEFID;
+  int zaxisID = CDI_UNDEFID;
   size_t len;
 
   char *zaxisname = strdup(zaxisnameptr);
@@ -356,7 +375,7 @@ int zaxisFromName(const char *zaxisnameptr)
       gen_zaxis_height(&zaxis, pline);
     }
 
-  if ( zaxis.type != -1 ) zaxisID = zaxisDefine(zaxis);
+  if ( zaxis.type != CDI_UNDEFID ) zaxisID = zaxisDefine(zaxis);
 
   free(zaxisname);
 
@@ -366,14 +385,14 @@ int zaxisFromName(const char *zaxisnameptr)
 
 int cdoDefineZaxis(const char *zaxisfile)
 {
-  int zaxisID = -1;
+  int zaxisID = CDI_UNDEFID;
 
   FILE *zfp = fopen(zaxisfile, "r");
   if ( zfp == NULL )
     {
       zaxisID = zaxisFromName(zaxisfile);
 
-      if ( zaxisID == -1 ) cdoAbort("Open failed on %s!", zaxisfile);
+      if ( zaxisID == CDI_UNDEFID ) cdoAbort("Open failed on %s!", zaxisfile);
     }
   else
     {
@@ -381,7 +400,7 @@ int cdoDefineZaxis(const char *zaxisfile)
       fclose(zfp);
     }
 
-  if ( zaxisID == -1 ) cdoAbort("Invalid zaxis description file %s!", zaxisfile);
+  if ( zaxisID == CDI_UNDEFID ) cdoAbort("Invalid zaxis description file %s!", zaxisfile);
 
   return zaxisID;
 }
@@ -401,8 +420,9 @@ void defineZaxis(const char *zaxisarg)
 static
 int ztype2ltype(int zaxistype)
 {
-  int ltype = -1;
+  int ltype = CDI_UNDEFID;
 
+  // clang-format off
   if      ( zaxistype == ZAXIS_SURFACE           )  ltype =   1;
   else if ( zaxistype == ZAXIS_PRESSURE          )  ltype = 100;
   else if ( zaxistype == ZAXIS_ALTITUDE          )  ltype = 103;
@@ -413,6 +433,7 @@ int ztype2ltype(int zaxistype)
   else if ( zaxistype == ZAXIS_DEPTH_BELOW_LAND  )  ltype = 111;
   else if ( zaxistype == ZAXIS_ISENTROPIC        )  ltype = 113;
   else if ( zaxistype == ZAXIS_DEPTH_BELOW_SEA   )  ltype = 160;
+  // clang-format on
 
   return ltype;
 }
@@ -420,10 +441,12 @@ int ztype2ltype(int zaxistype)
 
 int zaxis2ltype(int zaxisID)
 {
-  int zaxistype = zaxisInqType(zaxisID);
   int ltype = zaxisInqLtype(zaxisID);
-
-  if ( ltype <= 0 ) ltype = ztype2ltype(zaxistype);
+  if ( ltype <= 0 )
+    {
+      int zaxistype = zaxisInqType(zaxisID);
+      ltype = ztype2ltype(zaxistype);
+    }
 
   return ltype;
 }
diff --git a/src/zaxis_print.cc b/src/zaxis_print.cc
index d32b8ab..ea14457 100644
--- a/src/zaxis_print.cc
+++ b/src/zaxis_print.cc
@@ -27,7 +27,7 @@ void zaxis_print_kernel(int zaxisID, FILE *fp)
   char attstr[CDI_MAX_NAME];
   int type    = zaxisInqType(zaxisID);
   int nlevels = zaxisInqSize(zaxisID);
-  int prec    = zaxisInqPrec(zaxisID);
+  int prec    = zaxisInqDatatype(zaxisID);
   size_t nvals = (size_t) zaxisInqLevels(zaxisID, NULL);
 
   int dig = (prec == CDI_DATATYPE_FLT64) ? CDO_dbl_digits : CDO_flt_digits;
@@ -44,6 +44,7 @@ void zaxis_print_kernel(int zaxisID, FILE *fp)
   attstr[0] = 0; cdiZaxisInqKeyStr(zaxisID, CDI_KEY_UNITS, CDI_MAX_NAME, attstr);
   if ( attstr[0] )  fprintf(fp, "units     = \"%s\"\n", attstr);
 
+  char **cvals = NULL;
   double *vals = nvals ? (double*) Malloc(nvals*sizeof(double)) : NULL;
 
   if ( nvals )
@@ -52,6 +53,19 @@ void zaxis_print_kernel(int zaxisID, FILE *fp)
       static const char prefix[] = "levels    = ";
       printDblsPrefixAutoBrk(fp, dig, prefix, (int)sizeof(prefix)-1, nvals, vals, 0);
     }
+  else if ( type == ZAXIS_CHAR )
+    {
+      int clen = zaxisInqCLen(zaxisID);
+      zaxisInqCVals(zaxisID, &cvals);
+      fprintf(fp, "levels    = \n");
+      for ( int i = 0; i < nlevels; i++ )
+        {
+          fprintf(fp, "     [%2d] = %.*s\n", i, clen, cvals[i]);
+          Free(cvals[i]);
+        }
+    }
+  
+
 
   if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
     {
@@ -69,6 +83,7 @@ void zaxis_print_kernel(int zaxisID, FILE *fp)
     }
 
   if ( vals ) Free(vals);
+  if ( cvals ) Free(cvals);
 
   if ( type == ZAXIS_HYBRID || type == ZAXIS_HYBRID_HALF )
     {
diff --git a/test/EOF.test.in b/test/EOF.test.in
index 7077f8b..f2eac66 100644
--- a/test/EOF.test.in
+++ b/test/EOF.test.in
@@ -1,6 +1,6 @@
 #! @BASH@
 #
-echo 1..2 # Number of tests to be executed.
+echo 1..4 # Number of tests to be executed.
 #
 test -n "$CDO"      || CDO=cdo
 test -n "$DATAPATH" || DATAPATH=./data
@@ -22,11 +22,15 @@ OFILE1=eval_res
 OFILE2=eof_res
 OFILE3=res_pcoeff
 #
+DIM=""
+#
+for X in 1 2; do
+if [ $X = 2 ] ; then DIM=3d ; fi
 for MODE in jacobi danielson_lanczos; do
   export CDO_SVD_MODE=$MODE
   RSTAT=0
-  CDOTEST="eof/eofcoeff - $MODE"
-  CDOCOMMAND="$CDO $FORMAT eof,1 $IFILE $OFILE1 $OFILE2"
+  CDOTEST="eof${DIM}/eofcoeff${DIM} - $MODE"
+  CDOCOMMAND="$CDO $FORMAT eof${DIM},1 $IFILE $OFILE1 $OFILE2"
   echo "$CDOCOMMAND"
 
   $CDOCOMMAND
@@ -40,7 +44,7 @@ for MODE in jacobi danielson_lanczos; do
   test $? -eq 0 || let RSTAT+=1
   test -s $CDOOUT && let RSTAT+=1
 
-  CDOCOMMAND="$CDO $FORMAT eofcoeff $OFILE2 $IFILE $OFILE3"
+  CDOCOMMAND="$CDO $FORMAT eofcoeff${DIM} $OFILE2 $IFILE $OFILE3"
   echo "$CDOCOMMAND"
 
   $CDOCOMMAND
@@ -58,6 +62,7 @@ for MODE in jacobi danielson_lanczos; do
   let NTEST+=1
   rm -f $OFILE1 $OFILE2 ${OFILE3}00000
 done
+done
 #
 rm -f $CDOOUT $CDOERR
 #
diff --git a/test/File.test.in b/test/File.test.in
index eefdb28..3348327 100644
--- a/test/File.test.in
+++ b/test/File.test.in
@@ -23,6 +23,7 @@ function fileformat()
   if [ "${FORMAT}" = nc   ] ; then  FILEFORMAT=netCDF;   fi
   if [ "${FORMAT}" = nc2  ] ; then  FILEFORMAT=netCDF2;  fi
   if [ "${FORMAT}" = nc4  ] ; then  FILEFORMAT=netCDF4;  fi
+  if [ "${FORMAT}" = nc5  ] ; then  FILEFORMAT=netCDF5;  fi
 
   if [ "@ENABLE_SERVICE@" = no -a "${FORMAT}" = srv  ] ; then  ENABLE_TEST=no; fi
   if [ "@ENABLE_EXTRA@" = no   -a "${FORMAT}" = ext  ] ; then  ENABLE_TEST=no; fi
@@ -32,6 +33,7 @@ function fileformat()
   if [ "@ENABLE_NETCDF@" = no  -a "${FORMAT}" = nc   ] ; then  ENABLE_TEST=no; fi
   if [ "@ENABLE_NETCDF@" = no  -a "${FORMAT}" = nc2  ] ; then  ENABLE_TEST=no; fi
   if [ "@ENABLE_NC4@" = no     -a "${FORMAT}" = nc4  ] ; then  ENABLE_TEST=no; fi
+  if [ "@ENABLE_NC5@" = no     -a "${FORMAT}" = nc5  ] ; then  ENABLE_TEST=no; fi
 }
 #
 for OPERATOR in write copy; do
diff --git a/test/Makefile.am b/test/Makefile.am
index f89094b..5f997be 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -13,7 +13,7 @@ TEST_LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) \
 # tests which should pass
 TESTS = threads.test tsformat.test wildcard.test File.test Comp.test Compc.test \
         Read_grib.test Read_netcdf.test Copy_netcdf.test Cat.test Gridarea.test  \
-        Detrend.test Genweights.test Remap.test Remap2.test Select.test Spectral.test \
+        Detrend.test Genweights.test Remap.test Remap2.test Remapeta.test Select.test Spectral.test \
         Ensstat.test Enspctl.test Gridboxstat.test \
         Vertstat.test Fldstat.test Fldpctl.test Merstat.test Zonstat.test \
         Timstat.test Timselstat.test Seasstat.test \
diff --git a/test/Makefile.in b/test/Makefile.in
index 98237b1..dcfe021 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -86,22 +86,22 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(srcdir)/Compc.test.in $(srcdir)/Cat.test.in \
 	$(srcdir)/Gridarea.test.in $(srcdir)/Genweights.test.in \
 	$(srcdir)/Remap.test.in $(srcdir)/Remap2.test.in \
-	$(srcdir)/EOF.test.in $(srcdir)/Select.test.in \
-	$(srcdir)/Spectral.test.in $(srcdir)/Vertint.test.in \
-	$(srcdir)/Timstat.test.in $(srcdir)/Timselstat.test.in \
-	$(srcdir)/Seasstat.test.in $(srcdir)/Runstat.test.in \
-	$(srcdir)/Multiyearstat.test.in $(srcdir)/Ydrunstat.test.in \
-	$(srcdir)/Gridboxstat.test.in $(srcdir)/Vertstat.test.in \
-	$(srcdir)/Fldstat.test.in $(srcdir)/Fldpctl.test.in \
-	$(srcdir)/Ensstat.test.in $(srcdir)/Enspctl.test.in \
-	$(srcdir)/Merstat.test.in $(srcdir)/Zonstat.test.in \
-	$(srcdir)/Mergetime.test.in $(srcdir)/Afterburner.test.in \
-	$(srcdir)/Detrend.test.in $(srcdir)/Arithc.test.in \
-	$(srcdir)/Arith.test.in $(srcdir)/Expr.test.in \
-	$(srcdir)/Gradsdes.test.in $(srcdir)/Collgrid.test.in \
-	$(srcdir)/threads.test.in $(srcdir)/tsformat.test.in \
-	$(srcdir)/wildcard.test.in $(srcdir)/MapReduce.test.in \
-	$(srcdir)/Ninfo.test.in README
+	$(srcdir)/Remapeta.test.in $(srcdir)/EOF.test.in \
+	$(srcdir)/Select.test.in $(srcdir)/Spectral.test.in \
+	$(srcdir)/Vertint.test.in $(srcdir)/Timstat.test.in \
+	$(srcdir)/Timselstat.test.in $(srcdir)/Seasstat.test.in \
+	$(srcdir)/Runstat.test.in $(srcdir)/Multiyearstat.test.in \
+	$(srcdir)/Ydrunstat.test.in $(srcdir)/Gridboxstat.test.in \
+	$(srcdir)/Vertstat.test.in $(srcdir)/Fldstat.test.in \
+	$(srcdir)/Fldpctl.test.in $(srcdir)/Ensstat.test.in \
+	$(srcdir)/Enspctl.test.in $(srcdir)/Merstat.test.in \
+	$(srcdir)/Zonstat.test.in $(srcdir)/Mergetime.test.in \
+	$(srcdir)/Afterburner.test.in $(srcdir)/Detrend.test.in \
+	$(srcdir)/Arithc.test.in $(srcdir)/Arith.test.in \
+	$(srcdir)/Expr.test.in $(srcdir)/Gradsdes.test.in \
+	$(srcdir)/Collgrid.test.in $(srcdir)/threads.test.in \
+	$(srcdir)/tsformat.test.in $(srcdir)/wildcard.test.in \
+	$(srcdir)/MapReduce.test.in $(srcdir)/Ninfo.test.in README
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/acx_options.m4 \
 	$(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
@@ -116,14 +116,15 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/src/config.h
 CONFIG_CLEAN_FILES = File.test Read_grib.test Read_netcdf.test \
 	Copy_netcdf.test Comp.test Compc.test Cat.test Gridarea.test \
-	Genweights.test Remap.test Remap2.test EOF.test Select.test \
-	Spectral.test Vertint.test Timstat.test Timselstat.test \
-	Seasstat.test Runstat.test Multiyearstat.test Ydrunstat.test \
-	Gridboxstat.test Vertstat.test Fldstat.test Fldpctl.test \
-	Ensstat.test Enspctl.test Merstat.test Zonstat.test \
-	Mergetime.test Afterburner.test Detrend.test Arithc.test \
-	Arith.test Expr.test Gradsdes.test Collgrid.test threads.test \
-	tsformat.test wildcard.test MapReduce.test Ninfo.test
+	Genweights.test Remap.test Remap2.test Remapeta.test EOF.test \
+	Select.test Spectral.test Vertint.test Timstat.test \
+	Timselstat.test Seasstat.test Runstat.test Multiyearstat.test \
+	Ydrunstat.test Gridboxstat.test Vertstat.test Fldstat.test \
+	Fldpctl.test Ensstat.test Enspctl.test Merstat.test \
+	Zonstat.test Mergetime.test Afterburner.test Detrend.test \
+	Arithc.test Arith.test Expr.test Gradsdes.test Collgrid.test \
+	threads.test tsformat.test wildcard.test MapReduce.test \
+	Ninfo.test
 CONFIG_CLEAN_VPATH_FILES =
 AM_V_P = $(am__v_P_ at AM_V@)
 am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
@@ -537,7 +538,7 @@ TEST_LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) \
 # tests which should pass
 TESTS = threads.test tsformat.test wildcard.test File.test Comp.test Compc.test \
         Read_grib.test Read_netcdf.test Copy_netcdf.test Cat.test Gridarea.test  \
-        Detrend.test Genweights.test Remap.test Remap2.test Select.test Spectral.test \
+        Detrend.test Genweights.test Remap.test Remap2.test Remapeta.test Select.test Spectral.test \
         Ensstat.test Enspctl.test Gridboxstat.test \
         Vertstat.test Fldstat.test Fldpctl.test Merstat.test Zonstat.test \
         Timstat.test Timselstat.test Seasstat.test \
@@ -615,6 +616,8 @@ Remap.test: $(top_builddir)/config.status $(srcdir)/Remap.test.in
 	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 Remap2.test: $(top_builddir)/config.status $(srcdir)/Remap2.test.in
 	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+Remapeta.test: $(top_builddir)/config.status $(srcdir)/Remapeta.test.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 EOF.test: $(top_builddir)/config.status $(srcdir)/EOF.test.in
 	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 Select.test: $(top_builddir)/config.status $(srcdir)/Select.test.in
diff --git a/test/Multiyearstat.test.in b/test/Multiyearstat.test.in
index 5a80209..8d0a74f 100644
--- a/test/Multiyearstat.test.in
+++ b/test/Multiyearstat.test.in
@@ -8,6 +8,8 @@ CDOOUT=cout$$
 CDOERR=cerr$$
 TYPES="ymon yday yhour yseas"
 STATS="min max range sum avg mean std std1 var var1"
+FMS="srv grb nc"
+if [ "@ENABLE_NETCDF@" = no ] ; then  FMS="srv grb"; fi
 #
 IFILE=$DATAPATH/ts_mm_5years
 NTEST=1
@@ -23,18 +25,21 @@ for TYPE in $TYPES; do
     OFILE=${TYPE}${STAT}_res
 
     CDOTEST="${TYPE}$STAT"
-    CDOCOMMAND="$CDO ${TYPE}${STAT} $IFILE $OFILE"
 
-    echo "Running test: $NTEST"
-    echo "$CDOCOMMAND"
+    for FM in $FMS; do
+      CDOCOMMAND="$CDO -f $FM ${TYPE}${STAT} $IFILE $OFILE"
 
-    $CDOCOMMAND
-    test $? -eq 0 || let RSTAT+=1
+      echo "Running test: $NTEST"
+      echo "$CDOCOMMAND"
 
-    $CDO diff $OFILE $RFILE > $CDOOUT 2> $CDOERR
-    test $? -eq 0 || let RSTAT+=1
-    test -s $CDOOUT && let RSTAT+=1
-    cat $CDOOUT $CDOERR
+      $CDOCOMMAND
+      test $? -eq 0 || let RSTAT+=1
+
+      $CDO diff,0.004 $OFILE $RFILE > $CDOOUT 2> $CDOERR
+      test $? -eq 0 || let RSTAT+=1
+      test -s $CDOOUT && let RSTAT+=1
+      cat $CDOOUT $CDOERR
+    done
 
     test $RSTAT -eq 0 && echo "ok $NTEST - $CDOTEST"
     test $RSTAT -eq 0 || echo "not ok $NTEST - $CDOTEST"
diff --git a/test/README b/test/README
index 7173942..6e3c39b 100644
--- a/test/README
+++ b/test/README
@@ -11,7 +11,7 @@ or
 The cdo operators are tested with python-unittests using the python-bindings for cdo.
 The python-bindings are located at cdo/contrib/python/cdo.py.
 The use is roughly exlained at:
-    https://code.zmaw.de/projects/cdo/wiki/Cdo%7Brbpy%7D
+    https://code.mpimet.mpg.de/projects/cdo/wiki/Cdo%7Brbpy%7D
     TODO: Provide a more thorough documentation/tutorial.
 The documentation of the python unittest framework can be found at:
     http://docs.python.org/library/unittest.html
diff --git a/test/Remapeta.test.in b/test/Remapeta.test.in
new file mode 100644
index 0000000..30081cf
--- /dev/null
+++ b/test/Remapeta.test.in
@@ -0,0 +1,47 @@
+#! @BASH@
+echo 1..2 # Number of tests to be executed.
+#
+test -n "$CDO"      || CDO=cdo
+test -n "$DATAPATH" || DATAPATH=./data
+#
+ABSLIM=0.001
+CDOOUT=cout$$
+CDOERR=cerr$$
+#
+NTEST=1
+#
+for X in 1 2; do
+  RSTAT=0
+  RFILE=$DATAPATH/remapeta_ref
+  VCT=$DATAPATH/VCT.L62
+  IFILE=$DATAPATH/remapeta${X}.nc
+  OFILE=remapeta_res
+
+  CDOTEST="remapeta"
+  CDOCOMMAND="$CDO remapeta,$VCT $IFILE $OFILE"
+
+  if [ "@ENABLE_NETCDF@" = yes ] ; then
+    echo "Running test: $NTEST"
+    echo "$CDOCOMMAND"
+
+    $CDOCOMMAND
+    test $? -eq 0 || let RSTAT+=1
+
+    $CDO diff,$ABSLIM $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"
+  else
+    test $RSTAT -eq 0 && echo "ok $NTEST - $CDOTEST # SKIP netCDF not enabled"
+  fi
+
+  let NTEST+=1
+  rm -f $OFILE
+done
+#
+rm -f $CDOOUT $CDOERR
+#
+exit 0
diff --git a/test/Runstat.test.in b/test/Runstat.test.in
index 1ea9470..30e0f44 100644
--- a/test/Runstat.test.in
+++ b/test/Runstat.test.in
@@ -8,6 +8,8 @@ CDOOUT=cout$$
 CDOERR=cerr$$
 TYPE=run
 STATS="min max range sum avg mean std std1 var var1"
+FMS="srv grb nc"
+if [ "@ENABLE_NETCDF@" = no ] ; then  FMS="srv grb"; fi
 NTEST=1
 #
 IFILE=$DATAPATH/ts_mm_5years
@@ -18,18 +20,21 @@ for STAT in $STATS; do
   OFILE=${TYPE}${STAT}_res
 
   CDOTEST="${TYPE}$STAT"
-  CDOCOMMAND="$CDO ${TYPE}${STAT},12 $IFILE $OFILE"
 
-  echo "Running test: $NTEST"
-  echo "$CDOCOMMAND"
+  for FM in $FMS; do
+    CDOCOMMAND="$CDO -f $FM ${TYPE}${STAT},12 $IFILE $OFILE"
 
-  $CDOCOMMAND
-  test $? -eq 0 || let RSTAT+=1
+    echo "Running test: $NTEST"
+    echo "$CDOCOMMAND"
 
-  $CDO diff $OFILE $RFILE > $CDOOUT 2> $CDOERR
-  test $? -eq 0 || let RSTAT+=1
-  test -s $CDOOUT && let RSTAT+=1
-  cat $CDOOUT $CDOERR
+    $CDOCOMMAND
+    test $? -eq 0 || let RSTAT+=1
+
+    $CDO diff,0.004 $OFILE $RFILE > $CDOOUT 2> $CDOERR
+    test $? -eq 0 || let RSTAT+=1
+    test -s $CDOOUT && let RSTAT+=1
+    cat $CDOOUT $CDOERR
+  done
 
   test $RSTAT -eq 0 && echo "ok $NTEST - $CDOTEST"
   test $RSTAT -eq 0 || echo "not ok $NTEST - $CDOTEST"
diff --git a/test/Seasstat.test.in b/test/Seasstat.test.in
index 691e659..dd4fb71 100644
--- a/test/Seasstat.test.in
+++ b/test/Seasstat.test.in
@@ -8,6 +8,8 @@ CDOOUT=cout$$
 CDOERR=cerr$$
 TYPE=seas
 STATS="min max range sum avg mean std std1 var var1"
+FMS="srv grb nc"
+if [ "@ENABLE_NETCDF@" = no ] ; then  FMS="srv grb"; fi
 NTEST=1
 #
 IFILE=$DATAPATH/ts_mm_5years
@@ -18,18 +20,21 @@ for STAT in $STATS; do
   OFILE=${TYPE}${STAT}_res
 
   CDOTEST="${TYPE}$STAT"
-  CDOCOMMAND="$CDO ${TYPE}${STAT} $IFILE $OFILE"
 
-  echo "Running test: $NTEST"
-  echo "$CDOCOMMAND"
+  for FM in $FMS; do
+    CDOCOMMAND="$CDO -f $FM ${TYPE}${STAT} $IFILE $OFILE"
 
-  $CDOCOMMAND
-  test $? -eq 0 || let RSTAT+=1
+    echo "Running test: $NTEST"
+    echo "$CDOCOMMAND"
 
-  $CDO diff $OFILE $RFILE > $CDOOUT 2> $CDOERR
-  test $? -eq 0 || let RSTAT+=1
-  test -s $CDOOUT && let RSTAT+=1
-  cat $CDOOUT $CDOERR
+    $CDOCOMMAND
+    test $? -eq 0 || let RSTAT+=1
+
+    $CDO diff,0.004 $OFILE $RFILE > $CDOOUT 2> $CDOERR
+    test $? -eq 0 || let RSTAT+=1
+    test -s $CDOOUT && let RSTAT+=1
+    cat $CDOOUT $CDOERR
+  done
 
   test $RSTAT -eq 0 && echo "ok $NTEST - $CDOTEST"
   test $RSTAT -eq 0 || echo "not ok $NTEST - $CDOTEST"
diff --git a/test/Timselstat.test.in b/test/Timselstat.test.in
index f25ad78..ae144bb 100644
--- a/test/Timselstat.test.in
+++ b/test/Timselstat.test.in
@@ -8,6 +8,8 @@ CDOOUT=cout$$
 CDOERR=cerr$$
 TYPE=timsel
 STATS="min max range sum avg mean std std1 var var1"
+FMS="srv grb nc"
+if [ "@ENABLE_NETCDF@" = no ] ; then  FMS="srv grb"; fi
 NTEST=1
 #
 IFILE=$DATAPATH/ts_mm_5years
@@ -18,18 +20,21 @@ for STAT in $STATS; do
   OFILE=${TYPE}${STAT}_res
 
   CDOTEST="${TYPE}$STAT"
-  CDOCOMMAND="$CDO ${TYPE}${STAT},12 $IFILE $OFILE"
 
-  echo "Running test: $NTEST"
-  echo "$CDOCOMMAND"
+  for FM in $FMS; do
+    CDOCOMMAND="$CDO -f $FM ${TYPE}${STAT},12 $IFILE $OFILE"
 
-  $CDOCOMMAND
-  test $? -eq 0 || let RSTAT+=1
+    echo "Running test: $NTEST"
+    echo "$CDOCOMMAND"
 
-  $CDO diff $OFILE $RFILE > $CDOOUT 2> $CDOERR
-  test $? -eq 0 || let RSTAT+=1
-  test -s $CDOOUT && let RSTAT+=1
-  cat $CDOOUT $CDOERR
+    $CDOCOMMAND
+    test $? -eq 0 || let RSTAT+=1
+
+    $CDO diff,0.004 $OFILE $RFILE > $CDOOUT 2> $CDOERR
+    test $? -eq 0 || let RSTAT+=1
+    test -s $CDOOUT && let RSTAT+=1
+    cat $CDOOUT $CDOERR
+  done
 
   test $RSTAT -eq 0 && echo "ok $NTEST - $CDOTEST"
   test $RSTAT -eq 0 || echo "not ok $NTEST - $CDOTEST"
diff --git a/test/Timstat.test.in b/test/Timstat.test.in
index f4d4def..9f2b071 100644
--- a/test/Timstat.test.in
+++ b/test/Timstat.test.in
@@ -8,6 +8,8 @@ CDOOUT=cout$$
 CDOERR=cerr$$
 TYPES="tim year mon day"
 STATS="min max range sum avg mean std std1 var var1"
+FMS="srv grb nc"
+if [ "@ENABLE_NETCDF@" = no ] ; then  FMS="srv grb"; fi
 NTEST=1
 #
 for TYPE in $TYPES; do
@@ -25,18 +27,21 @@ for TYPE in $TYPES; do
     OFILE=${TYPE}${STAT}_res
 
     CDOTEST="${TYPE}$STAT"
-    CDOCOMMAND="$CDO ${TYPE}${STAT} $IFILE $OFILE"
 
-    echo "Running test: $NTEST"
-    echo "$CDOCOMMAND"
+    for FM in $FMS; do
+      CDOCOMMAND="$CDO -f $FM ${TYPE}${STAT} $IFILE $OFILE"
 
-    $CDOCOMMAND
-    test $? -eq 0 || let RSTAT+=1
+      echo "Running test: $NTEST"
+      echo "$CDOCOMMAND"
 
-    $CDO diff $OFILE $RFILE > $CDOOUT 2> $CDOERR
-    test $? -eq 0 || let RSTAT+=1
-    test -s $CDOOUT && let RSTAT+=1
-    cat $CDOOUT $CDOERR
+      $CDOCOMMAND
+      test $? -eq 0 || let RSTAT+=1
+
+      $CDO diff,0.004 $OFILE $RFILE > $CDOOUT 2> $CDOERR
+      test $? -eq 0 || let RSTAT+=1
+      test -s $CDOOUT && let RSTAT+=1
+      cat $CDOOUT $CDOERR
+    done
 
     test $RSTAT -eq 0 && echo "ok $NTEST - $CDOTEST"
     test $RSTAT -eq 0 || echo "not ok $NTEST - $CDOTEST"
diff --git a/test/Ydrunstat.test.in b/test/Ydrunstat.test.in
index 2fdca73..972d4b0 100644
--- a/test/Ydrunstat.test.in
+++ b/test/Ydrunstat.test.in
@@ -8,6 +8,8 @@ CDOOUT=cout$$
 CDOERR=cerr$$
 TYPES="ydrun"
 STATS="min max sum avg mean std std1 var var1"
+FMS="srv grb nc"
+if [ "@ENABLE_NETCDF@" = no ] ; then  FMS="srv grb"; fi
 #
 IFILE=$DATAPATH/ts_mm_5years
 NTEST=1
@@ -19,18 +21,21 @@ for TYPE in $TYPES; do
     OFILE=${TYPE}${STAT}_res
 
     CDOTEST="${TYPE}$STAT"
-    CDOCOMMAND="$CDO ${TYPE}${STAT},8 $IFILE $OFILE"
 
-    echo "Running test: $NTEST"
-    echo "$CDOCOMMAND"
+    for FM in $FMS; do
+      CDOCOMMAND="$CDO -f $FM ${TYPE}${STAT},8 $IFILE $OFILE"
 
-    $CDOCOMMAND
-    test $? -eq 0 || let RSTAT+=1
+      echo "Running test: $NTEST"
+      echo "$CDOCOMMAND"
 
-    $CDO diff $OFILE $RFILE > $CDOOUT 2> $CDOERR
-    test $? -eq 0 || let RSTAT+=1
-    test -s $CDOOUT && let RSTAT+=1
-    cat $CDOOUT $CDOERR
+      $CDOCOMMAND
+      test $? -eq 0 || let RSTAT+=1
+
+      $CDO diff,0.004 $OFILE $RFILE > $CDOOUT 2> $CDOERR
+      test $? -eq 0 || let RSTAT+=1
+      test -s $CDOOUT && let RSTAT+=1
+      cat $CDOOUT $CDOERR
+    done
 
     test $RSTAT -eq 0 && echo "ok $NTEST - $CDOTEST"
     test $RSTAT -eq 0 || echo "not ok $NTEST - $CDOTEST"
diff --git a/test/data/Makefile.am b/test/data/Makefile.am
index 484cc58..33d5e71 100644
--- a/test/data/Makefile.am
+++ b/test/data/Makefile.am
@@ -39,8 +39,9 @@ GRADSDES_REF = pl_data.ctl pl_data.gmp
 ARITH_REF    = arithadd_ref arithsub_ref arithmul_ref arithdiv_ref
 MAPREDUCE    = r18x9_grid icon_cell_grid griddes.r18x9 griddes.icon_cell
 MERGETIME    = mergetime_ref mergetime_y1 mergetime_y2 mergetime_y12
+REMAPETA     = remapeta1.nc remapeta2.nc remapeta_ref VCT.L62
 
 EXTRA_DIST = $(INPUTDATA) $(FILE_REF) $(GRIB_REF) $(NETCDF_REF) $(EOF_REF) $(COMP_REF) $(YDRUNSTAT_REF) $(YMONSTAT_REF) $(YSEASSTAT_REF) $(SEASSTAT_REF) \
              $(RUNSTAT_REF) $(TIMSTAT_REF) $(YEARSTAT_REF) $(MONSTAT_REF) $(DAYSTAT_REF) $(VERTSTAT_REF) $(FLDSTAT_REF) $(FLDPSTAT_REF) \
              $(MERSTAT_REF) $(ZONSTAT_REF) $(ENSPSTAT_REF) $(SPECTRAL_REF) $(VERTINT_REF) $(REMAP_REF) $(REMAP2_REF) $(SELECT_REF) $(DETREND_REF) \
-             $(THREAD_REF) $(EXPR_REF) $(GRADSDES_REF) $(ARITH_REF) $(MAPREDUCE) $(MERGETIME)
+             $(THREAD_REF) $(EXPR_REF) $(GRADSDES_REF) $(ARITH_REF) $(MAPREDUCE) $(MERGETIME) $(REMAPETA)
diff --git a/test/data/Makefile.in b/test/data/Makefile.in
index cde4a5f..a08f930 100644
--- a/test/data/Makefile.in
+++ b/test/data/Makefile.in
@@ -333,10 +333,11 @@ GRADSDES_REF = pl_data.ctl pl_data.gmp
 ARITH_REF = arithadd_ref arithsub_ref arithmul_ref arithdiv_ref
 MAPREDUCE = r18x9_grid icon_cell_grid griddes.r18x9 griddes.icon_cell
 MERGETIME = mergetime_ref mergetime_y1 mergetime_y2 mergetime_y12
+REMAPETA = remapeta1.nc remapeta2.nc remapeta_ref VCT.L62
 EXTRA_DIST = $(INPUTDATA) $(FILE_REF) $(GRIB_REF) $(NETCDF_REF) $(EOF_REF) $(COMP_REF) $(YDRUNSTAT_REF) $(YMONSTAT_REF) $(YSEASSTAT_REF) $(SEASSTAT_REF) \
              $(RUNSTAT_REF) $(TIMSTAT_REF) $(YEARSTAT_REF) $(MONSTAT_REF) $(DAYSTAT_REF) $(VERTSTAT_REF) $(FLDSTAT_REF) $(FLDPSTAT_REF) \
              $(MERSTAT_REF) $(ZONSTAT_REF) $(ENSPSTAT_REF) $(SPECTRAL_REF) $(VERTINT_REF) $(REMAP_REF) $(REMAP2_REF) $(SELECT_REF) $(DETREND_REF) \
-             $(THREAD_REF) $(EXPR_REF) $(GRADSDES_REF) $(ARITH_REF) $(MAPREDUCE) $(MERGETIME)
+             $(THREAD_REF) $(EXPR_REF) $(GRADSDES_REF) $(ARITH_REF) $(MAPREDUCE) $(MERGETIME) $(REMAPETA)
 
 all: all-am
 
diff --git a/test/data/VCT.L62 b/test/data/VCT.L62
new file mode 100644
index 0000000..77555b2
--- /dev/null
+++ b/test/data/VCT.L62
@@ -0,0 +1,63 @@
+    0         0.000000     0.000000
+    1       988.835876     0.000000
+    2      1977.676270     0.000000
+    3      2966.516602     0.000000
+    4      3955.356934     0.000000
+    5      4944.197266     0.000000
+    6      5933.037598     0.000000
+    7      6921.870117     0.000000
+    8      7909.441406     0.000013
+    9      8890.707031     0.000087
+   10      9860.528320     0.000275
+   11     10807.783203     0.000685
+   12     11722.749023     0.001415
+   13     12595.006836     0.002565
+   14     13419.463867     0.004187
+   15     14192.009766     0.006322
+   16     14922.685547     0.009035
+   17     15638.053711     0.012508
+   18     16329.560547     0.016860
+   19     16990.623047     0.022189
+   20     17613.281250     0.028610
+   21     18191.029297     0.036227
+   22     18716.968750     0.045146
+   23     19184.544922     0.055474
+   24     19587.513672     0.067316
+   25     19919.796875     0.080777
+   26     20175.394531     0.095964
+   27     20348.916016     0.112979
+   28     20434.158203     0.131935
+   29     20426.218750     0.152934
+   30     20319.011719     0.176091
+   31     20107.031250     0.201520
+   32     19785.357422     0.229315
+   33     19348.775391     0.259554
+   34     18798.822266     0.291993
+   35     18141.296875     0.326329
+   36     17385.595703     0.362203
+   37     16544.585938     0.399205
+   38     15633.566406     0.436906
+   39     14665.645508     0.475016
+   40     13653.219727     0.513280
+   41     12608.383789     0.551458
+   42     11543.166992     0.589317
+   43     10471.310547     0.626559
+   44      9405.222656     0.662934
+   45      8356.252930     0.698224
+   46      7335.164551     0.732224
+   47      6353.920898     0.764679
+   48      5422.802734     0.795385
+   49      4550.215820     0.824185
+   50      3743.464355     0.850950
+   51      3010.146973     0.875518
+   52      2356.202637     0.897767
+   53      1784.854614     0.917651
+   54      1297.656128     0.935157
+   55       895.193542     0.950274
+   56       576.314148     0.963007
+   57       336.772369     0.973466
+   58       162.043427     0.982238
+   59        54.208336     0.989153
+   60         6.575628     0.994204
+   61         0.003160     0.997630
+   62         0.000000     1.000000
diff --git a/test/data/grib_testfile01_sinfo_ref b/test/data/grib_testfile01_sinfo_ref
index ab59641..dde872e 100644
--- a/test/data/grib_testfile01_sinfo_ref
+++ b/test/data/grib_testfile01_sinfo_ref
@@ -1,6 +1,6 @@
    File format : GRIB
-    -1 : Institut Source   Steptype Levels Num    Points Num Dtype : Parameter ID
-     1 : unknown  unknown  instant       1   1      2592   1  P16  : 1             
+    -1 : Institut Source   T Steptype Levels Num    Points Num Dtype : Parameter ID
+     1 : unknown  unknown  v instant       1   1      2592   1  P16  : 1             
    Grid coordinates :
      1 : lonlat                   : points=2592 (72x36)
                               lon : -177.5 to 177.5 by 5 degrees_east  circular
diff --git a/test/data/grib_testfile02_sinfo_ref b/test/data/grib_testfile02_sinfo_ref
index ef42506..5752cab 100644
--- a/test/data/grib_testfile02_sinfo_ref
+++ b/test/data/grib_testfile02_sinfo_ref
@@ -1,6 +1,6 @@
    File format : GRIB
-    -1 : Institut Source   Steptype Levels Num    Points Num Dtype : Parameter ID
-     1 : unknown  unknown  instant       1   1         1   1  P0   : 1             
+    -1 : Institut Source   T Steptype Levels Num    Points Num Dtype : Parameter ID
+     1 : unknown  unknown  v instant       1   1         1   1  P0   : 1             
    Grid coordinates :
      1 : lonlat                   : points=1 (1x1)
                               lon : 0 degrees_east
diff --git a/test/data/grib_testfile03_sinfo_ref b/test/data/grib_testfile03_sinfo_ref
index 3d91dd5..150aa72 100644
--- a/test/data/grib_testfile03_sinfo_ref
+++ b/test/data/grib_testfile03_sinfo_ref
@@ -1,6 +1,6 @@
    File format : GRIB
-    -1 : Institut Source   Steptype Levels Num    Points Num Dtype : Parameter ID
-     1 : ECMWF    unknown  instant       1   1     35718   1  P16  : 151.128       
+    -1 : Institut Source   T Steptype Levels Num    Points Num Dtype : Parameter ID
+     1 : ECMWF    unknown  v instant       1   1     35718   1  P16  : 151.128       
    Grid coordinates :
      1 : gaussian reduced         : points=35718  nlat=160  np=80
                               lat : 89.14152 to -89.14152 degrees_north
diff --git a/test/data/netcdf_testfile01_sinfon_ref b/test/data/netcdf_testfile01_sinfon_ref
index 1b77b6c..aba52e7 100644
--- a/test/data/netcdf_testfile01_sinfon_ref
+++ b/test/data/netcdf_testfile01_sinfon_ref
@@ -1,6 +1,6 @@
    File format : NetCDF
-    -1 : Institut Source   Steptype Levels Num    Points Num Dtype : Parameter name
-     1 : unknown  unknown  instant       1   1      2592   1  I16  : tem           
+    -1 : Institut Source   T Steptype Levels Num    Points Num Dtype : Parameter name
+     1 : unknown  unknown  v instant       1   1      2592   1  I16  : tem           
    Grid coordinates :
      1 : lonlat                   : points=2592 (72x36)
                               lon : -177.5 to 177.5 by 5 degrees_east  circular
diff --git a/test/data/netcdf_testfile02_sinfon_ref b/test/data/netcdf_testfile02_sinfon_ref
index 3a5fa76..d983d5c 100644
--- a/test/data/netcdf_testfile02_sinfon_ref
+++ b/test/data/netcdf_testfile02_sinfon_ref
@@ -1,6 +1,6 @@
    File format : NetCDF
-    -1 : Institut Source   Steptype Levels Num    Points Num Dtype : Parameter name
-     1 : unknown  unknown  instant       1   1         1   1  F32  : for           
+    -1 : Institut Source   T Steptype Levels Num    Points Num Dtype : Parameter name
+     1 : unknown  unknown  v instant       1   1         1   1  F32  : for           
    Grid coordinates :
      1 : lonlat                   : points=1 (1x1)
                               lon : 0 degrees_east
diff --git a/test/data/remapeta1.nc b/test/data/remapeta1.nc
new file mode 100644
index 0000000..9d499fe
Binary files /dev/null and b/test/data/remapeta1.nc differ
diff --git a/test/data/remapeta2.nc b/test/data/remapeta2.nc
new file mode 100644
index 0000000..45786d2
Binary files /dev/null and b/test/data/remapeta2.nc differ
diff --git a/test/data/remapeta_ref b/test/data/remapeta_ref
new file mode 100644
index 0000000..5e17b66
Binary files /dev/null and b/test/data/remapeta_ref differ

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