[cdo] 16/84: New upstream 1.6.0

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


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

mckinstry pushed a commit to branch master
in repository cdo.

commit bc6aba1f66375d0fde2d2e4bac3c8e2fb2584073
Author: Alastair McKinstry <mckinstry at debian.org>
Date:   Wed Mar 27 10:45:20 2013 +0000

    New upstream 1.6.0
---
 ChangeLog                       |  109 +
 Makefile.in                     |    1 +
 NEWS                            |   21 +
 OPERATORS                       |   59 +-
 aclocal.m4                      |   12 -
 cdo.spec                        |    2 +-
 config/default                  |    6 +-
 configure                       |   59 +-
 configure.ac                    |   18 +-
 contrib/COPYING                 |  280 ++
 contrib/Makefile.am             |    6 +-
 contrib/Makefile.in             |    9 +-
 contrib/cdoCompletion.bash      |   38 +-
 contrib/cdoCompletion.tcsh      |   38 +-
 contrib/cdoCompletion.zsh       |   38 +-
 contrib/python/cdo.py           |   42 +-
 doc/cdo.pdf                     |  Bin 1413621 -> 1426317 bytes
 doc/cdo_refcard.pdf             |  Bin 94414 -> 95662 bytes
 libcdi/ChangeLog                |   65 +
 libcdi/NEWS                     |   16 +
 libcdi/aclocal.m4               |   12 -
 libcdi/app/cdi.c                |   73 +-
 libcdi/app/createtable.c        |    6 +-
 libcdi/app/printinfo.h          |   54 +-
 libcdi/configure                |  123 +-
 libcdi/configure.ac             |    8 +-
 libcdi/doc/cdi_cman.pdf         |  Bin 427249 -> 436900 bytes
 libcdi/doc/cdi_fman.pdf         |  Bin 467404 -> 477119 bytes
 libcdi/src/Makefile.am          |    1 +
 libcdi/src/Makefile.in          |    1 +
 libcdi/src/cdf_int.c            |   12 +-
 libcdi/src/cdi.h                |   30 +-
 libcdi/src/cdi.inc              |   65 +-
 libcdi/src/cdiFortran.c         |   30 +-
 libcdi/src/cdi_error.c          |    1 +
 libcdi/src/cdilib.c             | 6214 +++++++++++++++++++++------------------
 libcdi/src/cgribex.h            |    5 +-
 libcdi/src/cgribexlib.c         |  987 +++++--
 libcdi/src/config.h.in          |    3 +
 libcdi/src/extralib.c           |    6 +
 libcdi/src/gribapi.c            |   11 +-
 libcdi/src/gribapi.h            |    7 +-
 libcdi/src/grid.c               |  149 +-
 libcdi/src/grid.h               |    4 +-
 libcdi/src/ieglib.c             |    4 +
 libcdi/src/model.c              |    4 +-
 libcdi/src/pio_dbuffer.c        |    6 +-
 libcdi/src/pio_util.c           |   29 +-
 libcdi/src/pio_util.h           |    6 +-
 libcdi/src/resource_handle.c    |   14 +-
 libcdi/src/resource_handle.h    |    3 +-
 libcdi/src/servicelib.c         |    6 +
 libcdi/src/stream.c             |  124 +-
 libcdi/src/stream_cdf.c         |  736 +++--
 libcdi/src/stream_cdf.h         |   32 +-
 libcdi/src/stream_cgribex.c     |  191 +-
 libcdi/src/stream_cgribex.h     |    6 +-
 libcdi/src/stream_ext.c         |  198 +-
 libcdi/src/stream_ext.h         |   22 +-
 libcdi/src/stream_grb.c         |  180 +-
 libcdi/src/stream_grb.h         |   22 +-
 libcdi/src/stream_gribapi.c     |  693 +++--
 libcdi/src/stream_gribapi.h     |    6 +-
 libcdi/src/stream_history.c     |    6 +-
 libcdi/src/stream_ieg.c         |  203 +-
 libcdi/src/stream_ieg.h         |   22 +-
 libcdi/src/stream_int.c         |   23 +-
 libcdi/src/stream_int.h         |   24 +-
 libcdi/src/stream_record.c      |   86 +-
 libcdi/src/stream_srv.c         |  203 +-
 libcdi/src/stream_srv.h         |   22 +-
 libcdi/src/stream_var.c         |   20 +-
 libcdi/src/taxis.c              |    4 +-
 libcdi/src/timebase.c           |   70 +-
 libcdi/src/timebase.h           |   15 +-
 libcdi/src/tsteps.c             |   23 +-
 libcdi/src/util.c               |   61 +-
 libcdi/src/varscan.c            |   82 +-
 libcdi/src/varscan.h            |    2 +-
 libcdi/src/vlist.c              |   71 +
 libcdi/src/vlist.h              |   19 +
 libcdi/src/vlist_var.c          |  122 +-
 libcdi/src/zaxis.c              |   21 +-
 libcdi/src/zaxis.h              |    6 +
 src/._CdoMagicsMapper.h         |  Bin 205 -> 205 bytes
 src/._Maggraph.c                |  Bin 205 -> 205 bytes
 src/._Magplot.c                 |  Bin 205 -> 205 bytes
 src/._Magvector.c               |  Bin 205 -> 205 bytes
 src/._Rhopot.c                  |  Bin 0 -> 205 bytes
 src/._StringUtilities.c         |  Bin 205 -> 205 bytes
 src/._StringUtilities.h         |  Bin 205 -> 205 bytes
 src/._magics_template_parser.c  |  Bin 205 -> 205 bytes
 src/._results_template_parser.c |  Bin 205 -> 205 bytes
 src/._template_parser.c         |  Bin 205 -> 205 bytes
 src/._template_parser.h         |  Bin 205 -> 205 bytes
 src/{Rhopot.c => Adisit.c}      |  169 +-
 src/Arith.c                     |    2 +-
 src/Arithc.c                    |    2 +-
 src/Arithdays.c                 |    5 +-
 src/Arithlat.c                  |    2 +-
 src/CDIread.c                   |    2 +-
 src/CDItest.c                   |    2 +-
 src/CDIwrite.c                  |    2 +-
 src/Cat.c                       |    2 +-
 src/Change.c                    |    2 +-
 src/Change_e5slm.c              |    2 +-
 src/Cloudlayer.c                |    2 +-
 src/Command.c                   |    2 +-
 src/Comp.c                      |    2 +-
 src/Compc.c                     |    2 +-
 src/Complextorect.c             |    2 +-
 src/Cond.c                      |    2 +-
 src/Cond2.c                     |    2 +-
 src/Condc.c                     |    2 +-
 src/Consecstat.c                |    4 +-
 src/Copy.c                      |    6 +-
 src/Deltime.c                   |    2 +-
 src/Derivepar.c                 |    8 +-
 src/Detrend.c                   |    2 +-
 src/Diff.c                      |   71 +-
 src/Duplicate.c                 |    2 +-
 src/EOFs.c                      |    2 +-
 src/Echam5ini.c                 |    2 +-
 src/Enlarge.c                   |    2 +-
 src/Enlargegrid.c               |    2 +-
 src/Ensstat.c                   |   19 +-
 src/Ensstat3.c                  |   51 +-
 src/Ensval.c                    |    2 +-
 src/Eof3d.c                     |    2 +-
 src/Eofcoeff.c                  |    2 +-
 src/Eofcoeff3d.c                |    2 +-
 src/Exprf.c                     |    2 +-
 src/FC.c                        |    2 +-
 src/Filedes.c                   |    3 +-
 src/Fillmiss.c                  |    2 +-
 src/Filter.c                    |    4 +-
 src/Fldrms.c                    |    2 +-
 src/Fldstat.c                   |   17 +-
 src/Fldstat2.c                  |    2 +-
 src/Fourier.c                   |    2 +-
 src/Gather.c                    |    2 +-
 src/Gengrid.c                   |    2 +-
 src/Gradsdes.c                  |    2 +-
 src/Gridboxstat.c               |    2 +-
 src/Gridcell.c                  |    7 +-
 src/Harmonic.c                  |    2 +-
 src/Histogram.c                 |    2 +-
 src/Importamsr.c                |    2 +-
 src/Importbinary.c              |    2 +-
 src/Importcmsaf.c               |  111 +-
 src/Importobs.c                 |    2 +-
 src/Info.c                      |    2 +-
 src/Input.c                     |    2 +-
 src/Intgrid.c                   |    2 +-
 src/Intgridtraj.c               |    2 +-
 src/Intlevel.c                  |    2 +-
 src/Intlevel3d.c                |    2 +-
 src/Intntime.c                  |    2 +-
 src/Inttime.c                   |    2 +-
 src/Intyear.c                   |    2 +-
 src/Invert.c                    |    2 +-
 src/Invertlev.c                 |    2 +-
 src/Isosurface.c                |    2 +-
 src/Kvl.c                       |    2 +-
 src/Log.c                       |    2 +-
 src/Maggraph.c                  |   26 +
 src/Magplot.c                   |  367 +--
 src/Makefile.am                 |    4 +-
 src/Makefile.in                 |  222 +-
 src/Maskbox.c                   |  132 +-
 src/Mastrfu.c                   |    2 +-
 src/Math.c                      |    3 +-
 src/Merge.c                     |    4 +-
 src/Mergegrid.c                 |    2 +-
 src/Mergetime.c                 |    2 +-
 src/Merstat.c                   |    2 +-
 src/Monarith.c                  |    2 +-
 src/Mrotuv.c                    |    2 +-
 src/Mrotuvb.c                   |    2 +-
 src/Ninfo.c                     |    3 +-
 src/Nmltest.c                   |    2 +-
 src/Output.c                    |    2 +-
 src/Outputgmt.c                 |    2 +-
 src/Pinfo.c                     |    2 +-
 src/Pressure.c                  |    2 +-
 src/Regres.c                    |    2 +-
 src/Remap.c                     |    3 +-
 src/Replace.c                   |    2 +-
 src/Replacevalues.c             |    2 +-
 src/Rhopot.c                    |   99 +-
 src/Rotuv.c                     |    2 +-
 src/Runpctl.c                   |   28 +-
 src/Runstat.c                   |  246 +-
 src/Scatter.c                   |    2 +-
 src/Seasstat.c                  |    7 +-
 src/Selbox.c                    |  114 +-
 src/Select.c                    |    2 +-
 src/Seloperator.c               |    2 +-
 src/Selrec.c                    |    2 +-
 src/Seltime.c                   |   29 +-
 src/Selvar.c                    |    2 +-
 src/Set.c                       |    2 +-
 src/Setbox.c                    |  132 +-
 src/Setgatt.c                   |    2 +-
 src/Setgrid.c                   |    2 +-
 src/Sethalo.c                   |    2 +-
 src/Setmiss.c                   |    2 +-
 src/Setpartab.c                 |  107 +-
 src/Setrcaname.c                |    2 +-
 src/Settime.c                   |   22 +-
 src/Setzaxis.c                  |    2 +-
 src/Showinfo.c                  |    2 +-
 src/Sinfo.c                     |   84 +-
 src/Smooth9.c                   |    2 +-
 src/Sort.c                      |    2 +-
 src/Sorttimestamp.c             |    2 +-
 src/Specinfo.c                  |    8 +-
 src/Spectral.c                  |    2 +-
 src/Spectrum.c                  |    3 +-
 src/Split.c                     |    2 +-
 src/Splitrec.c                  |    2 +-
 src/Splitsel.c                  |    2 +-
 src/Splittime.c                 |    2 +-
 src/Splityear.c                 |    2 +-
 src/Subtrend.c                  |    2 +-
 src/Tee.c                       |    2 +-
 src/Templates.c                 |    2 +-
 src/Test.c                      |    2 +-
 src/Tests.c                     |    2 +-
 src/Timselstat.c                |   97 +-
 src/Timsort.c                   |    2 +-
 src/Timstat.c                   |  125 +-
 src/Timstat2.c                  |    2 +-
 src/Timstat3.c                  |    2 +-
 src/Tinfo.c                     |   46 +-
 src/Tocomplex.c                 |    2 +-
 src/Transpose.c                 |    2 +-
 src/Trend.c                     |    2 +-
 src/Trms.c                      |    2 +-
 src/Tstepcount.c                |    2 +-
 src/Vardup.c                    |    2 +-
 src/Vargen.c                    |   62 +-
 src/Varrms.c                    |    2 +-
 src/Vertint.c                   |    7 +-
 src/Vertstat.c                  |    2 +-
 src/Vertwind.c                  |    2 +-
 src/Wind.c                      |    2 +-
 src/Writegrid.c                 |    2 +-
 src/Writerandom.c               |    2 +-
 src/YAR.c                       |   11 +-
 src/Ydayarith.c                 |    2 +-
 src/Ydaystat.c                  |   97 +-
 src/Ydrunstat.c                 |   72 +-
 src/Yearmonstat.c               |  259 ++
 src/Yhourarith.c                |    2 +-
 src/Yhourstat.c                 |   97 +-
 src/Ymonarith.c                 |    2 +-
 src/Ymonstat.c                  |   97 +-
 src/Yseasstat.c                 |    2 +-
 src/Zonstat.c                   |    2 +-
 src/cdo.c                       |  375 +--
 src/cdo.h                       |    4 +-
 src/cdo_int.h                   |    8 +-
 src/cdo_pthread.c               |    2 +-
 src/cdo_vlist.c                 |    2 +-
 src/commandline.c               |    2 +-
 src/config.h.in                 |    6 +
 src/expr.c                      |   17 +-
 src/field.c                     |  225 +-
 src/field.h                     |   62 +-
 src/field2.c                    |  437 ++-
 src/fieldc.c                    |    4 +-
 src/fieldmem.c                  |    1 +
 src/fieldmer.c                  |    2 +-
 src/fieldzon.c                  |    2 +-
 src/functs.h                    |   11 +-
 src/gradsdeslib.c               |    1 -
 src/grid.c                      |    2 +-
 src/grid_gme.c                  |    3 +-
 src/griddes.c                   |  157 +-
 src/griddes.h                   |    7 +-
 src/griddes_h5.c                |   16 +-
 src/griddes_nc.c                |    2 +-
 src/history.c                   |    2 +-
 src/institution.c               |    2 +-
 src/interpol.c                  |    9 +-
 src/kvlist.c                    |    2 +-
 src/kvlist.h                    |    2 +-
 src/list.c                      |    2 +-
 src/list.h                      |    2 +-
 src/modules.c                   |   51 +-
 src/modules.h                   |    2 +-
 src/namelist.c                  |    2 +-
 src/namelist.h                  |    2 +-
 src/nth_element.c               |    2 +
 src/operator_help.h             |  536 +++-
 src/pipe.c                      |    2 +-
 src/pipe.h                      |    2 +-
 src/printinfo.h                 |   63 +-
 src/process.c                   |   19 +-
 src/process.h                   |    3 +-
 src/pstream.c                   |   13 +-
 src/pstream.h                   |    2 +-
 src/pstream_int.h               |    2 +-
 src/pthread_debug.c             |    2 +
 src/readline.c                  |    2 +-
 src/remaplib.c                  |   70 +-
 src/remapsort.c                 |   12 +-
 src/specspace.c                 |    4 +-
 src/table.c                     |    2 +-
 src/timer.c                     |    2 +-
 src/util.c                      |    2 +-
 src/util.h                      |    2 +-
 src/zaxis.c                     |   55 +-
 test/Makefile.in                |    1 +
 315 files changed, 9909 insertions(+), 7651 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 3de0b6e..4fcc38c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,112 @@
+2013-03-14 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* using CDI library version 1.6.0
+	* Version 1.6.0 released
+
+2013-03-01 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* gridarea: set number of timesteps to 0 (bug fix for operator chaining) [report: Dirk Notz]
+
+2013-02-25 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* merge: uses size of the first input file for the output buffer [Bug #3290]
+
+2013-02-22 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* New operator: yearmonmean - yearly mean from monthly data
+
+2013-02-21 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* added cdoDefaultFileType to UNCHANGED_RECORD (bug fix)
+
+2013-02-19 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* masklonlatbox: added support for curvilinear grids
+
+2013-02-09 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* New operator: duplicate  - Duplicates a dataset
+
+2013-02-08 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* sellonlatbox: wrong result with overlapped lonlatbox on curvilinear grids (bug fix) [report: Dirk Notz]
+
+2013-02-06 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* New operator: timselvar1  - Time range variance [Divisor is (n-1)]
+	* New operator: timselstd1  - Time range standard deviation [Divisor is (n-1)]
+	* New operator: runvar1  -  Running variance [Divisor is (n-1)]
+	* New operator: runstd1  -  Running standard deviation [Divisor is (n-1)]
+
+2013-02-05 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* ensrkhisttime: fixed memory fault [https://code.zmaw.de/boards/1/topics/1657]
+
+2013-02-04 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* Added CDO option -W to print extra warning messages
+
+2013-01-30 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* New operator: ymonvar1    - Multi-year monthly variance [Divisor is (n-1)]
+	* New operator: ymonstd1    - Multi-year monthly standard deviation [Divisor is(n-1)]
+	* New operator: ydayvar1   - Multi-year daily variance [Divisor is (n-1)]
+	* New operator: ydaystd1   - Multi-year daily standard deviation [Divisor is (n-1)]
+	* New operator: yhourvar1   - Multi-year hourly variance [Divisor is (n-1)]
+	* New operator: yhourstd1   - Multi-year hourly standard deviation [Divisor is (n-1)]
+	* New operator: ydrunvar1    - Multi-year daily running variance [Divisor is (n-1)]
+	* New operator: ydrunstd1    - Multi-year daily running standard deviation [Divisor is (n-1)]
+
+
+2013-01-25 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+        * New operator: timvar1    - Time variance [Divisor is (n-1)]
+	* New operator: timstd1    - Time standard deviation [Divisor is (n-1)]
+        * New operator: hourvar1   - Hourly variance [Divisor is (n-1)]
+	* New operator: hourstd1   - Hourly standard deviation [Divisor is (n-1)]
+	* New operator: dayvar1    - Daily variance [Divisor is (n-1)]
+	* New operator: daystd1    - Daily standard deviation [Divisor is (n-1)]
+	* New operator: monvar1    - Monthly variance [Divisor is (n-1)]
+	* New operator: monstd1    - Monthly standard deviation [Divisor is (n-1)]
+	* New operator: yearvar1   - Yearly variance [Divisor is (n-1)]
+	* New operator: yearstd1   - Yearly standard deviation [Divisor is (n-1)]
+
+2013-01-23 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* New operator: ensstd1 - Ensemble standard deviation [Divisor is (n-1)]
+	* New operator: ensvar1 - Ensemble variance [Divisor is (n-1)]
+	* New operator: fldstd1 - Field standard deviation [Divisor is (n-1)]
+	* New operator: fldvar1 - Field variance [Divisor is (n-1)]
+
+2013-01-22 Helmut Haak <Helmut.Haak at zmaw.de>
+
+	* New operator: adisit - Potential temperature to in-situ temperature
+
+2013-01-21 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* New operator: rhopot - Calculates potential density
+	* New operator: select - select fields from an unlimited number of input files
+
+2013-01-17 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* diff: print only records that differ
+	* setpartab: added namelist entry 'delete'
+
+2013-01-11 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* expr: wrong result for operation var1/var2 where var2 = 0
+
+2013-01-10 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* Settime: set number of output timesteps to unlimited
+
+2013-01-08 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* Runstat: added support for time bounds (Bug #3127)
+        * runpctl: added support for time bounds
+	* setcalendar: changed CDO calendar names to CF calendar names
+                    (standard, proleptic_gregorian, 360_day, 365_day, 366_day)
+
 2012-12-17 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
 
 	* using CDI library version 1.5.9
diff --git a/Makefile.in b/Makefile.in
index b7a7a94..0813dcd 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -164,6 +164,7 @@ ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 ENABLE_CDI_LIB = @ENABLE_CDI_LIB@
 ENABLE_CGRIBEX = @ENABLE_CGRIBEX@
+ENABLE_DATA = @ENABLE_DATA@
 ENABLE_EXTRA = @ENABLE_EXTRA@
 ENABLE_GRIB = @ENABLE_GRIB@
 ENABLE_IEG = @ENABLE_IEG@
diff --git a/NEWS b/NEWS
index e353b54..2d90388 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,26 @@
 CDO NEWS
 --------
+Version 1.6.0 (14 March 2013):
+
+   New operators:
+     * select: Select fields from an unlimited number of input files
+     * mergegrid: Merge horizontal grids
+     * yearmonmean: yearly mean from monthly data
+     * duplicate: Duplicates a dataset
+     * adisit: Potential temperature to in-situ temperature
+     * rhopot: Calculates potential density
+   Changed operators:
+     * setcalendar: changed CDO calendar names to CF calendar names (Feature #3123)
+                    (standard, proleptic_gregorian, 360_day, 365_day, 366_day)
+     * masklonlatbox: added support for curvilinear grids
+     * diff: print only records that differ
+   Fixed bugs:
+     * sellonlatbox: wrong result with overlapped lonlatbox on curvilinear grids
+     * ensrkhisttime: fixed memory fault
+     * expr: wrong result for operation var1/var2 where var2 = 0
+     * Runstat: added support for time bounds (Bug #3127)
+     * merge: uses size of the first input file for the output buffer
+
 Version 1.5.9 (17 December 2012):
 
    New features:
diff --git a/OPERATORS b/OPERATORS
index 2dba242..b030428 100644
--- a/OPERATORS
+++ b/OPERATORS
@@ -41,6 +41,8 @@ Operator catalog:
    Copy          copy            Copy datasets
    Copy          cat             Concatenate datasets
    Replace       replace         Replace variables
+   Duplicate     duplicate       Duplicates a dataset
+   Mergegrid     mergegrid       Merge grid
    Merge         merge           Merge datasets with different fields
    Merge         mergetime       Merge datasets sorted by date and time
    Split         splitcode       Split code numbers
@@ -59,6 +61,8 @@ Operator catalog:
 -------------------------------------------------------------
    Selection
 -------------------------------------------------------------
+   Select        select          Select fields
+   Select        delete          Delete fields
    Selvar        selparam        Select parameters by identifier
    Selvar        delparam        Delete parameters by identifier
    Selvar        selcode         Select parameters by code number
@@ -213,8 +217,10 @@ Operator catalog:
    Ensstat       enssum          Ensemble sum
    Ensstat       ensmean         Ensemble mean
    Ensstat       ensavg          Ensemble average
-   Ensstat       ensvar          Ensemble variance
    Ensstat       ensstd          Ensemble standard deviation
+   Ensstat       ensstd1         Ensemble standard deviation
+   Ensstat       ensvar          Ensemble variance
+   Ensstat       ensvar1         Ensemble variance
    Ensstat       enspctl         Ensemble percentiles
    Ensstat2      ensrkhistspace  Ranked Histogram averaged over time
    Ensstat2      ensrkhisttime   Ranked Histogram averaged over space
@@ -226,8 +232,10 @@ Operator catalog:
    Fldstat       fldsum          Field sum
    Fldstat       fldmean         Field mean
    Fldstat       fldavg          Field average
-   Fldstat       fldvar          Field variance
    Fldstat       fldstd          Field standard deviation
+   Fldstat       fldstd1         Field standard deviation
+   Fldstat       fldvar          Field variance
+   Fldstat       fldvar1         Field variance
    Fldstat       fldpctl         Field percentiles
    Zonstat       zonmin          Zonal minimum
    Zonstat       zonmax          Zonal maximum
@@ -264,56 +272,71 @@ Operator catalog:
    Timselstat    timselsum       Time range sum
    Timselstat    timselmean      Time range mean
    Timselstat    timselavg       Time range average
-   Timselstat    timselvar       Time range variance
    Timselstat    timselstd       Time range standard deviation
+   Timselstat    timselstd1      Time range standard deviation
+   Timselstat    timselvar       Time range variance
+   Timselstat    timselvar1      Time range variance
    Timselpctl    timselpctl      Time range percentiles
    Runstat       runmin          Running minimum
    Runstat       runmax          Running maximum
    Runstat       runsum          Running sum
    Runstat       runmean         Running mean
    Runstat       runavg          Running average
-   Runstat       runvar          Running variance
    Runstat       runstd          Running standard deviation
+   Runstat       runstd1         Running standard deviation
+   Runstat       runvar          Running variance
+   Runstat       runvar1         Running variance
    Runpctl       runpctl         Running percentiles
    Timstat       timmin          Time minimum
    Timstat       timmax          Time maximum
    Timstat       timsum          Time sum
    Timstat       timmean         Time mean
    Timstat       timavg          Time average
-   Timstat       timvar          Time variance
    Timstat       timstd          Time standard deviation
+   Timstat       timstd1         Time standard deviation
+   Timstat       timvar          Time variance
+   Timstat       timvar1         Time variance
    Timpctl       timpctl         Time percentiles
    Hourstat      hourmin         Hourly minimum
    Hourstat      hourmax         Hourly maximum
    Hourstat      hoursum         Hourly sum
    Hourstat      hourmean        Hourly mean
    Hourstat      houravg         Hourly average
-   Hourstat      hourvar         Hourly variance
    Hourstat      hourstd         Hourly standard deviation
+   Hourstat      hourstd1        Hourly standard deviation
+   Hourstat      hourvar         Hourly variance
+   Hourstat      hourvar1        Hourly variance
    Hourpctl      hourpctl        Hourly percentiles
    Daystat       daymin          Daily minimum
    Daystat       daymax          Daily maximum
    Daystat       daysum          Daily sum
    Daystat       daymean         Daily mean
    Daystat       dayavg          Daily average
-   Daystat       dayvar          Daily variance
    Daystat       daystd          Daily standard deviation
+   Daystat       daystd1         Daily standard deviation
+   Daystat       dayvar          Daily variance
+   Daystat       dayvar1         Daily variance
    Daypctl       daypctl         Daily percentiles
    Monstat       monmin          Monthly minimum
    Monstat       monmax          Monthly maximum
    Monstat       monsum          Monthly sum
    Monstat       monmean         Monthly mean
    Monstat       monavg          Monthly average
-   Monstat       monvar          Monthly variance
    Monstat       monstd          Monthly standard deviation
+   Monstat       monstd1         Monthly standard deviation
+   Monstat       monvar          Monthly variance
+   Monstat       monvar1         Monthly variance
    Monpctl       monpctl         Monthly percentiles
+   Yearmonstat   yearmonmean     Yearly mean from monthly data
    Yearstat      yearmin         Yearly minimum
    Yearstat      yearmax         Yearly maximum
    Yearstat      yearsum         Yearly sum
    Yearstat      yearmean        Yearly mean
    Yearstat      yearavg         Yearly average
-   Yearstat      yearvar         Yearly variance
    Yearstat      yearstd         Yearly standard deviation
+   Yearstat      yearstd1        Yearly standard deviation
+   Yearstat      yearvar         Yearly variance
+   Yearstat      yearvar1        Yearly variance
    Yearpctl      yearpctl        Yearly percentiles
    Seasstat      seasmin         Seasonal minimum
    Seasstat      seasmax         Seasonal maximum
@@ -328,23 +351,29 @@ Operator catalog:
    Yhourstat     yhoursum        Multi-year hourly sum
    Yhourstat     yhourmean       Multi-year hourly mean
    Yhourstat     yhouravg        Multi-year hourly average
-   Yhourstat     yhourvar        Multi-year hourly variance
    Yhourstat     yhourstd        Multi-year hourly standard deviation
+   Yhourstat     yhourstd1       Multi-year hourly standard deviation
+   Yhourstat     yhourvar        Multi-year hourly variance
+   Yhourstat     yhourvar1       Multi-year hourly variance
    Ydaystat      ydaymin         Multi-year daily minimum
    Ydaystat      ydaymax         Multi-year daily maximum
    Ydaystat      ydaysum         Multi-year daily sum
    Ydaystat      ydaymean        Multi-year daily mean
    Ydaystat      ydayavg         Multi-year daily average
-   Ydaystat      ydayvar         Multi-year daily variance
    Ydaystat      ydaystd         Multi-year daily standard deviation
+   Ydaystat      ydaystd1        Multi-year daily standard deviation
+   Ydaystat      ydayvar         Multi-year daily variance
+   Ydaystat      ydayvar1        Multi-year daily variance
    Ydaypctl      ydaypctl        Multi-year daily percentiles
    Ymonstat      ymonmin         Multi-year monthly minimum
    Ymonstat      ymonmax         Multi-year monthly maximum
    Ymonstat      ymonsum         Multi-year monthly sum
    Ymonstat      ymonmean        Multi-year monthly mean
    Ymonstat      ymonavg         Multi-year monthly average
-   Ymonstat      ymonvar         Multi-year monthly variance
    Ymonstat      ymonstd         Multi-year monthly standard deviation
+   Ymonstat      ymonstd1        Multi-year monthly standard deviation
+   Ymonstat      ymonvar         Multi-year monthly variance
+   Ymonstat      ymonvar1        Multi-year monthly variance
    Ymonpctl      ymonpctl        Multi-year monthly percentiles
    Yseasstat     yseasmin        Multi-year seasonal minimum
    Yseasstat     yseasmax        Multi-year seasonal maximum
@@ -359,8 +388,10 @@ Operator catalog:
    Ydrunstat     ydrunsum        Multi-year daily running sum
    Ydrunstat     ydrunmean       Multi-year daily running mean
    Ydrunstat     ydrunavg        Multi-year daily running average
-   Ydrunstat     ydrunvar        Multi-year daily running variance
    Ydrunstat     ydrunstd        Multi-year daily running standard deviation
+   Ydrunstat     ydrunstd1       Multi-year daily running standard deviation
+   Ydrunstat     ydrunvar        Multi-year daily running variance
+   Ydrunstat     ydrunvar1       Multi-year daily running variance
    Ydrunpctl     ydrunpctl       Multi-year daily running percentiles
 -------------------------------------------------------------
    Correlation and co.
@@ -458,6 +489,8 @@ Operator catalog:
    Vargen        stdatm          Create values for pressure and temperature for hydrostatic atmosphere
    Rotuv         rotuvb          Backward rotation
    Mastrfu       mastrfu         Mass stream function
+   Adisit        adisit          Potential temperature to in-situ temperature
+   Rhopot        rhopot          Calculates potential density
    Histogram     histcount       Histogram count
    Histogram     histsum         Histogram sum
    Histogram     histmean        Histogram mean
diff --git a/aclocal.m4 b/aclocal.m4
index 191a9ec..5f570db 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -416,18 +416,6 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
      [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
 ])
 
-# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 8
-
-# AM_CONFIG_HEADER is obsolete.  It has been replaced by AC_CONFIG_HEADERS.
-AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
-
 # Do all the work for Automake.                             -*- Autoconf -*-
 
 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
diff --git a/cdo.spec b/cdo.spec
index 54d8bf2..a74d62f 100644
--- a/cdo.spec
+++ b/cdo.spec
@@ -4,7 +4,7 @@
 
 Name:           cdo
 #BuildRequires:  
-Version:        1.5.9
+Version:        1.6.0
 Release:        1
 Summary:        Climate Data Operators
 License:        GNU GENERAL PUBLIC LICENSE Version 2, June 1991
diff --git a/config/default b/config/default
index b635ba2..2e3e086 100755
--- a/config/default
+++ b/config/default
@@ -26,10 +26,10 @@ case "${HOSTNAME}" in
                     --with-hdf5=$HOME/local \
                     --with-szlib=$HOME/local \
                     --with-proj=/opt/local \
-                    --with-libxml2=/usr \
-                    --with-magics=/Users/m214003/local/magics-2.14.9 \
 	            CC=icc CFLAGS="-g  -D_REENTRANT -Wall -W -O3 -openmp" \
                     LIBS="-L/opt/local/lib -lopenjpeg"
+#                    --with-libxml2=/usr \
+#                    --with-magics=/Users/m214003/local/magics-2.14.9 \
 	;;
 # i386-apple-darwin10
     bailung*)
@@ -42,6 +42,8 @@ case "${HOSTNAME}" in
                     --with-szlib=$HOME/local \
                     --with-udunits2=$HOME/local/udunits-2.1.24 \
                     --with-proj=/opt/local \
+                    --with-libxml2=/usr \
+                    --with-magics=/Users/m214003/local/magics-2.14.9 \
 	            CC=gcc CFLAGS="-g -pipe -D_REENTRANT -Wall -W -Wfloat-equal -pedantic -O3 -march=native -fopenmp -DHAVE_LIBYAC -I/Users/m214003/cdt/work/YAC/src" \
                     LIBS="-L/opt/local/lib -lopenjpeg -L/Users/m214003/cdt/work/YAC/src -lyac"
 #                    --with-libxml2=/usr
diff --git a/configure b/configure
index 1e3da8a..3c64ac3 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.5.9.
+# Generated by GNU Autoconf 2.68 for cdo 1.6.0.
 #
 # Report bugs to <http://code.zmaw.de/projects/cdo>.
 #
@@ -570,8 +570,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='cdo'
 PACKAGE_TARNAME='cdo'
-PACKAGE_VERSION='1.5.9'
-PACKAGE_STRING='cdo 1.5.9'
+PACKAGE_VERSION='1.6.0'
+PACKAGE_STRING='cdo 1.6.0'
 PACKAGE_BUGREPORT='http://code.zmaw.de/projects/cdo'
 PACKAGE_URL=''
 
@@ -662,6 +662,7 @@ PTHREAD_CFLAGS
 PTHREAD_LIBS
 PTHREAD_CC
 ax_pthread_config
+ENABLE_DATA
 SYSTEM_TYPE
 HOST_NAME
 USER_NAME
@@ -794,6 +795,7 @@ enable_dependency_tracking
 with_gnu_ld
 enable_libtool_lock
 enable_largefile
+enable_data
 with_threads
 with_zlib
 with_szlib
@@ -1368,7 +1370,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.5.9 to adapt to many kinds of systems.
+\`configure' configures cdo 1.6.0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1438,7 +1440,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of cdo 1.5.9:";;
+     short | recursive ) echo "Configuration of cdo 1.6.0:";;
    esac
   cat <<\_ACEOF
 
@@ -1456,6 +1458,7 @@ Optional Features:
   --enable-dependency-tracking   do not reject slow dependency extractors
   --disable-libtool-lock  avoid locking (might break parallel builds)
   --disable-largefile     omit support for large files
+  --enable-data           DATA support [default=yes]
   --enable-grib           GRIB support [default=yes]
   --enable-cgribex        Use the CGRIBEX library [default=yes]
   --enable-service        Use the service library [default=yes]
@@ -1581,7 +1584,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-cdo configure 1.5.9
+cdo configure 1.6.0
 generated by GNU Autoconf 2.68
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -2174,7 +2177,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.5.9, which was
+It was created by cdo $as_me 1.6.0, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
@@ -3068,7 +3071,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='cdo'
- VERSION='1.5.9'
+ VERSION='1.6.0'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -11327,7 +11330,6 @@ if test "$am_t" != yes; then
 fi
 
 
-#AC_PROG_RANLIB
 if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
 set dummy ${ac_tool_prefix}ar; ac_word=$2
@@ -16157,6 +16159,18 @@ fi
 
 done
 
+for ac_header in glob.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "glob.h" "ac_cv_header_glob_h" "$ac_includes_default"
+if test "x$ac_cv_header_glob_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_GLOB_H 1
+_ACEOF
+
+fi
+
+done
+
 #  ----------------------------------------------------------------------
 # Checks for the availability of functions
 for ac_func in mallinfo
@@ -16311,6 +16325,29 @@ _ACEOF
 fi
 
 #  ----------------------------------------------------------------------
+#  Enable GRIB support
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DATA support" >&5
+$as_echo_n "checking for DATA support... " >&6; }
+# Check whether --enable-data was given.
+if test "${enable_data+set}" = set; then :
+  enableval=$enable_data; if test "x$enable_data" != 'xno'; then :
+
+$as_echo "#define ENABLE_DATA 1" >>confdefs.h
+
+                      enable_grib=yes
+fi
+else
+
+$as_echo "#define ENABLE_DATA 1" >>confdefs.h
+
+               enable_data=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_data" >&5
+$as_echo "$enable_data" >&6; }
+ENABLE_DATA=$enable_data
+
+#  ----------------------------------------------------------------------
 # Add configure options
 
 
@@ -19698,7 +19735,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.5.9, which was
+This file was extended by cdo $as_me 1.6.0, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -19764,7 +19801,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.5.9
+cdo config.status 1.6.0
 configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index f18ce26..d291ac8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
 # Process this file with autoconf to produce a configure script.
 
-AC_INIT([cdo], [1.5.9], [http://code.zmaw.de/projects/cdo])
+AC_INIT([cdo], [1.6.0], [http://code.zmaw.de/projects/cdo])
 
 CONFIG_ABORT=yes
 AC_CONFIG_AUX_DIR(config)
@@ -9,7 +9,7 @@ AC_CANONICAL_HOST
 AC_CANONICAL_BUILD
 
 AM_INIT_AUTOMAKE
-AM_CONFIG_HEADER(src/config.h)
+AC_CONFIG_HEADERS([src/config.h])
 AM_MAINTAINER_MODE([disable])
 
 # Set up libtool.
@@ -20,7 +20,6 @@ LT_INIT
 AC_CHECK_TOOL([CC],[gcc],[:])
 AC_PROG_CC_C99
 AM_PROG_CC_C_O
-#AC_PROG_RANLIB
 AC_CHECK_TOOL([AR],[ar],[:])
 AC_CHECK_TOOL([CPP],[cpp],[:])
 AC_CHECK_TOOL([LD],[ld],[:])
@@ -53,6 +52,7 @@ AC_CHECK_MEMBERS([struct stat.st_blksize])
 AC_CHECK_HEADERS(sys/resource.h)
 AC_CHECK_HEADERS(sys/times.h)
 AC_CHECK_HEADERS(malloc.h)
+AC_CHECK_HEADERS(glob.h)
 #  ----------------------------------------------------------------------
 # Checks for the availability of functions
 AC_CHECK_FUNCS(mallinfo)
@@ -98,6 +98,18 @@ AC_SUBST([SYSTEM_TYPE],["$ac_cv_build"])
 #  Check for math library
 AC_CHECK_LIB([m],[floor])
 #  ----------------------------------------------------------------------
+#  Enable GRIB support
+AC_MSG_CHECKING([for DATA support])
+AC_ARG_ENABLE([data],
+              [AS_HELP_STRING([--enable-data],[DATA support [default=yes]])],
+              [AS_IF([test "x$enable_data" != 'xno'],
+                     [AC_DEFINE(ENABLE_DATA, [1], [Define to 1 for DATA support])
+                      enable_grib=yes])],
+              [AC_DEFINE(ENABLE_DATA, [1], [Define to 1 for DATA support])
+               enable_data=yes])
+AC_MSG_RESULT([$enable_data])
+AC_SUBST([ENABLE_DATA],[$enable_data])
+#  ----------------------------------------------------------------------
 # Add configure options
 ACX_OPTIONS
 #  ----------------------------------------------------------------------
diff --git a/contrib/COPYING b/contrib/COPYING
new file mode 100644
index 0000000..5a965fb
--- /dev/null
+++ b/contrib/COPYING
@@ -0,0 +1,280 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+

+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+

+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+

+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+

+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
diff --git a/contrib/Makefile.am b/contrib/Makefile.am
index ab03668..12dab6b 100644
--- a/contrib/Makefile.am
+++ b/contrib/Makefile.am
@@ -9,10 +9,10 @@ completions:
 test:
 	if (hash ruby &> /dev/null) ; then \
 	    (cd ruby;ruby test/test_cdo.rb) \
-    fi
-	if (hash ruby &> /dev/null) ; then \
+	fi
+	if (hash python &> /dev/null) ; then \
 	    (cd python; python test/test_cdo.py) \
-    fi
+	fi
 
 if MAINTAINER_MODE
 all-local: completions
diff --git a/contrib/Makefile.in b/contrib/Makefile.in
index aa9deae..0ef17c3 100644
--- a/contrib/Makefile.in
+++ b/contrib/Makefile.in
@@ -52,7 +52,7 @@ build_triplet = @build@
 host_triplet = @host@
 @MAINTAINER_MODE_TRUE at am__append_1 = `ls cdoCompletion.*`
 subdir = contrib
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in COPYING
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/acx_options.m4 \
 	$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
@@ -104,6 +104,7 @@ ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 ENABLE_CDI_LIB = @ENABLE_CDI_LIB@
 ENABLE_CGRIBEX = @ENABLE_CGRIBEX@
+ENABLE_DATA = @ENABLE_DATA@
 ENABLE_EXTRA = @ENABLE_EXTRA@
 ENABLE_GRIB = @ENABLE_GRIB@
 ENABLE_IEG = @ENABLE_IEG@
@@ -436,10 +437,10 @@ completions:
 test:
 	if (hash ruby &> /dev/null) ; then \
 	    (cd ruby;ruby test/test_cdo.rb) \
-    fi
-	if (hash ruby &> /dev/null) ; then \
+	fi
+	if (hash python &> /dev/null) ; then \
 	    (cd python; python test/test_cdo.py) \
-    fi
+	fi
 
 @MAINTAINER_MODE_TRUE at all-local: completions
 
diff --git a/contrib/cdoCompletion.bash b/contrib/cdoCompletion.bash
index 5e0f927..de56d7a 100644
--- a/contrib/cdoCompletion.bash
+++ b/contrib/cdoCompletion.bash
@@ -7,6 +7,7 @@ complete -W "
 -R \
 -S \
 -V \
+-W \
 -a \
 -b \
 -f \
@@ -23,6 +24,7 @@ abs -abs \
 acos -acos \
 add -add \
 addc -addc \
+adisit -adisit \
 aexpr -aexpr \
 aexprf -aexprf \
 anomaly -anomaly \
@@ -57,6 +59,7 @@ complextorect -complextorect \
 consecsum -consecsum \
 consects -consects \
 const -const \
+contour -contour \
 conv_cmor_table -conv_cmor_table \
 copy -copy \
 cos -cos \
@@ -70,8 +73,10 @@ daymean -daymean \
 daymin -daymin \
 daypctl -daypctl \
 daystd -daystd \
+daystd1 -daystd1 \
 daysum -daysum \
 dayvar -dayvar \
+dayvar1 -dayvar1 \
 del29feb -del29feb \
 delcode -delcode \
 delday -delday \
@@ -152,8 +157,10 @@ ensrkhistspace -ensrkhistspace \
 ensrkhisttime -ensrkhisttime \
 ensroc -ensroc \
 ensstd -ensstd \
+ensstd1 -ensstd1 \
 enssum -enssum \
 ensvar -ensvar \
+ensvar1 -ensvar1 \
 eof -eof \
 eof3d -eof3d \
 eof3dspatial -eof3dspatial \
@@ -184,8 +191,10 @@ fldmin -fldmin \
 fldpctl -fldpctl \
 fldrms -fldrms \
 fldstd -fldstd \
+fldstd1 -fldstd1 \
 fldsum -fldsum \
 fldvar -fldvar \
+fldvar1 -fldvar1 \
 for -for \
 fourier -fourier \
 fpressure -fpressure \
@@ -210,6 +219,8 @@ gp2spl -gp2spl \
 gradsdes -gradsdes \
 gradsdes1 -gradsdes1 \
 gradsdes2 -gradsdes2 \
+graph -graph \
+grfill -grfill \
 gridarea -gridarea \
 gridboxavg -gridboxavg \
 gridboxmax -gridboxmax \
@@ -240,8 +251,10 @@ hourmean -hourmean \
 hourmin -hourmin \
 hourpctl -hourpctl \
 hourstd -hourstd \
+hourstd1 -hourstd1 \
 hoursum -hoursum \
 hourvar -hourvar \
+hourvar1 -hourvar1 \
 hpressure -hpressure \
 hurr -hurr \
 ifnotthen -ifnotthen \
@@ -340,9 +353,11 @@ monmin -monmin \
 monmul -monmul \
 monpctl -monpctl \
 monstd -monstd \
+monstd1 -monstd1 \
 monsub -monsub \
 monsum -monsum \
 monvar -monvar \
+monvar1 -monvar1 \
 mrotuv -mrotuv \
 mrotuvb -mrotuvb \
 mul -mul \
@@ -424,11 +439,12 @@ runmean -runmean \
 runmin -runmin \
 runpctl -runpctl \
 runstd -runstd \
+runstd1 -runstd1 \
 runsum -runsum \
 runvar -runvar \
+runvar1 -runvar1 \
 scalllogo -scalllogo \
 scatter -scatter \
-sdiff -sdiff \
 seasavg -seasavg \
 seascount -seascount \
 seasmax -seasmax \
@@ -512,6 +528,7 @@ setvar -setvar \
 setvrange -setvrange \
 setyear -setyear \
 setzaxis -setzaxis \
+shaded -shaded \
 shifttime -shifttime \
 showcode -showcode \
 showdate -showdate \
@@ -528,6 +545,7 @@ showunit -showunit \
 showvar -showvar \
 showyear -showyear \
 sin -sin \
+sincos -sincos \
 sinfo -sinfo \
 sinfoc -sinfoc \
 sinfon -sinfon \
@@ -572,6 +590,7 @@ ssopar -ssopar \
 stdatm -stdatm \
 stimelogo -stimelogo \
 strbre -strbre \
+stream -stream \
 strgal -strgal \
 strwin -strwin \
 studentt -studentt \
@@ -602,12 +621,16 @@ timselmean -timselmean \
 timselmin -timselmin \
 timselpctl -timselpctl \
 timselstd -timselstd \
+timselstd1 -timselstd1 \
 timselsum -timselsum \
 timselvar -timselvar \
+timselvar1 -timselvar1 \
 timsort -timsort \
 timstd -timstd \
+timstd1 -timstd1 \
 timsum -timsum \
 timvar -timvar \
+timvar1 -timvar1 \
 tinfo -tinfo \
 topo -topo \
 tpnhalo -tpnhalo \
@@ -625,6 +648,7 @@ varquot2test -varquot2test \
 varrms -varrms \
 vct -vct \
 vct2 -vct2 \
+vector -vector \
 vertavg -vertavg \
 vertmax -vertmax \
 vertmean -vertmean \
@@ -650,26 +674,34 @@ ydaymin -ydaymin \
 ydaymul -ydaymul \
 ydaypctl -ydaypctl \
 ydaystd -ydaystd \
+ydaystd1 -ydaystd1 \
 ydaysub -ydaysub \
 ydaysum -ydaysum \
 ydayvar -ydayvar \
+ydayvar1 -ydayvar1 \
 ydrunavg -ydrunavg \
 ydrunmax -ydrunmax \
 ydrunmean -ydrunmean \
 ydrunmin -ydrunmin \
 ydrunpctl -ydrunpctl \
 ydrunstd -ydrunstd \
+ydrunstd1 -ydrunstd1 \
 ydrunsum -ydrunsum \
 ydrunvar -ydrunvar \
+ydrunvar1 -ydrunvar1 \
 yearavg -yearavg \
 yearcount -yearcount \
 yearmax -yearmax \
 yearmean -yearmean \
 yearmin -yearmin \
+yearmonavg -yearmonavg \
+yearmonmean -yearmonmean \
 yearpctl -yearpctl \
 yearstd -yearstd \
+yearstd1 -yearstd1 \
 yearsum -yearsum \
 yearvar -yearvar \
+yearvar1 -yearvar1 \
 yhouradd -yhouradd \
 yhouravg -yhouravg \
 yhourdiv -yhourdiv \
@@ -678,9 +710,11 @@ yhourmean -yhourmean \
 yhourmin -yhourmin \
 yhourmul -yhourmul \
 yhourstd -yhourstd \
+yhourstd1 -yhourstd1 \
 yhoursub -yhoursub \
 yhoursum -yhoursum \
 yhourvar -yhourvar \
+yhourvar1 -yhourvar1 \
 ymonadd -ymonadd \
 ymonavg -ymonavg \
 ymondiv -ymondiv \
@@ -690,9 +724,11 @@ ymonmin -ymonmin \
 ymonmul -ymonmul \
 ymonpctl -ymonpctl \
 ymonstd -ymonstd \
+ymonstd1 -ymonstd1 \
 ymonsub -ymonsub \
 ymonsum -ymonsum \
 ymonvar -ymonvar \
+ymonvar1 -ymonvar1 \
 yseasavg -yseasavg \
 yseasmax -yseasmax \
 yseasmean -yseasmean \
diff --git a/contrib/cdoCompletion.tcsh b/contrib/cdoCompletion.tcsh
index b5a69b0..c6ad742 100644
--- a/contrib/cdoCompletion.tcsh
+++ b/contrib/cdoCompletion.tcsh
@@ -7,6 +7,7 @@ Q \
 R \
 S \
 V \
+W \
 a \
 b \
 f \
@@ -23,6 +24,7 @@ abs \
 acos \
 add \
 addc \
+adisit \
 aexpr \
 aexprf \
 anomaly \
@@ -57,6 +59,7 @@ complextorect \
 consecsum \
 consects \
 const \
+contour \
 conv_cmor_table \
 copy \
 cos \
@@ -70,8 +73,10 @@ daymean \
 daymin \
 daypctl \
 daystd \
+daystd1 \
 daysum \
 dayvar \
+dayvar1 \
 del29feb \
 delcode \
 delday \
@@ -152,8 +157,10 @@ ensrkhistspace \
 ensrkhisttime \
 ensroc \
 ensstd \
+ensstd1 \
 enssum \
 ensvar \
+ensvar1 \
 eof \
 eof3d \
 eof3dspatial \
@@ -184,8 +191,10 @@ fldmin \
 fldpctl \
 fldrms \
 fldstd \
+fldstd1 \
 fldsum \
 fldvar \
+fldvar1 \
 for \
 fourier \
 fpressure \
@@ -210,6 +219,8 @@ gp2spl \
 gradsdes \
 gradsdes1 \
 gradsdes2 \
+graph \
+grfill \
 gridarea \
 gridboxavg \
 gridboxmax \
@@ -240,8 +251,10 @@ hourmean \
 hourmin \
 hourpctl \
 hourstd \
+hourstd1 \
 hoursum \
 hourvar \
+hourvar1 \
 hpressure \
 hurr \
 ifnotthen \
@@ -340,9 +353,11 @@ monmin \
 monmul \
 monpctl \
 monstd \
+monstd1 \
 monsub \
 monsum \
 monvar \
+monvar1 \
 mrotuv \
 mrotuvb \
 mul \
@@ -424,11 +439,12 @@ runmean \
 runmin \
 runpctl \
 runstd \
+runstd1 \
 runsum \
 runvar \
+runvar1 \
 scalllogo \
 scatter \
-sdiff \
 seasavg \
 seascount \
 seasmax \
@@ -512,6 +528,7 @@ setvar \
 setvrange \
 setyear \
 setzaxis \
+shaded \
 shifttime \
 showcode \
 showdate \
@@ -528,6 +545,7 @@ showunit \
 showvar \
 showyear \
 sin \
+sincos \
 sinfo \
 sinfoc \
 sinfon \
@@ -572,6 +590,7 @@ ssopar \
 stdatm \
 stimelogo \
 strbre \
+stream \
 strgal \
 strwin \
 studentt \
@@ -602,12 +621,16 @@ timselmean \
 timselmin \
 timselpctl \
 timselstd \
+timselstd1 \
 timselsum \
 timselvar \
+timselvar1 \
 timsort \
 timstd \
+timstd1 \
 timsum \
 timvar \
+timvar1 \
 tinfo \
 topo \
 tpnhalo \
@@ -625,6 +648,7 @@ varquot2test \
 varrms \
 vct \
 vct2 \
+vector \
 vertavg \
 vertmax \
 vertmean \
@@ -650,26 +674,34 @@ ydaymin \
 ydaymul \
 ydaypctl \
 ydaystd \
+ydaystd1 \
 ydaysub \
 ydaysum \
 ydayvar \
+ydayvar1 \
 ydrunavg \
 ydrunmax \
 ydrunmean \
 ydrunmin \
 ydrunpctl \
 ydrunstd \
+ydrunstd1 \
 ydrunsum \
 ydrunvar \
+ydrunvar1 \
 yearavg \
 yearcount \
 yearmax \
 yearmean \
 yearmin \
+yearmonavg \
+yearmonmean \
 yearpctl \
 yearstd \
+yearstd1 \
 yearsum \
 yearvar \
+yearvar1 \
 yhouradd \
 yhouravg \
 yhourdiv \
@@ -678,9 +710,11 @@ yhourmean \
 yhourmin \
 yhourmul \
 yhourstd \
+yhourstd1 \
 yhoursub \
 yhoursum \
 yhourvar \
+yhourvar1 \
 ymonadd \
 ymonavg \
 ymondiv \
@@ -690,9 +724,11 @@ ymonmin \
 ymonmul \
 ymonpctl \
 ymonstd \
+ymonstd1 \
 ymonsub \
 ymonsum \
 ymonvar \
+ymonvar1 \
 yseasavg \
 yseasmax \
 yseasmean \
diff --git a/contrib/cdoCompletion.zsh b/contrib/cdoCompletion.zsh
index 50cb62b..e4738fd 100644
--- a/contrib/cdoCompletion.zsh
+++ b/contrib/cdoCompletion.zsh
@@ -7,6 +7,7 @@ compctl -k "(
 -R \
 -S \
 -V \
+-W \
 -a \
 -b \
 -f \
@@ -23,6 +24,7 @@ abs -abs \
 acos -acos \
 add -add \
 addc -addc \
+adisit -adisit \
 aexpr -aexpr \
 aexprf -aexprf \
 anomaly -anomaly \
@@ -57,6 +59,7 @@ complextorect -complextorect \
 consecsum -consecsum \
 consects -consects \
 const -const \
+contour -contour \
 conv_cmor_table -conv_cmor_table \
 copy -copy \
 cos -cos \
@@ -70,8 +73,10 @@ daymean -daymean \
 daymin -daymin \
 daypctl -daypctl \
 daystd -daystd \
+daystd1 -daystd1 \
 daysum -daysum \
 dayvar -dayvar \
+dayvar1 -dayvar1 \
 del29feb -del29feb \
 delcode -delcode \
 delday -delday \
@@ -152,8 +157,10 @@ ensrkhistspace -ensrkhistspace \
 ensrkhisttime -ensrkhisttime \
 ensroc -ensroc \
 ensstd -ensstd \
+ensstd1 -ensstd1 \
 enssum -enssum \
 ensvar -ensvar \
+ensvar1 -ensvar1 \
 eof -eof \
 eof3d -eof3d \
 eof3dspatial -eof3dspatial \
@@ -184,8 +191,10 @@ fldmin -fldmin \
 fldpctl -fldpctl \
 fldrms -fldrms \
 fldstd -fldstd \
+fldstd1 -fldstd1 \
 fldsum -fldsum \
 fldvar -fldvar \
+fldvar1 -fldvar1 \
 for -for \
 fourier -fourier \
 fpressure -fpressure \
@@ -210,6 +219,8 @@ gp2spl -gp2spl \
 gradsdes -gradsdes \
 gradsdes1 -gradsdes1 \
 gradsdes2 -gradsdes2 \
+graph -graph \
+grfill -grfill \
 gridarea -gridarea \
 gridboxavg -gridboxavg \
 gridboxmax -gridboxmax \
@@ -240,8 +251,10 @@ hourmean -hourmean \
 hourmin -hourmin \
 hourpctl -hourpctl \
 hourstd -hourstd \
+hourstd1 -hourstd1 \
 hoursum -hoursum \
 hourvar -hourvar \
+hourvar1 -hourvar1 \
 hpressure -hpressure \
 hurr -hurr \
 ifnotthen -ifnotthen \
@@ -340,9 +353,11 @@ monmin -monmin \
 monmul -monmul \
 monpctl -monpctl \
 monstd -monstd \
+monstd1 -monstd1 \
 monsub -monsub \
 monsum -monsum \
 monvar -monvar \
+monvar1 -monvar1 \
 mrotuv -mrotuv \
 mrotuvb -mrotuvb \
 mul -mul \
@@ -424,11 +439,12 @@ runmean -runmean \
 runmin -runmin \
 runpctl -runpctl \
 runstd -runstd \
+runstd1 -runstd1 \
 runsum -runsum \
 runvar -runvar \
+runvar1 -runvar1 \
 scalllogo -scalllogo \
 scatter -scatter \
-sdiff -sdiff \
 seasavg -seasavg \
 seascount -seascount \
 seasmax -seasmax \
@@ -512,6 +528,7 @@ setvar -setvar \
 setvrange -setvrange \
 setyear -setyear \
 setzaxis -setzaxis \
+shaded -shaded \
 shifttime -shifttime \
 showcode -showcode \
 showdate -showdate \
@@ -528,6 +545,7 @@ showunit -showunit \
 showvar -showvar \
 showyear -showyear \
 sin -sin \
+sincos -sincos \
 sinfo -sinfo \
 sinfoc -sinfoc \
 sinfon -sinfon \
@@ -572,6 +590,7 @@ ssopar -ssopar \
 stdatm -stdatm \
 stimelogo -stimelogo \
 strbre -strbre \
+stream -stream \
 strgal -strgal \
 strwin -strwin \
 studentt -studentt \
@@ -602,12 +621,16 @@ timselmean -timselmean \
 timselmin -timselmin \
 timselpctl -timselpctl \
 timselstd -timselstd \
+timselstd1 -timselstd1 \
 timselsum -timselsum \
 timselvar -timselvar \
+timselvar1 -timselvar1 \
 timsort -timsort \
 timstd -timstd \
+timstd1 -timstd1 \
 timsum -timsum \
 timvar -timvar \
+timvar1 -timvar1 \
 tinfo -tinfo \
 topo -topo \
 tpnhalo -tpnhalo \
@@ -625,6 +648,7 @@ varquot2test -varquot2test \
 varrms -varrms \
 vct -vct \
 vct2 -vct2 \
+vector -vector \
 vertavg -vertavg \
 vertmax -vertmax \
 vertmean -vertmean \
@@ -650,26 +674,34 @@ ydaymin -ydaymin \
 ydaymul -ydaymul \
 ydaypctl -ydaypctl \
 ydaystd -ydaystd \
+ydaystd1 -ydaystd1 \
 ydaysub -ydaysub \
 ydaysum -ydaysum \
 ydayvar -ydayvar \
+ydayvar1 -ydayvar1 \
 ydrunavg -ydrunavg \
 ydrunmax -ydrunmax \
 ydrunmean -ydrunmean \
 ydrunmin -ydrunmin \
 ydrunpctl -ydrunpctl \
 ydrunstd -ydrunstd \
+ydrunstd1 -ydrunstd1 \
 ydrunsum -ydrunsum \
 ydrunvar -ydrunvar \
+ydrunvar1 -ydrunvar1 \
 yearavg -yearavg \
 yearcount -yearcount \
 yearmax -yearmax \
 yearmean -yearmean \
 yearmin -yearmin \
+yearmonavg -yearmonavg \
+yearmonmean -yearmonmean \
 yearpctl -yearpctl \
 yearstd -yearstd \
+yearstd1 -yearstd1 \
 yearsum -yearsum \
 yearvar -yearvar \
+yearvar1 -yearvar1 \
 yhouradd -yhouradd \
 yhouravg -yhouravg \
 yhourdiv -yhourdiv \
@@ -678,9 +710,11 @@ yhourmean -yhourmean \
 yhourmin -yhourmin \
 yhourmul -yhourmul \
 yhourstd -yhourstd \
+yhourstd1 -yhourstd1 \
 yhoursub -yhoursub \
 yhoursum -yhoursum \
 yhourvar -yhourvar \
+yhourvar1 -yhourvar1 \
 ymonadd -ymonadd \
 ymonavg -ymonavg \
 ymondiv -ymondiv \
@@ -690,9 +724,11 @@ ymonmin -ymonmin \
 ymonmul -ymonmul \
 ymonpctl -ymonpctl \
 ymonstd -ymonstd \
+ymonstd1 -ymonstd1 \
 ymonsub -ymonsub \
 ymonsum -ymonsum \
 ymonvar -ymonvar \
+ymonvar1 -ymonvar1 \
 yseasavg -yseasavg \
 yseasmax -yseasmax \
 yseasmean -yseasmean \
diff --git a/contrib/python/cdo.py b/contrib/python/cdo.py
index ba98d00..88bcc41 100644
--- a/contrib/python/cdo.py
+++ b/contrib/python/cdo.py
@@ -23,10 +23,11 @@ class CDOException(Exception):
 
     def __init__(self, stdout, stderr, returncode):
         super(CDOException, self).__init__()
-        self.stdout = stdout
-        self.stderr = stderr
+        self.stdout     = stdout
+        self.stderr     = stderr
         self.returncode = returncode
-        self.msg = '(returncode:%s) %s' % (returncode, stderr)
+        self.msg        = '(returncode:%s) %s' % (returncode, stderr)
+
     def __str__(self):
         return self.msg
 
@@ -70,6 +71,7 @@ class Cdo(object):
     self.outputOperatorsPattern = '(diff|info|output|griddes|zaxisdes|show|ncode|ndate|nlevel|nmon|nvar|nyear|ntime|npar|gradsdes|pardes)'
 
     self.cdfMod      = ''
+    self.libs        = self.getSupportedLibs()
 
   def __dir__(self):
     res = dir(type(self)) + list(self.__dict__.keys())
@@ -142,7 +144,7 @@ class Cdo(object):
       else:
         if kwargs["force"] or \
            (kwargs.__contains__("output") and not os.path.isfile(kwargs["output"])):
-          if not kwargs.__contains__("output"):
+          if not kwargs.__contains__("output") or None == kwargs["output"]:
             kwargs["output"] = self.tempfile.path()
 
           cmd.append(kwargs["output"])
@@ -205,6 +207,24 @@ class Cdo(object):
       except:
         raise ImportError,"scipy or python-netcdf4 module is required to return numpy arrays."
 
+  def getSupportedLibs(self,force=False):
+    proc = subprocess.Popen('cdo -V',
+        shell  = True,
+        stderr = subprocess.PIPE,
+        stdout = subprocess.PIPE)
+    retvals = proc.communicate()
+
+    withs     = re.findall('with: (.*)',retvals[1])[0].split(' ')
+    libs      = re.findall('(\w+) library version : (\d+\.\d+\.\d+)',retvals[1])
+    libraries = dict({})
+    for w in withs:
+      libraries[w.lower()] = True
+
+    for lib in libs:
+      l,v = lib
+      libraries[l.lower()] = v
+
+    return libraries
 
   def setReturnArray(self,value=True):
     self.returnCdf = value
@@ -240,6 +260,20 @@ class Cdo(object):
   def getCdo(self):
     return self.CDO
 
+  def hasLib(self,lib):
+    return lib in self.libs
+    return false
+
+  def libsVersion(self,lib):
+    if not self.hasLib(lib):
+      raise AttributeError, "Cdo does NOT have support for '#{lib}'"
+    else:
+      if True != self.libs[lib]:
+        return self.libs[lib]
+      else:
+        print "No version information available about '" + lib + "'"
+        return False
+
   #==================================================================
   # Addional operators:
   #------------------------------------------------------------------
diff --git a/doc/cdo.pdf b/doc/cdo.pdf
index 2686e56..a68cc8a 100644
Binary files a/doc/cdo.pdf and b/doc/cdo.pdf differ
diff --git a/doc/cdo_refcard.pdf b/doc/cdo_refcard.pdf
index 1cc1278..fe12eed 100644
Binary files a/doc/cdo_refcard.pdf and b/doc/cdo_refcard.pdf differ
diff --git a/libcdi/ChangeLog b/libcdi/ChangeLog
index 1c5ecb9..c64a7e0 100644
--- a/libcdi/ChangeLog
+++ b/libcdi/ChangeLog
@@ -1,3 +1,68 @@
+2013-03-14  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* Version 1.6.0 released
+	* using CGRIBEX library version 1.6.0
+
+2013-03-13  Florian Prill  <Florian.Prill at dwd.de>
+
+	* Read arbitrary GRIB keys [Feature #3267]
+
+2013-03-13  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* GRIB: added support for time step unit: seconds [Bug #3352]
+
+2013-03-12  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* Added support for level type CLOUD_BASE, CLOUD_TOP and ISOTHERM_ZERO [Feature #3247]
+	* stream_gribapi: changed units for level type GRIB2_LTYPE_LANDDEPTH to m (internally mm) [Bug #3287]
+	* gribapiGetGrid: get gridDescriptionFile with grib_get_string() instead of grib_get_bytes() (bug fix)
+
+2013-03-11  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* stream_gribapi: added support for local table shortName.def [Bug #3343]
+
+2013-03-08  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* vtime2timeval: check validity of month
+
+2013-03-07  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* cdfDefGrid: bug fix for generic grids with nx or ny > 0
+	* netCDF: ignore the attribute valid_min/valid_max, if the data type is inconsistent
+
+2013-02-18  Florian Prill  <Florian.Prill at dwd.de>
+
+	* Added function vlistDefVarIntKey() and vlistDefVarDblKey() to set GRIB_API Key/Value pairs
+
+2013-02-13  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* cgribexGetTsteptype: changed default to TSTEP_INSTANT [Bug #3211]
+
+2013-02-04  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* netCDF: ignore the attribute valid_range, if the data type is inconsistent
+	* netCDF: added env IGNORE_VALID_RANGE to ignore the attribute valid_range
+
+2013-01-31  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* stream_cgribex::cgribexGetGrid: add 360 to lastLon, if lastlon <firstLon [Bug #3189]
+
+2013-01-08  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* netCDF: check position of time dimension
+
+2013-01-15  Thomas Jahns  <jahns at dkrz.de>
+
+	* make_fint.c: added regexec support
+
+2013-01-08  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* global netCDF attribute "source" missing (bug fix)
+
+2012-12-18  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* reshGetValue: added caller function name to error message
+
 2012-12-17  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
 
 	* Version 1.5.9 released
diff --git a/libcdi/NEWS b/libcdi/NEWS
index f913d46..ae614eb 100644
--- a/libcdi/NEWS
+++ b/libcdi/NEWS
@@ -1,6 +1,22 @@
 CDI NEWS
 --------
 
+Version 1.6.0 (14 March 2013):
+
+   New features:
+     * Added support for level type CLOUD_BASE, CLOUD_TOP and ISOTHERM_ZERO [Feature #3247]
+     * Read arbitrary GRIB keys [Feature #3267]
+   New functions:
+     * vlistDefVarIntKey(): Set an arbitrary keyword/integer value pair for GRIB API
+     * vlistDefVarDblKey(): Set an arbitrary keyword/double value pair for GRIB API
+   Fixed bugs:
+     * GRIB: added support for time step unit: seconds [Bug #3352]
+     * stream_gribapi: added support for local table shortName.def [Bug #3343]
+     * stream_gribapi: changed units for level type GRIB2_LTYPE_LANDDEPTH to m (internally mm) [Bug #3287]
+     * netCDF: ignore the attribute valid_range, if the data type is inconsistent
+     * global netCDF attribute "source" missing
+     * cgribexGetTsteptype: changed default to TSTEP_INSTANT [Bug #3211]
+
 Version 1.5.9 (17 December 2012):
 
    New features:
diff --git a/libcdi/aclocal.m4 b/libcdi/aclocal.m4
index 1ea95c4..302b7f6 100644
--- a/libcdi/aclocal.m4
+++ b/libcdi/aclocal.m4
@@ -416,18 +416,6 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
      [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
 ])
 
-# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 8
-
-# AM_CONFIG_HEADER is obsolete.  It has been replaced by AC_CONFIG_HEADERS.
-AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
-
 # Do all the work for Automake.                             -*- Autoconf -*-
 
 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
diff --git a/libcdi/app/cdi.c b/libcdi/app/cdi.c
index 59f31e3..92138b0 100644
--- a/libcdi/app/cdi.c
+++ b/libcdi/app/cdi.c
@@ -261,6 +261,31 @@ void printInfo(int gridtype, int vdate, int vtime, char *varname, double level,
 
 #define MAXCHARS 82
 
+const char * tunit2str(int tunits)
+{
+  if      ( tunits == TUNIT_YEAR )    return ("years");
+  else if ( tunits == TUNIT_MONTH )   return ("months");
+  else if ( tunits == TUNIT_DAY )     return ("days");
+  else if ( tunits == TUNIT_12HOURS ) return ("12hours");
+  else if ( tunits == TUNIT_6HOURS )  return ("6hours");
+  else if ( tunits == TUNIT_3HOURS )  return ("3hours");
+  else if ( tunits == TUNIT_HOUR )    return ("hours");
+  else if ( tunits == TUNIT_MINUTE )  return ("minutes");
+  else if ( tunits == TUNIT_SECOND )  return ("seconds");
+  else                                return ("unknown");
+}
+
+
+const char * calendar2str(int calendar)
+{
+  if      ( calendar == CALENDAR_STANDARD )  return ("standard");
+  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");
+}
+
 static
 void printShortinfo(int streamID, int vlistID, int vardis)
 {
@@ -371,9 +396,9 @@ void printShortinfo(int streamID, int vlistID, int vardis)
 	  if ( vardis ) vlistInqVarName(vlistID, varID, varname);
 
           if ( vardis )
-	    fprintf(stdout, "%-11s ", varname);
+	    fprintf(stdout, "%-11s", varname);
 	  else
-	    fprintf(stdout, "%-11s ", paramstr);
+	    fprintf(stdout, "%-11s", paramstr);
 
 	  fprintf(stdout, "\n");
 	}
@@ -444,10 +469,10 @@ void printShortinfo(int streamID, int vlistID, int vardis)
 
 	  if ( taxisID != CDI_UNDEFID )
 	    {
-	      int calendar, tunits;
-
 	      if ( taxisInqType(taxisID) == TAXIS_RELATIVE )
 		{
+                  int calendar, tunits;
+
 		  vdate = taxisInqRdate(taxisID);
 		  vtime = taxisInqRtime(taxisID);
 
@@ -458,46 +483,10 @@ void printShortinfo(int streamID, int vlistID, int vardis)
 			  year, month, day, hour, minute, second);
 
 		  tunits = taxisInqTunit(taxisID);
-		  if ( tunits != CDI_UNDEFID )
-		    {
-		      if ( tunits == TUNIT_YEAR )
-			fprintf(stdout, "  Units = years");
-		      else if ( tunits == TUNIT_MONTH )
-			fprintf(stdout, "  Units = months");
-		      else if ( tunits == TUNIT_DAY )
-			fprintf(stdout, "  Units = days");
-		      else if ( tunits == TUNIT_12HOURS )
-			fprintf(stdout, "  Units = 12hours");
-		      else if ( tunits == TUNIT_6HOURS )
-			fprintf(stdout, "  Units = 6hours");
-		      else if ( tunits == TUNIT_3HOURS )
-			fprintf(stdout, "  Units = 3hours");
-		      else if ( tunits == TUNIT_HOUR )
-			fprintf(stdout, "  Units = hours");
-		      else if ( tunits == TUNIT_MINUTE )
-			fprintf(stdout, "  Units = minutes");
-		      else if ( tunits == TUNIT_SECOND )
-			fprintf(stdout, "  Units = seconds");
-		      else
-			fprintf(stdout, "  Units = unknown");
-		    }
+		  if ( tunits != CDI_UNDEFID )  fprintf(stdout, "  Units = %s", tunit2str(tunits));
 
 		  calendar = taxisInqCalendar(taxisID);
-		  if ( calendar != CDI_UNDEFID )
-		    {
-		      if ( calendar == CALENDAR_STANDARD )
-			fprintf(stdout, "  Calendar = STANDARD");
-		      else if ( calendar == CALENDAR_PROLEPTIC )
-			fprintf(stdout, "  Calendar = PROLEPTIC");
-		      else if ( calendar == CALENDAR_360DAYS )
-			fprintf(stdout, "  Calendar = 360DAYS");
-		      else if ( calendar == CALENDAR_365DAYS )
-			fprintf(stdout, "  Calendar = 365DAYS");
-		      else if ( calendar == CALENDAR_366DAYS )
-			fprintf(stdout, "  Calendar = 366DAYS");
-		      else
-			fprintf(stdout, "  Calendar = unknown");
-		    }
+		  if ( calendar != CDI_UNDEFID )  fprintf(stdout, "  Calendar = %s", calendar2str(calendar));
 
 		  if ( taxisHasBounds(taxisID) )
 		    fprintf(stdout, "  Bounds = true");
diff --git a/libcdi/app/createtable.c b/libcdi/app/createtable.c
index f7e2090..e3a829c 100644
--- a/libcdi/app/createtable.c
+++ b/libcdi/app/createtable.c
@@ -44,22 +44,22 @@ int main(int argc, char *argv[])
 	  if ( !strncmp(cstring, "debug", len) )
 	    {
 	      debug = 1;
-	      break;
 	    }
+	  break;
         case 'h':
 	  if ( !strncmp(cstring, "help", len) )
 	    { 
 	      usage( );
 	      return( 0 );
-	      break;
             }
+	  break;
         case 'v':
 	  if ( !strncmp(cstring, "version", len) )
 	    {
 	      version();
 	      return (0);
-	      break;
             }
+	  break;
         default:
 	  usage();
 	  fprintf(stderr, "illegal option %s\n", cstring);
diff --git a/libcdi/app/printinfo.h b/libcdi/app/printinfo.h
index ed53588..c7ab8e7 100644
--- a/libcdi/app/printinfo.h
+++ b/libcdi/app/printinfo.h
@@ -1,6 +1,8 @@
 #define DATE_FORMAT "%5.4d-%2.2d-%2.2d"
 #define TIME_FORMAT "%2.2d:%2.2d:%2.2d"
 
+void uuid2str(const char *uuid, char *uuidstr);
+
 void date2str(int date, char *datestr, int maxlen)
 {
   int year, month, day;
@@ -66,6 +68,7 @@ void printFiletype(int streamID, int vlistID)
       break;
     default:
       printf("  File format: unsupported filetype %d" , filetype);
+      break;
     }
 
   if ( filetype == FILETYPE_SRV || filetype == FILETYPE_EXT || filetype == FILETYPE_IEG )
@@ -133,6 +136,7 @@ void printGridInfo(int vlistID)
   int gridID, gridtype, trunc, gridsize, xsize, ysize;
   int nbyte0;
   char xname[CDI_MAX_NAME], yname[CDI_MAX_NAME], xunits[CDI_MAX_NAME], yunits[CDI_MAX_NAME];
+  char uuidOfHGrid[17];
 
   ngrids = vlistNgrids(vlistID);
   for ( index = 0; index < ngrids; index++ )
@@ -154,9 +158,11 @@ void printGridInfo(int vlistID)
 	   gridtype == GRID_LCC2 ||
 	   gridtype == GRID_LAEA ||
 	   gridtype == GRID_SINUSOIDAL ||
+	   gridtype == GRID_GENERIC ||
 	   gridtype == GRID_GAUSSIAN ||
 	   gridtype == GRID_GAUSSIAN_REDUCED )
 	{
+          int lxcoord = 1, lycoord = 1;
 	  double xfirst = 0.0, xlast = 0.0;
 	  double yfirst = 0.0, ylast = 0.0;
 	  double xinc = 0.0, yinc = 0.0;
@@ -168,14 +174,17 @@ void printGridInfo(int vlistID)
 	  if ( gridtype == GRID_GAUSSIAN_REDUCED )
 	    fprintf(stdout, "size : dim = %d  nlat = %d", gridsize, ysize);
 	  else
-	    fprintf(stdout, "size      : dim = %d  nlon = %d  nlat = %d", gridsize, xsize, ysize);
-	  
+	    fprintf(stdout, "size      : dim = %d  nx = %d  ny = %d", gridsize, xsize, ysize);
+
 	  if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_GAUSSIAN_REDUCED )
 	    fprintf(stdout, "  np = %d", gridInqNP(gridID));
 
 	  fprintf(stdout, "\n");
 
-	  if ( xsize > 0 )
+          if ( gridInqXvals(gridID, NULL) == 0 ) lxcoord = 0;
+          if ( gridInqYvals(gridID, NULL) == 0 ) lycoord = 0;
+
+	  if ( xsize > 0 && lxcoord )
 	    {
 	      if ( gridtype == GRID_GAUSSIAN_REDUCED )
 		{
@@ -194,19 +203,18 @@ void printGridInfo(int vlistID)
 		  if ( IS_NOT_EQUAL(xinc, 0) )
 		    fprintf(stdout, "  inc = %.9g", xinc);
 		  fprintf(stdout, "  %s", xunits);
-		  if ( gridIsCircular(gridID) )
-		    fprintf(stdout, "  circular");
+		  if ( gridIsCircular(gridID) ) fprintf(stdout, "  circular");
 		  fprintf(stdout, "\n");
 		}
 	    }
 
-	  if ( ysize > 0 )
+	  if ( ysize > 0 && lycoord )
 	    {
 	      fprintf(stdout, "%*s", nbyte0, "");
 	      fprintf(stdout, "%-9s : first = %.9g", yname, yfirst);
 	      if ( ysize > 1 ) fprintf(stdout, "  last = %.9g", ylast);
-	      if ( IS_NOT_EQUAL(yinc, 0) && 
-		   (gridtype == GRID_LONLAT || gridtype == GRID_SINUSOIDAL || 
+	      if ( IS_NOT_EQUAL(yinc, 0) &&
+		   (gridtype == GRID_LONLAT || gridtype == GRID_SINUSOIDAL ||
 		    gridtype == GRID_LCC2 || gridtype == GRID_LAEA) )
 		fprintf(stdout, "  inc = %.9g", yinc);
 	      fprintf(stdout, "  %s", yunits);
@@ -231,6 +239,7 @@ void printGridInfo(int vlistID)
 	      fprintf(stdout, "available :");
 	      if ( gridInqXbounds(gridID, NULL) ) fprintf(stdout, " xbounds");
 	      if ( gridInqYbounds(gridID, NULL) ) fprintf(stdout, " ybounds");
+	      if ( gridHasArea(gridID) )          fprintf(stdout, " area");
 	      if ( gridInqMask(gridID, NULL) )    fprintf(stdout, " mask");
 	      fprintf(stdout, "\n");
 	    }
@@ -317,12 +326,11 @@ void printGridInfo(int vlistID)
 
 	      fprintf(stdout, "%*s", nbyte0, "");
 	      fprintf(stdout, "%-9s : min = %.9g  max = %.9g  %s", xname, xfirst, xlast, xunits);
-	      if ( gridIsCircular(gridID) )
-		fprintf(stdout, "  circular");
+	      if ( gridIsCircular(gridID) ) fprintf(stdout, "  circular");
 	      fprintf(stdout, "\n");
 	      fprintf(stdout, "%*s", nbyte0, "");
 	      fprintf(stdout, "%-9s : min = %.9g  max = %.9g  %s\n", yname, yfirst, ylast, yunits);
- 
+
 	      free(xvals);
 	      free(yvals);
 	    }
@@ -352,18 +360,10 @@ void printGridInfo(int vlistID)
 	  if ( ysize == 0 )
 	    fprintf(stdout, "size      : dim = %d\n", gridsize);
 	  else
-	    {
-	      fprintf(stdout, "size      : dim = %d  nx = %d  ny = %d\n", gridsize, xsize, ysize);
-	      if ( gridIsCircular(gridID) )
-		{
-		  fprintf(stdout, "%*s", nbyte0, "");
-		  fprintf(stdout, "longitude :  circular\n");
-		}
-	    }
+            fprintf(stdout, "size      : dim = %d  nx = %d  ny = %d\n", gridsize, xsize, ysize);
 	}
 
-      if ( gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED ||
-	   gridtype == GRID_GENERIC || gridtype == GRID_LCC )
+      if ( gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED || gridtype == GRID_LCC )
 	{
 	  if ( gridInqXvals(gridID, NULL) || gridInqYvals(gridID, NULL) || gridHasArea(gridID) ||
 	       gridInqXbounds(gridID, NULL) || gridInqYbounds(gridID, NULL) )
@@ -379,6 +379,18 @@ void printGridInfo(int vlistID)
 	      fprintf(stdout, "\n");
 	    }
 	}
+
+      gridInqUUID(gridID, uuidOfHGrid);
+      if ( uuidOfHGrid[0] != 0 )
+        {
+          char uuidOfHGridStr[37];
+          uuid2str(uuidOfHGrid, uuidOfHGridStr);
+          if ( uuidOfHGridStr[0] != 0  && strlen(uuidOfHGridStr) == 36 )
+            {
+	      fprintf(stdout, "%*s", nbyte0, "");
+	      fprintf(stdout, "uuid      : %s\n", uuidOfHGridStr);
+            }
+        }
     }
 }
 /*
diff --git a/libcdi/configure b/libcdi/configure
index ecd6378..b7b8067 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.5.9.
+# Generated by GNU Autoconf 2.68 for cdi 1.6.0.
 #
 # Report bugs to <http://code.zmaw.de/projects/cdi>.
 #
@@ -570,8 +570,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='cdi'
 PACKAGE_TARNAME='cdi'
-PACKAGE_VERSION='1.5.9'
-PACKAGE_STRING='cdi 1.5.9'
+PACKAGE_VERSION='1.6.0'
+PACKAGE_STRING='cdi 1.6.0'
 PACKAGE_BUGREPORT='http://code.zmaw.de/projects/cdi'
 PACKAGE_URL=''
 
@@ -1403,7 +1403,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.5.9 to adapt to many kinds of systems.
+\`configure' configures cdi 1.6.0 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1473,7 +1473,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of cdi 1.5.9:";;
+     short | recursive ) echo "Configuration of cdi 1.6.0:";;
    esac
   cat <<\_ACEOF
 
@@ -1630,7 +1630,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-cdi configure 1.5.9
+cdi configure 1.6.0
 generated by GNU Autoconf 2.68
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -2391,7 +2391,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.5.9, which was
+It was created by cdi $as_me 1.6.0, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
@@ -3323,7 +3323,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='cdi'
- VERSION='1.5.9'
+ VERSION='1.6.0'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -18909,98 +18909,6 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
-if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
-set dummy ${ac_tool_prefix}ranlib; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_RANLIB+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$RANLIB"; then
-  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-RANLIB=$ac_cv_prog_RANLIB
-if test -n "$RANLIB"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
-$as_echo "$RANLIB" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_prog_RANLIB"; then
-  ac_ct_RANLIB=$RANLIB
-  # Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$ac_ct_RANLIB"; then
-  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_ac_ct_RANLIB="ranlib"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
-if test -n "$ac_ct_RANLIB"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
-$as_echo "$ac_ct_RANLIB" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-  if test "x$ac_ct_RANLIB" = x; then
-    RANLIB=":"
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    RANLIB=$ac_ct_RANLIB
-  fi
-else
-  RANLIB="$ac_cv_prog_RANLIB"
-fi
-
 ac_ext=cpp
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -23953,6 +23861,17 @@ _ACEOF
 fi
 done
 
+for ac_func in getline
+do :
+  ac_fn_c_check_func "$LINENO" "getline" "ac_cv_func_getline"
+if test "x$ac_cv_func_getline" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_GETLINE 1
+_ACEOF
+
+fi
+done
+
 #  ----------------------------------------------------------------------
 # Checks for the availability of ANSI-C99 functions
 ac_fn_c_check_decl "$LINENO" "isnan" "ac_cv_have_decl_isnan" "$ac_includes_default
@@ -27505,7 +27424,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.5.9, which was
+This file was extended by cdi $as_me 1.6.0, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -27571,7 +27490,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.5.9
+cdi config.status 1.6.0
 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 3ce158d..59a6a02 100644
--- a/libcdi/configure.ac
+++ b/libcdi/configure.ac
@@ -1,6 +1,6 @@
 #  Process this file with autoconf to produce a configure script.
 
-AC_INIT([cdi], [1.5.9], [http://code.zmaw.de/projects/cdi])
+AC_INIT([cdi], [1.6.0], [http://code.zmaw.de/projects/cdi])
 
 echo "configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}"
 
@@ -27,7 +27,7 @@ AC_DEFINE_UNQUOTED([SYSTEM_TYPE],["$ac_cv_build"], [System type])
 AC_SUBST([SYSTEM_TYPE],["$ac_cv_build"])
 
 AM_INIT_AUTOMAKE
-AM_CONFIG_HEADER([src/config.h])
+AC_CONFIG_HEADERS([src/config.h])
 AM_MAINTAINER_MODE([disable])
 
 # Set up libtool.
@@ -44,7 +44,6 @@ AS_IF([test -n "$FC" && test "X$FC" != "Xno"],
    AC_PROG_FPP
    AC_LANG_POP([Fortran])])
 AC_PROG_F77
-AC_PROG_RANLIB
 AC_PROG_CXX
 AC_CHECK_PROG(SED,sed,sed,false)
 AC_CHECK_PROG(GREP,grep,grep,false)
@@ -75,7 +74,8 @@ AC_CHECK_MEMBERS([struct stat.st_blksize])
 AC_CHECK_HEADERS(malloc.h)
 #  ----------------------------------------------------------------------
 # Checks for the availability of functions
-AC_CHECK_FUNCS(mallinfo)
+AC_CHECK_FUNCS([mallinfo])
+AC_CHECK_FUNCS([getline])
 #  ----------------------------------------------------------------------
 # Checks for the availability of ANSI-C99 functions
 AC_CHECK_DECLS([isnan],,,[AC_INCLUDES_DEFAULT
diff --git a/libcdi/doc/cdi_cman.pdf b/libcdi/doc/cdi_cman.pdf
index 7cca936..5a0b50c 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 35ba4e6..922bc90 100644
Binary files a/libcdi/doc/cdi_fman.pdf and b/libcdi/doc/cdi_fman.pdf differ
diff --git a/libcdi/src/Makefile.am b/libcdi/src/Makefile.am
index b2cc5ff..e11dea4 100644
--- a/libcdi/src/Makefile.am
+++ b/libcdi/src/Makefile.am
@@ -117,6 +117,7 @@ libcdi_la_SOURCES = 	 \
 	vlist_var.c 	 \
 	vlist_var.h	 \
 	zaxis.c		 \
+	zaxis.h		 \
         stream.c         \
         swap.c
 
diff --git a/libcdi/src/Makefile.in b/libcdi/src/Makefile.in
index 600f4c1..a230c5a 100644
--- a/libcdi/src/Makefile.in
+++ b/libcdi/src/Makefile.in
@@ -438,6 +438,7 @@ libcdi_la_SOURCES = \
 	vlist_var.c 	 \
 	vlist_var.h	 \
 	zaxis.c		 \
+	zaxis.h		 \
         stream.c         \
         swap.c
 
diff --git a/libcdi/src/cdf_int.c b/libcdi/src/cdf_int.c
index e6693b2..4a67fae 100644
--- a/libcdi/src/cdf_int.c
+++ b/libcdi/src/cdf_int.c
@@ -122,8 +122,7 @@ void cdf_close(int ncid)
 
   status = nc_close(ncid);
 
-  if ( status != NC_NOERR )
-    Error("%s", nc_strerror(status));
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
 
 
@@ -432,6 +431,13 @@ void cdf_put_vara_double(int ncid, int varid, const size_t start[],
   if ( CDF_Debug || status != NC_NOERR )
     Message("ncid = %d varid = %d val0 = %f", ncid, varid, *dp);
 
+  if ( status != NC_NOERR )
+    {
+      char name[256];
+      nc_inq_varname(ncid, varid, name);
+      Message("varname = %s", name);
+    }
+
   if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
 
@@ -506,7 +512,7 @@ void  cdf_get_vara_text(int ncid, int varid, const size_t start[],
 }
 
 
-void cdf_put_var_double (int ncid, int varid, const double *dp)
+void cdf_put_var_double(int ncid, int varid, const double *dp)
 {
   int status;
 
diff --git a/libcdi/src/cdi.h b/libcdi/src/cdi.h
index 5441048..0342077 100644
--- a/libcdi/src/cdi.h
+++ b/libcdi/src/cdi.h
@@ -155,7 +155,10 @@ extern "C" {
 #define  ZAXIS_TOA               13  /* Norminal top of atmosphere              */
 #define  ZAXIS_SEA_BOTTOM        14  /* Sea bottom                              */
 #define  ZAXIS_ATMOSPHERE        15  /* Entire atmosphere                       */
-#define  ZAXIS_REFERENCE         16  /* zaxis reference number                  */
+#define  ZAXIS_CLOUD_BASE        16  /* Cloud base level                        */
+#define  ZAXIS_CLOUD_TOP         17  /* Level of cloud tops                     */
+#define  ZAXIS_ISOTHERM_ZERO     18  /* Level of 0o C isotherm                  */
+#define  ZAXIS_REFERENCE         19  /* zaxis reference number                  */
 
 /* TIME types */
 
@@ -525,6 +528,29 @@ int     vlistMergedLevel(int vlistID, int varID, int levelID);
 void    vlistDefVarEnsemble(int vlistID, int varID, int ensID, int ensCount, int forecast_type);
 int     vlistInqVarEnsemble(int vlistID, int varID, int *ensID, int *ensCount, int *forecast_type);
 
+/* ---------------------------------- */
+/* Local change: 2013-01-28, FP (DWD) */
+/* ---------------------------------- */
+
+/* vlistDefVarIntKey: Set an arbitrary keyword/integer value pair for GRIB API */
+void    vlistDefVarIntKey(int vlistID, int varID, const char *name, int value);
+/* vlistDefVarDblKey: Set an arbitrary keyword/double value pair for GRIB API */
+void    vlistDefVarDblKey(int vlistID, int varID, const char *name, double value);
+
+  /* ---------------------------------- */
+  /* Local change: 2013-02-18, FP (DWD) */
+  /* ---------------------------------- */
+
+/* vlistInqVarRawBegin: Open GRIB record to retrieve raw meta-data in subsequent calls */
+void    vlistInqVarRawBegin(int streamID, int varID);
+/* vlistInqVarDblKey: raw access to GRIB meta-data */
+double  vlistInqVarDblKey(int streamID, const char* name);
+/* vlistInqVarIntKey: raw access to GRIB meta-data */
+int     vlistInqVarIntKey(int streamID, const char* name);
+/* vlistInqVarRawEnd: Free previously opened GRIB record */
+void    vlistInqVarRawEnd(int streamID);
+
+
 /* VLIST attributes */
 
 /*      vlistInqNatts: Get number of variable attributes assigned to this variable */
@@ -562,7 +588,6 @@ void    gridDefMask(int gridID, const int *mask_vec);
 int     gridInqMask(int gridID, int *mask_vec);
 
 void    gridPrint(int gridID, int opt);
-int     gridSize(void);
 
 /*      gridCreate: Create a horizontal Grid */
 int     gridCreate(int gridtype, int size);
@@ -761,7 +786,6 @@ int     zaxisDuplicate(int zaxisID);
 void    zaxisResize(int zaxisID, int size);
 
 void    zaxisPrint(int zaxisID);
-int     zaxisSize(void);
 
 /*      zaxisDefLevels: Define the levels of a Z-axis */
 void    zaxisDefLevels(int zaxisID, const double *levels_vec);
diff --git a/libcdi/src/cdi.inc b/libcdi/src/cdi.inc
index 5c4a024..a6bd108 100644
--- a/libcdi/src/cdi.inc
+++ b/libcdi/src/cdi.inc
@@ -1,10 +1,10 @@
 ! This file was automatically generated, don't edit!
 !
-! Fortran interface for CDI library version 1.5.9
+! Fortran interface for CDI library version 1.6.0
 !
 ! Author:
 ! -------
-! Uwe Schulzweida, MPI-MET, Hamburg,   December 2012
+! Uwe Schulzweida, MPI-MET, Hamburg,   March 2013
 !
 
       INTEGER    CDI_MAX_NAME          
@@ -260,8 +260,14 @@
       PARAMETER (ZAXIS_SEA_BOTTOM       = 14)
       INTEGER    ZAXIS_ATMOSPHERE      
       PARAMETER (ZAXIS_ATMOSPHERE       = 15)
+      INTEGER    ZAXIS_CLOUD_BASE      
+      PARAMETER (ZAXIS_CLOUD_BASE       = 16)
+      INTEGER    ZAXIS_CLOUD_TOP       
+      PARAMETER (ZAXIS_CLOUD_TOP        = 17)
+      INTEGER    ZAXIS_ISOTHERM_ZERO   
+      PARAMETER (ZAXIS_ISOTHERM_ZERO    = 18)
       INTEGER    ZAXIS_REFERENCE       
-      PARAMETER (ZAXIS_REFERENCE        = 16)
+      PARAMETER (ZAXIS_REFERENCE        = 19)
 !
 !  TIME types
 !
@@ -455,6 +461,12 @@
 !                                     INTEGER         pdis)
       EXTERNAL        cdiEncodeParam
 
+!
+!  date format:  YYYYMMDD
+!
+!
+!  time format:    hhmmss
+!
 !                     cdiDecodeDate
 !                                    (INTEGER         date,
 !                                     INTEGER         year,
@@ -1172,6 +1184,47 @@
       EXTERNAL        vlistInqVarEnsemble
 
 !
+!  ----------------------------------
+!
+!
+!  Local change: 2013-01-28, FP (DWD)
+!
+!
+!  ----------------------------------
+!
+!                     vlistDefVarIntKey
+!                                    (INTEGER         vlistID,
+!                                     INTEGER         varID,
+!                                     CHARACTER*(*)   name,
+!                                     INTEGER         value)
+      EXTERNAL        vlistDefVarIntKey
+
+!                     vlistDefVarDblKey
+!                                    (INTEGER         vlistID,
+!                                     INTEGER         varID,
+!                                     CHARACTER*(*)   name,
+!                                     DOUBLEPRECISION value)
+      EXTERNAL        vlistDefVarDblKey
+
+!
+!  ----------------------------------
+!
+!
+!  Local change: 2013-02-18, FP (DWD)
+!
+!
+!  ----------------------------------
+!
+!                     vlistInqVarRawBegin
+!                                    (INTEGER         streamID,
+!                                     INTEGER         varID)
+      EXTERNAL        vlistInqVarRawBegin
+
+!                     vlistInqVarRawEnd
+!                                    (INTEGER         streamID)
+      EXTERNAL        vlistInqVarRawEnd
+
+!
 !  VLIST attributes
 !
       INTEGER         vlistInqNatts
@@ -1286,9 +1339,6 @@
 !                                     INTEGER         opt)
       EXTERNAL        gridPrint
 
-      INTEGER         gridSize
-      EXTERNAL        gridSize
-
       INTEGER         gridCreate
 !                                    (INTEGER         gridtype,
 !                                     INTEGER         size)
@@ -1751,9 +1801,6 @@
 !                                    (INTEGER         zaxisID)
       EXTERNAL        zaxisPrint
 
-      INTEGER         zaxisSize
-      EXTERNAL        zaxisSize
-
 !                     zaxisDefLevels
 !                                    (INTEGER         zaxisID,
 !                                     DOUBLEPRECISION levels_vec)
diff --git a/libcdi/src/cdiFortran.c b/libcdi/src/cdiFortran.c
index b0329ce..47014c8 100644
--- a/libcdi/src/cdiFortran.c
+++ b/libcdi/src/cdiFortran.c
@@ -90,6 +90,12 @@ FCALLSCSUB2 (cdiDefGlobal, CDIDEFGLOBAL, cdidefglobal, STRING, INT)
 FCALLSCSUB3 (cdiParamToString, CDIPARAMTOSTRING, cdiparamtostring, INT, PSTRING, INT)
 FCALLSCSUB4 (cdiDecodeParam, CDIDECODEPARAM, cdidecodeparam, INT, PINT, PINT, PINT)
 FCALLSCFUN3 (INT, cdiEncodeParam, CDIENCODEPARAM, cdiencodeparam, INT, INT, INT)
+
+/*  date format:  YYYYMMDD  */
+
+
+/*  time format:    hhmmss  */
+
 FCALLSCSUB4 (cdiDecodeDate, CDIDECODEDATE, cdidecodedate, INT, PINT, PINT, PINT)
 FCALLSCFUN3 (INT, cdiEncodeDate, CDIENCODEDATE, cdiencodedate, INT, INT, INT)
 FCALLSCSUB4 (cdiDecodeTime, CDIDECODETIME, cdidecodetime, INT, PINT, PINT, PINT)
@@ -242,6 +248,28 @@ FCALLSCFUN3 (INT, vlistMergedLevel, VLISTMERGEDLEVEL, vlistmergedlevel, INT, INT
 FCALLSCSUB5 (vlistDefVarEnsemble, VLISTDEFVARENSEMBLE, vlistdefvarensemble, INT, INT, INT, INT, INT)
 FCALLSCFUN5 (INT, vlistInqVarEnsemble, VLISTINQVARENSEMBLE, vlistinqvarensemble, INT, INT, PINT, PINT, PINT)
 
+/*  ----------------------------------  */
+
+
+/*  Local change: 2013-01-28, FP (DWD)  */
+
+
+/*  ----------------------------------  */
+
+FCALLSCSUB4 (vlistDefVarIntKey, VLISTDEFVARINTKEY, vlistdefvarintkey, INT, INT, STRING, INT)
+FCALLSCSUB4 (vlistDefVarDblKey, VLISTDEFVARDBLKEY, vlistdefvardblkey, INT, INT, STRING, DOUBLE)
+
+/*  ----------------------------------  */
+
+
+/*  Local change: 2013-02-18, FP (DWD)  */
+
+
+/*  ----------------------------------  */
+
+FCALLSCSUB2 (vlistInqVarRawBegin, VLISTINQVARRAWBEGIN, vlistinqvarrawbegin, INT, INT)
+FCALLSCSUB1 (vlistInqVarRawEnd, VLISTINQVARRAWEND, vlistinqvarrawend, INT)
+
 /*  VLIST attributes  */
 
 FCALLSCFUN3 (INT, vlistInqNatts, VLISTINQNATTS, vlistinqnatts, INT, INT, PINT)
@@ -264,7 +292,6 @@ FCALLSCFUN2 (INT, gridInqMaskGME, GRIDINQMASKGME, gridinqmaskgme, INT, PINT)
 FCALLSCSUB2 (gridDefMask, GRIDDEFMASK, griddefmask, INT, PINT)
 FCALLSCFUN2 (INT, gridInqMask, GRIDINQMASK, gridinqmask, INT, PINT)
 FCALLSCSUB2 (gridPrint, GRIDPRINT, gridprint, INT, INT)
-FCALLSCFUN0 (INT, gridSize, GRIDSIZE, gridsize)
 FCALLSCFUN2 (INT, gridCreate, GRIDCREATE, gridcreate, INT, INT)
 FCALLSCSUB1 (gridDestroy, GRIDDESTROY, griddestroy, INT)
 FCALLSCFUN1 (INT, gridDuplicate, GRIDDUPLICATE, gridduplicate, INT)
@@ -372,7 +399,6 @@ FCALLSCFUN1 (INT, zaxisInqSize, ZAXISINQSIZE, zaxisinqsize, INT)
 FCALLSCFUN1 (INT, zaxisDuplicate, ZAXISDUPLICATE, zaxisduplicate, INT)
 FCALLSCSUB2 (zaxisResize, ZAXISRESIZE, zaxisresize, INT, INT)
 FCALLSCSUB1 (zaxisPrint, ZAXISPRINT, zaxisprint, INT)
-FCALLSCFUN0 (INT, zaxisSize, ZAXISSIZE, zaxissize)
 FCALLSCSUB2 (zaxisDefLevels, ZAXISDEFLEVELS, zaxisdeflevels, INT, PDOUBLE)
 FCALLSCSUB2 (zaxisInqLevels, ZAXISINQLEVELS, zaxisinqlevels, INT, PDOUBLE)
 FCALLSCSUB3 (zaxisDefLevel, ZAXISDEFLEVEL, zaxisdeflevel, INT, INT, DOUBLE)
diff --git a/libcdi/src/cdi_error.c b/libcdi/src/cdi_error.c
index e092208..0488bd4 100644
--- a/libcdi/src/cdi_error.c
+++ b/libcdi/src/cdi_error.c
@@ -2,6 +2,7 @@
 #  include "config.h"
 #endif
 
+#include <stdio.h>
 #include <string.h>
 #include <errno.h>
 #include "cdi.h"
diff --git a/libcdi/src/cdilib.c b/libcdi/src/cdilib.c
index b3a43f3..ba98417 100644
--- a/libcdi/src/cdilib.c
+++ b/libcdi/src/cdilib.c
@@ -1,12 +1,16 @@
 
-/* Automatically generated by m214003 at 2012-12-17, do not edit */
+/* Automatically generated by m214003 at 2013-03-14, do not edit */
 
-/* CDILIB_VERSION="1.5.9" */
+/* CDILIB_VERSION="1.6.0" */
 
 #if  defined  (HAVE_CONFIG_H)
 #  include "config.h"
 #endif
 
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 600
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
@@ -33,7 +37,7 @@
 #  include <grib_api.h>
 #endif
 
-#if defined (HAVE_MMAP)
+#if  defined  (HAVE_MMAP)
 #  include <sys/mman.h> /* mmap() is defined in this header */
 #endif
 
@@ -231,309 +235,6 @@ size_t fileWrite(int fileID, const void *restrict ptr, size_t size);
  * require-trailing-newline: t
  * End:
  */
-#ifndef _CGRIBEX_H
-#define _CGRIBEX_H
-
-#include <stdio.h>
-#include <sys/types.h>
-
-#define  GRIB_MISSVAL  -9.E33
-
-/* GRIB1 Level Types */
-#define  GRIB1_LTYPE_SURFACE               1
-#define  GRIB1_LTYPE_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
-#define  GRIB1_LTYPE_99_MARGIN          1000
-
-/* GRIB1 Data representation type (Grid Type) [Table 6] */
-#define  GRIB1_GTYPE_LATLON                0  /*  latitude/longitude                       */
-#define  GRIB1_GTYPE_LATLON_ROT           10  /*  rotated latitude/longitude               */
-#define  GRIB1_GTYPE_LATLON_STR           20  /*  stretched latitude/longitude             */
-#define  GRIB1_GTYPE_LATLON_ROTSTR        30  /*  rotated and stretched latitude/longitude */
-#define  GRIB1_GTYPE_GAUSSIAN              4  /*  gaussian grid                            */
-#define  GRIB1_GTYPE_GAUSSIAN_ROT         14  /*  rotated gaussian grid                    */
-#define  GRIB1_GTYPE_GAUSSIAN_STR         24  /*  stretched gaussian grid                  */
-#define  GRIB1_GTYPE_GAUSSIAN_ROTSTR      34  /*  rotated and stretched gaussian grid      */
-#define  GRIB1_GTYPE_LCC                   3  /*  Lambert conformal                        */
-#define  GRIB1_GTYPE_SPECTRAL             50  /*  spherical harmonics                      */
-#define  GRIB1_GTYPE_GME                 192  /*  hexagonal GME grid                       */
-
-/*
- *  Macros for the indicator section ( Section 0 )
- */
-#define  ISEC0_GRIB_Len             (isec0[ 0])  /*  Number of octets in the GRIB message         */
-#define  ISEC0_GRIB_Version         (isec0[ 1])  /*  GRIB edition number                          */
-
-
-/*
- *  Macros for the product definition section ( Section 1 )
- */
-#define  ISEC1_TABLE4_MINUTE    0
-#define  ISEC1_TABLE4_HOUR      1
-#define  ISEC1_TABLE4_DAY       2
-#define  ISEC1_TABLE4_3HOURS   10
-#define  ISEC1_TABLE4_6HOURS   11
-#define  ISEC1_TABLE4_12HOURS  12
-#define  ISEC1_TABLE4_QUARTER  13
-
-
-#define  ISEC1_CodeTable            (isec1[ 0])  /*  Version number of code table                 */
-#define  ISEC1_CenterID             (isec1[ 1])  /*  Identification of centre                     */
-#define  ISEC1_ModelID              (isec1[ 2])  /*  Identification of model                      */
-#define  ISEC1_GridDefinition       (isec1[ 3])  /*  Grid definition                              */
-#define  ISEC1_Sec2Or3Flag          (isec1[ 4])  /*  Section 2 or 3 included                      */
-#define  ISEC1_Parameter            (isec1[ 5])  /*  Parameter indicator                          */
-#define  ISEC1_LevelType            (isec1[ 6])  /*  Type of level indicator                      */
-#define  ISEC1_Level1               (isec1[ 7])  /*  Level 1                                      */
-#define  ISEC1_Level2               (isec1[ 8])  /*  Level 2                                      */
-#define  ISEC1_Year                 (isec1[ 9])  /*  Year of century (YY)                         */
-#define  ISEC1_Month                (isec1[10])  /*  Month (MM)                                   */
-#define  ISEC1_Day                  (isec1[11])  /*  Day (DD)                                     */
-#define  ISEC1_Hour                 (isec1[12])  /*  Hour (HH)                                    */
-#define  ISEC1_Minute               (isec1[13])  /*  Minute (MM)                                  */
-#define  ISEC1_TimeUnit             (isec1[14])  /*  Time unit indicator                          */
-#define  ISEC1_TimePeriod1          (isec1[15])  /*  P1 Time period                               */
-#define  ISEC1_TimePeriod2          (isec1[16])  /*  P2 Time period                               */
-#define  ISEC1_TimeRange            (isec1[17])  /*  Time range indicator                         */
-#define  ISEC1_AvgNum               (isec1[18])  /*  Number of products included in an average    */
-#define  ISEC1_AvgMiss              (isec1[19])  /*  Number of products missing from an average   */
-#define  ISEC1_Century              (isec1[20])  /*  Century                                      */
-#define  ISEC1_SubCenterID          (isec1[21])  /*  Subcenter identifier                         */
-#define  ISEC1_DecScaleFactor       (isec1[22])  /*  Decimal scale factor                         */
-#define  ISEC1_LocalFLag            (isec1[23])  /*  Flag field to indicate local use in isec1    */
-
-#define  ISEC1_ECMWF_LocalExtension (isec1[36])
-#define  ISEC1_ECMWF_Class          (isec1[37])
-
-
-/*
- *  Macros for the grid definition section ( Section 2 )
- */
-#define  ISEC2_GridType             (isec2[ 0])  /* Data representation type */
-
-/* Triangular grids */
-
-#define  ISEC2_GME_NI2              (isec2[ 1])  /*  Number of factor 2 in factorisation of Ni    */
-#define  ISEC2_GME_NI3              (isec2[ 2])  /*  Number of factor 3 in factorisation of Ni    */
-#define  ISEC2_GME_ND               (isec2[ 3])  /*  Nubmer of diamonds                           */
-#define  ISEC2_GME_NI               (isec2[ 4])  /*  Number of tri. subdiv. of the icosahedron    */
-#define  ISEC2_GME_AFlag            (isec2[ 5])  /*  Flag for orientation of diamonds (Table A)   */
-#define  ISEC2_GME_LatPP            (isec2[ 6])  /*  Latitude of pole point                       */
-#define  ISEC2_GME_LonPP            (isec2[ 7])  /*  Longitude of pole point                      */
-#define  ISEC2_GME_LonMPL           (isec2[ 8])  /*  Longitude of the first diamond               */
-#define  ISEC2_GME_BFlag            (isec2[ 9])  /*  Flag for storage sequence (Table B)          */
-
-/* Spherical harmonic coeficients */
-
-#define  ISEC2_PentaJ               (isec2[ 1])  /*  J pentagonal resolution parameter            */
-#define  ISEC2_PentaK               (isec2[ 2])  /*  K pentagonal resolution parameter            */
-#define  ISEC2_PentaM               (isec2[ 3])  /*  M pentagonal resolution parameter            */
-#define  ISEC2_RepType              (isec2[ 4])  /*  Representation type                          */
-#define  ISEC2_RepMode              (isec2[ 5])  /*  Representation mode                          */
-
-/* Gaussian grids */
-
-#define  ISEC2_NumLon               (isec2[ 1])  /*  Number of points along a parallel (Ni)       */
-#define  ISEC2_NumLat               (isec2[ 2])  /*  Number of points along a meridian (Nj)       */
-#define  ISEC2_FirstLat             (isec2[ 3])  /*  Latitude of the first grid point             */
-#define  ISEC2_FirstLon             (isec2[ 4])  /*  Longitude of the first grid point            */
-#define  ISEC2_ResFlag              (isec2[ 5])  /*  Resolution flag: 128 regular grid            */
-#define  ISEC2_LastLat              (isec2[ 6])  /*  Latitude of the last grid point              */
-#define  ISEC2_LastLon              (isec2[ 7])  /*  Longitude of the last grid point             */
-#define  ISEC2_LonIncr              (isec2[ 8])  /*  i direction increment                        */
-#define  ISEC2_LatIncr              (isec2[ 9])  /*  j direction increment                        */
-#define  ISEC2_NumPar               (isec2[ 9])  /*  Number of parallels between a pole and the E.*/
-#define  ISEC2_ScanFlag             (isec2[10])  /*  Scanning mode flags                          */
-#define  ISEC2_NumVCP               (isec2[11])  /*  Number of vertical coordinate parameters     */
-
-/* Lambert */
-#define  ISEC2_Lambert_Lov          (isec2[ 6])  /*  Orientation of the grid                      */
-#define  ISEC2_Lambert_dx           (isec2[ 8])  /*  X-direction grid length                      */
-#define  ISEC2_Lambert_dy           (isec2[ 9])  /*  Y-direction grid length                      */
-#define  ISEC2_Lambert_ProjFlag     (isec2[12])  /*  Projection centre flag                       */
-#define  ISEC2_Lambert_LatS1        (isec2[13])  /*  First lat at which the secant cone cuts the sphere */
-#define  ISEC2_Lambert_LatS2        (isec2[14])  /*  Second lat at which the secant cone cuts the sphere */
-#define  ISEC2_Lambert_LatSP        (isec2[19])  /*  Latitude of the southern pole                */
-#define  ISEC2_Lambert_LonSP        (isec2[20])  /*  Longitude of the southern pole               */
-
-
-#define  ISEC2_Reduced              (isec2[16])  /* 0: regular, 1: reduced grid                   */
-
-#define  ISEC2_RowLonPtr            (&isec2[22])
-#define  ISEC2_RowLon(i)            (isec2[22+i]) /* Number of points along each parallel         */
-
-/* */
-
-#define  ISEC2_LatSP                (isec2[12])  /* Latitude of the southern pole of rotation     */
-#define  ISEC2_LonSP                (isec2[13])  /* Longitude of the southern pole of rotation    */
-
-#define  FSEC2_RotAngle             (fsec2[ 0])  /* Angle of rotation                             */
-#define  FSEC2_StrFact              (fsec2[ 1])  /* Stretching factor                             */
-
-/*
- *  Macros for the bit map section ( Section 3 )
- */
-#define  ISEC3_PredefBitmap         (isec3[ 0])  /* Predefined bitmap                             */
-#define  ISEC3_MissVal              (isec3[ 1])  /* Missing data value for integers               */
-#define  FSEC3_MissVal              (fsec3[ 1])  /* Missing data value for floats                 */
-
-/*
- *  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  gribFixZSE(int flag);     /* 1: Fix ZeroShiftError of simple packed spherical harmonics */
-void  gribSetConst(int flag);   /* 1: Don't pack constant fields on regular grids */
-void  gribSetDebug(int debug);  /* 1: Debugging */
-void  gribSetRound(int round);
-void  gribSetRefDP(double refval);
-void  gribSetRefSP(float  refval);
-void  gribSetValueCheck(int vcheck);
-
-
-void  gribExSP(int *isec0, int *isec1, int *isec2, float *fsec2, int *isec3,
-               float *fsec3, int *isec4, float *fsec4, int klenp, int *kgrib,
-               int kleng, int *kword, char *hoper, int *kret);
-
-void  gribExDP(int *isec0, int *isec1, int *isec2, double *fsec2, int *isec3,
-               double *fsec3, int *isec4, double *fsec4, int klenp, int *kgrib,
-               int kleng, int *kword, char *hoper, int *kret);
-
-
-const char *cgribexLibraryVersion(void);
-
-void  gribDebug(int debug);
-void  gribSetCalendar(int calendar);
-
-void  gribDateTime(int *isec1, int *date, int *time);
-int   gribRefDate(int *isec1);
-int   gribRefTime(int *isec1);
-int   gribTimeIsFC(int *isec1);
-
-void  gribPrintSec0(int *isec0);
-void  gribPrintSec1(int *isec0, int *isec1);
-void  gribPrintSec2DP(int *isec0, int *isec2, double *fsec2);
-void  gribPrintSec2SP(int *isec0, int *isec2, float  *fsec2);
-void  gribPrintSec3DP(int *isec0, int *isec3, double *fsec3);
-void  gribPrintSec3SP(int *isec0, int *isec3, float  *fsec3);
-void  gribPrintSec4DP(int *isec0, int *isec4, double *fsec4);
-void  gribPrintSec4SP(int *isec0, int *isec4, float  *fsec4);
-void  gribPrintSec4Wave(int *isec4);
-
-void  gribPrintALL(int nrec, long offset, long recpos, long recsize, unsigned char *gribbuffer);
-void  gribPrintPDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
-void  gribPrintGDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
-void  gribPrintBMS(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
-void  gribPrintBDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
-void  gribCheck1(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
-void  gribRepair1(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
-
-int grib1Sections(unsigned char *gribbuffer, long recsize, unsigned char **pdsp,
-		  unsigned char **gdsp, unsigned char **bmsp, unsigned char **bdsp);
-int grib2Sections(unsigned char *gribbuffer, long recsize, unsigned char **idsp,
-		  unsigned char **lusp, unsigned char **gdsp, unsigned char **pdsp,
-		  unsigned char **drsp, unsigned char **bmsp, unsigned char **bdsp);
-
-int   gribGetZip(long recsize, unsigned char *gribbuffer, long *urecsize);
-
-int   gribBzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize);
-int   gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize);
-int   gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize);
-
-int   gribOpen(const char *filename, const char *mode);
-void  gribClose(int fileID);
-
-int   gribRead(int fileID, unsigned char *buffer, size_t *buffersize);
-int   gribWrite(int fileID, unsigned char *buffer, size_t buffersize);
-off_t gribGetPos(int fileID);
-int   gribGetSize(int fileID);
-int   gribCheckSeek(int fileID, long *offset, int *version);
-int   gribFileSeek(int fileID, long *offset);
-int   gribReadSize(int fileID);
-int   gribVersion(unsigned char *buffer, size_t buffersize);
-
-int   gribGinfo(long recpos, long recsize, unsigned char *gribbuffer, int *intnum, float *fltnum);
-
-double calculate_pfactor(const double* spectralField, long fieldTruncation, long subsetTruncation);
-
-#endif  /* _CGRIBEX_H */ 
-
-#ifndef _GRIBAPI_H
-#define _GRIBAPI_H
-
-#define  GRIBAPI_MISSVAL  -9.E33
-
-/* GRIB2 Level Types */
-#define  GRIB2_LTYPE_SURFACE               1
-#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_REFERENCE           150
-#define  GRIB2_LTYPE_SEADEPTH            160
-
-/* 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_NUMBER              101  /*  General Unstructured Grid                */
-
-const char *gribapiLibraryVersion(void);
-void gribContainersNew(int streamID);
-void gribContainersDelete(int streamID);
-void *gribHandleNew(int editionNumber);
-void gribHandleDelete(void *gh);
-
-typedef struct {
-  int 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 _SERVICE_H
 #define _SERVICE_H
 
@@ -892,7 +593,10 @@ extern "C" {
 #define  ZAXIS_TOA               13  /* Norminal top of atmosphere              */
 #define  ZAXIS_SEA_BOTTOM        14  /* Sea bottom                              */
 #define  ZAXIS_ATMOSPHERE        15  /* Entire atmosphere                       */
-#define  ZAXIS_REFERENCE         16  /* zaxis reference number                  */
+#define  ZAXIS_CLOUD_BASE        16  /* Cloud base level                        */
+#define  ZAXIS_CLOUD_TOP         17  /* Level of cloud tops                     */
+#define  ZAXIS_ISOTHERM_ZERO     18  /* Level of 0o C isotherm                  */
+#define  ZAXIS_REFERENCE         19  /* zaxis reference number                  */
 
 /* TIME types */
 
@@ -1262,6 +966,29 @@ int     vlistMergedLevel(int vlistID, int varID, int levelID);
 void    vlistDefVarEnsemble(int vlistID, int varID, int ensID, int ensCount, int forecast_type);
 int     vlistInqVarEnsemble(int vlistID, int varID, int *ensID, int *ensCount, int *forecast_type);
 
+/* ---------------------------------- */
+/* Local change: 2013-01-28, FP (DWD) */
+/* ---------------------------------- */
+
+/* vlistDefVarIntKey: Set an arbitrary keyword/integer value pair for GRIB API */
+void    vlistDefVarIntKey(int vlistID, int varID, const char *name, int value);
+/* vlistDefVarDblKey: Set an arbitrary keyword/double value pair for GRIB API */
+void    vlistDefVarDblKey(int vlistID, int varID, const char *name, double value);
+
+  /* ---------------------------------- */
+  /* Local change: 2013-02-18, FP (DWD) */
+  /* ---------------------------------- */
+
+/* vlistInqVarRawBegin: Open GRIB record to retrieve raw meta-data in subsequent calls */
+void    vlistInqVarRawBegin(int streamID, int varID);
+/* vlistInqVarDblKey: raw access to GRIB meta-data */
+double  vlistInqVarDblKey(int streamID, const char* name);
+/* vlistInqVarIntKey: raw access to GRIB meta-data */
+int     vlistInqVarIntKey(int streamID, const char* name);
+/* vlistInqVarRawEnd: Free previously opened GRIB record */
+void    vlistInqVarRawEnd(int streamID);
+
+
 /* VLIST attributes */
 
 /*      vlistInqNatts: Get number of variable attributes assigned to this variable */
@@ -1299,7 +1026,6 @@ void    gridDefMask(int gridID, const int *mask_vec);
 int     gridInqMask(int gridID, int *mask_vec);
 
 void    gridPrint(int gridID, int opt);
-int     gridSize(void);
 
 /*      gridCreate: Create a horizontal Grid */
 int     gridCreate(int gridtype, int size);
@@ -1498,7 +1224,6 @@ int     zaxisDuplicate(int zaxisID);
 void    zaxisResize(int zaxisID, int size);
 
 void    zaxisPrint(int zaxisID);
-int     zaxisSize(void);
 
 /*      zaxisDefLevels: Define the levels of a Z-axis */
 void    zaxisDefLevels(int zaxisID, const double *levels_vec);
@@ -1717,23 +1442,14 @@ int julday_to_date(int calendar, int julday);
 int time_to_sec(int time);
 int sec_to_time(int secofday);
 
-void   julday_add_seconds(int seconds, int *julday, int *secofday);
+void   julday_add_seconds(int64_t seconds, int *julday, int *secofday);
 void   julday_add(int days, int secs, int *julday, int *secofday);
 double julday_sub(int julday1, int secofday1, int julday2, int secofday2, int *days, int *secs);
 
-void encode_juldaysec(int calendar, int year, int month, int day, int hour, int minute, int *julday, int *secofday);
-void decode_juldaysec(int calendar, int julday, int secofday, int *year, int *month, int *day, int *hour, int *minute);
+void encode_juldaysec(int calendar, int year, int month, int day, int hour, int minute, int second, int *julday, int *secofday);
+void decode_juldaysec(int calendar, int julday, int secofday, int *year, int *month, int *day, int *hour, int *minute, int *second);
 
 #endif  /* _TIMEBASE_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 _CALENDAR_H
 #define _CALENDAR_H
 
@@ -1791,12 +1507,667 @@ DateTime;
  * require-trailing-newline: t
  * End:
  */
+#ifndef _STREAM_INT_H
+#define _STREAM_INT_H
+
+#if defined (HAVE_CONFIG_H)
+#  include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <sys/types.h>
+
+#ifndef strdupx
+#ifndef strdup
+char *strdup(const char *s);
+#endif
+#define strdupx  strdup
+/*
+#define strdupx(s)			          \
+({					      	  \
+   const char *__old = (s);			  \
+   size_t __len = strlen(__old) + 1;		  \
+   char *__new = (char *) malloc(__len);	  \
+   (char *) memcpy(__new, __old, __len);	  \
+})
+*/
+#endif
+
+#ifndef  M_PI
+#define  M_PI        3.14159265358979323846  /* pi */
+#endif
+
+
+#ifndef  _ERROR_H
+#  include "error.h"
+#endif
+#ifndef _BASETIME_H
+#  include "basetime.h"
+#endif
+#ifndef _TIMEBASE_H
+#  include "timebase.h"
+#endif
+#ifndef  _TAXIS_H
+#  include "taxis.h"
+#endif
+#ifndef  _CDI_LIMITS_H
+#  include "cdi_limits.h"
+#endif
+#ifndef  _SERVICE_H
+#  include "service.h"
+#endif
+#ifndef  _EXTRA_H
+#  include "extra.h"
+#endif
+#ifndef  _IEG_H
+#  include "ieg.h"
+#endif
+
+
+#define check_parg(arg)  if ( arg == 0 ) Warning("Argument '" #arg "' not allocated!")
+
+#if defined (__xlC__) /* performance problems on IBM */
+#ifndef DBL_IS_NAN
+#  define DBL_IS_NAN(x)     ((x) != (x))
+#endif
+#else
+#ifndef DBL_IS_NAN
+#if  defined  (HAVE_DECL_ISNAN)
+#  define DBL_IS_NAN(x)     (isnan(x))
+#elif  defined  (FP_NAN)
+#  define DBL_IS_NAN(x)     (fpclassify(x) == FP_NAN)
+#else
+#  define DBL_IS_NAN(x)     ((x) != (x))
+#endif
+#endif
+#endif
+
+#ifndef DBL_IS_EQUAL
+/*#define DBL_IS_EQUAL(x,y) (!(x < y || y < x)) */
+#  define DBL_IS_EQUAL(x,y) (DBL_IS_NAN(x)||DBL_IS_NAN(y)?(DBL_IS_NAN(x)&&DBL_IS_NAN(y)?1:0):!(x < y || y < x))
+#endif
+
+#ifndef IS_EQUAL
+#  define IS_NOT_EQUAL(x,y) (x < y || y < x)
+#  define IS_EQUAL(x,y)     (!IS_NOT_EQUAL(x,y))
+#endif
+
+
+#ifndef INT
+#  define  INT(x)  ((int)(x))
+#endif
+
+#ifndef NINT
+#  define  NINT(x)  ((x) < 0 ? (int)((x)-.5) : (int)((x)+.5))
+#endif
+
+#define  FALSE  0
+#define  TRUE   1
+
+#define  TYPE_REC  0
+#define  TYPE_VAR  1
+
+#define  MEMTYPE_DOUBLE  1
+#define  MEMTYPE_FLOAT   2
+
+typedef struct
+{
+  void     *buffer;
+  size_t    buffersize;
+  off_t     position;
+  int       recsize;
+  int       size;
+  int       dataread;
+  int       param;
+  int       level;
+  int       date;
+  int       time;
+  int       gridID;
+  int       zaxisID;
+  int       used;
+  int       nrec;
+  int       varID;
+  int       levelID;
+  int       recid;
+  int       prec;
+  int       sec0[2];
+  int       sec1[1024];
+  int       sec2[4096];
+  int       sec3[2];
+  int       sec4[512];
+#if  defined  (HAVE_LIBSERVICE)
+  srvrec_t   *srvp;
+#endif
+#if  defined  (HAVE_LIBEXTRA)
+  extrec_t   *extp;
+#endif
+#if  defined  (HAVE_LIBIEG)
+  iegrec_t   *iegp;
+#endif
+}
+Record;
+
+
+typedef struct
+{
+  off_t     position;
+  size_t    size;
+  int       zip;
+  int       param;
+  int       ilevel;
+  int       ilevel2;
+  int       ltype;
+  short     used;
+  short     varID;
+  short     levelID;
+  char      varname[32]; /* needed for grib decoding with GRIB_API */
+}
+record_t;
+
+
+typedef struct {
+  record_t *records;
+  int       recordSize;  /* number of allocated records           */
+  int      *recIDs;      /* IDs of non constant records           */
+  int       nrecs;       /* number of used records                */
+                         /* tsID=0 nallrecs                       */
+                         /* tsID>0 number of non constant records */
+  int       nallrecs;    /* number of all records                 */
+  int       curRecID;    /* current record ID                     */
+  long      next;
+  off_t     position;    /* timestep file position                */
+  taxis_t   taxis;
+}
+tsteps_t;
+
+
+typedef struct {
+  int       ncvarid;
+  int       nlevs;
+  int      *level;       /* record IDs */
+  int      *lindex;      /* level index */
+  int       defmiss;     /* TRUE if missval is defined in file */
+
+  int       isUsed;
+  int       gridID;
+  int       zaxisID;
+  int       tsteptype;   /* TSTEP_* */
+}
+svarinfo_t;
+
+
+typedef struct {
+  int       ilev;
+  int       mlev;
+  int       ilevID;
+  int       mlevID;
+}
+VCT;
+
+
+typedef struct {
+  int         self;
+  int         accesstype;   /* TYPE_REC or TYPE_VAR */
+  int         accessmode;
+  int         filetype;
+  int         byteorder;
+  int         fileID;
+  int         dimgroupID;
+  int         filemode;
+  off_t       numvals;
+  char       *filename;
+  Record     *record;
+  int        nrecs;        /* number of records                  */
+  int         nvars;        /* number of variables                */
+  int         varlocked;    /* variables locked                   */
+  svarinfo_t *vars;
+  int         varsAllocated;
+  int         varinit;
+  int         curTsID;      /* current timestep ID */
+  int         rtsteps;      /* number of tsteps accessed       */
+  long        ntsteps;      /* number of tsteps : only set if all records accessed */
+  int         numTimestep;  /* number of tsteps : only set if all records accessed */
+  tsteps_t   *tsteps;
+  int         tstepsTableSize;
+  int         tstepsNextID;
+  BaseTime    basetime;
+  int         ncmode;
+  int         vlistID;
+  int         xdimID[MAX_GRIDS_PS];
+  int         ydimID[MAX_GRIDS_PS];
+  int         zaxisID[MAX_ZAXES_PS];
+  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
+  int         curfile;
+  int         nfiles;
+  char      **fnames;
+#if defined (GRIBCONTAINER2D)
+  void      **gribContainers;
+#else
+  void       *gribContainers;
+#endif
+  int         vlistIDorig;
+
+  /* ---------------------------------- */
+  /* Local change: 2013-02-18, FP (DWD) */
+  /* ---------------------------------- */
+
+  void *gh; // grib handle
+}
+stream_t;
+
+
+extern int CDI_Debug;      /* If set to 1, debuggig (default 0)            */
+extern double cdiDefaultMissval;
+extern int cdiDefaultInstID;
+extern int cdiDefaultModelID;
+extern int cdiDefaultTableID;
+extern int cdiDefaultLeveltype;
+extern int cdiNcMissingValue;
+extern int cdiNcChunksizehint;
+extern int cdiChunkType;
+extern int cdiSplitLtype105;
+
+extern char *cdiPartabPath;
+extern int   cdiPartabIntern;
+
+stream_t *stream_to_pointer(int idx);
+stream_t *stream_new_entry(void);
+void stream_delete_entry(stream_t *streamptr);
+void stream_check_ptr(const char *caller, stream_t *streamptr);
+
+int     streamInqFileID(int streamID);
+
+int     zaxisInqLevelID(int zaxisID, double level);
+char   *gridNamePtr(int gridtype);
+char   *zaxisNamePtr(int leveltype);
+
+void    streamCheckID(const char *caller, int streamID);
+
+void    streamDefineTaxis(int streamID);
+
+int     streamsNewEntry(int filetype);
+void    streamsInitEntry(int streamID);
+int     stream_new_var(stream_t *streamptr, int gridID, int zaxisID);
+
+int     tstepsNewEntry(stream_t *streamptr);
+
+char   *strfiletype(int filetype);
+
+void    cdi_generate_vars(stream_t *streamptr);
+
+void    vlist_check_contents(int vlistID);
+
+void    cdi_create_records(stream_t *streamptr, int tsID);
+
+int     recordNewEntry(stream_t *streamptr, int tsID);
+
+void    cdiCreateTimesteps(stream_t *streamptr);
+
+void    recordInitEntry(record_t *record);
+
+void    cdiCheckZaxis(int zaxisID);
+
+void    cdiPrintDatatypes(void);
+
+void    cdiDefAccesstype(int streamID, int type);
+int     cdiInqAccesstype(int streamID);
+
+void    streamDefDimgroupID(int streamID, int dimgroupID);
+int     streamInqDimgroupID(int streamID);
+
+int     getByteswap(int byteorder);
+
+int     streamSize ();
+void    streamGetIndexList ( int, int * );
+
+
+void  cdiInitialize(void);
+
+void stream_write_record(int streamID, int memtype, const void *data, int nmiss);
+
+void uuid2str(const char *uuid, char *uuidstr);
+void str2uuid(const char *uuidstr, char *uuid);
+
+
+#endif  /* _STREAM_INT_H */
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef _CGRIBEX_H
+#define _CGRIBEX_H
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#define  GRIB_MISSVAL  -9.E33
+
+/* GRIB1 Level Types */
+#define  GRIB1_LTYPE_SURFACE               1
+#define  GRIB1_LTYPE_CLOUDBASE             2
+#define  GRIB1_LTYPE_CLOUDTOP              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
+#define  GRIB1_LTYPE_99_MARGIN          1000
+
+/* GRIB1 Data representation type (Grid Type) [Table 6] */
+#define  GRIB1_GTYPE_LATLON                0  /*  latitude/longitude                       */
+#define  GRIB1_GTYPE_LATLON_ROT           10  /*  rotated latitude/longitude               */
+#define  GRIB1_GTYPE_LATLON_STR           20  /*  stretched latitude/longitude             */
+#define  GRIB1_GTYPE_LATLON_ROTSTR        30  /*  rotated and stretched latitude/longitude */
+#define  GRIB1_GTYPE_GAUSSIAN              4  /*  gaussian grid                            */
+#define  GRIB1_GTYPE_GAUSSIAN_ROT         14  /*  rotated gaussian grid                    */
+#define  GRIB1_GTYPE_GAUSSIAN_STR         24  /*  stretched gaussian grid                  */
+#define  GRIB1_GTYPE_GAUSSIAN_ROTSTR      34  /*  rotated and stretched gaussian grid      */
+#define  GRIB1_GTYPE_LCC                   3  /*  Lambert conformal                        */
+#define  GRIB1_GTYPE_SPECTRAL             50  /*  spherical harmonics                      */
+#define  GRIB1_GTYPE_GME                 192  /*  hexagonal GME grid                       */
+
+/*
+ *  Macros for the indicator section ( Section 0 )
+ */
+#define  ISEC0_GRIB_Len             (isec0[ 0])  /*  Number of octets in the GRIB message         */
+#define  ISEC0_GRIB_Version         (isec0[ 1])  /*  GRIB edition number                          */
+
+
+/*
+ *  Macros for the product definition section ( Section 1 )
+ */
+#define  ISEC1_TABLE4_MINUTE    0
+#define  ISEC1_TABLE4_HOUR      1
+#define  ISEC1_TABLE4_DAY       2
+#define  ISEC1_TABLE4_3HOURS   10
+#define  ISEC1_TABLE4_6HOURS   11
+#define  ISEC1_TABLE4_12HOURS  12
+#define  ISEC1_TABLE4_QUARTER  13
+
+
+#define  ISEC1_CodeTable            (isec1[ 0])  /*  Version number of code table                 */
+#define  ISEC1_CenterID             (isec1[ 1])  /*  Identification of centre                     */
+#define  ISEC1_ModelID              (isec1[ 2])  /*  Identification of model                      */
+#define  ISEC1_GridDefinition       (isec1[ 3])  /*  Grid definition                              */
+#define  ISEC1_Sec2Or3Flag          (isec1[ 4])  /*  Section 2 or 3 included                      */
+#define  ISEC1_Parameter            (isec1[ 5])  /*  Parameter indicator                          */
+#define  ISEC1_LevelType            (isec1[ 6])  /*  Type of level indicator                      */
+#define  ISEC1_Level1               (isec1[ 7])  /*  Level 1                                      */
+#define  ISEC1_Level2               (isec1[ 8])  /*  Level 2                                      */
+#define  ISEC1_Year                 (isec1[ 9])  /*  Year of century (YY)                         */
+#define  ISEC1_Month                (isec1[10])  /*  Month (MM)                                   */
+#define  ISEC1_Day                  (isec1[11])  /*  Day (DD)                                     */
+#define  ISEC1_Hour                 (isec1[12])  /*  Hour (HH)                                    */
+#define  ISEC1_Minute               (isec1[13])  /*  Minute (MM)                                  */
+#define  ISEC1_TimeUnit             (isec1[14])  /*  Time unit indicator                          */
+#define  ISEC1_TimePeriod1          (isec1[15])  /*  P1 Time period                               */
+#define  ISEC1_TimePeriod2          (isec1[16])  /*  P2 Time period                               */
+#define  ISEC1_TimeRange            (isec1[17])  /*  Time range indicator                         */
+#define  ISEC1_AvgNum               (isec1[18])  /*  Number of products included in an average    */
+#define  ISEC1_AvgMiss              (isec1[19])  /*  Number of products missing from an average   */
+#define  ISEC1_Century              (isec1[20])  /*  Century                                      */
+#define  ISEC1_SubCenterID          (isec1[21])  /*  Subcenter identifier                         */
+#define  ISEC1_DecScaleFactor       (isec1[22])  /*  Decimal scale factor                         */
+#define  ISEC1_LocalFLag            (isec1[23])  /*  Flag field to indicate local use in isec1    */
+
+#define  ISEC1_ECMWF_LocalExtension (isec1[36])
+#define  ISEC1_ECMWF_Class          (isec1[37])
+
+
+/*
+ *  Macros for the grid definition section ( Section 2 )
+ */
+#define  ISEC2_GridType             (isec2[ 0])  /* Data representation type */
+
+/* Triangular grids */
+
+#define  ISEC2_GME_NI2              (isec2[ 1])  /*  Number of factor 2 in factorisation of Ni    */
+#define  ISEC2_GME_NI3              (isec2[ 2])  /*  Number of factor 3 in factorisation of Ni    */
+#define  ISEC2_GME_ND               (isec2[ 3])  /*  Nubmer of diamonds                           */
+#define  ISEC2_GME_NI               (isec2[ 4])  /*  Number of tri. subdiv. of the icosahedron    */
+#define  ISEC2_GME_AFlag            (isec2[ 5])  /*  Flag for orientation of diamonds (Table A)   */
+#define  ISEC2_GME_LatPP            (isec2[ 6])  /*  Latitude of pole point                       */
+#define  ISEC2_GME_LonPP            (isec2[ 7])  /*  Longitude of pole point                      */
+#define  ISEC2_GME_LonMPL           (isec2[ 8])  /*  Longitude of the first diamond               */
+#define  ISEC2_GME_BFlag            (isec2[ 9])  /*  Flag for storage sequence (Table B)          */
+
+/* Spherical harmonic coeficients */
+
+#define  ISEC2_PentaJ               (isec2[ 1])  /*  J pentagonal resolution parameter            */
+#define  ISEC2_PentaK               (isec2[ 2])  /*  K pentagonal resolution parameter            */
+#define  ISEC2_PentaM               (isec2[ 3])  /*  M pentagonal resolution parameter            */
+#define  ISEC2_RepType              (isec2[ 4])  /*  Representation type                          */
+#define  ISEC2_RepMode              (isec2[ 5])  /*  Representation mode                          */
+
+/* Gaussian grids */
+
+#define  ISEC2_NumLon               (isec2[ 1])  /*  Number of points along a parallel (Ni)       */
+#define  ISEC2_NumLat               (isec2[ 2])  /*  Number of points along a meridian (Nj)       */
+#define  ISEC2_FirstLat             (isec2[ 3])  /*  Latitude of the first grid point             */
+#define  ISEC2_FirstLon             (isec2[ 4])  /*  Longitude of the first grid point            */
+#define  ISEC2_ResFlag              (isec2[ 5])  /*  Resolution flag: 128 regular grid            */
+#define  ISEC2_LastLat              (isec2[ 6])  /*  Latitude of the last grid point              */
+#define  ISEC2_LastLon              (isec2[ 7])  /*  Longitude of the last grid point             */
+#define  ISEC2_LonIncr              (isec2[ 8])  /*  i direction increment                        */
+#define  ISEC2_LatIncr              (isec2[ 9])  /*  j direction increment                        */
+#define  ISEC2_NumPar               (isec2[ 9])  /*  Number of parallels between a pole and the E.*/
+#define  ISEC2_ScanFlag             (isec2[10])  /*  Scanning mode flags                          */
+#define  ISEC2_NumVCP               (isec2[11])  /*  Number of vertical coordinate parameters     */
+
+/* Lambert */
+#define  ISEC2_Lambert_Lov          (isec2[ 6])  /*  Orientation of the grid                      */
+#define  ISEC2_Lambert_dx           (isec2[ 8])  /*  X-direction grid length                      */
+#define  ISEC2_Lambert_dy           (isec2[ 9])  /*  Y-direction grid length                      */
+#define  ISEC2_Lambert_ProjFlag     (isec2[12])  /*  Projection centre flag                       */
+#define  ISEC2_Lambert_LatS1        (isec2[13])  /*  First lat at which the secant cone cuts the sphere */
+#define  ISEC2_Lambert_LatS2        (isec2[14])  /*  Second lat at which the secant cone cuts the sphere */
+#define  ISEC2_Lambert_LatSP        (isec2[19])  /*  Latitude of the southern pole                */
+#define  ISEC2_Lambert_LonSP        (isec2[20])  /*  Longitude of the southern pole               */
+
+
+#define  ISEC2_Reduced              (isec2[16])  /* 0: regular, 1: reduced grid                   */
+
+#define  ISEC2_RowLonPtr            (&isec2[22])
+#define  ISEC2_RowLon(i)            (isec2[22+i]) /* Number of points along each parallel         */
+
+/* */
+
+#define  ISEC2_LatSP                (isec2[12])  /* Latitude of the southern pole of rotation     */
+#define  ISEC2_LonSP                (isec2[13])  /* Longitude of the southern pole of rotation    */
+
+#define  FSEC2_RotAngle             (fsec2[ 0])  /* Angle of rotation                             */
+#define  FSEC2_StrFact              (fsec2[ 1])  /* Stretching factor                             */
+
+/*
+ *  Macros for the bit map section ( Section 3 )
+ */
+#define  ISEC3_PredefBitmap         (isec3[ 0])  /* Predefined bitmap                             */
+#define  ISEC3_MissVal              (isec3[ 1])  /* Missing data value for integers               */
+#define  FSEC3_MissVal              (fsec3[ 1])  /* Missing data value for floats                 */
+
+/*
+ *  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  gribFixZSE(int flag);     /* 1: Fix ZeroShiftError of simple packed spherical harmonics */
+void  gribSetConst(int flag);   /* 1: Don't pack constant fields on regular grids */
+void  gribSetDebug(int debug);  /* 1: Debugging */
+void  gribSetRound(int round);
+void  gribSetRefDP(double refval);
+void  gribSetRefSP(float  refval);
+void  gribSetValueCheck(int vcheck);
+
+
+void  gribExSP(int *isec0, int *isec1, int *isec2, float *fsec2, int *isec3,
+               float *fsec3, int *isec4, float *fsec4, int klenp, int *kgrib,
+               int kleng, int *kword, char *hoper, int *kret);
+
+void  gribExDP(int *isec0, int *isec1, int *isec2, double *fsec2, int *isec3,
+               double *fsec3, int *isec4, double *fsec4, int klenp, int *kgrib,
+               int kleng, int *kword, char *hoper, int *kret);
+
+
+const char *cgribexLibraryVersion(void);
+
+void  gribDebug(int debug);
+void  gribSetCalendar(int calendar);
+
+void  gribDateTime(int *isec1, int *date, int *time);
+int   gribRefDate(int *isec1);
+int   gribRefTime(int *isec1);
+int   gribTimeIsFC(int *isec1);
+
+void  gribPrintSec0(int *isec0);
+void  gribPrintSec1(int *isec0, int *isec1);
+void  gribPrintSec2DP(int *isec0, int *isec2, double *fsec2);
+void  gribPrintSec2SP(int *isec0, int *isec2, float  *fsec2);
+void  gribPrintSec3DP(int *isec0, int *isec3, double *fsec3);
+void  gribPrintSec3SP(int *isec0, int *isec3, float  *fsec3);
+void  gribPrintSec4DP(int *isec0, int *isec4, double *fsec4);
+void  gribPrintSec4SP(int *isec0, int *isec4, float  *fsec4);
+void  gribPrintSec4Wave(int *isec4);
+
+void  gribPrintALL(int nrec, long offset, long recpos, long recsize, unsigned char *gribbuffer);
+void  gribPrintPDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
+void  gribPrintGDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
+void  gribPrintBMS(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
+void  gribPrintBDS(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
+void  gribCheck1(int nrec, long recpos, long recsize, unsigned char *gribbuffer);
+void  gribRepair1(int nrec, long recsize, unsigned char *gribbuffer);
+
+int grib1Sections(unsigned char *gribbuffer, long recsize, unsigned char **pdsp,
+		  unsigned char **gdsp, unsigned char **bmsp, unsigned char **bdsp);
+int grib2Sections(unsigned char *gribbuffer, long recsize, unsigned char **idsp,
+		  unsigned char **lusp, unsigned char **gdsp, unsigned char **pdsp,
+		  unsigned char **drsp, unsigned char **bmsp, unsigned char **bdsp);
+
+int   gribGetZip(long recsize, unsigned char *gribbuffer, long *urecsize);
+
+int   gribBzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize);
+int   gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize);
+int   gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufsize);
+
+int   gribOpen(const char *filename, const char *mode);
+void  gribClose(int fileID);
+
+int   gribRead(int fileID, unsigned char *buffer, size_t *buffersize);
+int   gribWrite(int fileID, unsigned char *buffer, size_t buffersize);
+off_t gribGetPos(int fileID);
+int   gribGetSize(int fileID);
+int   gribCheckSeek(int fileID, long *offset, int *version);
+int   gribFileSeek(int fileID, long *offset);
+int   gribReadSize(int fileID);
+int   gribVersion(unsigned char *buffer, size_t buffersize);
+
+int   gribGinfo(long recpos, long recsize, unsigned char *gribbuffer, int *intnum, float *fltnum);
+
+double calculate_pfactor(const double* spectralField, long fieldTruncation, long subsetTruncation);
+
+#endif  /* _CGRIBEX_H */ 
+
+#ifndef _GRIBAPI_H
+#define _GRIBAPI_H
+
+#define  GRIBAPI_MISSVAL  -9.E33
+
+/* GRIB2 Level Types */
+#define  GRIB2_LTYPE_SURFACE               1
+#define  GRIB2_LTYPE_CLOUDBASE             2
+#define  GRIB2_LTYPE_CLOUDTOP              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_REFERENCE           150
+#define  GRIB2_LTYPE_SEADEPTH            160
+
+/* 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_NUMBER              101  /*  General Unstructured Grid                */
+
+const char *gribapiLibraryVersion(void);
+void gribContainersNew(stream_t * streamptr);
+void gribContainersDelete(stream_t * streamptr);
+void *gribHandleNew(int editionNumber);
+void gribHandleDelete(void *gh);
+
+typedef struct {
+  int 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 _STREAM_CGRIBEX_H
 #define _STREAM_CGRIBEX_H
 
-int cgribexScanTimestep1(int streamID);
-int cgribexScanTimestep2(int streamID);
-int cgribexScanTimestep(int streamID);
+int cgribexScanTimestep1(stream_t * streamptr);
+int cgribexScanTimestep2(stream_t * streamptr);
+int cgribexScanTimestep(stream_t * streamptr);
 
 int cgribexDecode(unsigned char *gribbuffer, int gribsize, double *data, int gridsize,
 		  int unreduced, int *nmiss, int *zip, double missval);
@@ -1818,9 +2189,9 @@ size_t cgribexEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
 #ifndef _STREAM_GRIBAPI_H
 #define _STREAM_GRIBAPI_H
 
-int gribapiScanTimestep1(int streamID);
-int gribapiScanTimestep2(int streamID);
-int gribapiScanTimestep(int streamID);
+int gribapiScanTimestep1(stream_t * streamptr);
+int gribapiScanTimestep2(stream_t * streamptr);
+int gribapiScanTimestep(stream_t * streamptr);
 
 int gribapiDecode(unsigned char *gribbuffer, int gribsize, double *data, int gridsize,
 		  int unreduced, int *nmiss, int *zip, double missval);
@@ -1845,20 +2216,20 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
 
 int   grbBitsPerValue(int datatype);
 
-int   grbInqContents(int streamID);
-int   grbInqTimestep(int streamID, int tsID);
+int   grbInqContents(stream_t * streamptr);
+int   grbInqTimestep(stream_t * streamptr, int tsID);
 
-int   grbInqRecord(int streamID, int *varID, int *levelID);
-int   grbDefRecord(int streamID);
-int   grbWriteRecord(int streamID, const double *data, int nmiss);
-int   grbReadRecord(int streamID, double *data, int *nmiss);
-int   grbCopyRecord(int streamIDdest, int streamIDsrc);
+int   grbInqRecord(stream_t * streamptr, int *varID, int *levelID);
+int   grbDefRecord(stream_t * streamptr);
+int   grb_write_record(stream_t * streamptr, int memtype, const void *data, int nmiss);
+int   grbReadRecord(stream_t * streamptr, double *data, int *nmiss);
+int   grbCopyRecord(stream_t * streamptr2, stream_t * streamptr1);
 
-void  grbReadVarDP(int streamID, int varID, double *data, int *nmiss);
-void  grbWriteVarDP(int streamID, int varID, const double *data, int nmiss);
+void  grbReadVarDP(stream_t * streamptr, int varID, double *data, int *nmiss);
+void  grb_write_var(stream_t * streamptr, int varID, int memtype, const void *data, int nmiss);
 
-void  grbReadVarSliceDP(int streamID, int varID, int levelID, double *data, int *nmiss);
-int   grbWriteVarSliceDP(int streamID, int varID, int levelID, const double *data, int nmiss);
+void  grbReadVarSliceDP(stream_t * streamptr, int varID, int levelID, double *data, int *nmiss);
+int   grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, int nmiss);
 
 int   grib1ltypeToZaxisType(int grib_ltype);
 int   grib2ltypeToZaxisType(int grib_ltype);
@@ -1876,27 +2247,27 @@ int   grib2ltypeToZaxisType(int grib_ltype);
 #ifndef _STREAM_CDF_H
 #define _STREAM_CDF_H
 
-void   cdfDefVars(int streamID);
-void   cdfDefTimestep(int streamID, int tsID);
-int    cdfInqTimestep(int streamID, int tsID);
-int    cdfInqContents(int streamID);
-void   cdfDefHistory(int streamID, int size, char *history);
-int    cdfInqHistorySize(int streamID);
-void   cdfInqHistoryString(int streamID, char *history);
+void   cdfDefVars(stream_t *streamptr);
+void   cdfDefTimestep(stream_t *streamptr, int tsID);
+int    cdfInqTimestep(stream_t *streamptr, int tsID);
+int    cdfInqContents(stream_t *streamptr);
+void   cdfDefHistory(stream_t *streamptr, int size, char *history);
+int    cdfInqHistorySize(stream_t *streamptr);
+void   cdfInqHistoryString(stream_t *streamptr, char *history);
 
-void   cdfEndDef(int streamID);
-int    cdfDefRecord(int streamID);
+void   cdfEndDef(stream_t * streamptr);
+int    cdfDefRecord(stream_t * streamptr);
 
-int    cdfCopyRecord(int streamIDdest, int streamIDsrc);
+int    cdfCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
 
-int    cdfReadRecord(int streamID, double *data, int *nmiss);
-void   cdf_write_record(int streamID, int memtype, const void *data, int nmiss);
+int    cdfReadRecord(stream_t *streamptr, double *data, int *nmiss);
+void   cdf_write_record(stream_t *streamptr, int memtype, const void *data, int nmiss);
 
-void   cdfReadVarDP(int streamID, int varID, double *data, int *nmiss);
-void   cdf_write_var(int streamID, int varID, int memtype, const void *data, int nmiss);
+void   cdfReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss);
+void   cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data, int nmiss);
 
-int    cdfReadVarSliceDP(int streamID, int varID, int levelID, double *data, int *nmiss);
-int    cdf_write_var_slice(int streamID, int varID, int levelID, int memtype, const void *data, int nmiss);
+int    cdfReadVarSliceDP(stream_t *streamptr, int varID, int levelID, double *data, int *nmiss);
+int    cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, int nmiss);
 
 #endif
 /*
@@ -3450,6 +3821,8 @@ grid_t;
 void grid_init(grid_t *gridptr);
 void grid_free(grid_t *gridptr);
 
+int gridSize(void);
+
 const double *gridInqXvalsPtr(int gridID);
 const double *gridInqYvalsPtr(int gridID);
 
@@ -3460,7 +3833,7 @@ const double *gridInqAreaPtr(int gridID);
 int gridCompare(int gridID, grid_t grid);
 int gridGenerate(grid_t grid);
 
-void     gridGetIndexList    ( int, int * );
+void gridGetIndexList( int, int * );
 
 #endif
 /*
@@ -3472,6 +3845,12 @@ void     gridGetIndexList    ( int, int * );
  * require-trailing-newline: t
  * End:
  */
+#ifndef _ZAXIS_H
+#define _ZAXIS_H
+
+int zaxisSize(void);
+
+#endif
 #ifndef _VARSCAN_H
 #define _VARSCAN_H
 
@@ -3481,7 +3860,7 @@ void     gridGetIndexList    ( int, int * );
 
 
 void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
-		  int level1, int level2, int prec,
+		  int level1, int level2, int level_sf, int prec,
 		  int *pvarID, int *plevelID, int tsteptype, int numavg, int ltype,
 		  const char *name, const char *longname, const char *units);
 
@@ -3623,20 +4002,20 @@ int  srvDefDataDP(srvrec_t *srvp, const double *data);
 #  include "service.h"
 #endif
 
-int    srvInqContents(int streamID);
-int    srvInqTimestep(int streamID, int tsID);
+int    srvInqContents(stream_t *streamptr);
+int    srvInqTimestep(stream_t *streamptr, int tsID);
 
-int    srvInqRecord(int streamID, int *varID, int *levelID);
-int    srvDefRecord(int streamID);
-int    srvCopyRecord(int streamIDdest, int streamIDsrc);
-int    srvReadRecord(int streamID, double *data, int *nmiss);
-int    srvWriteRecord(int streamID, const double *data);
+int    srvInqRecord(stream_t *streamptr, int *varID, int *levelID);
+int    srvDefRecord(stream_t *streamptr);
+int    srvCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
+int    srvReadRecord(stream_t *streamptr, double *data, int *nmiss);
+int    srvWriteRecord(stream_t *streamptr, const double *data);
 
-void   srvReadVarDP (int streamID, int varID,       double *data, int *nmiss);
-void   srvWriteVarDP(int streamID, int varID, const double *data);
+void   srvReadVarDP (stream_t *streamptr, int varID,       double *data, int *nmiss);
+void   srvWriteVarDP(stream_t *streamptr, int varID, const double *data);
 
-void   srvReadVarSliceDP (int streamID, int varID, int levelID,       double *data, int *nmiss);
-void   srvWriteVarSliceDP(int streamID, int varID, int levelID, const double *data);
+void   srvReadVarSliceDP (stream_t *streamptr, int varID, int levelID,       double *data, int *nmiss);
+void   srvWriteVarSliceDP(stream_t *streamptr, int varID, int levelID, const double *data);
 
 #endif  /* _STREAM_SRV_H */
 /*
@@ -3655,20 +4034,20 @@ void   srvWriteVarSliceDP(int streamID, int varID, int levelID, const double *da
 #  include "extra.h"
 #endif
 
-int    extInqContents(int streamID);
-int    extInqTimestep(int streamID, int tsID);
+int    extInqContents(stream_t *streamptr);
+int    extInqTimestep(stream_t *streamptr, int tsID);
 
-int    extInqRecord(int streamID, int *varID, int *levelID);
-int    extDefRecord(int streamID);
-int    extCopyRecord(int streamIDdest, int streamIDsrc);
-int    extReadRecord(int streamID, double *data, int *nmiss);
-int    extWriteRecord(int streamID, const double *data);
+int    extInqRecord(stream_t *streamptr, int *varID, int *levelID);
+int    extDefRecord(stream_t *streamptr);
+int    extCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
+int    extReadRecord(stream_t *streamptr, double *data, int *nmiss);
+int    extWriteRecord(stream_t *streamptr, const double *data);
 
-void   extReadVarDP (int streamID, int varID,       double *data, int *nmiss);
-void   extWriteVarDP(int streamID, int varID, const double *data);
+void   extReadVarDP (stream_t *streamptr, int varID,       double *data, int *nmiss);
+void   extWriteVarDP(stream_t *streamptr, int varID, const double *data);
 
-void   extReadVarSliceDP (int streamID, int varID, int levelID,       double *data, int *nmiss);
-void   extWriteVarSliceDP(int streamID, int varID, int levelID, const double *data);
+void   extReadVarSliceDP (stream_t *streamptr, int varID, int levelID,       double *data, int *nmiss);
+void   extWriteVarSliceDP(stream_t *streamptr, int varID, int levelID, const double *data);
 
 #endif  /* _STREAM_EXT_H */
 /*
@@ -3687,20 +4066,20 @@ void   extWriteVarSliceDP(int streamID, int varID, int levelID, const double *da
 #  include "ieg.h"
 #endif
 
-int    iegInqContents(int streamID);
-int    iegInqTimestep(int streamID, int tsID);
+int    iegInqContents(stream_t *streamptr);
+int    iegInqTimestep(stream_t *streamptr, int tsID);
 
-int    iegInqRecord(int streamID, int *varID, int *levelID);
-int    iegDefRecord(int streamID);
-int    iegCopyRecord(int streamIDdest, int streamIDsrc);
-int    iegReadRecord(int streamID, double *data, int *nmiss);
-int    iegWriteRecord(int streamID, const double *data);
+int    iegInqRecord(stream_t *streamptr, int *varID, int *levelID);
+int    iegDefRecord(stream_t *streamptr);
+int    iegCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
+int    iegReadRecord(stream_t *streamptr, double *data, int *nmiss);
+int    iegWriteRecord(stream_t *streamptr, const double *data);
 
-void   iegReadVarDP (int streamID, int varID,       double *data, int *nmiss);
-void   iegWriteVarDP(int streamID, int varID, const double *data);
+void   iegReadVarDP (stream_t *streamptr, int varID,       double *data, int *nmiss);
+void   iegWriteVarDP(stream_t *streamptr, int varID, const double *data);
 
-void   iegReadVarSliceDP (int streamID, int varID, int levelID,       double *data, int *nmiss);
-void   iegWriteVarSliceDP(int streamID, int varID, int levelID, const double *data);
+void   iegReadVarSliceDP (stream_t *streamptr, int varID, int levelID,       double *data, int *nmiss);
+void   iegWriteVarSliceDP(stream_t *streamptr, int varID, int levelID, const double *data);
 
 #endif  /* _STREAM_IEG_H */
 /*
@@ -3910,6 +4289,13 @@ typedef struct
 }
 ensinfo_t;
 
+/* ---------------------------------- */
+/* Local change: 2013-01-28, FP (DWD) */
+/* ---------------------------------- */
+
+/* Length of optional keyword/value pair list */
+#define MAX_OPT_GRIB_ENTRIES 50
+
 
 typedef struct
 {
@@ -3949,6 +4335,18 @@ typedef struct
   int         decoSize;
   deco_t     *deco;
 
+  /* ---------------------------------- */
+  /* Local change: 2013-01-28, FP (DWD) */
+  /* ---------------------------------- */
+
+  /* (Optional) list of keyword/double value pairs */
+  int    opt_grib_dbl_nentries;
+  char*  opt_grib_dbl_keyword[MAX_OPT_GRIB_ENTRIES];
+  double opt_grib_dbl_val[MAX_OPT_GRIB_ENTRIES];
+  /* (Optional) list of keyword/integer value pairs */
+  int    opt_grib_int_nentries;
+  char*  opt_grib_int_keyword[MAX_OPT_GRIB_ENTRIES];
+  int    opt_grib_int_val[MAX_OPT_GRIB_ENTRIES];
 }
 var_t;
 
@@ -4212,7 +4610,8 @@ void   reshRemove ( cdiResH, resOps * );
 
 int    reshCountType ( resOps * );
 
-void * reshGetVal ( cdiResH, resOps * );
+void * reshGetValue(const char *, cdiResH, resOps * );
+#define reshGetVal(resH, ops)  reshGetValue(__func__, resH, ops)
 
 void   reshGetResHListOfType ( int, int *, resOps * );
 
@@ -4284,7 +4683,7 @@ void   reshUnlock ( void );
 #  define  __attribute__(x)  /*NOTHING*/
 #endif
 
-void pcdiAssert   ( bool, const char *, const char *, int );
+void pcdiAssert( bool, const char *, const char *, int );
 #define xassert(arg) do {                               \
     if ((arg)) {                                        \
     } else {                                            \
@@ -4368,6 +4767,10 @@ char * outTextComm ( MPI_Comm * );
   }
 #endif
 
+void pcdiAbortC(const char *, const char *, const char *, int, const char *, ... )
+  __attribute__((noreturn));
+#define xabortC(caller, ...) pcdiAbortC(caller, __FILE__, __func__, __LINE__, __VA_ARGS__ )
+
 void pcdiAbort (const char *, const char *, int, const char *, ... )
   __attribute__((noreturn));
 #define xabort(...) pcdiAbort(__FILE__, __func__, __LINE__, __VA_ARGS__ )
@@ -5113,544 +5516,217 @@ size_t memTotal(void)
       fprintf(stderr, "arena      %8ld (non-mmapped space allocated from system)\n", (unsigned long) meminfo.arena);
       fprintf(stderr, "ordblks    %8ld (number of free chunks)\n", (unsigned long) meminfo.ordblks);
       fprintf(stderr, "smblks     %8ld (number of fastbin blocks)\n", (unsigned long) meminfo.smblks);
-      fprintf(stderr, "hblks      %8ld (number of mmapped regions)\n", (unsigned long) meminfo.hblks);
-      fprintf(stderr, "hblkhd     %8ld (space in mmapped regions)\n", (unsigned long) meminfo.hblkhd);
-      fprintf(stderr, "usmblks    %8ld (maximum total allocated space)\n", (unsigned long) meminfo.usmblks);
-      fprintf(stderr, "fsmblks    %8ld (maximum total allocated space)\n", (unsigned long) meminfo.fsmblks);
-      fprintf(stderr, "uordblks   %8ld (total allocated space)\n", (unsigned long) meminfo.uordblks);
-      fprintf(stderr, "fordblks   %8ld (total free space)\n", (unsigned long) meminfo.fordblks);
-      fprintf(stderr, "Memory in use:   %8ld bytes\n", (unsigned long) meminfo.usmblks + meminfo.uordblks);
-      fprintf(stderr, "Total heap size: %8ld bytes\n", (unsigned long) meminfo.arena);
-
-      /* malloc_stats(); */
-    }
-  memtotal = meminfo.arena;
-#endif
-
-  return (memtotal);
-}
-
-
-void memExitOnError(void)
-{
-  dmemory_ExitOnError = 1;
-}
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef _DMEMORY_H
-#define _DMEMORY_H
-
-#include <stdlib.h>
-
-/*
- * if DEBUG_MEMORY is defined setenv MEMORY_DEBUG to debug memory
- */
-
-#define  DEBUG_MEMORY
-
-#ifndef  WITH_CALLER_NAME
-#define  WITH_CALLER_NAME
-#endif
-
-extern size_t  memTotal(void);
-extern void    memDebug(int debug);
-extern void    memExitOnError(void);
-
-#if  defined  DEBUG_MEMORY
-
-extern void   *Realloc(const char *caller, const char *file, int line, void *ptr, size_t size);
-extern void   *Calloc (const char *caller, const char *file, int line, size_t nmemb, size_t size);
-extern void   *Malloc (const char *caller, const char *file, int line, size_t size);
-extern void    Free   (const char *caller, const char *file, int line, void *ptr);
-
-#if  defined  calloc
-#  undef  calloc
-#endif
-
-#if  defined  WITH_CALLER_NAME
-#  define  realloc(p, s)  Realloc(__func__, __FILE__, __LINE__, p, (size_t)s)
-#  define   calloc(n, s)   Calloc(__func__, __FILE__, __LINE__, n, (size_t)s)
-#  define   malloc(s)      Malloc(__func__, __FILE__, __LINE__, (size_t)s)
-#  define     free(p)        Free(__func__, __FILE__, __LINE__, p)
-#else
-#  define  realloc(p, s)  Realloc((void *) NULL, __FILE__, __LINE__, p, (size_t)s)
-#  define   calloc(n, s)   Calloc((void *) NULL, __FILE__, __LINE__, n, (size_t)s)
-#  define   malloc(s)      Malloc((void *) NULL, __FILE__, __LINE__, (size_t)s)
-#  define     free(p)        Free((void *) NULL, __FILE__, __LINE__, p)
-#endif
-
-#endif /* DEBUG_MEMORY */
-
-#endif /* _DMEMORY_H */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <errno.h>
-
-
-int _ExitOnError   = 1;	/* If set to 1, exit on error       */
-int _Verbose = 1;	/* If set to 1, errors are reported */
-int _Debug   = 0;       /* If set to 1, debugging           */
-
-
-void SysError_(const char *caller, const char *fmt, ...)
-{
-  va_list args;
-	
-  va_start(args, fmt);
-
-  printf("\n");
-   fprintf(stderr, "Error (%s) : ", caller);
-  vfprintf(stderr, fmt, args);
-   fprintf(stderr, "\n");
-
-  va_end(args);
-
-  if ( errno )
-    perror("System error message ");
-	
-  exit(EXIT_FAILURE);
-}
-
-
-void Error_(const char *caller, const char *fmt, ...)
-{
-  va_list args;
-	
-  va_start(args, fmt);
-
-  printf("\n");
-   fprintf(stderr, "Error (%s) : ", caller);
-  vfprintf(stderr, fmt, args);
-   fprintf(stderr, "\n");
-
-  va_end(args);
-
-  if ( _ExitOnError ) exit(EXIT_FAILURE);
-}
-
-
-void Warning_(const char *caller, const char *fmt, ...)
-{
-  va_list args;
-	
-  va_start(args, fmt);
-
-  if ( _Verbose )
-    {
-       fprintf(stderr, "Warning (%s) : ", caller);
-      vfprintf(stderr, fmt, args);
-       fprintf(stderr, "\n");
-    }
-
-  va_end(args);
-}
-
-
-void Message_(const char *caller, const char *fmt, ...)
-{
-  va_list args;
-	
-  va_start(args, fmt);
-
-   fprintf(stdout, "%-18s : ", caller);
-  vfprintf(stdout, fmt, args);
-   fprintf(stdout, "\n");
-
-  va_end(args);
-}
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef _ERROR_H
-#define _ERROR_H
-
-#ifndef  WITH_CALLER_NAME
-#define  WITH_CALLER_NAME
-#endif
-
-#define  _FATAL     1     /* Error flag: exit on error  */
-#define  _VERBOSE   2     /* Error flag: report errors  */
-#define  _DEBUG     4     /* Error flag: debug          */
-
-extern int _ExitOnError;  /* If set to 1, exit on error (default 1)       */
-extern int _Verbose;      /* If set to 1, errors are reported (default 1) */
-extern int _Debug;        /* If set to 1, debuggig (default 0)            */
-
-void SysError_(const char *caller, const char *fmt, ...);
-void    Error_(const char *caller, const char *fmt, ...);
-void  Warning_(const char *caller, const char *fmt, ...);
-void  Message_(const char *caller, const char *fmt, ...);
-
-#if  defined  WITH_CALLER_NAME
-#  define  SysError(...)  SysError_(__func__, __VA_ARGS__)
-#  define    Errorc(...)     Error_(  caller, __VA_ARGS__)
-#  define     Error(...)     Error_(__func__, __VA_ARGS__)
-#  define   Warning(...)   Warning_(__func__, __VA_ARGS__)
-#  define  Messagec(...)   Message_(  caller, __VA_ARGS__)
-#  define   Message(...)   Message_(__func__, __VA_ARGS__)
-#else
-#  define  SysError(...)  SysError_((void *), __VA_ARGS__)
-#  define    Errorc(...)     Error_((void *), __VA_ARGS__)
-#  define     Error(...)     Error_((void *), __VA_ARGS__)
-#  define   Warning(...)   Warning_((void *), __VA_ARGS__)
-#  define  Messagec(...)   Message_((void *), __VA_ARGS__)
-#  define   Message(...)   Message_((void *), __VA_ARGS__)
-#endif
-
-#endif  /* _ERROR_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_INT_H
-#define _STREAM_INT_H
-
-#if defined (HAVE_CONFIG_H)
-#endif
-
-#include <assert.h>
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-#include <sys/types.h>
-
-#ifndef strdupx
-#ifndef strdup
-char *strdup(const char *s);
-#endif
-#define strdupx  strdup
-/*
-#define strdupx(s)			          \
-({					      	  \
-   const char *__old = (s);			  \
-   size_t __len = strlen(__old) + 1;		  \
-   char *__new = (char *) malloc(__len);	  \
-   (char *) memcpy(__new, __old, __len);	  \
-})
-*/
-#endif
-
-#ifndef  M_PI
-#define  M_PI        3.14159265358979323846  /* pi */
-#endif
-
-
-#ifndef  _ERROR_H
-#endif
-#ifndef _BASETIME_H
-#endif
-#ifndef _TIMEBASE_H
-#endif
-#ifndef  _TAXIS_H
-#endif
-#ifndef  _CDI_LIMITS_H
-#endif
-#ifndef  _SERVICE_H
-#endif
-#ifndef  _EXTRA_H
-#endif
-#ifndef  _IEG_H
-#endif
-
-
-#define check_parg(arg)  if ( arg == 0 ) Warning("Argument '" #arg "' not allocated!")
-
-#if defined (__xlC__) /* performance problems on IBM */
-#ifndef DBL_IS_NAN
-#  define DBL_IS_NAN(x)     ((x) != (x))
-#endif
-#else
-#ifndef DBL_IS_NAN
-#if  defined  (HAVE_DECL_ISNAN)
-#  define DBL_IS_NAN(x)     (isnan(x))
-#elif  defined  (FP_NAN)
-#  define DBL_IS_NAN(x)     (fpclassify(x) == FP_NAN)
-#else
-#  define DBL_IS_NAN(x)     ((x) != (x))
-#endif
-#endif
-#endif
-
-#ifndef DBL_IS_EQUAL
-/*#define DBL_IS_EQUAL(x,y) (!(x < y || y < x)) */
-#  define DBL_IS_EQUAL(x,y) (DBL_IS_NAN(x)||DBL_IS_NAN(y)?(DBL_IS_NAN(x)&&DBL_IS_NAN(y)?1:0):!(x < y || y < x))
-#endif
-
-#ifndef IS_EQUAL
-#  define IS_NOT_EQUAL(x,y) (x < y || y < x)
-#  define IS_EQUAL(x,y)     (!IS_NOT_EQUAL(x,y))
-#endif
-
-
-#ifndef INT
-#  define  INT(x)  ((int)(x))
-#endif
-
-#ifndef NINT
-#  define  NINT(x)  ((x) < 0 ? (int)((x)-.5) : (int)((x)+.5))
-#endif
-
-#define  FALSE  0
-#define  TRUE   1
-
-#define  TYPE_REC  0
-#define  TYPE_VAR  1
-
-#define  MEMTYPE_DOUBLE  1
-#define  MEMTYPE_FLOAT   2
-
-typedef struct
-{
-  void     *buffer;
-  size_t    buffersize;
-  off_t     position;
-  int       recsize;
-  int       size;
-  int       dataread;
-  int       param;
-  int       level;
-  int       date;
-  int       time;
-  int       gridID;
-  int       zaxisID;
-  int       used;
-  int       nrec;
-  int       varID;
-  int       levelID;
-  int       recid;
-  int       prec;
-  int       sec0[2];
-  int       sec1[1024];
-  int       sec2[4096];
-  int       sec3[2];
-  int       sec4[512];
-#if  defined  (HAVE_LIBSERVICE)
-  srvrec_t   *srvp;
-#endif
-#if  defined  (HAVE_LIBEXTRA)
-  extrec_t   *extp;
-#endif
-#if  defined  (HAVE_LIBIEG)
-  iegrec_t   *iegp;
+      fprintf(stderr, "hblks      %8ld (number of mmapped regions)\n", (unsigned long) meminfo.hblks);
+      fprintf(stderr, "hblkhd     %8ld (space in mmapped regions)\n", (unsigned long) meminfo.hblkhd);
+      fprintf(stderr, "usmblks    %8ld (maximum total allocated space)\n", (unsigned long) meminfo.usmblks);
+      fprintf(stderr, "fsmblks    %8ld (maximum total allocated space)\n", (unsigned long) meminfo.fsmblks);
+      fprintf(stderr, "uordblks   %8ld (total allocated space)\n", (unsigned long) meminfo.uordblks);
+      fprintf(stderr, "fordblks   %8ld (total free space)\n", (unsigned long) meminfo.fordblks);
+      fprintf(stderr, "Memory in use:   %8ld bytes\n", (unsigned long) meminfo.usmblks + meminfo.uordblks);
+      fprintf(stderr, "Total heap size: %8ld bytes\n", (unsigned long) meminfo.arena);
+
+      /* malloc_stats(); */
+    }
+  memtotal = meminfo.arena;
 #endif
+
+  return (memtotal);
 }
-Record;
 
 
-typedef struct
+void memExitOnError(void)
 {
-  off_t     position;
-  size_t    size;
-  int       zip;
-  int       param;
-  int       ilevel;
-  int       ilevel2;
-  int       ltype;
-  short     used;
-  short     varID;
-  short     levelID;
+  dmemory_ExitOnError = 1;
 }
-record_t;
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef _DMEMORY_H
+#define _DMEMORY_H
 
+#include <stdlib.h>
 
-typedef struct {
-  record_t *records;
-  int       recordSize;  /* number of allocated records           */
-  int      *recIDs;      /* IDs of non constant records           */
-  int       nrecs;       /* number of used records                */
-                         /* tsID=0 nallrecs                       */
-                         /* tsID>0 number of non constant records */
-  int       nallrecs;    /* number of all records                 */
-  int       curRecID;    /* current record ID                     */
-  long      next;
-  off_t     position;    /* timestep file position                */
-  taxis_t   taxis;
-}
-tsteps_t;
+/*
+ * if DEBUG_MEMORY is defined setenv MEMORY_DEBUG to debug memory
+ */
 
+#define  DEBUG_MEMORY
 
-typedef struct {
-  int       ncvarid;
-  int       nlevs;
-  int      *level;       /* record IDs */
-  int      *lindex;      /* level index */
-  int       defmiss;     /* TRUE if missval is defined in file */
+#ifndef  WITH_CALLER_NAME
+#define  WITH_CALLER_NAME
+#endif
 
-  int       isUsed;
-  int       gridID;
-  int       zaxisID;
-  int       tsteptype;   /* TSTEP_* */
-}
-svarinfo_t;
+extern size_t  memTotal(void);
+extern void    memDebug(int debug);
+extern void    memExitOnError(void);
 
+#if  defined  DEBUG_MEMORY
 
-typedef struct {
-  int       ilev;
-  int       mlev;
-  int       ilevID;
-  int       mlevID;
-}
-VCT;
+extern void   *Realloc(const char *caller, const char *file, int line, void *ptr, size_t size);
+extern void   *Calloc (const char *caller, const char *file, int line, size_t nmemb, size_t size);
+extern void   *Malloc (const char *caller, const char *file, int line, size_t size);
+extern void    Free   (const char *caller, const char *file, int line, void *ptr);
 
+#if  defined  calloc
+#  undef  calloc
+#endif
 
-typedef struct {
-  int         self;
-  int         accesstype;   /* TYPE_REC or TYPE_VAR */
-  int         accessmode;
-  int         filetype;
-  int         byteorder;
-  int         fileID;
-  int         dimgroupID;
-  int         filemode;
-  off_t       numvals;
-  char       *filename;
-  Record     *record;
-  int        nrecs;        /* number of records                  */
-  int         nvars;        /* number of variables                */
-  int         varlocked;    /* variables locked                   */
-  svarinfo_t *vars;
-  int         varsAllocated;
-  int         varinit;
-  int         curTsID;      /* current timestep ID */
-  int         rtsteps;      /* number of tsteps accessed       */
-  long        ntsteps;      /* number of tsteps : only set if all records accessed */
-  int         numTimestep;  /* number of tsteps : only set if all records accessed */
-  tsteps_t   *tsteps;
-  int         tstepsTableSize;
-  int         tstepsNextID;
-  BaseTime    basetime;
-  int         ncmode;
-  int         vlistID;
-  int         xdimID[MAX_GRIDS_PS];
-  int         ydimID[MAX_GRIDS_PS];
-  int         zaxisID[MAX_ZAXES_PS];
-  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
-  int         curfile;
-  int         nfiles;
-  char      **fnames;
-#if defined (GRIBCONTAINER2D)
-  void      **gribContainers;
+#if  defined  WITH_CALLER_NAME
+#  define  realloc(p, s)  Realloc(__func__, __FILE__, __LINE__, p, (size_t)s)
+#  define   calloc(n, s)   Calloc(__func__, __FILE__, __LINE__, n, (size_t)s)
+#  define   malloc(s)      Malloc(__func__, __FILE__, __LINE__, (size_t)s)
+#  define     free(p)        Free(__func__, __FILE__, __LINE__, p)
 #else
-  void       *gribContainers;
+#  define  realloc(p, s)  Realloc((void *) NULL, __FILE__, __LINE__, p, (size_t)s)
+#  define   calloc(n, s)   Calloc((void *) NULL, __FILE__, __LINE__, n, (size_t)s)
+#  define   malloc(s)      Malloc((void *) NULL, __FILE__, __LINE__, (size_t)s)
+#  define     free(p)        Free((void *) NULL, __FILE__, __LINE__, p)
 #endif
-  int         vlistIDorig;
-}
-stream_t;
 
+#endif /* DEBUG_MEMORY */
 
-extern int CDI_Debug;      /* If set to 1, debuggig (default 0)            */
-extern double cdiDefaultMissval;
-extern int cdiDefaultInstID;
-extern int cdiDefaultModelID;
-extern int cdiDefaultTableID;
-extern int cdiDefaultLeveltype;
-extern int cdiNcMissingValue;
-extern int cdiNcChunksizehint;
-extern int cdiChunkType;
-extern int cdiSplitLtype105;
+#endif /* _DMEMORY_H */
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#if defined (HAVE_CONFIG_H)
+#endif
 
-extern char *cdiPartabPath;
-extern int   cdiPartabIntern;
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <errno.h>
 
-stream_t *stream_to_pointer(int idx);
-stream_t *stream_new_entry(void);
-void stream_delete_entry(stream_t *streamptr);
-void stream_check_ptr(const char *caller, stream_t *streamptr);
 
-int     streamInqFileID(int streamID);
+int _ExitOnError   = 1;	/* If set to 1, exit on error       */
+int _Verbose = 1;	/* If set to 1, errors are reported */
+int _Debug   = 0;       /* If set to 1, debugging           */
 
-int     zaxisInqLevelID(int zaxisID, double level);
-char   *gridNamePtr(int gridtype);
-char   *zaxisNamePtr(int leveltype);
 
-void    streamCheckID(const char *caller, int streamID);
+void SysError_(const char *caller, const char *fmt, ...)
+{
+  va_list args;
+	
+  va_start(args, fmt);
 
-void    streamDefineTaxis(int streamID);
+  printf("\n");
+   fprintf(stderr, "Error (%s) : ", caller);
+  vfprintf(stderr, fmt, args);
+   fprintf(stderr, "\n");
 
-int     streamsNewEntry(int filetype);
-void    streamsInitEntry(int streamID);
-int     streamNewVar(int streamID, int gridID, int zaxisID);
+  va_end(args);
 
-int     tstepsNewEntry(int streamID);
+  if ( errno )
+    perror("System error message ");
+	
+  exit(EXIT_FAILURE);
+}
 
-char   *strfiletype(int filetype);
 
-void    cdiGenVars(int streamID);
+void Error_(const char *caller, const char *fmt, ...)
+{
+  va_list args;
+	
+  va_start(args, fmt);
 
-void    cdiCheckContents(int streamID);
+  printf("\n");
+   fprintf(stderr, "Error (%s) : ", caller);
+  vfprintf(stderr, fmt, args);
+   fprintf(stderr, "\n");
 
-void    cdiCreateRecords(int streamID, int tsID);
+  va_end(args);
 
-int     recordNewEntry(int streamID, int tsID);
+  if ( _ExitOnError ) exit(EXIT_FAILURE);
+}
 
-void    cdiCreateTimesteps(int streamID);
 
-void    recordInitEntry(record_t *record);
+void Warning_(const char *caller, const char *fmt, ...)
+{
+  va_list args;
+	
+  va_start(args, fmt);
 
-void    cdiCheckZaxis(int zaxisID);
+  if ( _Verbose )
+    {
+       fprintf(stderr, "Warning (%s) : ", caller);
+      vfprintf(stderr, fmt, args);
+       fprintf(stderr, "\n");
+    }
 
-void    cdiPrintDatatypes(void);
+  va_end(args);
+}
 
-void    cdiDefAccesstype(int streamID, int type);
-int     cdiInqAccesstype(int streamID);
 
-void    streamDefDimgroupID(int streamID, int dimgroupID);
-int     streamInqDimgroupID(int streamID);
+void Message_(const char *caller, const char *fmt, ...)
+{
+  va_list args;
+	
+  va_start(args, fmt);
 
-int     getByteswap(int byteorder);
+   fprintf(stdout, "%-18s : ", caller);
+  vfprintf(stdout, fmt, args);
+   fprintf(stdout, "\n");
 
-int     streamSize ();
-void    streamGetIndexList ( int, int * );
+  va_end(args);
+}
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
+#ifndef _ERROR_H
+#define _ERROR_H
 
+#ifndef  WITH_CALLER_NAME
+#define  WITH_CALLER_NAME
+#endif
 
-void  cdiInitialize(void);
+#define  _FATAL     1     /* Error flag: exit on error  */
+#define  _VERBOSE   2     /* Error flag: report errors  */
+#define  _DEBUG     4     /* Error flag: debug          */
 
-void stream_write_record(int streamID, int memtype, const void *data, int nmiss);
+extern int _ExitOnError;  /* If set to 1, exit on error (default 1)       */
+extern int _Verbose;      /* If set to 1, errors are reported (default 1) */
+extern int _Debug;        /* If set to 1, debuggig (default 0)            */
 
+void SysError_(const char *caller, const char *fmt, ...);
+void    Error_(const char *caller, const char *fmt, ...);
+void  Warning_(const char *caller, const char *fmt, ...);
+void  Message_(const char *caller, const char *fmt, ...);
 
-#endif  /* _STREAM_INT_H */
+#if  defined  WITH_CALLER_NAME
+#  define  SysError(...)  SysError_(__func__, __VA_ARGS__)
+#  define    Errorc(...)     Error_(  caller, __VA_ARGS__)
+#  define     Error(...)     Error_(__func__, __VA_ARGS__)
+#  define   Warning(...)   Warning_(__func__, __VA_ARGS__)
+#  define  Messagec(...)   Message_(  caller, __VA_ARGS__)
+#  define   Message(...)   Message_(__func__, __VA_ARGS__)
+#else
+#  define  SysError(...)  SysError_((void *), __VA_ARGS__)
+#  define    Errorc(...)     Error_((void *), __VA_ARGS__)
+#  define     Error(...)     Error_((void *), __VA_ARGS__)
+#  define   Warning(...)   Warning_((void *), __VA_ARGS__)
+#  define  Messagec(...)   Message_((void *), __VA_ARGS__)
+#  define   Message(...)   Message_((void *), __VA_ARGS__)
+#endif
+
+#endif  /* _ERROR_H */
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -6665,8 +6741,6 @@ double vtime2timeval(int vdate, int vtime, taxis_t *taxis)
     {
       int nmonth, dpm;
 
-      dpm = days_per_month(calendar, year, month);
-
       value = (year-ryear)*12 - rmonth + month;
 
       nmonth = (int) value;
@@ -6675,6 +6749,8 @@ double vtime2timeval(int vdate, int vtime, taxis_t *taxis)
       while ( month > 12 ) { month -= 12; year++; }
       while ( month <  1 ) { month += 12; year--; }
 
+      dpm = days_per_month(calendar, year, month);
+
       encode_caldaysec(calendar, year, month, day, hour, minute, second, &julday2, &secofday2);
 
       julday_sub(julday1, secofday1, julday2, secofday2, &days, &secs);
@@ -7052,6 +7128,7 @@ void taxisPack ( void * voidP, void * packBuffer, int packBufferSize,
  * End:
  */
 #include <stdio.h>
+#include <stdint.h>
 #include <math.h>		/* for floor() */
 
 
@@ -7188,9 +7265,9 @@ int sec_to_time(int secofday)
 }
 
 static
-void adjust_seconds(int *julday, int *secofday)
+void adjust_seconds(int *julday, int64_t *secofday)
 {
-  int secperday = 86400;
+  int64_t secperday = 86400;
 
   while ( *secofday >= secperday ) 
     { 
@@ -7206,52 +7283,66 @@ void adjust_seconds(int *julday, int *secofday)
 }
 
 
-void julday_add_seconds(int seconds, int *julday, int *secofday)
+void julday_add_seconds(int64_t seconds, int *julday, int *secofday)
 {
-  *secofday += seconds;
+  int64_t sec_of_day = *secofday;
+
+  sec_of_day += seconds;
 
-  adjust_seconds(julday, secofday);
+  adjust_seconds(julday, &sec_of_day);
+
+  *secofday = (int) sec_of_day;
 }
 
 /* add days and secs to julday/secofday */
 void julday_add(int days, int secs, int *julday, int *secofday)
 {
-  *julday   += days;
-  *secofday += secs;
+  int64_t sec_of_day = *secofday;
+
+  sec_of_day += secs;
+  *julday    += days;
 
-  adjust_seconds(julday, secofday);
+  adjust_seconds(julday, &sec_of_day);
+
+  *secofday = (int) sec_of_day;
 }
 
 /* subtract julday1/secofday1 from julday2/secofday2 and returns the result in seconds */
 double julday_sub(int julday1, int secofday1, int julday2, int secofday2, int *days, int *secs)
 {
-  int seconds;
+  int64_t sec_of_day;
+  int64_t seconds;
 
   *days = julday2 - julday1;
   *secs = secofday2 - secofday1;
 
-  adjust_seconds(days, secs);
+  sec_of_day = *secs;
+
+  adjust_seconds(days, &sec_of_day);
 
-  seconds = *days*86400. + *secs;
+  *secs = (int) sec_of_day;
+
+  seconds = *days*86400. + sec_of_day;
 
   return (seconds);
 }
 
 
-void encode_juldaysec(int calendar, int year, int month, int day, int hour, int minute, int *julday, int *secofday)
+void encode_juldaysec(int calendar, int year, int month, int day, int hour, int minute, int second, int *julday, int *secofday)
 {
   *julday = encode_julday(calendar, year, month, day);
 
-  *secofday = (hour*60 + minute)*60;
+  *secofday = (hour*60 + minute)*60 + second;
 }
 
 
-void decode_juldaysec(int calendar, int julday, int secofday, int *year, int *month, int *day, int *hour, int *minute)
+void decode_juldaysec(int calendar, int julday, int secofday, int *year, int *month, int *day, int *hour, int *minute, int *second)
 {
   decode_julday(calendar, julday, year, month, day);
 
   *hour   = secofday/3600;
   *minute = secofday/60 - *hour*60;
+  *second = secofday - *hour*3600 - *minute*60;
 }
 
 
@@ -7265,6 +7356,7 @@ int main(void)
   int i, j = 0;
   int year, mon, day, hour, minute, second;
   int julday, secofday;
+  int calendar = CALENDAR_STANDARD;
 
   /* 1 - Check valid range of years */
 
@@ -7354,39 +7446,31 @@ int main(void)
 {
   int i;
   int julday, secofday;
-  int year, month, day, hour, minute;
+  int year, month, day, hour, minute, second;
   int value = 30;
   int factor = 86400;
+  int calendar = CALENDAR_STANDARD;
 
-  year=1979; month=1; day=15; hour=12; minute=30;
+  year=1979; month=1; day=15; hour=12; minute=30, second=17;
 
-  printf("%d/%02d/%02d %02d:%02d\n", year, month, day, hour, minute);
+  printf("%d/%02d/%02d %02d:%02d:%02d\n", year, month, day, hour, minute, second);
 
-  encode_juldaysec(calendar, year, month, day, hour, minute, &julday, &secofday);
+  encode_juldaysec(calendar, year, month, day, hour, minute, second, &julday, &secofday);
 
-  decode_juldaysec(calendar, julday, secofday, &year, &month, &day, &hour, &minute);
-  printf("%d/%02d/%02d %02d:%02d   %d %d\n", year, month, day, hour, minute, julday, secofday);
+  decode_juldaysec(calendar, julday, secofday, &year, &month, &day, &hour, &minute, &second);
+  printf("%d/%02d/%02d %02d:%02d:%02d   %d %d\n", year, month, day, hour, minute, second, julday, secofday);
 
   for ( i = 0; i < 420; i++ )
     {
 
-      decode_juldaysec(calendar, julday, secofday, &year, &month, &day, &hour, &minute);
-      printf("%2d %d/%02d/%02d %02d:%02d\n", i, year, month, day, hour, minute);
+      decode_juldaysec(calendar, julday, secofday, &year, &month, &day, &hour, &minute, &second);
+      printf("%2d %d/%02d/%02d %02d:%02d:%02d\n", i, year, month, day, hour, minute, second);
       julday_add_seconds(value*factor, &julday, &secofday);
     }
 
   return (0);
 }
 #endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
 #include <stdio.h>
 
 
@@ -7899,9 +7983,9 @@ int modelInq(int instID, int modelgribID, char *name)
                   if ( modelptr->name )
                     {
                       len = strlen(modelptr->name);
-                      if ( memcmp(modelptr->name, name, len) == 0 ) break;
+                      if ( strncmp(modelptr->name, name, len) == 0 ) break;
                       len = strlen(name);
-                      if ( memcmp(modelptr->name, name, len) == 0 ) break;
+                      if ( strncmp(modelptr->name, name, len) == 0 ) break;
                     }
                 }
             }
@@ -9486,27 +9570,27 @@ void cdiPrintDatatypes(void)
   /* IsBigendian returns 1 for big endian byte order */
   static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
 
-  fprintf (stderr, "+-------------+-------+\n"); 
-  fprintf (stderr, "| types       | bytes |\n"); 
-  fprintf (stderr, "+-------------+-------+\n"); 
+  fprintf (stderr, "+-------------+-------+\n");
+  fprintf (stderr, "| types       | bytes |\n");
+  fprintf (stderr, "+-------------+-------+\n");
   fprintf (stderr, "| void *      |   %3d |\n", (int) sizeof(void *));
-  fprintf (stderr, "+-------------+-------+\n"); 
+  fprintf (stderr, "+-------------+-------+\n");
   fprintf (stderr, "| char        |   %3d |\n", (int) sizeof(char));
-  fprintf (stderr, "+-------------+-------+\n"); 
+  fprintf (stderr, "+-------------+-------+\n");
   fprintf (stderr, "| short       |   %3d |\n", (int) sizeof(short));
   fprintf (stderr, "| int         |   %3d |\n", (int) sizeof(int));
   fprintf (stderr, "| long        |   %3d |\n", (int) sizeof(long));
   fprintf (stderr, "| long long   |   %3d |\n", (int) sizeof(long long));
   fprintf (stderr, "| size_t      |   %3d |\n", (int) sizeof(size_t));
   fprintf (stderr, "| off_t       |   %3d |\n", (int) sizeof(off_t));
-  fprintf (stderr, "+-------------+-------+\n"); 
+  fprintf (stderr, "+-------------+-------+\n");
   fprintf (stderr, "| float       |   %3d |\n", (int) sizeof(float));
   fprintf (stderr, "| double      |   %3d |\n", (int) sizeof(double));
   fprintf (stderr, "| long double |   %3d |\n", (int) sizeof(long double));
-  fprintf (stderr, "+-------------+-------+\n\n"); 
+  fprintf (stderr, "+-------------+-------+\n\n");
 #define XSTRING(x)	#x
 #define STRING(x)	XSTRING(x)
-  fprintf (stderr, "+-------------+-----------+\n"); 
+  fprintf (stderr, "+-------------+-----------+\n");
   fprintf (stderr, "| INT32       | %-9s |\n", STRING(INT32));
   fprintf (stderr, "| INT64       | %-9s |\n", STRING(INT64));
   fprintf (stderr, "| FLT32       | %-9s |\n", STRING(FLT32));
@@ -9518,6 +9602,51 @@ void cdiPrintDatatypes(void)
   else
     fprintf (stderr, "\n  byte ordering is LITTLEENDIAN\n\n");
 }
+
+
+void uuid2str(const char *uuid, char *uuidstr)
+{
+  int iret;
+  unsigned int ui[16];
+
+  if ( uuid == NULL ) return;
+  if ( uuidstr == NULL ) return;
+
+  uuidstr[0] = 0;
+
+  for ( int i = 0; i < 16; ++i ) ui[i] = (unsigned char) uuid[i];
+
+  iret = sprintf(uuidstr, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+		 ui[0], ui[1], ui[2], ui[3], ui[4], ui[5], ui[6], ui[7],
+		 ui[8], ui[9], ui[10], ui[11], ui[12], ui[13], ui[14], ui[15]);
+
+  if ( iret != 36 ) uuidstr[0] = 0;
+}
+
+
+void str2uuid(const char *uuidstr, char *uuid)
+{
+  int iret;
+  unsigned int ui[16];
+
+  if ( uuid == NULL ) return;
+  if ( uuidstr == NULL ) return;
+
+  uuid[0] = 0;
+
+  if ( strlen(uuidstr) != 36 ) return;
+
+  iret = sscanf(uuidstr, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+		&ui[0], &ui[1], &ui[2], &ui[3], &ui[4], &ui[5], &ui[6], &ui[7],
+		&ui[8], &ui[9], &ui[10], &ui[11], &ui[12], &ui[13], &ui[14], &ui[15]);
+
+  if ( iret != 16 ) return;
+
+  for ( int i = 0; i < 16; ++i ) uuid[i] = ui[i];
+
+  uuid[16] = 0;
+}
+
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -9908,6 +10037,7 @@ typedef struct
   int         zaxistype;
   int         ltype;     /* GRIB level type */
   int         lbounds;
+  int         level_sf;
   int         zaxisID;
   int         nlevels;
   int         levelTableSize;
@@ -9944,6 +10074,8 @@ void paramInitEntry(int varID, int param)
   vartable[varID].gridID         = UNDEFID;
   vartable[varID].zaxistype      = 0;
   vartable[varID].ltype          = 0;
+  vartable[varID].lbounds        = 0;
+  vartable[varID].level_sf       = 0;
   vartable[varID].levelTable     = NULL;
   vartable[varID].levelTableSize = 0;
   vartable[varID].nlevels        = 0;
@@ -9961,7 +10093,7 @@ void paramInitEntry(int varID, int param)
 }
 
 static
-int varGetEntry(int param, int zaxistype, int ltype)
+int varGetEntry(int param, int zaxistype, int ltype, const char *name)
 {
   int varID;
 
@@ -9970,7 +10102,16 @@ int varGetEntry(int param, int zaxistype, int ltype)
       if ( vartable[varID].param     == param     &&
 	   vartable[varID].zaxistype == zaxistype &&
 	   vartable[varID].ltype     == ltype )
-	return (varID);
+        {
+          if ( name && name[0] && vartable[varID].name && vartable[varID].name[0] )
+            {
+              if ( strcmp(name, vartable[varID].name) == 0 ) return (varID);
+            }
+          else
+            {
+              return (varID);
+            }
+        }
     }
 
   return (UNDEFID);
@@ -10063,9 +10204,9 @@ int levelNewEntry(int varID, int level1, int level2)
 	levelTable[i].recID = UNDEFID;
     }
 
-  levelTable[levelID].level1 = level1;
-  levelTable[levelID].level2 = level2;
-  levelTable[levelID].lindex = levelID;
+  levelTable[levelID].level1   = level1;
+  levelTable[levelID].level2   = level2;
+  levelTable[levelID].lindex   = levelID;
 
   vartable[varID].nlevels = levelID+1;
   vartable[varID].levelTableSize = levelTableSize;
@@ -10135,7 +10276,7 @@ int paramNewEntry(int param)
 
 
 void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
-		  int level1, int level2, int prec,
+		  int level1, int level2, int level_sf, int prec,
 		  int *pvarID, int *plevelID, int tsteptype, int numavg, int ltype,
 		  const char *name, const char *longname, const char *units)
 {
@@ -10143,7 +10284,7 @@ void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
   int levelID = -1;
 
   if ( ! (cdiSplitLtype105 == 1 && zaxistype == ZAXIS_HEIGHT) )
-    varID = varGetEntry(param, zaxistype, ltype);
+    varID = varGetEntry(param, zaxistype, ltype, name);
 
   if ( varID == UNDEFID )
     {
@@ -10153,6 +10294,7 @@ void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
       vartable[varID].zaxistype = zaxistype;
       vartable[varID].ltype     = ltype;
       vartable[varID].lbounds   = lbounds;
+      vartable[varID].level_sf  = level_sf;
       if ( tsteptype != UNDEFID ) vartable[varID].tsteptype = tsteptype;
       if ( numavg ) vartable[varID].timave = 1;
 
@@ -10162,17 +10304,16 @@ void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
     }
   else
     {
+      char paramstr[32];
+      cdiParamToString(param, paramstr, sizeof(paramstr));
+
       if ( vartable[varID].gridID != gridID )
 	{
-	  char paramstr[32];
-	  cdiParamToString(param, paramstr, sizeof(paramstr));
 	  Message("param = %s gridID = %d", paramstr, gridID);
 	  Error("horizontal grid must not change for same param!");
 	}
       if ( vartable[varID].zaxistype != zaxistype )
 	{
-	  char paramstr[32];
-	  cdiParamToString(param, paramstr, sizeof(paramstr));
 	  Message("param = %s zaxistype = %d", paramstr, zaxistype);
 	  Error("zaxistype must not change for same param!");
 	}
@@ -10189,7 +10330,7 @@ void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
   *pvarID   = varID;
   *plevelID = levelID;
 }
-
+/*
 static
 int dblcmp(const void *s1, const void *s2)
 {
@@ -10200,7 +10341,7 @@ int dblcmp(const void *s1, const void *s2)
 
   return (cmp);
 }
-
+*/
 static
 int cmpLevelTable(const void *s1, const void *s2)
 {
@@ -10254,7 +10395,7 @@ int cmpltype(const void *s1, const void *s2)
 }
 
 
-void cdiGenVars(int streamID)
+void cdi_generate_vars(stream_t *streamptr)
 {
   int varID, gridID, zaxisID, levelID;
   int instID, modelID, tableID;
@@ -10270,11 +10411,9 @@ void cdiGenVars(int streamID)
   double *dlevels2 = NULL;
   int vlistID;
   int *varids, index, varid;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
+  double level_sf = 1;
 
-  vlistID =  streamInqVlist(streamID);
+  vlistID =  streamptr->vlistID;
 
   varids = (int *) malloc(nvars*sizeof(int));
   for ( varID = 0; varID < nvars; varID++ ) varids[varID] = varID;
@@ -10326,6 +10465,9 @@ void cdiGenVars(int streamID)
       timaccu   = vartable[varid].timaccu;
       comptype  = vartable[varid].comptype;
 
+      level_sf  = 1;
+      if ( vartable[varid].level_sf == 77 ) level_sf = 0.001;
+
       zaxisID = UNDEFID;
 
       if ( ltype == 0 && zaxistype == ZAXIS_GENERIC && nlevels == 1 &&
@@ -10336,11 +10478,11 @@ void cdiGenVars(int streamID)
 
       if ( lbounds && zaxistype != ZAXIS_HYBRID && zaxistype != ZAXIS_HYBRID_HALF )
 	for ( levelID = 0; levelID < nlevels; levelID++ )
-	  dlevels[levelID] = (vartable[varid].levelTable[levelID].level1 +
-	                      vartable[varid].levelTable[levelID].level2)/2;
+	  dlevels[levelID] = (level_sf*vartable[varid].levelTable[levelID].level1 +
+	                      level_sf*vartable[varid].levelTable[levelID].level2)/2;
       else
 	for ( levelID = 0; levelID < nlevels; levelID++ )
-	  dlevels[levelID] = vartable[varid].levelTable[levelID].level1;
+	  dlevels[levelID] = level_sf*vartable[varid].levelTable[levelID].level1;
 
       if ( nlevels > 1 )
 	{
@@ -10366,16 +10508,15 @@ void cdiGenVars(int streamID)
 		  /*
 		  qsort(dlevels, nlevels, sizeof(double), dblcmp);
 		  */
-		  qsort(vartable[varid].levelTable, nlevels, 
-			sizeof(leveltable_t), cmpLevelTable);
+		  qsort(vartable[varid].levelTable, nlevels, sizeof(leveltable_t), cmpLevelTable);
 
 		  if ( lbounds && zaxistype != ZAXIS_HYBRID && zaxistype != ZAXIS_HYBRID_HALF )
 		    for ( levelID = 0; levelID < nlevels; levelID++ )
-		      dlevels[levelID] = (vartable[varid].levelTable[levelID].level1 +
-					  vartable[varid].levelTable[levelID].level2)/2.;
+		      dlevels[levelID] = (level_sf*vartable[varid].levelTable[levelID].level1 +
+					  level_sf*vartable[varid].levelTable[levelID].level2)/2.;
 		  else
 		    for ( levelID = 0; levelID < nlevels; levelID++ )
-		      dlevels[levelID] = vartable[varid].levelTable[levelID].level1;
+		      dlevels[levelID] = level_sf*vartable[varid].levelTable[levelID].level1;
 		}
 	    }
 	}
@@ -10384,20 +10525,24 @@ void cdiGenVars(int streamID)
 	{
 	  dlevels1 = (double *) malloc(nlevels*sizeof(double));
 	  for ( levelID = 0; levelID < nlevels; levelID++ )
-	    dlevels1[levelID] = vartable[varid].levelTable[levelID].level1;
+	    dlevels1[levelID] = level_sf*vartable[varid].levelTable[levelID].level1;
 	  dlevels2 = (double *) malloc(nlevels*sizeof(double));
 	  for ( levelID = 0; levelID < nlevels; levelID++ )
-	    dlevels2[levelID] = vartable[varid].levelTable[levelID].level2;
+	    dlevels2[levelID] = level_sf*vartable[varid].levelTable[levelID].level2;
 	}
 
-      zaxisID = varDefZaxis(vlistID, zaxistype, nlevels, dlevels, lbounds, dlevels1, dlevels2,
-			    Vctsize, Vct, NULL, NULL, NULL, 0, 0, ltype);
+      if ( vartable[varid].level_sf == 77 )
+        zaxisID = varDefZaxis(vlistID, zaxistype, nlevels, dlevels, lbounds, dlevels1, dlevels2,
+                              Vctsize, Vct, NULL, NULL, "m", 0, 0, ltype);
+      else
+        zaxisID = varDefZaxis(vlistID, zaxistype, nlevels, dlevels, lbounds, dlevels1, dlevels2,
+                              Vctsize, Vct, NULL, NULL, NULL, 0, 0, ltype);
 
       if ( lbounds ) free(dlevels1);
       if ( lbounds ) free(dlevels2);
       free(dlevels);
 
-      varID = streamNewVar(streamID, gridID, zaxisID);
+      varID = stream_new_var(streamptr, gridID, zaxisID);
       varID = vlistDefVar(vlistID, gridID, zaxisID, tsteptype);
 
       vlistDefVarParam(vlistID, varID, param);
@@ -10467,8 +10612,7 @@ void cdiGenVars(int streamID)
       */
       for ( levelID = 0; levelID < nlevels; levelID++ )
 	{
-	  streamptr->vars[varID].level[levelID] =
-	    vartable[varid].levelTable[levelID].recID;
+	  streamptr->vars[varID].level[levelID] = vartable[varid].levelTable[levelID].recID;
 	  for ( lindex = 0; lindex < nlevels; lindex++ )
 	    if ( levelID == vartable[varid].levelTable[lindex].lindex ) break;
 
@@ -11015,6 +11159,16 @@ void vlistDestroy(int vlistID)
 
       if ( vlistptr->vars[varID].ensdata )  free(vlistptr->vars[varID].ensdata);
 
+      int i;
+      for (i=0; i<vlistptr->vars[varID].opt_grib_int_nentries; i++) {
+	if ( vlistptr->vars[varID].opt_grib_int_keyword[i] )
+	  free(vlistptr->vars[varID].opt_grib_int_keyword[i]);
+      }
+      for (i=0; i<vlistptr->vars[varID].opt_grib_dbl_nentries; i++) {
+	if ( vlistptr->vars[varID].opt_grib_dbl_keyword[i] )
+	  free(vlistptr->vars[varID].opt_grib_dbl_keyword[i]);
+      }
+
       vlistDelAtts(vlistID, varID);
     }
 
@@ -11081,6 +11235,26 @@ void vlistCopy(int vlistID2, int vlistID1)
                      vlistptr1->vars[varID].ensdata, sizeof(ensinfo_t));
             }
 
+          /* ---------------------------------- */
+          /* Local change: 2013-01-28, FP (DWD) */
+          /* ---------------------------------- */
+
+	  int i;
+	  vlistptr2->vars[varID].opt_grib_int_nentries = vlistptr1->vars[varID].opt_grib_int_nentries;
+	  for (i=0; i<vlistptr1->vars[varID].opt_grib_int_nentries; i++) {
+	    if ( vlistptr1->vars[varID].opt_grib_int_keyword[i] ) {
+	      vlistptr2->vars[varID].opt_grib_int_keyword[i] = strdupx(vlistptr1->vars[varID].opt_grib_int_keyword[i]);
+	      vlistptr2->vars[varID].opt_grib_int_val[i]     = vlistptr1->vars[varID].opt_grib_int_val[i];
+	    }
+	  }
+	  vlistptr2->vars[varID].opt_grib_dbl_nentries = vlistptr1->vars[varID].opt_grib_dbl_nentries;
+	  for (i=0; i<vlistptr1->vars[varID].opt_grib_dbl_nentries; i++) {
+	    if ( vlistptr1->vars[varID].opt_grib_dbl_keyword[i] ) {
+	      vlistptr2->vars[varID].opt_grib_dbl_keyword[i] = strdupx(vlistptr1->vars[varID].opt_grib_dbl_keyword[i]);
+	      vlistptr2->vars[varID].opt_grib_dbl_val[i]     = vlistptr1->vars[varID].opt_grib_dbl_val[i];
+	    }
+	  }
+
 	  vlistptr2->vars[varID].atts.nelems = 0;
 	  vlistCopyVarAtts(vlistID1, varID, vlistID2, varID);
 
@@ -11310,6 +11484,26 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
                        vlistptr1->vars[varID].ensdata, sizeof(ensinfo_t));
               }
 
+	    /* ---------------------------------- */
+	    /* Local change: 2013-01-28, FP (DWD) */
+	    /* ---------------------------------- */
+
+	    int i;
+	    vlistptr2->vars[varID2].opt_grib_int_nentries = vlistptr1->vars[varID].opt_grib_int_nentries;
+	    for (i=0; i<vlistptr1->vars[varID].opt_grib_int_nentries; i++) {
+	      if ( vlistptr1->vars[varID].opt_grib_int_keyword[i] ) {
+		vlistptr2->vars[varID2].opt_grib_int_keyword[i] = strdupx(vlistptr1->vars[varID].opt_grib_int_keyword[i]);
+		vlistptr2->vars[varID2].opt_grib_int_val[i]     = vlistptr1->vars[varID].opt_grib_int_val[i];
+	      }
+	    }
+	    vlistptr2->vars[varID2].opt_grib_dbl_nentries = vlistptr1->vars[varID].opt_grib_dbl_nentries;
+	    for (i=0; i<vlistptr1->vars[varID].opt_grib_dbl_nentries; i++) {
+	      if ( vlistptr1->vars[varID].opt_grib_dbl_keyword[i] ) {
+		vlistptr2->vars[varID2].opt_grib_dbl_keyword[i] = strdupx(vlistptr1->vars[varID].opt_grib_dbl_keyword[i]);
+		vlistptr2->vars[varID2].opt_grib_dbl_val[i]     = vlistptr1->vars[varID].opt_grib_dbl_val[i];
+	      }
+	    }
+
 	    vlistptr2->vars[varID2].atts.nelems = 0;
 	    vlistCopyVarAtts(vlistID1, varID, vlistID2, varID2);
 
@@ -11509,6 +11703,26 @@ void vlistCat(int vlistID2, int vlistID1)
           memcpy(vlistptr2->vars[varID2].ensdata, vlistptr1->vars[varID].ensdata, sizeof(ensinfo_t));
         }
 
+      /* ---------------------------------- */
+      /* Local change: 2013-01-28, FP (DWD) */
+      /* ---------------------------------- */
+
+      int i;
+      vlistptr2->vars[varID2].opt_grib_int_nentries = vlistptr1->vars[varID].opt_grib_int_nentries;
+      for (i=0; i<vlistptr1->vars[varID].opt_grib_int_nentries; i++) {
+	if ( vlistptr1->vars[varID].opt_grib_int_keyword[i] ) {
+	  vlistptr2->vars[varID2].opt_grib_int_keyword[i] = strdupx(vlistptr1->vars[varID].opt_grib_int_keyword[i]);
+	  vlistptr2->vars[varID2].opt_grib_int_val[i]     = vlistptr1->vars[varID].opt_grib_int_val[i];
+	}
+      }
+      vlistptr2->vars[varID2].opt_grib_dbl_nentries = vlistptr1->vars[varID].opt_grib_dbl_nentries;
+      for (i=0; i<vlistptr1->vars[varID].opt_grib_dbl_nentries; i++) {
+	if ( vlistptr1->vars[varID].opt_grib_dbl_keyword[i] ) {
+	  vlistptr2->vars[varID2].opt_grib_dbl_keyword[i] = strdupx(vlistptr1->vars[varID].opt_grib_dbl_keyword[i]);
+	  vlistptr2->vars[varID2].opt_grib_dbl_val[i]     = vlistptr1->vars[varID].opt_grib_dbl_val[i];
+	}
+      }
+
       vlistptr2->vars[varID2].atts.nelems = 0;
       vlistCopyVarAtts(vlistID1, varID, vlistID2, varID2);
 
@@ -13164,6 +13378,20 @@ void vlistvarInitEntry(int vlistID, int varID)
   vlistptr->vars[varID].iorank        = CDI_UNDEFID;
   vlistptr->vars[varID].decoSize      = 0;
   vlistptr->vars[varID].deco          = NULL;
+
+  /* ---------------------------------- */
+  /* Local change: 2013-01-28, FP (DWD) */
+  /* ---------------------------------- */
+
+  vlistptr->vars[varID].opt_grib_dbl_nentries = 0;
+  vlistptr->vars[varID].opt_grib_int_nentries = 0;
+  int i;
+  for (i=0; i<MAX_OPT_GRIB_ENTRIES; i++) {
+    vlistptr->vars[varID].opt_grib_dbl_val[i] = 0.0;
+    vlistptr->vars[varID].opt_grib_int_val[i] =   0;
+    vlistptr->vars[varID].opt_grib_int_keyword[i] = NULL;
+    vlistptr->vars[varID].opt_grib_dbl_keyword[i] = NULL;
+  } // for
 }
 
 static
@@ -13760,7 +13988,7 @@ void vlistInqVarStdname(int vlistID, int varID, char *stdname)
   if ( vlistptr->vars[varID].stdname == NULL )
     {
       stdname[0] = '\0';
-    }  
+    }
   else
     strcpy(stdname, vlistptr->vars[varID].stdname);
 
@@ -13775,7 +14003,7 @@ void vlistInqVarStdname(int vlistID, int varID, char *stdname)
 @Parameter
     @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
     @Item  varID    Variable identifier.
-    @Item  units    Units of the variable. The caller must allocate space for the 
+    @Item  units    Units of the variable. The caller must allocate space for the
                     returned string. The maximum possible length, in characters, of
                     the string is given by the predefined constant @func{CDI_MAX_NAME}.
 
@@ -14898,6 +15126,108 @@ int vlistInqVarEnsemble( int vlistID, int varID, int *ensID, int *ensCount, int
   return (status);
 }
 
+/* ---------------------------------- */
+/* Local change: 2013-01-28, FP (DWD) */
+/* ---------------------------------- */
+
+/* vlistDefVarIntKey: Set an arbitrary keyword/integer value pair for GRIB API */
+void vlistDefVarIntKey(int vlistID, int varID, const char *name, int value)
+{
+  vlist_t *vlistptr;
+  vlistptr = vlist_to_pointer(vlistID);
+
+  int idx = vlistptr->vars[varID].opt_grib_int_nentries;
+  vlistptr->vars[varID].opt_grib_int_nentries++;
+  if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/integer value pairs!");
+  vlistptr->vars[varID].opt_grib_int_val[idx] = value;
+  if ( name )
+    vlistptr->vars[varID].opt_grib_int_keyword[idx] = strdupx(name);
+  else
+    Error("Internal error!");
+}
+
+/* vlistDefVarDblKey: Set an arbitrary keyword/double value pair for GRIB API */
+void vlistDefVarDblKey(int vlistID, int varID, const char *name, double value)
+{
+  vlist_t *vlistptr;
+  vlistptr = vlist_to_pointer(vlistID);
+
+  int idx = vlistptr->vars[varID].opt_grib_dbl_nentries;
+  vlistptr->vars[varID].opt_grib_dbl_nentries++;
+  if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/double value pairs!");
+  vlistptr->vars[varID].opt_grib_dbl_val[idx] = value;
+  if ( name )
+    vlistptr->vars[varID].opt_grib_dbl_keyword[idx] = strdupx(name);
+  else
+    Error("Internal error!");
+}
+
+#if  defined  (HAVE_LIBGRIB_API)
+#endif
+
+/* vlistInqVarRawBegin: Open GRIB record to retrieve raw meta-data in subsequent calls */
+void vlistInqVarRawBegin(int streamID, int varID)
+{
+#if  defined  (HAVE_LIBGRIB_API)
+  stream_t *streamptr;
+  int       recID, tsID, fileID;
+  long      recpos, recsize;
+
+  streamptr = stream_to_pointer(streamID);
+  stream_check_ptr(__func__, streamptr);
+
+  fileID  = streamInqFileID(streamID);
+  tsID    = streamptr->curTsID;
+
+  // determine record ID for varID in current time step
+  for (recID=0; (recID<streamptr->tsteps[0].nrecs) && (varID != streamptr->tsteps[tsID].records[recID].varID); recID++);
+  recpos  = streamptr->tsteps[tsID].records[recID].position;
+  recsize = streamptr->tsteps[tsID].records[recID].size;
+
+  fileSetPos(fileID, recpos, SEEK_SET);
+  fileRead(fileID, streamptr->record->buffer, (size_t) recsize);
+
+  streamptr->gh = (void *) grib_handle_new_from_message(NULL, (void *) streamptr->record->buffer, recsize);
+#endif
+}
+
+
+/* vlistInqVarDblKey: raw access to GRIB meta-data */
+double vlistInqVarDblKey(int streamID, const char* name)
+{
+  double value = 0;
+#if  defined  (HAVE_LIBGRIB_API)
+  stream_t *streamptr = stream_to_pointer(streamID);
+  stream_check_ptr(__func__, streamptr);
+  GRIB_CHECK(grib_get_double((grib_handle*) streamptr->gh, name, &value), 0);
+#endif
+  return value;
+}
+
+
+/* vlistInqVarIntKey: raw access to GRIB meta-data */
+int vlistInqVarIntKey(int streamID, const char* name)
+{
+  long int value = 0;
+#if  defined  (HAVE_LIBGRIB_API)
+  stream_t *streamptr = stream_to_pointer(streamID);
+  stream_check_ptr(__func__, streamptr);
+  GRIB_CHECK(grib_get_long((grib_handle*) streamptr->gh, name, &value), 0);
+#endif
+  return (int) value;
+}
+
+
+/* vlistInqVarRawEnd: Free previously opened GRIB record */
+void vlistInqVarRawEnd(int streamID)
+{
+#if  defined  (HAVE_LIBGRIB_API)
+  stream_t *streamptr = stream_to_pointer(streamID);
+  stream_check_ptr(__func__, streamptr);
+  grib_handle_delete((grib_handle*) streamptr->gh);
+#endif
+}
+
 
 void vlistDefVarDeco ( int vlistID, int varID, int decoSize, deco_t * deco )
 {
@@ -15392,6 +15722,7 @@ void srvLibInit()
 	      }
 	    default:
 	      Message("Invalid character in %s: %s", envName, envString);
+	      break;
 	    }
 	  pos += 2;
 	}
@@ -15590,6 +15921,7 @@ int srvInqData(srvrec_t *srvp, int prec, void *data)
     default:
       {
 	Error("unexpected data precision %d", dprec);
+        break;
       }
     }
 
@@ -15678,6 +16010,7 @@ int srvDefData(srvrec_t *srvp, int prec, const void *data)
     default:
       {
 	Error("unexpected data precision %d", dprec);
+        break;
       }
     }
 
@@ -15753,6 +16086,7 @@ int srvRead(int fileID, srvrec_t *srvp)
     default:
       {
 	Error("unexpected header precision %d", hprec);
+        break;
       }
     }
 
@@ -15853,6 +16187,7 @@ int srvWrite(int fileID, srvrec_t *srvp)
     default:
       {
 	Error("unexpected header precision %d", hprec);
+        break;
       }
     }
   
@@ -15882,6 +16217,7 @@ int srvWrite(int fileID, srvrec_t *srvp)
     default:
       {
 	Error("unexpected data precision %d", dprec);
+        break;
       }
     }
 
@@ -15989,6 +16325,7 @@ void extLibInit()
 	      }
 	    default:
 	      Message("Invalid character in %s: %s", envName, envString);
+	      break;
 	    }
 	}
     }
@@ -16184,6 +16521,7 @@ int extInqData(void *ext, int prec, void *data)
     default:
       {
 	Error("unexpected data precision %d", rprec);
+        break;
       }
     }
 
@@ -16267,6 +16605,7 @@ int extDefData(void *ext, int prec, const void *data)
     default:
       {
 	Error("unexpected data precision %d", rprec);
+        break;
       }
     }
 
@@ -16342,6 +16681,7 @@ int extRead(int fileID, void *ext)
     default:
       {
 	Error("unexpected header precision %d", hprec);
+        break;
       }
     }
 
@@ -16450,6 +16790,7 @@ int extWrite(int fileID, void *ext)
     default:
       {
 	Error("unexpected header precision %d", rprec);
+        break;
       }
     }
   
@@ -16480,6 +16821,7 @@ int extWrite(int fileID, void *ext)
     default:
       {
 	Error("unexpected data precision %d", rprec);
+        break;
       }
     }
 
@@ -16567,6 +16909,7 @@ void iegLibInit()
 	      }
 	    default:
 	      Message("Invalid character in %s: %s", envName, envString);
+	      break;
 	    }
 	  pos += 2;
 	}
@@ -16766,6 +17109,7 @@ int iegInqData(iegrec_t *iegp, int prec, void *data)
     default:
       {
 	Error("unexpected data precision %d", dprec);
+        break;
       }
     }
 
@@ -16845,6 +17189,7 @@ int iegDefData(iegrec_t *iegp, int prec, const void *data)
     default:
       {
 	Error("unexpected data precision %d", dprec);
+        break;
       }
     }
 
@@ -17083,6 +17428,7 @@ int iegWrite(int fileID, iegrec_t *iegp)
     default:
       {
 	Error("unexpected data precision %d", dprec);
+        break;
       }
     }
 
@@ -19288,9 +19634,10 @@ void grid_check_cyclic(grid_t *gridptr)
       if ( xvals && xsize > 1 )
         {
           xinc = xvals[1] - xvals[0];
-          if ( IS_EQUAL(xinc, 0) )
-            xinc = (xvals[xsize-1] - xvals[0])/(xsize-1);
+          if ( IS_EQUAL(xinc, 0) ) xinc = (xvals[xsize-1] - xvals[0])/(xsize-1);
+
           x0 = 2*xvals[xsize-1]-xvals[xsize-2]-360;
+
           if ( IS_NOT_EQUAL(xvals[0], xvals[xsize-1]) )
             if ( fabs(x0 - xvals[0]) < 0.01*xinc ) gridptr->isCyclic = TRUE;
         }
@@ -19318,6 +19665,7 @@ void grid_check_cyclic(grid_t *gridptr)
 	      if ( valn <    1 && val1 > 300 ) valn += 360;
 	      if ( val1 < -179 && valn > 120 ) val1 += 360;
 	      if ( valn < -179 && val1 > 120 ) valn += 360;
+              if ( fabs(valn-val1) > 180 ) val1 += 360;
 
               if ( valn > val1 ) x0 = valn - xinc;
               else               x0 = valn + xinc;
@@ -19349,6 +19697,7 @@ void grid_check_cyclic(grid_t *gridptr)
 		      if ( val2 <    1 && val1 > 300 ) val2 += 360;
 		      if ( val1 < -179 && val2 > 120 ) val1 += 360;
 		      if ( val2 < -179 && val1 > 120 ) val2 += 360;
+                      if ( fabs(val2-val1) > 180 ) val1 += 360;
 
 		      if ( fabs(val1-val2) < 0.001 )
 			{
@@ -19635,37 +19984,36 @@ int gridCompareP ( void * gridptr1, void * gridptr2 )
   if ( g1->rowlon )
     {
       for ( i = 0; i < g1->nrowlon; i++ )
-	if ( g1->rowlon[i] != g2->rowlon[i] ) return differ; 
-    } 
+	if ( g1->rowlon[i] != g2->rowlon[i] ) return differ;
+    }
   else if ( g2->rowlon )
     return differ;
 
-  if ( g1->xfirst        != g2->xfirst        ) return differ;       
-  if ( g1->yfirst	 != g2->yfirst        ) return differ;
-  if ( g1->xlast         != g2->xlast         ) return differ;
-  if ( g1->ylast         != g2->ylast         ) return differ;
-  if ( g1->xinc	         != g2->xinc          ) return differ;
-  if ( g1->yinc	         != g2->yinc          ) return differ;
-  if ( g1->lcc_originLon != g2->lcc_originLon ) return differ;         
-  if ( g1->lcc_originLat != g2->lcc_originLat ) return differ;
-  if ( g1->lcc_lonParY   != g2->lcc_lonParY   ) return differ;
-  if ( g1->lcc_lat1      != g2->lcc_lat1      ) return differ;
-  if ( g1->lcc_lat2      != g2->lcc_lat2      ) return differ;
-  if ( g1->lcc_xinc      != g2->lcc_xinc      ) return differ;
-  if ( g1->lcc_yinc      != g2->lcc_yinc      ) return differ;
-  if ( g1->lcc2_lon_0    != g2->lcc2_lon_0    ) return differ;         
-  if ( g1->lcc2_lat_0    != g2->lcc2_lat_0    ) return differ;
-  if ( g1->lcc2_lat_1    != g2->lcc2_lat_1    ) return differ;
-  if ( g1->lcc2_lat_2    != g2->lcc2_lat_2    ) return differ;
-  if ( g1->lcc2_a        != g2->lcc2_a        ) return differ;
-  if ( g1->laea_lon_0    != g2->laea_lon_0    ) return differ;         
-  if ( g1->laea_lat_0    != g2->laea_lat_0    ) return differ;
-  if ( g1->laea_a        != g2->laea_a        ) return differ;
-  if ( g1->xpole         != g2->xpole         ) return differ;
-  if ( g1->ypole         != g2->ypole         ) return differ;
-  if ( g1->angle         != g2->angle         ) return differ; 
+  if ( IS_NOT_EQUAL(g1->xfirst        , g2->xfirst)        ) return differ;
+  if ( IS_NOT_EQUAL(g1->yfirst	      , g2->yfirst)        ) return differ;
+  if ( IS_NOT_EQUAL(g1->xlast         , g2->xlast)         ) return differ;
+  if ( IS_NOT_EQUAL(g1->ylast         , g2->ylast)         ) return differ;
+  if ( IS_NOT_EQUAL(g1->xinc	      , g2->xinc)          ) return differ;
+  if ( IS_NOT_EQUAL(g1->yinc	      , g2->yinc)          ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc_originLon , g2->lcc_originLon) ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc_originLat , g2->lcc_originLat) ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc_lonParY   , g2->lcc_lonParY)   ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc_lat1      , g2->lcc_lat1)      ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc_lat2      , g2->lcc_lat2)      ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc_xinc      , g2->lcc_xinc)      ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc_yinc      , g2->lcc_yinc)      ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc2_lon_0    , g2->lcc2_lon_0)    ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc2_lat_0    , g2->lcc2_lat_0)    ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc2_lat_1    , g2->lcc2_lat_1)    ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc2_lat_2    , g2->lcc2_lat_2)    ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc2_a        , g2->lcc2_a)        ) return differ;
+  if ( IS_NOT_EQUAL(g1->laea_lon_0    , g2->laea_lon_0)    ) return differ;
+  if ( IS_NOT_EQUAL(g1->laea_lat_0    , g2->laea_lat_0)    ) return differ;
+  if ( IS_NOT_EQUAL(g1->laea_a        , g2->laea_a)        ) return differ;
+  if ( IS_NOT_EQUAL(g1->xpole         , g2->xpole)         ) return differ;
+  if ( IS_NOT_EQUAL(g1->ypole         , g2->ypole)         ) return differ;
+  if ( IS_NOT_EQUAL(g1->angle         , g2->angle)         ) return differ;
 
-  
   if ( g1->xvals )
     {
       if ( g1->type == GRID_UNSTRUCTURED || g1->type == GRID_CURVILINEAR )
@@ -19677,11 +20025,11 @@ int gridCompareP ( void * gridptr1, void * gridptr2 )
       if ( !g2->xvals ) return differ;
 
       for ( i = 0; i < size; i++ )
-	if ( g1->xvals[i] != g2->xvals[i] ) return differ; 
-    } 
+	if ( IS_NOT_EQUAL(g1->xvals[i], g2->xvals[i]) ) return differ;
+    }
   else if ( g2->xvals )
     return differ;
-  
+
   if ( g1->yvals )
     {
       if ( g1->type == GRID_UNSTRUCTURED || g1->type == GRID_CURVILINEAR )
@@ -19693,11 +20041,11 @@ int gridCompareP ( void * gridptr1, void * gridptr2 )
       if ( !g2->yvals ) return differ;
 
       for ( i = 0; i < size; i++ )
-	  if ( g1->yvals[i] != g2->yvals[i] ) return differ;
-    } 
+        if ( IS_NOT_EQUAL(g1->yvals[i], g2->yvals[i]) ) return differ;
+    }
   else if ( g2->yvals )
     return differ;
-  
+
   if ( g1->area )
     {
       xassert ( g1->size );
@@ -19705,8 +20053,8 @@ int gridCompareP ( void * gridptr1, void * gridptr2 )
       if ( !g2->area ) return differ;
 
       for ( i = 0; i < g1->size; i++ )
-	if ( g1->area[i] != g2->area[i] ) return differ;
-    } 
+	if ( IS_NOT_EQUAL(g1->area[i], g2->area[i]) ) return differ;
+    }
   else if ( g2->area )
     return differ;
 
@@ -19722,8 +20070,8 @@ int gridCompareP ( void * gridptr1, void * gridptr2 )
       if ( !g2->xbounds ) return differ;
 
       for ( i = 0; i < size; i++ )
-	if ( g1->xbounds[i] != g2->xbounds[i] ) return differ;
-    } 
+	if ( IS_NOT_EQUAL(g1->xbounds[i], g2->xbounds[i]) ) return differ;
+    }
   else if ( g2->xbounds )
     return differ;
 
@@ -19739,34 +20087,25 @@ int gridCompareP ( void * gridptr1, void * gridptr2 )
       if ( !g2->ybounds ) return differ;
 
       for ( i = 0; i < size; i++ )
-	if ( g1->ybounds[i] != g2->ybounds[i] ) return differ;
-    } 
+	if ( IS_NOT_EQUAL(g1->ybounds[i], g2->ybounds[i]) ) return differ;
+    }
   else if ( g2->ybounds )
     return differ;
 
-  if ( memcmp ( &g1->xname    ,&g2->xname    ,CDI_MAX_NAME )) 
-    return differ;
-  if ( memcmp ( &g1->yname    ,&g2->yname    ,CDI_MAX_NAME )) 
-    return differ;
-  if ( memcmp ( &g1->xlongname,&g2->xlongname,CDI_MAX_NAME )) 
-    return differ;
-  if ( memcmp ( &g1->ylongname,&g2->ylongname,CDI_MAX_NAME )) 
-    return differ;
-  if ( memcmp ( &g1->xstdname ,&g2->xstdname ,CDI_MAX_NAME )) 
-    return differ;
-  if ( memcmp ( &g1->ystdname ,&g2->ystdname ,CDI_MAX_NAME )) 
-    return differ;
-  if ( memcmp ( &g1->xunits   ,&g2->xunits   ,CDI_MAX_NAME )) 
-    return differ;
-  if ( memcmp ( &g1->yunits   ,&g2->yunits   ,CDI_MAX_NAME )) 
-    return differ; 
+  if ( memcmp ( &g1->xname    ,&g2->xname    ,CDI_MAX_NAME ) ) return differ;
+  if ( memcmp ( &g1->yname    ,&g2->yname    ,CDI_MAX_NAME ) ) return differ;
+  if ( memcmp ( &g1->xlongname,&g2->xlongname,CDI_MAX_NAME ) ) return differ;
+  if ( memcmp ( &g1->ylongname,&g2->ylongname,CDI_MAX_NAME ) ) return differ;
+  if ( memcmp ( &g1->xstdname ,&g2->xstdname ,CDI_MAX_NAME ) ) return differ;
+  if ( memcmp ( &g1->ystdname ,&g2->ystdname ,CDI_MAX_NAME ) ) return differ;
+  if ( memcmp ( &g1->xunits   ,&g2->xunits   ,CDI_MAX_NAME ) ) return differ;
+  if ( memcmp ( &g1->yunits   ,&g2->yunits   ,CDI_MAX_NAME ) ) return differ;
 
   if ( g1->reference )
     {
       if ( !g2->reference ) return differ;
       size = strlen ( g1->reference ) + 1;
-      if ( memcmp ( g1->reference, g2->reference, size )) 
-	return differ;
+      if ( memcmp ( g1->reference, g2->reference, size ) ) return differ;
     }
   else if ( g2->reference )
     return differ;
@@ -19775,8 +20114,7 @@ int gridCompareP ( void * gridptr1, void * gridptr2 )
     {
       xassert ( g1->size );
       if ( !g2->mask ) return differ;
-      if ( memcmp ( g1->mask, g2->mask, g1->size * sizeof ( unsigned char ))) 
-	return differ;
+      if ( memcmp ( g1->mask, g2->mask, g1->size*sizeof(unsigned char)) ) return differ;
     }
   else if ( g2->mask )
     return differ;
@@ -19785,8 +20123,7 @@ int gridCompareP ( void * gridptr1, void * gridptr2 )
     {
       xassert ( g1->size );
       if ( !g2->mask_gme ) return differ;
-      if ( memcmp ( g1->mask_gme, g2->mask_gme, 
-		    g1->size * sizeof ( unsigned char ))) return differ;
+      if ( memcmp ( g1->mask_gme, g2->mask_gme, g1->size*sizeof(unsigned char)) ) return differ;
     }
   else if ( g2->mask_gme )
     return differ;
@@ -20527,7 +20864,7 @@ void gridPrintKernel(grid_t * gridptr, int opt, FILE *fp)
   int nbyte0, nbyte;
   int i;
   int nvertex, iv;
-  char uuid[17];
+  char uuidOfHGrid[17];
   int gridID = gridptr->self;
   const double *area    = gridInqAreaPtr(gridID);
   const double *xvals   = gridInqXvalsPtr(gridID);
@@ -20594,7 +20931,7 @@ void gridPrintKernel(grid_t * gridptr, int opt, FILE *fp)
 
 	if ( type == GRID_LAEA )
 	  {
-	    double a, lon_0, lat_0;
+	    double a = 0, lon_0 = 0, lat_0 = 0;
 	    gridInqLaea(gridID, &a, &lon_0, &lat_0);
 	    fprintf(fp, "a         = %g\n", a);
 	    fprintf(fp, "lon_0     = %g\n", lon_0);
@@ -20603,7 +20940,7 @@ void gridPrintKernel(grid_t * gridptr, int opt, FILE *fp)
 
 	if ( type == GRID_LCC2 )
 	  {
-	    double a, lon_0, lat_0, lat_1, lat_2;
+	    double a = 0, lon_0 = 0, lat_0 = 0, lat_1 = 0, lat_2 = 0;
 	    gridInqLcc2(gridID, &a, &lon_0, &lat_0, &lat_1, &lat_2);
 	    fprintf(fp, "a         = %g\n", a);
 	    fprintf(fp, "lon_0     = %g\n", lon_0);
@@ -20623,8 +20960,8 @@ void gridPrintKernel(grid_t * gridptr, int opt, FILE *fp)
 	  {
 	    double xfirst = 0.0, xinc = 0.0;
 
-	    if ( type == GRID_LONLAT     || type == GRID_GAUSSIAN || 
-		 type == GRID_GENERIC    || type == GRID_LCC2     || 
+	    if ( type == GRID_LONLAT     || type == GRID_GAUSSIAN ||
+		 type == GRID_GENERIC    || type == GRID_LCC2     ||
                  type == GRID_SINUSOIDAL || type == GRID_LAEA )
 	      {
 		xfirst = gridInqXval(gridID, 0);
@@ -20756,8 +21093,8 @@ void gridPrintKernel(grid_t * gridptr, int opt, FILE *fp)
       }
     case GRID_LCC:
       {
-	double originLon, originLat, lonParY, lat1, lat2, xincm, yincm;
-	int projflag, scanflag;
+	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);
 
@@ -20796,14 +21133,16 @@ void gridPrintKernel(grid_t * gridptr, int opt, FILE *fp)
       }
     case GRID_REFERENCE:
       {
-        const unsigned char *d;
+        // const unsigned char *d;
 	fprintf(fp, "number    = %d\n", gridInqNumber(gridID));
 	fprintf(fp, "position  = %d\n", gridInqPosition(gridID));
-        gridInqUUID(gridID, uuid);
-        d = (unsigned char *) &uuid;
+        /*
+        gridInqUUID(gridID, uuidOfHGrid);
+        d = (unsigned char *) &uuidOfHGrid;
 	fprintf(fp, "uuid      = %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", 
                 d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
                 d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
+        */
 	if ( gridInqReference(gridID, NULL) )
 	  {
 	    char reference_link[8192];
@@ -20815,9 +21154,19 @@ void gridPrintKernel(grid_t * gridptr, int opt, FILE *fp)
    default:
       {
 	fprintf(stderr, "Unsupported grid type: %s\n", gridNamePtr(type));
+        break;
       }
     }
 
+  gridInqUUID(gridID, uuidOfHGrid);
+  if ( uuidOfHGrid[0] != 0 )
+    {
+      char uuidOfHGridStr[37];
+      uuid2str(uuidOfHGrid, uuidOfHGridStr);
+      if ( uuidOfHGridStr[0] != 0 && strlen(uuidOfHGridStr) == 36 )
+        fprintf(fp, "uuid      = %s\n", uuidOfHGridStr);
+    }
+
   if ( gridptr->mask )
     {
       nbyte0 = fprintf(fp, "mask      = ");
@@ -21970,7 +22319,10 @@ ZaxistypeEntry[] = {
   { /* 13 */ 0, "toa",        "top_of_atmosphere", "",               ""},
   { /* 14 */ 0, "seabottom",  "sea_bottom",        "",               ""},
   { /* 15 */ 0, "atmosphere", "atmosphere",        "",               ""},
-  { /* 16 */ 0, "height",     "generalized height","height",         "m"},
+  { /* 16 */ 0, "cloudbase",  "cloud_base",        "",               ""},
+  { /* 17 */ 0, "cloudtop",   "cloud_top",         "",               ""},
+  { /* 18 */ 0, "isotherm0",  "isotherm_zero",     "",               ""},
+  { /* 19 */ 0, "height",     "generalized height","height",         "m"},
 };
 
 static int CDI_MaxZaxistype = sizeof(ZaxistypeEntry) / sizeof(ZaxistypeEntry[0]);
@@ -22104,6 +22456,9 @@ int zaxisSize(void)
     @Item  zaxistype  The type of the Z-axis, one of the set of predefined CDI Z-axis types.
                       The valid CDI Z-axis types are @func{ZAXIS_GENERIC}, @func{ZAXIS_SURFACE},
                       @func{ZAXIS_HYBRID}, @func{ZAXIS_SIGMA}, @func{ZAXIS_PRESSURE}, @func{ZAXIS_HEIGHT},
+                      @func{ZAXIS_ISENTROPIC}, @func{ZAXIS_ALTITUDE}, @func{ZAXIS_MEANSEA}, @func{ZAXIS_TOA},
+                      @func{ZAXIS_SEA_BOTTOM}, @func{ZAXIS_ATMOSPHERE}, @func{ZAXIS_CLOUD_BASE},
+                      @func{ZAXIS_CLOUD_TOP}, @func{ZAXIS_ISOTHERM_ZERO}, 
                       @func{ZAXIS_DEPTH_BELOW_SEA} and @func{ZAXIS_DEPTH_BELOW_LAND}.
     @Item  size       Number of levels.
 
@@ -22912,6 +23267,9 @@ The function @func{zaxisInqType} returns the type of a Z-axis.
 one of the set of predefined CDI Z-axis types.
 The valid CDI Z-axis types are @func{ZAXIS_GENERIC}, @func{ZAXIS_SURFACE},
 @func{ZAXIS_HYBRID}, @func{ZAXIS_SIGMA}, @func{ZAXIS_PRESSURE}, @func{ZAXIS_HEIGHT},
+ at func{ZAXIS_ISENTROPIC}, @func{ZAXIS_ALTITUDE}, @func{ZAXIS_MEANSEA}, @func{ZAXIS_TOA},
+ at func{ZAXIS_SEA_BOTTOM}, @func{ZAXIS_ATMOSPHERE}, @func{ZAXIS_CLOUD_BASE},
+ at func{ZAXIS_CLOUD_TOP}, @func{ZAXIS_ISOTHERM_ZERO}, 
 @func{ZAXIS_DEPTH_BELOW_SEA} and @func{ZAXIS_DEPTH_BELOW_LAND}.
 
 @EndFunction
@@ -23401,7 +23759,7 @@ int  zaxisCompareP ( void * zaxisptr1, void * zaxisptr2 )
       if ( !z2->vals ) return differ;
 
       for ( i = 0; i < z1->size; i++ )
-        if ( z1->vals[i] != z2->vals[i] ) return differ;
+        if ( IS_NOT_EQUAL(z1->vals[i], z2->vals[i]) ) return differ;
     }
   else if ( z2->vals )
     return differ;
@@ -23413,7 +23771,7 @@ int  zaxisCompareP ( void * zaxisptr1, void * zaxisptr2 )
       if ( !z2->lbounds ) return differ;
 
       for ( i = 0; i < z1->size; i++ )
-        if ( z1->lbounds[i] != z2->lbounds[i] ) return differ;
+        if ( IS_NOT_EQUAL(z1->lbounds[i], z2->lbounds[i]) ) return differ;
     }
   else if ( z2->lbounds )
     return differ;
@@ -23425,7 +23783,7 @@ int  zaxisCompareP ( void * zaxisptr1, void * zaxisptr2 )
       if ( !z2->ubounds ) return differ;
 
       for ( i = 0; i < z1->size; i++ )
-        if ( z1->ubounds[i] != z2->ubounds[i] ) return differ;
+        if ( IS_NOT_EQUAL(z1->ubounds[i], z2->ubounds[i]) ) return differ;
     }
   else if ( z2->ubounds )
     return differ;
@@ -23437,7 +23795,7 @@ int  zaxisCompareP ( void * zaxisptr1, void * zaxisptr2 )
       if ( !z2->weights ) return differ;
 
       for ( i = 0; i < z1->size; i++ )
-        if ( z1->weights[i] != z2->weights[i] ) return differ;
+        if ( IS_NOT_EQUAL(z1->weights[i], z2->weights[i]) ) return differ;
     }
   else if ( z2->weights )
     return differ;
@@ -23449,7 +23807,7 @@ int  zaxisCompareP ( void * zaxisptr1, void * zaxisptr2 )
       if ( !z2->vct ) return differ;
 
       for ( i = 0; i < z1->vctsize; i++ )
-        if ( z1->vct[i] != z2->vct[i] ) return differ;
+        if ( IS_NOT_EQUAL(z1->vct[i], z2->vct[i]) ) return differ;
     }
   else if ( z2->vct )
     return differ;
@@ -23909,8 +24267,7 @@ void cdf_close(int ncid)
 
   status = nc_close(ncid);
 
-  if ( status != NC_NOERR )
-    Error("%s", nc_strerror(status));
+  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
 
 
@@ -24219,6 +24576,13 @@ void cdf_put_vara_double(int ncid, int varid, const size_t start[],
   if ( CDF_Debug || status != NC_NOERR )
     Message("ncid = %d varid = %d val0 = %f", ncid, varid, *dp);
 
+  if ( status != NC_NOERR )
+    {
+      char name[256];
+      nc_inq_varname(ncid, varid, name);
+      Message("varname = %s", name);
+    }
+
   if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
 }
 
@@ -24293,7 +24657,7 @@ void  cdf_get_vara_text(int ncid, int varid, const size_t start[],
 }
 
 
-void cdf_put_var_double (int ncid, int varid, const double *dp)
+void cdf_put_var_double(int ncid, int varid, const double *dp)
 {
   int status;
 
@@ -24598,6 +24962,7 @@ void cdf_inq_attid(int ncid, int varid, const char *name, int *attnump)
 #if defined (HAVE_CONFIG_H)
 #endif
 
+#include <stdio.h>
 #include <string.h>
 #include <errno.h>
 
@@ -24765,6 +25130,7 @@ int cdiChunkType       = CHUNK_GRID;
 int cdiSplitLtype105   = CDI_UNDEFID;
 
 int cdiIgnoreAttCoordinates = FALSE;
+int cdiIgnoreValidRange     = FALSE;
 int cdiSkipRecords          = 0;
 int cdiInventoryMode        = 1;
 
@@ -24780,6 +25146,7 @@ char *Filetypes[] = {
   "netCDF",
   "netCDF2",
   "netCDF4",
+  "netCDF4c",
   "SERVICE",
   "EXTRA",
   "IEG",
@@ -24844,6 +25211,7 @@ long cdiGetenvInt(char *envName)
 		  fact = 0;
 		  Message("Invalid number string in %s: %s", envName, envString);
 		  Warning("%s must comprise only digits [0-9].",envName);
+		  break;
 		}
 	      break;
 	    }
@@ -24860,8 +25228,8 @@ long cdiGetenvInt(char *envName)
 static
 void cdiSetChunk(const char *chunkAlgo)
 {
-  char *pch;
-  size_t len = strlen(chunkAlgo);
+  //char *pch;
+  //size_t len = strlen(chunkAlgo);
   int algo = -1;
 
   if      ( strcmp("auto",  chunkAlgo)   == 0 ) algo = CHUNK_AUTO;
@@ -24939,6 +25307,9 @@ void cdiInitialize(void)
       envString = getenv("IGNORE_ATT_COORDINATES");
       if ( envString ) cdiIgnoreAttCoordinates = atoi(envString);
 
+      envString = getenv("IGNORE_VALID_RANGE");
+      if ( envString ) cdiIgnoreValidRange = atoi(envString);
+
       envString = getenv("CDI_SKIP_RECORDS");
       if ( envString )
 	{
@@ -25000,7 +25371,7 @@ char *strfiletype(int filetype)
   if ( filetype > 0 && filetype < size )
     name = Filetypes[filetype];
   else
-    name = Filetypes[0];  
+    name = Filetypes[0];
 
   return (name);
 }
@@ -25155,17 +25526,10 @@ double cdiInqMissval(void)
 }
 
 
-void cdiCheckContents(int streamID)
+void vlist_check_contents(int vlistID)
 {
   int index, nzaxis, zaxisID;
-  int vlistID;
-  stream_t *streamptr;
 
-  streamptr = ( stream_t *) reshGetVal ( streamID, &streamOps );
-
-  stream_check_ptr(__func__, streamptr);
-
-  vlistID = streamInqVlist(streamID);
   nzaxis = vlistNzaxis(vlistID);
 
   for ( index = 0; index < nzaxis; index++ )
@@ -25199,7 +25563,7 @@ void streamDefineTaxis(int streamID)
       int varID, nvars;
       int vlistID;
 
-      vlistID = streamInqVlist(streamID);
+      vlistID = streamptr->vlistID;
 
       nvars = vlistNvars(vlistID);
       for ( varID = 0; varID < nvars; varID++ )
@@ -25500,15 +25864,15 @@ void cdiPrintDefaults(void)
 
 void cdiDebug(int level)
 {
-  if ( level == 1 || level &  2 ) CDI_Debug = 1;
+  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 &  4) ) memDebug(1);
 
-  if ( level == 1 || level &  8 ) fileDebug(1);
+  if ( level == 1 || (level &  8) ) fileDebug(1);
 
-  if ( level == 1 || level & 16 )
+  if ( level == 1 || (level & 16) )
     {
 #if  defined  (HAVE_LIBGRIB)
       gribSetDebug(1);
@@ -25955,7 +26319,7 @@ char *streamFilename(int streamID)
   return (streamptr->filename);
 }
 
-
+static
 int cdiInqTimeSize(int streamID)
 {
   int ntsteps;
@@ -25976,18 +26340,13 @@ int cdiInqTimeSize(int streamID)
   return (ntsteps);
 }
 
-
-int cdiInqContents(int streamID)
+static
+int cdiInqContents(stream_t * streamptr)
 {
   int filetype;
   int vlistID;
   int taxisID;
   int status = 0;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   filetype = streamptr->filetype;
 
@@ -25997,28 +26356,28 @@ int cdiInqContents(int streamID)
     case FILETYPE_GRB:
     case FILETYPE_GRB2:
       {
-        status = grbInqContents(streamID);
+        status = grbInqContents(streamptr);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBSERVICE)
     case FILETYPE_SRV:
       {
-        status = srvInqContents(streamID);
+        status = srvInqContents(streamptr);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBEXTRA)
     case FILETYPE_EXT:
       {
-        status = extInqContents(streamID);
+        status = extInqContents(streamptr);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBIEG)
     case FILETYPE_IEG:
       {
-        status = iegInqContents(streamID);
+        status = iegInqContents(streamptr);
 	break;
       }
 #endif
@@ -26028,7 +26387,7 @@ int cdiInqContents(int streamID)
     case FILETYPE_NC4:
     case FILETYPE_NC4C:
       {
-        status = cdfInqContents(streamID);
+        status = cdfInqContents(streamptr);
 	break;
       }
 #endif
@@ -26038,12 +26397,13 @@ int cdiInqContents(int streamID)
 	  Message("%s support not compiled in!", strfiletype(filetype));
 
 	status = CDI_ELIBNAVAIL;
+        break;
       }
     }
 
   if ( status == 0 )
     {
-      vlistID = streamInqVlist(streamID);
+      vlistID = streamptr->vlistID;
       taxisID = vlistInqTaxis(vlistID);
       if ( taxisID != -1 )
         {
@@ -26198,7 +26558,7 @@ int streamOpen(const char *filename, const char *filemode, int filetype)
 
 	  streamptr->vlistID = vlistID;
 	  /* cdiReadByteorder(streamID); */
-	  status = cdiInqContents(streamID);
+	  status = cdiInqContents(streamptr);
 	  if ( status < 0 ) return (status);
 	  vlistptr = vlist_to_pointer(streamptr->vlistID);
 	  vlistptr->ntsteps = streamNtsteps(streamID);
@@ -26308,7 +26668,7 @@ int streamOpenA(const char *filename, const char *filemode, int filetype)
 
       streamptr->vlistID = vlistCreate();
       /* cdiReadByteorder(streamID); */
-      status = cdiInqContents(streamID);
+      status = cdiInqContents(streamptr);
       if ( status < 0 ) return (status);
       vlistptr = vlist_to_pointer(streamptr->vlistID);
       vlistptr->ntsteps = cdiInqTimeSize(streamID);
@@ -26627,7 +26987,7 @@ void streamClose(int streamID)
 	  case FILETYPE_GRB2:
 	    {
 	      gribClose(fileID);
-	      gribContainersDelete(streamID);
+	      gribContainersDelete(streamptr);
 	      break;
 	    }
 #endif
@@ -26772,7 +27132,7 @@ void streamSync(int streamID)
 
   fileID   = streamptr->fileID;
   filetype = streamptr->filetype;
-  vlistID  = streamInqVlist(streamID);
+  vlistID  = streamptr->vlistID;
   nvars    = vlistNvars(vlistID);
 
   if ( fileID == CDI_UNDEFID )
@@ -26842,7 +27202,7 @@ int streamDefTimestep(int streamID, int tsID)
 
   stream_check_ptr(__func__, streamptr);
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
 
   time_is_varying = vlistHasTime(vlistID);
 
@@ -26857,7 +27217,7 @@ int streamDefTimestep(int streamID, int tsID)
         }
     }
 
-  newtsID = tstepsNewEntry(streamID);
+  newtsID = tstepsNewEntry(streamptr);
 
   if ( tsID != newtsID )
     Error("Internal problem: tsID = %d newtsID = %d", tsID, newtsID);
@@ -26884,9 +27244,9 @@ int streamDefTimestep(int streamID, int tsID)
            streamptr->filetype == FILETYPE_NC4 ||
            streamptr->filetype == FILETYPE_NC4C)
        && time_is_varying )
-    cdfDefTimestep(streamID, tsID);
+    cdfDefTimestep(streamptr, tsID);
 
-  cdiCreateRecords(streamID, tsID);
+  cdi_create_records(streamptr, tsID);
 
   return (streamptr->ntsteps);
 }
@@ -26920,7 +27280,7 @@ int streamInqTimestep(int streamID, int tsID)
 
   stream_check_ptr(__func__, streamptr);
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
 
   if ( tsID < streamptr->rtsteps )
     {
@@ -26951,28 +27311,28 @@ int streamInqTimestep(int streamID, int tsID)
     case FILETYPE_GRB:
     case FILETYPE_GRB2:
       {
-        nrecs = grbInqTimestep(streamID, tsID);
+        nrecs = grbInqTimestep(streamptr, tsID);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBSERVICE)
     case FILETYPE_SRV:
       {
-        nrecs = srvInqTimestep(streamID, tsID);
+        nrecs = srvInqTimestep(streamptr, tsID);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBEXTRA)
     case FILETYPE_EXT:
       {
-        nrecs = extInqTimestep(streamID, tsID);
+        nrecs = extInqTimestep(streamptr, tsID);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBIEG)
     case FILETYPE_IEG:
       {
-        nrecs = iegInqTimestep(streamID, tsID);
+        nrecs = iegInqTimestep(streamptr, tsID);
 	break;
       }
 #endif
@@ -26982,7 +27342,7 @@ int streamInqTimestep(int streamID, int tsID)
     case FILETYPE_NC4:
     case FILETYPE_NC4C:
       {
-        nrecs = cdfInqTimestep(streamID, tsID);
+        nrecs = cdfInqTimestep(streamptr, tsID);
 	break;
       }
 #endif
@@ -27043,28 +27403,28 @@ void streamReadVar(int streamID, int varID, double *data, int *nmiss)
     case FILETYPE_GRB:
     case FILETYPE_GRB2:
       {
-        grbReadVarDP(streamID, varID, data, nmiss);
+        grbReadVarDP(streamptr, varID, data, nmiss);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBSERVICE)
     case FILETYPE_SRV:
       {
-        srvReadVarDP(streamID, varID, data, nmiss);
+        srvReadVarDP(streamptr, varID, data, nmiss);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBEXTRA)
     case FILETYPE_EXT:
       {
-        extReadVarDP(streamID, varID, data, nmiss);
+        extReadVarDP(streamptr, varID, data, nmiss);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBIEG)
     case FILETYPE_IEG:
       {
-        iegReadVarDP(streamID, varID, data, nmiss);
+        iegReadVarDP(streamptr, varID, data, nmiss);
 	break;
       }
 #endif
@@ -27074,7 +27434,7 @@ void streamReadVar(int streamID, int varID, double *data, int *nmiss)
     case FILETYPE_NC4:
     case FILETYPE_NC4C:
       {
-        cdfReadVarDP(streamID, varID, data, nmiss);
+        cdfReadVarDP(streamptr, varID, data, nmiss);
 	break;
       }
 #endif
@@ -27086,7 +27446,7 @@ void streamReadVar(int streamID, int varID, double *data, int *nmiss)
     }
 }
 
-
+static
 void stream_write_var(int streamID, int varID, int memtype, const void *data, int nmiss)
 {
   int filetype;
@@ -27133,8 +27493,7 @@ void stream_write_var(int streamID, int varID, int memtype, const void *data, in
     case FILETYPE_GRB:
     case FILETYPE_GRB2:
       {
-        if ( memtype == MEMTYPE_FLOAT ) Error("grbWriteVar not implemented for memtype float!");
-        grbWriteVarDP(streamID, varID, data, nmiss);
+        grb_write_var(streamptr, varID, memtype, data, nmiss);
 	break;
       }
 #endif
@@ -27142,7 +27501,7 @@ void stream_write_var(int streamID, int varID, int memtype, const void *data, in
     case FILETYPE_SRV:
       {
         if ( memtype == MEMTYPE_FLOAT ) Error("srvWriteVar not implemented for memtype float!");
-        srvWriteVarDP(streamID, varID, data);
+        srvWriteVarDP(streamptr, varID, data);
 	break;
       }
 #endif
@@ -27150,7 +27509,7 @@ void stream_write_var(int streamID, int varID, int memtype, const void *data, in
     case FILETYPE_EXT:
       {
         if ( memtype == MEMTYPE_FLOAT ) Error("extWriteVar not implemented for memtype float!");
-        extWriteVarDP(streamID, varID, data);
+        extWriteVarDP(streamptr, varID, data);
 	break;
       }
 #endif
@@ -27158,7 +27517,7 @@ void stream_write_var(int streamID, int varID, int memtype, const void *data, in
     case FILETYPE_IEG:
       {
         if ( memtype == MEMTYPE_FLOAT ) Error("iegWriteVar not implemented for memtype float!");
-        iegWriteVarDP(streamID, varID, data);
+        iegWriteVarDP(streamptr, varID, data);
 	break;
       }
 #endif
@@ -27168,8 +27527,8 @@ void stream_write_var(int streamID, int varID, int memtype, const void *data, in
     case FILETYPE_NC4:
     case FILETYPE_NC4C:
       {
-	if ( streamptr->accessmode == 0 ) cdfEndDef(streamID);
-        cdf_write_var(streamID, varID, memtype, data, nmiss);
+	if ( streamptr->accessmode == 0 ) cdfEndDef(streamptr);
+        cdf_write_var(streamptr, varID, memtype, data, nmiss);
 	break;
       }
 #endif
@@ -27266,28 +27625,28 @@ void streamReadVarSlice(int streamID, int varID, int levelID, double *data, int
     case FILETYPE_GRB:
     case FILETYPE_GRB2:
       {
-        grbReadVarSliceDP(streamID, varID, levelID, data, nmiss);
+        grbReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBSERVICE)
     case FILETYPE_SRV:
       {
-        srvReadVarSliceDP(streamID, varID, levelID, data, nmiss);
+        srvReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBEXTRA)
     case FILETYPE_EXT:
       {
-        extReadVarSliceDP(streamID, varID, levelID, data, nmiss);
+        extReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBIEG)
     case FILETYPE_IEG:
       {
-        iegReadVarSliceDP(streamID, varID, levelID, data, nmiss);
+        iegReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
 	break;
       }
 #endif
@@ -27298,7 +27657,7 @@ void streamReadVarSlice(int streamID, int varID, int levelID, double *data, int
     case FILETYPE_NC4C:
       {
         /* FIXME: status value ignored */
-        int ierr = cdfReadVarSliceDP(streamID, varID, levelID, data, nmiss);
+        int ierr = cdfReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
 	break;
       }
 #endif
@@ -27310,7 +27669,7 @@ void streamReadVarSlice(int streamID, int varID, int levelID, double *data, int
     }
 }
 
-
+static
 void stream_write_var_slice(int streamID, int varID, int levelID, int memtype, const void *data, int nmiss)
 {
   int filetype;
@@ -27332,8 +27691,7 @@ void stream_write_var_slice(int streamID, int varID, int levelID, int memtype, c
     case FILETYPE_GRB:
     case FILETYPE_GRB2:
       {
-        if ( memtype == MEMTYPE_FLOAT ) Error("grbWriteVarSlice not implemented for memtype float!");
-        grbWriteVarSliceDP(streamID, varID, levelID, data, nmiss);
+        grb_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
 	break;
       }
 #endif
@@ -27341,7 +27699,7 @@ void stream_write_var_slice(int streamID, int varID, int levelID, int memtype, c
     case FILETYPE_SRV:
       {
         if ( memtype == MEMTYPE_FLOAT ) Error("srvWriteVarSlice not implemented for memtype float!");
-        srvWriteVarSliceDP(streamID, varID, levelID, data);
+        srvWriteVarSliceDP(streamptr, varID, levelID, data);
 	break;
       }
 #endif
@@ -27349,7 +27707,7 @@ void stream_write_var_slice(int streamID, int varID, int levelID, int memtype, c
     case FILETYPE_EXT:
       {
         if ( memtype == MEMTYPE_FLOAT ) Error("extWriteVarSlice not implemented for memtype float!");
-        extWriteVarSliceDP(streamID, varID, levelID, data);
+        extWriteVarSliceDP(streamptr, varID, levelID, data);
 	break;
       }
 #endif
@@ -27357,7 +27715,7 @@ void stream_write_var_slice(int streamID, int varID, int levelID, int memtype, c
     case FILETYPE_IEG:
       {
         if ( memtype == MEMTYPE_FLOAT ) Error("iegWriteVarSlice not implemented for memtype float!");
-        iegWriteVarSliceDP(streamID, varID, levelID, data);
+        iegWriteVarSliceDP(streamptr, varID, levelID, data);
 	break;
       }
 #endif
@@ -27368,8 +27726,8 @@ void stream_write_var_slice(int streamID, int varID, int levelID, int memtype, c
     case FILETYPE_NC4C:
       {
         int ierr = 0;
-	if ( streamptr->accessmode == 0 ) cdfEndDef(streamID);
-        ierr = cdf_write_var_slice(streamID, varID, levelID, memtype, data, nmiss);
+	if ( streamptr->accessmode == 0 ) cdfEndDef(streamptr);
+        ierr = cdf_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
 	break;
       }
 #endif
@@ -27447,7 +27805,7 @@ void streamWriteContents(int streamID, char *cname)
 
   stream_check_ptr(__func__, streamptr);
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
 
   cnp = fopen(cname, "w");
 
@@ -27657,26 +28015,24 @@ void streamDefVlist(int streamID, int vlistID)
 	{
 	  gridID  = vlistInqVarGrid(vlistID, varID);
 	  zaxisID = vlistInqVarZaxis(vlistID, varID);
-	  streamNewVar(streamID, gridID, zaxisID);
+	  stream_new_var(streamptr, gridID, zaxisID);
 	  if ( streamptr->have_missval )
-	    vlistDefVarMissval(streamptr->vlistID, varID, 
-                               vlistInqVarMissval(vlistID, varID));
+	    vlistDefVarMissval(streamptr->vlistID, varID, vlistInqVarMissval(vlistID, varID));
 	}
 
-      if (namespaceHasLocalFile(namespaceGetActive())
-          && streamptr->filemode == 'w' )
+      if ( namespaceHasLocalFile(namespaceGetActive()) && streamptr->filemode == 'w' )
 	{
 	  if ( streamptr->filetype == FILETYPE_NC  ||
 	       streamptr->filetype == FILETYPE_NC2 ||
 	       streamptr->filetype == FILETYPE_NC4 ||
 	       streamptr->filetype == FILETYPE_NC4C )
 	    {
-	      cdfDefVars(streamID);
+	      cdfDefVars(streamptr);
 	    }
 	  else if ( streamptr->filetype == FILETYPE_GRB  ||
 		    streamptr->filetype == FILETYPE_GRB2 )
 	    {
-	      gribContainersNew(streamID);
+	      gribContainersNew(streamptr);
 	    }
 	}
     }
@@ -27817,7 +28173,7 @@ void streamDefHistory(int streamID, int length, const char *history)
 	  if ( len )
 	    {
 	      histstring = strdupx(history);
-	      cdfDefHistory(streamID, length, histstring);
+	      cdfDefHistory(streamptr, length, histstring);
 	      free(histstring);
 	    }
 	}
@@ -27837,7 +28193,7 @@ int streamInqHistorySize(int streamID)
        streamptr->filetype == FILETYPE_NC4 ||
        streamptr->filetype == FILETYPE_NC4C )
     {
-      size = cdfInqHistorySize(streamID);
+      size = cdfInqHistorySize(streamptr);
     }
 
   return (size);
@@ -27855,7 +28211,7 @@ void streamInqHistoryString(int streamID, char *history)
        streamptr->filetype == FILETYPE_NC4 ||
        streamptr->filetype == FILETYPE_NC4C )
     {
-      cdfInqHistoryString(streamID, history);
+      cdfInqHistoryString(streamptr, history);
     }
 }
 /*
@@ -27964,6 +28320,7 @@ int cgribexGetTimeUnit(int *isec1)
 	  Message("GRIB time unit %d unsupported!", ISEC1_TimeUnit);
 	  lprint = FALSE;
 	}
+      break;
     }
 
   return (timeunit);
@@ -27983,7 +28340,7 @@ int cgribexTimeIsFC(int *isec1)
 static
 int cgribexGetTsteptype(int timerange)
 {
-  int tsteptype = 0;
+  int tsteptype = TSTEP_INSTANT;
   static int lprint = TRUE;
 
   switch ( timerange )
@@ -28001,6 +28358,7 @@ int cgribexGetTsteptype(int timerange)
 	  Message("GRIB time range %d unsupported!", timerange);
 	  lprint = FALSE;
 	}
+      break;
     }
 
   return (tsteptype);
@@ -28047,6 +28405,7 @@ void cgribexGetGrid(stream_t *streamptr, int *isec2, int *isec4, grid_t *grid, i
 
 		if ( ISEC2_ResFlag && ISEC2_LonIncr > 0 )
                   {
+                    if ( ISEC2_LastLon < ISEC2_FirstLon && ISEC2_LastLon < 0 ) ISEC2_LastLon += 360000;
                     if ( abs(ISEC2_LastLon - (ISEC2_FirstLon+ISEC2_LonIncr*(grid->xsize-1))) <= 2 )
                       {
                         recompinc = FALSE;
@@ -28210,7 +28569,7 @@ void cgribexGetGrid(stream_t *streamptr, int *isec2, int *isec4, grid_t *grid, i
 }
 
 static
-void cgribexAddRecord(int streamID, int param, int *isec1, int *isec2, double *fsec2, double *fsec3,
+void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, double *fsec2, double *fsec3,
 		      int *isec4, long recsize, off_t position, int datatype, int comptype, int lmv, int iret)
 {
   int zaxistype;
@@ -28224,13 +28583,10 @@ void cgribexAddRecord(int streamID, int param, int *isec1, int *isec2, double *f
   record_t *record;
   grid_t grid;
   int vlistID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   tsID    = streamptr->curTsID;
-  recID   = recordNewEntry(streamID, tsID);
+  recID   = recordNewEntry(streamptr, tsID);
   record  = &streamptr->tsteps[tsID].records[recID];
 
   tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);
@@ -28267,7 +28623,7 @@ void cgribexAddRecord(int streamID, int param, int *isec1, int *isec2, double *f
   if ( datatype > 32 ) datatype = DATATYPE_PACK32;
   if ( datatype <  0 ) datatype = DATATYPE_PACK;
 
-  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2,
+  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, 0,
 	       datatype, &varID, &levelID, tsteptype, numavg, ISEC1_LevelType, NULL, NULL, NULL);
 
   (*record).varID   = varID;
@@ -28372,9 +28728,38 @@ void cgribexDecodeHeader(int *isec0, int *isec1, int *isec2, double *fsec2,
       *lmv = 1;
     }
 }
+
+static
+compvar_t cgribexVarSet(int param, int level1, int level2, int leveltype)
+{
+  compvar_t compVar;
+
+  compVar.param  = param;
+  compVar.level1 = level1;
+  compVar.level2 = level2;
+  compVar.ltype  = leveltype;
+
+  return (compVar);
+}
+
+static
+int cgribexVarCompare(compvar_t compVar, record_t record)
+{
+  int rstatus;
+  compvar_t compVar0;
+
+  compVar0.param  = record.param;
+  compVar0.level1 = record.ilevel;
+  compVar0.level2 = record.ilevel2;
+  compVar0.ltype  = record.ltype;
+
+  rstatus = memcmp(&compVar0, &compVar, sizeof(compvar_t));
+
+  return (rstatus);
+}
 #endif
 
-int cgribexScanTimestep1(int streamID)
+int cgribexScanTimestep1(stream_t * streamptr)
 {
 #if  defined  (HAVE_LIBCGRIBEX)
   int *isec0, *isec1, *isec2, *isec3, *isec4;
@@ -28392,6 +28777,7 @@ int cgribexScanTimestep1(int streamID)
   int varID;
   size_t readsize;
   int nrecords, nrecs, recID;
+  int nrecs_scanned;
   int datatype;
   long recsize = 0;
   int warn_time = TRUE;
@@ -28402,15 +28788,10 @@ int cgribexScanTimestep1(int streamID)
   int vlistID;
   int comptype;
   long unzipsize;
-  compvar_t compVar, compVar0;
-  stream_t *streamptr;
+  compvar_t compVar;
   extern int cdiSkipRecords;
   int nskip = cdiSkipRecords;
 
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
-
   streamptr->curTsID = 0;
 
   isec0 = streamptr->record->sec0;
@@ -28419,13 +28800,13 @@ int cgribexScanTimestep1(int streamID)
   isec3 = streamptr->record->sec3;
   isec4 = streamptr->record->sec4;
 
-  tsID  = tstepsNewEntry(streamID);
+  tsID  = tstepsNewEntry(streamptr);
   taxis = &streamptr->tsteps[tsID].taxis;
 
   if ( tsID != 0 )
     Error("Internal problem! tstepsNewEntry returns %d", tsID);
 
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
 
   while ( nskip-- > 0 )
     {
@@ -28437,6 +28818,7 @@ int cgribexScanTimestep1(int streamID)
       fileSetPos(fileID, recsize, SEEK_CUR);
     }
 
+  nrecs_scanned = 0;
   nrecs = 0;
   while ( TRUE )
     {
@@ -28473,6 +28855,7 @@ int cgribexScanTimestep1(int streamID)
 	    }
 	}
 
+      nrecs_scanned++;
       cgribexDecodeHeader(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
 			  (int *) gribbuffer, recsize, &lmv, &iret);
 
@@ -28502,18 +28885,12 @@ int cgribexScanTimestep1(int streamID)
 	{
 	  datetime.date  = vdate;
 	  datetime.time  = vtime;
-	  compVar.param  = param;
-          compVar.level1 = level1;
-          compVar.level2 = level2;
-          compVar.ltype  = ISEC1_LevelType;
+
+	  compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType);
+
 	  for ( recID = 0; recID < nrecs; recID++ )
 	    {
-	      compVar0.param  = streamptr->tsteps[0].records[recID].param;
-	      compVar0.level1 = streamptr->tsteps[0].records[recID].ilevel;
-	      compVar0.level2 = streamptr->tsteps[0].records[recID].ilevel2;
-	      compVar0.ltype  = streamptr->tsteps[0].records[recID].ltype;
-
-	      if ( memcmp(&compVar0, &compVar, sizeof(compvar_t)) == 0 ) break;
+	      if ( cgribexVarCompare(compVar, streamptr->tsteps[0].records[recID]) == 0 ) break;
 	    }
 
 	  if ( cdiInventoryMode == 1 )
@@ -28536,7 +28913,7 @@ int cgribexScanTimestep1(int streamID)
 		{
 		  char paramstr[32];
 		  cdiParamToString(param, paramstr, sizeof(paramstr));
-		  Warning("Param=%s level=%d already exist, skipped!", paramstr, level1);
+		  Warning("Param=%s level=%d (record %d) already exist, skipped!", paramstr, level1, nrecs_scanned);
 		  continue;
 		}
 	    }
@@ -28561,7 +28938,7 @@ int cgribexScanTimestep1(int streamID)
       if ( CDI_Debug )
 	Message("%4d %8d %4d  %8d %8d %6d", nrecs, (int)recpos, param, level1, vdate, vtime);
 
-      cgribexAddRecord(streamID, param, isec1, isec2, fsec2, fsec3,
+      cgribexAddRecord(streamptr, param, isec1, isec2, fsec2, fsec3,
 		       isec4, recsize, recpos, datatype, comptype, lmv, iret);
     }
 
@@ -28569,7 +28946,7 @@ int cgribexScanTimestep1(int streamID)
 
   if ( nrecs == 0 ) return (CDI_EUFSTRUCT);
 
-  cdiGenVars(streamID);
+  cdi_generate_vars(streamptr);
 
   if ( fcast )
     {
@@ -28589,7 +28966,7 @@ int cgribexScanTimestep1(int streamID)
   taxis->vdate = datetime0.date;
   taxis->vtime = datetime0.time;
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   vlistDefTaxis(vlistID, taxisID);
 
   nrecords = streamptr->tsteps[0].nallrecs;
@@ -28610,7 +28987,7 @@ int cgribexScanTimestep1(int streamID)
 
   if ( streamptr->ntsteps == -1 )
     {
-      tsID = tstepsNewEntry(streamID);
+      tsID = tstepsNewEntry(streamptr);
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
@@ -28637,7 +29014,7 @@ int cgribexScanTimestep1(int streamID)
 }
 
 
-int cgribexScanTimestep2(int streamID)
+int cgribexScanTimestep2(stream_t * streamptr)
 {
   int rstatus = 0;
 #if  defined  (HAVE_LIBCGRIBEX)
@@ -28662,12 +29039,7 @@ int cgribexScanTimestep2(int streamID)
   taxis_t *taxis;
   int vlistID;
   long unzipsize;
-  compvar_t compVar, compVar0;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
+  compvar_t compVar;
 
   streamptr->curTsID = 1;
 
@@ -28677,8 +29049,8 @@ int cgribexScanTimestep2(int streamID)
   isec3 = streamptr->record->sec3;
   isec4 = streamptr->record->sec4;
 
-  fileID  = streamInqFileID(streamID);
-  vlistID = streamInqVlist(streamID);
+  fileID  = streamptr->fileID;
+  vlistID = streamptr->vlistID;
   taxisID = vlistInqTaxis(vlistID);
 
   gribbuffer = (unsigned char *) streamptr->record->buffer;
@@ -28692,10 +29064,10 @@ int cgribexScanTimestep2(int streamID)
 
   fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-  cdiCreateRecords(streamID, tsID);
+  cdi_create_records(streamptr, tsID);
 
   nrecords = streamptr->tsteps[tsID].nallrecs;
-  streamptr->tsteps[1].recIDs = (int *) malloc(nrecords*sizeof(int));
+  if ( nrecords ) streamptr->tsteps[1].recIDs = (int *) malloc(nrecords*sizeof(int));
   streamptr->tsteps[1].nrecs = 0;
   for ( recID = 0; recID < nrecords; recID++ )
     streamptr->tsteps[1].recIDs[recID] = -1;
@@ -28791,18 +29163,12 @@ int cgribexScanTimestep2(int streamID)
 
       datetime.date  = vdate;
       datetime.time  = vtime;
-      compVar.param  = param;
-      compVar.level1 = level1;
-      compVar.level2 = level2;
-      compVar.ltype  = ISEC1_LevelType;
+
+      compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType);
+
       for ( recID = 0; recID < nrecords; recID++ )
 	{
-	  compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
-	  compVar0.level1 = streamptr->tsteps[tsID].records[recID].ilevel;
-	  compVar0.level2 = streamptr->tsteps[tsID].records[recID].ilevel2;
-	  compVar0.ltype  = streamptr->tsteps[tsID].records[recID].ltype;
-
-	  if ( memcmp(&compVar0, &compVar, sizeof(compvar_t)) == 0 ) break;
+	  if ( cgribexVarCompare(compVar, streamptr->tsteps[tsID].records[recID]) == 0 ) break;
 	}
 
       if ( recID == nrecords )
@@ -28849,12 +29215,7 @@ int cgribexScanTimestep2(int streamID)
 
       streamptr->tsteps[tsID].records[recID].size = recsize;
 
-      compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
-      compVar0.level1 = streamptr->tsteps[tsID].records[recID].ilevel;
-      compVar0.level2 = streamptr->tsteps[tsID].records[recID].ilevel2;
-      compVar0.ltype  = streamptr->tsteps[tsID].records[recID].ltype;
-
-      if ( memcmp(&compVar0, &compVar, sizeof(compvar_t)) != 0 )
+      if ( cgribexVarCompare(compVar, streamptr->tsteps[tsID].records[recID]) != 0 )
 	{
 	  Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
 		  tsID, recID,
@@ -28898,7 +29259,7 @@ int cgribexScanTimestep2(int streamID)
 
   if ( streamptr->ntsteps == -1 )
     {
-      tsID = tstepsNewEntry(streamID);
+      tsID = tstepsNewEntry(streamptr);
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
@@ -28914,7 +29275,7 @@ int cgribexScanTimestep2(int streamID)
 }
 
 
-int cgribexScanTimestep(int streamID)
+int cgribexScanTimestep(stream_t * streamptr)
 {
   int rstatus = 0;
 #if  defined  (HAVE_LIBCGRIBEX)
@@ -28938,18 +29299,13 @@ int cgribexScanTimestep(int streamID)
   int vlistID;
   int rindex, nrecs = 0;
   long unzipsize;
-  compvar_t compVar, compVar0;
-  stream_t *streamptr;
+  compvar_t compVar;
 
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
-
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
 
   if ( CDI_Debug )
     {
-      Message("streamID = %d", streamID);
+      Message("streamID = %d", streamptr->self);
       Message("cts = %d", streamptr->curTsID);
       Message("rts = %d", streamptr->rtsteps);
       Message("nts = %d", streamptr->ntsteps);
@@ -28969,7 +29325,7 @@ int cgribexScanTimestep(int streamID)
       gribbuffer = (unsigned char *) streamptr->record->buffer;
       buffersize = streamptr->record->buffersize;
 
-      cdiCreateRecords(streamID, tsID);
+      cdi_create_records(streamptr, tsID);
 
       nrecs = streamptr->tsteps[1].nrecs;
 
@@ -28978,7 +29334,7 @@ int cgribexScanTimestep(int streamID)
       for ( recID = 0; recID < nrecs; recID++ )
 	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
 
-      fileID = streamInqFileID(streamID);
+      fileID = streamptr->fileID;
 
       fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
@@ -29074,19 +29430,13 @@ int cgribexScanTimestep(int streamID)
 
 	  datetime.date  = vdate;
 	  datetime.time  = vtime;
-	  compVar.param  = param;
-          compVar.level1 = level1;
-          compVar.level2 = level2;
-          compVar.ltype  = ISEC1_LevelType;
+
+	  compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType);
+
 	  for ( vrecID = 0; vrecID < nrecs; vrecID++ )
 	    {
 	      recID   = streamptr->tsteps[1].recIDs[vrecID];
-	      compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
-	      compVar0.level1 = streamptr->tsteps[tsID].records[recID].ilevel;
-	      compVar0.level2 = streamptr->tsteps[tsID].records[recID].ilevel2;
-	      compVar0.ltype  = streamptr->tsteps[tsID].records[recID].ltype;
-
-	      if ( memcmp(&compVar0, &compVar, sizeof(compvar_t)) == 0 ) break;
+	      if ( cgribexVarCompare(compVar, streamptr->tsteps[tsID].records[recID]) == 0 ) break;
 	    }
 
 	  if ( vrecID == nrecs )
@@ -29130,12 +29480,7 @@ int cgribexScanTimestep(int streamID)
 	  if ( CDI_Debug )
 	    Message("%4d %8d %4d %8d %8d %6d", rindex+1, (int)recpos, param, level1, vdate, vtime);
 
-	  compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
-	  compVar0.level1 = streamptr->tsteps[tsID].records[recID].ilevel;
-	  compVar0.level2 = streamptr->tsteps[tsID].records[recID].ilevel2;
-	  compVar0.ltype  = streamptr->tsteps[tsID].records[recID].ltype;
-
-	  if ( memcmp(&compVar0, &compVar, sizeof(compvar_t)) != 0 )
+	  if ( cgribexVarCompare(compVar, streamptr->tsteps[tsID].records[recID]) != 0 )
 	    {
 	      Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
 		      tsID, recID,
@@ -29172,7 +29517,7 @@ int cgribexScanTimestep(int streamID)
 
       if ( streamptr->ntsteps != streamptr->rtsteps )
 	{
-	  tsID = tstepsNewEntry(streamID);
+	  tsID = tstepsNewEntry(streamptr);
 	  if ( tsID != streamptr->rtsteps )
 	    Error("Internal error. tsID = %d", tsID);
 
@@ -29352,11 +29697,11 @@ int cgribexDefTimerange(int tsteptype, int factor, int calendar,
 
   cdiDecodeDate(rdate, &year, &month, &day);
   cdiDecodeTime(rtime, &hour, &minute, &second);
-  encode_juldaysec(calendar, year, month, day, hour, minute, &julday1, &secofday1);
+  encode_juldaysec(calendar, year, month, day, hour, minute, second, &julday1, &secofday1);
 
   cdiDecodeDate(vdate, &year, &month, &day);
   cdiDecodeTime(vtime, &hour, &minute, &second);
-  encode_juldaysec(calendar, year, month, day, hour, minute, &julday2, &secofday2);
+  encode_juldaysec(calendar, year, month, day, hour, minute, second, &julday2, &secofday2);
 
   (void) julday_sub(julday1, secofday1, julday2, secofday2, &days, &secs);
 
@@ -29749,6 +30094,7 @@ void cgribexDefGrid(int *isec1, int *isec2, int *isec4, int gridID)
       {
 	Warning("The CGRIBEX library can not store fields on the used grid!");
 	Error("Unsupported grid type: %s", gridNamePtr(gridtype));
+	break;
       }
     }
 }
@@ -29785,6 +30131,27 @@ void cgribexDefLevel(int *isec1, int *isec2, double *fsec2, int zaxisID, int lev
 	ISEC1_Level2    = 0;
 	break;
       }
+    case ZAXIS_CLOUD_BASE:
+      {
+	ISEC1_LevelType = GRIB1_LTYPE_CLOUDBASE;
+	ISEC1_Level1    = 0;
+	ISEC1_Level2    = 0;
+	break;
+      }
+    case ZAXIS_CLOUD_TOP:
+      {
+	ISEC1_LevelType = GRIB1_LTYPE_CLOUDTOP;
+	ISEC1_Level1    = 0;
+	ISEC1_Level2    = 0;
+	break;
+      }
+    case ZAXIS_ISOTHERM_ZERO:
+      {
+	ISEC1_LevelType = GRIB1_LTYPE_ISOTHERM0;
+	ISEC1_Level1    = 0;
+	ISEC1_Level2    = 0;
+	break;
+      }
     case ZAXIS_TOA:
       {
 	ISEC1_LevelType = GRIB1_LTYPE_TOA;
@@ -30137,6 +30504,7 @@ size_t cgribexEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
 #if  defined  (HAVE_LIBGRIB_API)
 #endif
 
+#define  NINT(x)  ((x) < 0 ? (int)((x)-.5) : (int)((x)+.5))
 
 extern int cdiInventoryMode;
 
@@ -30145,6 +30513,7 @@ typedef struct {
   int level1;
   int level2;
   int ltype;
+  char name[32];
 } compvar2_t;
 
 
@@ -30153,12 +30522,14 @@ static
 int gribapiGetGridType(grib_handle *gh)
 {
   int gridtype = GRID_GENERIC;
-  int gribgridtype;
+  int gribgridtype = -1;
   long lpar;
 
     {
-      GRIB_CHECK(grib_get_long(gh, "gridDefinitionTemplateNumber", &lpar), 0);
-      gribgridtype = (int) lpar;
+      int status;
+      status = grib_get_long(gh, "gridDefinitionTemplateNumber", &lpar);
+
+      if ( status ==  0 ) gribgridtype = (int) lpar;
 
       switch (gribgridtype)
 	{
@@ -30187,15 +30558,15 @@ static
 int gribapiGetIsRotated(grib_handle *gh)
 {
   int isRotated = 0;
-  int gribgridtype;
+  int gribgridtype = -1;
   long lpar;
+  int status;
 
-    {
-      GRIB_CHECK(grib_get_long(gh, "gridDefinitionTemplateNumber", &lpar), 0);
-      gribgridtype = (int) lpar;
+  status = grib_get_long(gh, "gridDefinitionTemplateNumber", &lpar);
 
-      if ( gribgridtype == GRIB2_GTYPE_LATLON_ROT ) isRotated = 1;
-    }
+  if ( status ==  0 ) gribgridtype = (int) lpar;
+
+  if ( gribgridtype == GRIB2_GTYPE_LATLON_ROT ) isRotated = 1;
 
   return (isRotated);
 }
@@ -30260,34 +30631,16 @@ double timeunit_factor(int tu1, int tu2)
 }
 
 static
-int gribapiGetEndStep(grib_handle *gh, int startStep, int timeunits)
-{
-  int endStep = startStep;
-  int timeunits2;
-  long unitsOfTime;
-  long lpar;
-
-  GRIB_CHECK(grib_get_long(gh, "stepUnits", &unitsOfTime), 0);
-
-  timeunits2 = getTimeunits(unitsOfTime);
-
-  GRIB_CHECK(grib_get_long(gh, "endStep", &lpar), 0);
-
-  endStep = (int)  ((lpar * timeunit_factor(timeunits, timeunits2)) + 0.5);
-
-  return (endStep);
-}
-
-static
 int gribapiGetTimeUnits(grib_handle *gh)
 {
   int timeunits = -1;
-  long unitsOfTime;
+  long unitsOfTime = -1;
+  int status;
   // size_t len = 8;
   //char stepunits[8];
   //static int lprint = TRUE;
 
-  GRIB_CHECK(grib_get_long(gh, "indicatorOfUnitOfTimeRange", &unitsOfTime), 0);
+  status = grib_get_long(gh, "indicatorOfUnitOfTimeRange", &unitsOfTime);
 
   timeunits = getTimeunits(unitsOfTime);
 
@@ -30316,6 +30669,29 @@ int gribapiGetTimeUnits(grib_handle *gh)
 }
 
 static
+int gribapiGetEndStep(grib_handle *gh, int startStep, int timeunits)
+{
+  int endStep = startStep;
+  int timeunits2;
+  int status;
+  long unitsOfTime;
+  long lpar;
+
+  // status = grib_get_long(gh, "stepUnits", &unitsOfTime);
+
+  // timeunits2 = getTimeunits(unitsOfTime);
+  timeunits2 = gribapiGetTimeUnits(gh);
+
+  status = grib_get_long(gh, "endStep", &lpar);
+
+  if ( status == 0 )
+    endStep = (int) ((lpar * timeunit_factor(timeunits, timeunits2)) + 0.5);
+  // printf("%d %d %d %d %d %g\n", startStep, endStep, lpar, timeunits, timeunits2, timeunit_factor(timeunits, timeunits2));
+
+  return (endStep);
+}
+
+static
 int gribapiTimeIsFC(grib_handle *gh)
 {
   long editionNumber;
@@ -30374,12 +30750,31 @@ int gribapiGetTsteptype(grib_handle *gh)
 }
 
 static
+void gribapiGetDataDateTime(grib_handle *gh, int *datadate, int *datatime)
+{
+  long lpar;
+
+  GRIB_CHECK(grib_get_long(gh, "dataDate", &lpar), 0);
+  *datadate = (int) lpar;
+  GRIB_CHECK(grib_get_long(gh, "dataTime", &lpar), 0);
+  *datatime = (int) lpar*100;
+}
+
+static
+void gribapiSetDataDateTime(grib_handle *gh, int datadate, int datatime)
+{
+  GRIB_CHECK(grib_set_long(gh, "dataDate", datadate), 0);
+  GRIB_CHECK(grib_set_long(gh, "dataTime", datatime/100), 0);
+}
+
+static
 int gribapiGetValidityDateTime(grib_handle *gh, int *vdate, int *vtime)
 {
   int rdate, rtime;
-  int timeUnits, startStep, endStep;
+  int timeUnits, startStep = 0, endStep;
   int tstepRange = 0;
   int range;
+  int status;
   long lpar;
   long sigofrtime = 3;
   long editionNumber;
@@ -30393,19 +30788,14 @@ int gribapiGetValidityDateTime(grib_handle *gh, int *vdate, int *vtime)
 
   if ( sigofrtime == 3 )
     {
-      GRIB_CHECK(grib_get_long(gh, "dataDate", &lpar), 0);
-      *vdate = (int) lpar;
-      GRIB_CHECK(grib_get_long(gh, "dataTime", &lpar), 0);
-      *vtime = (int) lpar*100;
+      gribapiGetDataDateTime(gh, vdate, vtime);
     }
   else
     {
-      GRIB_CHECK(grib_get_long(gh, "dataDate", &lpar), 0);
-      rdate = (int) lpar;
-      GRIB_CHECK(grib_get_long(gh, "dataTime", &lpar), 0);
-      rtime = (int) lpar*100;
-      GRIB_CHECK(grib_get_long(gh, "forecastTime", &lpar), 0);
-      startStep = (int) lpar;
+      gribapiGetDataDateTime(gh, &rdate, &rtime);
+
+      status = grib_get_long(gh, "forecastTime", &lpar);
+      if ( status == 0 ) startStep = (int) lpar;
       timeUnits = gribapiGetTimeUnits(gh);
       endStep = gribapiGetEndStep(gh, startStep, timeUnits);
 
@@ -30445,14 +30835,13 @@ int gribapiGetValidityDateTime(grib_handle *gh, int *vdate, int *vtime)
 	        Warning("Time unit %d unsupported", timeUnits);
 		lprint = FALSE;
 	      }
+	    break;
 	  }
 
 	julday_add_seconds(addsec, &julday, &secofday);
 
 	decode_caldaysec(grib_calendar, julday, secofday, &ryear, &rmonth, &rday, &rhour, &rminute, &rsecond);
-	/*
-	  printf("new %d/%d/%d %d:%d\n", ryear, rmonth, rday, rhour, rminute);
-	*/
+
 	*vdate = cdiEncodeDate(ryear, rmonth, rday);
 	*vtime = cdiEncodeTime(rhour, rminute, rsecond);
       }
@@ -30505,8 +30894,7 @@ void gribapiGetGrid(grib_handle *gh, grid_t *grid)
           }
 
 	if ( numberOfPoints != nlon*nlat )
-	  Error("numberOfPoints (%d) and gridSize (%d) differ!",
-		(int)numberOfPoints, nlon*nlat);
+	  Error("numberOfPoints (%d) and gridSize (%d) differ!", (int)numberOfPoints, nlon*nlat);
 
 	grid->size  = numberOfPoints;
 	grid->xsize = nlon;
@@ -30683,27 +31071,26 @@ void gribapiGetGrid(grib_handle *gh, grid_t *grid)
     case GRID_REFERENCE:
       {
         char uuid[17];
-	char reference_link[8192];
-	size_t len = sizeof(reference_link);
-	reference_link[0] = 0;
+    	char reference_link[8192];
+        size_t len = sizeof(reference_link);
+        reference_link[0] = 0;
 
-	grid->size  = numberOfPoints;
-	if ( grib_get_long(gh, "numberOfGridUsed", &lpar) == 0 )
-	  {
-	    grid->number   = lpar;
-	    if ( grib_get_long(gh, "numberOfGridInReference", &lpar) == 0 ) grid->position = lpar;
-	    if ( grib_get_string(gh, "gridDescriptionFile", reference_link, &len) == 0 )
-	      {
-		if ( strncmp(reference_link, "file://", 7) == 0 )
-		  grid->reference = strdupx(reference_link);
-	      }
+    	grid->size  = numberOfPoints;
+        if ( grib_get_long(gh, "numberOfGridUsed", &lpar) == 0 )
+          {
+            grid->number   = lpar;
+            if ( grib_get_long(gh, "numberOfGridInReference", &lpar) == 0 ) grid->position = lpar;
+            if ( grib_get_string(gh, "gridDescriptionFile", reference_link, &len) == 0 )
+              {
+                if ( strncmp(reference_link, "file://", 7) == 0 )
+                  grid->reference = strdupx(reference_link);
+              }
             len = (size_t) 16;
-            if ( grib_get_string(gh, "uuidOfHGrid", uuid, &len) == 0)
+            if ( grib_get_bytes(gh, "uuidOfHGrid", (unsigned char *) uuid, &len) == 0)
               {
                 strncpy(grid->uuid, uuid, 16);
               }
-	  }
-
+          }
 	break;
       }
     case GRID_GENERIC:
@@ -30798,7 +31185,7 @@ void grib1GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, i
 }
 
 static
-void grib2GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, int *level2)
+void grib2GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, int *level2, int *level_sf)
 {
   int status;
   int leveltype2 = -1;
@@ -30810,6 +31197,7 @@ void grib2GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, i
   *lbounds = 0;
   *level1  = 0;
   *level2  = 0;
+  *level_sf = 0;
 
   status = grib_get_long(gh, "typeOfFirstFixedSurface", &lpar);
   if ( status == 0 )
@@ -30827,9 +31215,11 @@ void grib2GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, i
 	    {
 	      GRIB_CHECK(grib_get_long(gh, "scaleFactorOfFirstFixedSurface", &factor), 0);
 	      GRIB_CHECK(grib_get_double(gh, "scaledValueOfFirstFixedSurface", &dlevel), 0);
-	      if      ( factor == 0 ) dlevel *= 100;   //  m to cm
-	      else if ( factor == 1 ) dlevel *=  10;   // dm to cm
-	      else if ( factor == 3 ) dlevel *=   0.1; // mm to cm
+	      if      ( factor == 0 ) dlevel *= 1000;  //  m to mm
+	      else if ( factor == 1 ) dlevel *=  100;  // dm to mm
+	      else if ( factor == 2 ) dlevel *=   10;  // cm to mm
+	      else if ( factor == 3 ) dlevel *=    1;  // mm to mm
+              *level_sf = 77;
 	    }
 	  else
 	    {
@@ -30848,16 +31238,19 @@ void grib2GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, i
 	    {
 	      GRIB_CHECK(grib_get_long(gh, "scaleFactorOfFirstFixedSurface", &factor), 0);
 	      GRIB_CHECK(grib_get_double(gh, "scaledValueOfFirstFixedSurface", &dlevel), 0);
-	      if      ( factor == 0 ) dlevel *= 100;   //  m to cm
-	      else if ( factor == 1 ) dlevel *=  10;   // dm to cm
-	      else if ( factor == 3 ) dlevel *=   0.1; // mm to cm
+	      if      ( factor == 0 ) dlevel *= 1000;  //  m to mm
+	      else if ( factor == 1 ) dlevel *=  100;  // dm to mm
+	      else if ( factor == 2 ) dlevel *=   10;  // cm to mm
+	      else if ( factor == 3 ) dlevel *=    1;  // mm to mm
 	      *level1 = (int) dlevel;
 	      GRIB_CHECK(grib_get_long(gh, "scaleFactorOfSecondFixedSurface", &factor), 0);
 	      GRIB_CHECK(grib_get_double(gh, "scaledValueOfSecondFixedSurface", &dlevel), 0);
-	      if      ( factor == 0 ) dlevel *= 100;   //  m to cm
-	      else if ( factor == 1 ) dlevel *=  10;   // dm to cm
-	      else if ( factor == 3 ) dlevel *=   0.1; // mm to cm
+	      if      ( factor == 0 ) dlevel *= 1000;  //  m to mm
+	      else if ( factor == 1 ) dlevel *=  100;  // dm to mm
+	      else if ( factor == 2 ) dlevel *=   10;  // cm to mm
+	      else if ( factor == 3 ) dlevel *=    1;  // mm to mm
 	      *level2 = (int) dlevel;
+              *level_sf = 77;
 	    }
 	  else
 	    {
@@ -30871,34 +31264,39 @@ void grib2GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, i
 }
 
 static
-void gribapiAddRecord(int streamID, int param, grib_handle *gh,
-		      long recsize, off_t position, int datatype, int comptype)
+void gribapiGetString(grib_handle *gh, const char *key, char *string, size_t length)
+{
+  string[0] = 0;
+
+  GRIB_CHECK(grib_get_string(gh, key, string, &length), 0);
+  if      ( length == 8 && memcmp(string, "unknown", length) == 0 ) string[0] = 0;
+  else if ( length == 2 && memcmp(string, "~", length)       == 0 ) string[0] = 0;
+}
+
+static
+void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
+		      long recsize, off_t position, int datatype, int comptype, size_t len, const char *varname,
+                      int leveltype, int lbounds, int level1, int level2, int level_sf)
 {
   long editionNumber;
   int zaxistype;
   int gridID = CDI_UNDEFID, varID;
   int levelID = 0;
   int tsID, recID;
-  int level1 = 0, level2 = 0;
   int numavg;
   int tsteptype;
-  int lbounds = 0;
   record_t *record;
   grid_t grid;
   int vlistID;
-  stream_t *streamptr;
-  int leveltype;
   long lpar;
   int status;
-  char name[256], longname[256], units[256];
+  char longname[256], units[256];
   size_t vlen;
   long ens_index = 0, ens_count = 0, ens_forecast_type = 0;
 
-  streamptr = stream_to_pointer(streamID);
-
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   tsID    = streamptr->curTsID;
-  recID   = recordNewEntry(streamID, tsID);
+  recID   = recordNewEntry(streamptr, tsID);
   record  = &streamptr->tsteps[tsID].records[recID];
 
   tsteptype = gribapiGetTsteptype(gh);
@@ -30907,11 +31305,6 @@ void gribapiAddRecord(int streamID, int param, grib_handle *gh,
 
   GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
 
-  if ( editionNumber <= 1 )
-    grib1GetLevel(gh, &leveltype, &lbounds, &level1, &level2);
-  else
-    grib2GetLevel(gh, &leveltype, &lbounds, &level1, &level2);
-
   // fprintf(stderr, "param %d %d %d %d\n", param, level1, level2, leveltype);
 
   (*record).size     = recsize;
@@ -30920,6 +31313,7 @@ void gribapiAddRecord(int streamID, int param, grib_handle *gh,
   (*record).ilevel   = level1;
   (*record).ilevel2  = level2;
   (*record).ltype    = leveltype;
+  memcpy((*record).varname, varname, len);
 
   gribapiGetGrid(gh, &grid);
 
@@ -30952,19 +31346,21 @@ void gribapiAddRecord(int streamID, int param, grib_handle *gh,
       {
         size_t len;
         char uuid[17];
+        double dtmp;
         long nlev, nvgrid;
 
         GRIB_CHECK(grib_get_long(gh, "NV", &lpar), 0);
-        if ( lpar != 3 )
+        if ( lpar != 6 )
           {
             fprintf(stderr, "Warning ...\n");
           }
-        GRIB_CHECK(grib_get_long(gh, "nlev", &nlev), 0);
-        GRIB_CHECK(grib_get_long(gh, "numberOfVGridUsed", &nvgrid), 0);
-
+        GRIB_CHECK(grib_get_double(gh, "nlev", &dtmp), 0);
+        nlev = (int) NINT(dtmp);
+        GRIB_CHECK(grib_get_double(gh, "numberOfVGridUsed", &dtmp), 0);
+        nvgrid = NINT(dtmp);
         len = (size_t) 16;
         uuid[16] = 0;
-        GRIB_CHECK(grib_get_string(gh, "uuidOfVGrid", uuid, &len), 0);
+        GRIB_CHECK(grib_get_bytes(gh, "uuidOfVGrid", (unsigned char *) uuid, &len), 0);
         varDefZAxisReference((int) nlev, (int) nvgrid, uuid);
         break;
       }
@@ -30973,29 +31369,21 @@ void gribapiAddRecord(int streamID, int param, grib_handle *gh,
   // if ( datatype > 32 ) datatype = DATATYPE_PACK32;
   if ( datatype <  0 ) datatype = DATATYPE_PACK;
 
-  name[0] = 0;
   longname[0] = 0;
   units[0] = 0;
 
-  vlen = 256;
-  GRIB_CHECK(grib_get_string(gh, "shortName", name, &vlen), 0);
-  if      ( vlen == 8 && memcmp(name, "unknown", vlen) == 0 ) name[0] = 0;
-  else if ( vlen == 2 && memcmp(name, "~", vlen)       == 0 ) name[0] = 0;
-
-  if ( name[0] != 0 )
+  if ( varname[0] != 0 )
     {
       vlen = 256;
-      GRIB_CHECK(grib_get_string(gh, "name", longname, &vlen), 0);
-      if ( vlen == 8 && memcmp(longname, "unknown", vlen) == 0 ) longname[0] = 0;
+      gribapiGetString(gh, "name", longname, vlen);
       vlen = 256;
-      GRIB_CHECK(grib_get_string(gh, "units", units, &vlen), 0);
-      if ( vlen == 8 && memcmp(units, "unknown", vlen) == 0 ) units[0] = 0;
+      gribapiGetString(gh, "units", units, vlen);
     }
-  // fprintf(stderr, "param %d name %s %s %s\n", param, name, longname, units); 
+  // fprintf(stderr, "param %d name %s %s %s\n", param, name, longname, units);
 
-  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2,
+  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, level_sf,
 	       datatype, &varID, &levelID, tsteptype, numavg, leveltype,
-	       name, longname, units);
+	       varname, longname, units);
 
   (*record).varID   = varID;
   (*record).levelID = levelID;
@@ -31004,7 +31392,7 @@ void gribapiAddRecord(int streamID, int param, grib_handle *gh,
 
   /*
     Get the ensemble Info from the grib-2 Tables and update the intermediate datastructure.
-    Further update to the "vlist" is handled in the same way as for GRIB-1 by "cdiGenVars"
+    Further update to the "vlist" is handled in the same way as for GRIB-1 by "cdi_generate_vars"
   */
   {
     int status;
@@ -31071,9 +31459,67 @@ void gribapiAddRecord(int streamID, int param, grib_handle *gh,
     Message("varID = %d  param = %d  zaxistype = %d  gridID = %d  levelID = %d",
 	    varID, param, zaxistype, gridID, levelID);
 }
+
+static
+int gribapiGetParam(grib_handle *gh)
+{
+  int pdis = 0, pcat = 0, pnum = 0;
+  int param = 0;
+  int status;
+  long lpar;
+
+  GRIB_CHECK(grib_get_long(gh, "discipline", &lpar), 0);
+  pdis = (int) lpar;
+
+  status = grib_get_long(gh, "parameterCategory", &lpar);
+  if ( status == 0 ) pcat = (int) lpar;
+
+  status = grib_get_long(gh, "parameterNumber", &lpar);
+  if ( status == 0 ) pnum = (int) lpar;
+
+  param = cdiEncodeParam(pnum, pcat, pdis);
+
+  return (param);
+}
+
+static
+compvar2_t gribapiVarSet(int param, int level1, int level2, int leveltype, char *name)
+{
+  compvar2_t compVar;
+  size_t maxlen = sizeof(compVar.name);
+  size_t len = strlen(name);
+  if ( len > maxlen ) len = maxlen;
+
+  compVar.param  = param;
+  compVar.level1 = level1;
+  compVar.level2 = level2;
+  compVar.ltype  = leveltype;
+  memset(compVar.name, 0, maxlen);
+  memcpy(compVar.name, name, len);
+
+  return (compVar);
+}
+
+static
+int gribapiVarCompare(compvar2_t compVar, record_t record)
+{
+  int rstatus;
+  compvar2_t compVar0;
+  size_t maxlen = sizeof(compVar.name);
+
+  compVar0.param  = record.param;
+  compVar0.level1 = record.ilevel;
+  compVar0.level2 = record.ilevel2;
+  compVar0.ltype  = record.ltype;
+  memcpy(compVar0.name, record.varname, maxlen);
+
+  rstatus = memcmp(&compVar0, &compVar, sizeof(compvar2_t));
+
+  return (rstatus);
+}
 #endif
 
-int gribapiScanTimestep1(int streamID)
+int gribapiScanTimestep1(stream_t * streamptr)
 {
 #if  defined  (HAVE_LIBGRIB_API)
   off_t recpos = 0;
@@ -31091,6 +31537,7 @@ int gribapiScanTimestep1(int streamID)
   int varID;
   size_t readsize;
   int nrecords, nrecs, recID;
+  int nrecs_scanned;
   int datatype;
   long recsize = 0;
   int warn_time = TRUE;
@@ -31101,31 +31548,30 @@ int gribapiScanTimestep1(int streamID)
   int vlistID;
   int comptype;
   long unzipsize;
-  compvar2_t compVar, compVar0;
-  stream_t *streamptr;
+  compvar2_t compVar;
   grib_handle *gh = NULL;
   int leveltype;
-  int pdis = 0, pcat = 0, pnum = 0;
   long editionNumber;
   long lpar;
+  size_t len;
   int bitsPerValue;
   int lieee = FALSE;
   int lbounds;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
+  int level_sf;
+  char paramstr[32];
+  char varname[256];
 
   streamptr->curTsID = 0;
 
-  tsID  = tstepsNewEntry(streamID);
+  tsID  = tstepsNewEntry(streamptr);
   taxis = &streamptr->tsteps[tsID].taxis;
 
   if ( tsID != 0 )
     Error("Internal problem! tstepsNewEntry returns %d", tsID);
 
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
 
+  nrecs_scanned = 0;
   nrecs = 0;
   while ( TRUE )
     {
@@ -31163,6 +31609,7 @@ int gribapiScanTimestep1(int streamID)
 	    }
 	}
 
+      nrecs_scanned++;
       gh = grib_handle_new_from_message(NULL, (void *) gribbuffer, recsize);
       GRIB_CHECK(grib_set_double(gh, "missingValue", cdiDefaultMissval), 0);
 
@@ -31178,6 +31625,7 @@ int gribapiScanTimestep1(int streamID)
 	  param = cdiEncodeParam(rcode, rtabnum, 255);
 
 	  grib1GetLevel(gh, &leveltype, &lbounds, &level1, &level2);
+          level_sf = 0;
 	}
       else
 	{
@@ -31192,19 +31640,18 @@ int gribapiScanTimestep1(int streamID)
 	      else if ( strncmp(typeOfPacking, "grid_ieee", len) == 0 ) lieee = TRUE;
 	    }
 
-	  GRIB_CHECK(grib_get_long(gh, "discipline", &lpar), 0);
-	  pdis = (int) lpar;
+	  param = gribapiGetParam(gh);
 
-	  GRIB_CHECK(grib_get_long(gh, "parameterCategory", &lpar), 0);
-	  pcat = (int) lpar;
-
-	  GRIB_CHECK(grib_get_long(gh, "parameterNumber", &lpar), 0);
-	  pnum = (int) lpar;
+	  grib2GetLevel(gh, &leveltype, &lbounds, &level1, &level2, &level_sf);
+	}
 
-	  param = cdiEncodeParam(pnum, pcat, pdis);
+      cdiParamToString(param, paramstr, sizeof(paramstr));
 
-	  grib2GetLevel(gh, &leveltype, &lbounds, &level1, &level2);
-	}
+      varname[0] = 0;
+      gribapiGetString(gh, "shortName", varname, sizeof(varname));
+      len = strlen(varname);
+      if ( len > 32 ) len = 32;
+      //printf("param = %s  name = %s   l1 = %d  l2 = %d\n", paramstr, varname, level1, level2);
 
       gribapiGetValidityDateTime(gh, &vdate, &vtime);
       /*
@@ -31232,10 +31679,9 @@ int gribapiScanTimestep1(int streamID)
 	{
 	  datetime0.date = vdate;
 	  datetime0.time = vtime;
-	  GRIB_CHECK(grib_get_long(gh, "dataDate", &lpar), 0);
-	  rdate = (int) lpar;
-	  GRIB_CHECK(grib_get_long(gh, "dataTime", &lpar), 0);
-	  rtime = (int) lpar*100;
+
+          gribapiGetDataDateTime(gh, &rdate, &rtime);
+
 	  fcast = gribapiTimeIsFC(gh);
 	  if ( fcast ) tunit = gribapiGetTimeUnits(gh);
 	}
@@ -31244,23 +31690,10 @@ int gribapiScanTimestep1(int streamID)
 	  datetime.date  = vdate;
 	  datetime.time  = vtime;
 
-	  compVar.param  = param;
-          compVar.level1 = level1;
-          compVar.level2 = level2;
-	  compVar.ltype  = leveltype;
+	  compVar = gribapiVarSet(param, level1, level2, leveltype, varname);
 
 	  for ( recID = 0; recID < nrecs; recID++ )
-	    {
-	      compVar0.param  = streamptr->tsteps[0].records[recID].param;
-	      compVar0.level1 = streamptr->tsteps[0].records[recID].ilevel;
-	      compVar0.level2 = streamptr->tsteps[0].records[recID].ilevel2;
-	      compVar0.ltype  = streamptr->tsteps[0].records[recID].ltype;
-	      /*
-	      printf("var0: %d %d %d %d %d\n", recID, compVar0.param, compVar0.level1, compVar0.level2, compVar0.ltype);
-	      printf("var1: %d %d %d %d %d\n", recID, compVar.param, compVar.level1, compVar.level2, compVar.ltype);
-	      */
-	      if ( memcmp(&compVar0, &compVar, sizeof(compvar2_t)) == 0 ) break;
-	    }
+            if ( gribapiVarCompare(compVar, streamptr->tsteps[0].records[recID]) == 0 ) break;
 
 	  if ( cdiInventoryMode == 1 )
 	    {
@@ -31268,8 +31701,6 @@ int gribapiScanTimestep1(int streamID)
 	      if ( warn_time )
 		if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 )
 		  {
-		    char paramstr[32];
-		    cdiParamToString(param, paramstr, sizeof(paramstr));
 		    Warning("Inconsistent verification time (param=%s level=%d)", paramstr, level1);
 		    warn_time = FALSE;
 		  }
@@ -31280,9 +31711,7 @@ int gribapiScanTimestep1(int streamID)
 
 	      if ( recID < nrecs )
 		{
-		  char paramstr[32];
-		  cdiParamToString(param, paramstr, sizeof(paramstr));
-		  Warning("Param=%s level=%d already exist, skipped!", paramstr, level1);
+		  Warning("Param=%s level=%d (record %d) already exist, skipped!", paramstr, level1, nrecs_scanned);
 		  continue;
 		}
 	    }
@@ -31307,7 +31736,8 @@ int gribapiScanTimestep1(int streamID)
       if ( CDI_Debug )
 	Message("%4d %8d %4d  %8d %8d %6d", nrecs, (int)recpos, param, level1, vdate, vtime);
 
-      gribapiAddRecord(streamID, param, gh, recsize, recpos, datatype, comptype);
+      gribapiAddRecord(streamptr, param, gh, recsize, recpos, datatype, comptype, len, varname,
+                       leveltype, lbounds, level1, level2, level_sf);
 
       grib_handle_delete(gh);
       gh = NULL;
@@ -31319,7 +31749,7 @@ int gribapiScanTimestep1(int streamID)
 
   if ( nrecs == 0 ) return (CDI_EUFSTRUCT);
 
-  cdiGenVars(streamID);
+  cdi_generate_vars(streamptr);
 
   if ( fcast )
     {
@@ -31338,7 +31768,7 @@ int gribapiScanTimestep1(int streamID)
   taxis->vdate = datetime0.date;
   taxis->vtime = datetime0.time;
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   vlistDefTaxis(vlistID, taxisID);
 
   nrecords = streamptr->tsteps[0].nallrecs;
@@ -31359,7 +31789,7 @@ int gribapiScanTimestep1(int streamID)
 
   if ( streamptr->ntsteps == -1 )
     {
-      tsID = tstepsNewEntry(streamID);
+      tsID = tstepsNewEntry(streamptr);
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
@@ -31386,7 +31816,7 @@ int gribapiScanTimestep1(int streamID)
 }
 
 
-int gribapiScanTimestep2(int streamID)
+int gribapiScanTimestep2(stream_t * streamptr)
 {
   int rstatus = 0;
 #if  defined  (HAVE_LIBGRIB_API)
@@ -31409,24 +31839,21 @@ int gribapiScanTimestep2(int streamID)
   taxis_t *taxis;
   int vlistID;
   long unzipsize;
-  compvar2_t compVar, compVar0;
-  stream_t *streamptr;
+  compvar2_t compVar;
   grib_handle *gh = NULL;
   int leveltype;
-  int pdis = 0, pcat = 0, pnum = 0;
   int param = 0;
   long editionNumber;
   long lpar;
   int lbounds;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
+  int level_sf;
+  char paramstr[32];
+  char varname[256];
 
   streamptr->curTsID = 1;
 
-  fileID  = streamInqFileID(streamID);
-  vlistID = streamInqVlist(streamID);
+  fileID  = streamptr->fileID;
+  vlistID = streamptr->vlistID;
   taxisID = vlistInqTaxis(vlistID);
 
   gribbuffer = (unsigned char *) streamptr->record->buffer;
@@ -31440,7 +31867,7 @@ int gribapiScanTimestep2(int streamID)
 
   fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-  cdiCreateRecords(streamID, tsID);
+  cdi_create_records(streamptr, tsID);
 
   nrecords = streamptr->tsteps[tsID].nallrecs;
   streamptr->tsteps[1].recIDs = (int *) malloc(nrecords*sizeof(int));
@@ -31502,22 +31929,19 @@ int gribapiScanTimestep2(int streamID)
 	  param = cdiEncodeParam(rcode, rtabnum, 255);
 
 	  grib1GetLevel(gh, &leveltype, &lbounds, &level1, &level2);
+          level_sf = 0;
 	}
       else
 	{
-	  GRIB_CHECK(grib_get_long(gh, "discipline", &lpar), 0);
-	  pdis = (int) lpar;
+	  param = gribapiGetParam(gh);
 
-	  GRIB_CHECK(grib_get_long(gh, "parameterCategory", &lpar), 0);
-	  pcat = (int) lpar;
-
-	  GRIB_CHECK(grib_get_long(gh, "parameterNumber", &lpar), 0);
-	  pnum = (int) lpar;
+	  grib2GetLevel(gh, &leveltype, &lbounds, &level1, &level2, &level_sf);
+	}
 
-	  param = cdiEncodeParam(pnum, pcat, pdis);
+      cdiParamToString(param, paramstr, sizeof(paramstr));
 
-	  grib2GetLevel(gh, &leveltype, &lbounds, &level1, &level2);
-	}
+      varname[0] = 0;
+      gribapiGetString(gh, "shortName", varname, sizeof(varname));
 
       gribapiGetValidityDateTime(gh, &vdate, &vtime);
 
@@ -31526,10 +31950,9 @@ int gribapiScanTimestep2(int streamID)
 	  if ( taxisInqType(taxisID) == TAXIS_RELATIVE )
 	    {
 	      taxis->type  = TAXIS_RELATIVE;
-	      GRIB_CHECK(grib_get_long(gh, "dataDate", &lpar), 0);
-	      taxis->rdate = (int) lpar;
-	      GRIB_CHECK(grib_get_long(gh, "dataTime", &lpar), 0);
-	      taxis->rtime = (int) lpar*100;
+
+              gribapiGetDataDateTime(gh, &(taxis->rdate), &(taxis->rtime));
+
 	      taxis->unit  = gribapiGetTimeUnits(gh);
 	    }
 	  else
@@ -31560,70 +31983,39 @@ int gribapiScanTimestep2(int streamID)
       */
       datetime.date  = vdate;
       datetime.time  = vtime;
-      compVar.param  = param;
-      compVar.level1 = level1;
-      compVar.level2 = level2;
-      compVar.ltype  = leveltype;
-      for ( recID = 0; recID < nrecords; recID++ )
-	{
-	  compVar0.param = streamptr->tsteps[tsID].records[recID].param;
-	  compVar0.level1 = streamptr->tsteps[tsID].records[recID].ilevel;
-	  compVar0.level2 = streamptr->tsteps[tsID].records[recID].ilevel2;
-	  compVar0.ltype  = streamptr->tsteps[tsID].records[recID].ltype;
 
-	  if ( memcmp(&compVar0, &compVar, sizeof(compvar2_t)) == 0 ) break;
-	}
+      compVar = gribapiVarSet(param, level1, level2, leveltype, varname);
+
+      for ( recID = 0; recID < nrecords; recID++ )
+        if ( gribapiVarCompare(compVar, streamptr->tsteps[tsID].records[recID]) == 0 ) break;
 
       if ( recID == nrecords )
 	{
-	  char paramstr[32];
-	  cdiParamToString(param, paramstr, sizeof(paramstr));
-	  Warning("Param=%s level=%d not defined at timestep 1!", paramstr, level1);
+	  Warning("Param=%s (%s) l1=%d l2=%d not defined at timestep 1!", paramstr, varname, level1, level2);
 	  return (CDI_EUFSTRUCT);
 	}
 
-      if ( cdiInventoryMode == 1 )
-	{
-	  if ( streamptr->tsteps[tsID].records[recID].used )
-	    {
-	      break;
-	    }
-	  else
-	    {
-	      streamptr->tsteps[tsID].records[recID].used = TRUE;
-	      streamptr->tsteps[tsID].recIDs[rindex] = recID;
-	    }    
-	}
-      else
-	{
-	  if ( streamptr->tsteps[tsID].records[recID].used )
+      if ( streamptr->tsteps[tsID].records[recID].used )
+        {
+          if ( cdiInventoryMode == 1 ) break;
+          else
 	    {
-	      char paramstr[32];
-	      cdiParamToString(param, paramstr, sizeof(paramstr));
-
 	      if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;
 
 	      Warning("Param=%s level=%d already exist, skipped!", paramstr, level1);
 	      continue;
 	    }
-	  else
-	    {
-	      streamptr->tsteps[tsID].records[recID].used = TRUE;
-	      streamptr->tsteps[tsID].recIDs[rindex] = recID;
-	    }    
 	}
 
+      streamptr->tsteps[tsID].records[recID].used = TRUE;
+      streamptr->tsteps[tsID].recIDs[rindex] = recID;
+
       if ( CDI_Debug )
 	Message("%4d %8d %4d %8d %8d %6d", rindex+1, (int)recpos, param, level1, vdate, vtime);
 
       streamptr->tsteps[tsID].records[recID].size = recsize;
 
-      compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
-      compVar0.level1 = streamptr->tsteps[tsID].records[recID].ilevel;
-      compVar0.level2 = streamptr->tsteps[tsID].records[recID].ilevel2;
-      compVar0.ltype  = streamptr->tsteps[tsID].records[recID].ltype;
-
-      if ( memcmp(&compVar0, &compVar, sizeof(compvar2_t)) != 0 )
+      if ( gribapiVarCompare(compVar, streamptr->tsteps[tsID].records[recID]) != 0 )
 	{
 	  Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
 		  tsID, recID,
@@ -31673,7 +32065,7 @@ int gribapiScanTimestep2(int streamID)
 
   if ( streamptr->ntsteps == -1 )
     {
-      tsID = tstepsNewEntry(streamID);
+      tsID = tstepsNewEntry(streamptr);
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
@@ -31689,7 +32081,7 @@ int gribapiScanTimestep2(int streamID)
 }
 
 
-int gribapiScanTimestep(int streamID)
+int gribapiScanTimestep(stream_t * streamptr)
 {
   int rstatus = 0;
 #if  defined  (HAVE_LIBGRIB_API)
@@ -31710,25 +32102,22 @@ int gribapiScanTimestep(int streamID)
   int vlistID;
   int rindex, nrecs = 0;
   long unzipsize;
-  compvar2_t compVar, compVar0;
-  stream_t *streamptr;
+  compvar2_t compVar;
   grib_handle *gh = NULL;
   int leveltype;
-  int pdis = 0, pcat = 0, pnum = 0;
   int param = 0;
   long editionNumber;
   long lpar;
   int lbounds;
+  int level_sf;
+  char paramstr[32];
+  char varname[256];
 
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
-
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
 
   if ( CDI_Debug )
     {
-      Message("streamID = %d", streamID);
+      Message("streamID = %d", streamptr->self);
       Message("cts = %d", streamptr->curTsID);
       Message("rts = %d", streamptr->rtsteps);
       Message("nts = %d", streamptr->ntsteps);
@@ -31742,7 +32131,7 @@ int gribapiScanTimestep(int streamID)
       gribbuffer = (unsigned char *) streamptr->record->buffer;
       buffersize = streamptr->record->buffersize;
 
-      cdiCreateRecords(streamID, tsID);
+      cdi_create_records(streamptr, tsID);
 
       nrecs = streamptr->tsteps[1].nrecs;
 
@@ -31751,7 +32140,7 @@ int gribapiScanTimestep(int streamID)
       for ( recID = 0; recID < nrecs; recID++ )
 	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
 
-      fileID = streamInqFileID(streamID);
+      fileID = streamptr->fileID;
 
       fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
@@ -31810,22 +32199,19 @@ int gribapiScanTimestep(int streamID)
 	      param = cdiEncodeParam(rcode, rtabnum, 255);
 
 	      grib1GetLevel(gh, &leveltype, &lbounds, &level1, &level2);
+              level_sf = 0;
 	    }
 	  else
 	    {
-	      GRIB_CHECK(grib_get_long(gh, "discipline", &lpar), 0);
-	      pdis = (int) lpar;
+	      param = gribapiGetParam(gh);
 
-	      GRIB_CHECK(grib_get_long(gh, "parameterCategory", &lpar), 0);
-	      pcat = (int) lpar;
-
-	      GRIB_CHECK(grib_get_long(gh, "parameterNumber", &lpar), 0);
-	      pnum = (int) lpar;
+	      grib2GetLevel(gh, &leveltype, &lbounds, &level1, &level2, &level_sf);
+	    }
 
-	      param = cdiEncodeParam(pnum, pcat, pdis);
+          cdiParamToString(param, paramstr, sizeof(paramstr));
 
-	      grib2GetLevel(gh, &leveltype, &lbounds, &level1, &level2);
-	    }
+          varname[0] = 0;
+	  gribapiGetString(gh, "shortName", varname, sizeof(varname));
 
 	  gribapiGetValidityDateTime(gh, &vdate, &vtime);
 
@@ -31837,10 +32223,9 @@ int gribapiScanTimestep(int streamID)
 	      if ( taxisInqType(taxisID) == TAXIS_RELATIVE )
 		{
 		  taxis->type  = TAXIS_RELATIVE;
-		  GRIB_CHECK(grib_get_long(gh, "dataDate", &lpar), 0);
-		  taxis->rdate = (int) lpar;
-		  GRIB_CHECK(grib_get_long(gh, "dataTime", &lpar), 0);
-		  taxis->rtime = (int) lpar*100;
+
+                  gribapiGetDataDateTime(gh, &(taxis->rdate), &(taxis->rtime));
+
 		  taxis->unit  = gribapiGetTimeUnits(gh);
 		}
 	      else
@@ -31869,25 +32254,17 @@ int gribapiScanTimestep(int streamID)
 	  */
 	  datetime.date  = vdate;
 	  datetime.time  = vtime;
-	  compVar.param  = param;
-          compVar.level1 = level1;
-          compVar.level2 = level2;
-          compVar.ltype  = leveltype;
+
+	  compVar = gribapiVarSet(param, level1, level2, leveltype, varname);
+
 	  for ( vrecID = 0; vrecID < nrecs; vrecID++ )
 	    {
 	      recID   = streamptr->tsteps[1].recIDs[vrecID];
-	      compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
-	      compVar0.level1 = streamptr->tsteps[tsID].records[recID].ilevel;
-	      compVar0.level2 = streamptr->tsteps[tsID].records[recID].ilevel2;
-	      compVar0.ltype  = streamptr->tsteps[tsID].records[recID].ltype;
-
-	      if ( memcmp(&compVar0, &compVar, sizeof(compvar2_t)) == 0 ) break;
+	      if ( gribapiVarCompare(compVar, streamptr->tsteps[tsID].records[recID]) == 0 ) break;
 	    }
 
 	  if ( vrecID == nrecs )
 	    {
-	      char paramstr[32];
-	      cdiParamToString(param, paramstr, sizeof(paramstr));
 	      Warning("Param=%s level=%d not available at timestep %d!", paramstr, level1, tsID+1);
 
 	      if ( cdiInventoryMode == 1 )
@@ -31896,18 +32273,10 @@ int gribapiScanTimestep(int streamID)
 		continue;
 	    }
 
-	  if ( cdiInventoryMode == 1 )
-	    {
-	      streamptr->tsteps[tsID].records[recID].used = TRUE;
-	      streamptr->tsteps[tsID].recIDs[rindex] = recID;
-	    }
-	  else
+	  if ( cdiInventoryMode != 1 )
 	    {
 	      if ( streamptr->tsteps[tsID].records[recID].used )
 		{
-		  char paramstr[32];
-		  cdiParamToString(param, paramstr, sizeof(paramstr));
-
 		  if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;
 
 		  if ( CDI_Debug )
@@ -31915,22 +32284,15 @@ int gribapiScanTimestep(int streamID)
 
 		  continue;
 		}
-	      else
-		{
-		  streamptr->tsteps[tsID].records[recID].used = TRUE;
-		  streamptr->tsteps[tsID].recIDs[rindex] = recID;
-		}
 	    }
 
+          streamptr->tsteps[tsID].records[recID].used = TRUE;
+          streamptr->tsteps[tsID].recIDs[rindex] = recID;
+
 	  if ( CDI_Debug )
 	    Message("%4d %8d %4d %8d %8d %6d", rindex+1, (int)recpos, param, level1, vdate, vtime);
 
-	  compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
-	  compVar0.level1 = streamptr->tsteps[tsID].records[recID].ilevel;
-	  compVar0.level2 = streamptr->tsteps[tsID].records[recID].ilevel2;
-	  compVar0.ltype  = streamptr->tsteps[tsID].records[recID].ltype;
-
-	  if ( memcmp(&compVar0, &compVar, sizeof(compvar2_t)) != 0 )
+	  if ( gribapiVarCompare(compVar, streamptr->tsteps[tsID].records[recID]) != 0 )
 	    {
 	      Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
 		      tsID, recID,
@@ -31961,7 +32323,6 @@ int gribapiScanTimestep(int streamID)
 
       if ( vrecID < nrecs )
 	{
-	  char paramstr[32];
 	  cdiParamToString(streamptr->tsteps[tsID].records[recID].param, paramstr, sizeof(paramstr));
 	  Warning("Param %d level %d not found at timestep %d!",
 		  paramstr, streamptr->tsteps[tsID].records[recID].ilevel, tsID+1);
@@ -31972,7 +32333,7 @@ int gribapiScanTimestep(int streamID)
 
       if ( streamptr->ntsteps != streamptr->rtsteps )
 	{
-	  tsID = tstepsNewEntry(streamID);
+	  tsID = tstepsNewEntry(streamptr);
 	  if ( tsID != streamptr->rtsteps )
 	    Error("Internal error. tsID = %d", tsID);
 
@@ -32216,8 +32577,7 @@ void gribapiDefDateTimeAbs(int editionNumber, grib_handle *gh, int date, int tim
   if ( editionNumber > 1 ) GRIB_CHECK(grib_set_long(gh, "stepRange", 0), 0);
 
   if ( date == 0 ) date = 10101;
-  GRIB_CHECK(grib_set_long(gh, "dataDate", date), 0);
-  GRIB_CHECK(grib_set_long(gh, "dataTime", time/100), 0);
+  gribapiSetDataDateTime(gh, date, time);
 
   (void ) gribapiDefSteptype(editionNumber, gh, tsteptype, gcinit);
 }
@@ -32234,11 +32594,11 @@ int gribapiDefDateTimeRel(int editionNumber, grib_handle *gh, int rdate, int rti
 
   cdiDecodeDate(rdate, &year, &month, &day);
   cdiDecodeTime(rtime, &hour, &minute, &second);
-  encode_juldaysec(calendar, year, month, day, hour, minute, &julday1, &secofday1);
+  encode_juldaysec(calendar, year, month, day, hour, minute, second, &julday1, &secofday1);
 
   cdiDecodeDate(vdate, &year, &month, &day);
   cdiDecodeTime(vtime, &hour, &minute, &second);
-  encode_juldaysec(calendar, year, month, day, hour, minute, &julday2, &secofday2);
+  encode_juldaysec(calendar, year, month, day, hour, minute, second, &julday2, &secofday2);
 
   (void) julday_sub(julday1, secofday1, julday2, secofday2, &days, &secs);
 
@@ -32250,10 +32610,9 @@ int gribapiDefDateTimeRel(int editionNumber, grib_handle *gh, int rdate, int rti
       if ( editionNumber > 1 ) GRIB_CHECK(grib_set_long(gh, "stepRange", 0), 0);
 
       if ( rdate == 0 ) rdate = 10101;
-      GRIB_CHECK(grib_set_long(gh, "dataDate", rdate), 0);
-      GRIB_CHECK(grib_set_long(gh, "dataTime", rtime/100), 0);
+      gribapiSetDataDateTime(gh, rdate, rtime);
 
-      // printf(">>>>> tsteptype %d  startStep %d  endStep %d\n", tsteptype, startStep, endStep);
+      // printf(">>>>> tsteptype %d  startStep %ld  endStep %ld\n", tsteptype, startStep, endStep);
 
       proDefTempNum = gribapiDefSteptype(editionNumber, gh, tsteptype, gcinit);
 
@@ -32658,7 +33017,7 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int ljpeg, i
 	    GRIB_CHECK(grib_set_long(gh, "numberOfGridUsed", gridInqNumber(gridID)), 0);
 	    GRIB_CHECK(grib_set_long(gh, "numberOfGridInReference", gridInqPosition(gridID)), 0);
             len = 16;
-            GRIB_CHECK(grib_set_string(gh, "uuidOfHGrid", gridInqUUID(gridID, uuid), &len), 0);
+            GRIB_CHECK(grib_set_bytes(gh, "uuidOfHGrid", (unsigned char *) gridInqUUID(gridID, uuid), &len), 0);
 	  }
 
 	break;
@@ -32666,11 +33025,24 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int ljpeg, i
     default:
       {
 	Error("Unsupported grid type: %s", gridNamePtr(gridtype));
+	break;
       }
     }
 }
 
 static
+void getLevelFactor(double level, long *factor, double *scale)
+{
+  double dum;
+
+  if      ( level >= 1     && (int)(1000*modf(level,      &dum)) == 0 ) { *factor = 0; *scale = 1; }
+  else if ( level >= 0.1   && (int)(1000*modf(level*10,   &dum)) == 0 ) { *factor = 1; *scale = 10; }
+  else if ( level >= 0.01  && (int)(1000*modf(level*100,  &dum)) == 0 ) { *factor = 2; *scale = 100; }
+  else if ( level >= 0.001 && (int)(1000*modf(level*1000, &dum)) == 0 ) { *factor = 3; *scale = 1000; }
+  else                                                                  { *factor = 2; *scale = 10; }
+}
+
+static
 void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID, int levelID, int gcinit)
 {
   double level;
@@ -32687,8 +33059,7 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
   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");
@@ -32711,6 +33082,45 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
 
 	break;
       }
+    case ZAXIS_CLOUD_BASE:
+      {
+	if ( editionNumber <= 1 )
+          {
+            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_CLOUDBASE), 0);
+          }
+        else
+          {
+            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_CLOUDBASE), 0);
+          }
+
+        break;
+      }
+    case ZAXIS_CLOUD_TOP:
+      {
+	if ( editionNumber <= 1 )
+          {
+            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_CLOUDTOP), 0);
+          }
+        else
+          {
+            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_CLOUDTOP), 0);
+          }
+
+        break;
+      }
+    case ZAXIS_ISOTHERM_ZERO:
+      {
+	if ( editionNumber <= 1 )
+          {
+            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_ISOTHERM0), 0);
+          }
+        else
+          {
+            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_ISOTHERM0), 0);
+          }
+
+        break;
+      }
     case ZAXIS_TOA:
       {
 	if ( editionNumber <= 1 )
@@ -32922,29 +33332,37 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
 	else
 	  {
 	    long factor;
-	    if      ( memcmp(units, "mm", 2) == 0 ) factor = 3;
-	    else if ( memcmp(units, "cm", 2) == 0 ) factor = 2;
-	    else if ( memcmp(units, "dm", 2) == 0 ) factor = 1;
-	    else                                    factor = 0; // meter
+            double scale;
+            double scalefactor;
+
+	    if      ( memcmp(units, "mm", 2) == 0 ) scalefactor = 0.001;
+	    else if ( memcmp(units, "cm", 2) == 0 ) scalefactor = 0.01;
+	    else if ( memcmp(units, "dm", 2) == 0 ) scalefactor = 0.1;
+	    else                                    scalefactor = 1; // meter
 
 	    if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
 	      {
 		double level1, level2;
-		level1 = zaxisInqLbound(zaxisID, levelID);
-		level2 = zaxisInqUbound(zaxisID, levelID);
+		level1 = scalefactor*zaxisInqLbound(zaxisID, levelID);
+		level2 = scalefactor*zaxisInqUbound(zaxisID, levelID);
 
+                getLevelFactor(level1, &factor, &scale);
 		if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_LANDDEPTH), 0);
 		GRIB_CHECK(grib_set_long(gh, "scaleFactorOfFirstFixedSurface", factor), 0);
-		GRIB_CHECK(grib_set_double(gh, "scaledValueOfFirstFixedSurface", level1), 0);
+		GRIB_CHECK(grib_set_double(gh, "scaledValueOfFirstFixedSurface", level1*scale), 0);
+
+                getLevelFactor(level, &factor, &scale);
 		if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfSecondFixedSurface", GRIB2_LTYPE_LANDDEPTH), 0);
 		GRIB_CHECK(grib_set_long(gh, "scaleFactorOfSecondFixedSurface", factor), 0);
-		GRIB_CHECK(grib_set_double(gh, "scaledValueOfSecondFixedSurface", level2), 0);
+		GRIB_CHECK(grib_set_double(gh, "scaledValueOfSecondFixedSurface", level2*scale), 0);
 	      }
 	    else
 	      {
+                level *= scalefactor;
+                getLevelFactor(level, &factor, &scale);
 		if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_LANDDEPTH), 0);
 		GRIB_CHECK(grib_set_long(gh, "scaleFactorOfFirstFixedSurface", factor), 0);
-	       	GRIB_CHECK(grib_set_double(gh, "scaledValueOfFirstFixedSurface", level), 0);
+	       	GRIB_CHECK(grib_set_double(gh, "scaledValueOfFirstFixedSurface", level*scale), 0);
 	      }
 	  }
 
@@ -32988,13 +33406,12 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
           {
             reference = zaxisInqReference(zaxisID);
             if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_REFERENCE), 0);
-            GRIB_CHECK(grib_set_double(gh, "level", level), 0);
-
-            GRIB_CHECK(grib_set_long(gh, "NV", 3), 0);
-            GRIB_CHECK(grib_set_long(gh, "nlev", (long) zaxisInqSize(zaxisID)), 0);
-            GRIB_CHECK(grib_set_long(gh, "numberOfVGridUsed", reference), 0);
+            GRIB_CHECK(grib_set_long(gh, "NV", 6), 0);
+            GRIB_CHECK(grib_set_double(gh, "nlev", (double) zaxisInqSize(zaxisID)), 0);
+            GRIB_CHECK(grib_set_double(gh, "numberOfVGridUsed", (double) reference), 0);
             len = 16;
-            GRIB_CHECK(grib_set_string(gh, "uuidOfVGrid", zaxisInqUUID(zaxisID, uuid), &len), 0);
+            GRIB_CHECK(grib_set_bytes(gh, "uuidOfVGrid", (unsigned char *) zaxisInqUUID(zaxisID, uuid), &len), 0);
+            GRIB_CHECK(grib_set_double(gh, "level", level), 0);
           }
 
         break;
@@ -33108,6 +33525,27 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
 
   gribapiDefLevel(editionNumber, gh, param, zaxisID, levelID, gc->init);
 
+  /* ---------------------------------- */
+  /* Local change: 2013-01-28, FP (DWD) */
+  /* ---------------------------------- */
+
+  vlist_t *vlistptr;
+  vlistptr = vlist_to_pointer(vlistID);
+  if (!gc->init) {
+    int i;
+    for (i=0; i<vlistptr->vars[varID].opt_grib_dbl_nentries; i++)
+      {
+	GRIB_CHECK(grib_set_double(gh, vlistptr->vars[varID].opt_grib_dbl_keyword[i],
+				   vlistptr->vars[varID].opt_grib_dbl_val[i]), 0);
+      }
+    for (i=0; i<vlistptr->vars[varID].opt_grib_int_nentries; i++)
+      {
+	GRIB_CHECK(grib_set_long(gh, vlistptr->vars[varID].opt_grib_int_keyword[i],
+				 vlistptr->vars[varID].opt_grib_int_val[i]), 0);
+      }
+  }
+
+
   if ( nmiss > 0 )
     {
       GRIB_CHECK(grib_set_long(gh, "bitmapPresent", 1), 0);
@@ -33165,23 +33603,26 @@ int grib1ltypeToZaxisType(int grib_ltype)
 
   switch ( grib_ltype )
     {
-    case GRIB1_LTYPE_SURFACE:         { zaxistype = ZAXIS_SURFACE;           break; }
-    case GRIB1_LTYPE_TOA:             { zaxistype = ZAXIS_TOA;               break; }
-    case GRIB1_LTYPE_SEA_BOTTOM:      { zaxistype = ZAXIS_SEA_BOTTOM;        break; }
-    case GRIB1_LTYPE_ATMOSPHERE:      { zaxistype = ZAXIS_ATMOSPHERE;        break; }
-    case GRIB1_LTYPE_MEANSEA:         { zaxistype = ZAXIS_MEANSEA;           break; }
+    case GRIB1_LTYPE_SURFACE:            { zaxistype = ZAXIS_SURFACE;           break; }
+    case GRIB1_LTYPE_CLOUDBASE:          { zaxistype = ZAXIS_CLOUD_BASE;        break; }
+    case GRIB1_LTYPE_CLOUDTOP:           { zaxistype = ZAXIS_CLOUD_TOP;         break; }
+    case GRIB1_LTYPE_ISOTHERM0:          { zaxistype = ZAXIS_ISOTHERM_ZERO;     break; }
+    case GRIB1_LTYPE_TOA:                { zaxistype = ZAXIS_TOA;               break; }
+    case GRIB1_LTYPE_SEA_BOTTOM:         { zaxistype = ZAXIS_SEA_BOTTOM;        break; }
+    case GRIB1_LTYPE_ATMOSPHERE:         { zaxistype = ZAXIS_ATMOSPHERE;        break; }
+    case GRIB1_LTYPE_MEANSEA:            { zaxistype = ZAXIS_MEANSEA;           break; }
     case GRIB1_LTYPE_99:
-    case GRIB1_LTYPE_ISOBARIC:        { zaxistype = ZAXIS_PRESSURE;          break; }
-    case GRIB1_LTYPE_HEIGHT:          { zaxistype = ZAXIS_HEIGHT;            break; }
-    case GRIB1_LTYPE_ALTITUDE:        { zaxistype = ZAXIS_ALTITUDE;	     break; }
+    case GRIB1_LTYPE_ISOBARIC:           { zaxistype = ZAXIS_PRESSURE;          break; }
+    case GRIB1_LTYPE_HEIGHT:             { zaxistype = ZAXIS_HEIGHT;            break; }
+    case GRIB1_LTYPE_ALTITUDE:           { zaxistype = ZAXIS_ALTITUDE;	     break; }
     case GRIB1_LTYPE_SIGMA:
-    case GRIB1_LTYPE_SIGMA_LAYER:     { zaxistype = ZAXIS_SIGMA;	     break; }
+    case GRIB1_LTYPE_SIGMA_LAYER:        { zaxistype = ZAXIS_SIGMA;	     break; }
     case GRIB1_LTYPE_HYBRID:
-    case GRIB1_LTYPE_HYBRID_LAYER:    { zaxistype = ZAXIS_HYBRID;	     break; }
+    case GRIB1_LTYPE_HYBRID_LAYER:       { zaxistype = ZAXIS_HYBRID;	     break; }
     case GRIB1_LTYPE_LANDDEPTH:
-    case GRIB1_LTYPE_LANDDEPTH_LAYER: { zaxistype = ZAXIS_DEPTH_BELOW_LAND;  break; }
-    case GRIB1_LTYPE_ISENTROPIC:      { zaxistype = ZAXIS_ISENTROPIC;	     break; }
-    case GRIB1_LTYPE_SEADEPTH:        { zaxistype = ZAXIS_DEPTH_BELOW_SEA;   break; }
+    case GRIB1_LTYPE_LANDDEPTH_LAYER:    { zaxistype = ZAXIS_DEPTH_BELOW_LAND;  break; }
+    case GRIB1_LTYPE_ISENTROPIC:         { zaxistype = ZAXIS_ISENTROPIC;	     break; }
+    case GRIB1_LTYPE_SEADEPTH:           { zaxistype = ZAXIS_DEPTH_BELOW_SEA;   break; }
     }
 
   return (zaxistype);
@@ -33195,6 +33636,9 @@ int grib2ltypeToZaxisType(int grib_ltype)
   switch ( grib_ltype )
     {
     case GRIB2_LTYPE_SURFACE:            { zaxistype = ZAXIS_SURFACE;           break; }
+    case GRIB2_LTYPE_CLOUDBASE:          { zaxistype = ZAXIS_CLOUD_BASE;        break; }
+    case GRIB2_LTYPE_CLOUDTOP:           { zaxistype = ZAXIS_CLOUD_TOP;         break; }
+    case GRIB2_LTYPE_ISOTHERM0:          { zaxistype = ZAXIS_ISOTHERM_ZERO;     break; }
     case GRIB2_LTYPE_TOA:                { zaxistype = ZAXIS_TOA;               break; }
     case GRIB2_LTYPE_SEA_BOTTOM:         { zaxistype = ZAXIS_SEA_BOTTOM;        break; }
     case GRIB2_LTYPE_ATMOSPHERE:         { zaxistype = ZAXIS_ATMOSPHERE;        break; }
@@ -33237,24 +33681,19 @@ int grbBitsPerValue(int datatype)
 
 
 /*
-int grbInqRecord(int streamID, int *varID, int *levelID)
+int grbInqRecord(stream_t * streamptr, int *varID, int *levelID)
 {
   int status;
 
-  status = cgribexInqRecord(streamID, varID, levelID);
+  status = cgribexInqRecord(streamptr, varID, levelID);
 
   return (status);
 }
 */
 
-int grbDefRecord(int streamID)
+int grbDefRecord(stream_t * streamptr)
 {
   int status = 0;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   return (status);
 }
@@ -33271,12 +33710,12 @@ int grbDecode(int filetype, unsigned char *gribbuffer, int gribsize, double *dat
   else
 #endif
     status = gribapiDecode(gribbuffer, gribsize, data, gridsize, unreduced, nmiss, zip, missval);
- 
+
   return (status);
 }
 
 
-int grbReadRecord(int streamID, double *data, int *nmiss)
+int grbReadRecord(stream_t * streamptr, double *data, int *nmiss)
 {
   int status = 0;
   unsigned char *gribbuffer;
@@ -33289,18 +33728,13 @@ int grbReadRecord(int streamID, double *data, int *nmiss)
   int zip;
   int filetype;
   double missval;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   filetype = streamptr->filetype;
 
   gribbuffer = (unsigned char *) streamptr->record->buffer;
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
   tsID    = streamptr->curTsID;
   vrecID  = streamptr->tsteps[tsID].curRecID;
   recID   = streamptr->tsteps[tsID].recIDs[vrecID];
@@ -33327,95 +33761,84 @@ int grbReadRecord(int streamID, double *data, int *nmiss)
 }
 
 static
-int grbScanTimestep1(int streamID)
+int grbScanTimestep1(stream_t * streamptr)
 {
   int status;
   int filetype;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
   filetype  = streamptr->filetype;
 
 #if  defined  (HAVE_LIBCGRIBEX)
   if ( filetype == FILETYPE_GRB )
     {
-      status = cgribexScanTimestep1(streamID);
+      status = cgribexScanTimestep1(streamptr);
     }
   else
 #endif
     {
-      status = gribapiScanTimestep1(streamID);
+      status = gribapiScanTimestep1(streamptr);
     }
 
   return (status);
 }
 
 static
-int grbScanTimestep2(int streamID)
+int grbScanTimestep2(stream_t * streamptr)
 {
   int status;
   int filetype;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
   filetype  = streamptr->filetype;
 
 #if  defined  (HAVE_LIBCGRIBEX)
   if ( filetype == FILETYPE_GRB )
     {
-      status = cgribexScanTimestep2(streamID);
+      status = cgribexScanTimestep2(streamptr);
     }
   else
 #endif
     {
-      status = gribapiScanTimestep2(streamID);
+      status = gribapiScanTimestep2(streamptr);
     }
 
   return (status);
 }
 
 static
-int grbScanTimestep(int streamID)
+int grbScanTimestep(stream_t * streamptr)
 {
   int status;
   int filetype;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
   filetype  = streamptr->filetype;
 
 #if  defined  (HAVE_LIBCGRIBEX)
   if ( filetype == FILETYPE_GRB )
     {
-      status = cgribexScanTimestep(streamID);
+      status = cgribexScanTimestep(streamptr);
     }
   else
 #endif
     {
-      status = gribapiScanTimestep(streamID);
+      status = gribapiScanTimestep(streamptr);
     }
 
   return (status);
 }
 
 
-int grbInqContents(int streamID)
+int grbInqContents(stream_t * streamptr)
 {
   int fileID;
   int status = 0;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
 
   streamptr->curTsID = 0;
 
-  status = grbScanTimestep1(streamID);
- 
-  if ( status == 0 && streamptr->ntsteps == -1 ) status = grbScanTimestep2(streamID);
+  status = grbScanTimestep1(streamptr);
+
+  if ( status == 0 && streamptr->ntsteps == -1 ) status = grbScanTimestep2(streamptr);
 
   fileSetPos(fileID, 0, SEEK_SET);
 
@@ -33423,25 +33846,20 @@ int grbInqContents(int streamID)
 }
 
 
-int grbInqTimestep(int streamID, int tsID)
+int grbInqTimestep(stream_t * streamptr, int tsID)
 {
   int ntsteps, nrecs;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   if ( tsID == 0 && streamptr->rtsteps == 0 )
     Error("Call to cdiInqContents missing!");
 
   if ( CDI_Debug )
     Message("tsid = %d rtsteps = %d", tsID, streamptr->rtsteps);
-  
+
   ntsteps = CDI_UNDEFID;
   while ( (tsID + 1) > streamptr->rtsteps && ntsteps == CDI_UNDEFID )
     {
-      ntsteps = grbScanTimestep(streamID);
+      ntsteps = grbScanTimestep(streamptr);
       if ( ntsteps == CDI_EUFSTRUCT )
 	{
 	  streamptr->ntsteps = streamptr->rtsteps;
@@ -33463,7 +33881,7 @@ int grbInqTimestep(int streamID, int tsID)
 }
 
 
-void grbReadVarDP(int streamID, int varID, double *data, int *nmiss)
+void grbReadVarDP(stream_t * streamptr, int varID, double *data, int *nmiss)
 {
   int fileID;
   int levelID, nlevs, gridID, gridsize;
@@ -33476,18 +33894,13 @@ void grbReadVarDP(int streamID, int varID, double *data, int *nmiss)
   int zip;
   int filetype;
   double missval;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   filetype = streamptr->filetype;
 
   gribbuffer = (unsigned char *) streamptr->record->buffer;
 
-  vlistID  = streamInqVlist(streamID);
-  fileID   = streamInqFileID(streamID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   tsID     = streamptr->curTsID;
 
   nlevs    = streamptr->vars[varID].nlevs;
@@ -33512,7 +33925,7 @@ void grbReadVarDP(int streamID, int varID, double *data, int *nmiss)
 
       missval = vlistInqVarMissval(vlistID, varID);
 
-      grbDecode(filetype, gribbuffer, recsize, &data[levelID*gridsize], gridsize, 
+      grbDecode(filetype, gribbuffer, recsize, &data[levelID*gridsize], gridsize,
 		streamptr->unreduced, &imiss, &zip, missval);
 
       *nmiss += imiss;
@@ -33524,7 +33937,7 @@ void grbReadVarDP(int streamID, int varID, double *data, int *nmiss)
 }
 
 
-void grbReadVarSliceDP(int streamID, int varID, int levelID, double *data, int *nmiss)
+void grbReadVarSliceDP(stream_t * streamptr, int varID, int levelID, double *data, int *nmiss)
 {
   int fileID;
   int gridID, gridsize;
@@ -33536,17 +33949,12 @@ void grbReadVarSliceDP(int streamID, int varID, int levelID, double *data, int *
   int zip;
   int filetype;
   double missval;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   filetype = streamptr->filetype;
 
   gribbuffer = (unsigned char *) streamptr->record->buffer;
 
-  vlistID  = streamInqVlist(streamID);
+  vlistID  = streamptr->vlistID;
   gridID   = vlistInqVarGrid(vlistID, varID);
   gridsize = gridInqSize(gridID);
   tsID     = streamptr->curTsID;
@@ -33554,7 +33962,7 @@ void grbReadVarSliceDP(int streamID, int varID, int levelID, double *data, int *
   if ( CDI_Debug )
     Message("gridID = %d gridsize = %d", gridID, gridsize);
 
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
 
   currentfilepos = fileGetPos(fileID);
 
@@ -33581,7 +33989,7 @@ void grbReadVarSliceDP(int streamID, int varID, int levelID, double *data, int *
 
 static
 size_t grbEncode(int filetype, int varID, int levelID, int vlistID, int gridID, int zaxisID,
-		 int date, int time, int tsteptype, int numavg, 
+		 int date, int time, int tsteptype, int numavg,
 		 long datasize, const double *data, int nmiss, unsigned char **gribbuffer,
 		 int ljpeg, void *gribContainer)
 {
@@ -33595,14 +34003,14 @@ size_t grbEncode(int filetype, int varID, int levelID, int vlistID, int gridID,
       *gribbuffer = (unsigned char *) malloc(gribbuffersize);
 
       nbytes = cgribexEncode(varID, levelID, vlistID, gridID, zaxisID,
-			     date, time, tsteptype, numavg, 
+			     date, time, tsteptype, numavg,
 			     datasize, data, nmiss, *gribbuffer, gribbuffersize);
     }
   else
 #endif
     {
       nbytes = gribapiEncode(varID, levelID, vlistID, gridID, zaxisID,
-			     date, time, tsteptype, numavg, 
+			     date, time, tsteptype, numavg,
 			     datasize, data, nmiss, gribbuffer, &gribbuffersize,
 			     ljpeg, gribContainer);
     }
@@ -33640,7 +34048,7 @@ size_t grbSzip(int filetype, unsigned char *gribbuffer, size_t gribbuffersize)
 }
 
 
-int grbWriteVarSliceDP(int streamID, int varID, int levelID, const double *data, int nmiss)
+int grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, int nmiss)
 {
   size_t nwrite;
   int fileID;
@@ -33655,19 +34063,15 @@ int grbWriteVarSliceDP(int streamID, int varID, int levelID, const double *data,
   int numavg = 0;
   size_t nbytes;
   int filetype;
-  stream_t *streamptr;
   int ljpeg = 0;
   int ljpeg_warn = 1;
   void *gc = NULL;
 
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
+  if ( memtype == MEMTYPE_FLOAT ) Error("cdf_write_var_slice not implemented for memtype float!");
 
   filetype  = streamptr->filetype;
-
-  fileID    = streamInqFileID(streamID);
-  vlistID   = streamInqVlist(streamID);
+  fileID    = streamptr->fileID;
+  vlistID   = streamptr->vlistID;
   gridID    = vlistInqVarGrid(vlistID, varID);
   zaxisID   = vlistInqVarZaxis(vlistID, varID);
   tsteptype = vlistInqVarTsteptype(vlistID, varID);
@@ -33738,12 +34142,12 @@ int grbWriteVarSliceDP(int streamID, int varID, int levelID, const double *data,
 }
 
 
-void grbWriteVarDP(int streamID, int varID, const double *data, int nmiss)
+void grb_write_var(stream_t *streamptr, int varID, int memtype, const void *data, int nmiss)
 {
   int vlistID, gridID, zaxisID, levelID, nlevs;
   int gridsize;
 
-  vlistID  = streamInqVlist(streamID);
+  vlistID  = streamptr->vlistID;
   gridID   = vlistInqVarGrid(vlistID, varID);
   gridsize = gridInqSize(gridID);
   zaxisID  = vlistInqVarZaxis(vlistID, varID);
@@ -33751,12 +34155,15 @@ void grbWriteVarDP(int streamID, int varID, const double *data, int nmiss)
 
   for ( levelID = 0; levelID < nlevs; levelID++ )
     {
-      grbWriteVarSliceDP(streamID, varID, levelID, data+levelID*gridsize, nmiss);
+      if ( memtype == MEMTYPE_FLOAT )
+        grb_write_var_slice(streamptr, varID, levelID, memtype, ((float*)data)+levelID*gridsize, nmiss);
+      else
+        grb_write_var_slice(streamptr, varID, levelID, memtype, ((double*)data)+levelID*gridsize, nmiss);
     }
 }
 
 
-int grbCopyRecord(int streamID2, int streamID1)
+int grbCopyRecord(stream_t * streamptr2, stream_t * streamptr1)
 {
   int fileID1, fileID2;
   int tsID, recID, vrecID;
@@ -33769,19 +34176,11 @@ int grbCopyRecord(int streamID2, int streamID1)
   size_t nbytes;
   long unzipsize;
   int izip;
-  stream_t *streamptr1;
-  stream_t *streamptr2;
-
-  streamptr1 = stream_to_pointer(streamID1);
-  streamptr2 = stream_to_pointer(streamID2);
-
-  stream_check_ptr(__func__, streamptr1);
-  stream_check_ptr(__func__, streamptr2);
 
   filetype = streamptr1->filetype;
 
-  fileID1 = streamInqFileID(streamID1);
-  fileID2 = streamInqFileID(streamID2);
+  fileID1 = streamptr1->fileID;
+  fileID2 = streamptr2->fileID;
 
   tsID    = streamptr1->curTsID;
   vrecID  = streamptr1->tsteps[tsID].curRecID;
@@ -33816,20 +34215,15 @@ int grbCopyRecord(int streamID2, int streamID1)
 }
 
 
-int grbWriteRecord(int streamID, const double *data, int nmiss)
+int grb_write_record(stream_t * streamptr, int memtype, const void *data, int nmiss)
 {
   int status = 0;
   int varID, levelID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   varID   = streamptr->record->varID;
   levelID = streamptr->record->levelID;
 
-  status = grbWriteVarSliceDP(streamID, varID, levelID, data, nmiss);
+  status = grb_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
 
   return (status);
 }
@@ -33898,7 +34292,7 @@ void streamInqGinfo(int streamID, int *intnum, float *fltnum)
 typedef struct {
   int param;
   int level;
-} SRVCOMPVAR; 
+} SRVCOMPVAR;
 
 
 int srvInqDatatype(int prec)
@@ -33929,7 +34323,7 @@ int srvDefDatatype(int datatype)
 }
 
 /* not used
-int srvInqRecord(int streamID, int *varID, int *levelID)
+int srvInqRecord(stream_t *streamptr, int *varID, int *levelID)
 {
   int status;
   int fileID;
@@ -33938,14 +34332,9 @@ int srvInqRecord(int streamID, int *varID, int *levelID)
   int header[8];
   int vlistID;
   srvrec_t *srvp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
   srvp    = streamptr->record->srvp;
 
   *varID   = -1;
@@ -33966,12 +34355,12 @@ int srvInqRecord(int streamID, int *varID, int *levelID)
   zaxisID = vlistInqVarZaxis(vlistID, *varID);
 
   *levelID = zaxisInqLevelID(zaxisID, (double) ilevel);
-  
+
   return (1);
 }
 */
 
-int srvReadRecord(int streamID, double *data, int *nmiss)
+int srvReadRecord(stream_t *streamptr, double *data, int *nmiss)
 {
   int vlistID, fileID;
   int status;
@@ -33982,14 +34371,9 @@ int srvReadRecord(int streamID, double *data, int *nmiss)
   int i, size;
   double missval;
   srvrec_t *srvp;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
-
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
   tsID    = streamptr->curTsID;
   vrecID  = streamptr->tsteps[tsID].curRecID;
   recID   = streamptr->tsteps[tsID].recIDs[vrecID];
@@ -34023,7 +34407,7 @@ int srvReadRecord(int streamID, double *data, int *nmiss)
 }
 
 
-int srvCopyRecord(int streamID2, int streamID1)
+int srvCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
 {
   int fileID1, fileID2;
   int tsID, recID, vrecID;
@@ -34031,17 +34415,9 @@ int srvCopyRecord(int streamID2, int streamID1)
   off_t recpos;
   int status = 0;
   char *buffer;
-  stream_t *streamptr1;
-  stream_t *streamptr2;
 
-  streamptr1 = stream_to_pointer(streamID1);
-  streamptr2 = stream_to_pointer(streamID2);
-
-  stream_check_ptr(__func__, streamptr1);
-  stream_check_ptr(__func__, streamptr2);
-
-  fileID1 = streamInqFileID(streamID1);
-  fileID2 = streamInqFileID(streamID2);
+  fileID1 = streamptr1->fileID;
+  fileID2 = streamptr2->fileID;
 
   tsID    = streamptr1->curTsID;
   vrecID  = streamptr1->tsteps[tsID].curRecID;
@@ -34063,7 +34439,7 @@ int srvCopyRecord(int streamID2, int streamID1)
 }
 
 
-int srvDefRecord(int streamID)
+int srvDefRecord(stream_t *streamptr)
 {
   int gridID;
   int header[8];
@@ -34072,11 +34448,6 @@ int srvDefRecord(int streamID)
   int datatype;
   int pdis, pcat, pnum;
   srvrec_t *srvp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   gridID = streamptr->record->gridID;
   srvp   = streamptr->record->srvp;
@@ -34113,18 +34484,13 @@ int srvDefRecord(int streamID)
 }
 
 
-int srvWriteRecord(int streamID, const double *data)
+int srvWriteRecord(stream_t *streamptr, const double *data)
 {
   int fileID;
   int status = 0;
   srvrec_t *srvp;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
-
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
   srvp   = streamptr->record->srvp;
 
   srvDefDataDP(srvp, data);
@@ -34134,9 +34500,9 @@ int srvWriteRecord(int streamID, const double *data)
   return (status);
 }
 
-
-void srvAddRecord(int streamID, int param, int level, int xsize, int ysize,
-		  long recsize, off_t position, int prec)
+static
+void srv_add_record(stream_t *streamptr, int param, int level, int xsize, int ysize,
+                    long recsize, off_t position, int prec)
 {
   int leveltype;
   int gridID = UNDEFID;
@@ -34146,13 +34512,10 @@ void srvAddRecord(int streamID, int param, int level, int xsize, int ysize,
   record_t *record;
   grid_t grid;
   int vlistID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   tsID    = streamptr->curTsID;
-  recID   = recordNewEntry(streamID, tsID);
+  recID   = recordNewEntry(streamptr, tsID);
   record  = &streamptr->tsteps[tsID].records[recID];
 
   (*record).size     = recsize;
@@ -34161,7 +34524,7 @@ void srvAddRecord(int streamID, int param, int level, int xsize, int ysize,
   (*record).ilevel   = level;
 
   memset(&grid, 0, sizeof(grid_t));
-  grid.type  = GRID_GENERIC; 
+  grid.type  = GRID_GENERIC;
   grid.size  = xsize*ysize;
   grid.xsize = xsize;
   grid.ysize = ysize;
@@ -34176,7 +34539,7 @@ void srvAddRecord(int streamID, int param, int level, int xsize, int ysize,
 
   datatype = srvInqDatatype(prec);
 
-  varAddRecord(recID, param, gridID, leveltype, 0, level, 0,
+  varAddRecord(recID, param, gridID, leveltype, 0, level, 0, 0,
 	       datatype, &varID, &levelID, UNDEFID, 0, 0, NULL, NULL, NULL);
 
   (*record).varID   = varID;
@@ -34191,15 +34554,12 @@ void srvAddRecord(int streamID, int param, int level, int xsize, int ysize,
 }
 
 
-void srvCmpRecord(int streamID, int tsID, int recID, off_t position, int param,
+void srvCmpRecord(stream_t *streamptr, int tsID, int recID, off_t position, int param,
 		  int level, int xsize, int ysize)
 {
   int varID = 0;
   int levelID = 0;
   record_t *record;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   record  = &streamptr->tsteps[tsID].records[recID];
 
@@ -34221,8 +34581,8 @@ void srvCmpRecord(int streamID, int tsID, int recID, off_t position, int param,
 }
 
 static
-void srvScanTimestep1(int streamID)
-{  
+void srvScanTimestep1(stream_t *streamptr)
+{
   int header[8];
   int prec = 0;
   int status;
@@ -34241,22 +34601,17 @@ void srvScanTimestep1(int streamID)
   int vlistID;
   SRVCOMPVAR compVar, compVar0;
   srvrec_t *srvp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   streamptr->curTsID = 0;
 
   srvp  = streamptr->record->srvp;
-  tsID  = tstepsNewEntry(streamID);
+  tsID  = tstepsNewEntry(streamptr);
   taxis = &streamptr->tsteps[tsID].taxis;
 
   if ( tsID != 0 )
     Error("Internal problem! tstepsNewEntry returns %d", tsID);
 
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
 
   nrecs = 0;
   while ( TRUE )
@@ -34310,22 +34665,22 @@ void srvScanTimestep1(int streamID)
       if ( CDI_Debug )
 	Message("%4d%8d%4d%8d%8d%6d", nrecs, (int)recpos, rcode, rlevel, vdate, vtime);
 
-      srvAddRecord(streamID, param, rlevel, rxsize, rysize, recsize, recpos, prec);
+      srv_add_record(streamptr, param, rlevel, rxsize, rysize, recsize, recpos, prec);
     }
 
   streamptr->rtsteps = 1;
 
-  cdiGenVars(streamID);
+  cdi_generate_vars(streamptr);
 
   taxisID = taxisCreate(TAXIS_ABSOLUTE);
   taxis->type  = TAXIS_ABSOLUTE;
   taxis->vdate = datetime0.date;
   taxis->vtime = datetime0.time;
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   vlistDefTaxis(vlistID, taxisID);
 
-  cdiCheckContents(streamID);
+  vlist_check_contents(vlistID);
 
   nrecords = streamptr->tsteps[0].nallrecs;
   if ( nrecords < streamptr->tsteps[0].recordSize )
@@ -34342,7 +34697,7 @@ void srvScanTimestep1(int streamID)
 
   if ( streamptr->ntsteps == -1 )
     {
-      tsID = tstepsNewEntry(streamID);
+      tsID = tstepsNewEntry(streamptr);
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
@@ -34364,8 +34719,8 @@ void srvScanTimestep1(int streamID)
 }
 
 static
-int srvScanTimestep2(int streamID)
-{  
+int srvScanTimestep2(stream_t *streamptr)
+{
   int header[8];
   int status;
   int fileID;
@@ -34381,16 +34736,11 @@ int srvScanTimestep2(int streamID)
   int vlistID;
   SRVCOMPVAR compVar, compVar0;
   srvrec_t *srvp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   streamptr->curTsID = 1;
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
   srvp    = streamptr->record->srvp;
 
   tsID = streamptr->rtsteps;
@@ -34401,7 +34751,7 @@ int srvScanTimestep2(int streamID)
 
   fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-  cdiCreateRecords(streamID, tsID);
+  cdi_create_records(streamptr, tsID);
 
   nrecords = streamptr->tsteps[0].nallrecs;
   streamptr->tsteps[1].recIDs = (int *) malloc(nrecords*sizeof(int));
@@ -34412,9 +34762,9 @@ int srvScanTimestep2(int streamID)
   for ( recID = 0; recID < nrecords; recID++ )
     {
       varID = streamptr->tsteps[0].records[recID].varID;
-      streamptr->tsteps[tsID].records[recID].position = 
+      streamptr->tsteps[tsID].records[recID].position =
 	streamptr->tsteps[0].records[recID].position;
-      streamptr->tsteps[tsID].records[recID].size     = 
+      streamptr->tsteps[tsID].records[recID].size     =
 	streamptr->tsteps[0].records[recID].size;
     }
 
@@ -34514,7 +34864,7 @@ int srvScanTimestep2(int streamID)
 
   if ( streamptr->ntsteps == -1 )
     {
-      tsID = tstepsNewEntry(streamID);
+      tsID = tstepsNewEntry(streamptr);
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
@@ -34526,23 +34876,18 @@ int srvScanTimestep2(int streamID)
 }
 
 
-int srvInqContents(int streamID)
+int srvInqContents(stream_t *streamptr)
 {
   int fileID;
   int status = 0;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  stream_check_ptr(__func__, streamptr);
-
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
 
   streamptr->curTsID = 0;
 
-  srvScanTimestep1(streamID);
- 
-  if ( streamptr->ntsteps == -1 ) status = srvScanTimestep2(streamID);
+  srvScanTimestep1(streamptr);
+
+  if ( streamptr->ntsteps == -1 ) status = srvScanTimestep2(streamptr);
 
   fileSetPos(fileID, 0, SEEK_SET);
 
@@ -34550,7 +34895,7 @@ int srvInqContents(int streamID)
 }
 
 static
-int srvScanTimestep(int streamID)
+int srvScanTimestep(stream_t *streamptr)
 {
   int header[8];
   int status;
@@ -34566,15 +34911,10 @@ int srvScanTimestep(int streamID)
   int rindex, nrecs = 0;
   SRVCOMPVAR compVar, compVar0;
   srvrec_t *srvp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   if ( CDI_Debug )
     {
-      Message("streamID = %d", streamID);
+      Message("streamID = %d", streamptr->self);
       Message("cts = %d", streamptr->curTsID);
       Message("rts = %d", streamptr->rtsteps);
       Message("nts = %d", streamptr->ntsteps);
@@ -34589,7 +34929,7 @@ int srvScanTimestep(int streamID)
 
   if ( streamptr->tsteps[tsID].recordSize == 0 )
     {
-      cdiCreateRecords(streamID, tsID);
+      cdi_create_records(streamptr, tsID);
 
       nrecs = streamptr->tsteps[1].nrecs;
 
@@ -34598,7 +34938,7 @@ int srvScanTimestep(int streamID)
       for ( recID = 0; recID < nrecs; recID++ )
 	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
 
-      fileID = streamInqFileID(streamID);
+      fileID = streamptr->fileID;
 
       fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
@@ -34635,7 +34975,7 @@ int srvScanTimestep(int streamID)
 	      taxis->vtime = vtime;
 	    }
 	  /*
-	  srvCmpRecord(streamID, tsID, nrecs, recpos, param, rlevel, rxsize, rysize);
+	  srvCmpRecord(streamptr, tsID, nrecs, recpos, param, rlevel, rxsize, rysize);
 	  */
 	  compVar.param  = param;
           compVar.level  = rlevel;
@@ -34662,7 +35002,7 @@ int srvScanTimestep(int streamID)
 
       if ( streamptr->ntsteps != streamptr->rtsteps )
 	{
-	  tsID = tstepsNewEntry(streamID);
+	  tsID = tstepsNewEntry(streamptr);
 	  if ( tsID != streamptr->rtsteps )
 	    Error("Internal error. tsID = %d", tsID);
 
@@ -34684,24 +35024,19 @@ int srvScanTimestep(int streamID)
 }
 
 
-int srvInqTimestep(int streamID, int tsID)
+int srvInqTimestep(stream_t *streamptr, int tsID)
 {
   int ntsteps, nrecs;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   if ( tsID == 0 && streamptr->rtsteps == 0 )
     Error("Call to cdiInqContents missing!");
 
   if ( CDI_Debug )
     Message("tsID = %d rtsteps = %d", tsID, streamptr->rtsteps);
-  
+
   ntsteps = UNDEFID;
   while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == UNDEFID )
-    ntsteps = srvScanTimestep(streamID);
+    ntsteps = srvScanTimestep(streamptr);
 
   if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID )
     {
@@ -34717,7 +35052,7 @@ int srvInqTimestep(int streamID, int tsID)
 }
 
 
-void srvReadVarDP(int streamID, int varID, double *data, int *nmiss)
+void srvReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
 {
   int vlistID, fileID;
   int levID, nlevs, gridID, gridsize;
@@ -34728,13 +35063,10 @@ void srvReadVarDP(int streamID, int varID, double *data, int *nmiss)
   int i;
   double missval;
   srvrec_t *srvp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   srvp     = streamptr->record->srvp;
-  vlistID  = streamInqVlist(streamID);
-  fileID   = streamInqFileID(streamID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   nlevs    = streamptr->vars[varID].nlevs;
   missval  = vlistInqVarMissval(vlistID, varID);
   gridID   = vlistInqVarGrid(vlistID, varID);
@@ -34767,7 +35099,7 @@ void srvReadVarDP(int streamID, int varID, double *data, int *nmiss)
 }
 
 
-void srvReadVarSliceDP(int streamID, int varID, int levID, double *data, int *nmiss)
+void srvReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, int *nmiss)
 {
   int vlistID, fileID;
   int nlevs, gridID, gridsize;
@@ -34778,13 +35110,10 @@ void srvReadVarSliceDP(int streamID, int varID, int levID, double *data, int *nm
   int i;
   double missval;
   srvrec_t *srvp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   srvp     = streamptr->record->srvp;
-  vlistID  = streamInqVlist(streamID);
-  fileID   = streamInqFileID(streamID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   nlevs    = streamptr->vars[varID].nlevs;
   missval  = vlistInqVarMissval(vlistID, varID);
   gridID   = vlistInqVarGrid(vlistID, varID);
@@ -34816,7 +35145,7 @@ void srvReadVarSliceDP(int streamID, int varID, int levID, double *data, int *nm
 }
 
 
-void srvWriteVarDP(int streamID, int varID, const double *data)
+void srvWriteVarDP(stream_t *streamptr, int varID, const double *data)
 {
   int fileID;
   int levID, nlevs, gridID, gridsize;
@@ -34829,16 +35158,13 @@ void srvWriteVarDP(int streamID, int varID, const double *data)
   int vlistID;
   int pdis, pcat, pnum;
   srvrec_t *srvp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   if ( CDI_Debug )
-    Message("streamID = %d  varID = %d", streamID, varID);
+    Message("streamID = %d  varID = %d", streamptr->self, varID);
 
   srvp     = streamptr->record->srvp;
-  vlistID  = streamInqVlist(streamID);
-  fileID   = streamInqFileID(streamID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   tsID     = streamptr->curTsID;
   gridID   = vlistInqVarGrid(vlistID, varID);
   gridsize = gridInqSize(gridID);
@@ -34886,7 +35212,7 @@ void srvWriteVarDP(int streamID, int varID, const double *data)
 }
 
 
-void srvWriteVarSliceDP(int streamID, int varID, int levID, const double *data)
+void srvWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double *data)
 {
   int fileID;
   int gridID;
@@ -34899,13 +35225,10 @@ void srvWriteVarSliceDP(int streamID, int varID, int levID, const double *data)
   int vlistID;
   int pdis, pcat, pnum;
   srvrec_t *srvp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   srvp     = streamptr->record->srvp;
-  vlistID  = streamInqVlist(streamID);
-  fileID   = streamInqFileID(streamID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   tsID     = streamptr->curTsID;
   gridID   = vlistInqVarGrid(vlistID, varID);
   zaxisID  = vlistInqVarZaxis(vlistID, varID);
@@ -34977,7 +35300,7 @@ void srvWriteVarSliceDP(int streamID, int varID, int levID, const double *data)
 typedef struct {
   int param;
   int level;
-} extcompvar_t; 
+} extcompvar_t;
 
 static
 int extInqDatatype(int prec, int number)
@@ -35018,7 +35341,7 @@ void extDefDatatype(int datatype, int *prec, int *number)
 }
 
 /* not used
-int extInqRecord(int streamID, int *varID, int *levelID)
+int extInqRecord(stream_t *streamptr, int *varID, int *levelID)
 {
   int status;
   int fileID;
@@ -35027,14 +35350,9 @@ int extInqRecord(int streamID, int *varID, int *levelID)
   int header[4];
   int vlistID;
   extrec_t *extp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  stream_check_ptr(__func__, streamptr);
-
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
   extp    = streamptr->record->extp;
 
   *varID   = -1;
@@ -35055,12 +35373,12 @@ int extInqRecord(int streamID, int *varID, int *levelID)
   zaxisID = vlistInqVarZaxis(vlistID, *varID);
 
   *levelID = zaxisInqLevelID(zaxisID, (double) ilevel);
-  
+
   return (1);
 }
 */
 
-int extReadRecord(int streamID, double *data, int *nmiss)
+int extReadRecord(stream_t *streamptr, double *data, int *nmiss)
 {
   int vlistID, fileID;
   int status;
@@ -35071,14 +35389,9 @@ int extReadRecord(int streamID, double *data, int *nmiss)
   int i, size;
   double missval;
   extrec_t *extp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  stream_check_ptr(__func__, streamptr);
-
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
   tsID    = streamptr->curTsID;
   vrecID  = streamptr->tsteps[tsID].curRecID;
   recID   = streamptr->tsteps[tsID].recIDs[vrecID];
@@ -35124,7 +35437,7 @@ int extReadRecord(int streamID, double *data, int *nmiss)
 }
 
 
-int extCopyRecord(int streamID2, int streamID1)
+int extCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
 {
   int fileID1, fileID2;
   int tsID, recID, vrecID;
@@ -35132,17 +35445,9 @@ int extCopyRecord(int streamID2, int streamID1)
   off_t recpos;
   int status = 0;
   char *buffer;
-  stream_t *streamptr1;
-  stream_t *streamptr2;
-
-  streamptr1 = stream_to_pointer(streamID1);
-  streamptr2 = stream_to_pointer(streamID2);
 
-  stream_check_ptr(__func__, streamptr1);
-  stream_check_ptr(__func__, streamptr2);
-
-  fileID1 = streamInqFileID(streamID1);
-  fileID2 = streamInqFileID(streamID2);
+  fileID1 = streamptr1->fileID;
+  fileID2 = streamptr2->fileID;
 
   tsID    = streamptr1->curTsID;
   vrecID  = streamptr1->tsteps[tsID].curRecID;
@@ -35164,18 +35469,13 @@ int extCopyRecord(int streamID2, int streamID1)
 }
 
 
-int extDefRecord(int streamID)
+int extDefRecord(stream_t *streamptr)
 {
   int gridID;
   int header[4];
   int status = 0;
   int pdis, pcat, pnum;
   extrec_t *extp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   gridID   = streamptr->record->gridID;
   extp     = streamptr->record->extp;
@@ -35194,18 +35494,13 @@ int extDefRecord(int streamID)
 }
 
 
-int extWriteRecord(int streamID, const double *data)
+int extWriteRecord(stream_t *streamptr, const double *data)
 {
   int fileID;
   int status = 0;
   extrec_t *extp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
   extp   = streamptr->record->extp;
 
   extDefDataDP(extp, data);
@@ -35216,7 +35511,7 @@ int extWriteRecord(int streamID, const double *data)
 }
 
 static
-void extAddRecord(int streamID, int param, int level, int xysize,
+void extAddRecord(stream_t *streamptr, int param, int level, int xysize,
 		  long recsize, off_t position, int prec, int number)
 {
   int leveltype;
@@ -35226,13 +35521,10 @@ void extAddRecord(int streamID, int param, int level, int xysize,
   record_t *record;
   grid_t grid;
   int vlistID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   tsID    = streamptr->curTsID;
-  recID   = recordNewEntry(streamID, tsID);
+  recID   = recordNewEntry(streamptr, tsID);
   record  = &streamptr->tsteps[tsID].records[recID];
 
   (*record).size     = recsize;
@@ -35254,7 +35546,7 @@ void extAddRecord(int streamID, int param, int level, int xysize,
   */
   leveltype = ZAXIS_GENERIC;
 
-  varAddRecord(recID, param, gridID, leveltype, 0, level, 0,
+  varAddRecord(recID, param, gridID, leveltype, 0, level, 0, 0,
 	       extInqDatatype(prec, number), &varID, &levelID, UNDEFID, 0, 0, NULL, NULL, NULL);
 
   (*record).varID   = varID;
@@ -35269,15 +35561,12 @@ void extAddRecord(int streamID, int param, int level, int xysize,
 }
 
 
-void extCmpRecord(int streamID, int tsID, int recID, off_t position, int param,
+void extCmpRecord(stream_t *streamptr, int tsID, int recID, off_t position, int param,
 		  int level, int xysize)
 {
   int varID = 0;
   int levelID = 0;
   record_t *record;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   record  = &streamptr->tsteps[tsID].records[recID];
 
@@ -35299,8 +35588,8 @@ void extCmpRecord(int streamID, int tsID, int recID, off_t position, int param,
 }
 
 static
-void extScanTimestep1(int streamID)
-{  
+void extScanTimestep1(stream_t *streamptr)
+{
   int header[4];
   int status;
   int fileID;
@@ -35318,22 +35607,17 @@ void extScanTimestep1(int streamID)
   int vlistID;
   extcompvar_t compVar, compVar0;
   extrec_t *extp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   streamptr->curTsID = 0;
 
   extp  = streamptr->record->extp;
-  tsID  = tstepsNewEntry(streamID);
+  tsID  = tstepsNewEntry(streamptr);
   taxis = &streamptr->tsteps[tsID].taxis;
 
   if ( tsID != 0 )
     Error("Internal problem! tstepsNewEntry returns %d", tsID);
 
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
 
   nrecs = 0;
   while ( TRUE )
@@ -35385,22 +35669,22 @@ void extScanTimestep1(int streamID)
       if ( CDI_Debug )
 	Message("%4d%8d%4d%8d%8d%6d", nrecs, (int)recpos, rcode, rlevel, vdate, vtime);
 
-      extAddRecord(streamID, param, rlevel, rxysize, recsize, recpos, extp->prec, extp->number);
+      extAddRecord(streamptr, param, rlevel, rxysize, recsize, recpos, extp->prec, extp->number);
     }
 
   streamptr->rtsteps = 1;
 
-  cdiGenVars(streamID);
+  cdi_generate_vars(streamptr);
 
   taxisID = taxisCreate(TAXIS_ABSOLUTE);
   taxis->type  = TAXIS_ABSOLUTE;
   taxis->vdate = datetime0.date;
   taxis->vtime = datetime0.time;
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   vlistDefTaxis(vlistID, taxisID);
 
-  cdiCheckContents(streamID);
+  vlist_check_contents(vlistID);
 
   nrecords = streamptr->tsteps[0].nallrecs;
   if ( nrecords < streamptr->tsteps[0].recordSize )
@@ -35417,7 +35701,7 @@ void extScanTimestep1(int streamID)
 
   if ( streamptr->ntsteps == -1 )
     {
-      tsID = tstepsNewEntry(streamID);
+      tsID = tstepsNewEntry(streamptr);
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
@@ -35439,8 +35723,8 @@ void extScanTimestep1(int streamID)
 }
 
 static
-int extScanTimestep2(int streamID)
-{  
+int extScanTimestep2(stream_t *streamptr)
+{
   int header[4];
   int status;
   int fileID;
@@ -35457,16 +35741,11 @@ int extScanTimestep2(int streamID)
   int vlistID;
   extcompvar_t compVar, compVar0;
   extrec_t *extp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   streamptr->curTsID = 1;
 
-  fileID  = streamInqFileID(streamID);
-  vlistID = streamInqVlist(streamID);
+  fileID  = streamptr->fileID;
+  vlistID = streamptr->vlistID;
   extp    = streamptr->record->extp;
 
   tsID = streamptr->rtsteps;
@@ -35477,7 +35756,7 @@ int extScanTimestep2(int streamID)
 
   fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-  cdiCreateRecords(streamID, tsID);
+  cdi_create_records(streamptr, tsID);
 
   nrecords = streamptr->tsteps[0].nallrecs;
   streamptr->tsteps[1].recIDs = (int *) malloc(nrecords*sizeof(int));
@@ -35488,9 +35767,9 @@ int extScanTimestep2(int streamID)
   for ( recID = 0; recID < nrecords; recID++ )
     {
       varID = streamptr->tsteps[0].records[recID].varID;
-      streamptr->tsteps[tsID].records[recID].position = 
+      streamptr->tsteps[tsID].records[recID].position =
 	streamptr->tsteps[0].records[recID].position;
-      streamptr->tsteps[tsID].records[recID].size     = 
+      streamptr->tsteps[tsID].records[recID].size     =
 	streamptr->tsteps[0].records[recID].size;
     }
 
@@ -35591,7 +35870,7 @@ int extScanTimestep2(int streamID)
 
   if ( streamptr->ntsteps == -1 )
     {
-      tsID = tstepsNewEntry(streamID);
+      tsID = tstepsNewEntry(streamptr);
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
@@ -35603,23 +35882,18 @@ int extScanTimestep2(int streamID)
 }
 
 
-int extInqContents(int streamID)
+int extInqContents(stream_t *streamptr)
 {
   int fileID;
   int status = 0;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
-
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
 
   streamptr->curTsID = 0;
 
-  extScanTimestep1(streamID);
- 
-  if ( streamptr->ntsteps == -1 ) status = extScanTimestep2(streamID);
+  extScanTimestep1(streamptr);
+
+  if ( streamptr->ntsteps == -1 ) status = extScanTimestep2(streamptr);
 
   fileSetPos(fileID, 0, SEEK_SET);
 
@@ -35627,7 +35901,7 @@ int extInqContents(int streamID)
 }
 
 static
-int extScanTimestep(int streamID)
+int extScanTimestep(stream_t *streamptr)
 {
   int header[4];
   int status;
@@ -35643,15 +35917,10 @@ int extScanTimestep(int streamID)
   int rindex, nrecs = 0;
   extcompvar_t compVar, compVar0;
   extrec_t *extp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   if ( CDI_Debug )
     {
-      Message("streamID = %d", streamID);
+      Message("streamID = %d", streamptr->self);
       Message("cts = %d", streamptr->curTsID);
       Message("rts = %d", streamptr->rtsteps);
       Message("nts = %d", streamptr->ntsteps);
@@ -35666,7 +35935,7 @@ int extScanTimestep(int streamID)
 
   if ( streamptr->tsteps[tsID].recordSize == 0 )
     {
-      cdiCreateRecords(streamID, tsID);
+      cdi_create_records(streamptr, tsID);
 
       nrecs = streamptr->tsteps[1].nrecs;
 
@@ -35675,7 +35944,7 @@ int extScanTimestep(int streamID)
       for ( recID = 0; recID < nrecs; recID++ )
 	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
 
-      fileID = streamInqFileID(streamID);
+      fileID = streamptr->fileID;
 
       fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
@@ -35711,7 +35980,7 @@ int extScanTimestep(int streamID)
 	      taxis->vtime = vtime;
 	    }
 	  /*
-	  extCmpRecord(streamID, tsID, nrecs, recpos, param, rlevel, rxysize);
+	  extCmpRecord(streamptr, tsID, nrecs, recpos, param, rlevel, rxysize);
 	  */
 	  compVar.param  = param;
           compVar.level  = rlevel;
@@ -35738,7 +36007,7 @@ int extScanTimestep(int streamID)
 
       if ( streamptr->ntsteps != streamptr->rtsteps )
 	{
-	  tsID = tstepsNewEntry(streamID);
+	  tsID = tstepsNewEntry(streamptr);
 	  if ( tsID != streamptr->rtsteps )
 	    Error("Internal error. tsID = %d", tsID);
 
@@ -35760,24 +36029,19 @@ int extScanTimestep(int streamID)
 }
 
 
-int extInqTimestep(int streamID, int tsID)
+int extInqTimestep(stream_t *streamptr, int tsID)
 {
   int ntsteps, nrecs;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   if ( tsID == 0 && streamptr->rtsteps == 0 )
     Error("Call to cdiInqContents missing!");
 
   if ( CDI_Debug )
     Message("tsID = %d rtsteps = %d", tsID, streamptr->rtsteps);
-  
+
   ntsteps = UNDEFID;
   while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == UNDEFID )
-    ntsteps = extScanTimestep(streamID);
+    ntsteps = extScanTimestep(streamptr);
 
   if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID )
     {
@@ -35793,7 +36057,7 @@ int extInqTimestep(int streamID, int tsID)
 }
 
 
-void extReadVarDP(int streamID, int varID, double *data, int *nmiss)
+void extReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
 {
   int vlistID, fileID;
   int levID, nlevs, gridID, gridsize;
@@ -35804,13 +36068,10 @@ void extReadVarDP(int streamID, int varID, double *data, int *nmiss)
   int i;
   double missval;
   extrec_t *extp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   extp     = streamptr->record->extp;
-  vlistID  = streamInqVlist(streamID);
-  fileID   = streamInqFileID(streamID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   nlevs    = streamptr->vars[varID].nlevs;
   missval  = vlistInqVarMissval(vlistID, varID);
   gridID   = vlistInqVarGrid(vlistID, varID);
@@ -35855,7 +36116,7 @@ void extReadVarDP(int streamID, int varID, double *data, int *nmiss)
 }
 
 
-void extReadVarSliceDP(int streamID, int varID, int levID, double *data, int *nmiss)
+void extReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, int *nmiss)
 {
   int vlistID, fileID;
   int nlevs, gridID, gridsize;
@@ -35866,13 +36127,10 @@ void extReadVarSliceDP(int streamID, int varID, int levID, double *data, int *nm
   int i;
   double missval;
   extrec_t *extp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   extp     = streamptr->record->extp;
-  vlistID  = streamInqVlist(streamID);
-  fileID   = streamInqFileID(streamID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   nlevs    = streamptr->vars[varID].nlevs;
   missval  = vlistInqVarMissval(vlistID, varID);
   gridID   = vlistInqVarGrid(vlistID, varID);
@@ -35916,7 +36174,7 @@ void extReadVarSliceDP(int streamID, int varID, int levID, double *data, int *nm
 }
 
 
-void extWriteVarDP(int streamID, int varID, const double *data)
+void extWriteVarDP(stream_t *streamptr, int varID, const double *data)
 {
   int fileID;
   int levID, nlevs, gridID, gridsize;
@@ -35927,16 +36185,12 @@ void extWriteVarDP(int streamID, int varID, const double *data)
   int vlistID;
   int pdis, pcat, pnum;
   extrec_t *extp;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  if ( CDI_Debug )
-    Message("streamID = %d  varID = %d", streamID, varID);
+  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
 
   extp     = streamptr->record->extp;
-  vlistID  = streamInqVlist(streamID);
-  fileID   = streamInqFileID(streamID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   tsID     = streamptr->curTsID;
   gridID   = vlistInqVarGrid(vlistID, varID);
   gridsize = gridInqSize(gridID);
@@ -35966,7 +36220,7 @@ void extWriteVarDP(int streamID, int varID, const double *data)
 }
 
 
-void extWriteVarSliceDP(int streamID, int varID, int levID, const double *data)
+void extWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double *data)
 {
   int fileID;
   int gridID;
@@ -35977,13 +36231,10 @@ void extWriteVarSliceDP(int streamID, int varID, int levID, const double *data)
   int vlistID;
   int pdis, pcat, pnum;
   extrec_t *extp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   extp     = streamptr->record->extp;
-  vlistID  = streamInqVlist(streamID);
-  fileID   = streamInqFileID(streamID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   tsID     = streamptr->curTsID;
   gridID   = vlistInqVarGrid(vlistID, varID);
   zaxisID  = vlistInqVarZaxis(vlistID, varID);
@@ -36039,7 +36290,7 @@ void extWriteVarSliceDP(int streamID, int varID, int levID, const double *data)
 typedef struct {
   int param;
   int level;
-} IEGCOMPVAR; 
+} IEGCOMPVAR;
 
 
 int iegInqDatatype(int prec)
@@ -36070,7 +36321,7 @@ int iegDefDatatype(int datatype)
 }
 
 /* not used
-int iegInqRecord(int streamID, int *varID, int *levelID)
+int iegInqRecord(stream_t *streamptr, int *varID, int *levelID)
 {
   int status;
   int fileID;
@@ -36078,14 +36329,9 @@ int iegInqRecord(int streamID, int *varID, int *levelID)
   int zaxisID = -1;
   int vlistID;
   iegrec_t *iegp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
   iegp    = streamptr->record->iegp;
 
   *varID   = -1;
@@ -36107,12 +36353,12 @@ int iegInqRecord(int streamID, int *varID, int *levelID)
   zaxisID = vlistInqVarZaxis(vlistID, *varID);
 
   *levelID = zaxisInqLevelID(zaxisID, (double) ilevel);
-  
+
   return (1);
 }
 */
 
-int iegReadRecord(int streamID, double *data, int *nmiss)
+int iegReadRecord(stream_t *streamptr, double *data, int *nmiss)
 {
   int vlistID, fileID;
   int status;
@@ -36122,14 +36368,9 @@ int iegReadRecord(int streamID, double *data, int *nmiss)
   int i, size;
   double missval;
   iegrec_t *iegp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
   tsID    = streamptr->curTsID;
   vrecID  = streamptr->tsteps[tsID].curRecID;
   recID   = streamptr->tsteps[tsID].recIDs[vrecID];
@@ -36544,7 +36785,7 @@ void iegDefLevel(int *pdb, int *gdb, double *vct, int zaxisID, int levelID)
 }
 
 
-int iegCopyRecord(int streamID2, int streamID1)
+int iegCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
 {
   int fileID1, fileID2;
   int tsID, recID, vrecID;
@@ -36552,17 +36793,9 @@ int iegCopyRecord(int streamID2, int streamID1)
   off_t recpos;
   int status = 0;
   char *buffer;
-  stream_t *streamptr1;
-  stream_t *streamptr2;
-
-  streamptr1 = stream_to_pointer(streamID1);
-  streamptr2 = stream_to_pointer(streamID2);
-
-  stream_check_ptr(__func__, streamptr1);
-  stream_check_ptr(__func__, streamptr2);
 
-  fileID1 = streamInqFileID(streamID1);
-  fileID2 = streamInqFileID(streamID2);
+  fileID1 = streamptr1->fileID;
+  fileID2 = streamptr2->fileID;
 
   tsID    = streamptr1->curTsID;
   vrecID  = streamptr1->tsteps[tsID].curRecID;
@@ -36584,7 +36817,7 @@ int iegCopyRecord(int streamID2, int streamID1)
 }
 
 
-int iegDefRecord(int streamID)
+int iegDefRecord(stream_t *streamptr)
 {
   int status = 0;
   int vlistID;
@@ -36596,13 +36829,8 @@ int iegDefRecord(int streamID)
   int varID, levelID, tsID, zaxisID;
   int byteorder;
   iegrec_t *iegp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  stream_check_ptr(__func__, streamptr);
-
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   iegp    = streamptr->record->iegp;
   byteorder = streamptr->byteorder;
 
@@ -36612,7 +36840,7 @@ int iegDefRecord(int streamID)
 
   gridID  = vlistInqVarGrid(vlistID, varID);
   zaxisID = vlistInqVarZaxis(vlistID, varID);
-  
+
   iegInitMem(iegp);
   for ( i = 0; i < 37; i++ ) iegp->ipdb[i] = -1;
 
@@ -36637,23 +36865,18 @@ int iegDefRecord(int streamID)
 }
 
 
-int iegWriteRecord(int streamID, const double *data)
+int iegWriteRecord(stream_t *streamptr, const double *data)
 {
   int fileID;
   int status = 0;
   int i, gridsize, gridID;
   double refval;
   iegrec_t *iegp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
   iegp   = streamptr->record->iegp;
   gridID = streamptr->record->gridID;
-  
+
   gridsize = gridInqSize(gridID);
 
   refval = data[0];
@@ -36670,7 +36893,7 @@ int iegWriteRecord(int streamID, const double *data)
 }
 
 static
-void iegAddRecord(int streamID, int param, int *pdb, int *gdb, double *vct,
+void iegAddRecord(stream_t *streamptr, int param, int *pdb, int *gdb, double *vct,
 		  long recsize, off_t position, int prec)
 {
   int leveltype;
@@ -36684,13 +36907,10 @@ void iegAddRecord(int streamID, int param, int *pdb, int *gdb, double *vct,
   record_t *record;
   grid_t grid;
   int vlistID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   tsID    = streamptr->curTsID;
-  recID   = recordNewEntry(streamID, tsID);
+  recID   = recordNewEntry(streamptr, tsID);
   record  = &streamptr->tsteps[tsID].records[recID];
 
   if ( IEG_P_LevelType(pdb) == IEG_LTYPE_HYBRID_LAYER )
@@ -36791,7 +37011,7 @@ void iegAddRecord(int streamID, int param, int *pdb, int *gdb, double *vct,
   gridID = varDefGrid(vlistID, grid, 0);
 
   leveltype = iegGetZaxisType(IEG_P_LevelType(pdb));
-  
+
   if ( leveltype == ZAXIS_HYBRID )
     {
       int i;
@@ -36808,7 +37028,7 @@ void iegAddRecord(int streamID, int param, int *pdb, int *gdb, double *vct,
 
   datatype = iegInqDatatype(prec);
 
-  varAddRecord(recID, param, gridID, leveltype, lbounds, level1, level2,
+  varAddRecord(recID, param, gridID, leveltype, lbounds, level1, level2, 0,
 	       datatype, &varID, &levelID, UNDEFID, 0, 0, NULL, NULL, NULL);
 
   (*record).varID   = varID;
@@ -36824,15 +37044,12 @@ void iegAddRecord(int streamID, int param, int *pdb, int *gdb, double *vct,
 
 #if 0
 static
-void iegCmpRecord(int streamID, int tsID, int recID, off_t position, int param,
+void iegCmpRecord(stream_t *streamptr, int tsID, int recID, off_t position, int param,
 		  int level, int xsize, int ysize)
 {
   int varID = 0;
   int levelID = 0;
   record_t *record;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   record  = &streamptr->tsteps[tsID].records[recID];
 
@@ -36873,8 +37090,8 @@ void iegDateTime(int *pdb, int *date, int *time)
 }
 
 static
-void iegScanTimestep1(int streamID)
-{  
+void iegScanTimestep1(stream_t *streamptr)
+{
   int prec = 0;
   int status;
   int fileID;
@@ -36892,22 +37109,17 @@ void iegScanTimestep1(int streamID)
   int vlistID;
   IEGCOMPVAR compVar, compVar0;
   iegrec_t *iegp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   streamptr->curTsID = 0;
 
   iegp  = streamptr->record->iegp;
-  tsID  = tstepsNewEntry(streamID);
+  tsID  = tstepsNewEntry(streamptr);
   taxis = &streamptr->tsteps[tsID].taxis;
 
   if ( tsID != 0 )
     Error("Internal problem! tstepsNewEntry returns %d", tsID);
 
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
 
   nrecs = 0;
   while ( TRUE )
@@ -36963,22 +37175,22 @@ void iegScanTimestep1(int streamID)
       if ( CDI_Debug )
 	Message("%4d%8d%4d%8d%8d%6d", nrecs, (int)recpos, param, rlevel, vdate, vtime);
 
-      iegAddRecord(streamID, param, iegp->ipdb, iegp->igdb, iegp->vct, recsize, recpos, prec);
+      iegAddRecord(streamptr, param, iegp->ipdb, iegp->igdb, iegp->vct, recsize, recpos, prec);
     }
 
   streamptr->rtsteps = 1;
 
-  cdiGenVars(streamID);
+  cdi_generate_vars(streamptr);
 
   taxisID = taxisCreate(TAXIS_ABSOLUTE);
   taxis->type  = TAXIS_ABSOLUTE;
   taxis->vdate = datetime0.date;
   taxis->vtime = datetime0.time;
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   vlistDefTaxis(vlistID, taxisID);
 
-  cdiCheckContents(streamID);
+  vlist_check_contents(vlistID);
 
   nrecords = streamptr->tsteps[0].nallrecs;
   if ( nrecords < streamptr->tsteps[0].recordSize )
@@ -36995,7 +37207,7 @@ void iegScanTimestep1(int streamID)
 
   if ( streamptr->ntsteps == -1 )
     {
-      tsID = tstepsNewEntry(streamID);
+      tsID = tstepsNewEntry(streamptr);
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
@@ -37017,8 +37229,8 @@ void iegScanTimestep1(int streamID)
 }
 
 static
-int iegScanTimestep2(int streamID)
-{  
+int iegScanTimestep2(stream_t *streamptr)
+{
   int status;
   int fileID;
   int tabnum;
@@ -37034,16 +37246,11 @@ int iegScanTimestep2(int streamID)
   int vlistID;
   IEGCOMPVAR compVar, compVar0;
   iegrec_t *iegp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   streamptr->curTsID = 1;
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
   iegp    = streamptr->record->iegp;
 
   tsID = streamptr->rtsteps;
@@ -37054,7 +37261,7 @@ int iegScanTimestep2(int streamID)
 
   fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-  cdiCreateRecords(streamID, tsID);
+  cdi_create_records(streamptr, tsID);
 
   nrecords = streamptr->tsteps[0].nallrecs;
   streamptr->tsteps[1].recIDs = (int *) malloc(nrecords*sizeof(int));
@@ -37065,9 +37272,9 @@ int iegScanTimestep2(int streamID)
   for ( recID = 0; recID < nrecords; recID++ )
     {
       varID = streamptr->tsteps[0].records[recID].varID;
-      streamptr->tsteps[tsID].records[recID].position = 
+      streamptr->tsteps[tsID].records[recID].position =
 	streamptr->tsteps[0].records[recID].position;
-      streamptr->tsteps[tsID].records[recID].size     = 
+      streamptr->tsteps[tsID].records[recID].size     =
 	streamptr->tsteps[0].records[recID].size;
     }
 
@@ -37173,7 +37380,7 @@ int iegScanTimestep2(int streamID)
 
   if ( streamptr->ntsteps == -1 )
     {
-      tsID = tstepsNewEntry(streamID);
+      tsID = tstepsNewEntry(streamptr);
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
@@ -37185,23 +37392,18 @@ int iegScanTimestep2(int streamID)
 }
 
 
-int iegInqContents(int streamID)
+int iegInqContents(stream_t *streamptr)
 {
   int fileID;
   int status = 0;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  stream_check_ptr(__func__, streamptr);
-
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
 
   streamptr->curTsID = 0;
 
-  iegScanTimestep1(streamID);
- 
-  if ( streamptr->ntsteps == -1 ) status = iegScanTimestep2(streamID);
+  iegScanTimestep1(streamptr);
+
+  if ( streamptr->ntsteps == -1 ) status = iegScanTimestep2(streamptr);
 
   fileSetPos(fileID, 0, SEEK_SET);
 
@@ -37209,7 +37411,7 @@ int iegInqContents(int streamID)
 }
 
 static
-int iegScanTimestep(int streamID)
+int iegScanTimestep(stream_t *streamptr)
 {
   int status;
   int fileID;
@@ -37224,15 +37426,10 @@ int iegScanTimestep(int streamID)
   int rindex, nrecs = 0;
   IEGCOMPVAR compVar, compVar0;
   iegrec_t *iegp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   if ( CDI_Debug )
     {
-      Message("streamID = %d", streamID);
+      Message("streamID = %d", streamptr->self);
       Message("cts = %d", streamptr->curTsID);
       Message("rts = %d", streamptr->rtsteps);
       Message("nts = %d", streamptr->ntsteps);
@@ -37247,7 +37444,7 @@ int iegScanTimestep(int streamID)
 
   if ( streamptr->tsteps[tsID].recordSize == 0 )
     {
-      cdiCreateRecords(streamID, tsID);
+      cdi_create_records(streamptr, tsID);
 
       nrecs = streamptr->tsteps[1].nrecs;
 
@@ -37256,7 +37453,7 @@ int iegScanTimestep(int streamID)
       for ( recID = 0; recID < nrecs; recID++ )
 	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
 
-      fileID = streamInqFileID(streamID);
+      fileID = streamptr->fileID;
 
       fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
@@ -37320,7 +37517,7 @@ int iegScanTimestep(int streamID)
 
       if ( streamptr->ntsteps != streamptr->rtsteps )
 	{
-	  tsID = tstepsNewEntry(streamID);
+	  tsID = tstepsNewEntry(streamptr);
 	  if ( tsID != streamptr->rtsteps )
 	    Error("Internal error. tsID = %d", tsID);
 
@@ -37342,24 +37539,19 @@ int iegScanTimestep(int streamID)
 }
 
 
-int iegInqTimestep(int streamID, int tsID)
+int iegInqTimestep(stream_t *streamptr, int tsID)
 {
   int ntsteps, nrecs;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   if ( tsID == 0 && streamptr->rtsteps == 0 )
     Error("Call to cdiInqContents missing!");
 
   if ( CDI_Debug )
     Message("tsID = %d rtsteps = %d", tsID, streamptr->rtsteps);
-  
+
   ntsteps = UNDEFID;
   while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == UNDEFID )
-    ntsteps = iegScanTimestep(streamID);
+    ntsteps = iegScanTimestep(streamptr);
 
   if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID )
     {
@@ -37375,7 +37567,7 @@ int iegInqTimestep(int streamID, int tsID)
 }
 
 
-void iegReadVarDP(int streamID, int varID, double *data, int *nmiss)
+void iegReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
 {
   int vlistID, fileID;
   int levID, nlevs, gridID, gridsize;
@@ -37385,13 +37577,10 @@ void iegReadVarDP(int streamID, int varID, double *data, int *nmiss)
   int i;
   double missval;
   iegrec_t *iegp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   iegp     = streamptr->record->iegp;
-  vlistID  = streamInqVlist(streamID);
-  fileID   = streamInqFileID(streamID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   nlevs    = streamptr->vars[varID].nlevs;
   missval  = vlistInqVarMissval(vlistID, varID);
   gridID   = vlistInqVarGrid(vlistID, varID);
@@ -37423,7 +37612,7 @@ void iegReadVarDP(int streamID, int varID, double *data, int *nmiss)
 }
 
 
-void iegReadVarSliceDP(int streamID, int varID, int levID, double *data, int *nmiss)
+void iegReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, int *nmiss)
 {
   int vlistID, fileID;
   int nlevs, gridID, gridsize;
@@ -37433,13 +37622,10 @@ void iegReadVarSliceDP(int streamID, int varID, int levID, double *data, int *nm
   int i;
   double missval;
   iegrec_t *iegp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   iegp     = streamptr->record->iegp;
-  vlistID  = streamInqVlist(streamID);
-  fileID   = streamInqFileID(streamID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   nlevs    = streamptr->vars[varID].nlevs;
   missval  = vlistInqVarMissval(vlistID, varID);
   gridID   = vlistInqVarGrid(vlistID, varID);
@@ -37470,7 +37656,7 @@ void iegReadVarSliceDP(int streamID, int varID, int levID, double *data, int *nm
 }
 
 
-void iegWriteVarDP(int streamID, int varID, const double *data)
+void iegWriteVarDP(stream_t *streamptr, int varID, const double *data)
 {
   int fileID;
   int levID, nlevs, gridID, gridsize;
@@ -37483,20 +37669,17 @@ void iegWriteVarDP(int streamID, int varID, const double *data)
   int param, pdis, pcat, pnum;
   double refval;
   iegrec_t *iegp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   if ( CDI_Debug )
-    Message("streamID = %d  varID = %d", streamID, varID);
+    Message("streamID = %d  varID = %d", streamptr->self, varID);
 
   iegp     = streamptr->record->iegp;
 
   iegInitMem(iegp);
   for ( i = 0; i < 37; i++ ) iegp->ipdb[i] = -1;
 
-  vlistID  = streamInqVlist(streamID);
-  fileID   = streamInqFileID(streamID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   tsID     = streamptr->curTsID;
   gridID   = vlistInqVarGrid(vlistID, varID);
   gridsize = gridInqSize(gridID);
@@ -37536,7 +37719,7 @@ void iegWriteVarDP(int streamID, int varID, const double *data)
 }
 
 
-void iegWriteVarSliceDP(int streamID, int varID, int levID, const double *data)
+void iegWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double *data)
 {
   int fileID;
   int gridID;
@@ -37547,13 +37730,10 @@ void iegWriteVarSliceDP(int streamID, int varID, int levID, const double *data)
   int vlistID;
   /* int param, date, time, datasize; */
   iegrec_t *iegp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   iegp     = streamptr->record->iegp;
-  vlistID  = streamInqVlist(streamID);
-  fileID   = streamInqFileID(streamID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   /* tsID     = streamptr->curTsID; */
   gridID   = vlistInqVarGrid(vlistID, varID);
   zaxisID  = vlistInqVarZaxis(vlistID, varID);
@@ -37608,8 +37788,8 @@ void iegWriteVarSliceDP(int streamID, int varID, int levID, const double *data)
 #define UNDEFID  CDI_UNDEFID
 
 
-void cdfDefGlobalAtts(int streamID);
-void cdfDefLocalAtts(int streamID);
+void cdfDefGlobalAtts(stream_t *streamptr);
+void cdfDefLocalAtts(stream_t *streamptr);
 
 
 #define  X_AXIS  1
@@ -38064,7 +38244,7 @@ void defineAttributes(int vlistID, int varID, int fileID, int ncvarID)
 }
 #endif
 
-int cdfCopyRecord(int streamID2, int streamID1)
+int cdfCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
 {
   double *data;
   int datasize;
@@ -38074,14 +38254,6 @@ int cdfCopyRecord(int streamID2, int streamID1)
   int ierr = 0;
   int memtype = MEMTYPE_DOUBLE;
   int vlistID1;
-  stream_t *streamptr1;
-  stream_t *streamptr2;
-
-  streamptr1 = stream_to_pointer(streamID1);
-  streamptr2 = stream_to_pointer(streamID2);
-
-  stream_check_ptr(__func__, streamptr1);
-  stream_check_ptr(__func__, streamptr2);
 
   vlistID1 = streamptr1->vlistID;
 
@@ -38099,8 +38271,8 @@ int cdfCopyRecord(int streamID2, int streamID1)
 
   data = (double *) malloc(datasize*sizeof(double));
 
-  streamReadRecord(streamID1, data, &nmiss);
-  stream_write_record(streamID2, memtype, data, nmiss);
+  cdfReadRecord(streamptr1, data, &nmiss);
+  cdf_write_record(streamptr2, memtype, data, nmiss);
 
   free(data);
 
@@ -38108,21 +38280,15 @@ int cdfCopyRecord(int streamID2, int streamID1)
 }
 
 /* not used
-int cdfInqRecord(int streamID, int *varID, int *levelID)
+int cdfInqRecord(stream_t *streamptr, int *varID, int *levelID)
 {
   int tsID, recID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   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 )
+  if ( streamptr->tsteps[0].curRecID >= streamptr->tsteps[0].nrecs )
     {
       streamptr->tsteps[0].curRecID = 0;
     }
@@ -38135,40 +38301,31 @@ int cdfInqRecord(int streamID, int *varID, int *levelID)
 
   if ( CDI_Debug )
     Message("recID = %d  varID = %d  levelID = %d", recID, *varID, *levelID);
-  
+
   return (recID+1);
 }
 */
-int cdfDefRecord(int streamID)
-{
-  int ierr = 0;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  if ( CDI_Debug )
-    Message("streamID = %d", streamID);
 
-  stream_check_ptr(__func__, streamptr);
+int cdfDefRecord(stream_t *streamptr)
+{
+  int ierr = 0;
 
   return (ierr);
 }
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfWriteGridTraj(int streamID, int gridID)
+void cdfWriteGridTraj(stream_t *streamptr, int gridID)
 {
   int tsID, fileID;
   int lonID, latID, gridindex;
   size_t index;
   double xlon, xlat;
   int vlistID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   gridindex = vlistGridIndex(vlistID, gridID);
   lonID = streamptr->xdimID[gridindex];
@@ -38182,23 +38339,18 @@ void cdfWriteGridTraj(int streamID, int gridID)
   cdf_put_var1_double(fileID, lonID, &index, &xlon);
   cdf_put_var1_double(fileID, latID, &index, &xlat);
 }
-#endif
 
-#if  defined  (HAVE_LIBNETCDF)
 static
-void cdfReadGridTraj(int streamID, int gridID)
+void cdfReadGridTraj(stream_t *streamptr, int gridID)
 {
   int tsID, fileID;
   int lonID, latID, gridindex;
   size_t index;
   double xlon, xlat;
   int vlistID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   gridindex = vlistGridIndex(vlistID, gridID);
   lonID = streamptr->xdimID[gridindex];
@@ -38272,12 +38424,8 @@ void cdfDefVarSzip(int ncid, int ncvarid)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefVarMissval(int streamID, int varID, int dtype, int lcheck)
+void cdfDefVarMissval(stream_t *streamptr, int varID, int dtype, int lcheck)
 {
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
   if ( streamptr->vars[varID].defmiss == FALSE )
     {
       int fileID;
@@ -38286,10 +38434,11 @@ void cdfDefVarMissval(int streamID, int varID, int dtype, int lcheck)
       int vlistID;
       int xtype;
 
-      vlistID = streamInqVlist(streamID);
-      fileID  = streamInqFileID(streamID);
+      vlistID = streamptr->vlistID;
+      fileID  = streamptr->fileID;
       ncvarid = streamptr->vars[varID].ncvarid;
       missval = vlistInqVarMissval(vlistID, varID);
+
       if ( lcheck && streamptr->ncmode == 2 ) cdf_redef(fileID);
 
       xtype = cdfDefDatatype(dtype, streamptr->filetype);
@@ -38306,35 +38455,28 @@ void cdfDefVarMissval(int streamID, int varID, int dtype, int lcheck)
 }
 #endif
 
-void cdf_write_record(int streamID, int memtype, const void *data, int nmiss)
+void cdf_write_record(stream_t *streamptr, int memtype, const void *data, int nmiss)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int varID;
   int levelID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   varID   = streamptr->record->varID;
   levelID = streamptr->record->levelID;
 
-  if ( CDI_Debug )
-    Message("streamID = %d  varID = %d", streamID, varID);
+  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
 
-  cdf_write_var_slice(streamID, varID, levelID, memtype, data, nmiss);
+  cdf_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
 #endif
 }
 
 
-int cdfReadRecord(int streamID, double *data, int *nmiss)
+int cdfReadRecord(stream_t *streamptr, double *data, int *nmiss)
 {
   int ierr = 0;
   int levelID, varID, tsID, recID, vrecID;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  if ( CDI_Debug ) Message("streamID = %d", streamID);
+  if ( CDI_Debug ) Message("streamID = %d", streamptr->self);
 
   tsID    = streamptr->curTsID;
   vrecID  = streamptr->tsteps[tsID].curRecID;
@@ -38342,13 +38484,13 @@ int cdfReadRecord(int streamID, double *data, int *nmiss)
   varID   = streamptr->tsteps[tsID].records[recID].varID;
   levelID = streamptr->tsteps[tsID].records[recID].levelID;
 
-  cdfReadVarSliceDP(streamID, varID, levelID, data, nmiss);
+  cdfReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
 
   return (ierr);
 }
 
 static
-void cdfDefTimeValue(int streamID, int tsID)
+void cdfDefTimeValue(stream_t *streamptr, int tsID)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int fileID;
@@ -38356,14 +38498,11 @@ void cdfDefTimeValue(int streamID, int tsID)
   int ncvarid;
   size_t index;
   taxis_t *taxis;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
 
   if ( CDI_Debug )
-    Message("streamID = %d, fileID = %d", streamID, fileID);
+    Message("streamID = %d, fileID = %d", streamptr->self, fileID);
 
   taxis = &streamptr->tsteps[tsID].taxis;
 
@@ -38402,7 +38541,7 @@ printf("fileID = %d %d %d %f\n", fileID, time_varid, index, timevalue);
 }
 
 static
-void cdfDefTime(int streamID)
+void cdfDefTime(stream_t *streamptr)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int fileID;
@@ -38417,13 +38556,10 @@ void cdfDefTime(int streamID)
   char *taxis_name = default_name;
   size_t len;
   taxis_t *taxis;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   if ( streamptr->basetime.ncvarid != UNDEFID ) return;
 
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
 
   if ( streamptr->ncmode == 0 ) streamptr->ncmode = 1;
 
@@ -38533,20 +38669,20 @@ void cdfDefTime(int streamID)
 }
 
 
-void cdfDefTimestep(int streamID, int tsID)
+void cdfDefTimestep(stream_t *streamptr, int tsID)
 {
   int vlistID;
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
 
-  if ( vlistHasTime(vlistID) ) cdfDefTime(streamID);
+  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
 
-  cdfDefTimeValue(streamID, tsID);
+  cdfDefTimeValue(streamptr, tsID);
 }
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefComplex(int streamID, int gridID)
+void cdfDefComplex(stream_t *streamptr, int gridID)
 {
   char axisname[] = "nc2";
   int index;
@@ -38556,12 +38692,9 @@ void cdfDefComplex(int streamID, int gridID)
   int fileID;
   int dimlen;
   int vlistID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   ngrids = vlistNgrids(vlistID);
 
@@ -38598,7 +38731,7 @@ void cdfDefComplex(int streamID, int gridID)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefSP(int streamID, int gridID)
+void cdfDefSP(stream_t *streamptr, int gridID)
 {
   /*
   char longname[] = "Spherical harmonic coefficient";
@@ -38611,12 +38744,9 @@ void cdfDefSP(int streamID, int gridID)
   int fileID;
   int dimlen, dimlen0;
   int vlistID;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   ngrids = vlistNgrids(vlistID);
 
@@ -38662,7 +38792,7 @@ void cdfDefSP(int streamID, int gridID)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefFC(int streamID, int gridID)
+void cdfDefFC(stream_t *streamptr, int gridID)
 {
   char axisname[5] = "nfcX";
   int index, iz = 0;
@@ -38672,12 +38802,9 @@ void cdfDefFC(int streamID, int gridID)
   int fileID;
   int dimlen, dimlen0;
   int vlistID;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   ngrids = vlistNgrids(vlistID);
 
@@ -38723,7 +38850,7 @@ void cdfDefFC(int streamID, int gridID)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefTrajLon(int streamID, int gridID)
+void cdfDefTrajLon(stream_t *streamptr, int gridID)
 {
   char units[CDI_MAX_NAME];
   char longname[CDI_MAX_NAME];
@@ -38737,14 +38864,11 @@ void cdfDefTrajLon(int streamID, int gridID)
   int ncvarid;
   int vlistID;
   int xtype = NC_DOUBLE;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   if ( gridInqPrec(gridID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   gridtype = gridInqType(gridID);
   dimlen = gridInqXsize(gridID);
@@ -38783,7 +38907,7 @@ void cdfDefTrajLon(int streamID, int gridID)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefTrajLat(int streamID, int gridID)
+void cdfDefTrajLat(stream_t *streamptr, int gridID)
 {
   char units[] = "degrees_north";
   char longname[] = "latitude";
@@ -38797,14 +38921,11 @@ void cdfDefTrajLat(int streamID, int gridID)
   int ncvarid;
   int vlistID;
   int xtype = NC_DOUBLE;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   if ( gridInqPrec(gridID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
 
-  vlistID = streamInqVlist(streamID);
-  fileID = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID = streamptr->fileID;
 
   gridtype = gridInqType(gridID);
   dimlen = gridInqYsize(gridID);
@@ -38857,7 +38978,7 @@ int checkGridName(int type, char *axisname, int fileID, int vlistID, int gridID,
   checkname = TRUE;
   iz = 0;
 
-  while ( checkname ) 
+  while ( checkname )
     {
       strcpy(axisname2, axisname);
       if ( iz ) sprintf(&axisname2[strlen(axisname2)], "_%d", iz+1);
@@ -38907,7 +39028,7 @@ int checkGridName(int type, char *axisname, int fileID, int vlistID, int gridID,
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefXaxis(int streamID, int gridID)
+void cdfDefXaxis(stream_t *streamptr, int gridID)
 {
   char units[CDI_MAX_NAME];
   char longname[CDI_MAX_NAME];
@@ -38926,14 +39047,11 @@ void cdfDefXaxis(int streamID, int gridID)
   int nvertex = 2, nvdimID = UNDEFID;
   int vlistID;
   int xtype = NC_DOUBLE;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   if ( gridInqPrec(gridID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   ngrids = vlistNgrids(vlistID);
 
@@ -39036,7 +39154,7 @@ void cdfDefXaxis(int streamID, int gridID)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefYaxis(int streamID, int gridID)
+void cdfDefYaxis(stream_t *streamptr, int gridID)
 {
   char units[CDI_MAX_NAME];
   char longname[CDI_MAX_NAME];
@@ -39055,14 +39173,11 @@ void cdfDefYaxis(int streamID, int gridID)
   int nvertex = 2, nvdimID = UNDEFID;
   int vlistID;
   int xtype = NC_DOUBLE;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   if ( gridInqPrec(gridID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   ngrids = vlistNgrids(vlistID);
 
@@ -39179,7 +39294,7 @@ void cdfGridCompress(int fileID, int ncvarid, int gridsize, int filetype, int co
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefCurvilinear(int streamID, int gridID)
+void cdfDefCurvilinear(stream_t *streamptr, int gridID)
 {
   char xunits[CDI_MAX_NAME];
   char xlongname[CDI_MAX_NAME];
@@ -39205,14 +39320,11 @@ void cdfDefCurvilinear(int streamID, int gridID)
   int nvertex = 4, nvdimID = UNDEFID;
   int vlistID;
   int xtype = NC_DOUBLE;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   if ( gridInqPrec(gridID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   ngrids = vlistNgrids(vlistID);
 
@@ -39375,7 +39487,7 @@ void cdfDefCurvilinear(int streamID, int gridID)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefRgrid(int streamID, int gridID)
+void cdfDefRgrid(stream_t *streamptr, int gridID)
 {
   char axisname[7] = "rgridX";
   int index, iz = 0;
@@ -39386,12 +39498,9 @@ void cdfDefRgrid(int streamID, int gridID)
   int dimlen, dimlen0;
   int vlistID;
   int lwarn = TRUE;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   ngrids = vlistNgrids(vlistID);
 
@@ -39445,9 +39554,8 @@ void cdfDefRgrid(int streamID, int gridID)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefGdim(int streamID, int gridID)
+void cdfDefGdim(stream_t *streamptr, int gridID)
 {
-  char axisname[7] = "gsizeX";
   int index, iz = 0;
   int gridID0, gridtype0, gridindex;
   int dimID = UNDEFID;
@@ -39455,12 +39563,9 @@ void cdfDefGdim(int streamID, int gridID)
   int fileID;
   int dimlen, dimlen0;
   int vlistID;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   ngrids = vlistNgrids(vlistID);
 
@@ -39482,7 +39587,7 @@ void cdfDefGdim(int streamID, int gridID)
                     break;
                   }
                 else
-                  iz++; 
+                  iz++;
               }
           }
       }
@@ -39503,18 +39608,25 @@ void cdfDefGdim(int streamID, int gridID)
                     break;
                   }
                 else
-                  iz++; 
+                  iz++;
               }
           }
       }
 
   if ( dimID == UNDEFID )
     {
+      int status;
+      char axisname[CDI_MAX_NAME];
+      strcpy(axisname, "gsize");
+
+      status = checkGridName('D', axisname, fileID, vlistID, gridID, ngrids, 'X');
+      /*
       if ( iz == 0 ) axisname[5] = '\0';
       else           sprintf(&axisname[5], "%1d", iz+1);
-
+      */
       if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
+      //printf("axisname, dimlen %s %d\n", axisname, dimlen);
       cdf_def_dim(fileID, axisname, dimlen, &dimID);
 
       cdf_enddef(fileID);
@@ -39528,7 +39640,7 @@ void cdfDefGdim(int streamID, int gridID)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefUnstructured(int streamID, int gridID)
+void cdfDefUnstructured(stream_t *streamptr, int gridID)
 {
   char xunits[CDI_MAX_NAME];
   char xlongname[CDI_MAX_NAME];
@@ -39550,14 +39662,11 @@ void cdfDefUnstructured(int streamID, int gridID)
   int nvertex, nvdimID = UNDEFID;
   int vlistID;
   int xtype = NC_DOUBLE;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   if ( gridInqPrec(gridID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   ngrids = vlistNgrids(vlistID);
 
@@ -39700,12 +39809,9 @@ void cdfDefUnstructured(int streamID, int gridID)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefVCT(int streamID, int zaxisID)
+void cdfDefVCT(stream_t *streamptr, int zaxisID)
 {
   int type;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   type = zaxisInqType(zaxisID);
   if ( type == ZAXIS_HYBRID || type == ZAXIS_HYBRID_HALF )
@@ -39734,7 +39840,7 @@ void cdfDefVCT(int streamID, int zaxisID)
           return;
         }
 
-      fileID = streamInqFileID(streamID);
+      fileID = streamptr->fileID;
 
       if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
@@ -39790,7 +39896,7 @@ void cdfDefVCT(int streamID, int zaxisID)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefZaxis(int streamID, int zaxisID)
+void cdfDefZaxis(stream_t *streamptr, int zaxisID)
 {
   /*  char zaxisname0[CDI_MAX_NAME]; */
   char axisname[CDI_MAX_NAME];
@@ -39814,14 +39920,11 @@ void cdfDefZaxis(int streamID, int zaxisID)
   int zaxisindex;
   int xtype = NC_DOUBLE;
   int positive;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   if ( zaxisInqPrec(zaxisID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
 
@@ -39830,11 +39933,14 @@ void cdfDefZaxis(int streamID, int zaxisID)
   dimlen = zaxisInqSize(zaxisID);
   type   = zaxisInqType(zaxisID);
 
-  if ( dimlen == 1 && type == ZAXIS_SURFACE     ) return;
-  if ( dimlen == 1 && type == ZAXIS_TOA         ) return;
-  if ( dimlen == 1 && type == ZAXIS_SEA_BOTTOM  ) return;
-  if ( dimlen == 1 && type == ZAXIS_ATMOSPHERE  ) return;
-  if ( dimlen == 1 && type == ZAXIS_MEANSEA     ) return;
+  if ( dimlen == 1 && type == ZAXIS_SURFACE       ) return;
+  if ( dimlen == 1 && type == ZAXIS_CLOUD_BASE    ) return;
+  if ( dimlen == 1 && type == ZAXIS_CLOUD_TOP     ) return;
+  if ( dimlen == 1 && type == ZAXIS_ISOTHERM_ZERO ) return;
+  if ( dimlen == 1 && type == ZAXIS_TOA           ) return;
+  if ( dimlen == 1 && type == ZAXIS_SEA_BOTTOM    ) return;
+  if ( dimlen == 1 && type == ZAXIS_ATMOSPHERE    ) return;
+  if ( dimlen == 1 && type == ZAXIS_MEANSEA       ) return;
 
   zaxisInqName(zaxisID, axisname);
   /*
@@ -39951,7 +40057,7 @@ void cdfDefZaxis(int streamID, int zaxisID)
 	      cdf_put_var_double(fileID, ncvarid, zaxisInqLevelsPtr(zaxisID));
             }
 
-          cdfDefVCT(streamID, zaxisID);
+          cdfDefVCT(streamptr, zaxisID);
 
           if ( dimID == UNDEFID )
             {
@@ -40048,7 +40154,7 @@ void cdfDefZaxis(int streamID, int zaxisID)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefPole(int streamID, int gridID)
+void cdfDefPole(stream_t *streamptr, int gridID)
 {
   int fileID;
   int ncvarid = UNDEFID;
@@ -40057,7 +40163,7 @@ void cdfDefPole(int streamID, int gridID)
   char varname[] = "rotated_pole";
   char mapname[] = "rotated_latitude_longitude";
 
-  fileID  = streamInqFileID(streamID);
+  fileID  = streamptr->fileID;
 
   ypole = gridInqYpole(gridID);
   xpole = gridInqXpole(gridID);
@@ -40081,7 +40187,7 @@ void cdfDefPole(int streamID, int gridID)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefMapping(int streamID, int gridID)
+void cdfDefMapping(stream_t *streamptr, int gridID)
 {
   int fileID;
   int ncvarid = UNDEFID;
@@ -40092,7 +40198,7 @@ void cdfDefMapping(int streamID, int gridID)
       char varname[] = "sinusoidal";
       char mapname[] = "sinusoidal";
 
-      fileID  = streamInqFileID(streamID);
+      fileID  = streamptr->fileID;
 
       cdf_redef(fileID);
 
@@ -40113,7 +40219,7 @@ void cdfDefMapping(int streamID, int gridID)
       char varname[] = "laea";
       char mapname[] = "lambert_azimuthal_equal_area";
 
-      fileID  = streamInqFileID(streamID);
+      fileID  = streamptr->fileID;
 
       cdf_redef(fileID);
 
@@ -40137,7 +40243,7 @@ void cdfDefMapping(int streamID, int gridID)
       char varname[] = "Lambert_Conformal";
       char mapname[] = "lambert_conformal_conic";
 
-      fileID  = streamInqFileID(streamID);
+      fileID  = streamptr->fileID;
 
       cdf_redef(fileID);
 
@@ -40171,16 +40277,33 @@ void cdfDefMapping(int streamID, int gridID)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefGrid(int streamID, int gridID)
+void cdfDefGridUUID(stream_t *streamptr, int gridID)
+{
+  char uuidOfHGrid[17];
+
+  gridInqUUID(gridID, uuidOfHGrid);
+  if ( uuidOfHGrid[0] != 0 )
+    {
+      char uuidOfHGridStr[37];
+      uuid2str(uuidOfHGrid, uuidOfHGridStr);
+      if ( uuidOfHGridStr[0] != 0 && strlen(uuidOfHGridStr) == 36 )
+        {
+          int fileID  = streamptr->fileID;
+          if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+          cdf_put_att_text(fileID, NC_GLOBAL, "uuidOfHGrid", 36, uuidOfHGridStr);
+          if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
+        }
+    }
+}
+
+static
+void cdfDefGrid(stream_t *streamptr, int gridID)
 {
   int gridtype, size;
   int gridindex;
   int vlistID;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   gridindex = vlistGridIndex(vlistID, gridID);
   if ( streamptr->xdimID[gridindex] != UNDEFID ) return;
 
@@ -40194,73 +40317,90 @@ void cdfDefGrid(int streamID, int gridID)
        gridtype == GRID_LONLAT   ||
        gridtype == GRID_GENERIC )
     {
-      if ( gridtype == GRID_GENERIC && size == 1 && 
-           gridInqXsize(gridID) == 0 && gridInqYsize(gridID) == 0 )
+      if ( gridtype == GRID_GENERIC )
         {
-          /* no grid information */
-        }
-      else if ( gridtype == GRID_GENERIC && (gridInqXsize(gridID) == 0 || gridInqYsize(gridID) == 0) )
-        {
-          cdfDefGdim(streamID, gridID);
+          if ( size == 1 && gridInqXsize(gridID) == 0 && gridInqYsize(gridID) == 0 )
+            {
+              /* no grid information */
+            }
+          else
+            {
+              int lx = 0, ly = 0;
+              if ( gridInqXsize(gridID) > 0 /*&& gridInqXvals(gridID, NULL) > 0*/ )
+                {
+                  cdfDefXaxis(streamptr, gridID);
+                  lx = 1;
+                }
+
+              if ( gridInqYsize(gridID) > 0 /*&& gridInqYvals(gridID, NULL) > 0*/ )
+                {
+                  cdfDefYaxis(streamptr, gridID);
+                  ly = 1;
+                }
+
+              if ( lx == 0 && ly == 0 ) cdfDefGdim(streamptr, gridID);
+            }
         }
       else
         {
-          if ( gridInqXsize(gridID) > 0 ) cdfDefXaxis(streamID, gridID);
-          if ( gridInqYsize(gridID) > 0 ) cdfDefYaxis(streamID, gridID);
+          if ( gridInqXsize(gridID) > 0 ) cdfDefXaxis(streamptr, gridID);
+          if ( gridInqYsize(gridID) > 0 ) cdfDefYaxis(streamptr, gridID);
         }
 
-      if ( gridIsRotated(gridID) ) cdfDefPole(streamID, gridID);
+      if ( gridIsRotated(gridID) ) cdfDefPole(streamptr, gridID);
     }
   else if ( gridtype == GRID_CURVILINEAR )
     {
-      cdfDefCurvilinear(streamID, gridID);
+      cdfDefCurvilinear(streamptr, gridID);
     }
   else if ( gridtype == GRID_UNSTRUCTURED )
     {
-      cdfDefUnstructured(streamID, gridID);
+      cdfDefUnstructured(streamptr, gridID);
     }
   else if ( gridtype == GRID_GAUSSIAN_REDUCED )
     {
-      cdfDefRgrid(streamID, gridID);
+      cdfDefRgrid(streamptr, gridID);
     }
   else if ( gridtype == GRID_SPECTRAL )
     {
-      cdfDefComplex(streamID, gridID);
-      cdfDefSP(streamID, gridID);
+      cdfDefComplex(streamptr, gridID);
+      cdfDefSP(streamptr, gridID);
     }
   else if ( gridtype == GRID_FOURIER )
     {
-      cdfDefComplex(streamID, gridID);
-      cdfDefFC(streamID, gridID);
+      cdfDefComplex(streamptr, gridID);
+      cdfDefFC(streamptr, gridID);
     }
   else if ( gridtype == GRID_TRAJECTORY )
     {
-      cdfDefTrajLon(streamID, gridID);
-      cdfDefTrajLat(streamID, gridID);
+      cdfDefTrajLon(streamptr, gridID);
+      cdfDefTrajLat(streamptr, gridID);
     }
   else if ( gridtype == GRID_SINUSOIDAL || gridtype == GRID_LAEA || gridtype == GRID_LCC2 )
     {
-      cdfDefXaxis(streamID, gridID);
-      cdfDefYaxis(streamID, gridID);
+      cdfDefXaxis(streamptr, gridID);
+      cdfDefYaxis(streamptr, gridID);
 
-      cdfDefMapping(streamID, gridID);
+      cdfDefMapping(streamptr, gridID);
     }
   /*
   else if ( gridtype == GRID_LCC )
     {
-      cdfDefLcc(streamID, gridID);
+      cdfDefLcc(streamptr, gridID);
     }
   */
   else
     {
       Error("Unsupported grid type: %s", gridNamePtr(gridtype));
     }
+
+  cdfDefGridUUID(streamptr, gridID);
 }
 #endif
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-int cdfDefVar(int streamID, int varID)
+int cdfDefVar(stream_t *streamptr, int varID)
 {
   int ncvarid = -1;
   int fileID;
@@ -40290,21 +40430,18 @@ int cdfDefVar(int streamID, int varID)
   int ixyz;
   int iax = 0;
   char axis[5];
-  stream_t *streamptr;
   int ensID, ensCount, forecast_type;
   int retval;
 
-  streamptr = stream_to_pointer(streamID);
-
-  fileID  = streamInqFileID(streamID);
+  fileID  = streamptr->fileID;
 
   if ( CDI_Debug )
-    Message("streamID = %d, fileID = %d, varID = %d", streamID, fileID, varID);
+    Message("streamID = %d, fileID = %d, varID = %d", streamptr->self, fileID, varID);
 
   if ( streamptr->vars[varID].ncvarid != UNDEFID )
     return (streamptr->vars[varID].ncvarid);
 
-  vlistID   = streamInqVlist(streamID);
+  vlistID   = streamptr->vlistID;
   gridID    = vlistInqVarGrid(vlistID, varID);
   zaxisID   = vlistInqVarZaxis(vlistID, varID);
   tsteptype = vlistInqVarTsteptype(vlistID, varID);
@@ -40413,7 +40550,7 @@ int cdfDefVar(int streamID, int varID)
       checkname = TRUE;
       iz = 0;
 
-      while ( checkname ) 
+      while ( checkname )
         {
           if ( iz ) sprintf(varname, "%s_%d", name, iz+1);
 
@@ -40680,12 +40817,15 @@ int cdfDefVar(int streamID, int varID)
   streamptr->vars[varID].ncvarid = ncvarid;
 
   if ( vlistInqVarMissvalUsed(vlistID, varID) )
-    cdfDefVarMissval(streamID, varID, vlistInqVarDatatype(vlistID, varID), 0);
+    cdfDefVarMissval(streamptr, varID, vlistInqVarDatatype(vlistID, varID), 0);
 
   if ( zid == -1 )
     {
-      if ( zaxisInqType(zaxisID) == ZAXIS_TOA         || 
-           zaxisInqType(zaxisID) == ZAXIS_SEA_BOTTOM  ||
+      if ( zaxisInqType(zaxisID) == ZAXIS_CLOUD_BASE    ||
+           zaxisInqType(zaxisID) == ZAXIS_CLOUD_TOP     ||
+           zaxisInqType(zaxisID) == ZAXIS_ISOTHERM_ZERO ||
+           zaxisInqType(zaxisID) == ZAXIS_TOA           ||
+           zaxisInqType(zaxisID) == ZAXIS_SEA_BOTTOM    ||
            zaxisInqType(zaxisID) == ZAXIS_ATMOSPHERE )
         {
           zaxisInqName(zaxisID, varname);
@@ -40693,12 +40833,11 @@ int cdfDefVar(int streamID, int varID)
         }
     }
 
-  if( vlistInqVarEnsemble( vlistID,  varID, &ensID, &ensCount, &forecast_type ) )
+  if ( vlistInqVarEnsemble( vlistID,  varID, &ensID, &ensCount, &forecast_type ) )
     {
       /* void cdf_put_att_int(  int ncid, int varid, const char *name, nc_type xtype,
 	                        size_t len, const int *ip )
        */
-
 	cdf_put_att_int(fileID, ncvarid, "realization", NC_INT, 1, &ensID);
 	cdf_put_att_int(fileID, ncvarid, "ensemble_members", NC_INT, 1, &ensCount);
 	cdf_put_att_int(fileID, ncvarid, "forecast_init_type", NC_INT, 1, &forecast_type);
@@ -40741,7 +40880,7 @@ void scale_add(long size, double *data, double addoffset, double scalefactor)
 }
 #endif
 
-void cdfReadVarDP(int streamID, int varID, double *data, int *nmiss)
+void cdfReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int fileID;
@@ -40762,15 +40901,11 @@ void cdfReadVarDP(int streamID, int varID, double *data, int *nmiss)
   double missval;
   int laddoffset, lscalefactor;
   double addoffset, scalefactor;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  if ( CDI_Debug )
-    Message("streamID = %d  varID = %d", streamID, varID);
+  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   tsID = streamptr->curTsID;
 
@@ -40785,7 +40920,7 @@ void cdfReadVarDP(int streamID, int varID, double *data, int *nmiss)
   gridindex = vlistGridIndex(vlistID, gridID);
   if ( gridInqType(gridID) == GRID_TRAJECTORY )
     {
-      cdfReadGridTraj(streamID, gridID);
+      cdfReadGridTraj(streamptr, gridID);
     }
   else
     {
@@ -41053,7 +41188,7 @@ int cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarid, int dtyp
 }
 #endif
 
-void cdf_write_var(int streamID, int varID, int memtype, const void *data, int nmiss)
+void cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data, int nmiss)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int fileID;
@@ -41074,23 +41209,18 @@ void cdf_write_var(int streamID, int varID, int memtype, const void *data, int n
   int gridindex, zaxisindex;
   int dtype;
   int vlistID;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
+  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
 
-  if ( CDI_Debug )
-    Message("streamID = %d  varID = %d", streamID, varID);
-
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   ntsteps = streamptr->ntsteps;
-  if ( CDI_Debug )
-    Message("ntsteps = %d", ntsteps); 
+  if ( CDI_Debug ) Message("ntsteps = %d", ntsteps);
 
-  if ( vlistHasTime(vlistID) ) cdfDefTime(streamID);
+  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
 
-  ncvarid = cdfDefVar(streamID, varID);
+  ncvarid = cdfDefVar(streamptr, varID);
 
   gridID    = vlistInqVarGrid(vlistID, varID);
   zaxisID   = vlistInqVarZaxis(vlistID, varID);
@@ -41099,7 +41229,7 @@ void cdf_write_var(int streamID, int varID, int memtype, const void *data, int n
   gridindex = vlistGridIndex(vlistID, gridID);
   if ( gridInqType(gridID) == GRID_TRAJECTORY )
     {
-      cdfWriteGridTraj(streamID, gridID);
+      cdfWriteGridTraj(streamptr, gridID);
     }
   else
     {
@@ -41151,7 +41281,7 @@ void cdf_write_var(int streamID, int varID, int memtype, const void *data, int n
 
   dtype = vlistInqVarDatatype(vlistID, varID);
 
-  if ( nmiss > 0 ) cdfDefVarMissval(streamID, varID, dtype, 1);
+  if ( nmiss > 0 ) cdfDefVarMissval(streamptr, varID, dtype, 1);
 
   nvals = gridInqSize(gridID)*zaxisInqSize(zaxisID);
 
@@ -41161,7 +41291,7 @@ void cdf_write_var(int streamID, int varID, int memtype, const void *data, int n
 }
 
 
-int cdfReadVarSliceDP(int streamID, int varID, int levelID, double *data, int *nmiss)
+int cdfReadVarSliceDP(stream_t *streamptr, int varID, int levelID, double *data, int *nmiss)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int fileID;
@@ -41189,19 +41319,15 @@ int cdfReadVarSliceDP(int streamID, int varID, int levelID, double *data, int *n
   double missval;
   int laddoffset, lscalefactor;
   double addoffset, scalefactor;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   if ( CDI_Debug )
-    Message("streamID = %d  varID = %d  levelID = %d", streamID, varID, levelID);
+    Message("streamID = %d  varID = %d  levelID = %d", streamptr->self, varID, levelID);
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   tsID = streamptr->curTsID;
-  if ( CDI_Debug )
-    Message("tsID = %d", tsID);
+  if ( CDI_Debug ) Message("tsID = %d", tsID);
 
   ncvarid = streamptr->vars[varID].ncvarid;
 
@@ -41220,7 +41346,7 @@ int cdfReadVarSliceDP(int streamID, int varID, int levelID, double *data, int *n
   gridindex = vlistGridIndex(vlistID, gridID);
   if ( gridInqType(gridID) == GRID_TRAJECTORY )
     {
-      cdfReadGridTraj(streamID, gridID);
+      cdfReadGridTraj(streamptr, gridID);
     }
   else if ( gridInqType(gridID) == GRID_UNSTRUCTURED )
     {
@@ -41235,7 +41361,7 @@ int cdfReadVarSliceDP(int streamID, int varID, int levelID, double *data, int *n
   zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
   zid = streamptr->zaxisID[zaxisindex];
   /*
-  printf("2 %d %d %d %s\n", streamID, zaxisindex, streamptr->zaxisID[zaxisindex], vlistInqVarNamePtr(vlistID, varID));
+  printf("2 %p %d %d %s\n", streamptr, zaxisindex, streamptr->zaxisID[zaxisindex], vlistInqVarNamePtr(vlistID, varID));
   */
   dimorder[0] = ixyz/100;
   dimorder[1] = (ixyz-dimorder[0]*100)/10;
@@ -41369,7 +41495,7 @@ int cdfReadVarSliceDP(int streamID, int varID, int levelID, double *data, int *n
 }
 
 
-int cdf_write_var_slice(int streamID, int varID, int levelID, int memtype, const void *data, int nmiss)
+int cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, int nmiss)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int fileID;
@@ -41391,23 +41517,19 @@ int cdf_write_var_slice(int streamID, int varID, int levelID, int memtype, const
   int swapxy = FALSE;
   int dtype;
   int vlistID;
-  stream_t *streamptr;
   extern int CDF_Debug;
 
-  streamptr = stream_to_pointer(streamID);
-
-  if ( CDI_Debug )
-    Message("streamID = %d  varID = %d", streamID, varID);
+  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   ntsteps = streamptr->ntsteps;
   if ( CDI_Debug ) Message("ntsteps = %d", ntsteps);
 
-  if ( vlistHasTime(vlistID) ) cdfDefTime(streamID);
+  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
 
-  ncvarid = cdfDefVar(streamID, varID);
+  ncvarid = cdfDefVar(streamptr, varID);
 
   gridID    = vlistInqVarGrid(vlistID, varID);
   zaxisID   = vlistInqVarZaxis(vlistID, varID);
@@ -41418,7 +41540,7 @@ int cdf_write_var_slice(int streamID, int varID, int levelID, int memtype, const
   gridindex = vlistGridIndex(vlistID, gridID);
   if ( gridInqType(gridID) == GRID_TRAJECTORY )
     {
-      cdfWriteGridTraj(streamID, gridID);
+      cdfWriteGridTraj(streamptr, gridID);
     }
   else
     {
@@ -41477,7 +41599,7 @@ int cdf_write_var_slice(int streamID, int varID, int levelID, int memtype, const
 
   dtype = vlistInqVarDatatype(vlistID, varID);
 
-  if ( nmiss > 0 ) cdfDefVarMissval(streamID, varID, dtype, 1);
+  if ( nmiss > 0 ) cdfDefVarMissval(streamptr, varID, dtype, 1);
 
   nvals = gridInqSize(gridID);
 
@@ -41487,8 +41609,8 @@ int cdf_write_var_slice(int streamID, int varID, int levelID, int memtype, const
   return (0);
 }
 
-
-void cdfCreateRecords(int streamID, int tsID)
+static
+void cdfCreateRecords(stream_t *streamptr, int tsID)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int varID, levelID, recID, vrecID, zaxisID;
@@ -41496,11 +41618,8 @@ void cdfCreateRecords(int streamID, int tsID)
   record_t *records = NULL;
   int *recIDs = NULL;
   int vlistID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  vlistID  = streamInqVlist(streamID);
+  vlistID  = streamptr->vlistID;
 
   if ( tsID < 0 || (tsID >= streamptr->ntsteps && tsID > 0) ) return;
 
@@ -42061,11 +42180,24 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
 #endif
 
       if ( nvdims > 0 )
-        if ( timedimid == dimidsp[0] )
-          {
-            ncvars[ncvarid].tsteptype = TSTEP_INSTANT;
-            cdfSetDim(ncvars, ncvarid, 0, T_AXIS);
-          }
+        {
+          if ( timedimid == dimidsp[0] )
+            {
+              ncvars[ncvarid].tsteptype = TSTEP_INSTANT;
+              cdfSetDim(ncvars, ncvarid, 0, T_AXIS);
+            }
+          else
+            {
+              for ( ncdimid = 1; ncdimid < nvdims; ncdimid++ )
+                {
+                  if ( timedimid == dimidsp[ncdimid] )
+                    {
+                      Warning("Time must be the first dimension! Unsupported array structure, skipped variable %s!", ncvars[ncvarid].name);
+                      ncvars[ncvarid].isvar = FALSE;
+                    }
+                }
+            }
+        }
 
       for ( iatt = 0; iatt < nvatts; iatt++ )
         {
@@ -42171,12 +42303,18 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
 
               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, "atmosphere") == 0 )
                 ncvars[ncvarid].zaxistype = ZAXIS_ATMOSPHERE;
               else
-                { 
+                {
                   static int warn = TRUE;
                   if ( warn )
                     {
@@ -42380,22 +42518,58 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
             {
               if ( ncvars[ncvarid].lvalidrange == 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); */
+                  extern int cdiIgnoreValidRange;
+                  int lignore = FALSE;
+                  if ( (atttype == NC_FLOAT || atttype == NC_DOUBLE) && xtype != NC_FLOAT && xtype != NC_DOUBLE ) lignore = TRUE;
+                  if ( cdiIgnoreValidRange == FALSE && lignore == FALSE )
+                    {
+                      cdfGetAttDouble(ncid, ncvarid, attname, 2, ncvars[ncvarid].validrange);
+                      ncvars[ncvarid].lvalidrange = TRUE;
+                      if ( ((int)ncvars[ncvarid].validrange[0]) == 0 && ((int)ncvars[ncvarid].validrange[1]) == 255 )
+                        ncvars[ncvarid].lunsigned = TRUE;
+                      /* cdfSetVar(ncvars, ncvarid, TRUE); */
+                    }
+                  else if ( lignore )
+                    {
+                      Warning("Inconsistent data type for attribute %s:valid_range, ignored!", name);
+                    }
                 }
             }
           else if ( strcmp(attname, "valid_min") == 0 && attlen == 1 )
             {
-              cdfGetAttDouble(ncid, ncvarid, attname, 1, &(ncvars[ncvarid].validrange)[0]);
-              ncvars[ncvarid].lvalidrange = TRUE;
+              if ( ncvars[ncvarid].lvalidrange == FALSE )
+                {
+                  extern int cdiIgnoreValidRange;
+                  int lignore = FALSE;
+                  if ( (atttype == NC_FLOAT || atttype == NC_DOUBLE) && xtype != NC_FLOAT && xtype != NC_DOUBLE ) lignore = TRUE;
+                  if ( cdiIgnoreValidRange == FALSE && lignore == FALSE )
+                    {
+                      cdfGetAttDouble(ncid, ncvarid, attname, 1, &(ncvars[ncvarid].validrange)[0]);
+                      ncvars[ncvarid].lvalidrange = TRUE;
+                    }
+                  else if ( lignore )
+                    {
+                      Warning("Inconsistent data type for attribute %s:valid_min, ignored!", name);
+                    }
+                }
             }
           else if ( strcmp(attname, "valid_max") == 0 && attlen == 1 )
             {
-              cdfGetAttDouble(ncid, ncvarid, attname, 1, &(ncvars[ncvarid].validrange)[1]);
-              ncvars[ncvarid].lvalidrange = TRUE;
+              if ( ncvars[ncvarid].lvalidrange == FALSE )
+                {
+                  extern int cdiIgnoreValidRange;
+                  int lignore = FALSE;
+                  if ( (atttype == NC_FLOAT || atttype == NC_DOUBLE) && xtype != NC_FLOAT && xtype != NC_DOUBLE ) lignore = TRUE;
+                  if ( cdiIgnoreValidRange == FALSE && lignore == FALSE )
+                    {
+                      cdfGetAttDouble(ncid, ncvarid, attname, 1, &(ncvars[ncvarid].validrange)[1]);
+                      ncvars[ncvarid].lvalidrange = TRUE;
+                    }
+                  else if ( lignore )
+                    {
+                      Warning("Inconsistent data type for attribute %s:valid_max, ignored!", name);
+                    }
+                }
             }
           else if ( strcmp(attname, "_Unsigned") == 0 && atttype == NC_CHAR )
             {
@@ -42805,7 +42979,7 @@ void copy_numeric_projatts(int gridID, int ncvarID, int ncfileID)
 
 /* define all input grids */
 static
-void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nvars, ncvar_t *ncvars, int timedimid)
+void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nvars, ncvar_t *ncvars, int timedimid, char *uuidOfHGrid)
 {
   int ncvarid, ncvarid2;
   int ndims;
@@ -43352,6 +43526,9 @@ void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
 #endif
 	    ncvars[ncvarid].gridID = varDefGrid(vlistID, grid, 1);
 
+          if ( uuidOfHGrid[0] != 0 && grid.type == GRID_UNSTRUCTURED )
+            gridDefUUID(ncvars[ncvarid].gridID, uuidOfHGrid);
+
           if ( ncvars[ncvarid].chunked )
             {
               ndims = ncvars[ncvarid].ndims;
@@ -43367,7 +43544,7 @@ void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
                 {
                   if ( grid.xsize > 1 && grid.ysize > 1 && ndims > 1 &&
                        grid.xsize == ncvars[ncvarid].chunks[ndims-1] &&
-                       grid.ysize == ncvars[ncvarid].chunks[ndims-2] ) 
+                       grid.ysize == ncvars[ncvarid].chunks[ndims-2] )
                     ncvars[ncvarid].chunktype = CHUNK_GRID;
                   else if ( grid.xsize > 1 && grid.xsize == ncvars[ncvarid].chunks[ndims-1] )
                     ncvars[ncvarid].chunktype = CHUNK_LINES;
@@ -43556,7 +43733,7 @@ void define_all_zaxes(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
 	    Message("zaxisID %d %d %s", ncvars[ncvarid].zaxisID, ncvarid, ncvars[ncvarid].name);
 
 	  for ( ncvarid2 = ncvarid+1; ncvarid2 < nvars; ncvarid2++ )
-	    if ( ncvars[ncvarid2].isvar == TRUE && ncvars[ncvarid2].zaxisID == UNDEFID )
+	    if ( ncvars[ncvarid2].isvar == TRUE && ncvars[ncvarid2].zaxisID == UNDEFID && ncvars[ncvarid2].zaxistype == UNDEFID )
 	      {
 		int zdimid2 = -1;
 		ndims = ncvars[ncvarid2].ndims;
@@ -43579,17 +43756,12 @@ void define_all_zaxes(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
 
 /* define all input data variables */
 static
-void define_all_vars(int streamID, int vlistID, int instID, int modelID, int *varids, int nvars, ncvar_t *ncvars)
+void define_all_vars(stream_t *streamptr, int vlistID, int instID, int modelID, int *varids, int nvars, ncvar_t *ncvars)
 {
   int ncid;
   int varID1, varID, ncvarid;
   int code;
   int tableID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   if ( streamptr->sortname )
     {
@@ -43624,7 +43796,7 @@ void define_all_vars(int streamID, int vlistID, int instID, int modelID, int *va
       gridID  = ncvars[ncvarid].gridID;
       zaxisID = ncvars[ncvarid].zaxisID;
 
-      varID = streamNewVar(streamID, gridID, zaxisID);
+      varID = stream_new_var(streamptr, gridID, zaxisID);
       varID = vlistDefVar(vlistID, gridID, zaxisID, ncvars[ncvarid].tsteptype);
 
 #if  defined  (HAVE_NETCDF4)
@@ -43860,10 +44032,9 @@ void define_all_vars(int streamID, int vlistID, int instID, int modelID, int *va
 		  tableID = cdiDefaultTableID;
 		}
 	    }
-	  if ( cdiDefaultModelID != UNDEFID )
-	    modelID = cdiDefaultModelID;
-	  if ( cdiDefaultInstID != UNDEFID )
-	    instID = cdiDefaultInstID;
+
+	  if ( cdiDefaultModelID != UNDEFID ) modelID = cdiDefaultModelID;
+	  if ( cdiDefaultInstID  != UNDEFID ) instID  = cdiDefaultInstID;
 	}
       if ( instID  != UNDEFID ) vlistDefVarInstitut(vlistID, varID, instID);
       if ( modelID != UNDEFID ) vlistDefVarModel(vlistID, varID, modelID);
@@ -43872,8 +44043,8 @@ void define_all_vars(int streamID, int vlistID, int instID, int modelID, int *va
 }
 
 static
-void read_global_attributtes(int fileID, int vlistID, stream_t *streamptr, int ngatts,
-                               int *instID, int *modelID, int *ucla_les)
+void scan_global_attributtes(int fileID, int vlistID, stream_t *streamptr, int ngatts,
+                             int *instID, int *modelID, int *ucla_les, char *uuidOfHGrid)
 {
   nc_type xtype;
   size_t attlen;
@@ -43906,6 +44077,8 @@ void read_global_attributtes(int fileID, int vlistID, stream_t *streamptr, int n
 	      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 )
 		{
@@ -43923,6 +44096,12 @@ void read_global_attributtes(int fileID, int vlistID, stream_t *streamptr, int n
 	      else if ( strcmp(attname, "CDO") == 0 )
 		{
 		}
+	      else if ( strcmp(attname, "uuidOfHGrid") == 0 && attlen == 36 )
+		{
+                  attstring[36] = 0;
+                  str2uuid(attstring, uuidOfHGrid);
+                  //   printf("uuid: %d %s\n", attlen, attstring);
+		}
 	      else
 		{
 		  vlistDefAttTxt(vlistID, CDI_GLOBAL, attname, (int)attlen, attstring);
@@ -43955,7 +44134,7 @@ void read_global_attributtes(int fileID, int vlistID, stream_t *streamptr, int n
 }
 #endif
 
-int cdfInqContents(int streamID)
+int cdfInqContents(stream_t *streamptr)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int ndims, nvars, ngatts, unlimdimid;
@@ -43983,19 +44162,16 @@ int cdfInqContents(int streamID)
   ncdim_t *ncdims;
   ncvar_t *ncvars = NULL;
   int vlistID;
-  stream_t *streamptr;
   int format = 0;
   int ucla_les = FALSE;
+  char uuidOfHGrid[17];
 
-  streamptr = stream_to_pointer(streamID);
+  uuidOfHGrid[0] = 0;
 
-  stream_check_ptr(__func__, streamptr);
-
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
-  if ( CDI_Debug )
-    Message("streamID = %d, fileID = %d", streamID, fileID);
+  if ( CDI_Debug ) Message("streamID = %d, fileID = %d", streamptr->self, fileID);
 
 #if  defined  (HAVE_NETCDF4)
   nc_inq_format(fileID, &format);
@@ -44059,8 +44235,8 @@ int cdfInqContents(int streamID)
       return (CDI_EUFSTRUCT);
     }
 
-  /* read global attributtes */
-  read_global_attributtes(fileID, vlistID, streamptr, ngatts, &instID, &modelID, &ucla_les);
+  /* scan global attributtes */
+  scan_global_attributtes(fileID, vlistID, streamptr, ngatts, &instID, &modelID, &ucla_les, uuidOfHGrid);
 
   /* find time dim */
   if ( unlimdimid >= 0 )
@@ -44146,13 +44322,13 @@ int cdfInqContents(int streamID)
 	      {
 		streamptr->basetime.ncvarid = ncvarid;
 		ltimevar = TRUE;
-		if ( CDI_Debug ) 
+		if ( CDI_Debug )
 		  fprintf(stderr, "timevar %s\n", ncvars[ncvarid].name);
 	      }
 	    else
 	      {
 		if ( CDI_Debug )
-		  fprintf(stderr, "skip timevar %s\n", ncvars[ncvarid].name);
+		  fprintf(stderr, "skipped timevar %s\n", ncvars[ncvarid].name);
 	      }
 	  }
 
@@ -44353,7 +44529,7 @@ int cdfInqContents(int streamID)
 
 
   /* define all grids */
-  define_all_grids(streamptr, vlistID, ncdims, nvars, ncvars, timedimid);
+  define_all_grids(streamptr, vlistID, ncdims, nvars, ncvars, timedimid, uuidOfHGrid);
 
 
   /* read VCT */
@@ -44395,10 +44571,10 @@ int cdfInqContents(int streamID)
   streamptr->ntsteps = ntsteps;
 
   /* define all data variables */
-  define_all_vars(streamID, vlistID, instID, modelID, varids, nvars_data, ncvars);
+  define_all_vars(streamptr, vlistID, instID, modelID, varids, nvars_data, ncvars);
 
 
-  cdiCreateTimesteps(streamID);
+  cdiCreateTimesteps(streamptr);
 
   /* time varID */
   ncvarid = streamptr->basetime.ncvarid;
@@ -44488,9 +44664,9 @@ int cdfInqContents(int streamID)
   streamptr->curTsID = 0;
   streamptr->rtsteps = 1;
 
-  (void) cdfInqTimestep(streamID, 0);
+  (void) cdfInqTimestep(streamptr, 0);
 
-  cdfCreateRecords(streamID, 0);
+  cdfCreateRecords(streamptr, 0);
 
   /* free ncdims */
   free (ncdims);
@@ -44504,7 +44680,7 @@ int cdfInqContents(int streamID)
 }
 
 
-int cdfInqTimestep(int streamID, int tsID)
+int cdfInqTimestep(stream_t * streamptr, int tsID)
 {
   long nrecs = 0;
 #if  defined  (HAVE_LIBNETCDF)
@@ -44514,20 +44690,14 @@ int cdfInqTimestep(int streamID, int tsID)
   int fileID;
   size_t index;
   taxis_t *taxis;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  if ( CDI_Debug )
-    Message("streamID = %d  tsID = %d", streamID, tsID);
-
-  stream_check_ptr(__func__, streamptr);
+  if ( CDI_Debug ) Message("streamID = %d  tsID = %d", streamptr->self, tsID);
 
   if ( tsID < 0 ) Error("unexpected tsID = %d", tsID);
 
   if ( tsID < streamptr->ntsteps && streamptr->ntsteps > 0 )
     {
-      cdfCreateRecords(streamID, tsID);
+      cdfCreateRecords(streamptr, tsID);
 
       taxis = &streamptr->tsteps[tsID].taxis;
       if ( tsID > 0 )
@@ -44538,7 +44708,7 @@ int cdfInqTimestep(int streamID, int tsID)
       nctimevarid = streamptr->basetime.ncvarid;
       if ( nctimevarid != UNDEFID )
 	{
-	  fileID = streamInqFileID(streamID);
+	  fileID = streamptr->fileID;
 	  index  = tsID;
 
 	  if ( streamptr->basetime.lwrf )
@@ -44562,7 +44732,7 @@ int cdfInqTimestep(int streamID, int tsID)
 	  else
 	    {
 	      cdf_get_var1_double(fileID, nctimevarid, &index, &timevalue);
-              if ( timevalue >= NC_FILL_DOUBLE ) timevalue = 0;
+              if ( timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE ) timevalue = 0;
 
 	      cdiDecodeTimeval(timevalue, taxis, &taxis->vdate, &taxis->vtime);
 	    }
@@ -44573,13 +44743,13 @@ int cdfInqTimestep(int streamID, int tsID)
 	      size_t start[2], count[2];
 	      start[0] = tsID; count[0] = 1; start[1] = 0; count[1] = 1;
 	      cdf_get_vara_double(fileID, nctimeboundsid, start, count, &timevalue);
-              if ( timevalue >= NC_FILL_DOUBLE ) timevalue = 0;
+              if ( timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE ) timevalue = 0;
 
 	      cdiDecodeTimeval(timevalue, taxis, &taxis->vdate_lb, &taxis->vtime_lb);
 
 	      start[0] = tsID; count[0] = 1; start[1] = 1; count[1] = 1;
 	      cdf_get_vara_double(fileID, nctimeboundsid, start, count, &timevalue);
-              if ( timevalue >= NC_FILL_DOUBLE ) timevalue = 0;
+              if ( timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE ) timevalue = 0;
 
 	      cdiDecodeTimeval(timevalue, taxis, &taxis->vdate_ub, &taxis->vtime_ub);
 	    }
@@ -44594,20 +44764,17 @@ int cdfInqTimestep(int streamID, int tsID)
 }
 
 
-void cdfEndDef(int streamID)
+void cdfEndDef(stream_t *streamptr)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int varID;
   int nvars;
   int fileID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  fileID  = streamInqFileID(streamID);
+  fileID  = streamptr->fileID;
 
-  cdfDefGlobalAtts(streamID);
-  cdfDefLocalAtts(streamID);
+  cdfDefGlobalAtts(streamptr);
+  cdfDefLocalAtts(streamptr);
   if ( streamptr->accessmode == 0 )
     {
       nvars =  streamptr->nvars;
@@ -44615,7 +44782,7 @@ void cdfEndDef(int streamID)
       if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
       for ( varID = 0; varID < nvars; varID++ )
-	cdfDefVar(streamID, varID);
+	cdfDefVar(streamptr, varID);
 
       if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
 
@@ -44625,19 +44792,16 @@ void cdfEndDef(int streamID)
 }
 
 
-void cdfDefInstitut(int streamID)
+void cdfDefInstitut(stream_t *streamptr)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int fileID, instID;
   char *longname;
   size_t len;
   int vlistID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
   instID  = vlistInqInstitut(vlistID);
 
   if ( instID != UNDEFID )
@@ -44657,19 +44821,17 @@ void cdfDefInstitut(int streamID)
 #endif
 }
 
-void cdfDefSource(int streamID)
+
+void cdfDefSource(stream_t *streamptr)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int fileID, modelID;
   char *longname;
   size_t len;
   int vlistID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
   modelID = vlistInqModel(vlistID);
 
   if ( modelID != UNDEFID )
@@ -44690,22 +44852,19 @@ void cdfDefSource(int streamID)
 }
 
 
-void cdfDefGlobalAtts(int streamID)
+void cdfDefGlobalAtts(stream_t *streamptr)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int fileID, vlistID;
-  stream_t *streamptr;
   int natts;
 
-  streamptr = stream_to_pointer(streamID);
-
   if ( streamptr->globalatts ) return;
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
-  cdfDefSource(streamID);
-  cdfDefInstitut(streamID);
+  cdfDefSource(streamptr);
+  cdfDefInstitut(streamptr);
 
   vlistInqNatts(vlistID, CDI_GLOBAL, &natts);
 
@@ -44720,7 +44879,7 @@ void cdfDefGlobalAtts(int streamID)
 }
 
 
-void cdfDefLocalAtts(int streamID)
+void cdfDefLocalAtts(stream_t *streamptr)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int varID, instID, fileID;
@@ -44728,12 +44887,9 @@ void cdfDefLocalAtts(int streamID)
   size_t len;
   int ncvarid;
   int vlistID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   if ( streamptr->localatts ) return;
   if ( vlistInqInstitut(vlistID) != UNDEFID ) return;
@@ -44761,27 +44917,23 @@ void cdfDefLocalAtts(int streamID)
 #endif
 }
 
-void cdfDefHistory(int streamID, int size, char *history)
+
+void cdfDefHistory(stream_t *streamptr, int size, char *history)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int ncid;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   ncid = streamptr->fileID;
   cdf_put_att_text(ncid, NC_GLOBAL, "history", (size_t) size, history);
 #endif
 }
 
-int cdfInqHistorySize(int streamID)
+
+int cdfInqHistorySize(stream_t *streamptr)
 {
   size_t size = 0;
 #if  defined  (HAVE_LIBNETCDF)
   int ncid;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   ncid = streamptr->fileID;
   if ( streamptr->historyID != UNDEFID )
@@ -44792,13 +44944,10 @@ int cdfInqHistorySize(int streamID)
 }
 
 
-void cdfInqHistoryString(int streamID, char *history)
+void cdfInqHistoryString(stream_t *streamptr, char *history)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int ncid;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   ncid = streamptr->fileID;
   if ( streamptr->historyID != UNDEFID )
@@ -44808,42 +44957,39 @@ void cdfInqHistoryString(int streamID, char *history)
 }
 
 
-void cdfDefVars(int streamID)
+void cdfDefVars(stream_t *streamptr)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int index, gridID, zaxisID, vlistID;
   int ngrids, nzaxis;
   /* int  nvars, ncvarid; */
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   if ( vlistID == UNDEFID )
-    Error("Internal problem! vlist undefined for streamID %d", streamID);
+    Error("Internal problem! vlist undefined for streamptr %p", streamptr);
 
   /* nvars  = vlistNvars(vlistID); */
   ngrids = vlistNgrids(vlistID);
   nzaxis = vlistNzaxis(vlistID);
   /*
-  if ( vlistHasTime(vlistID) ) cdfDefTime(streamID);
+  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
   */
   for ( index = 0; index < ngrids; index++ )
     {
       gridID = vlistGrid(vlistID, index);
-      cdfDefGrid(streamID, gridID);
+      cdfDefGrid(streamptr, gridID);
     }
 
   for ( index = 0; index < nzaxis; index++ )
     {
       zaxisID = vlistZaxis(vlistID, index);
-      if ( streamptr->zaxisID[index] == UNDEFID ) cdfDefZaxis(streamID, zaxisID);
+      if ( streamptr->zaxisID[index] == UNDEFID ) cdfDefZaxis(streamptr, zaxisID);
     }
   /*
     define time first!!!
   for (varID = 0; varID < nvars; varID++ )
     {
-      ncvarid = cdfDefVar(streamID, varID);
+      ncvarid = cdfDefVar(streamptr, varID);
     }
   */
 #endif
@@ -44866,12 +45012,8 @@ void cdfDefVars(int streamID)
 
 
 static
-void streamvarInitEntry(int streamID, int varID)
+void streamvar_init_entry(stream_t *streamptr, int varID)
 {
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
   streamptr->vars[varID].ncvarid      = CDI_UNDEFID;
   streamptr->vars[varID].defmiss      = 0;
   streamptr->vars[varID].nlevs        = 0;
@@ -44886,14 +45028,11 @@ void streamvarInitEntry(int streamID, int varID)
 }
 
 static
-int streamvarNewEntry(int streamID)
+int streamvar_new_entry(stream_t *streamptr)
 {
   int varID = 0;
   int streamvarSize;
   svarinfo_t *streamvar;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   streamvarSize = streamptr->varsAllocated;
   streamvar     = streamptr->vars;
@@ -44947,7 +45086,7 @@ int streamvarNewEntry(int streamID)
   streamptr->varsAllocated = streamvarSize;
   streamptr->vars          = streamvar;
 
-  streamvarInitEntry(streamID, varID);
+  streamvar_init_entry(streamptr, varID);
 
   streamptr->vars[varID].isUsed = TRUE;
 
@@ -44955,21 +45094,18 @@ int streamvarNewEntry(int streamID)
 }
 
 
-int streamNewVar(int streamID, int gridID, int zaxisID)
+int stream_new_var(stream_t *streamptr, int gridID, int zaxisID)
 {
   int varID;
   int *level;
   int *lindex;
   int nlevs;
   int levID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   if ( CDI_Debug )
     Message("gridID = %d  zaxisID = %d", gridID, zaxisID);
 
-  varID = streamvarNewEntry(streamID);
+  varID = streamvar_new_entry(streamptr);
 
   streamptr->nvars++;
 
@@ -45020,17 +45156,15 @@ void recordInitEntry(record_t *record)
   (*record).used     = FALSE;
   (*record).varID    = CDI_UNDEFID;
   (*record).levelID  = CDI_UNDEFID;
+  memset((*record).varname, 0, sizeof((*record).varname));
 }
 
 
-int recordNewEntry(int streamID, int tsID)
+int recordNewEntry(stream_t *streamptr, int tsID)
 {
   int recordID = 0;
   int recordSize;
   record_t *records;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   recordSize = streamptr->tsteps[tsID].recordSize;
   records    = streamptr->tsteps[tsID].records;
@@ -45091,13 +45225,9 @@ int recordNewEntry(int streamID, int tsID)
   return (recordID);
 }
 
-
-void cdiInitRecord(int streamID)
+static
+void cdiInitRecord(stream_t *streamptr)
 {
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
   streamptr->record = (Record *) malloc(sizeof(Record));
 
   streamptr->record->used       = 0;
@@ -45134,7 +45264,7 @@ void streamInqRecord(int streamID, int *varID, int *levelID)
 
   cdiDefAccesstype(streamID, TYPE_REC);
 
-  if ( ! streamptr->record ) cdiInitRecord(streamID);
+  if ( ! streamptr->record ) cdiInitRecord(streamptr);
 
   tsID   = streamptr->curTsID;
   rindex = streamptr->tsteps[tsID].curRecID + 1;
@@ -45172,7 +45302,7 @@ void streamInqRecord(int streamID, int *varID, int *levelID)
       }
     case FILETYPE_SRV:
       {
-        rec = srvInqRecord(streamID, varID, levelID);
+        rec = srvInqRecord(streamptr, varID, levelID);
 	break;
       }
 #if  defined  (HAVE_LIBNETCDF)
@@ -45216,9 +45346,9 @@ void streamDefRecord(int streamID, int varID, int levelID)
       streamDefTimestep(streamID, tsID);
     }
 
-  if ( ! streamptr->record ) cdiInitRecord(streamID);
+  if ( ! streamptr->record ) cdiInitRecord(streamptr);
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   gridID  = vlistInqVarGrid(vlistID, varID);
   zaxisID = vlistInqVarZaxis(vlistID, varID);
   param   = vlistInqVarParam(vlistID, varID);
@@ -45242,28 +45372,28 @@ void streamDefRecord(int streamID, int varID, int levelID)
     case FILETYPE_GRB:
     case FILETYPE_GRB2:
       {
-        status = grbDefRecord(streamID);
+        status = grbDefRecord(streamptr);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBSERVICE)
     case FILETYPE_SRV:
       {
-        status = srvDefRecord(streamID);
+        status = srvDefRecord(streamptr);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBEXTRA)
     case FILETYPE_EXT:
       {
-        status = extDefRecord(streamID);
+        status = extDefRecord(streamptr);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBIEG)
     case FILETYPE_IEG:
       {
-        status = iegDefRecord(streamID);
+        status = iegDefRecord(streamptr);
 	break;
       }
 #endif
@@ -45273,8 +45403,8 @@ void streamDefRecord(int streamID, int varID, int levelID)
     case FILETYPE_NC4:
     case FILETYPE_NC4C:
       {
-	if ( streamptr->accessmode == 0 ) cdfEndDef(streamID);
-	status = cdfDefRecord(streamID);
+	if ( streamptr->accessmode == 0 ) cdfEndDef(streamptr);
+	status = cdfDefRecord(streamptr);
 	break;
       }
 #endif
@@ -45310,28 +45440,28 @@ void streamReadRecord(int streamID, double *data, int *nmiss)
     case FILETYPE_GRB:
     case FILETYPE_GRB2:
       {
-        status = grbReadRecord(streamID, data, nmiss);
+        status = grbReadRecord(streamptr, data, nmiss);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBSERVICE)
     case FILETYPE_SRV:
       {
-        status = srvReadRecord(streamID, data, nmiss);
+        status = srvReadRecord(streamptr, data, nmiss);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBEXTRA)
     case FILETYPE_EXT:
       {
-        status = extReadRecord(streamID, data, nmiss);
+        status = extReadRecord(streamptr, data, nmiss);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBIEG)
     case FILETYPE_IEG:
       {
-        status = iegReadRecord(streamID, data, nmiss);
+        status = iegReadRecord(streamptr, data, nmiss);
 	break;
       }
 #endif
@@ -45341,7 +45471,7 @@ void streamReadRecord(int streamID, double *data, int *nmiss)
     case FILETYPE_NC4:
     case FILETYPE_NC4C:
       {
-	status = cdfReadRecord(streamID, data, nmiss);
+	status = cdfReadRecord(streamptr, data, nmiss);
 	break;
       }
 #endif
@@ -45374,8 +45504,7 @@ void stream_write_record(int streamID, int memtype, const void *data, int nmiss)
     case FILETYPE_GRB:
     case FILETYPE_GRB2:
       {
-        if ( memtype == MEMTYPE_FLOAT ) Error("grbWriteRecord not implemented for memtype float!");
-        status = grbWriteRecord(streamID, data, nmiss);
+        status = grb_write_record(streamptr, memtype, data, nmiss);
 	break;
       }
 #endif
@@ -45383,7 +45512,7 @@ void stream_write_record(int streamID, int memtype, const void *data, int nmiss)
     case FILETYPE_SRV:
       {
         if ( memtype == MEMTYPE_FLOAT ) Error("srvWriteRecord not implemented for memtype float!");
-        status = srvWriteRecord(streamID, data);
+        status = srvWriteRecord(streamptr, data);
 	break;
       }
 #endif
@@ -45391,7 +45520,7 @@ void stream_write_record(int streamID, int memtype, const void *data, int nmiss)
     case FILETYPE_EXT:
       {
         if ( memtype == MEMTYPE_FLOAT ) Error("extWriteRecord not implemented for memtype float!");
-        status = extWriteRecord(streamID, data);
+        status = extWriteRecord(streamptr, data);
 	break;
       }
 #endif
@@ -45399,7 +45528,7 @@ void stream_write_record(int streamID, int memtype, const void *data, int nmiss)
     case FILETYPE_IEG:
       {
         if ( memtype == MEMTYPE_FLOAT ) Error("iegWriteRecord not implemented for memtype float!");
-        status = iegWriteRecord(streamID, data);
+        status = iegWriteRecord(streamptr, data);
 	break;
       }
 #endif
@@ -45409,7 +45538,7 @@ void stream_write_record(int streamID, int memtype, const void *data, int nmiss)
     case FILETYPE_NC4:
     case FILETYPE_NC4C:
       {
-	cdf_write_record(streamID, memtype, data, nmiss);
+	cdf_write_record(streamptr, memtype, data, nmiss);
 	break;
       }
 #endif
@@ -45450,6 +45579,8 @@ void streamCopyRecord(int streamID2, int streamID1)
   filetype2 = streamptr2->filetype;
 
   if ( filetype1 == filetype2 ) filetype = filetype2;
+  else
+    Error("Streams have different file types (%s -> %s)!", strfiletype(filetype1), strfiletype(filetype2));
 
   switch (filetype)
     {
@@ -45457,55 +45588,60 @@ void streamCopyRecord(int streamID2, int streamID1)
     case FILETYPE_GRB:
     case FILETYPE_GRB2:
       {
-	status = grbCopyRecord(streamID2, streamID1);
+	status = grbCopyRecord(streamptr2, streamptr1);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBSERVICE)
     case FILETYPE_SRV:
       {
-	status = srvCopyRecord(streamID2, streamID1);
+	status = srvCopyRecord(streamptr2, streamptr1);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBEXTRA)
     case FILETYPE_EXT:
       {
-	status = extCopyRecord(streamID2, streamID1);
+	status = extCopyRecord(streamptr2, streamptr1);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBIEG)
     case FILETYPE_IEG:
       {
-	status = iegCopyRecord(streamID2, streamID1);
+	status = iegCopyRecord(streamptr2, streamptr1);
+	break;
+      }
+#endif
+#if  defined  (HAVE_LIBNETCDF)
+    case FILETYPE_NC:
+    case FILETYPE_NC2:
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
+      {
+	status = cdfCopyRecord(streamptr2, streamptr1);
 	break;
       }
 #endif
     default:
       {
-	status = cdfCopyRecord(streamID2, streamID1);
+	Error("%s support not compiled in!", strfiletype(filetype));
 	break;
       }
     }
 }
 
 
-void cdiCreateRecords(int streamID, int tsID)
+void cdi_create_records(stream_t *streamptr, int tsID)
 {
   int nrecords, maxrecords;
   int nvars, varID, recID;
   record_t *records;
   int vlistID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   if ( streamptr->tsteps[tsID].records ) return;
 
-  vlistID  = streamInqVlist(streamID);
+  vlistID  = streamptr->vlistID;
 
   if ( tsID == 0 )
     {
@@ -45585,12 +45721,9 @@ void cdiCreateRecords(int streamID, int tsID)
 
 
 
-static void tstepsInitEntry(int streamID, int tsID)
+static
+void tstepsInitEntry(stream_t *streamptr, int tsID)
 {
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
   streamptr->tsteps[tsID].curRecID     = CDI_UNDEFID;
   streamptr->tsteps[tsID].position     = 0;
   streamptr->tsteps[tsID].records      = NULL;
@@ -45603,14 +45736,12 @@ static void tstepsInitEntry(int streamID, int tsID)
   ptaxisInit(&streamptr->tsteps[tsID].taxis);
 }
 
-int tstepsNewEntry(int streamID)
+
+int tstepsNewEntry(stream_t *streamptr)
 {
   int tsID = 0;
   int tstepsTableSize;
   tsteps_t *tstepsTable;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   tsID            = streamptr->tstepsNextID++;
   tstepsTableSize = streamptr->tstepsTableSize;
@@ -45634,20 +45765,18 @@ int tstepsNewEntry(int streamID)
   streamptr->tstepsTableSize = tstepsTableSize;
   streamptr->tsteps          = tstepsTable;
 
-  tstepsInitEntry(streamID, tsID);
+  tstepsInitEntry(streamptr, tsID);
 
   streamptr->tsteps[tsID].taxis.used = TRUE;
 
   return (tsID);
 }
 
-void cdiCreateTimesteps(int streamID)
+
+void cdiCreateTimesteps(stream_t *streamptr)
 {
   int ntsteps;
   int tsID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   if ( streamptr->ntsteps < 0 || streamptr->tstepsTableSize > 0 )
     return;
@@ -45664,7 +45793,7 @@ void cdiCreateTimesteps(int streamID)
 
   for ( tsID = 0; tsID < ntsteps; tsID++ )
     {
-      tstepsInitEntry(streamID, tsID);
+      tstepsInitEntry(streamptr, tsID);
       streamptr->tsteps[tsID].taxis.used = TRUE;
     }
 }
@@ -47090,9 +47219,9 @@ size_t fileWrite(int fileID, const void *restrict ptr, size_t size)
  * End:
  */
 
-/* Automatically generated by m214003 at 2012-12-17, do not edit */
+/* Automatically generated by m214003 at 2013-03-05, do not edit */
 
-/* CGRIBEXLIB_VERSION="1.5.6" */
+/* CGRIBEXLIB_VERSION="1.6.0" */
 
 #ifdef _ARCH_PWR6
 #pragma options nostrict
@@ -47144,6 +47273,7 @@ size_t fileWrite(int fileID, const void *restrict ptr, size_t size)
 #  define VECTORCODE
 #endif
 
+
 #if defined (VECTORCODE)
 #if  defined  (INT32)
 #  define  GRIBPACK     unsigned INT32
@@ -47446,7 +47576,7 @@ void  gribDecode(int *isec0, int *isec1, int *isec2, double *fsec2, int *isec3,
 #include <math.h>
 
 
-double _pow2tab[158] = {
+const double const _pow2tab[158] = {
  /* pow(2.0,  0.0) */  1.0,
  /* pow(2.0,  1.0) */  2.0,
  /* pow(2.0,  2.0) */  4.0,
@@ -47608,7 +47738,7 @@ double _pow2tab[158] = {
 };
 
 
-double _pow16tab[71] = {
+const double const _pow16tab[71] = {
  /* pow(16.0,  0.0) */  1.0,
  /* pow(16.0,  1.0) */  16.0,
  /* pow(16.0,  2.0) */  256.0,
@@ -48565,13 +48695,15 @@ void encode_double_array_unrolled(int numBits, size_t packStart, size_t datasize
 #else
 #define __UNROLL_DEPTH_2 8
 #endif
-  size_t residual =  datasize % __UNROLL_DEPTH_2;
-  size_t ofs = datasize - residual;
+  size_t residual;
+  size_t ofs;
   double dval[__UNROLL_DEPTH_2];
   unsigned long ival;
 
   data += packStart;
   datasize -= packStart;
+  residual =  datasize % __UNROLL_DEPTH_2;
+  ofs = datasize - residual;
 
   // reducing FP operations to single FMA is slowing down on pwr6 ...
 
@@ -48778,6 +48910,463 @@ void encode_double_array_unrolled(int numBits, size_t packStart, size_t datasize
   *gz = z;
 #undef __UNROLL_DEPTH_2
 }
+//#undef _GET_X86_COUNTER
+//#undef _GET_MACH_COUNTER
+//#undef _GET_IBM_COUNTER
+//#undef _ARCH_PWR6
+
+#if defined _GET_IBM_COUNTER
+#include <libhpc.h>
+#elif defined _GET_X86_COUNTER
+#include <x86intrin.h>
+#elif defined _GET_MACH_COUNTER
+#include <mach/mach_time.h>
+#endif
+
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
+
+/*
+#if ((__GNUC__ >= 4) || (__ICC >= 1100) || defined (__clang__))
+#define _ENABLE_SIMD
+#include <immintrin.h>
+#undef __AVX
+#ifdef __AVX__
+#define _ENABLE_AVX
+#elif __SSE4_1__
+#define _ENABLE_SSE4_1
+#endif
+#endif
+*/
+
+#undef _ENABLE_AVX
+#undef _ENABLE_SSE4_1
+
+#if defined _ENABLE_AVX
+
+static
+void avx_decode_double_array_2byte(size_t datasize, const unsigned char * restrict igrib,
+				     double * restrict fpdata, double fmin, double zscale)
+{
+  size_t i, j;
+  size_t nframes = datasize;
+  size_t residual;
+  size_t ofs;
+
+  double dval;
+
+  double *data = fpdata;
+  __m128i *sgrib;
+  
+  __m128i mask = _mm_set_epi8(14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1);
+
+  __m256d ymm0 = _mm256_set1_pd(fmin);
+  __m256d ymm1 = _mm256_set1_pd(zscale);
+  
+  __m128i xmm0, xmm1, xmm2, xmm3;
+  __m256d ymm2, ymm3;
+
+  i = -1;
+  while ( ((unsigned long) data) % 32 != 0 && datasize > 0)
+    {
+      i++;
+      dval = (((int)igrib[2*i] <<  8) | (int)igrib[2*i+1]);
+      fpdata[i] = fmin + zscale * dval;
+      data++;
+      nframes--;
+    }
+  
+  if (i == -1) i = 0;
+  sgrib = (__m128i *) (igrib+i);
+
+  while (nframes >= 16)
+    { 
+      xmm0 = _mm_loadu_si128((__m128i *) sgrib);
+      xmm0 = _mm_shuffle_epi8(xmm0, mask);
+      xmm1 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(1, 0, 3, 2));
+      xmm2 = _mm_cvtepu16_epi32(xmm0);
+      xmm3 = _mm_cvtepu16_epi32(xmm1);
+
+      ymm2 = _mm256_cvtepi32_pd(xmm2);
+      ymm2 = _mm256_add_pd(_mm256_mul_pd(ymm2, ymm1), ymm0);
+      (void) _mm256_stream_pd(data, ymm2);
+      ymm3 = _mm256_cvtepi32_pd(xmm3);
+      ymm3 = _mm256_add_pd(_mm256_mul_pd(ymm3, ymm1), ymm0);
+      (void) _mm256_stream_pd(data+4, ymm3);  
+      
+      xmm0 = _mm_loadu_si128((__m128i *) sgrib + 1);
+      xmm0 = _mm_shuffle_epi8(xmm0, mask);
+      xmm1 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(1, 0, 3, 2));
+      xmm2 = _mm_cvtepu16_epi32(xmm0);
+      xmm3 = _mm_cvtepu16_epi32(xmm1);
+      
+      ymm2 = _mm256_cvtepi32_pd(xmm2);
+      ymm2 = _mm256_add_pd(_mm256_mul_pd(ymm2, ymm1), ymm0);
+      (void) _mm256_stream_pd(data+8, ymm2);
+      ymm3 = _mm256_cvtepi32_pd(xmm3);
+      ymm3 = _mm256_add_pd(_mm256_mul_pd(ymm3, ymm1), ymm0);
+      (void) _mm256_stream_pd(data+12, ymm3);  
+      
+      data += 16;
+      sgrib += 2;
+      nframes -= 16;
+    }
+
+  residual = nframes;
+  ofs = datasize - residual;
+  for ( j = 0; j < residual; j++ )
+    {
+      dval = (((int)igrib[2*(ofs+j)] <<  8) | (int)igrib[2*(ofs+j)+1]);
+      fpdata[ofs+j] = fmin + zscale * dval;
+    }
+
+  return;
+}
+
+#elif defined _ENABLE_SSE4_1
+
+static
+void sse41_decode_double_array_2byte(size_t datasize, const unsigned char * restrict igrib,
+				     double * restrict fpdata, double fmin, double zscale)
+{
+  size_t i, j;
+  size_t nframes = datasize;
+  size_t residual;
+  size_t ofs;
+
+  double dval;
+
+  double *data = fpdata;
+  __m128i *sgrib;
+  
+  __m128i mask = _mm_set_epi8(14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1);
+  __m128d dmm8 = _mm_set1_pd(fmin);
+  __m128d dmm9 = _mm_set1_pd(zscale);
+  
+  __m128i xmm4, xmm5;
+  __m128i xmm6, xmm7;
+  
+  __m128d dmm0, dmm1, dmm2, dmm3;
+  __m128d dmm4, dmm5, dmm6, dmm7;
+
+  i = -1;
+  while ( ((unsigned long) data) % 32 != 0 && datasize > 0)
+    {
+      i++;
+      dval = (((int)igrib[2*i] <<  8) | (int)igrib[2*i+1]);
+      fpdata[i] = fmin + zscale * dval;
+      data++;
+      nframes--;
+    }
+  
+  if (i == -1) i = 0;
+  sgrib = (__m128i *) (igrib+i);
+  
+  while (nframes >= 16)
+    {
+      xmm5 = _mm_loadu_si128((__m128i *) sgrib);
+      xmm5 = _mm_shuffle_epi8(xmm5, mask);
+      xmm4 = _mm_srli_si128(xmm5, 8);
+      xmm6 = _mm_cvtepu16_epi32(xmm5);
+      dmm0 = _mm_cvtepi32_pd(xmm6);
+      dmm0 = _mm_add_pd(_mm_mul_pd(dmm0, dmm9), dmm8);
+      (void) _mm_stream_pd(data, dmm0);
+      xmm7 = _mm_srli_si128(xmm6, 8);
+      dmm1 = _mm_cvtepi32_pd(xmm7);
+      dmm1 = _mm_add_pd(_mm_mul_pd(dmm1, dmm9), dmm8);
+      (void) _mm_stream_pd(data+2, dmm1);
+      xmm6 = _mm_cvtepu16_epi32(xmm4);
+      dmm2 = _mm_cvtepi32_pd(xmm6);
+      dmm2 = _mm_add_pd(_mm_mul_pd(dmm2, dmm9), dmm8);
+      (void) _mm_stream_pd(data+4, dmm2);
+      xmm7 = _mm_srli_si128(xmm6, 8);
+      dmm3 = _mm_cvtepi32_pd(xmm7);
+      dmm3 = _mm_add_pd(_mm_mul_pd(dmm3, dmm9), dmm8);
+      (void) _mm_stream_pd(data+6, dmm3);
+      
+      xmm5 = _mm_loadu_si128((__m128i *) sgrib+1);
+      xmm5 = _mm_shuffle_epi8(xmm5, mask);
+      xmm4 = _mm_srli_si128(xmm5, 8);
+      xmm6 = _mm_cvtepu16_epi32(xmm5);
+      dmm4 = _mm_cvtepi32_pd(xmm6);
+      dmm4 = _mm_add_pd(_mm_mul_pd(dmm4, dmm9), dmm8);
+      (void) _mm_stream_pd(data+8, dmm4);
+      xmm7 = _mm_srli_si128(xmm6, 8);
+      dmm5 = _mm_cvtepi32_pd(xmm7);
+      dmm5 = _mm_add_pd(_mm_mul_pd(dmm5, dmm9), dmm8);
+      (void) _mm_stream_pd(data+10, dmm5);
+      xmm6 = _mm_cvtepu16_epi32(xmm4);
+      dmm6 = _mm_cvtepi32_pd(xmm6);
+      dmm6 = _mm_add_pd(_mm_mul_pd(dmm6, dmm9), dmm8);
+      (void) _mm_stream_pd(data+12, dmm6);
+      xmm7 = _mm_srli_si128(xmm6, 8);
+      dmm7 = _mm_cvtepi32_pd(xmm7);
+      dmm7 = _mm_add_pd(_mm_mul_pd(dmm7, dmm9), dmm8);
+      (void) _mm_stream_pd(data+14, dmm7);
+
+      data += 16;
+      sgrib += 2;
+      nframes -= 16;
+    }
+
+  residual = nframes;
+  ofs = datasize - residual;
+  for ( j = 0; j < residual; j++ )
+    {
+      dval = (((int)igrib[2*(ofs+j)] <<  8) | (int)igrib[2*(ofs+j)+1]);
+      fpdata[ofs+j] = fmin + zscale * dval;
+    }
+
+  return;
+}
+
+#endif
+
+static 
+void decode_double_array_common(const unsigned char * restrict igrib, long jlend, int NumBits, 
+				double fmin, double zscale, double * restrict fpdata)
+{
+  /* code from wgrib routine BDS_unpack */
+  const unsigned char *bits = igrib;
+  unsigned int jmask;
+  long i;
+  unsigned int tbits = 0;
+  int n_bits = NumBits;
+  int t_bits = 0;
+      
+  jmask = (1 << n_bits) - 1;
+  for ( i = 0; i < jlend; i++ )
+    {
+      if (n_bits - t_bits > 8)
+	{
+	  tbits = (tbits << 16) | (bits[0] << 8) | (bits[1]);
+	  bits += 2;
+	  t_bits += 16;
+	}
+
+      while ( t_bits < n_bits )
+	{
+	  tbits = (tbits * 256) + *bits++;
+	  t_bits += 8;
+	}
+      t_bits -= n_bits;
+      fpdata[i] = (tbits >> t_bits) & jmask;
+    }
+  /* at least this vectorizes :) */
+  for ( i = 0; i < jlend; i++ )
+    fpdata[i] = fmin + zscale*fpdata[i];
+}
+
+static unsigned int mask[] = {0,1,3,7,15,31,63,127,255};
+static double shift[9] = {1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0};
+
+static 
+void decode_double_array_common2(const unsigned char * restrict igrib, long jlend, int NumBits, 
+				 double fmin, double zscale, double * restrict fpdata)
+{
+  /* code from wgrib routine BDS_unpack */
+  const unsigned char *bits = igrib;
+  long i;
+  int n_bits = NumBits;
+  int c_bits, j_bits;
+  double jj;
+
+  /* older unoptimized code, not often used */
+  c_bits = 8;
+  for ( i = 0; i < jlend; i++ )
+    {
+      jj = 0.0;
+      j_bits = n_bits;
+      while (c_bits <= j_bits)
+	{
+	  if (c_bits == 8)
+	    {
+	      jj = jj * 256.0  + (double) (*bits++);
+	      j_bits -= 8;
+	    }
+	  else
+	    {
+	      jj = (jj * shift[c_bits]) + (double) (*bits & mask[c_bits]);
+	      bits++;
+	      j_bits -= c_bits;
+	      c_bits = 8;
+	    }
+	}
+
+      if (j_bits)
+	{
+	  c_bits -= j_bits;
+	  jj = (jj * shift[j_bits]) + (double) ((*bits >> c_bits) & mask[j_bits]);
+	}
+      
+      fpdata[i] = fmin + zscale*jj;
+    }
+} 
+
+static 
+void decode_double_array_byte(const unsigned char * restrict igrib, long jlend, int numBits, 
+			      double fmin, double zscale, double * restrict fpdata)
+{
+#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER 
+  uint64_t start_decode, end_decode;
+#endif
+
+  long i;
+  double dval;
+#if defined (VECTORCODE)
+  GRIBPACK *lgrib = NULL;
+
+  if ( numBits%8 == 0 )
+    {
+      long jlenc = jlend * numBits / 8;
+      if ( jlenc > 0 ) 
+	{
+	  lgrib = (GRIBPACK *) malloc(jlenc*sizeof(GRIBPACK));
+	  if ( lgrib == NULL ) SysError("No Memory!");
+
+	  (void) UNPACK_GRIB(igrib, lgrib, jlenc, -1L);
+	}
+    }
+
+  if ( numBits ==  0 )
+    {
+      for ( i = 0; i < jlend; i++ )
+	fpdata[i] = fmin;
+    }
+  else if ( numBits ==  8 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (int)lgrib[i];
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits == 16 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (((int)lgrib[2*i  ] <<  8) +  (int)lgrib[2*i+1]);
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits == 24 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (((int)lgrib[3*i  ] << 16) + ((int)lgrib[3*i+1] <<  8) +
+	  	 (int)lgrib[3*i+2]);
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits == 32 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (((unsigned int)lgrib[4*i  ] << 24) + ((unsigned int)lgrib[4*i+1] << 16) +
+		((unsigned int)lgrib[4*i+2] <<  8) +  (unsigned int)lgrib[4*i+3]);
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits <= 25 )
+    {
+      decode_double_array_common(igrib, jlend, numBits, fmin, zscale, fpdata);
+    }
+  else if ( numBits > 25 && numBits < 32 )
+    {
+      decode_double_array_common2(igrib, jlend, numBits, fmin, zscale, fpdata);
+    }
+  else
+    {
+      Error("Unimplemented packing factor %d!", numBits);
+    }
+
+  if ( lgrib ) free(lgrib);
+
+#else
+  if ( numBits ==  0 )
+    {
+      for ( i = 0; i < jlend; i++ )
+	fpdata[i] = fmin;
+    }
+  else if ( numBits ==  8 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (int)igrib[i];
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits == 16 )
+    {
+#ifdef _GET_IBM_COUNTER 
+      hpmStart(6, "unpack 16 bit base");
+#elif defined _GET_X86_COUNTER 
+      start_decode = _rdtsc();
+#elif defined _GET_MACH_COUNTER 
+      start_decode = mach_absolute_time();
+#endif
+      
+#if defined _ENABLE_AVX
+      printf("AVX selected ...\n");
+      avx_decode_double_array_2byte((size_t) jlend, igrib, fpdata, fmin, zscale);
+#elif defined _ENABLE_SSE4_1
+      printf("SSE4 selected ...\n");
+      sse41_decode_double_array_2byte((size_t) jlend, igrib, fpdata, fmin, zscale);
+#else
+      for ( i = 0; i < jlend; i++ )
+	{
+	  dval = (((int)igrib[2*i  ] <<  8) |  (int)igrib[2*i+1]);
+	  fpdata[i] = fmin + zscale * dval;
+	}
+#endif
+
+#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER
+#if defined _GET_X86_COUNTER 
+      end_decode = _rdtsc();
+#elif defined _GET_MACH_COUNTER 
+      end_decode = mach_absolute_time();
+#endif
+#if defined _ENABLE_AVX
+      printf("AVX encoding cycles:: %" PRIu64 "\n", 
+	     end_decode-start_decode);
+#elif defined _ENABLE_SSE4_1
+      printf("SSE 4.1 encoding cycles:: %" PRIu64 "\n", 
+	     end_decode-start_decode);
+#else
+      printf("loop encoding cycles:: %" PRIu64 "\n", 
+	     end_decode-start_decode);
+#endif  
+#endif
+      
+#ifdef _GET_IBM_COUNTER 
+      hpmStop(6);
+#endif
+    }
+  else if ( numBits == 24 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (((int)igrib[3*i  ] << 16) + ((int)igrib[3*i+1] <<  8) +
+		 (int)igrib[3*i+2]);
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits == 32 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (((unsigned int)igrib[4*i  ] << 24) + ((unsigned int)igrib[4*i+1] << 16) +
+		((unsigned int)igrib[4*i+2] <<  8) +  (unsigned int)igrib[4*i+3]);
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits <= 25 )
+    {
+      decode_double_array_common(igrib, jlend, numBits, fmin, zscale, fpdata);
+    }
+  else if ( numBits > 25 && numBits < 32 )
+    {
+      decode_double_array_common2(igrib, jlend, numBits, fmin, zscale, fpdata);
+    }
+  else
+    {
+      Error("Unimplemented packing factor %d!", numBits);
+    }
+#endif
+}
+
+static 
+void decode_double_array_unrolled(const unsigned char * restrict igrib, long jlend, int numBits, 
+				  double fmin, double zscale, double * restrict fpdata)
+{
+  decode_double_array_byte(igrib, jlend, numBits, fmin, zscale, fpdata);
+}
 
 #define  NINT(x)  ((x) < 0 ? (int)((x)-.5) : (int)((x)+.5))
 
@@ -48850,12 +49439,12 @@ void confp3(double pval, int *kexp, int *kmant, int kbits, int kround)
         - replace 1.0 / pow(16.0, (double)(iexp - 70)) by rpow16m70tab[iexp]
   */
 
-  double zval, rpowref;
+  double rpowref;
   double zref, zeps;
   int iexp, isign;
   int iround;
-  extern int CGRIBEX_Debug;
-  extern double _pow16tab[71];
+  // extern int CGRIBEX_Debug;
+  extern const double const _pow16tab[71];
 
   /* ----------------------------------------------------------------- */
   /*   Section 1 . Initialise                                          */
@@ -49014,19 +49603,20 @@ void confp3(double pval, int *kexp, int *kmant, int kbits, int kround)
   /* ----------------------------------------------------------------- */
 
 LABEL900:
-
+  /*
   if ( CGRIBEX_Debug )
     {
+      double zval;
+
       Message("Conversion type parameter = %4d", kround);
       Message("Original number = %30.20f", pval);
 
       zval = decfp2(*kexp, *kmant);
 
       Message("Converted to      %30.20f", zval);
-      Message("Sign = %3d, Exponent = %3d, Mantissa = %12d",
-	      isign, iexp, *kmant);
+      Message("Sign = %3d, Exponent = %3d, Mantissa = %12d", isign, iexp, *kmant);
     }
-
+  */
   return;
 } /* confp3 */
 
@@ -49100,14 +49690,14 @@ double decfp2(int kexp, int kmant)
 
   double pval;
   int iexp, isign;
-  extern int CGRIBEX_Debug;
-  extern double _pow16tab[71];
+  //extern int CGRIBEX_Debug;
+  extern const double const _pow16tab[71];
   
   /* ----------------------------------------------------------------- */
   /*   Section 1 . Convert value of 0.0. Ignore sign bit.              */
   /* ----------------------------------------------------------------- */
 
-  if ( CGRIBEX_Debug ) Message("KEXP = %d  KMANT = %d", kexp, kmant);
+  //if ( CGRIBEX_Debug ) Message("KEXP = %d  KMANT = %d", kexp, kmant);
   /*
   if ( (kexp == 128 || kexp == 0) && kmant == 0 )
   */
@@ -49151,11 +49741,12 @@ double decfp2(int kexp, int kmant)
 
 LABEL900:
 
-  if ( CGRIBEX_Debug ) Message("Returned value = %f", pval);
+  //if ( CGRIBEX_Debug ) Message("Returned value = %f", pval);
 
   return (pval);
 } /* decfp2 */
 #include <stdio.h>
+#include <stdint.h>
 #include <string.h>
 #include <stdarg.h>
 
@@ -49234,8 +49825,9 @@ void gribDateTime(int *isec1, int *date, int *time)
 {
   static int lprint = TRUE;
   int ryear, rmonth, rday, rhour, rminute, second;
-  int time_period = 0;
-  int julday, secofday, addsec;
+  int julday, secofday;
+  int64_t addsec = 0;
+  int64_t time_period = 0;
   int century;
   extern int grib_calendar;
 
@@ -49298,6 +49890,7 @@ void gribDateTime(int *isec1, int *date, int *time)
 	      gprintf(__func__, "Time unit %d unsupported", ISEC1_TimeUnit);
 	      lprint = FALSE;
 	    }
+	  break;
 	}
 
       julday_add_seconds(addsec, &julday, &secofday);
@@ -49337,12 +49930,12 @@ gribExDP(int *isec0, int *isec1, int *isec2, double *fsec2, int *isec3,
 {
   int yfunc = *hoper;
 
-  if ( yfunc == 'D' || yfunc == 'J' || yfunc == 'R' )
-    gribDecode(isec0, isec1, isec2, fsec2, isec3,
+  if ( yfunc == 'C' )
+    gribEncode(isec0, isec1, isec2, fsec2, isec3,
 	       fsec3, isec4, fsec4, klenp, kgrib,
 	       kleng, kword, yfunc, kret);
-  else if ( yfunc == 'C' )
-    gribEncode(isec0, isec1, isec2, fsec2, isec3,
+  else if ( yfunc == 'D' || yfunc == 'J' || yfunc == 'R' )
+    gribDecode(isec0, isec1, isec2, fsec2, isec3,
 	       fsec3, isec4, fsec4, klenp, kgrib,
 	       kleng, kword, yfunc, kret);
   else if ( yfunc == 'V' )
@@ -51579,7 +52172,7 @@ int encodeBDS(GRIBPACK *lGrib, long *gribLen, int decscale, int *isec2, int *ise
   double jpepsln = 1.0e-12;     /* -----> tolerance used to check equality     */
                                 /*        of floating point numbers - needed   */
 		                /*        on some platforms (eg vpp700, linux) */
-  extern double _pow2tab[158];
+  extern const double const _pow2tab[158];
   extern int CGRIBEX_Const;         /* 1: Don't pack constant fields on regular grids */
 
   if ( isec2 )
@@ -51937,6 +52530,8 @@ void gribEncode(int *isec0, int *isec1, int *isec2, double *fsec2, int *isec3,
 
 
 
+
+
 int gribVersion(unsigned char *is, size_t buffersize)
 {
   if ( buffersize < 8 )
@@ -52451,204 +53046,6 @@ int decodeGDS(unsigned char  *gds, int *isec0, int *isec2, double *fsec2, int *n
   return (gdsLen);
 }
 
-static 
-void decode_double_array_common(unsigned char *igrib, long jlend, int NumBits, 
-				double fmin, double zscale, double *fpdata)
-{
-  /* code from wgrib routine BDS_unpack */
-  unsigned char *bits = igrib;
-  unsigned int jmask;
-  long i;
-  unsigned int tbits = 0;
-  int n_bits = NumBits;
-  int t_bits = 0;
-      
-  jmask = (1 << n_bits) - 1;
-  for ( i = 0; i < jlend; i++ )
-    {
-      if (n_bits - t_bits > 8)
-	{
-	  tbits = (tbits << 16) | (bits[0] << 8) | (bits[1]);
-	  bits += 2;
-	  t_bits += 16;
-	}
-
-      while ( t_bits < n_bits )
-	{
-	  tbits = (tbits * 256) + *bits++;
-	  t_bits += 8;
-	}
-      t_bits -= n_bits;
-      fpdata[i] = (tbits >> t_bits) & jmask;
-    }
-  /* at least this vectorizes :) */
-  for ( i = 0; i < jlend; i++ )
-    fpdata[i] = fmin + zscale*fpdata[i];
-}
-
-static unsigned int mask[] = {0,1,3,7,15,31,63,127,255};
-static double shift[9] = {1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0};
-
-static 
-void decode_double_array_common2(unsigned char *igrib, long jlend, int NumBits, 
-				 double fmin, double zscale, double *fpdata)
-{
-  /* code from wgrib routine BDS_unpack */
-  unsigned char *bits = igrib;
-  long i;
-  int n_bits = NumBits;
-  int c_bits, j_bits;
-  double jj;
-
-  /* older unoptimized code, not often used */
-  c_bits = 8;
-  for ( i = 0; i < jlend; i++ )
-    {
-      jj = 0.0;
-      j_bits = n_bits;
-      while (c_bits <= j_bits)
-	{
-	  if (c_bits == 8)
-	    {
-	      jj = jj * 256.0  + (double) (*bits++);
-	      j_bits -= 8;
-	    }
-	  else
-	    {
-	      jj = (jj * shift[c_bits]) + (double) (*bits & mask[c_bits]);
-	      bits++;
-	      j_bits -= c_bits;
-	      c_bits = 8;
-	    }
-	}
-
-      if (j_bits)
-	{
-	  c_bits -= j_bits;
-	  jj = (jj * shift[j_bits]) + (double) ((*bits >> c_bits) & mask[j_bits]);
-	}
-      
-      fpdata[i] = fmin + zscale*jj;
-    }
-} 
-
-static 
-void decode_double_array(unsigned char *igrib, long jlend, int numBits, 
-			 double fmin, double zscale, double *fpdata)
-{
-  long i;
-  double dval;
-#if defined (VECTORCODE)
-  GRIBPACK *lgrib = NULL;
-
-  if ( numBits ==  8 || numBits == 16 ||
-       numBits == 24 || numBits == 32 )
-    {
-      long jlenc = jlend * numBits / 8;
-      if ( jlenc > 0 ) 
-	{
-	  lgrib = (GRIBPACK *) malloc(jlenc*sizeof(GRIBPACK));
-	  if ( lgrib == NULL ) SysError("No Memory!");
-
-	  (void) UNPACK_GRIB(igrib, lgrib, jlenc, -1L);
-	}
-    }
-
-  if ( numBits ==  0 )
-    {
-      for ( i = 0; i < jlend; i++ )
-	fpdata[i] = fmin;
-    }
-  else if ( numBits ==  8 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (int)lgrib[i];
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits == 16 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (((int)lgrib[2*i  ] <<  8) +  (int)lgrib[2*i+1]);
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits == 24 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (((int)lgrib[3*i  ] << 16) + ((int)lgrib[3*i+1] <<  8) +
-	  	 (int)lgrib[3*i+2]);
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits == 32 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (((unsigned int)lgrib[4*i  ] << 24) + ((unsigned int)lgrib[4*i+1] << 16) +
-		((unsigned int)lgrib[4*i+2] <<  8) +  (unsigned int)lgrib[4*i+3]);
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits <= 25 )
-    {
-      decode_double_array_common(igrib, jlend, numBits, fmin, zscale, fpdata);
-    }
-  else if ( numBits > 25 && numBits < 32 )
-    {
-      decode_double_array_common2(igrib, jlend, numBits, fmin, zscale, fpdata);
-    }
-  else
-    {
-      fprintf(stderr," Unimplemented packing factor %d!\n", numBits);
-      exit(EXIT_FAILURE);
-    }
-
-  if ( lgrib ) free(lgrib);
-
-#else
-  if ( numBits ==  0 )
-    {
-      for ( i = 0; i < jlend; i++ )
-	fpdata[i] = fmin;
-    }
-  else if ( numBits ==  8 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (int)igrib[i];
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits == 16 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (((int)igrib[2*i  ] <<  8) |  (int)igrib[2*i+1]);
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits == 24 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (((int)igrib[3*i  ] << 16) + ((int)igrib[3*i+1] <<  8) +
-		 (int)igrib[3*i+2]);
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits == 32 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (((unsigned int)igrib[4*i  ] << 24) + ((unsigned int)igrib[4*i+1] << 16) +
-		((unsigned int)igrib[4*i+2] <<  8) +  (unsigned int)igrib[4*i+3]);
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits <= 25 )
-    {
-      decode_double_array_common(igrib, jlend, numBits, fmin, zscale, fpdata);
-    }
-  else if ( numBits > 25 && numBits < 32 )
-    {
-      decode_double_array_common2(igrib, jlend, numBits, fmin, zscale, fpdata);
-    }
-  else
-    {
-      fprintf(stderr, "Unimplemented packing factor %d!\n", numBits);
-      exit(EXIT_FAILURE);
-    }
-#endif
-}
-
 static
 int decodeBDS(int decscale, unsigned char *bds, int *isec2, int *isec4, 
 	      double *fsec4, int fsec4len, int dfunc, int bdsLenIn, int numGridVals, int llarge, int *iret)
@@ -52658,7 +53055,7 @@ int decodeBDS(int decscale, unsigned char *bds, int *isec2, int *isec4,
   int lcompress;
   int jup, kup, mup;
   int locnd;
-  int jlend;
+  long jlend;
   long i;
   int bds_flag, jscale, imiss;
   int bds_ubits;
@@ -52881,11 +53278,11 @@ int decodeBDS(int decscale, unsigned char *bds, int *isec2, int *isec4,
 
   /* check length of output array. */
   
-  if ( jlend+ioff > fsec4len )
+  if ( ISEC4_NumValues > fsec4len )
     {
       *iret = 710;
       gprintf(__func__, " Output array too small. Length = %d", fsec4len);
-      gprintf(__func__, " Number of values = %d", jlend+ioff);
+      gprintf(__func__, " Number of values = %d", ISEC4_NumValues);
       gprintf(__func__, " Return code =  %d", *iret);
       return (0);
     }
@@ -52895,7 +53292,11 @@ int decodeBDS(int decscale, unsigned char *bds, int *isec2, int *isec4,
     {
       igrib += locnd;
 
-      decode_double_array(igrib, jlend, ISEC4_NumBits, fmin, zscale, fpdata);
+#if  defined  (_ARCH_PWR6)
+      decode_double_array_unrolled(igrib, jlend, ISEC4_NumBits, fmin, zscale, fpdata);
+#else
+      decode_double_array_byte    (igrib, jlend, ISEC4_NumBits, fmin, zscale, fpdata);
+#endif
     }
 
   if ( lspherc && lcomplex )
@@ -52911,7 +53312,7 @@ int decodeBDS(int decscale, unsigned char *bds, int *isec2, int *isec4,
     if ( lspherc && !lcomplex )
       {
         /* 20100705: Fix ZeroShiftError - Edi Kirk */
-	if ( fsec4[1] != 0.0 )
+	if ( IS_NOT_EQUAL(fsec4[1], 0.0) )
 	  {
 	    double zserr = fsec4[1];
 	    for ( i = 1; i < ISEC4_NumValues; i++ ) fsec4[i] -= zserr;
@@ -53236,7 +53637,8 @@ void gribDecode(int *isec0, int *isec1, int *isec2, double *fsec2, int *isec3,
 	}
 
       if ( dfunc == 'R' && *iret == -801 )
-	  gprintf(__func__, "Number of values (%d) and sum of lons per row (%d) differ, abort conversion to regular grid!", ISEC4_NumValues, nvalues);
+	  gprintf(__func__, "Number of values (%d) and sum of lons per row (%d) differ, abort conversion to regular grid!",
+		  ISEC4_NumValues, nvalues);
       
       if ( dfunc == 'R' && *iret != -801 )
 	{
@@ -53866,7 +54268,7 @@ double calculate_pfactor(const double* spectralField, long fieldTruncation, long
 
   for( loop = ismin; loop <= ismax; loop++ ) {
     norms[n] = norms[n] > zeps ? norms[n] : zeps;
-    if( norms[n] == zeps ) weights[n] = 100.0 * zeps;
+    if( IS_EQUAL(norms[n], zeps) ) weights[n] = 100.0 * zeps;
   }
 
   /*
@@ -55842,6 +56244,7 @@ int grib1Sections(unsigned char *gribbuffer, long bufsize, unsigned char **pdsp,
     {
       fprintf(stderr, "Missing end section >%2x %2x %2x %2x<\n",
 	      bufpointer[0], bufpointer[1], bufpointer[2], bufpointer[3]);
+      return (-2);
     }
 
   return (0);
@@ -56026,6 +56429,7 @@ int grib2Sections(unsigned char *gribbuffer, long bufsize, unsigned char **idsp,
     {
       fprintf(stderr, "Missing end section >%2x %2x %2x %2x<\n",
 	      section[0], section[1], section[2], section[3]);
+      return (-2);
     }
 
   return (0);
@@ -56175,7 +56579,7 @@ void grib1PrintALL(int nrec, long offset, long recpos, long recsize, unsigned ch
   bdslen = BDS_Len;
   bdslen = correct_bdslen(bdslen, recsize, bds-gribbuffer);
 
-  if ( (BDS_Flag >> 4)&1 && BDS_Z == 128 )
+  if ( ((BDS_Flag >> 4)&1) && (BDS_Z == 128 || BDS_Z == 130) )
     {
       int s1, s2;
       s1 = gribrec_len(bds[14], bds[15], bds[16]);
@@ -56501,7 +56905,7 @@ void grib1PrintBDS(int nrec, long recpos, long recsize, unsigned char *gribbuffe
   else
     level = PDS_Level1;
 
-  if ( (BDS_Flag >> 4)&1 && BDS_Z == 128 )
+  if ( ((BDS_Flag >> 4)&1) && BDS_Z == 128 )
     {
       int s1, s2;
       s1 = ((int) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
@@ -56570,7 +56974,7 @@ void gribCheck1(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
   else
     level = PDS_Level1;
 
-  if ( (BDS_Flag >> 4)&1 && BDS_Z == 128 )
+  if ( ((BDS_Flag >> 4)&1) && BDS_Z == 128 )
     {
       int s1, s2;
       s1 = ((int) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
@@ -56578,7 +56982,7 @@ void gribCheck1(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
       cr = ((double)s1)/s2;
     }
 
-  if ( cr == 1 && BDS_NumBits == 24 )
+  if ( IS_EQUAL(cr, 1) && BDS_NumBits == 24 )
     {
       fprintf(stdout, "GRIB record %5d : code = %4d   level = %7d\n", nrec, PDS_Parameter, level);
     }
@@ -56656,7 +57060,7 @@ void repair1(unsigned char *gbuf, long gbufsize)
 }
 
 
-void gribRepair1(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
+void gribRepair1(int nrec, long recsize, unsigned char *gribbuffer)
 {
   int level, nerr;
   unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
@@ -56676,7 +57080,7 @@ void gribRepair1(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
   else
     level = PDS_Level1;
 
-  if ( (BDS_Flag >> 4)&1 && BDS_Z == 128 )
+  if ( ((BDS_Flag >> 4)&1) && BDS_Z == 128 )
     {
       int s1, s2;
       s1 = ((int) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
@@ -56684,7 +57088,7 @@ void gribRepair1(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
       cr = ((double)s1)/s2;
     }
 
-  if ( cr == 1 && BDS_NumBits == 24 )
+  if ( IS_EQUAL(cr, 1) && BDS_NumBits == 24 )
     {
       fprintf(stdout, "Repair GRIB record %5d : code = %4d   level = %7d\n", nrec, PDS_Parameter, level);
       repair1(gribbuffer, recsize);
@@ -56696,16 +57100,25 @@ void gribRepair1(int nrec, long recpos, 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
+#if defined (HAVE_LIBAEC)
+#  include <libaec.h>
+#else
 #  include <szlib.h>
+#endif
 #if defined (__cplusplus)
 }
 #endif
 
+#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)
 
@@ -56713,6 +57126,18 @@ extern "C" {
 #  define MIN_SIZE            (256)
 #endif
 
+#define  Z_SZIP  128
+#define  Z_AEC   130
+
+
+#define SetLen3(var, offset, value) ((var[offset+0] = 0xFF & (value >> 16)), \
+				     (var[offset+1] = 0xFF & (value >>  8)), \
+				     (var[offset+2] = 0xFF & (value      )))
+#define SetLen4(var, offset, value) ((var[offset+0] = 0xFF & (value >> 24)), \
+				     (var[offset+1] = 0xFF & (value >> 16)), \
+				     (var[offset+2] = 0xFF & (value >>  8)), \
+				     (var[offset+3] = 0xFF & (value      )))
+
 
 int gribGetZip(long recsize, unsigned char *gribbuffer, long *urecsize)
 {
@@ -56747,7 +57172,7 @@ int gribGetZip(long recsize, unsigned char *gribbuffer, long *urecsize)
   if ( lcompress )
     {
       compress = BDS_Z;
-      if ( compress == 128 )
+      if ( compress == Z_SZIP || compress == Z_AEC )
 	{
 	  gribsize = gribrec_len(bds[14], bds[15], bds[16]);
 	}
@@ -56765,7 +57190,7 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
   int gribLen;
   int rec_len;
   int llarge = FALSE;
-#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;
@@ -56778,28 +57203,35 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
   nerr = grib1Sections(dbuf, dbufsize, &pds, &gds, &bms, &bds);
   if ( nerr )
     {
-      fprintf(stdout, "grib1Sections error\n");
+      fprintf(stdout, "grib1Sections error!\n");
       return (rec_len);
     }
 
-#if  defined  (HAVE_LIBSZ)
+#if  defined (HAVE_LIBSZ) || defined (HAVE_LIBAEC)
 
   {
     long i;
     int bdsLen;
     int gribLenOld = 0;
     int status;
-    int datstart, datsize;
+    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 = 12;
+    int bds_zoffset, bds_zstart;
     unsigned char *pbuf = NULL;
 
-    if ( llarge ) bds_zoffset = 14;
+    bds_zstart  = 14;
+    bds_zoffset = 12;
+    if ( llarge ) bds_zoffset += 2;
 
     bds_len   = BDS_Len;
     bds_len   = correct_bdslen(bds_len, gribLen, bds-dbuf);
@@ -56820,16 +57252,26 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
 	  }
 	return (rec_len);
       }
-    
-    sz_param.options_mask        = OPTIONS_MASK;
 
+#if defined (HAVE_LIBSZ)
     if ( bds_nbits == 24 )
-      sz_param.bits_per_pixel    = 8;
+      bits_per_sample    = 8;
     else
-      sz_param.bits_per_pixel    = bds_nbits;
+#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 ( lspherc )
       {
@@ -56860,6 +57302,7 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
     source = bds + datstart;
     dest = sbuf;
 
+#if defined (HAVE_LIBSZ)
     if ( bds_nbits == 24 )
       {
 	long nelem;
@@ -56873,7 +57316,23 @@ 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);
+      }
 
+    destLen = strm.total_out;
+#else
     status = SZ_BufftoBuffCompress(dest, &destLen, source, sourceLen, &sz_param);
     if ( status != SZ_OK )
       {
@@ -56888,12 +57347,12 @@ 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);
     /*
     fprintf(stderr, "sourceLen, destLen %d %d\n", sourceLen, destLen);
     */
-    
     if ( destLen < MIN_COMPRESS*sourceLen )
       {
 	source = bds + datstart + bds_zoffset;
@@ -56914,7 +57373,7 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
 	*/
 	/*	memcpy(bds + datstart + bds_zoffset, source, destLen); */
 	/*
-    fprintf(stderr, "z>>> %d %d %d %d <<<\n", (int) bds[0+datstart+bds_zoffset],
+	  fprintf(stderr, "z>>> %d %d %d %d <<<\n", (int) bds[0+datstart+bds_zoffset],
 	    (int)bds[1+datstart+bds_zoffset], (int)bds[2+datstart+bds_zoffset], (int)bds[3+datstart+bds_zoffset]);
 	*/
 	if ( llarge )
@@ -56926,40 +57385,27 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
 	      }
 	    gribLenOld = gribLenOld / (-120);
 	    gribLenOld = JP23SET - gribLenOld + 1;
-	    bds[14] = 0xFF & (gribLenOld >> 16);
-	    bds[15] = 0xFF & (gribLenOld >>  8);
-	    bds[16] = 0xFF & (gribLenOld);
-
-	    bds[17] = 0xFF & (sourceLen >> 24);
-	    bds[18] = 0xFF & (sourceLen >> 16);
-	    bds[19] = 0xFF & (sourceLen >>  8);
-	    bds[20] = 0xFF & (sourceLen);
-
-	    bds[21] = 0xFF & (destLen >> 24);
-	    bds[22] = 0xFF & (destLen >> 16);
-	    bds[23] = 0xFF & (destLen >>  8);
-	    bds[24] = 0xFF & (destLen);
+
+	    SetLen3(bds, bds_zstart, gribLenOld);
+	    SetLen4(bds, bds_zstart+3, sourceLen);
+	    SetLen4(bds, bds_zstart+7, destLen);
 	  }
 	else
 	  {
-	    bds[14] = 0xFF & (gribLenOld >> 16);
-	    bds[15] = 0xFF & (gribLenOld >>  8);
-	    bds[16] = 0xFF & (gribLenOld);
-
-	    bds[17] = 0xFF & (sourceLen >> 16);
-	    bds[18] = 0xFF & (sourceLen >>  8);
-	    bds[19] = 0xFF & (sourceLen);
-
-	    bds[20] = 0xFF & (destLen >> 16);
-	    bds[21] = 0xFF & (destLen >>  8);
-	    bds[22] = 0xFF & (destLen);
+	    SetLen3(bds, bds_zstart, gribLenOld);
+	    SetLen3(bds, bds_zstart+3, sourceLen);
+	    SetLen3(bds, bds_zstart+6, destLen);
 	  }
 
 	bdsLen = datstart + bds_zoffset + destLen;
 
 	bds[11] = 0;
 	bds[12] = 0;
-	BDS_Z   = 128;
+#if defined (HAVE_LIBAEC)
+	BDS_Z   = Z_AEC;
+#else
+	BDS_Z   = Z_SZIP;
+#endif
 
 	BDS_Flag += 16;
 	if ( (bdsLen%2) == 1 )
@@ -56968,9 +57414,7 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
 	    bds[bdsLen++] = 0;
 	  }
 
-	bds[0] = 0xFF & (bdsLen >> 16);
-	bds[1] = 0xFF & (bdsLen >>  8);
-	bds[2] = 0xFF & (bdsLen);
+	SetLen3(bds, 0, bdsLen);
 
 	gribLen = (bds - dbuf) + bdsLen;
 
@@ -56997,23 +57441,20 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
 	    itemp = gribLen / (-120);
 	    itemp = JP23SET - itemp + 1;
 
-	    dbuf[4] = 0xFF & (itemp >> 16);
-	    dbuf[5] = 0xFF & (itemp >>  8);
-	    dbuf[6] = 0xFF & (itemp);
+	    SetLen3(dbuf, 4, itemp);
 
 	    bdslen = gribLen - bdslen;
 
-	    bds[0] = 0xFF & (bdsLen >> 16);
-	    bds[1] = 0xFF & (bdsLen >>  8);
-	    bds[2] = 0xFF & (bdsLen);
+	    SetLen3(bds, 0, bdslen);
 	  }
 	else
 	  {
-	    dbuf[4] = 0xFF & (gribLen >> 16);
-	    dbuf[5] = 0xFF & (gribLen >>  8);
-	    dbuf[6] = 0xFF & (gribLen);
+	    SetLen3(dbuf, 4, gribLen);
 	  }
       }
+    else
+      {
+      }
     /*
     fprintf(stderr, "%3d %3d griblen in %6d  out %6d  CR %g   slen %6d dlen %6d  CR %g\n",
 	    PDS_Parameter, PDS_Level1, gribLenOld, gribLen,
@@ -57025,12 +57466,15 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
 #else
   if ( libszwarn )
     {
-      Warning("Compression disabled, szlib not available!");
+      Warning("Compression disabled, szlib or libaec not available!");
       libszwarn = 0;
     }
 #endif
 
-  while ( gribLen & 7 ) dbuf[gribLen++] = 0;
+  if ( llarge )
+    while ( gribLen%120 ) dbuf[gribLen++] = 0;
+  else
+    while ( gribLen & 7 ) dbuf[gribLen++] = 0;
 
   rec_len = gribLen;
 
@@ -57040,18 +57484,18 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
 
 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
   int nerr;
   unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
   int bdsLen, recLen, gribLen = 0;
-  char *dest, *source;
+  unsigned char *dest, *source;
   size_t destLen, sourceLen;
   int /* bds_len, */ bds_nbits, bds_flag, lspherc, lcomplex /*, lcompress*/;
   int bds_head = 11;
   int bds_ext = 0;
-  int bds_zoffset = 12;
+  int bds_zoffset, bds_zstart;
   int datstart = 0;
   int llarge = FALSE;
 
@@ -57062,10 +57506,13 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
       return (0);
     }
 
-  recLen = gribrec_len(bds[14], bds[15], bds[16]);
+  bds_zstart = 14;
+
+  recLen = gribrec_len(bds[bds_zstart], bds[bds_zstart+1], bds[bds_zstart+2]);
   if ( recLen > JP23SET ) llarge = TRUE;
 
-  if ( llarge ) bds_zoffset = 14;
+  bds_zoffset = 12;
+  if ( llarge ) bds_zoffset += 2;
 
   /* bds_len   = BDS_Len; */
   bds_nbits = BDS_NumBits;
@@ -57091,7 +57538,7 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
 
   datstart = bds_head + bds_ext;
 
-  source = (char *) 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
@@ -57104,8 +57551,8 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
       return (0);
     }
 
-  dest = (char *) bds + datstart;
-  if ( llarge )
+  dest = bds + datstart;
+   if ( llarge )
     destLen = ((size_t) ((bds[17]<<24)+(bds[18]<<16)+(bds[19]<<8)+bds[20]));
   else
     destLen = ((size_t) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
@@ -57114,23 +57561,38 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
 
   bdsLen = datstart + destLen;
 
-#if  defined  (HAVE_LIBSZ)
+#if  defined (HAVE_LIBSZ) || defined (HAVE_LIBAEC)
   {
     int status;
     long i;
     size_t tmpLen;
     int bds_ubits;
+    int bits_per_sample;
+#if defined (HAVE_LIBAEC)
+    struct aec_stream strm;
+#else
     SZ_com_t sz_param;          /* szip parameter block */
+#endif
 
-    sz_param.options_mask        = OPTIONS_MASK;
-
+#if defined (HAVE_LIBSZ)
     if ( bds_nbits == 24 )
-      sz_param.bits_per_pixel    = 8;
+      bits_per_sample    = 8;
     else
-      sz_param.bits_per_pixel    = bds_nbits;
+#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 ( i = 0; i < bds_ext; ++i )
@@ -57143,6 +57605,18 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
     */
 
     tmpLen = destLen;
+#if defined (HAVE_LIBAEC)
+    strm.next_in   = source;
+    strm.avail_in  = sourceLen;
+    strm.next_out  = dest;
+    strm.avail_out = tmpLen;
+
+    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 )
       {
@@ -57157,6 +57631,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);
@@ -57164,7 +57639,8 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
     if ( tmpLen != destLen )
       Warning("unzip size differ: code %3d level %3d  ibuflen %ld ubuflen %ld",
 	      PDS_Parameter, PDS_Level2, (long) destLen, (long) tmpLen);
- 
+
+#if defined (HAVE_LIBSZ)
     if ( bds_nbits == 24 )
       {
 	long nelem;
@@ -57180,7 +57656,8 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
 	memcpy(dest, pbuf, tmpLen);
 	free(pbuf);
       }
-  
+#endif
+
     bds_ubits = BDS_Flag & 15;
     BDS_Flag -= bds_ubits;
 
@@ -57190,9 +57667,7 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
 	bds[bdsLen++] = 0;
       }
 
-    bds[0] = 0xFF & (bdsLen >> 16);
-    bds[1] = 0xFF & (bdsLen >>  8);
-    bds[2] = 0xFF & (bdsLen);
+    SetLen3(bds, 0, bdsLen);
 
     gribLen = (bds - dbuf) + bdsLen;
     
@@ -57221,26 +57696,23 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
 	itemp = gribLen / (-120);
 	itemp = JP23SET - itemp + 1;
 	
-	dbuf[4] = 0xFF & (itemp >> 16);
-	dbuf[5] = 0xFF & (itemp >>  8);
-	dbuf[6] = 0xFF & (itemp);
-	
+	SetLen3(dbuf, 4, itemp);
+
 	bdsLen = gribLen - bdsLen;
 	    
-	bds[0] = 0xFF & (bdsLen >> 16);
-	bds[1] = 0xFF & (bdsLen >>  8);
-	bds[2] = 0xFF & (bdsLen);
+	SetLen3(bds, 0, bdsLen);
       }
     else
       {
-	dbuf[4] = 0xFF & (recLen >> 16);
-	dbuf[5] = 0xFF & (recLen >>  8);
-	dbuf[6] = 0xFF & (recLen);
+	SetLen3(dbuf, 4, recLen);
       }
     /*
     fprintf(stderr, "recLen, gribLen, bdsLen %d %d %d\n", recLen, gribLen, bdsLen);
     */
-    while ( gribLen & 7 ) dbuf[gribLen++] = 0;
+    if ( llarge )
+      while ( gribLen%120 ) dbuf[gribLen++] = 0;
+    else
+      while ( gribLen & 7 ) dbuf[gribLen++] = 0;
     /*
     fprintf(stderr, "recLen, gribLen, bdsLen %d %d %d\n", recLen, gribLen, bdsLen);
     */
@@ -57248,14 +57720,14 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
 #else
   if ( libszwarn )
     {
-      Warning("Decompression disabled, szlib not available!");
+      Warning("Decompression disabled, szlib or libaec not available!");
       libszwarn = 0;
     }
 #endif
 
   return (gribLen);
 }
-static const char grb_libvers[] = "1.5.6" " of ""Dec 17 2012"" ""13:44:05";
+static const char grb_libvers[] = "1.6.0" " of ""Mar  5 2013"" ""11:10:25";
 const char *
 cgribexLibraryVersion(void)
 {
@@ -57294,13 +57766,10 @@ const char *gribapiLibraryVersion(void)
 }
 
 
-void gribContainersNew(int streamID)
+void gribContainersNew(stream_t * streamptr)
 {
-  stream_t *streamptr;
   int editionNumber = 2;
 
-  streamptr = stream_to_pointer(streamID);
-
   if ( streamptr->filetype == FILETYPE_GRB ) editionNumber = 1;
 
 #if  defined  (HAVE_LIBCGRIBEX)
@@ -57345,12 +57814,8 @@ void gribContainersNew(int streamID)
 }
 
 
-void gribContainersDelete(int streamID)
+void gribContainersDelete(stream_t * streamptr)
 {
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
   if ( streamptr->gribContainers )
     {
       int nvars = streamptr->nvars;
@@ -58135,7 +58600,9 @@ statusCode namespaceInqResStatus ( void )
 #if defined (HAVE_CONFIG_H)
 #endif
 
+#ifndef _XOPEN_SOURCE
 #define _XOPEN_SOURCE 600 /* PTHREAD_MUTEX_RECURSIVE */
+#endif
 
 #include <stdlib.h>
 #include <stdio.h>
@@ -58407,7 +58874,7 @@ void reshRemove ( cdiResH resH, resOps * ops )
 
 /**************************************************************/
 
-void *reshGetVal ( cdiResH resH, resOps * ops  )
+void *reshGetValue(const char * caller, cdiResH resH, resOps * ops)
 {
   int nsp;
   namespaceTuple_t nspT;
@@ -58423,9 +58890,8 @@ void *reshGetVal ( cdiResH resH, resOps * ops  )
 
   nspT = namespaceResHDecode ( resH );
 
-  if (nspT.nsp == nsp &&
-      nspT.idx >= 0 &&
-      nspT.idx < listSizeAllocated[nsp])
+  if ( nspT.nsp == nsp &&
+       nspT.idx >= 0 && nspT.idx < listSizeAllocated[nsp] )
     {
       listElem = listResources[nsp] + nspT.idx;
       LIST_UNLOCK();
@@ -58433,10 +58899,11 @@ void *reshGetVal ( cdiResH resH, resOps * ops  )
   else
     {
       LIST_UNLOCK();
-      xabort("Invalid namespace %d or index %d for resH %d!", nspT.nsp, nspT.idx, (int)resH);
+      xabortC(caller, "Invalid namespace %d or index %d for resource handle %d!", nspT.nsp, nspT.idx, (int)resH);
     }
 
-  xassert(listElem && listElem->ops == ops);
+  if ( !(listElem && listElem->ops == ops) )
+    xabortC(caller, "Invalid resource handle %d, list element not found!", (int)resH);
 
   return listElem->val;
 }
@@ -58846,8 +59313,8 @@ char commands[][13] = { "FINALIZE\0",
                         "WRITETS\0"};
 
 
-void pcdiAssert   ( bool assumption, const char * filename,
-                    const char * functionname, int line )
+void pcdiAssert(bool assumption,
+                const char * filename, const char * functionname, int line )
 {
   if ( !assumption )
     {
@@ -58873,6 +59340,31 @@ void pcdiAssert   ( bool assumption, const char * filename,
 
 /****************************************************/
 
+void pcdiAbortC(const char * caller, const char * filename, const char *functionname, int line,
+                const char * errorString, ... )
+{
+  va_list ap;
+  va_start(ap, errorString);
+#ifdef USE_MPI
+  {
+    int rank;
+    MPI_Comm_rank ( MPI_COMM_WORLD, &rank );
+    fprintf(stderr, "ERROR, pe%d in %s, %s, line %d, called from %s\nerrorString: \"",
+            rank, functionname, filename, line, caller);
+  }
+  vfprintf(stderr, errorString, ap);
+  fputs("\"\n", stderr);
+  MPI_Abort ( MPI_COMM_WORLD, 1 );
+#else
+  fprintf(stderr, "ERROR, %s, %s, line %d, called from %s\nerrorString: \"",
+          functionname, filename, line, caller);
+  vfprintf(stderr, errorString, ap);
+  fputs("\"\n", stderr);
+#endif
+  exit ( EXIT_FAILURE );
+  va_end(ap);
+}
+
 void pcdiAbort(const char * filename, const char *functionname, int line,
                const char * errorString, ... )
 {
@@ -60263,11 +60755,13 @@ void pioWriteTimestep ( int tsID, int vdate, int vtime )
  * require-trailing-newline: t
  * End:
  */
-#define _XOPEN_SOURCE 600
-
 #ifdef HAVE_CONFIG_H
 #endif
 
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 600
+#endif
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdbool.h>
@@ -62188,7 +62682,7 @@ listSetForeach(listSet *q, void (*func)(void *elem, void *data), void *data)
  * require-trailing-newline: t
  * End:
  */
-   static char cdi_libvers[] = "1.5.9" " of ""Dec 17 2012"" ""13:48:03";
+   static char cdi_libvers[] = "1.6.0" " of ""Mar 14 2013"" ""11:28:22";
 char *cdiLibraryVersion(void);
 char *cdiLibraryVersion(void)
 {
@@ -64681,6 +65175,12 @@ FCALLSCSUB2 (cdiDefGlobal, CDIDEFGLOBAL, cdidefglobal, STRING, INT)
 FCALLSCSUB3 (cdiParamToString, CDIPARAMTOSTRING, cdiparamtostring, INT, PSTRING, INT)
 FCALLSCSUB4 (cdiDecodeParam, CDIDECODEPARAM, cdidecodeparam, INT, PINT, PINT, PINT)
 FCALLSCFUN3 (INT, cdiEncodeParam, CDIENCODEPARAM, cdiencodeparam, INT, INT, INT)
+
+/*  date format:  YYYYMMDD  */
+
+
+/*  time format:    hhmmss  */
+
 FCALLSCSUB4 (cdiDecodeDate, CDIDECODEDATE, cdidecodedate, INT, PINT, PINT, PINT)
 FCALLSCFUN3 (INT, cdiEncodeDate, CDIENCODEDATE, cdiencodedate, INT, INT, INT)
 FCALLSCSUB4 (cdiDecodeTime, CDIDECODETIME, cdidecodetime, INT, PINT, PINT, PINT)
@@ -64833,6 +65333,28 @@ FCALLSCFUN3 (INT, vlistMergedLevel, VLISTMERGEDLEVEL, vlistmergedlevel, INT, INT
 FCALLSCSUB5 (vlistDefVarEnsemble, VLISTDEFVARENSEMBLE, vlistdefvarensemble, INT, INT, INT, INT, INT)
 FCALLSCFUN5 (INT, vlistInqVarEnsemble, VLISTINQVARENSEMBLE, vlistinqvarensemble, INT, INT, PINT, PINT, PINT)
 
+/*  ----------------------------------  */
+
+
+/*  Local change: 2013-01-28, FP (DWD)  */
+
+
+/*  ----------------------------------  */
+
+FCALLSCSUB4 (vlistDefVarIntKey, VLISTDEFVARINTKEY, vlistdefvarintkey, INT, INT, STRING, INT)
+FCALLSCSUB4 (vlistDefVarDblKey, VLISTDEFVARDBLKEY, vlistdefvardblkey, INT, INT, STRING, DOUBLE)
+
+/*  ----------------------------------  */
+
+
+/*  Local change: 2013-02-18, FP (DWD)  */
+
+
+/*  ----------------------------------  */
+
+FCALLSCSUB2 (vlistInqVarRawBegin, VLISTINQVARRAWBEGIN, vlistinqvarrawbegin, INT, INT)
+FCALLSCSUB1 (vlistInqVarRawEnd, VLISTINQVARRAWEND, vlistinqvarrawend, INT)
+
 /*  VLIST attributes  */
 
 FCALLSCFUN3 (INT, vlistInqNatts, VLISTINQNATTS, vlistinqnatts, INT, INT, PINT)
@@ -64855,7 +65377,6 @@ FCALLSCFUN2 (INT, gridInqMaskGME, GRIDINQMASKGME, gridinqmaskgme, INT, PINT)
 FCALLSCSUB2 (gridDefMask, GRIDDEFMASK, griddefmask, INT, PINT)
 FCALLSCFUN2 (INT, gridInqMask, GRIDINQMASK, gridinqmask, INT, PINT)
 FCALLSCSUB2 (gridPrint, GRIDPRINT, gridprint, INT, INT)
-FCALLSCFUN0 (INT, gridSize, GRIDSIZE, gridsize)
 FCALLSCFUN2 (INT, gridCreate, GRIDCREATE, gridcreate, INT, INT)
 FCALLSCSUB1 (gridDestroy, GRIDDESTROY, griddestroy, INT)
 FCALLSCFUN1 (INT, gridDuplicate, GRIDDUPLICATE, gridduplicate, INT)
@@ -64963,7 +65484,6 @@ FCALLSCFUN1 (INT, zaxisInqSize, ZAXISINQSIZE, zaxisinqsize, INT)
 FCALLSCFUN1 (INT, zaxisDuplicate, ZAXISDUPLICATE, zaxisduplicate, INT)
 FCALLSCSUB2 (zaxisResize, ZAXISRESIZE, zaxisresize, INT, INT)
 FCALLSCSUB1 (zaxisPrint, ZAXISPRINT, zaxisprint, INT)
-FCALLSCFUN0 (INT, zaxisSize, ZAXISSIZE, zaxissize)
 FCALLSCSUB2 (zaxisDefLevels, ZAXISDEFLEVELS, zaxisdeflevels, INT, PDOUBLE)
 FCALLSCSUB2 (zaxisInqLevels, ZAXISINQLEVELS, zaxisinqlevels, INT, PDOUBLE)
 FCALLSCSUB3 (zaxisDefLevel, ZAXISDEFLEVEL, zaxisdeflevel, INT, INT, DOUBLE)
diff --git a/libcdi/src/cgribex.h b/libcdi/src/cgribex.h
index 35b9fe6..8169e60 100644
--- a/libcdi/src/cgribex.h
+++ b/libcdi/src/cgribex.h
@@ -8,6 +8,9 @@
 
 /* GRIB1 Level Types */
 #define  GRIB1_LTYPE_SURFACE               1
+#define  GRIB1_LTYPE_CLOUDBASE             2
+#define  GRIB1_LTYPE_CLOUDTOP              3
+#define  GRIB1_LTYPE_ISOTHERM0             4
 #define  GRIB1_LTYPE_TOA                   8
 #define  GRIB1_LTYPE_SEA_BOTTOM            9
 #define  GRIB1_LTYPE_ATMOSPHERE           10
@@ -212,7 +215,7 @@ void  gribPrintGDS(int nrec, long recpos, long recsize, unsigned char *gribbuffe
 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 recpos, long recsize, unsigned char *gribbuffer);
+void  gribRepair1(int nrec, long recsize, unsigned char *gribbuffer);
 
 int grib1Sections(unsigned char *gribbuffer, long recsize, unsigned char **pdsp,
 		  unsigned char **gdsp, unsigned char **bmsp, unsigned char **bdsp);
diff --git a/libcdi/src/cgribexlib.c b/libcdi/src/cgribexlib.c
index 9ee2628..063e78f 100644
--- a/libcdi/src/cgribexlib.c
+++ b/libcdi/src/cgribexlib.c
@@ -1,7 +1,7 @@
 
-/* Automatically generated by m214003 at 2012-12-17, do not edit */
+/* Automatically generated by m214003 at 2013-03-05, do not edit */
 
-/* CGRIBEXLIB_VERSION="1.5.6" */
+/* CGRIBEXLIB_VERSION="1.6.0" */
 
 #ifdef _ARCH_PWR6
 #pragma options nostrict
@@ -63,6 +63,7 @@
 #  define VECTORCODE
 #endif
 
+
 #if defined (VECTORCODE)
 #if  defined  (INT32)
 #  define  GRIBPACK     unsigned INT32
@@ -365,7 +366,7 @@ void  gribDecode(int *isec0, int *isec1, int *isec2, double *fsec2, int *isec3,
 #include <math.h>
 
 
-double _pow2tab[158] = {
+const double const _pow2tab[158] = {
  /* pow(2.0,  0.0) */  1.0,
  /* pow(2.0,  1.0) */  2.0,
  /* pow(2.0,  2.0) */  4.0,
@@ -527,7 +528,7 @@ double _pow2tab[158] = {
 };
 
 
-double _pow16tab[71] = {
+const double const _pow16tab[71] = {
  /* pow(16.0,  0.0) */  1.0,
  /* pow(16.0,  1.0) */  16.0,
  /* pow(16.0,  2.0) */  256.0,
@@ -1484,13 +1485,15 @@ void encode_double_array_unrolled(int numBits, size_t packStart, size_t datasize
 #else
 #define __UNROLL_DEPTH_2 8
 #endif
-  size_t residual =  datasize % __UNROLL_DEPTH_2;
-  size_t ofs = datasize - residual;
+  size_t residual;
+  size_t ofs;
   double dval[__UNROLL_DEPTH_2];
   unsigned long ival;
 
   data += packStart;
   datasize -= packStart;
+  residual =  datasize % __UNROLL_DEPTH_2;
+  ofs = datasize - residual;
 
   // reducing FP operations to single FMA is slowing down on pwr6 ...
 
@@ -1697,6 +1700,463 @@ void encode_double_array_unrolled(int numBits, size_t packStart, size_t datasize
   *gz = z;
 #undef __UNROLL_DEPTH_2
 }
+//#undef _GET_X86_COUNTER
+//#undef _GET_MACH_COUNTER
+//#undef _GET_IBM_COUNTER
+//#undef _ARCH_PWR6
+
+#if defined _GET_IBM_COUNTER
+#include <libhpc.h>
+#elif defined _GET_X86_COUNTER
+#include <x86intrin.h>
+#elif defined _GET_MACH_COUNTER
+#include <mach/mach_time.h>
+#endif
+
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
+
+/*
+#if ((__GNUC__ >= 4) || (__ICC >= 1100) || defined (__clang__))
+#define _ENABLE_SIMD
+#include <immintrin.h>
+#undef __AVX
+#ifdef __AVX__
+#define _ENABLE_AVX
+#elif __SSE4_1__
+#define _ENABLE_SSE4_1
+#endif
+#endif
+*/
+
+#undef _ENABLE_AVX
+#undef _ENABLE_SSE4_1
+
+#if defined _ENABLE_AVX
+
+static
+void avx_decode_double_array_2byte(size_t datasize, const unsigned char * restrict igrib,
+				     double * restrict fpdata, double fmin, double zscale)
+{
+  size_t i, j;
+  size_t nframes = datasize;
+  size_t residual;
+  size_t ofs;
+
+  double dval;
+
+  double *data = fpdata;
+  __m128i *sgrib;
+  
+  __m128i mask = _mm_set_epi8(14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1);
+
+  __m256d ymm0 = _mm256_set1_pd(fmin);
+  __m256d ymm1 = _mm256_set1_pd(zscale);
+  
+  __m128i xmm0, xmm1, xmm2, xmm3;
+  __m256d ymm2, ymm3;
+
+  i = -1;
+  while ( ((unsigned long) data) % 32 != 0 && datasize > 0)
+    {
+      i++;
+      dval = (((int)igrib[2*i] <<  8) | (int)igrib[2*i+1]);
+      fpdata[i] = fmin + zscale * dval;
+      data++;
+      nframes--;
+    }
+  
+  if (i == -1) i = 0;
+  sgrib = (__m128i *) (igrib+i);
+
+  while (nframes >= 16)
+    { 
+      xmm0 = _mm_loadu_si128((__m128i *) sgrib);
+      xmm0 = _mm_shuffle_epi8(xmm0, mask);
+      xmm1 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(1, 0, 3, 2));
+      xmm2 = _mm_cvtepu16_epi32(xmm0);
+      xmm3 = _mm_cvtepu16_epi32(xmm1);
+
+      ymm2 = _mm256_cvtepi32_pd(xmm2);
+      ymm2 = _mm256_add_pd(_mm256_mul_pd(ymm2, ymm1), ymm0);
+      (void) _mm256_stream_pd(data, ymm2);
+      ymm3 = _mm256_cvtepi32_pd(xmm3);
+      ymm3 = _mm256_add_pd(_mm256_mul_pd(ymm3, ymm1), ymm0);
+      (void) _mm256_stream_pd(data+4, ymm3);  
+      
+      xmm0 = _mm_loadu_si128((__m128i *) sgrib + 1);
+      xmm0 = _mm_shuffle_epi8(xmm0, mask);
+      xmm1 = _mm_shuffle_epi32(xmm0, _MM_SHUFFLE(1, 0, 3, 2));
+      xmm2 = _mm_cvtepu16_epi32(xmm0);
+      xmm3 = _mm_cvtepu16_epi32(xmm1);
+      
+      ymm2 = _mm256_cvtepi32_pd(xmm2);
+      ymm2 = _mm256_add_pd(_mm256_mul_pd(ymm2, ymm1), ymm0);
+      (void) _mm256_stream_pd(data+8, ymm2);
+      ymm3 = _mm256_cvtepi32_pd(xmm3);
+      ymm3 = _mm256_add_pd(_mm256_mul_pd(ymm3, ymm1), ymm0);
+      (void) _mm256_stream_pd(data+12, ymm3);  
+      
+      data += 16;
+      sgrib += 2;
+      nframes -= 16;
+    }
+
+  residual = nframes;
+  ofs = datasize - residual;
+  for ( j = 0; j < residual; j++ )
+    {
+      dval = (((int)igrib[2*(ofs+j)] <<  8) | (int)igrib[2*(ofs+j)+1]);
+      fpdata[ofs+j] = fmin + zscale * dval;
+    }
+
+  return;
+}
+
+#elif defined _ENABLE_SSE4_1
+
+static
+void sse41_decode_double_array_2byte(size_t datasize, const unsigned char * restrict igrib,
+				     double * restrict fpdata, double fmin, double zscale)
+{
+  size_t i, j;
+  size_t nframes = datasize;
+  size_t residual;
+  size_t ofs;
+
+  double dval;
+
+  double *data = fpdata;
+  __m128i *sgrib;
+  
+  __m128i mask = _mm_set_epi8(14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1);
+  __m128d dmm8 = _mm_set1_pd(fmin);
+  __m128d dmm9 = _mm_set1_pd(zscale);
+  
+  __m128i xmm4, xmm5;
+  __m128i xmm6, xmm7;
+  
+  __m128d dmm0, dmm1, dmm2, dmm3;
+  __m128d dmm4, dmm5, dmm6, dmm7;
+
+  i = -1;
+  while ( ((unsigned long) data) % 32 != 0 && datasize > 0)
+    {
+      i++;
+      dval = (((int)igrib[2*i] <<  8) | (int)igrib[2*i+1]);
+      fpdata[i] = fmin + zscale * dval;
+      data++;
+      nframes--;
+    }
+  
+  if (i == -1) i = 0;
+  sgrib = (__m128i *) (igrib+i);
+  
+  while (nframes >= 16)
+    {
+      xmm5 = _mm_loadu_si128((__m128i *) sgrib);
+      xmm5 = _mm_shuffle_epi8(xmm5, mask);
+      xmm4 = _mm_srli_si128(xmm5, 8);
+      xmm6 = _mm_cvtepu16_epi32(xmm5);
+      dmm0 = _mm_cvtepi32_pd(xmm6);
+      dmm0 = _mm_add_pd(_mm_mul_pd(dmm0, dmm9), dmm8);
+      (void) _mm_stream_pd(data, dmm0);
+      xmm7 = _mm_srli_si128(xmm6, 8);
+      dmm1 = _mm_cvtepi32_pd(xmm7);
+      dmm1 = _mm_add_pd(_mm_mul_pd(dmm1, dmm9), dmm8);
+      (void) _mm_stream_pd(data+2, dmm1);
+      xmm6 = _mm_cvtepu16_epi32(xmm4);
+      dmm2 = _mm_cvtepi32_pd(xmm6);
+      dmm2 = _mm_add_pd(_mm_mul_pd(dmm2, dmm9), dmm8);
+      (void) _mm_stream_pd(data+4, dmm2);
+      xmm7 = _mm_srli_si128(xmm6, 8);
+      dmm3 = _mm_cvtepi32_pd(xmm7);
+      dmm3 = _mm_add_pd(_mm_mul_pd(dmm3, dmm9), dmm8);
+      (void) _mm_stream_pd(data+6, dmm3);
+      
+      xmm5 = _mm_loadu_si128((__m128i *) sgrib+1);
+      xmm5 = _mm_shuffle_epi8(xmm5, mask);
+      xmm4 = _mm_srli_si128(xmm5, 8);
+      xmm6 = _mm_cvtepu16_epi32(xmm5);
+      dmm4 = _mm_cvtepi32_pd(xmm6);
+      dmm4 = _mm_add_pd(_mm_mul_pd(dmm4, dmm9), dmm8);
+      (void) _mm_stream_pd(data+8, dmm4);
+      xmm7 = _mm_srli_si128(xmm6, 8);
+      dmm5 = _mm_cvtepi32_pd(xmm7);
+      dmm5 = _mm_add_pd(_mm_mul_pd(dmm5, dmm9), dmm8);
+      (void) _mm_stream_pd(data+10, dmm5);
+      xmm6 = _mm_cvtepu16_epi32(xmm4);
+      dmm6 = _mm_cvtepi32_pd(xmm6);
+      dmm6 = _mm_add_pd(_mm_mul_pd(dmm6, dmm9), dmm8);
+      (void) _mm_stream_pd(data+12, dmm6);
+      xmm7 = _mm_srli_si128(xmm6, 8);
+      dmm7 = _mm_cvtepi32_pd(xmm7);
+      dmm7 = _mm_add_pd(_mm_mul_pd(dmm7, dmm9), dmm8);
+      (void) _mm_stream_pd(data+14, dmm7);
+
+      data += 16;
+      sgrib += 2;
+      nframes -= 16;
+    }
+
+  residual = nframes;
+  ofs = datasize - residual;
+  for ( j = 0; j < residual; j++ )
+    {
+      dval = (((int)igrib[2*(ofs+j)] <<  8) | (int)igrib[2*(ofs+j)+1]);
+      fpdata[ofs+j] = fmin + zscale * dval;
+    }
+
+  return;
+}
+
+#endif
+
+static 
+void decode_double_array_common(const unsigned char * restrict igrib, long jlend, int NumBits, 
+				double fmin, double zscale, double * restrict fpdata)
+{
+  /* code from wgrib routine BDS_unpack */
+  const unsigned char *bits = igrib;
+  unsigned int jmask;
+  long i;
+  unsigned int tbits = 0;
+  int n_bits = NumBits;
+  int t_bits = 0;
+      
+  jmask = (1 << n_bits) - 1;
+  for ( i = 0; i < jlend; i++ )
+    {
+      if (n_bits - t_bits > 8)
+	{
+	  tbits = (tbits << 16) | (bits[0] << 8) | (bits[1]);
+	  bits += 2;
+	  t_bits += 16;
+	}
+
+      while ( t_bits < n_bits )
+	{
+	  tbits = (tbits * 256) + *bits++;
+	  t_bits += 8;
+	}
+      t_bits -= n_bits;
+      fpdata[i] = (tbits >> t_bits) & jmask;
+    }
+  /* at least this vectorizes :) */
+  for ( i = 0; i < jlend; i++ )
+    fpdata[i] = fmin + zscale*fpdata[i];
+}
+
+static unsigned int mask[] = {0,1,3,7,15,31,63,127,255};
+static double shift[9] = {1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0};
+
+static 
+void decode_double_array_common2(const unsigned char * restrict igrib, long jlend, int NumBits, 
+				 double fmin, double zscale, double * restrict fpdata)
+{
+  /* code from wgrib routine BDS_unpack */
+  const unsigned char *bits = igrib;
+  long i;
+  int n_bits = NumBits;
+  int c_bits, j_bits;
+  double jj;
+
+  /* older unoptimized code, not often used */
+  c_bits = 8;
+  for ( i = 0; i < jlend; i++ )
+    {
+      jj = 0.0;
+      j_bits = n_bits;
+      while (c_bits <= j_bits)
+	{
+	  if (c_bits == 8)
+	    {
+	      jj = jj * 256.0  + (double) (*bits++);
+	      j_bits -= 8;
+	    }
+	  else
+	    {
+	      jj = (jj * shift[c_bits]) + (double) (*bits & mask[c_bits]);
+	      bits++;
+	      j_bits -= c_bits;
+	      c_bits = 8;
+	    }
+	}
+
+      if (j_bits)
+	{
+	  c_bits -= j_bits;
+	  jj = (jj * shift[j_bits]) + (double) ((*bits >> c_bits) & mask[j_bits]);
+	}
+      
+      fpdata[i] = fmin + zscale*jj;
+    }
+} 
+
+static 
+void decode_double_array_byte(const unsigned char * restrict igrib, long jlend, int numBits, 
+			      double fmin, double zscale, double * restrict fpdata)
+{
+#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER 
+  uint64_t start_decode, end_decode;
+#endif
+
+  long i;
+  double dval;
+#if defined (VECTORCODE)
+  GRIBPACK *lgrib = NULL;
+
+  if ( numBits%8 == 0 )
+    {
+      long jlenc = jlend * numBits / 8;
+      if ( jlenc > 0 ) 
+	{
+	  lgrib = (GRIBPACK *) malloc(jlenc*sizeof(GRIBPACK));
+	  if ( lgrib == NULL ) SysError("No Memory!");
+
+	  (void) UNPACK_GRIB(igrib, lgrib, jlenc, -1L);
+	}
+    }
+
+  if ( numBits ==  0 )
+    {
+      for ( i = 0; i < jlend; i++ )
+	fpdata[i] = fmin;
+    }
+  else if ( numBits ==  8 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (int)lgrib[i];
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits == 16 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (((int)lgrib[2*i  ] <<  8) +  (int)lgrib[2*i+1]);
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits == 24 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (((int)lgrib[3*i  ] << 16) + ((int)lgrib[3*i+1] <<  8) +
+	  	 (int)lgrib[3*i+2]);
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits == 32 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (((unsigned int)lgrib[4*i  ] << 24) + ((unsigned int)lgrib[4*i+1] << 16) +
+		((unsigned int)lgrib[4*i+2] <<  8) +  (unsigned int)lgrib[4*i+3]);
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits <= 25 )
+    {
+      decode_double_array_common(igrib, jlend, numBits, fmin, zscale, fpdata);
+    }
+  else if ( numBits > 25 && numBits < 32 )
+    {
+      decode_double_array_common2(igrib, jlend, numBits, fmin, zscale, fpdata);
+    }
+  else
+    {
+      Error("Unimplemented packing factor %d!", numBits);
+    }
+
+  if ( lgrib ) free(lgrib);
+
+#else
+  if ( numBits ==  0 )
+    {
+      for ( i = 0; i < jlend; i++ )
+	fpdata[i] = fmin;
+    }
+  else if ( numBits ==  8 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (int)igrib[i];
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits == 16 )
+    {
+#ifdef _GET_IBM_COUNTER 
+      hpmStart(6, "unpack 16 bit base");
+#elif defined _GET_X86_COUNTER 
+      start_decode = _rdtsc();
+#elif defined _GET_MACH_COUNTER 
+      start_decode = mach_absolute_time();
+#endif
+      
+#if defined _ENABLE_AVX
+      printf("AVX selected ...\n");
+      avx_decode_double_array_2byte((size_t) jlend, igrib, fpdata, fmin, zscale);
+#elif defined _ENABLE_SSE4_1
+      printf("SSE4 selected ...\n");
+      sse41_decode_double_array_2byte((size_t) jlend, igrib, fpdata, fmin, zscale);
+#else
+      for ( i = 0; i < jlend; i++ )
+	{
+	  dval = (((int)igrib[2*i  ] <<  8) |  (int)igrib[2*i+1]);
+	  fpdata[i] = fmin + zscale * dval;
+	}
+#endif
+
+#if defined _GET_X86_COUNTER || defined _GET_MACH_COUNTER
+#if defined _GET_X86_COUNTER 
+      end_decode = _rdtsc();
+#elif defined _GET_MACH_COUNTER 
+      end_decode = mach_absolute_time();
+#endif
+#if defined _ENABLE_AVX
+      printf("AVX encoding cycles:: %" PRIu64 "\n", 
+	     end_decode-start_decode);
+#elif defined _ENABLE_SSE4_1
+      printf("SSE 4.1 encoding cycles:: %" PRIu64 "\n", 
+	     end_decode-start_decode);
+#else
+      printf("loop encoding cycles:: %" PRIu64 "\n", 
+	     end_decode-start_decode);
+#endif  
+#endif
+      
+#ifdef _GET_IBM_COUNTER 
+      hpmStop(6);
+#endif
+    }
+  else if ( numBits == 24 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (((int)igrib[3*i  ] << 16) + ((int)igrib[3*i+1] <<  8) +
+		 (int)igrib[3*i+2]);
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits == 32 )
+    for ( i = 0; i < jlend; i++ )
+      {
+	dval = (((unsigned int)igrib[4*i  ] << 24) + ((unsigned int)igrib[4*i+1] << 16) +
+		((unsigned int)igrib[4*i+2] <<  8) +  (unsigned int)igrib[4*i+3]);
+	fpdata[i] = fmin + zscale * dval;
+      }
+  else if ( numBits <= 25 )
+    {
+      decode_double_array_common(igrib, jlend, numBits, fmin, zscale, fpdata);
+    }
+  else if ( numBits > 25 && numBits < 32 )
+    {
+      decode_double_array_common2(igrib, jlend, numBits, fmin, zscale, fpdata);
+    }
+  else
+    {
+      Error("Unimplemented packing factor %d!", numBits);
+    }
+#endif
+}
+
+static 
+void decode_double_array_unrolled(const unsigned char * restrict igrib, long jlend, int numBits, 
+				  double fmin, double zscale, double * restrict fpdata)
+{
+  decode_double_array_byte(igrib, jlend, numBits, fmin, zscale, fpdata);
+}
 
 #define  NINT(x)  ((x) < 0 ? (int)((x)-.5) : (int)((x)+.5))
 
@@ -1769,12 +2229,12 @@ void confp3(double pval, int *kexp, int *kmant, int kbits, int kround)
         - replace 1.0 / pow(16.0, (double)(iexp - 70)) by rpow16m70tab[iexp]
   */
 
-  double zval, rpowref;
+  double rpowref;
   double zref, zeps;
   int iexp, isign;
   int iround;
-  extern int CGRIBEX_Debug;
-  extern double _pow16tab[71];
+  // extern int CGRIBEX_Debug;
+  extern const double const _pow16tab[71];
 
   /* ----------------------------------------------------------------- */
   /*   Section 1 . Initialise                                          */
@@ -1933,19 +2393,20 @@ void confp3(double pval, int *kexp, int *kmant, int kbits, int kround)
   /* ----------------------------------------------------------------- */
 
 LABEL900:
-
+  /*
   if ( CGRIBEX_Debug )
     {
+      double zval;
+
       Message("Conversion type parameter = %4d", kround);
       Message("Original number = %30.20f", pval);
 
       zval = decfp2(*kexp, *kmant);
 
       Message("Converted to      %30.20f", zval);
-      Message("Sign = %3d, Exponent = %3d, Mantissa = %12d",
-	      isign, iexp, *kmant);
+      Message("Sign = %3d, Exponent = %3d, Mantissa = %12d", isign, iexp, *kmant);
     }
-
+  */
   return;
 } /* confp3 */
 
@@ -2019,14 +2480,14 @@ double decfp2(int kexp, int kmant)
 
   double pval;
   int iexp, isign;
-  extern int CGRIBEX_Debug;
-  extern double _pow16tab[71];
+  //extern int CGRIBEX_Debug;
+  extern const double const _pow16tab[71];
   
   /* ----------------------------------------------------------------- */
   /*   Section 1 . Convert value of 0.0. Ignore sign bit.              */
   /* ----------------------------------------------------------------- */
 
-  if ( CGRIBEX_Debug ) Message("KEXP = %d  KMANT = %d", kexp, kmant);
+  //if ( CGRIBEX_Debug ) Message("KEXP = %d  KMANT = %d", kexp, kmant);
   /*
   if ( (kexp == 128 || kexp == 0) && kmant == 0 )
   */
@@ -2070,11 +2531,12 @@ double decfp2(int kexp, int kmant)
 
 LABEL900:
 
-  if ( CGRIBEX_Debug ) Message("Returned value = %f", pval);
+  //if ( CGRIBEX_Debug ) Message("Returned value = %f", pval);
 
   return (pval);
 } /* decfp2 */
 #include <stdio.h>
+#include <stdint.h>
 #include <string.h>
 #include <stdarg.h>
 
@@ -2153,8 +2615,9 @@ void gribDateTime(int *isec1, int *date, int *time)
 {
   static int lprint = TRUE;
   int ryear, rmonth, rday, rhour, rminute, second;
-  int time_period = 0;
-  int julday, secofday, addsec;
+  int julday, secofday;
+  int64_t addsec = 0;
+  int64_t time_period = 0;
   int century;
   extern int grib_calendar;
 
@@ -2217,6 +2680,7 @@ void gribDateTime(int *isec1, int *date, int *time)
 	      gprintf(__func__, "Time unit %d unsupported", ISEC1_TimeUnit);
 	      lprint = FALSE;
 	    }
+	  break;
 	}
 
       julday_add_seconds(addsec, &julday, &secofday);
@@ -2256,12 +2720,12 @@ gribExDP(int *isec0, int *isec1, int *isec2, double *fsec2, int *isec3,
 {
   int yfunc = *hoper;
 
-  if ( yfunc == 'D' || yfunc == 'J' || yfunc == 'R' )
-    gribDecode(isec0, isec1, isec2, fsec2, isec3,
+  if ( yfunc == 'C' )
+    gribEncode(isec0, isec1, isec2, fsec2, isec3,
 	       fsec3, isec4, fsec4, klenp, kgrib,
 	       kleng, kword, yfunc, kret);
-  else if ( yfunc == 'C' )
-    gribEncode(isec0, isec1, isec2, fsec2, isec3,
+  else if ( yfunc == 'D' || yfunc == 'J' || yfunc == 'R' )
+    gribDecode(isec0, isec1, isec2, fsec2, isec3,
 	       fsec3, isec4, fsec4, klenp, kgrib,
 	       kleng, kword, yfunc, kret);
   else if ( yfunc == 'V' )
@@ -4498,7 +4962,7 @@ int encodeBDS(GRIBPACK *lGrib, long *gribLen, int decscale, int *isec2, int *ise
   double jpepsln = 1.0e-12;     /* -----> tolerance used to check equality     */
                                 /*        of floating point numbers - needed   */
 		                /*        on some platforms (eg vpp700, linux) */
-  extern double _pow2tab[158];
+  extern const double const _pow2tab[158];
   extern int CGRIBEX_Const;         /* 1: Don't pack constant fields on regular grids */
 
   if ( isec2 )
@@ -4856,6 +5320,8 @@ void gribEncode(int *isec0, int *isec1, int *isec2, double *fsec2, int *isec3,
 
 
 
+
+
 int gribVersion(unsigned char *is, size_t buffersize)
 {
   if ( buffersize < 8 )
@@ -5370,204 +5836,6 @@ int decodeGDS(unsigned char  *gds, int *isec0, int *isec2, double *fsec2, int *n
   return (gdsLen);
 }
 
-static 
-void decode_double_array_common(unsigned char *igrib, long jlend, int NumBits, 
-				double fmin, double zscale, double *fpdata)
-{
-  /* code from wgrib routine BDS_unpack */
-  unsigned char *bits = igrib;
-  unsigned int jmask;
-  long i;
-  unsigned int tbits = 0;
-  int n_bits = NumBits;
-  int t_bits = 0;
-      
-  jmask = (1 << n_bits) - 1;
-  for ( i = 0; i < jlend; i++ )
-    {
-      if (n_bits - t_bits > 8)
-	{
-	  tbits = (tbits << 16) | (bits[0] << 8) | (bits[1]);
-	  bits += 2;
-	  t_bits += 16;
-	}
-
-      while ( t_bits < n_bits )
-	{
-	  tbits = (tbits * 256) + *bits++;
-	  t_bits += 8;
-	}
-      t_bits -= n_bits;
-      fpdata[i] = (tbits >> t_bits) & jmask;
-    }
-  /* at least this vectorizes :) */
-  for ( i = 0; i < jlend; i++ )
-    fpdata[i] = fmin + zscale*fpdata[i];
-}
-
-static unsigned int mask[] = {0,1,3,7,15,31,63,127,255};
-static double shift[9] = {1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0};
-
-static 
-void decode_double_array_common2(unsigned char *igrib, long jlend, int NumBits, 
-				 double fmin, double zscale, double *fpdata)
-{
-  /* code from wgrib routine BDS_unpack */
-  unsigned char *bits = igrib;
-  long i;
-  int n_bits = NumBits;
-  int c_bits, j_bits;
-  double jj;
-
-  /* older unoptimized code, not often used */
-  c_bits = 8;
-  for ( i = 0; i < jlend; i++ )
-    {
-      jj = 0.0;
-      j_bits = n_bits;
-      while (c_bits <= j_bits)
-	{
-	  if (c_bits == 8)
-	    {
-	      jj = jj * 256.0  + (double) (*bits++);
-	      j_bits -= 8;
-	    }
-	  else
-	    {
-	      jj = (jj * shift[c_bits]) + (double) (*bits & mask[c_bits]);
-	      bits++;
-	      j_bits -= c_bits;
-	      c_bits = 8;
-	    }
-	}
-
-      if (j_bits)
-	{
-	  c_bits -= j_bits;
-	  jj = (jj * shift[j_bits]) + (double) ((*bits >> c_bits) & mask[j_bits]);
-	}
-      
-      fpdata[i] = fmin + zscale*jj;
-    }
-} 
-
-static 
-void decode_double_array(unsigned char *igrib, long jlend, int numBits, 
-			 double fmin, double zscale, double *fpdata)
-{
-  long i;
-  double dval;
-#if defined (VECTORCODE)
-  GRIBPACK *lgrib = NULL;
-
-  if ( numBits ==  8 || numBits == 16 ||
-       numBits == 24 || numBits == 32 )
-    {
-      long jlenc = jlend * numBits / 8;
-      if ( jlenc > 0 ) 
-	{
-	  lgrib = (GRIBPACK *) malloc(jlenc*sizeof(GRIBPACK));
-	  if ( lgrib == NULL ) SysError("No Memory!");
-
-	  (void) UNPACK_GRIB(igrib, lgrib, jlenc, -1L);
-	}
-    }
-
-  if ( numBits ==  0 )
-    {
-      for ( i = 0; i < jlend; i++ )
-	fpdata[i] = fmin;
-    }
-  else if ( numBits ==  8 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (int)lgrib[i];
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits == 16 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (((int)lgrib[2*i  ] <<  8) +  (int)lgrib[2*i+1]);
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits == 24 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (((int)lgrib[3*i  ] << 16) + ((int)lgrib[3*i+1] <<  8) +
-	  	 (int)lgrib[3*i+2]);
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits == 32 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (((unsigned int)lgrib[4*i  ] << 24) + ((unsigned int)lgrib[4*i+1] << 16) +
-		((unsigned int)lgrib[4*i+2] <<  8) +  (unsigned int)lgrib[4*i+3]);
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits <= 25 )
-    {
-      decode_double_array_common(igrib, jlend, numBits, fmin, zscale, fpdata);
-    }
-  else if ( numBits > 25 && numBits < 32 )
-    {
-      decode_double_array_common2(igrib, jlend, numBits, fmin, zscale, fpdata);
-    }
-  else
-    {
-      fprintf(stderr," Unimplemented packing factor %d!\n", numBits);
-      exit(EXIT_FAILURE);
-    }
-
-  if ( lgrib ) free(lgrib);
-
-#else
-  if ( numBits ==  0 )
-    {
-      for ( i = 0; i < jlend; i++ )
-	fpdata[i] = fmin;
-    }
-  else if ( numBits ==  8 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (int)igrib[i];
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits == 16 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (((int)igrib[2*i  ] <<  8) |  (int)igrib[2*i+1]);
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits == 24 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (((int)igrib[3*i  ] << 16) + ((int)igrib[3*i+1] <<  8) +
-		 (int)igrib[3*i+2]);
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits == 32 )
-    for ( i = 0; i < jlend; i++ )
-      {
-	dval = (((unsigned int)igrib[4*i  ] << 24) + ((unsigned int)igrib[4*i+1] << 16) +
-		((unsigned int)igrib[4*i+2] <<  8) +  (unsigned int)igrib[4*i+3]);
-	fpdata[i] = fmin + zscale * dval;
-      }
-  else if ( numBits <= 25 )
-    {
-      decode_double_array_common(igrib, jlend, numBits, fmin, zscale, fpdata);
-    }
-  else if ( numBits > 25 && numBits < 32 )
-    {
-      decode_double_array_common2(igrib, jlend, numBits, fmin, zscale, fpdata);
-    }
-  else
-    {
-      fprintf(stderr, "Unimplemented packing factor %d!\n", numBits);
-      exit(EXIT_FAILURE);
-    }
-#endif
-}
-
 static
 int decodeBDS(int decscale, unsigned char *bds, int *isec2, int *isec4, 
 	      double *fsec4, int fsec4len, int dfunc, int bdsLenIn, int numGridVals, int llarge, int *iret)
@@ -5577,7 +5845,7 @@ int decodeBDS(int decscale, unsigned char *bds, int *isec2, int *isec4,
   int lcompress;
   int jup, kup, mup;
   int locnd;
-  int jlend;
+  long jlend;
   long i;
   int bds_flag, jscale, imiss;
   int bds_ubits;
@@ -5800,11 +6068,11 @@ int decodeBDS(int decscale, unsigned char *bds, int *isec2, int *isec4,
 
   /* check length of output array. */
   
-  if ( jlend+ioff > fsec4len )
+  if ( ISEC4_NumValues > fsec4len )
     {
       *iret = 710;
       gprintf(__func__, " Output array too small. Length = %d", fsec4len);
-      gprintf(__func__, " Number of values = %d", jlend+ioff);
+      gprintf(__func__, " Number of values = %d", ISEC4_NumValues);
       gprintf(__func__, " Return code =  %d", *iret);
       return (0);
     }
@@ -5814,7 +6082,11 @@ int decodeBDS(int decscale, unsigned char *bds, int *isec2, int *isec4,
     {
       igrib += locnd;
 
-      decode_double_array(igrib, jlend, ISEC4_NumBits, fmin, zscale, fpdata);
+#if  defined  (_ARCH_PWR6)
+      decode_double_array_unrolled(igrib, jlend, ISEC4_NumBits, fmin, zscale, fpdata);
+#else
+      decode_double_array_byte    (igrib, jlend, ISEC4_NumBits, fmin, zscale, fpdata);
+#endif
     }
 
   if ( lspherc && lcomplex )
@@ -5830,7 +6102,7 @@ int decodeBDS(int decscale, unsigned char *bds, int *isec2, int *isec4,
     if ( lspherc && !lcomplex )
       {
         /* 20100705: Fix ZeroShiftError - Edi Kirk */
-	if ( fsec4[1] != 0.0 )
+	if ( IS_NOT_EQUAL(fsec4[1], 0.0) )
 	  {
 	    double zserr = fsec4[1];
 	    for ( i = 1; i < ISEC4_NumValues; i++ ) fsec4[i] -= zserr;
@@ -6155,7 +6427,8 @@ void gribDecode(int *isec0, int *isec1, int *isec2, double *fsec2, int *isec3,
 	}
 
       if ( dfunc == 'R' && *iret == -801 )
-	  gprintf(__func__, "Number of values (%d) and sum of lons per row (%d) differ, abort conversion to regular grid!", ISEC4_NumValues, nvalues);
+	  gprintf(__func__, "Number of values (%d) and sum of lons per row (%d) differ, abort conversion to regular grid!",
+		  ISEC4_NumValues, nvalues);
       
       if ( dfunc == 'R' && *iret != -801 )
 	{
@@ -6786,7 +7059,7 @@ double calculate_pfactor(const double* spectralField, long fieldTruncation, long
 
   for( loop = ismin; loop <= ismax; loop++ ) {
     norms[n] = norms[n] > zeps ? norms[n] : zeps;
-    if( norms[n] == zeps ) weights[n] = 100.0 * zeps;
+    if( IS_EQUAL(norms[n], zeps) ) weights[n] = 100.0 * zeps;
   }
 
   /*
@@ -8762,6 +9035,7 @@ int grib1Sections(unsigned char *gribbuffer, long bufsize, unsigned char **pdsp,
     {
       fprintf(stderr, "Missing end section >%2x %2x %2x %2x<\n",
 	      bufpointer[0], bufpointer[1], bufpointer[2], bufpointer[3]);
+      return (-2);
     }
 
   return (0);
@@ -8946,6 +9220,7 @@ int grib2Sections(unsigned char *gribbuffer, long bufsize, unsigned char **idsp,
     {
       fprintf(stderr, "Missing end section >%2x %2x %2x %2x<\n",
 	      section[0], section[1], section[2], section[3]);
+      return (-2);
     }
 
   return (0);
@@ -9095,7 +9370,7 @@ void grib1PrintALL(int nrec, long offset, long recpos, long recsize, unsigned ch
   bdslen = BDS_Len;
   bdslen = correct_bdslen(bdslen, recsize, bds-gribbuffer);
 
-  if ( (BDS_Flag >> 4)&1 && BDS_Z == 128 )
+  if ( ((BDS_Flag >> 4)&1) && (BDS_Z == 128 || BDS_Z == 130) )
     {
       int s1, s2;
       s1 = gribrec_len(bds[14], bds[15], bds[16]);
@@ -9421,7 +9696,7 @@ void grib1PrintBDS(int nrec, long recpos, long recsize, unsigned char *gribbuffe
   else
     level = PDS_Level1;
 
-  if ( (BDS_Flag >> 4)&1 && BDS_Z == 128 )
+  if ( ((BDS_Flag >> 4)&1) && BDS_Z == 128 )
     {
       int s1, s2;
       s1 = ((int) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
@@ -9490,7 +9765,7 @@ void gribCheck1(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
   else
     level = PDS_Level1;
 
-  if ( (BDS_Flag >> 4)&1 && BDS_Z == 128 )
+  if ( ((BDS_Flag >> 4)&1) && BDS_Z == 128 )
     {
       int s1, s2;
       s1 = ((int) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
@@ -9498,7 +9773,7 @@ void gribCheck1(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
       cr = ((double)s1)/s2;
     }
 
-  if ( cr == 1 && BDS_NumBits == 24 )
+  if ( IS_EQUAL(cr, 1) && BDS_NumBits == 24 )
     {
       fprintf(stdout, "GRIB record %5d : code = %4d   level = %7d\n", nrec, PDS_Parameter, level);
     }
@@ -9576,7 +9851,7 @@ void repair1(unsigned char *gbuf, long gbufsize)
 }
 
 
-void gribRepair1(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
+void gribRepair1(int nrec, long recsize, unsigned char *gribbuffer)
 {
   int level, nerr;
   unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
@@ -9596,7 +9871,7 @@ void gribRepair1(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
   else
     level = PDS_Level1;
 
-  if ( (BDS_Flag >> 4)&1 && BDS_Z == 128 )
+  if ( ((BDS_Flag >> 4)&1) && BDS_Z == 128 )
     {
       int s1, s2;
       s1 = ((int) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
@@ -9604,7 +9879,7 @@ void gribRepair1(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
       cr = ((double)s1)/s2;
     }
 
-  if ( cr == 1 && BDS_NumBits == 24 )
+  if ( IS_EQUAL(cr, 1) && BDS_NumBits == 24 )
     {
       fprintf(stdout, "Repair GRIB record %5d : code = %4d   level = %7d\n", nrec, PDS_Parameter, level);
       repair1(gribbuffer, recsize);
@@ -9617,16 +9892,25 @@ void gribRepair1(int nrec, long recpos, long recsize, unsigned char *gribbuffer)
 #  include "config.h"
 #endif
 
-#if  defined  (HAVE_LIBSZ)
+#if  defined (HAVE_LIBSZ) || defined (HAVE_LIBAEC)
 #if defined(__cplusplus)
 extern "C" {
 #endif
+#if defined (HAVE_LIBAEC)
+#  include <libaec.h>
+#else
 #  include <szlib.h>
+#endif
 #if defined (__cplusplus)
 }
 #endif
 
+#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)
 
@@ -9634,6 +9918,18 @@ extern "C" {
 #  define MIN_SIZE            (256)
 #endif
 
+#define  Z_SZIP  128
+#define  Z_AEC   130
+
+
+#define SetLen3(var, offset, value) ((var[offset+0] = 0xFF & (value >> 16)), \
+				     (var[offset+1] = 0xFF & (value >>  8)), \
+				     (var[offset+2] = 0xFF & (value      )))
+#define SetLen4(var, offset, value) ((var[offset+0] = 0xFF & (value >> 24)), \
+				     (var[offset+1] = 0xFF & (value >> 16)), \
+				     (var[offset+2] = 0xFF & (value >>  8)), \
+				     (var[offset+3] = 0xFF & (value      )))
+
 
 int gribGetZip(long recsize, unsigned char *gribbuffer, long *urecsize)
 {
@@ -9668,7 +9964,7 @@ int gribGetZip(long recsize, unsigned char *gribbuffer, long *urecsize)
   if ( lcompress )
     {
       compress = BDS_Z;
-      if ( compress == 128 )
+      if ( compress == Z_SZIP || compress == Z_AEC )
 	{
 	  gribsize = gribrec_len(bds[14], bds[15], bds[16]);
 	}
@@ -9686,7 +9982,7 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
   int gribLen;
   int rec_len;
   int llarge = FALSE;
-#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;
@@ -9699,28 +9995,35 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
   nerr = grib1Sections(dbuf, dbufsize, &pds, &gds, &bms, &bds);
   if ( nerr )
     {
-      fprintf(stdout, "grib1Sections error\n");
+      fprintf(stdout, "grib1Sections error!\n");
       return (rec_len);
     }
 
-#if  defined  (HAVE_LIBSZ)
+#if  defined (HAVE_LIBSZ) || defined (HAVE_LIBAEC)
 
   {
     long i;
     int bdsLen;
     int gribLenOld = 0;
     int status;
-    int datstart, datsize;
+    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 = 12;
+    int bds_zoffset, bds_zstart;
     unsigned char *pbuf = NULL;
 
-    if ( llarge ) bds_zoffset = 14;
+    bds_zstart  = 14;
+    bds_zoffset = 12;
+    if ( llarge ) bds_zoffset += 2;
 
     bds_len   = BDS_Len;
     bds_len   = correct_bdslen(bds_len, gribLen, bds-dbuf);
@@ -9741,16 +10044,26 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
 	  }
 	return (rec_len);
       }
-    
-    sz_param.options_mask        = OPTIONS_MASK;
 
+#if defined (HAVE_LIBSZ)
     if ( bds_nbits == 24 )
-      sz_param.bits_per_pixel    = 8;
+      bits_per_sample    = 8;
     else
-      sz_param.bits_per_pixel    = bds_nbits;
-
+#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 ( lspherc )
       {
@@ -9781,6 +10094,7 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
     source = bds + datstart;
     dest = sbuf;
 
+#if defined (HAVE_LIBSZ)
     if ( bds_nbits == 24 )
       {
 	long nelem;
@@ -9794,7 +10108,23 @@ 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);
+      }
 
+    destLen = strm.total_out;
+#else
     status = SZ_BufftoBuffCompress(dest, &destLen, source, sourceLen, &sz_param);
     if ( status != SZ_OK )
       {
@@ -9809,12 +10139,12 @@ 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);
     /*
     fprintf(stderr, "sourceLen, destLen %d %d\n", sourceLen, destLen);
     */
-    
     if ( destLen < MIN_COMPRESS*sourceLen )
       {
 	source = bds + datstart + bds_zoffset;
@@ -9835,7 +10165,7 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
 	*/
 	/*	memcpy(bds + datstart + bds_zoffset, source, destLen); */
 	/*
-    fprintf(stderr, "z>>> %d %d %d %d <<<\n", (int) bds[0+datstart+bds_zoffset],
+	  fprintf(stderr, "z>>> %d %d %d %d <<<\n", (int) bds[0+datstart+bds_zoffset],
 	    (int)bds[1+datstart+bds_zoffset], (int)bds[2+datstart+bds_zoffset], (int)bds[3+datstart+bds_zoffset]);
 	*/
 	if ( llarge )
@@ -9847,40 +10177,27 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
 	      }
 	    gribLenOld = gribLenOld / (-120);
 	    gribLenOld = JP23SET - gribLenOld + 1;
-	    bds[14] = 0xFF & (gribLenOld >> 16);
-	    bds[15] = 0xFF & (gribLenOld >>  8);
-	    bds[16] = 0xFF & (gribLenOld);
-
-	    bds[17] = 0xFF & (sourceLen >> 24);
-	    bds[18] = 0xFF & (sourceLen >> 16);
-	    bds[19] = 0xFF & (sourceLen >>  8);
-	    bds[20] = 0xFF & (sourceLen);
-
-	    bds[21] = 0xFF & (destLen >> 24);
-	    bds[22] = 0xFF & (destLen >> 16);
-	    bds[23] = 0xFF & (destLen >>  8);
-	    bds[24] = 0xFF & (destLen);
+
+	    SetLen3(bds, bds_zstart, gribLenOld);
+	    SetLen4(bds, bds_zstart+3, sourceLen);
+	    SetLen4(bds, bds_zstart+7, destLen);
 	  }
 	else
 	  {
-	    bds[14] = 0xFF & (gribLenOld >> 16);
-	    bds[15] = 0xFF & (gribLenOld >>  8);
-	    bds[16] = 0xFF & (gribLenOld);
-
-	    bds[17] = 0xFF & (sourceLen >> 16);
-	    bds[18] = 0xFF & (sourceLen >>  8);
-	    bds[19] = 0xFF & (sourceLen);
-
-	    bds[20] = 0xFF & (destLen >> 16);
-	    bds[21] = 0xFF & (destLen >>  8);
-	    bds[22] = 0xFF & (destLen);
+	    SetLen3(bds, bds_zstart, gribLenOld);
+	    SetLen3(bds, bds_zstart+3, sourceLen);
+	    SetLen3(bds, bds_zstart+6, destLen);
 	  }
 
 	bdsLen = datstart + bds_zoffset + destLen;
 
 	bds[11] = 0;
 	bds[12] = 0;
-	BDS_Z   = 128;
+#if defined (HAVE_LIBAEC)
+	BDS_Z   = Z_AEC;
+#else
+	BDS_Z   = Z_SZIP;
+#endif
 
 	BDS_Flag += 16;
 	if ( (bdsLen%2) == 1 )
@@ -9889,9 +10206,7 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
 	    bds[bdsLen++] = 0;
 	  }
 
-	bds[0] = 0xFF & (bdsLen >> 16);
-	bds[1] = 0xFF & (bdsLen >>  8);
-	bds[2] = 0xFF & (bdsLen);
+	SetLen3(bds, 0, bdsLen);
 
 	gribLen = (bds - dbuf) + bdsLen;
 
@@ -9918,23 +10233,20 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
 	    itemp = gribLen / (-120);
 	    itemp = JP23SET - itemp + 1;
 
-	    dbuf[4] = 0xFF & (itemp >> 16);
-	    dbuf[5] = 0xFF & (itemp >>  8);
-	    dbuf[6] = 0xFF & (itemp);
+	    SetLen3(dbuf, 4, itemp);
 
 	    bdslen = gribLen - bdslen;
 
-	    bds[0] = 0xFF & (bdsLen >> 16);
-	    bds[1] = 0xFF & (bdsLen >>  8);
-	    bds[2] = 0xFF & (bdsLen);
+	    SetLen3(bds, 0, bdslen);
 	  }
 	else
 	  {
-	    dbuf[4] = 0xFF & (gribLen >> 16);
-	    dbuf[5] = 0xFF & (gribLen >>  8);
-	    dbuf[6] = 0xFF & (gribLen);
+	    SetLen3(dbuf, 4, gribLen);
 	  }
       }
+    else
+      {
+      }
     /*
     fprintf(stderr, "%3d %3d griblen in %6d  out %6d  CR %g   slen %6d dlen %6d  CR %g\n",
 	    PDS_Parameter, PDS_Level1, gribLenOld, gribLen,
@@ -9946,12 +10258,15 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
 #else
   if ( libszwarn )
     {
-      Warning("Compression disabled, szlib not available!");
+      Warning("Compression disabled, szlib or libaec not available!");
       libszwarn = 0;
     }
 #endif
 
-  while ( gribLen & 7 ) dbuf[gribLen++] = 0;
+  if ( llarge )
+    while ( gribLen%120 ) dbuf[gribLen++] = 0;
+  else
+    while ( gribLen & 7 ) dbuf[gribLen++] = 0;
 
   rec_len = gribLen;
 
@@ -9961,18 +10276,18 @@ int  gribZip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbufs
 
 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
   int nerr;
   unsigned char *pds = NULL, *gds = NULL, *bms = NULL, *bds = NULL;
   int bdsLen, recLen, gribLen = 0;
-  char *dest, *source;
+  unsigned char *dest, *source;
   size_t destLen, sourceLen;
   int /* bds_len, */ bds_nbits, bds_flag, lspherc, lcomplex /*, lcompress*/;
   int bds_head = 11;
   int bds_ext = 0;
-  int bds_zoffset = 12;
+  int bds_zoffset, bds_zstart;
   int datstart = 0;
   int llarge = FALSE;
 
@@ -9983,10 +10298,13 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
       return (0);
     }
 
-  recLen = gribrec_len(bds[14], bds[15], bds[16]);
+  bds_zstart = 14;
+
+  recLen = gribrec_len(bds[bds_zstart], bds[bds_zstart+1], bds[bds_zstart+2]);
   if ( recLen > JP23SET ) llarge = TRUE;
 
-  if ( llarge ) bds_zoffset = 14;
+  bds_zoffset = 12;
+  if ( llarge ) bds_zoffset += 2;
 
   /* bds_len   = BDS_Len; */
   bds_nbits = BDS_NumBits;
@@ -10012,7 +10330,7 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
 
   datstart = bds_head + bds_ext;
 
-  source = (char *) 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
@@ -10025,8 +10343,8 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
       return (0);
     }
 
-  dest = (char *) bds + datstart;
-  if ( llarge )
+  dest = bds + datstart;
+   if ( llarge )
     destLen = ((size_t) ((bds[17]<<24)+(bds[18]<<16)+(bds[19]<<8)+bds[20]));
   else
     destLen = ((size_t) ((bds[17]<<16)+(bds[18]<<8)+bds[19]));
@@ -10035,23 +10353,38 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
 
   bdsLen = datstart + destLen;
 
-#if  defined  (HAVE_LIBSZ)
+#if  defined (HAVE_LIBSZ) || defined (HAVE_LIBAEC)
   {
     int status;
     long i;
     size_t tmpLen;
     int bds_ubits;
+    int bits_per_sample;
+#if defined (HAVE_LIBAEC)
+    struct aec_stream strm;
+#else
     SZ_com_t sz_param;          /* szip parameter block */
+#endif
 
-    sz_param.options_mask        = OPTIONS_MASK;
-
+#if defined (HAVE_LIBSZ)
     if ( bds_nbits == 24 )
-      sz_param.bits_per_pixel    = 8;
+      bits_per_sample    = 8;
     else
-      sz_param.bits_per_pixel    = bds_nbits;
-
+#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 ( i = 0; i < bds_ext; ++i )
@@ -10064,6 +10397,18 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
     */
 
     tmpLen = destLen;
+#if defined (HAVE_LIBAEC)
+    strm.next_in   = source;
+    strm.avail_in  = sourceLen;
+    strm.next_out  = dest;
+    strm.avail_out = tmpLen;
+
+    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 )
       {
@@ -10078,6 +10423,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);
@@ -10085,7 +10431,8 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
     if ( tmpLen != destLen )
       Warning("unzip size differ: code %3d level %3d  ibuflen %ld ubuflen %ld",
 	      PDS_Parameter, PDS_Level2, (long) destLen, (long) tmpLen);
- 
+
+#if defined (HAVE_LIBSZ)
     if ( bds_nbits == 24 )
       {
 	long nelem;
@@ -10101,7 +10448,8 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
 	memcpy(dest, pbuf, tmpLen);
 	free(pbuf);
       }
-  
+#endif
+
     bds_ubits = BDS_Flag & 15;
     BDS_Flag -= bds_ubits;
 
@@ -10111,9 +10459,7 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
 	bds[bdsLen++] = 0;
       }
 
-    bds[0] = 0xFF & (bdsLen >> 16);
-    bds[1] = 0xFF & (bdsLen >>  8);
-    bds[2] = 0xFF & (bdsLen);
+    SetLen3(bds, 0, bdsLen);
 
     gribLen = (bds - dbuf) + bdsLen;
     
@@ -10142,26 +10488,23 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
 	itemp = gribLen / (-120);
 	itemp = JP23SET - itemp + 1;
 	
-	dbuf[4] = 0xFF & (itemp >> 16);
-	dbuf[5] = 0xFF & (itemp >>  8);
-	dbuf[6] = 0xFF & (itemp);
-	
+	SetLen3(dbuf, 4, itemp);
+
 	bdsLen = gribLen - bdsLen;
 	    
-	bds[0] = 0xFF & (bdsLen >> 16);
-	bds[1] = 0xFF & (bdsLen >>  8);
-	bds[2] = 0xFF & (bdsLen);
+	SetLen3(bds, 0, bdsLen);
       }
     else
       {
-	dbuf[4] = 0xFF & (recLen >> 16);
-	dbuf[5] = 0xFF & (recLen >>  8);
-	dbuf[6] = 0xFF & (recLen);
+	SetLen3(dbuf, 4, recLen);
       }
     /*
     fprintf(stderr, "recLen, gribLen, bdsLen %d %d %d\n", recLen, gribLen, bdsLen);
     */
-    while ( gribLen & 7 ) dbuf[gribLen++] = 0;
+    if ( llarge )
+      while ( gribLen%120 ) dbuf[gribLen++] = 0;
+    else
+      while ( gribLen & 7 ) dbuf[gribLen++] = 0;
     /*
     fprintf(stderr, "recLen, gribLen, bdsLen %d %d %d\n", recLen, gribLen, bdsLen);
     */
@@ -10169,14 +10512,14 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
 #else
   if ( libszwarn )
     {
-      Warning("Decompression disabled, szlib not available!");
+      Warning("Decompression disabled, szlib or libaec not available!");
       libszwarn = 0;
     }
 #endif
 
   return (gribLen);
 }
-static const char grb_libvers[] = "1.5.6" " of ""Dec 17 2012"" ""13:44:05";
+static const char grb_libvers[] = "1.6.0" " of ""Mar  5 2013"" ""11:10:25";
 const char *
 cgribexLibraryVersion(void)
 {
diff --git a/libcdi/src/config.h.in b/libcdi/src/config.h.in
index c51482d..c2bd546 100644
--- a/libcdi/src/config.h.in
+++ b/libcdi/src/config.h.in
@@ -10,6 +10,9 @@
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #undef HAVE_DLFCN_H
 
+/* Define to 1 if you have the `getline' function. */
+#undef HAVE_GETLINE
+
 /* Define to 1 if you have the `getpagesize' function. */
 #undef HAVE_GETPAGESIZE
 
diff --git a/libcdi/src/extralib.c b/libcdi/src/extralib.c
index 30b535f..613bbf2 100644
--- a/libcdi/src/extralib.c
+++ b/libcdi/src/extralib.c
@@ -96,6 +96,7 @@ void extLibInit()
 	      }
 	    default:
 	      Message("Invalid character in %s: %s", envName, envString);
+	      break;
 	    }
 	}
     }
@@ -291,6 +292,7 @@ int extInqData(void *ext, int prec, void *data)
     default:
       {
 	Error("unexpected data precision %d", rprec);
+        break;
       }
     }
 
@@ -374,6 +376,7 @@ int extDefData(void *ext, int prec, const void *data)
     default:
       {
 	Error("unexpected data precision %d", rprec);
+        break;
       }
     }
 
@@ -449,6 +452,7 @@ int extRead(int fileID, void *ext)
     default:
       {
 	Error("unexpected header precision %d", hprec);
+        break;
       }
     }
 
@@ -557,6 +561,7 @@ int extWrite(int fileID, void *ext)
     default:
       {
 	Error("unexpected header precision %d", rprec);
+        break;
       }
     }
   
@@ -587,6 +592,7 @@ int extWrite(int fileID, void *ext)
     default:
       {
 	Error("unexpected data precision %d", rprec);
+        break;
       }
     }
 
diff --git a/libcdi/src/gribapi.c b/libcdi/src/gribapi.c
index c037c29..4692671 100644
--- a/libcdi/src/gribapi.c
+++ b/libcdi/src/gribapi.c
@@ -36,13 +36,10 @@ const char *gribapiLibraryVersion(void)
 }
 
 
-void gribContainersNew(int streamID)
+void gribContainersNew(stream_t * streamptr)
 {
-  stream_t *streamptr;
   int editionNumber = 2;
 
-  streamptr = stream_to_pointer(streamID);
-
   if ( streamptr->filetype == FILETYPE_GRB ) editionNumber = 1;
 
 #if  defined  (HAVE_LIBCGRIBEX)
@@ -87,12 +84,8 @@ void gribContainersNew(int streamID)
 }
 
 
-void gribContainersDelete(int streamID)
+void gribContainersDelete(stream_t * streamptr)
 {
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
   if ( streamptr->gribContainers )
     {
       int nvars = streamptr->nvars;
diff --git a/libcdi/src/gribapi.h b/libcdi/src/gribapi.h
index 8d59aad..080e39d 100644
--- a/libcdi/src/gribapi.h
+++ b/libcdi/src/gribapi.h
@@ -5,6 +5,9 @@
 
 /* GRIB2 Level Types */
 #define  GRIB2_LTYPE_SURFACE               1
+#define  GRIB2_LTYPE_CLOUDBASE             2
+#define  GRIB2_LTYPE_CLOUDTOP              3
+#define  GRIB2_LTYPE_ISOTHERM0             4
 #define  GRIB2_LTYPE_TOA                   8
 #define  GRIB2_LTYPE_SEA_BOTTOM            9
 #define  GRIB2_LTYPE_ATMOSPHERE           10
@@ -34,8 +37,8 @@
 #define  GRIB2_GTYPE_NUMBER              101  /*  General Unstructured Grid                */
 
 const char *gribapiLibraryVersion(void);
-void gribContainersNew(int streamID);
-void gribContainersDelete(int streamID);
+void gribContainersNew(stream_t * streamptr);
+void gribContainersDelete(stream_t * streamptr);
 void *gribHandleNew(int editionNumber);
 void gribHandleDelete(void *gh);
 
diff --git a/libcdi/src/grid.c b/libcdi/src/grid.c
index d79e111..6b6c014 100644
--- a/libcdi/src/grid.c
+++ b/libcdi/src/grid.c
@@ -2198,9 +2198,10 @@ void grid_check_cyclic(grid_t *gridptr)
       if ( xvals && xsize > 1 )
         {
           xinc = xvals[1] - xvals[0];
-          if ( IS_EQUAL(xinc, 0) )
-            xinc = (xvals[xsize-1] - xvals[0])/(xsize-1);
+          if ( IS_EQUAL(xinc, 0) ) xinc = (xvals[xsize-1] - xvals[0])/(xsize-1);
+
           x0 = 2*xvals[xsize-1]-xvals[xsize-2]-360;
+
           if ( IS_NOT_EQUAL(xvals[0], xvals[xsize-1]) )
             if ( fabs(x0 - xvals[0]) < 0.01*xinc ) gridptr->isCyclic = TRUE;
         }
@@ -2228,6 +2229,7 @@ void grid_check_cyclic(grid_t *gridptr)
 	      if ( valn <    1 && val1 > 300 ) valn += 360;
 	      if ( val1 < -179 && valn > 120 ) val1 += 360;
 	      if ( valn < -179 && val1 > 120 ) valn += 360;
+              if ( fabs(valn-val1) > 180 ) val1 += 360;
 
               if ( valn > val1 ) x0 = valn - xinc;
               else               x0 = valn + xinc;
@@ -2259,6 +2261,7 @@ void grid_check_cyclic(grid_t *gridptr)
 		      if ( val2 <    1 && val1 > 300 ) val2 += 360;
 		      if ( val1 < -179 && val2 > 120 ) val1 += 360;
 		      if ( val2 < -179 && val1 > 120 ) val2 += 360;
+                      if ( fabs(val2-val1) > 180 ) val1 += 360;
 
 		      if ( fabs(val1-val2) < 0.001 )
 			{
@@ -2545,37 +2548,36 @@ int gridCompareP ( void * gridptr1, void * gridptr2 )
   if ( g1->rowlon )
     {
       for ( i = 0; i < g1->nrowlon; i++ )
-	if ( g1->rowlon[i] != g2->rowlon[i] ) return differ; 
-    } 
+	if ( g1->rowlon[i] != g2->rowlon[i] ) return differ;
+    }
   else if ( g2->rowlon )
     return differ;
 
-  if ( g1->xfirst        != g2->xfirst        ) return differ;       
-  if ( g1->yfirst	 != g2->yfirst        ) return differ;
-  if ( g1->xlast         != g2->xlast         ) return differ;
-  if ( g1->ylast         != g2->ylast         ) return differ;
-  if ( g1->xinc	         != g2->xinc          ) return differ;
-  if ( g1->yinc	         != g2->yinc          ) return differ;
-  if ( g1->lcc_originLon != g2->lcc_originLon ) return differ;         
-  if ( g1->lcc_originLat != g2->lcc_originLat ) return differ;
-  if ( g1->lcc_lonParY   != g2->lcc_lonParY   ) return differ;
-  if ( g1->lcc_lat1      != g2->lcc_lat1      ) return differ;
-  if ( g1->lcc_lat2      != g2->lcc_lat2      ) return differ;
-  if ( g1->lcc_xinc      != g2->lcc_xinc      ) return differ;
-  if ( g1->lcc_yinc      != g2->lcc_yinc      ) return differ;
-  if ( g1->lcc2_lon_0    != g2->lcc2_lon_0    ) return differ;         
-  if ( g1->lcc2_lat_0    != g2->lcc2_lat_0    ) return differ;
-  if ( g1->lcc2_lat_1    != g2->lcc2_lat_1    ) return differ;
-  if ( g1->lcc2_lat_2    != g2->lcc2_lat_2    ) return differ;
-  if ( g1->lcc2_a        != g2->lcc2_a        ) return differ;
-  if ( g1->laea_lon_0    != g2->laea_lon_0    ) return differ;         
-  if ( g1->laea_lat_0    != g2->laea_lat_0    ) return differ;
-  if ( g1->laea_a        != g2->laea_a        ) return differ;
-  if ( g1->xpole         != g2->xpole         ) return differ;
-  if ( g1->ypole         != g2->ypole         ) return differ;
-  if ( g1->angle         != g2->angle         ) return differ; 
+  if ( IS_NOT_EQUAL(g1->xfirst        , g2->xfirst)        ) return differ;
+  if ( IS_NOT_EQUAL(g1->yfirst	      , g2->yfirst)        ) return differ;
+  if ( IS_NOT_EQUAL(g1->xlast         , g2->xlast)         ) return differ;
+  if ( IS_NOT_EQUAL(g1->ylast         , g2->ylast)         ) return differ;
+  if ( IS_NOT_EQUAL(g1->xinc	      , g2->xinc)          ) return differ;
+  if ( IS_NOT_EQUAL(g1->yinc	      , g2->yinc)          ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc_originLon , g2->lcc_originLon) ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc_originLat , g2->lcc_originLat) ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc_lonParY   , g2->lcc_lonParY)   ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc_lat1      , g2->lcc_lat1)      ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc_lat2      , g2->lcc_lat2)      ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc_xinc      , g2->lcc_xinc)      ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc_yinc      , g2->lcc_yinc)      ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc2_lon_0    , g2->lcc2_lon_0)    ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc2_lat_0    , g2->lcc2_lat_0)    ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc2_lat_1    , g2->lcc2_lat_1)    ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc2_lat_2    , g2->lcc2_lat_2)    ) return differ;
+  if ( IS_NOT_EQUAL(g1->lcc2_a        , g2->lcc2_a)        ) return differ;
+  if ( IS_NOT_EQUAL(g1->laea_lon_0    , g2->laea_lon_0)    ) return differ;
+  if ( IS_NOT_EQUAL(g1->laea_lat_0    , g2->laea_lat_0)    ) return differ;
+  if ( IS_NOT_EQUAL(g1->laea_a        , g2->laea_a)        ) return differ;
+  if ( IS_NOT_EQUAL(g1->xpole         , g2->xpole)         ) return differ;
+  if ( IS_NOT_EQUAL(g1->ypole         , g2->ypole)         ) return differ;
+  if ( IS_NOT_EQUAL(g1->angle         , g2->angle)         ) return differ;
 
-  
   if ( g1->xvals )
     {
       if ( g1->type == GRID_UNSTRUCTURED || g1->type == GRID_CURVILINEAR )
@@ -2587,11 +2589,11 @@ int gridCompareP ( void * gridptr1, void * gridptr2 )
       if ( !g2->xvals ) return differ;
 
       for ( i = 0; i < size; i++ )
-	if ( g1->xvals[i] != g2->xvals[i] ) return differ; 
-    } 
+	if ( IS_NOT_EQUAL(g1->xvals[i], g2->xvals[i]) ) return differ;
+    }
   else if ( g2->xvals )
     return differ;
-  
+
   if ( g1->yvals )
     {
       if ( g1->type == GRID_UNSTRUCTURED || g1->type == GRID_CURVILINEAR )
@@ -2603,11 +2605,11 @@ int gridCompareP ( void * gridptr1, void * gridptr2 )
       if ( !g2->yvals ) return differ;
 
       for ( i = 0; i < size; i++ )
-	  if ( g1->yvals[i] != g2->yvals[i] ) return differ;
-    } 
+        if ( IS_NOT_EQUAL(g1->yvals[i], g2->yvals[i]) ) return differ;
+    }
   else if ( g2->yvals )
     return differ;
-  
+
   if ( g1->area )
     {
       xassert ( g1->size );
@@ -2615,8 +2617,8 @@ int gridCompareP ( void * gridptr1, void * gridptr2 )
       if ( !g2->area ) return differ;
 
       for ( i = 0; i < g1->size; i++ )
-	if ( g1->area[i] != g2->area[i] ) return differ;
-    } 
+	if ( IS_NOT_EQUAL(g1->area[i], g2->area[i]) ) return differ;
+    }
   else if ( g2->area )
     return differ;
 
@@ -2632,8 +2634,8 @@ int gridCompareP ( void * gridptr1, void * gridptr2 )
       if ( !g2->xbounds ) return differ;
 
       for ( i = 0; i < size; i++ )
-	if ( g1->xbounds[i] != g2->xbounds[i] ) return differ;
-    } 
+	if ( IS_NOT_EQUAL(g1->xbounds[i], g2->xbounds[i]) ) return differ;
+    }
   else if ( g2->xbounds )
     return differ;
 
@@ -2649,34 +2651,25 @@ int gridCompareP ( void * gridptr1, void * gridptr2 )
       if ( !g2->ybounds ) return differ;
 
       for ( i = 0; i < size; i++ )
-	if ( g1->ybounds[i] != g2->ybounds[i] ) return differ;
-    } 
+	if ( IS_NOT_EQUAL(g1->ybounds[i], g2->ybounds[i]) ) return differ;
+    }
   else if ( g2->ybounds )
     return differ;
 
-  if ( memcmp ( &g1->xname    ,&g2->xname    ,CDI_MAX_NAME )) 
-    return differ;
-  if ( memcmp ( &g1->yname    ,&g2->yname    ,CDI_MAX_NAME )) 
-    return differ;
-  if ( memcmp ( &g1->xlongname,&g2->xlongname,CDI_MAX_NAME )) 
-    return differ;
-  if ( memcmp ( &g1->ylongname,&g2->ylongname,CDI_MAX_NAME )) 
-    return differ;
-  if ( memcmp ( &g1->xstdname ,&g2->xstdname ,CDI_MAX_NAME )) 
-    return differ;
-  if ( memcmp ( &g1->ystdname ,&g2->ystdname ,CDI_MAX_NAME )) 
-    return differ;
-  if ( memcmp ( &g1->xunits   ,&g2->xunits   ,CDI_MAX_NAME )) 
-    return differ;
-  if ( memcmp ( &g1->yunits   ,&g2->yunits   ,CDI_MAX_NAME )) 
-    return differ; 
+  if ( memcmp ( &g1->xname    ,&g2->xname    ,CDI_MAX_NAME ) ) return differ;
+  if ( memcmp ( &g1->yname    ,&g2->yname    ,CDI_MAX_NAME ) ) return differ;
+  if ( memcmp ( &g1->xlongname,&g2->xlongname,CDI_MAX_NAME ) ) return differ;
+  if ( memcmp ( &g1->ylongname,&g2->ylongname,CDI_MAX_NAME ) ) return differ;
+  if ( memcmp ( &g1->xstdname ,&g2->xstdname ,CDI_MAX_NAME ) ) return differ;
+  if ( memcmp ( &g1->ystdname ,&g2->ystdname ,CDI_MAX_NAME ) ) return differ;
+  if ( memcmp ( &g1->xunits   ,&g2->xunits   ,CDI_MAX_NAME ) ) return differ;
+  if ( memcmp ( &g1->yunits   ,&g2->yunits   ,CDI_MAX_NAME ) ) return differ;
 
   if ( g1->reference )
     {
       if ( !g2->reference ) return differ;
       size = strlen ( g1->reference ) + 1;
-      if ( memcmp ( g1->reference, g2->reference, size )) 
-	return differ;
+      if ( memcmp ( g1->reference, g2->reference, size ) ) return differ;
     }
   else if ( g2->reference )
     return differ;
@@ -2685,8 +2678,7 @@ int gridCompareP ( void * gridptr1, void * gridptr2 )
     {
       xassert ( g1->size );
       if ( !g2->mask ) return differ;
-      if ( memcmp ( g1->mask, g2->mask, g1->size * sizeof ( unsigned char ))) 
-	return differ;
+      if ( memcmp ( g1->mask, g2->mask, g1->size*sizeof(unsigned char)) ) return differ;
     }
   else if ( g2->mask )
     return differ;
@@ -2695,8 +2687,7 @@ int gridCompareP ( void * gridptr1, void * gridptr2 )
     {
       xassert ( g1->size );
       if ( !g2->mask_gme ) return differ;
-      if ( memcmp ( g1->mask_gme, g2->mask_gme, 
-		    g1->size * sizeof ( unsigned char ))) return differ;
+      if ( memcmp ( g1->mask_gme, g2->mask_gme, g1->size*sizeof(unsigned char)) ) return differ;
     }
   else if ( g2->mask_gme )
     return differ;
@@ -3437,7 +3428,7 @@ void gridPrintKernel(grid_t * gridptr, int opt, FILE *fp)
   int nbyte0, nbyte;
   int i;
   int nvertex, iv;
-  char uuid[17];
+  char uuidOfHGrid[17];
   int gridID = gridptr->self;
   const double *area    = gridInqAreaPtr(gridID);
   const double *xvals   = gridInqXvalsPtr(gridID);
@@ -3504,7 +3495,7 @@ void gridPrintKernel(grid_t * gridptr, int opt, FILE *fp)
 
 	if ( type == GRID_LAEA )
 	  {
-	    double a, lon_0, lat_0;
+	    double a = 0, lon_0 = 0, lat_0 = 0;
 	    gridInqLaea(gridID, &a, &lon_0, &lat_0);
 	    fprintf(fp, "a         = %g\n", a);
 	    fprintf(fp, "lon_0     = %g\n", lon_0);
@@ -3513,7 +3504,7 @@ void gridPrintKernel(grid_t * gridptr, int opt, FILE *fp)
 
 	if ( type == GRID_LCC2 )
 	  {
-	    double a, lon_0, lat_0, lat_1, lat_2;
+	    double a = 0, lon_0 = 0, lat_0 = 0, lat_1 = 0, lat_2 = 0;
 	    gridInqLcc2(gridID, &a, &lon_0, &lat_0, &lat_1, &lat_2);
 	    fprintf(fp, "a         = %g\n", a);
 	    fprintf(fp, "lon_0     = %g\n", lon_0);
@@ -3533,8 +3524,8 @@ void gridPrintKernel(grid_t * gridptr, int opt, FILE *fp)
 	  {
 	    double xfirst = 0.0, xinc = 0.0;
 
-	    if ( type == GRID_LONLAT     || type == GRID_GAUSSIAN || 
-		 type == GRID_GENERIC    || type == GRID_LCC2     || 
+	    if ( type == GRID_LONLAT     || type == GRID_GAUSSIAN ||
+		 type == GRID_GENERIC    || type == GRID_LCC2     ||
                  type == GRID_SINUSOIDAL || type == GRID_LAEA )
 	      {
 		xfirst = gridInqXval(gridID, 0);
@@ -3666,8 +3657,8 @@ void gridPrintKernel(grid_t * gridptr, int opt, FILE *fp)
       }
     case GRID_LCC:
       {
-	double originLon, originLat, lonParY, lat1, lat2, xincm, yincm;
-	int projflag, scanflag;
+	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);
 
@@ -3706,14 +3697,16 @@ void gridPrintKernel(grid_t * gridptr, int opt, FILE *fp)
       }
     case GRID_REFERENCE:
       {
-        const unsigned char *d;
+        // const unsigned char *d;
 	fprintf(fp, "number    = %d\n", gridInqNumber(gridID));
 	fprintf(fp, "position  = %d\n", gridInqPosition(gridID));
-        gridInqUUID(gridID, uuid);
-        d = (unsigned char *) &uuid;
+        /*
+        gridInqUUID(gridID, uuidOfHGrid);
+        d = (unsigned char *) &uuidOfHGrid;
 	fprintf(fp, "uuid      = %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", 
                 d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
                 d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
+        */
 	if ( gridInqReference(gridID, NULL) )
 	  {
 	    char reference_link[8192];
@@ -3725,9 +3718,19 @@ void gridPrintKernel(grid_t * gridptr, int opt, FILE *fp)
    default:
       {
 	fprintf(stderr, "Unsupported grid type: %s\n", gridNamePtr(type));
+        break;
       }
     }
 
+  gridInqUUID(gridID, uuidOfHGrid);
+  if ( uuidOfHGrid[0] != 0 )
+    {
+      char uuidOfHGridStr[37];
+      uuid2str(uuidOfHGrid, uuidOfHGridStr);
+      if ( uuidOfHGridStr[0] != 0 && strlen(uuidOfHGridStr) == 36 )
+        fprintf(fp, "uuid      = %s\n", uuidOfHGridStr);
+    }
+
   if ( gridptr->mask )
     {
       nbyte0 = fprintf(fp, "mask      = ");
diff --git a/libcdi/src/grid.h b/libcdi/src/grid.h
index 83748a9..f44a984 100644
--- a/libcdi/src/grid.h
+++ b/libcdi/src/grid.h
@@ -73,6 +73,8 @@ grid_t;
 void grid_init(grid_t *gridptr);
 void grid_free(grid_t *gridptr);
 
+int gridSize(void);
+
 const double *gridInqXvalsPtr(int gridID);
 const double *gridInqYvalsPtr(int gridID);
 
@@ -83,7 +85,7 @@ const double *gridInqAreaPtr(int gridID);
 int gridCompare(int gridID, grid_t grid);
 int gridGenerate(grid_t grid);
 
-void     gridGetIndexList    ( int, int * );
+void gridGetIndexList( int, int * );
 
 #endif
 /*
diff --git a/libcdi/src/ieglib.c b/libcdi/src/ieglib.c
index 6cfca94..5962468 100644
--- a/libcdi/src/ieglib.c
+++ b/libcdi/src/ieglib.c
@@ -76,6 +76,7 @@ void iegLibInit()
 	      }
 	    default:
 	      Message("Invalid character in %s: %s", envName, envString);
+	      break;
 	    }
 	  pos += 2;
 	}
@@ -275,6 +276,7 @@ int iegInqData(iegrec_t *iegp, int prec, void *data)
     default:
       {
 	Error("unexpected data precision %d", dprec);
+        break;
       }
     }
 
@@ -354,6 +356,7 @@ int iegDefData(iegrec_t *iegp, int prec, const void *data)
     default:
       {
 	Error("unexpected data precision %d", dprec);
+        break;
       }
     }
 
@@ -592,6 +595,7 @@ int iegWrite(int fileID, iegrec_t *iegp)
     default:
       {
 	Error("unexpected data precision %d", dprec);
+        break;
       }
     }
 
diff --git a/libcdi/src/model.c b/libcdi/src/model.c
index fbf3137..c0f3241 100644
--- a/libcdi/src/model.c
+++ b/libcdi/src/model.c
@@ -183,9 +183,9 @@ int modelInq(int instID, int modelgribID, char *name)
                   if ( modelptr->name )
                     {
                       len = strlen(modelptr->name);
-                      if ( memcmp(modelptr->name, name, len) == 0 ) break;
+                      if ( strncmp(modelptr->name, name, len) == 0 ) break;
                       len = strlen(name);
-                      if ( memcmp(modelptr->name, name, len) == 0 ) break;
+                      if ( strncmp(modelptr->name, name, len) == 0 ) break;
                     }
                 }
             }
diff --git a/libcdi/src/pio_dbuffer.c b/libcdi/src/pio_dbuffer.c
index 95b85f3..a329d70 100644
--- a/libcdi/src/pio_dbuffer.c
+++ b/libcdi/src/pio_dbuffer.c
@@ -1,9 +1,11 @@
-#define _XOPEN_SOURCE 600
-
 #ifdef HAVE_CONFIG_H
 #  include "config.h"
 #endif
 
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 600
+#endif
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdbool.h>
diff --git a/libcdi/src/pio_util.c b/libcdi/src/pio_util.c
index 1465471..3947e9d 100644
--- a/libcdi/src/pio_util.c
+++ b/libcdi/src/pio_util.c
@@ -18,8 +18,8 @@ char commands[][13] = { "FINALIZE\0",
                         "WRITETS\0"};
 
 
-void pcdiAssert   ( bool assumption, const char * filename,
-                    const char * functionname, int line )
+void pcdiAssert(bool assumption,
+                const char * filename, const char * functionname, int line )
 {
   if ( !assumption )
     {
@@ -45,6 +45,31 @@ void pcdiAssert   ( bool assumption, const char * filename,
 
 /****************************************************/
 
+void pcdiAbortC(const char * caller, const char * filename, const char *functionname, int line,
+                const char * errorString, ... )
+{
+  va_list ap;
+  va_start(ap, errorString);
+#ifdef USE_MPI
+  {
+    int rank;
+    MPI_Comm_rank ( MPI_COMM_WORLD, &rank );
+    fprintf(stderr, "ERROR, pe%d in %s, %s, line %d, called from %s\nerrorString: \"",
+            rank, functionname, filename, line, caller);
+  }
+  vfprintf(stderr, errorString, ap);
+  fputs("\"\n", stderr);
+  MPI_Abort ( MPI_COMM_WORLD, 1 );
+#else
+  fprintf(stderr, "ERROR, %s, %s, line %d, called from %s\nerrorString: \"",
+          functionname, filename, line, caller);
+  vfprintf(stderr, errorString, ap);
+  fputs("\"\n", stderr);
+#endif
+  exit ( EXIT_FAILURE );
+  va_end(ap);
+}
+
 void pcdiAbort(const char * filename, const char *functionname, int line,
                const char * errorString, ... )
 {
diff --git a/libcdi/src/pio_util.h b/libcdi/src/pio_util.h
index 282d4cb..0b3ee91 100644
--- a/libcdi/src/pio_util.h
+++ b/libcdi/src/pio_util.h
@@ -45,7 +45,7 @@
 #  define  __attribute__(x)  /*NOTHING*/
 #endif
 
-void pcdiAssert   ( bool, const char *, const char *, int );
+void pcdiAssert( bool, const char *, const char *, int );
 #define xassert(arg) do {                               \
     if ((arg)) {                                        \
     } else {                                            \
@@ -129,6 +129,10 @@ char * outTextComm ( MPI_Comm * );
   }
 #endif
 
+void pcdiAbortC(const char *, const char *, const char *, int, const char *, ... )
+  __attribute__((noreturn));
+#define xabortC(caller, ...) pcdiAbortC(caller, __FILE__, __func__, __LINE__, __VA_ARGS__ )
+
 void pcdiAbort (const char *, const char *, int, const char *, ... )
   __attribute__((noreturn));
 #define xabort(...) pcdiAbort(__FILE__, __func__, __LINE__, __VA_ARGS__ )
diff --git a/libcdi/src/resource_handle.c b/libcdi/src/resource_handle.c
index 43164c9..6797886 100644
--- a/libcdi/src/resource_handle.c
+++ b/libcdi/src/resource_handle.c
@@ -2,7 +2,9 @@
 #  include "config.h"
 #endif
 
+#ifndef _XOPEN_SOURCE
 #define _XOPEN_SOURCE 600 /* PTHREAD_MUTEX_RECURSIVE */
+#endif
 
 #include <stdlib.h>
 #include <stdio.h>
@@ -282,7 +284,7 @@ void reshRemove ( cdiResH resH, resOps * ops )
 
 /**************************************************************/
 
-void *reshGetVal ( cdiResH resH, resOps * ops  )
+void *reshGetValue(const char * caller, cdiResH resH, resOps * ops)
 {
   int nsp;
   namespaceTuple_t nspT;
@@ -298,9 +300,8 @@ void *reshGetVal ( cdiResH resH, resOps * ops  )
 
   nspT = namespaceResHDecode ( resH );
 
-  if (nspT.nsp == nsp &&
-      nspT.idx >= 0 &&
-      nspT.idx < listSizeAllocated[nsp])
+  if ( nspT.nsp == nsp &&
+       nspT.idx >= 0 && nspT.idx < listSizeAllocated[nsp] )
     {
       listElem = listResources[nsp] + nspT.idx;
       LIST_UNLOCK();
@@ -308,10 +309,11 @@ void *reshGetVal ( cdiResH resH, resOps * ops  )
   else
     {
       LIST_UNLOCK();
-      xabort("Invalid namespace %d or index %d for resH %d!", nspT.nsp, nspT.idx, (int)resH);
+      xabortC(caller, "Invalid namespace %d or index %d for resource handle %d!", nspT.nsp, nspT.idx, (int)resH);
     }
 
-  xassert(listElem && listElem->ops == ops);
+  if ( !(listElem && listElem->ops == ops) )
+    xabortC(caller, "Invalid resource handle %d, list element not found!", (int)resH);
 
   return listElem->val;
 }
diff --git a/libcdi/src/resource_handle.h b/libcdi/src/resource_handle.h
index d11072c..d352966 100644
--- a/libcdi/src/resource_handle.h
+++ b/libcdi/src/resource_handle.h
@@ -47,7 +47,8 @@ void   reshRemove ( cdiResH, resOps * );
 
 int    reshCountType ( resOps * );
 
-void * reshGetVal ( cdiResH, resOps * );
+void * reshGetValue(const char *, cdiResH, resOps * );
+#define reshGetVal(resH, ops)  reshGetValue(__func__, resH, ops)
 
 void   reshGetResHListOfType ( int, int *, resOps * );
 
diff --git a/libcdi/src/servicelib.c b/libcdi/src/servicelib.c
index ded17f0..f38ed9d 100644
--- a/libcdi/src/servicelib.c
+++ b/libcdi/src/servicelib.c
@@ -98,6 +98,7 @@ void srvLibInit()
 	      }
 	    default:
 	      Message("Invalid character in %s: %s", envName, envString);
+	      break;
 	    }
 	  pos += 2;
 	}
@@ -296,6 +297,7 @@ int srvInqData(srvrec_t *srvp, int prec, void *data)
     default:
       {
 	Error("unexpected data precision %d", dprec);
+        break;
       }
     }
 
@@ -384,6 +386,7 @@ int srvDefData(srvrec_t *srvp, int prec, const void *data)
     default:
       {
 	Error("unexpected data precision %d", dprec);
+        break;
       }
     }
 
@@ -459,6 +462,7 @@ int srvRead(int fileID, srvrec_t *srvp)
     default:
       {
 	Error("unexpected header precision %d", hprec);
+        break;
       }
     }
 
@@ -559,6 +563,7 @@ int srvWrite(int fileID, srvrec_t *srvp)
     default:
       {
 	Error("unexpected header precision %d", hprec);
+        break;
       }
     }
   
@@ -588,6 +593,7 @@ int srvWrite(int fileID, srvrec_t *srvp)
     default:
       {
 	Error("unexpected data precision %d", dprec);
+        break;
       }
     }
 
diff --git a/libcdi/src/stream.c b/libcdi/src/stream.c
index 4befe82..43d9b99 100644
--- a/libcdi/src/stream.c
+++ b/libcdi/src/stream.c
@@ -50,15 +50,15 @@ void cdiPrintDefaults(void)
 
 void cdiDebug(int level)
 {
-  if ( level == 1 || level &  2 ) CDI_Debug = 1;
+  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 &  4) ) memDebug(1);
 
-  if ( level == 1 || level &  8 ) fileDebug(1);
+  if ( level == 1 || (level &  8) ) fileDebug(1);
 
-  if ( level == 1 || level & 16 )
+  if ( level == 1 || (level & 16) )
     {
 #if  defined  (HAVE_LIBGRIB)
       gribSetDebug(1);
@@ -505,7 +505,7 @@ char *streamFilename(int streamID)
   return (streamptr->filename);
 }
 
-
+static
 int cdiInqTimeSize(int streamID)
 {
   int ntsteps;
@@ -526,18 +526,13 @@ int cdiInqTimeSize(int streamID)
   return (ntsteps);
 }
 
-
-int cdiInqContents(int streamID)
+static
+int cdiInqContents(stream_t * streamptr)
 {
   int filetype;
   int vlistID;
   int taxisID;
   int status = 0;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   filetype = streamptr->filetype;
 
@@ -547,28 +542,28 @@ int cdiInqContents(int streamID)
     case FILETYPE_GRB:
     case FILETYPE_GRB2:
       {
-        status = grbInqContents(streamID);
+        status = grbInqContents(streamptr);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBSERVICE)
     case FILETYPE_SRV:
       {
-        status = srvInqContents(streamID);
+        status = srvInqContents(streamptr);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBEXTRA)
     case FILETYPE_EXT:
       {
-        status = extInqContents(streamID);
+        status = extInqContents(streamptr);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBIEG)
     case FILETYPE_IEG:
       {
-        status = iegInqContents(streamID);
+        status = iegInqContents(streamptr);
 	break;
       }
 #endif
@@ -578,7 +573,7 @@ int cdiInqContents(int streamID)
     case FILETYPE_NC4:
     case FILETYPE_NC4C:
       {
-        status = cdfInqContents(streamID);
+        status = cdfInqContents(streamptr);
 	break;
       }
 #endif
@@ -588,12 +583,13 @@ int cdiInqContents(int streamID)
 	  Message("%s support not compiled in!", strfiletype(filetype));
 
 	status = CDI_ELIBNAVAIL;
+        break;
       }
     }
 
   if ( status == 0 )
     {
-      vlistID = streamInqVlist(streamID);
+      vlistID = streamptr->vlistID;
       taxisID = vlistInqTaxis(vlistID);
       if ( taxisID != -1 )
         {
@@ -748,7 +744,7 @@ int streamOpen(const char *filename, const char *filemode, int filetype)
 
 	  streamptr->vlistID = vlistID;
 	  /* cdiReadByteorder(streamID); */
-	  status = cdiInqContents(streamID);
+	  status = cdiInqContents(streamptr);
 	  if ( status < 0 ) return (status);
 	  vlistptr = vlist_to_pointer(streamptr->vlistID);
 	  vlistptr->ntsteps = streamNtsteps(streamID);
@@ -858,7 +854,7 @@ int streamOpenA(const char *filename, const char *filemode, int filetype)
 
       streamptr->vlistID = vlistCreate();
       /* cdiReadByteorder(streamID); */
-      status = cdiInqContents(streamID);
+      status = cdiInqContents(streamptr);
       if ( status < 0 ) return (status);
       vlistptr = vlist_to_pointer(streamptr->vlistID);
       vlistptr->ntsteps = cdiInqTimeSize(streamID);
@@ -1179,7 +1175,7 @@ void streamClose(int streamID)
 	  case FILETYPE_GRB2:
 	    {
 	      gribClose(fileID);
-	      gribContainersDelete(streamID);
+	      gribContainersDelete(streamptr);
 	      break;
 	    }
 #endif
@@ -1324,7 +1320,7 @@ void streamSync(int streamID)
 
   fileID   = streamptr->fileID;
   filetype = streamptr->filetype;
-  vlistID  = streamInqVlist(streamID);
+  vlistID  = streamptr->vlistID;
   nvars    = vlistNvars(vlistID);
 
   if ( fileID == CDI_UNDEFID )
@@ -1394,7 +1390,7 @@ int streamDefTimestep(int streamID, int tsID)
 
   stream_check_ptr(__func__, streamptr);
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
 
   time_is_varying = vlistHasTime(vlistID);
 
@@ -1409,7 +1405,7 @@ int streamDefTimestep(int streamID, int tsID)
         }
     }
 
-  newtsID = tstepsNewEntry(streamID);
+  newtsID = tstepsNewEntry(streamptr);
 
   if ( tsID != newtsID )
     Error("Internal problem: tsID = %d newtsID = %d", tsID, newtsID);
@@ -1436,9 +1432,9 @@ int streamDefTimestep(int streamID, int tsID)
            streamptr->filetype == FILETYPE_NC4 ||
            streamptr->filetype == FILETYPE_NC4C)
        && time_is_varying )
-    cdfDefTimestep(streamID, tsID);
+    cdfDefTimestep(streamptr, tsID);
 
-  cdiCreateRecords(streamID, tsID);
+  cdi_create_records(streamptr, tsID);
 
   return (streamptr->ntsteps);
 }
@@ -1472,7 +1468,7 @@ int streamInqTimestep(int streamID, int tsID)
 
   stream_check_ptr(__func__, streamptr);
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
 
   if ( tsID < streamptr->rtsteps )
     {
@@ -1503,28 +1499,28 @@ int streamInqTimestep(int streamID, int tsID)
     case FILETYPE_GRB:
     case FILETYPE_GRB2:
       {
-        nrecs = grbInqTimestep(streamID, tsID);
+        nrecs = grbInqTimestep(streamptr, tsID);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBSERVICE)
     case FILETYPE_SRV:
       {
-        nrecs = srvInqTimestep(streamID, tsID);
+        nrecs = srvInqTimestep(streamptr, tsID);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBEXTRA)
     case FILETYPE_EXT:
       {
-        nrecs = extInqTimestep(streamID, tsID);
+        nrecs = extInqTimestep(streamptr, tsID);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBIEG)
     case FILETYPE_IEG:
       {
-        nrecs = iegInqTimestep(streamID, tsID);
+        nrecs = iegInqTimestep(streamptr, tsID);
 	break;
       }
 #endif
@@ -1534,7 +1530,7 @@ int streamInqTimestep(int streamID, int tsID)
     case FILETYPE_NC4:
     case FILETYPE_NC4C:
       {
-        nrecs = cdfInqTimestep(streamID, tsID);
+        nrecs = cdfInqTimestep(streamptr, tsID);
 	break;
       }
 #endif
@@ -1595,28 +1591,28 @@ void streamReadVar(int streamID, int varID, double *data, int *nmiss)
     case FILETYPE_GRB:
     case FILETYPE_GRB2:
       {
-        grbReadVarDP(streamID, varID, data, nmiss);
+        grbReadVarDP(streamptr, varID, data, nmiss);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBSERVICE)
     case FILETYPE_SRV:
       {
-        srvReadVarDP(streamID, varID, data, nmiss);
+        srvReadVarDP(streamptr, varID, data, nmiss);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBEXTRA)
     case FILETYPE_EXT:
       {
-        extReadVarDP(streamID, varID, data, nmiss);
+        extReadVarDP(streamptr, varID, data, nmiss);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBIEG)
     case FILETYPE_IEG:
       {
-        iegReadVarDP(streamID, varID, data, nmiss);
+        iegReadVarDP(streamptr, varID, data, nmiss);
 	break;
       }
 #endif
@@ -1626,7 +1622,7 @@ void streamReadVar(int streamID, int varID, double *data, int *nmiss)
     case FILETYPE_NC4:
     case FILETYPE_NC4C:
       {
-        cdfReadVarDP(streamID, varID, data, nmiss);
+        cdfReadVarDP(streamptr, varID, data, nmiss);
 	break;
       }
 #endif
@@ -1638,7 +1634,7 @@ void streamReadVar(int streamID, int varID, double *data, int *nmiss)
     }
 }
 
-
+static
 void stream_write_var(int streamID, int varID, int memtype, const void *data, int nmiss)
 {
   int filetype;
@@ -1685,8 +1681,7 @@ void stream_write_var(int streamID, int varID, int memtype, const void *data, in
     case FILETYPE_GRB:
     case FILETYPE_GRB2:
       {
-        if ( memtype == MEMTYPE_FLOAT ) Error("grbWriteVar not implemented for memtype float!");
-        grbWriteVarDP(streamID, varID, data, nmiss);
+        grb_write_var(streamptr, varID, memtype, data, nmiss);
 	break;
       }
 #endif
@@ -1694,7 +1689,7 @@ void stream_write_var(int streamID, int varID, int memtype, const void *data, in
     case FILETYPE_SRV:
       {
         if ( memtype == MEMTYPE_FLOAT ) Error("srvWriteVar not implemented for memtype float!");
-        srvWriteVarDP(streamID, varID, data);
+        srvWriteVarDP(streamptr, varID, data);
 	break;
       }
 #endif
@@ -1702,7 +1697,7 @@ void stream_write_var(int streamID, int varID, int memtype, const void *data, in
     case FILETYPE_EXT:
       {
         if ( memtype == MEMTYPE_FLOAT ) Error("extWriteVar not implemented for memtype float!");
-        extWriteVarDP(streamID, varID, data);
+        extWriteVarDP(streamptr, varID, data);
 	break;
       }
 #endif
@@ -1710,7 +1705,7 @@ void stream_write_var(int streamID, int varID, int memtype, const void *data, in
     case FILETYPE_IEG:
       {
         if ( memtype == MEMTYPE_FLOAT ) Error("iegWriteVar not implemented for memtype float!");
-        iegWriteVarDP(streamID, varID, data);
+        iegWriteVarDP(streamptr, varID, data);
 	break;
       }
 #endif
@@ -1720,8 +1715,8 @@ void stream_write_var(int streamID, int varID, int memtype, const void *data, in
     case FILETYPE_NC4:
     case FILETYPE_NC4C:
       {
-	if ( streamptr->accessmode == 0 ) cdfEndDef(streamID);
-        cdf_write_var(streamID, varID, memtype, data, nmiss);
+	if ( streamptr->accessmode == 0 ) cdfEndDef(streamptr);
+        cdf_write_var(streamptr, varID, memtype, data, nmiss);
 	break;
       }
 #endif
@@ -1818,28 +1813,28 @@ void streamReadVarSlice(int streamID, int varID, int levelID, double *data, int
     case FILETYPE_GRB:
     case FILETYPE_GRB2:
       {
-        grbReadVarSliceDP(streamID, varID, levelID, data, nmiss);
+        grbReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBSERVICE)
     case FILETYPE_SRV:
       {
-        srvReadVarSliceDP(streamID, varID, levelID, data, nmiss);
+        srvReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBEXTRA)
     case FILETYPE_EXT:
       {
-        extReadVarSliceDP(streamID, varID, levelID, data, nmiss);
+        extReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBIEG)
     case FILETYPE_IEG:
       {
-        iegReadVarSliceDP(streamID, varID, levelID, data, nmiss);
+        iegReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
 	break;
       }
 #endif
@@ -1850,7 +1845,7 @@ void streamReadVarSlice(int streamID, int varID, int levelID, double *data, int
     case FILETYPE_NC4C:
       {
         /* FIXME: status value ignored */
-        int ierr = cdfReadVarSliceDP(streamID, varID, levelID, data, nmiss);
+        int ierr = cdfReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
 	break;
       }
 #endif
@@ -1862,7 +1857,7 @@ void streamReadVarSlice(int streamID, int varID, int levelID, double *data, int
     }
 }
 
-
+static
 void stream_write_var_slice(int streamID, int varID, int levelID, int memtype, const void *data, int nmiss)
 {
   int filetype;
@@ -1884,8 +1879,7 @@ void stream_write_var_slice(int streamID, int varID, int levelID, int memtype, c
     case FILETYPE_GRB:
     case FILETYPE_GRB2:
       {
-        if ( memtype == MEMTYPE_FLOAT ) Error("grbWriteVarSlice not implemented for memtype float!");
-        grbWriteVarSliceDP(streamID, varID, levelID, data, nmiss);
+        grb_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
 	break;
       }
 #endif
@@ -1893,7 +1887,7 @@ void stream_write_var_slice(int streamID, int varID, int levelID, int memtype, c
     case FILETYPE_SRV:
       {
         if ( memtype == MEMTYPE_FLOAT ) Error("srvWriteVarSlice not implemented for memtype float!");
-        srvWriteVarSliceDP(streamID, varID, levelID, data);
+        srvWriteVarSliceDP(streamptr, varID, levelID, data);
 	break;
       }
 #endif
@@ -1901,7 +1895,7 @@ void stream_write_var_slice(int streamID, int varID, int levelID, int memtype, c
     case FILETYPE_EXT:
       {
         if ( memtype == MEMTYPE_FLOAT ) Error("extWriteVarSlice not implemented for memtype float!");
-        extWriteVarSliceDP(streamID, varID, levelID, data);
+        extWriteVarSliceDP(streamptr, varID, levelID, data);
 	break;
       }
 #endif
@@ -1909,7 +1903,7 @@ void stream_write_var_slice(int streamID, int varID, int levelID, int memtype, c
     case FILETYPE_IEG:
       {
         if ( memtype == MEMTYPE_FLOAT ) Error("iegWriteVarSlice not implemented for memtype float!");
-        iegWriteVarSliceDP(streamID, varID, levelID, data);
+        iegWriteVarSliceDP(streamptr, varID, levelID, data);
 	break;
       }
 #endif
@@ -1920,8 +1914,8 @@ void stream_write_var_slice(int streamID, int varID, int levelID, int memtype, c
     case FILETYPE_NC4C:
       {
         int ierr = 0;
-	if ( streamptr->accessmode == 0 ) cdfEndDef(streamID);
-        ierr = cdf_write_var_slice(streamID, varID, levelID, memtype, data, nmiss);
+	if ( streamptr->accessmode == 0 ) cdfEndDef(streamptr);
+        ierr = cdf_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
 	break;
       }
 #endif
@@ -1999,7 +1993,7 @@ void streamWriteContents(int streamID, char *cname)
 
   stream_check_ptr(__func__, streamptr);
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
 
   cnp = fopen(cname, "w");
 
@@ -2209,26 +2203,24 @@ void streamDefVlist(int streamID, int vlistID)
 	{
 	  gridID  = vlistInqVarGrid(vlistID, varID);
 	  zaxisID = vlistInqVarZaxis(vlistID, varID);
-	  streamNewVar(streamID, gridID, zaxisID);
+	  stream_new_var(streamptr, gridID, zaxisID);
 	  if ( streamptr->have_missval )
-	    vlistDefVarMissval(streamptr->vlistID, varID, 
-                               vlistInqVarMissval(vlistID, varID));
+	    vlistDefVarMissval(streamptr->vlistID, varID, vlistInqVarMissval(vlistID, varID));
 	}
 
-      if (namespaceHasLocalFile(namespaceGetActive())
-          && streamptr->filemode == 'w' )
+      if ( namespaceHasLocalFile(namespaceGetActive()) && streamptr->filemode == 'w' )
 	{
 	  if ( streamptr->filetype == FILETYPE_NC  ||
 	       streamptr->filetype == FILETYPE_NC2 ||
 	       streamptr->filetype == FILETYPE_NC4 ||
 	       streamptr->filetype == FILETYPE_NC4C )
 	    {
-	      cdfDefVars(streamID);
+	      cdfDefVars(streamptr);
 	    }
 	  else if ( streamptr->filetype == FILETYPE_GRB  ||
 		    streamptr->filetype == FILETYPE_GRB2 )
 	    {
-	      gribContainersNew(streamID);
+	      gribContainersNew(streamptr);
 	    }
 	}
     }
diff --git a/libcdi/src/stream_cdf.c b/libcdi/src/stream_cdf.c
index 9d40679..9b7f651 100644
--- a/libcdi/src/stream_cdf.c
+++ b/libcdi/src/stream_cdf.c
@@ -32,8 +32,8 @@
 #define UNDEFID  CDI_UNDEFID
 
 
-void cdfDefGlobalAtts(int streamID);
-void cdfDefLocalAtts(int streamID);
+void cdfDefGlobalAtts(stream_t *streamptr);
+void cdfDefLocalAtts(stream_t *streamptr);
 
 
 #define  X_AXIS  1
@@ -488,7 +488,7 @@ void defineAttributes(int vlistID, int varID, int fileID, int ncvarID)
 }
 #endif
 
-int cdfCopyRecord(int streamID2, int streamID1)
+int cdfCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
 {
   double *data;
   int datasize;
@@ -498,14 +498,6 @@ int cdfCopyRecord(int streamID2, int streamID1)
   int ierr = 0;
   int memtype = MEMTYPE_DOUBLE;
   int vlistID1;
-  stream_t *streamptr1;
-  stream_t *streamptr2;
-
-  streamptr1 = stream_to_pointer(streamID1);
-  streamptr2 = stream_to_pointer(streamID2);
-
-  stream_check_ptr(__func__, streamptr1);
-  stream_check_ptr(__func__, streamptr2);
 
   vlistID1 = streamptr1->vlistID;
 
@@ -523,8 +515,8 @@ int cdfCopyRecord(int streamID2, int streamID1)
 
   data = (double *) malloc(datasize*sizeof(double));
 
-  streamReadRecord(streamID1, data, &nmiss);
-  stream_write_record(streamID2, memtype, data, nmiss);
+  cdfReadRecord(streamptr1, data, &nmiss);
+  cdf_write_record(streamptr2, memtype, data, nmiss);
 
   free(data);
 
@@ -532,21 +524,15 @@ int cdfCopyRecord(int streamID2, int streamID1)
 }
 
 /* not used
-int cdfInqRecord(int streamID, int *varID, int *levelID)
+int cdfInqRecord(stream_t *streamptr, int *varID, int *levelID)
 {
   int tsID, recID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   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 )
+  if ( streamptr->tsteps[0].curRecID >= streamptr->tsteps[0].nrecs )
     {
       streamptr->tsteps[0].curRecID = 0;
     }
@@ -559,40 +545,31 @@ int cdfInqRecord(int streamID, int *varID, int *levelID)
 
   if ( CDI_Debug )
     Message("recID = %d  varID = %d  levelID = %d", recID, *varID, *levelID);
-  
+
   return (recID+1);
 }
 */
-int cdfDefRecord(int streamID)
-{
-  int ierr = 0;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  if ( CDI_Debug )
-    Message("streamID = %d", streamID);
 
-  stream_check_ptr(__func__, streamptr);
+int cdfDefRecord(stream_t *streamptr)
+{
+  int ierr = 0;
 
   return (ierr);
 }
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfWriteGridTraj(int streamID, int gridID)
+void cdfWriteGridTraj(stream_t *streamptr, int gridID)
 {
   int tsID, fileID;
   int lonID, latID, gridindex;
   size_t index;
   double xlon, xlat;
   int vlistID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   gridindex = vlistGridIndex(vlistID, gridID);
   lonID = streamptr->xdimID[gridindex];
@@ -606,23 +583,18 @@ void cdfWriteGridTraj(int streamID, int gridID)
   cdf_put_var1_double(fileID, lonID, &index, &xlon);
   cdf_put_var1_double(fileID, latID, &index, &xlat);
 }
-#endif
 
-#if  defined  (HAVE_LIBNETCDF)
 static
-void cdfReadGridTraj(int streamID, int gridID)
+void cdfReadGridTraj(stream_t *streamptr, int gridID)
 {
   int tsID, fileID;
   int lonID, latID, gridindex;
   size_t index;
   double xlon, xlat;
   int vlistID;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   gridindex = vlistGridIndex(vlistID, gridID);
   lonID = streamptr->xdimID[gridindex];
@@ -696,12 +668,8 @@ void cdfDefVarSzip(int ncid, int ncvarid)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefVarMissval(int streamID, int varID, int dtype, int lcheck)
+void cdfDefVarMissval(stream_t *streamptr, int varID, int dtype, int lcheck)
 {
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
   if ( streamptr->vars[varID].defmiss == FALSE )
     {
       int fileID;
@@ -710,10 +678,11 @@ void cdfDefVarMissval(int streamID, int varID, int dtype, int lcheck)
       int vlistID;
       int xtype;
 
-      vlistID = streamInqVlist(streamID);
-      fileID  = streamInqFileID(streamID);
+      vlistID = streamptr->vlistID;
+      fileID  = streamptr->fileID;
       ncvarid = streamptr->vars[varID].ncvarid;
       missval = vlistInqVarMissval(vlistID, varID);
+
       if ( lcheck && streamptr->ncmode == 2 ) cdf_redef(fileID);
 
       xtype = cdfDefDatatype(dtype, streamptr->filetype);
@@ -730,35 +699,28 @@ void cdfDefVarMissval(int streamID, int varID, int dtype, int lcheck)
 }
 #endif
 
-void cdf_write_record(int streamID, int memtype, const void *data, int nmiss)
+void cdf_write_record(stream_t *streamptr, int memtype, const void *data, int nmiss)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int varID;
   int levelID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   varID   = streamptr->record->varID;
   levelID = streamptr->record->levelID;
 
-  if ( CDI_Debug )
-    Message("streamID = %d  varID = %d", streamID, varID);
+  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
 
-  cdf_write_var_slice(streamID, varID, levelID, memtype, data, nmiss);
+  cdf_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
 #endif
 }
 
 
-int cdfReadRecord(int streamID, double *data, int *nmiss)
+int cdfReadRecord(stream_t *streamptr, double *data, int *nmiss)
 {
   int ierr = 0;
   int levelID, varID, tsID, recID, vrecID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  if ( CDI_Debug ) Message("streamID = %d", streamID);
+  if ( CDI_Debug ) Message("streamID = %d", streamptr->self);
 
   tsID    = streamptr->curTsID;
   vrecID  = streamptr->tsteps[tsID].curRecID;
@@ -766,13 +728,13 @@ int cdfReadRecord(int streamID, double *data, int *nmiss)
   varID   = streamptr->tsteps[tsID].records[recID].varID;
   levelID = streamptr->tsteps[tsID].records[recID].levelID;
 
-  cdfReadVarSliceDP(streamID, varID, levelID, data, nmiss);
+  cdfReadVarSliceDP(streamptr, varID, levelID, data, nmiss);
 
   return (ierr);
 }
 
 static
-void cdfDefTimeValue(int streamID, int tsID)
+void cdfDefTimeValue(stream_t *streamptr, int tsID)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int fileID;
@@ -780,14 +742,11 @@ void cdfDefTimeValue(int streamID, int tsID)
   int ncvarid;
   size_t index;
   taxis_t *taxis;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
 
   if ( CDI_Debug )
-    Message("streamID = %d, fileID = %d", streamID, fileID);
+    Message("streamID = %d, fileID = %d", streamptr->self, fileID);
 
   taxis = &streamptr->tsteps[tsID].taxis;
 
@@ -826,7 +785,7 @@ printf("fileID = %d %d %d %f\n", fileID, time_varid, index, timevalue);
 }
 
 static
-void cdfDefTime(int streamID)
+void cdfDefTime(stream_t *streamptr)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int fileID;
@@ -841,13 +800,10 @@ void cdfDefTime(int streamID)
   char *taxis_name = default_name;
   size_t len;
   taxis_t *taxis;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   if ( streamptr->basetime.ncvarid != UNDEFID ) return;
 
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
 
   if ( streamptr->ncmode == 0 ) streamptr->ncmode = 1;
 
@@ -957,20 +913,20 @@ void cdfDefTime(int streamID)
 }
 
 
-void cdfDefTimestep(int streamID, int tsID)
+void cdfDefTimestep(stream_t *streamptr, int tsID)
 {
   int vlistID;
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
 
-  if ( vlistHasTime(vlistID) ) cdfDefTime(streamID);
+  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
 
-  cdfDefTimeValue(streamID, tsID);
+  cdfDefTimeValue(streamptr, tsID);
 }
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefComplex(int streamID, int gridID)
+void cdfDefComplex(stream_t *streamptr, int gridID)
 {
   char axisname[] = "nc2";
   int index;
@@ -980,12 +936,9 @@ void cdfDefComplex(int streamID, int gridID)
   int fileID;
   int dimlen;
   int vlistID;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   ngrids = vlistNgrids(vlistID);
 
@@ -1022,7 +975,7 @@ void cdfDefComplex(int streamID, int gridID)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefSP(int streamID, int gridID)
+void cdfDefSP(stream_t *streamptr, int gridID)
 {
   /*
   char longname[] = "Spherical harmonic coefficient";
@@ -1035,12 +988,9 @@ void cdfDefSP(int streamID, int gridID)
   int fileID;
   int dimlen, dimlen0;
   int vlistID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   ngrids = vlistNgrids(vlistID);
 
@@ -1086,7 +1036,7 @@ void cdfDefSP(int streamID, int gridID)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefFC(int streamID, int gridID)
+void cdfDefFC(stream_t *streamptr, int gridID)
 {
   char axisname[5] = "nfcX";
   int index, iz = 0;
@@ -1096,12 +1046,9 @@ void cdfDefFC(int streamID, int gridID)
   int fileID;
   int dimlen, dimlen0;
   int vlistID;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   ngrids = vlistNgrids(vlistID);
 
@@ -1147,7 +1094,7 @@ void cdfDefFC(int streamID, int gridID)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefTrajLon(int streamID, int gridID)
+void cdfDefTrajLon(stream_t *streamptr, int gridID)
 {
   char units[CDI_MAX_NAME];
   char longname[CDI_MAX_NAME];
@@ -1161,14 +1108,11 @@ void cdfDefTrajLon(int streamID, int gridID)
   int ncvarid;
   int vlistID;
   int xtype = NC_DOUBLE;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   if ( gridInqPrec(gridID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   gridtype = gridInqType(gridID);
   dimlen = gridInqXsize(gridID);
@@ -1207,7 +1151,7 @@ void cdfDefTrajLon(int streamID, int gridID)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefTrajLat(int streamID, int gridID)
+void cdfDefTrajLat(stream_t *streamptr, int gridID)
 {
   char units[] = "degrees_north";
   char longname[] = "latitude";
@@ -1221,14 +1165,11 @@ void cdfDefTrajLat(int streamID, int gridID)
   int ncvarid;
   int vlistID;
   int xtype = NC_DOUBLE;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   if ( gridInqPrec(gridID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
 
-  vlistID = streamInqVlist(streamID);
-  fileID = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID = streamptr->fileID;
 
   gridtype = gridInqType(gridID);
   dimlen = gridInqYsize(gridID);
@@ -1281,7 +1222,7 @@ int checkGridName(int type, char *axisname, int fileID, int vlistID, int gridID,
   checkname = TRUE;
   iz = 0;
 
-  while ( checkname ) 
+  while ( checkname )
     {
       strcpy(axisname2, axisname);
       if ( iz ) sprintf(&axisname2[strlen(axisname2)], "_%d", iz+1);
@@ -1331,7 +1272,7 @@ int checkGridName(int type, char *axisname, int fileID, int vlistID, int gridID,
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefXaxis(int streamID, int gridID)
+void cdfDefXaxis(stream_t *streamptr, int gridID)
 {
   char units[CDI_MAX_NAME];
   char longname[CDI_MAX_NAME];
@@ -1350,14 +1291,11 @@ void cdfDefXaxis(int streamID, int gridID)
   int nvertex = 2, nvdimID = UNDEFID;
   int vlistID;
   int xtype = NC_DOUBLE;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   if ( gridInqPrec(gridID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   ngrids = vlistNgrids(vlistID);
 
@@ -1460,7 +1398,7 @@ void cdfDefXaxis(int streamID, int gridID)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefYaxis(int streamID, int gridID)
+void cdfDefYaxis(stream_t *streamptr, int gridID)
 {
   char units[CDI_MAX_NAME];
   char longname[CDI_MAX_NAME];
@@ -1479,14 +1417,11 @@ void cdfDefYaxis(int streamID, int gridID)
   int nvertex = 2, nvdimID = UNDEFID;
   int vlistID;
   int xtype = NC_DOUBLE;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   if ( gridInqPrec(gridID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   ngrids = vlistNgrids(vlistID);
 
@@ -1603,7 +1538,7 @@ void cdfGridCompress(int fileID, int ncvarid, int gridsize, int filetype, int co
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefCurvilinear(int streamID, int gridID)
+void cdfDefCurvilinear(stream_t *streamptr, int gridID)
 {
   char xunits[CDI_MAX_NAME];
   char xlongname[CDI_MAX_NAME];
@@ -1629,14 +1564,11 @@ void cdfDefCurvilinear(int streamID, int gridID)
   int nvertex = 4, nvdimID = UNDEFID;
   int vlistID;
   int xtype = NC_DOUBLE;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   if ( gridInqPrec(gridID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   ngrids = vlistNgrids(vlistID);
 
@@ -1799,7 +1731,7 @@ void cdfDefCurvilinear(int streamID, int gridID)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefRgrid(int streamID, int gridID)
+void cdfDefRgrid(stream_t *streamptr, int gridID)
 {
   char axisname[7] = "rgridX";
   int index, iz = 0;
@@ -1810,12 +1742,9 @@ void cdfDefRgrid(int streamID, int gridID)
   int dimlen, dimlen0;
   int vlistID;
   int lwarn = TRUE;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   ngrids = vlistNgrids(vlistID);
 
@@ -1869,9 +1798,8 @@ void cdfDefRgrid(int streamID, int gridID)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefGdim(int streamID, int gridID)
+void cdfDefGdim(stream_t *streamptr, int gridID)
 {
-  char axisname[7] = "gsizeX";
   int index, iz = 0;
   int gridID0, gridtype0, gridindex;
   int dimID = UNDEFID;
@@ -1879,12 +1807,9 @@ void cdfDefGdim(int streamID, int gridID)
   int fileID;
   int dimlen, dimlen0;
   int vlistID;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   ngrids = vlistNgrids(vlistID);
 
@@ -1906,7 +1831,7 @@ void cdfDefGdim(int streamID, int gridID)
                     break;
                   }
                 else
-                  iz++; 
+                  iz++;
               }
           }
       }
@@ -1927,18 +1852,25 @@ void cdfDefGdim(int streamID, int gridID)
                     break;
                   }
                 else
-                  iz++; 
+                  iz++;
               }
           }
       }
 
   if ( dimID == UNDEFID )
     {
+      int status;
+      char axisname[CDI_MAX_NAME];
+      strcpy(axisname, "gsize");
+
+      status = checkGridName('D', axisname, fileID, vlistID, gridID, ngrids, 'X');
+      /*
       if ( iz == 0 ) axisname[5] = '\0';
       else           sprintf(&axisname[5], "%1d", iz+1);
-
+      */
       if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
+      //printf("axisname, dimlen %s %d\n", axisname, dimlen);
       cdf_def_dim(fileID, axisname, dimlen, &dimID);
 
       cdf_enddef(fileID);
@@ -1952,7 +1884,7 @@ void cdfDefGdim(int streamID, int gridID)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefUnstructured(int streamID, int gridID)
+void cdfDefUnstructured(stream_t *streamptr, int gridID)
 {
   char xunits[CDI_MAX_NAME];
   char xlongname[CDI_MAX_NAME];
@@ -1974,14 +1906,11 @@ void cdfDefUnstructured(int streamID, int gridID)
   int nvertex, nvdimID = UNDEFID;
   int vlistID;
   int xtype = NC_DOUBLE;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   if ( gridInqPrec(gridID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   ngrids = vlistNgrids(vlistID);
 
@@ -2124,12 +2053,9 @@ void cdfDefUnstructured(int streamID, int gridID)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefVCT(int streamID, int zaxisID)
+void cdfDefVCT(stream_t *streamptr, int zaxisID)
 {
   int type;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   type = zaxisInqType(zaxisID);
   if ( type == ZAXIS_HYBRID || type == ZAXIS_HYBRID_HALF )
@@ -2158,7 +2084,7 @@ void cdfDefVCT(int streamID, int zaxisID)
           return;
         }
 
-      fileID = streamInqFileID(streamID);
+      fileID = streamptr->fileID;
 
       if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
@@ -2214,7 +2140,7 @@ void cdfDefVCT(int streamID, int zaxisID)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefZaxis(int streamID, int zaxisID)
+void cdfDefZaxis(stream_t *streamptr, int zaxisID)
 {
   /*  char zaxisname0[CDI_MAX_NAME]; */
   char axisname[CDI_MAX_NAME];
@@ -2238,14 +2164,11 @@ void cdfDefZaxis(int streamID, int zaxisID)
   int zaxisindex;
   int xtype = NC_DOUBLE;
   int positive;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   if ( zaxisInqPrec(zaxisID) == DATATYPE_FLT32 ) xtype = NC_FLOAT;
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
 
@@ -2254,11 +2177,14 @@ void cdfDefZaxis(int streamID, int zaxisID)
   dimlen = zaxisInqSize(zaxisID);
   type   = zaxisInqType(zaxisID);
 
-  if ( dimlen == 1 && type == ZAXIS_SURFACE     ) return;
-  if ( dimlen == 1 && type == ZAXIS_TOA         ) return;
-  if ( dimlen == 1 && type == ZAXIS_SEA_BOTTOM  ) return;
-  if ( dimlen == 1 && type == ZAXIS_ATMOSPHERE  ) return;
-  if ( dimlen == 1 && type == ZAXIS_MEANSEA     ) return;
+  if ( dimlen == 1 && type == ZAXIS_SURFACE       ) return;
+  if ( dimlen == 1 && type == ZAXIS_CLOUD_BASE    ) return;
+  if ( dimlen == 1 && type == ZAXIS_CLOUD_TOP     ) return;
+  if ( dimlen == 1 && type == ZAXIS_ISOTHERM_ZERO ) return;
+  if ( dimlen == 1 && type == ZAXIS_TOA           ) return;
+  if ( dimlen == 1 && type == ZAXIS_SEA_BOTTOM    ) return;
+  if ( dimlen == 1 && type == ZAXIS_ATMOSPHERE    ) return;
+  if ( dimlen == 1 && type == ZAXIS_MEANSEA       ) return;
 
   zaxisInqName(zaxisID, axisname);
   /*
@@ -2375,7 +2301,7 @@ void cdfDefZaxis(int streamID, int zaxisID)
 	      cdf_put_var_double(fileID, ncvarid, zaxisInqLevelsPtr(zaxisID));
             }
 
-          cdfDefVCT(streamID, zaxisID);
+          cdfDefVCT(streamptr, zaxisID);
 
           if ( dimID == UNDEFID )
             {
@@ -2472,7 +2398,7 @@ void cdfDefZaxis(int streamID, int zaxisID)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefPole(int streamID, int gridID)
+void cdfDefPole(stream_t *streamptr, int gridID)
 {
   int fileID;
   int ncvarid = UNDEFID;
@@ -2481,7 +2407,7 @@ void cdfDefPole(int streamID, int gridID)
   char varname[] = "rotated_pole";
   char mapname[] = "rotated_latitude_longitude";
 
-  fileID  = streamInqFileID(streamID);
+  fileID  = streamptr->fileID;
 
   ypole = gridInqYpole(gridID);
   xpole = gridInqXpole(gridID);
@@ -2505,7 +2431,7 @@ void cdfDefPole(int streamID, int gridID)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefMapping(int streamID, int gridID)
+void cdfDefMapping(stream_t *streamptr, int gridID)
 {
   int fileID;
   int ncvarid = UNDEFID;
@@ -2516,7 +2442,7 @@ void cdfDefMapping(int streamID, int gridID)
       char varname[] = "sinusoidal";
       char mapname[] = "sinusoidal";
 
-      fileID  = streamInqFileID(streamID);
+      fileID  = streamptr->fileID;
 
       cdf_redef(fileID);
 
@@ -2537,7 +2463,7 @@ void cdfDefMapping(int streamID, int gridID)
       char varname[] = "laea";
       char mapname[] = "lambert_azimuthal_equal_area";
 
-      fileID  = streamInqFileID(streamID);
+      fileID  = streamptr->fileID;
 
       cdf_redef(fileID);
 
@@ -2561,7 +2487,7 @@ void cdfDefMapping(int streamID, int gridID)
       char varname[] = "Lambert_Conformal";
       char mapname[] = "lambert_conformal_conic";
 
-      fileID  = streamInqFileID(streamID);
+      fileID  = streamptr->fileID;
 
       cdf_redef(fileID);
 
@@ -2595,16 +2521,33 @@ void cdfDefMapping(int streamID, int gridID)
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-void cdfDefGrid(int streamID, int gridID)
+void cdfDefGridUUID(stream_t *streamptr, int gridID)
+{
+  char uuidOfHGrid[17];
+
+  gridInqUUID(gridID, uuidOfHGrid);
+  if ( uuidOfHGrid[0] != 0 )
+    {
+      char uuidOfHGridStr[37];
+      uuid2str(uuidOfHGrid, uuidOfHGridStr);
+      if ( uuidOfHGridStr[0] != 0 && strlen(uuidOfHGridStr) == 36 )
+        {
+          int fileID  = streamptr->fileID;
+          if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+          cdf_put_att_text(fileID, NC_GLOBAL, "uuidOfHGrid", 36, uuidOfHGridStr);
+          if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
+        }
+    }
+}
+
+static
+void cdfDefGrid(stream_t *streamptr, int gridID)
 {
   int gridtype, size;
   int gridindex;
   int vlistID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   gridindex = vlistGridIndex(vlistID, gridID);
   if ( streamptr->xdimID[gridindex] != UNDEFID ) return;
 
@@ -2618,73 +2561,90 @@ void cdfDefGrid(int streamID, int gridID)
        gridtype == GRID_LONLAT   ||
        gridtype == GRID_GENERIC )
     {
-      if ( gridtype == GRID_GENERIC && size == 1 && 
-           gridInqXsize(gridID) == 0 && gridInqYsize(gridID) == 0 )
+      if ( gridtype == GRID_GENERIC )
         {
-          /* no grid information */
-        }
-      else if ( gridtype == GRID_GENERIC && (gridInqXsize(gridID) == 0 || gridInqYsize(gridID) == 0) )
-        {
-          cdfDefGdim(streamID, gridID);
+          if ( size == 1 && gridInqXsize(gridID) == 0 && gridInqYsize(gridID) == 0 )
+            {
+              /* no grid information */
+            }
+          else
+            {
+              int lx = 0, ly = 0;
+              if ( gridInqXsize(gridID) > 0 /*&& gridInqXvals(gridID, NULL) > 0*/ )
+                {
+                  cdfDefXaxis(streamptr, gridID);
+                  lx = 1;
+                }
+
+              if ( gridInqYsize(gridID) > 0 /*&& gridInqYvals(gridID, NULL) > 0*/ )
+                {
+                  cdfDefYaxis(streamptr, gridID);
+                  ly = 1;
+                }
+
+              if ( lx == 0 && ly == 0 ) cdfDefGdim(streamptr, gridID);
+            }
         }
       else
         {
-          if ( gridInqXsize(gridID) > 0 ) cdfDefXaxis(streamID, gridID);
-          if ( gridInqYsize(gridID) > 0 ) cdfDefYaxis(streamID, gridID);
+          if ( gridInqXsize(gridID) > 0 ) cdfDefXaxis(streamptr, gridID);
+          if ( gridInqYsize(gridID) > 0 ) cdfDefYaxis(streamptr, gridID);
         }
 
-      if ( gridIsRotated(gridID) ) cdfDefPole(streamID, gridID);
+      if ( gridIsRotated(gridID) ) cdfDefPole(streamptr, gridID);
     }
   else if ( gridtype == GRID_CURVILINEAR )
     {
-      cdfDefCurvilinear(streamID, gridID);
+      cdfDefCurvilinear(streamptr, gridID);
     }
   else if ( gridtype == GRID_UNSTRUCTURED )
     {
-      cdfDefUnstructured(streamID, gridID);
+      cdfDefUnstructured(streamptr, gridID);
     }
   else if ( gridtype == GRID_GAUSSIAN_REDUCED )
     {
-      cdfDefRgrid(streamID, gridID);
+      cdfDefRgrid(streamptr, gridID);
     }
   else if ( gridtype == GRID_SPECTRAL )
     {
-      cdfDefComplex(streamID, gridID);
-      cdfDefSP(streamID, gridID);
+      cdfDefComplex(streamptr, gridID);
+      cdfDefSP(streamptr, gridID);
     }
   else if ( gridtype == GRID_FOURIER )
     {
-      cdfDefComplex(streamID, gridID);
-      cdfDefFC(streamID, gridID);
+      cdfDefComplex(streamptr, gridID);
+      cdfDefFC(streamptr, gridID);
     }
   else if ( gridtype == GRID_TRAJECTORY )
     {
-      cdfDefTrajLon(streamID, gridID);
-      cdfDefTrajLat(streamID, gridID);
+      cdfDefTrajLon(streamptr, gridID);
+      cdfDefTrajLat(streamptr, gridID);
     }
   else if ( gridtype == GRID_SINUSOIDAL || gridtype == GRID_LAEA || gridtype == GRID_LCC2 )
     {
-      cdfDefXaxis(streamID, gridID);
-      cdfDefYaxis(streamID, gridID);
+      cdfDefXaxis(streamptr, gridID);
+      cdfDefYaxis(streamptr, gridID);
 
-      cdfDefMapping(streamID, gridID);
+      cdfDefMapping(streamptr, gridID);
     }
   /*
   else if ( gridtype == GRID_LCC )
     {
-      cdfDefLcc(streamID, gridID);
+      cdfDefLcc(streamptr, gridID);
     }
   */
   else
     {
       Error("Unsupported grid type: %s", gridNamePtr(gridtype));
     }
+
+  cdfDefGridUUID(streamptr, gridID);
 }
 #endif
 
 #if  defined  (HAVE_LIBNETCDF)
 static
-int cdfDefVar(int streamID, int varID)
+int cdfDefVar(stream_t *streamptr, int varID)
 {
   int ncvarid = -1;
   int fileID;
@@ -2714,21 +2674,18 @@ int cdfDefVar(int streamID, int varID)
   int ixyz;
   int iax = 0;
   char axis[5];
-  stream_t *streamptr;
   int ensID, ensCount, forecast_type;
   int retval;
 
-  streamptr = stream_to_pointer(streamID);
-
-  fileID  = streamInqFileID(streamID);
+  fileID  = streamptr->fileID;
 
   if ( CDI_Debug )
-    Message("streamID = %d, fileID = %d, varID = %d", streamID, fileID, varID);
+    Message("streamID = %d, fileID = %d, varID = %d", streamptr->self, fileID, varID);
 
   if ( streamptr->vars[varID].ncvarid != UNDEFID )
     return (streamptr->vars[varID].ncvarid);
 
-  vlistID   = streamInqVlist(streamID);
+  vlistID   = streamptr->vlistID;
   gridID    = vlistInqVarGrid(vlistID, varID);
   zaxisID   = vlistInqVarZaxis(vlistID, varID);
   tsteptype = vlistInqVarTsteptype(vlistID, varID);
@@ -2837,7 +2794,7 @@ int cdfDefVar(int streamID, int varID)
       checkname = TRUE;
       iz = 0;
 
-      while ( checkname ) 
+      while ( checkname )
         {
           if ( iz ) sprintf(varname, "%s_%d", name, iz+1);
 
@@ -3104,12 +3061,15 @@ int cdfDefVar(int streamID, int varID)
   streamptr->vars[varID].ncvarid = ncvarid;
 
   if ( vlistInqVarMissvalUsed(vlistID, varID) )
-    cdfDefVarMissval(streamID, varID, vlistInqVarDatatype(vlistID, varID), 0);
+    cdfDefVarMissval(streamptr, varID, vlistInqVarDatatype(vlistID, varID), 0);
 
   if ( zid == -1 )
     {
-      if ( zaxisInqType(zaxisID) == ZAXIS_TOA         || 
-           zaxisInqType(zaxisID) == ZAXIS_SEA_BOTTOM  ||
+      if ( zaxisInqType(zaxisID) == ZAXIS_CLOUD_BASE    ||
+           zaxisInqType(zaxisID) == ZAXIS_CLOUD_TOP     ||
+           zaxisInqType(zaxisID) == ZAXIS_ISOTHERM_ZERO ||
+           zaxisInqType(zaxisID) == ZAXIS_TOA           ||
+           zaxisInqType(zaxisID) == ZAXIS_SEA_BOTTOM    ||
            zaxisInqType(zaxisID) == ZAXIS_ATMOSPHERE )
         {
           zaxisInqName(zaxisID, varname);
@@ -3117,12 +3077,11 @@ int cdfDefVar(int streamID, int varID)
         }
     }
 
-  if( vlistInqVarEnsemble( vlistID,  varID, &ensID, &ensCount, &forecast_type ) )
+  if ( vlistInqVarEnsemble( vlistID,  varID, &ensID, &ensCount, &forecast_type ) )
     {
       /* void cdf_put_att_int(  int ncid, int varid, const char *name, nc_type xtype,
 	                        size_t len, const int *ip )
        */
-
 	cdf_put_att_int(fileID, ncvarid, "realization", NC_INT, 1, &ensID);
 	cdf_put_att_int(fileID, ncvarid, "ensemble_members", NC_INT, 1, &ensCount);
 	cdf_put_att_int(fileID, ncvarid, "forecast_init_type", NC_INT, 1, &forecast_type);
@@ -3165,7 +3124,7 @@ void scale_add(long size, double *data, double addoffset, double scalefactor)
 }
 #endif
 
-void cdfReadVarDP(int streamID, int varID, double *data, int *nmiss)
+void cdfReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int fileID;
@@ -3186,15 +3145,11 @@ void cdfReadVarDP(int streamID, int varID, double *data, int *nmiss)
   double missval;
   int laddoffset, lscalefactor;
   double addoffset, scalefactor;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
+  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
 
-  if ( CDI_Debug )
-    Message("streamID = %d  varID = %d", streamID, varID);
-
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   tsID = streamptr->curTsID;
 
@@ -3209,7 +3164,7 @@ void cdfReadVarDP(int streamID, int varID, double *data, int *nmiss)
   gridindex = vlistGridIndex(vlistID, gridID);
   if ( gridInqType(gridID) == GRID_TRAJECTORY )
     {
-      cdfReadGridTraj(streamID, gridID);
+      cdfReadGridTraj(streamptr, gridID);
     }
   else
     {
@@ -3477,7 +3432,7 @@ int cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarid, int dtyp
 }
 #endif
 
-void cdf_write_var(int streamID, int varID, int memtype, const void *data, int nmiss)
+void cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data, int nmiss)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int fileID;
@@ -3498,23 +3453,18 @@ void cdf_write_var(int streamID, int varID, int memtype, const void *data, int n
   int gridindex, zaxisindex;
   int dtype;
   int vlistID;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
+  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
 
-  if ( CDI_Debug )
-    Message("streamID = %d  varID = %d", streamID, varID);
-
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   ntsteps = streamptr->ntsteps;
-  if ( CDI_Debug )
-    Message("ntsteps = %d", ntsteps); 
+  if ( CDI_Debug ) Message("ntsteps = %d", ntsteps);
 
-  if ( vlistHasTime(vlistID) ) cdfDefTime(streamID);
+  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
 
-  ncvarid = cdfDefVar(streamID, varID);
+  ncvarid = cdfDefVar(streamptr, varID);
 
   gridID    = vlistInqVarGrid(vlistID, varID);
   zaxisID   = vlistInqVarZaxis(vlistID, varID);
@@ -3523,7 +3473,7 @@ void cdf_write_var(int streamID, int varID, int memtype, const void *data, int n
   gridindex = vlistGridIndex(vlistID, gridID);
   if ( gridInqType(gridID) == GRID_TRAJECTORY )
     {
-      cdfWriteGridTraj(streamID, gridID);
+      cdfWriteGridTraj(streamptr, gridID);
     }
   else
     {
@@ -3575,7 +3525,7 @@ void cdf_write_var(int streamID, int varID, int memtype, const void *data, int n
 
   dtype = vlistInqVarDatatype(vlistID, varID);
 
-  if ( nmiss > 0 ) cdfDefVarMissval(streamID, varID, dtype, 1);
+  if ( nmiss > 0 ) cdfDefVarMissval(streamptr, varID, dtype, 1);
 
   nvals = gridInqSize(gridID)*zaxisInqSize(zaxisID);
 
@@ -3585,7 +3535,7 @@ void cdf_write_var(int streamID, int varID, int memtype, const void *data, int n
 }
 
 
-int cdfReadVarSliceDP(int streamID, int varID, int levelID, double *data, int *nmiss)
+int cdfReadVarSliceDP(stream_t *streamptr, int varID, int levelID, double *data, int *nmiss)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int fileID;
@@ -3613,19 +3563,15 @@ int cdfReadVarSliceDP(int streamID, int varID, int levelID, double *data, int *n
   double missval;
   int laddoffset, lscalefactor;
   double addoffset, scalefactor;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   if ( CDI_Debug )
-    Message("streamID = %d  varID = %d  levelID = %d", streamID, varID, levelID);
+    Message("streamID = %d  varID = %d  levelID = %d", streamptr->self, varID, levelID);
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   tsID = streamptr->curTsID;
-  if ( CDI_Debug )
-    Message("tsID = %d", tsID);
+  if ( CDI_Debug ) Message("tsID = %d", tsID);
 
   ncvarid = streamptr->vars[varID].ncvarid;
 
@@ -3644,7 +3590,7 @@ int cdfReadVarSliceDP(int streamID, int varID, int levelID, double *data, int *n
   gridindex = vlistGridIndex(vlistID, gridID);
   if ( gridInqType(gridID) == GRID_TRAJECTORY )
     {
-      cdfReadGridTraj(streamID, gridID);
+      cdfReadGridTraj(streamptr, gridID);
     }
   else if ( gridInqType(gridID) == GRID_UNSTRUCTURED )
     {
@@ -3659,7 +3605,7 @@ int cdfReadVarSliceDP(int streamID, int varID, int levelID, double *data, int *n
   zaxisindex = vlistZaxisIndex(vlistID, zaxisID);
   zid = streamptr->zaxisID[zaxisindex];
   /*
-  printf("2 %d %d %d %s\n", streamID, zaxisindex, streamptr->zaxisID[zaxisindex], vlistInqVarNamePtr(vlistID, varID));
+  printf("2 %p %d %d %s\n", streamptr, zaxisindex, streamptr->zaxisID[zaxisindex], vlistInqVarNamePtr(vlistID, varID));
   */
   dimorder[0] = ixyz/100;
   dimorder[1] = (ixyz-dimorder[0]*100)/10;
@@ -3793,7 +3739,7 @@ int cdfReadVarSliceDP(int streamID, int varID, int levelID, double *data, int *n
 }
 
 
-int cdf_write_var_slice(int streamID, int varID, int levelID, int memtype, const void *data, int nmiss)
+int cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, int nmiss)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int fileID;
@@ -3815,23 +3761,19 @@ int cdf_write_var_slice(int streamID, int varID, int levelID, int memtype, const
   int swapxy = FALSE;
   int dtype;
   int vlistID;
-  stream_t *streamptr;
   extern int CDF_Debug;
 
-  streamptr = stream_to_pointer(streamID);
+  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
 
-  if ( CDI_Debug )
-    Message("streamID = %d  varID = %d", streamID, varID);
-
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   ntsteps = streamptr->ntsteps;
   if ( CDI_Debug ) Message("ntsteps = %d", ntsteps);
 
-  if ( vlistHasTime(vlistID) ) cdfDefTime(streamID);
+  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
 
-  ncvarid = cdfDefVar(streamID, varID);
+  ncvarid = cdfDefVar(streamptr, varID);
 
   gridID    = vlistInqVarGrid(vlistID, varID);
   zaxisID   = vlistInqVarZaxis(vlistID, varID);
@@ -3842,7 +3784,7 @@ int cdf_write_var_slice(int streamID, int varID, int levelID, int memtype, const
   gridindex = vlistGridIndex(vlistID, gridID);
   if ( gridInqType(gridID) == GRID_TRAJECTORY )
     {
-      cdfWriteGridTraj(streamID, gridID);
+      cdfWriteGridTraj(streamptr, gridID);
     }
   else
     {
@@ -3901,7 +3843,7 @@ int cdf_write_var_slice(int streamID, int varID, int levelID, int memtype, const
 
   dtype = vlistInqVarDatatype(vlistID, varID);
 
-  if ( nmiss > 0 ) cdfDefVarMissval(streamID, varID, dtype, 1);
+  if ( nmiss > 0 ) cdfDefVarMissval(streamptr, varID, dtype, 1);
 
   nvals = gridInqSize(gridID);
 
@@ -3911,8 +3853,8 @@ int cdf_write_var_slice(int streamID, int varID, int levelID, int memtype, const
   return (0);
 }
 
-
-void cdfCreateRecords(int streamID, int tsID)
+static
+void cdfCreateRecords(stream_t *streamptr, int tsID)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int varID, levelID, recID, vrecID, zaxisID;
@@ -3920,11 +3862,8 @@ void cdfCreateRecords(int streamID, int tsID)
   record_t *records = NULL;
   int *recIDs = NULL;
   int vlistID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  vlistID  = streamInqVlist(streamID);
+  vlistID  = streamptr->vlistID;
 
   if ( tsID < 0 || (tsID >= streamptr->ntsteps && tsID > 0) ) return;
 
@@ -4485,11 +4424,24 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
 #endif
 
       if ( nvdims > 0 )
-        if ( timedimid == dimidsp[0] )
-          {
-            ncvars[ncvarid].tsteptype = TSTEP_INSTANT;
-            cdfSetDim(ncvars, ncvarid, 0, T_AXIS);
-          }
+        {
+          if ( timedimid == dimidsp[0] )
+            {
+              ncvars[ncvarid].tsteptype = TSTEP_INSTANT;
+              cdfSetDim(ncvars, ncvarid, 0, T_AXIS);
+            }
+          else
+            {
+              for ( ncdimid = 1; ncdimid < nvdims; ncdimid++ )
+                {
+                  if ( timedimid == dimidsp[ncdimid] )
+                    {
+                      Warning("Time must be the first dimension! Unsupported array structure, skipped variable %s!", ncvars[ncvarid].name);
+                      ncvars[ncvarid].isvar = FALSE;
+                    }
+                }
+            }
+        }
 
       for ( iatt = 0; iatt < nvatts; iatt++ )
         {
@@ -4595,12 +4547,18 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
 
               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, "atmosphere") == 0 )
                 ncvars[ncvarid].zaxistype = ZAXIS_ATMOSPHERE;
               else
-                { 
+                {
                   static int warn = TRUE;
                   if ( warn )
                     {
@@ -4804,22 +4762,58 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
             {
               if ( ncvars[ncvarid].lvalidrange == 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); */
+                  extern int cdiIgnoreValidRange;
+                  int lignore = FALSE;
+                  if ( (atttype == NC_FLOAT || atttype == NC_DOUBLE) && xtype != NC_FLOAT && xtype != NC_DOUBLE ) lignore = TRUE;
+                  if ( cdiIgnoreValidRange == FALSE && lignore == FALSE )
+                    {
+                      cdfGetAttDouble(ncid, ncvarid, attname, 2, ncvars[ncvarid].validrange);
+                      ncvars[ncvarid].lvalidrange = TRUE;
+                      if ( ((int)ncvars[ncvarid].validrange[0]) == 0 && ((int)ncvars[ncvarid].validrange[1]) == 255 )
+                        ncvars[ncvarid].lunsigned = TRUE;
+                      /* cdfSetVar(ncvars, ncvarid, TRUE); */
+                    }
+                  else if ( lignore )
+                    {
+                      Warning("Inconsistent data type for attribute %s:valid_range, ignored!", name);
+                    }
                 }
             }
           else if ( strcmp(attname, "valid_min") == 0 && attlen == 1 )
             {
-              cdfGetAttDouble(ncid, ncvarid, attname, 1, &(ncvars[ncvarid].validrange)[0]);
-              ncvars[ncvarid].lvalidrange = TRUE;
+              if ( ncvars[ncvarid].lvalidrange == FALSE )
+                {
+                  extern int cdiIgnoreValidRange;
+                  int lignore = FALSE;
+                  if ( (atttype == NC_FLOAT || atttype == NC_DOUBLE) && xtype != NC_FLOAT && xtype != NC_DOUBLE ) lignore = TRUE;
+                  if ( cdiIgnoreValidRange == FALSE && lignore == FALSE )
+                    {
+                      cdfGetAttDouble(ncid, ncvarid, attname, 1, &(ncvars[ncvarid].validrange)[0]);
+                      ncvars[ncvarid].lvalidrange = TRUE;
+                    }
+                  else if ( lignore )
+                    {
+                      Warning("Inconsistent data type for attribute %s:valid_min, ignored!", name);
+                    }
+                }
             }
           else if ( strcmp(attname, "valid_max") == 0 && attlen == 1 )
             {
-              cdfGetAttDouble(ncid, ncvarid, attname, 1, &(ncvars[ncvarid].validrange)[1]);
-              ncvars[ncvarid].lvalidrange = TRUE;
+              if ( ncvars[ncvarid].lvalidrange == FALSE )
+                {
+                  extern int cdiIgnoreValidRange;
+                  int lignore = FALSE;
+                  if ( (atttype == NC_FLOAT || atttype == NC_DOUBLE) && xtype != NC_FLOAT && xtype != NC_DOUBLE ) lignore = TRUE;
+                  if ( cdiIgnoreValidRange == FALSE && lignore == FALSE )
+                    {
+                      cdfGetAttDouble(ncid, ncvarid, attname, 1, &(ncvars[ncvarid].validrange)[1]);
+                      ncvars[ncvarid].lvalidrange = TRUE;
+                    }
+                  else if ( lignore )
+                    {
+                      Warning("Inconsistent data type for attribute %s:valid_max, ignored!", name);
+                    }
+                }
             }
           else if ( strcmp(attname, "_Unsigned") == 0 && atttype == NC_CHAR )
             {
@@ -5229,7 +5223,7 @@ void copy_numeric_projatts(int gridID, int ncvarID, int ncfileID)
 
 /* define all input grids */
 static
-void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nvars, ncvar_t *ncvars, int timedimid)
+void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nvars, ncvar_t *ncvars, int timedimid, char *uuidOfHGrid)
 {
   int ncvarid, ncvarid2;
   int ndims;
@@ -5776,6 +5770,9 @@ void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
 #endif
 	    ncvars[ncvarid].gridID = varDefGrid(vlistID, grid, 1);
 
+          if ( uuidOfHGrid[0] != 0 && grid.type == GRID_UNSTRUCTURED )
+            gridDefUUID(ncvars[ncvarid].gridID, uuidOfHGrid);
+
           if ( ncvars[ncvarid].chunked )
             {
               ndims = ncvars[ncvarid].ndims;
@@ -5791,7 +5788,7 @@ void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
                 {
                   if ( grid.xsize > 1 && grid.ysize > 1 && ndims > 1 &&
                        grid.xsize == ncvars[ncvarid].chunks[ndims-1] &&
-                       grid.ysize == ncvars[ncvarid].chunks[ndims-2] ) 
+                       grid.ysize == ncvars[ncvarid].chunks[ndims-2] )
                     ncvars[ncvarid].chunktype = CHUNK_GRID;
                   else if ( grid.xsize > 1 && grid.xsize == ncvars[ncvarid].chunks[ndims-1] )
                     ncvars[ncvarid].chunktype = CHUNK_LINES;
@@ -5980,7 +5977,7 @@ void define_all_zaxes(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
 	    Message("zaxisID %d %d %s", ncvars[ncvarid].zaxisID, ncvarid, ncvars[ncvarid].name);
 
 	  for ( ncvarid2 = ncvarid+1; ncvarid2 < nvars; ncvarid2++ )
-	    if ( ncvars[ncvarid2].isvar == TRUE && ncvars[ncvarid2].zaxisID == UNDEFID )
+	    if ( ncvars[ncvarid2].isvar == TRUE && ncvars[ncvarid2].zaxisID == UNDEFID && ncvars[ncvarid2].zaxistype == UNDEFID )
 	      {
 		int zdimid2 = -1;
 		ndims = ncvars[ncvarid2].ndims;
@@ -6003,17 +6000,12 @@ void define_all_zaxes(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
 
 /* define all input data variables */
 static
-void define_all_vars(int streamID, int vlistID, int instID, int modelID, int *varids, int nvars, ncvar_t *ncvars)
+void define_all_vars(stream_t *streamptr, int vlistID, int instID, int modelID, int *varids, int nvars, ncvar_t *ncvars)
 {
   int ncid;
   int varID1, varID, ncvarid;
   int code;
   int tableID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   if ( streamptr->sortname )
     {
@@ -6048,7 +6040,7 @@ void define_all_vars(int streamID, int vlistID, int instID, int modelID, int *va
       gridID  = ncvars[ncvarid].gridID;
       zaxisID = ncvars[ncvarid].zaxisID;
 
-      varID = streamNewVar(streamID, gridID, zaxisID);
+      varID = stream_new_var(streamptr, gridID, zaxisID);
       varID = vlistDefVar(vlistID, gridID, zaxisID, ncvars[ncvarid].tsteptype);
 
 #if  defined  (HAVE_NETCDF4)
@@ -6284,10 +6276,9 @@ void define_all_vars(int streamID, int vlistID, int instID, int modelID, int *va
 		  tableID = cdiDefaultTableID;
 		}
 	    }
-	  if ( cdiDefaultModelID != UNDEFID )
-	    modelID = cdiDefaultModelID;
-	  if ( cdiDefaultInstID != UNDEFID )
-	    instID = cdiDefaultInstID;
+
+	  if ( cdiDefaultModelID != UNDEFID ) modelID = cdiDefaultModelID;
+	  if ( cdiDefaultInstID  != UNDEFID ) instID  = cdiDefaultInstID;
 	}
       if ( instID  != UNDEFID ) vlistDefVarInstitut(vlistID, varID, instID);
       if ( modelID != UNDEFID ) vlistDefVarModel(vlistID, varID, modelID);
@@ -6296,8 +6287,8 @@ void define_all_vars(int streamID, int vlistID, int instID, int modelID, int *va
 }
 
 static
-void read_global_attributtes(int fileID, int vlistID, stream_t *streamptr, int ngatts,
-                               int *instID, int *modelID, int *ucla_les)
+void scan_global_attributtes(int fileID, int vlistID, stream_t *streamptr, int ngatts,
+                             int *instID, int *modelID, int *ucla_les, char *uuidOfHGrid)
 {
   nc_type xtype;
   size_t attlen;
@@ -6330,6 +6321,8 @@ void read_global_attributtes(int fileID, int vlistID, stream_t *streamptr, int n
 	      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 )
 		{
@@ -6347,6 +6340,12 @@ void read_global_attributtes(int fileID, int vlistID, stream_t *streamptr, int n
 	      else if ( strcmp(attname, "CDO") == 0 )
 		{
 		}
+	      else if ( strcmp(attname, "uuidOfHGrid") == 0 && attlen == 36 )
+		{
+                  attstring[36] = 0;
+                  str2uuid(attstring, uuidOfHGrid);
+                  //   printf("uuid: %d %s\n", attlen, attstring);
+		}
 	      else
 		{
 		  vlistDefAttTxt(vlistID, CDI_GLOBAL, attname, (int)attlen, attstring);
@@ -6379,7 +6378,7 @@ void read_global_attributtes(int fileID, int vlistID, stream_t *streamptr, int n
 }
 #endif
 
-int cdfInqContents(int streamID)
+int cdfInqContents(stream_t *streamptr)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int ndims, nvars, ngatts, unlimdimid;
@@ -6407,19 +6406,16 @@ int cdfInqContents(int streamID)
   ncdim_t *ncdims;
   ncvar_t *ncvars = NULL;
   int vlistID;
-  stream_t *streamptr;
   int format = 0;
   int ucla_les = FALSE;
+  char uuidOfHGrid[17];
 
-  streamptr = stream_to_pointer(streamID);
+  uuidOfHGrid[0] = 0;
 
-  stream_check_ptr(__func__, streamptr);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
-
-  if ( CDI_Debug )
-    Message("streamID = %d, fileID = %d", streamID, fileID);
+  if ( CDI_Debug ) Message("streamID = %d, fileID = %d", streamptr->self, fileID);
 
 #if  defined  (HAVE_NETCDF4)
   nc_inq_format(fileID, &format);
@@ -6483,8 +6479,8 @@ int cdfInqContents(int streamID)
       return (CDI_EUFSTRUCT);
     }
 
-  /* read global attributtes */
-  read_global_attributtes(fileID, vlistID, streamptr, ngatts, &instID, &modelID, &ucla_les);
+  /* scan global attributtes */
+  scan_global_attributtes(fileID, vlistID, streamptr, ngatts, &instID, &modelID, &ucla_les, uuidOfHGrid);
 
   /* find time dim */
   if ( unlimdimid >= 0 )
@@ -6570,13 +6566,13 @@ int cdfInqContents(int streamID)
 	      {
 		streamptr->basetime.ncvarid = ncvarid;
 		ltimevar = TRUE;
-		if ( CDI_Debug ) 
+		if ( CDI_Debug )
 		  fprintf(stderr, "timevar %s\n", ncvars[ncvarid].name);
 	      }
 	    else
 	      {
 		if ( CDI_Debug )
-		  fprintf(stderr, "skip timevar %s\n", ncvars[ncvarid].name);
+		  fprintf(stderr, "skipped timevar %s\n", ncvars[ncvarid].name);
 	      }
 	  }
 
@@ -6777,7 +6773,7 @@ int cdfInqContents(int streamID)
 
 
   /* define all grids */
-  define_all_grids(streamptr, vlistID, ncdims, nvars, ncvars, timedimid);
+  define_all_grids(streamptr, vlistID, ncdims, nvars, ncvars, timedimid, uuidOfHGrid);
 
 
   /* read VCT */
@@ -6819,10 +6815,10 @@ int cdfInqContents(int streamID)
   streamptr->ntsteps = ntsteps;
 
   /* define all data variables */
-  define_all_vars(streamID, vlistID, instID, modelID, varids, nvars_data, ncvars);
+  define_all_vars(streamptr, vlistID, instID, modelID, varids, nvars_data, ncvars);
 
 
-  cdiCreateTimesteps(streamID);
+  cdiCreateTimesteps(streamptr);
 
   /* time varID */
   ncvarid = streamptr->basetime.ncvarid;
@@ -6912,9 +6908,9 @@ int cdfInqContents(int streamID)
   streamptr->curTsID = 0;
   streamptr->rtsteps = 1;
 
-  (void) cdfInqTimestep(streamID, 0);
+  (void) cdfInqTimestep(streamptr, 0);
 
-  cdfCreateRecords(streamID, 0);
+  cdfCreateRecords(streamptr, 0);
 
   /* free ncdims */
   free (ncdims);
@@ -6928,7 +6924,7 @@ int cdfInqContents(int streamID)
 }
 
 
-int cdfInqTimestep(int streamID, int tsID)
+int cdfInqTimestep(stream_t * streamptr, int tsID)
 {
   long nrecs = 0;
 #if  defined  (HAVE_LIBNETCDF)
@@ -6938,20 +6934,14 @@ int cdfInqTimestep(int streamID, int tsID)
   int fileID;
   size_t index;
   taxis_t *taxis;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  if ( CDI_Debug )
-    Message("streamID = %d  tsID = %d", streamID, tsID);
 
-  stream_check_ptr(__func__, streamptr);
+  if ( CDI_Debug ) Message("streamID = %d  tsID = %d", streamptr->self, tsID);
 
   if ( tsID < 0 ) Error("unexpected tsID = %d", tsID);
 
   if ( tsID < streamptr->ntsteps && streamptr->ntsteps > 0 )
     {
-      cdfCreateRecords(streamID, tsID);
+      cdfCreateRecords(streamptr, tsID);
 
       taxis = &streamptr->tsteps[tsID].taxis;
       if ( tsID > 0 )
@@ -6962,7 +6952,7 @@ int cdfInqTimestep(int streamID, int tsID)
       nctimevarid = streamptr->basetime.ncvarid;
       if ( nctimevarid != UNDEFID )
 	{
-	  fileID = streamInqFileID(streamID);
+	  fileID = streamptr->fileID;
 	  index  = tsID;
 
 	  if ( streamptr->basetime.lwrf )
@@ -6986,7 +6976,7 @@ int cdfInqTimestep(int streamID, int tsID)
 	  else
 	    {
 	      cdf_get_var1_double(fileID, nctimevarid, &index, &timevalue);
-              if ( timevalue >= NC_FILL_DOUBLE ) timevalue = 0;
+              if ( timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE ) timevalue = 0;
 
 	      cdiDecodeTimeval(timevalue, taxis, &taxis->vdate, &taxis->vtime);
 	    }
@@ -6997,13 +6987,13 @@ int cdfInqTimestep(int streamID, int tsID)
 	      size_t start[2], count[2];
 	      start[0] = tsID; count[0] = 1; start[1] = 0; count[1] = 1;
 	      cdf_get_vara_double(fileID, nctimeboundsid, start, count, &timevalue);
-              if ( timevalue >= NC_FILL_DOUBLE ) timevalue = 0;
+              if ( timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE ) timevalue = 0;
 
 	      cdiDecodeTimeval(timevalue, taxis, &taxis->vdate_lb, &taxis->vtime_lb);
 
 	      start[0] = tsID; count[0] = 1; start[1] = 1; count[1] = 1;
 	      cdf_get_vara_double(fileID, nctimeboundsid, start, count, &timevalue);
-              if ( timevalue >= NC_FILL_DOUBLE ) timevalue = 0;
+              if ( timevalue >= NC_FILL_DOUBLE || timevalue < -NC_FILL_DOUBLE ) timevalue = 0;
 
 	      cdiDecodeTimeval(timevalue, taxis, &taxis->vdate_ub, &taxis->vtime_ub);
 	    }
@@ -7018,20 +7008,17 @@ int cdfInqTimestep(int streamID, int tsID)
 }
 
 
-void cdfEndDef(int streamID)
+void cdfEndDef(stream_t *streamptr)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int varID;
   int nvars;
   int fileID;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
+  fileID  = streamptr->fileID;
 
-  fileID  = streamInqFileID(streamID);
-
-  cdfDefGlobalAtts(streamID);
-  cdfDefLocalAtts(streamID);
+  cdfDefGlobalAtts(streamptr);
+  cdfDefLocalAtts(streamptr);
   if ( streamptr->accessmode == 0 )
     {
       nvars =  streamptr->nvars;
@@ -7039,7 +7026,7 @@ void cdfEndDef(int streamID)
       if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
 
       for ( varID = 0; varID < nvars; varID++ )
-	cdfDefVar(streamID, varID);
+	cdfDefVar(streamptr, varID);
 
       if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
 
@@ -7049,19 +7036,16 @@ void cdfEndDef(int streamID)
 }
 
 
-void cdfDefInstitut(int streamID)
+void cdfDefInstitut(stream_t *streamptr)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int fileID, instID;
   char *longname;
   size_t len;
   int vlistID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
   instID  = vlistInqInstitut(vlistID);
 
   if ( instID != UNDEFID )
@@ -7081,19 +7065,17 @@ void cdfDefInstitut(int streamID)
 #endif
 }
 
-void cdfDefSource(int streamID)
+
+void cdfDefSource(stream_t *streamptr)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int fileID, modelID;
   char *longname;
   size_t len;
   int vlistID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
   modelID = vlistInqModel(vlistID);
 
   if ( modelID != UNDEFID )
@@ -7114,22 +7096,19 @@ void cdfDefSource(int streamID)
 }
 
 
-void cdfDefGlobalAtts(int streamID)
+void cdfDefGlobalAtts(stream_t *streamptr)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int fileID, vlistID;
-  stream_t *streamptr;
   int natts;
 
-  streamptr = stream_to_pointer(streamID);
-
   if ( streamptr->globalatts ) return;
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
-  cdfDefSource(streamID);
-  cdfDefInstitut(streamID);
+  cdfDefSource(streamptr);
+  cdfDefInstitut(streamptr);
 
   vlistInqNatts(vlistID, CDI_GLOBAL, &natts);
 
@@ -7144,7 +7123,7 @@ void cdfDefGlobalAtts(int streamID)
 }
 
 
-void cdfDefLocalAtts(int streamID)
+void cdfDefLocalAtts(stream_t *streamptr)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int varID, instID, fileID;
@@ -7152,12 +7131,9 @@ void cdfDefLocalAtts(int streamID)
   size_t len;
   int ncvarid;
   int vlistID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
 
   if ( streamptr->localatts ) return;
   if ( vlistInqInstitut(vlistID) != UNDEFID ) return;
@@ -7185,27 +7161,23 @@ void cdfDefLocalAtts(int streamID)
 #endif
 }
 
-void cdfDefHistory(int streamID, int size, char *history)
+
+void cdfDefHistory(stream_t *streamptr, int size, char *history)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int ncid;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   ncid = streamptr->fileID;
   cdf_put_att_text(ncid, NC_GLOBAL, "history", (size_t) size, history);
 #endif
 }
 
-int cdfInqHistorySize(int streamID)
+
+int cdfInqHistorySize(stream_t *streamptr)
 {
   size_t size = 0;
 #if  defined  (HAVE_LIBNETCDF)
   int ncid;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   ncid = streamptr->fileID;
   if ( streamptr->historyID != UNDEFID )
@@ -7216,13 +7188,10 @@ int cdfInqHistorySize(int streamID)
 }
 
 
-void cdfInqHistoryString(int streamID, char *history)
+void cdfInqHistoryString(stream_t *streamptr, char *history)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int ncid;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   ncid = streamptr->fileID;
   if ( streamptr->historyID != UNDEFID )
@@ -7232,42 +7201,39 @@ void cdfInqHistoryString(int streamID, char *history)
 }
 
 
-void cdfDefVars(int streamID)
+void cdfDefVars(stream_t *streamptr)
 {
 #if  defined  (HAVE_LIBNETCDF)
   int index, gridID, zaxisID, vlistID;
   int ngrids, nzaxis;
   /* int  nvars, ncvarid; */
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   if ( vlistID == UNDEFID )
-    Error("Internal problem! vlist undefined for streamID %d", streamID);
+    Error("Internal problem! vlist undefined for streamptr %p", streamptr);
 
   /* nvars  = vlistNvars(vlistID); */
   ngrids = vlistNgrids(vlistID);
   nzaxis = vlistNzaxis(vlistID);
   /*
-  if ( vlistHasTime(vlistID) ) cdfDefTime(streamID);
+  if ( vlistHasTime(vlistID) ) cdfDefTime(streamptr);
   */
   for ( index = 0; index < ngrids; index++ )
     {
       gridID = vlistGrid(vlistID, index);
-      cdfDefGrid(streamID, gridID);
+      cdfDefGrid(streamptr, gridID);
     }
 
   for ( index = 0; index < nzaxis; index++ )
     {
       zaxisID = vlistZaxis(vlistID, index);
-      if ( streamptr->zaxisID[index] == UNDEFID ) cdfDefZaxis(streamID, zaxisID);
+      if ( streamptr->zaxisID[index] == UNDEFID ) cdfDefZaxis(streamptr, zaxisID);
     }
   /*
     define time first!!!
   for (varID = 0; varID < nvars; varID++ )
     {
-      ncvarid = cdfDefVar(streamID, varID);
+      ncvarid = cdfDefVar(streamptr, varID);
     }
   */
 #endif
diff --git a/libcdi/src/stream_cdf.h b/libcdi/src/stream_cdf.h
index c00652e..efe47ef 100644
--- a/libcdi/src/stream_cdf.h
+++ b/libcdi/src/stream_cdf.h
@@ -1,27 +1,27 @@
 #ifndef _STREAM_CDF_H
 #define _STREAM_CDF_H
 
-void   cdfDefVars(int streamID);
-void   cdfDefTimestep(int streamID, int tsID);
-int    cdfInqTimestep(int streamID, int tsID);
-int    cdfInqContents(int streamID);
-void   cdfDefHistory(int streamID, int size, char *history);
-int    cdfInqHistorySize(int streamID);
-void   cdfInqHistoryString(int streamID, char *history);
+void   cdfDefVars(stream_t *streamptr);
+void   cdfDefTimestep(stream_t *streamptr, int tsID);
+int    cdfInqTimestep(stream_t *streamptr, int tsID);
+int    cdfInqContents(stream_t *streamptr);
+void   cdfDefHistory(stream_t *streamptr, int size, char *history);
+int    cdfInqHistorySize(stream_t *streamptr);
+void   cdfInqHistoryString(stream_t *streamptr, char *history);
 
-void   cdfEndDef(int streamID);
-int    cdfDefRecord(int streamID);
+void   cdfEndDef(stream_t * streamptr);
+int    cdfDefRecord(stream_t * streamptr);
 
-int    cdfCopyRecord(int streamIDdest, int streamIDsrc);
+int    cdfCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
 
-int    cdfReadRecord(int streamID, double *data, int *nmiss);
-void   cdf_write_record(int streamID, int memtype, const void *data, int nmiss);
+int    cdfReadRecord(stream_t *streamptr, double *data, int *nmiss);
+void   cdf_write_record(stream_t *streamptr, int memtype, const void *data, int nmiss);
 
-void   cdfReadVarDP(int streamID, int varID, double *data, int *nmiss);
-void   cdf_write_var(int streamID, int varID, int memtype, const void *data, int nmiss);
+void   cdfReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss);
+void   cdf_write_var(stream_t *streamptr, int varID, int memtype, const void *data, int nmiss);
 
-int    cdfReadVarSliceDP(int streamID, int varID, int levelID, double *data, int *nmiss);
-int    cdf_write_var_slice(int streamID, int varID, int levelID, int memtype, const void *data, int nmiss);
+int    cdfReadVarSliceDP(stream_t *streamptr, int varID, int levelID, double *data, int *nmiss);
+int    cdf_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, int nmiss);
 
 #endif
 /*
diff --git a/libcdi/src/stream_cgribex.c b/libcdi/src/stream_cgribex.c
index b473af0..1626d06 100644
--- a/libcdi/src/stream_cgribex.c
+++ b/libcdi/src/stream_cgribex.c
@@ -105,6 +105,7 @@ int cgribexGetTimeUnit(int *isec1)
 	  Message("GRIB time unit %d unsupported!", ISEC1_TimeUnit);
 	  lprint = FALSE;
 	}
+      break;
     }
 
   return (timeunit);
@@ -124,7 +125,7 @@ int cgribexTimeIsFC(int *isec1)
 static
 int cgribexGetTsteptype(int timerange)
 {
-  int tsteptype = 0;
+  int tsteptype = TSTEP_INSTANT;
   static int lprint = TRUE;
 
   switch ( timerange )
@@ -142,6 +143,7 @@ int cgribexGetTsteptype(int timerange)
 	  Message("GRIB time range %d unsupported!", timerange);
 	  lprint = FALSE;
 	}
+      break;
     }
 
   return (tsteptype);
@@ -188,6 +190,7 @@ void cgribexGetGrid(stream_t *streamptr, int *isec2, int *isec4, grid_t *grid, i
 
 		if ( ISEC2_ResFlag && ISEC2_LonIncr > 0 )
                   {
+                    if ( ISEC2_LastLon < ISEC2_FirstLon && ISEC2_LastLon < 0 ) ISEC2_LastLon += 360000;
                     if ( abs(ISEC2_LastLon - (ISEC2_FirstLon+ISEC2_LonIncr*(grid->xsize-1))) <= 2 )
                       {
                         recompinc = FALSE;
@@ -351,7 +354,7 @@ void cgribexGetGrid(stream_t *streamptr, int *isec2, int *isec4, grid_t *grid, i
 }
 
 static
-void cgribexAddRecord(int streamID, int param, int *isec1, int *isec2, double *fsec2, double *fsec3,
+void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, double *fsec2, double *fsec3,
 		      int *isec4, long recsize, off_t position, int datatype, int comptype, int lmv, int iret)
 {
   int zaxistype;
@@ -365,13 +368,10 @@ void cgribexAddRecord(int streamID, int param, int *isec1, int *isec2, double *f
   record_t *record;
   grid_t grid;
   int vlistID;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   tsID    = streamptr->curTsID;
-  recID   = recordNewEntry(streamID, tsID);
+  recID   = recordNewEntry(streamptr, tsID);
   record  = &streamptr->tsteps[tsID].records[recID];
 
   tsteptype = cgribexGetTsteptype(ISEC1_TimeRange);
@@ -408,7 +408,7 @@ void cgribexAddRecord(int streamID, int param, int *isec1, int *isec2, double *f
   if ( datatype > 32 ) datatype = DATATYPE_PACK32;
   if ( datatype <  0 ) datatype = DATATYPE_PACK;
 
-  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2,
+  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, 0,
 	       datatype, &varID, &levelID, tsteptype, numavg, ISEC1_LevelType, NULL, NULL, NULL);
 
   (*record).varID   = varID;
@@ -513,9 +513,38 @@ void cgribexDecodeHeader(int *isec0, int *isec1, int *isec2, double *fsec2,
       *lmv = 1;
     }
 }
+
+static
+compvar_t cgribexVarSet(int param, int level1, int level2, int leveltype)
+{
+  compvar_t compVar;
+
+  compVar.param  = param;
+  compVar.level1 = level1;
+  compVar.level2 = level2;
+  compVar.ltype  = leveltype;
+
+  return (compVar);
+}
+
+static
+int cgribexVarCompare(compvar_t compVar, record_t record)
+{
+  int rstatus;
+  compvar_t compVar0;
+
+  compVar0.param  = record.param;
+  compVar0.level1 = record.ilevel;
+  compVar0.level2 = record.ilevel2;
+  compVar0.ltype  = record.ltype;
+
+  rstatus = memcmp(&compVar0, &compVar, sizeof(compvar_t));
+
+  return (rstatus);
+}
 #endif
 
-int cgribexScanTimestep1(int streamID)
+int cgribexScanTimestep1(stream_t * streamptr)
 {
 #if  defined  (HAVE_LIBCGRIBEX)
   int *isec0, *isec1, *isec2, *isec3, *isec4;
@@ -533,6 +562,7 @@ int cgribexScanTimestep1(int streamID)
   int varID;
   size_t readsize;
   int nrecords, nrecs, recID;
+  int nrecs_scanned;
   int datatype;
   long recsize = 0;
   int warn_time = TRUE;
@@ -543,15 +573,10 @@ int cgribexScanTimestep1(int streamID)
   int vlistID;
   int comptype;
   long unzipsize;
-  compvar_t compVar, compVar0;
-  stream_t *streamptr;
+  compvar_t compVar;
   extern int cdiSkipRecords;
   int nskip = cdiSkipRecords;
 
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
-
   streamptr->curTsID = 0;
 
   isec0 = streamptr->record->sec0;
@@ -560,13 +585,13 @@ int cgribexScanTimestep1(int streamID)
   isec3 = streamptr->record->sec3;
   isec4 = streamptr->record->sec4;
 
-  tsID  = tstepsNewEntry(streamID);
+  tsID  = tstepsNewEntry(streamptr);
   taxis = &streamptr->tsteps[tsID].taxis;
 
   if ( tsID != 0 )
     Error("Internal problem! tstepsNewEntry returns %d", tsID);
 
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
 
   while ( nskip-- > 0 )
     {
@@ -578,6 +603,7 @@ int cgribexScanTimestep1(int streamID)
       fileSetPos(fileID, recsize, SEEK_CUR);
     }
 
+  nrecs_scanned = 0;
   nrecs = 0;
   while ( TRUE )
     {
@@ -614,6 +640,7 @@ int cgribexScanTimestep1(int streamID)
 	    }
 	}
 
+      nrecs_scanned++;
       cgribexDecodeHeader(isec0, isec1, isec2, fsec2, isec3, fsec3, isec4, fsec4,
 			  (int *) gribbuffer, recsize, &lmv, &iret);
 
@@ -643,18 +670,12 @@ int cgribexScanTimestep1(int streamID)
 	{
 	  datetime.date  = vdate;
 	  datetime.time  = vtime;
-	  compVar.param  = param;
-          compVar.level1 = level1;
-          compVar.level2 = level2;
-          compVar.ltype  = ISEC1_LevelType;
+
+	  compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType);
+
 	  for ( recID = 0; recID < nrecs; recID++ )
 	    {
-	      compVar0.param  = streamptr->tsteps[0].records[recID].param;
-	      compVar0.level1 = streamptr->tsteps[0].records[recID].ilevel;
-	      compVar0.level2 = streamptr->tsteps[0].records[recID].ilevel2;
-	      compVar0.ltype  = streamptr->tsteps[0].records[recID].ltype;
-
-	      if ( memcmp(&compVar0, &compVar, sizeof(compvar_t)) == 0 ) break;
+	      if ( cgribexVarCompare(compVar, streamptr->tsteps[0].records[recID]) == 0 ) break;
 	    }
 
 	  if ( cdiInventoryMode == 1 )
@@ -677,7 +698,7 @@ int cgribexScanTimestep1(int streamID)
 		{
 		  char paramstr[32];
 		  cdiParamToString(param, paramstr, sizeof(paramstr));
-		  Warning("Param=%s level=%d already exist, skipped!", paramstr, level1);
+		  Warning("Param=%s level=%d (record %d) already exist, skipped!", paramstr, level1, nrecs_scanned);
 		  continue;
 		}
 	    }
@@ -702,7 +723,7 @@ int cgribexScanTimestep1(int streamID)
       if ( CDI_Debug )
 	Message("%4d %8d %4d  %8d %8d %6d", nrecs, (int)recpos, param, level1, vdate, vtime);
 
-      cgribexAddRecord(streamID, param, isec1, isec2, fsec2, fsec3,
+      cgribexAddRecord(streamptr, param, isec1, isec2, fsec2, fsec3,
 		       isec4, recsize, recpos, datatype, comptype, lmv, iret);
     }
 
@@ -710,7 +731,7 @@ int cgribexScanTimestep1(int streamID)
 
   if ( nrecs == 0 ) return (CDI_EUFSTRUCT);
 
-  cdiGenVars(streamID);
+  cdi_generate_vars(streamptr);
 
   if ( fcast )
     {
@@ -730,7 +751,7 @@ int cgribexScanTimestep1(int streamID)
   taxis->vdate = datetime0.date;
   taxis->vtime = datetime0.time;
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   vlistDefTaxis(vlistID, taxisID);
 
   nrecords = streamptr->tsteps[0].nallrecs;
@@ -751,7 +772,7 @@ int cgribexScanTimestep1(int streamID)
 
   if ( streamptr->ntsteps == -1 )
     {
-      tsID = tstepsNewEntry(streamID);
+      tsID = tstepsNewEntry(streamptr);
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
@@ -778,7 +799,7 @@ int cgribexScanTimestep1(int streamID)
 }
 
 
-int cgribexScanTimestep2(int streamID)
+int cgribexScanTimestep2(stream_t * streamptr)
 {
   int rstatus = 0;
 #if  defined  (HAVE_LIBCGRIBEX)
@@ -803,12 +824,7 @@ int cgribexScanTimestep2(int streamID)
   taxis_t *taxis;
   int vlistID;
   long unzipsize;
-  compvar_t compVar, compVar0;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
+  compvar_t compVar;
 
   streamptr->curTsID = 1;
 
@@ -818,8 +834,8 @@ int cgribexScanTimestep2(int streamID)
   isec3 = streamptr->record->sec3;
   isec4 = streamptr->record->sec4;
 
-  fileID  = streamInqFileID(streamID);
-  vlistID = streamInqVlist(streamID);
+  fileID  = streamptr->fileID;
+  vlistID = streamptr->vlistID;
   taxisID = vlistInqTaxis(vlistID);
 
   gribbuffer = (unsigned char *) streamptr->record->buffer;
@@ -833,10 +849,10 @@ int cgribexScanTimestep2(int streamID)
 
   fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-  cdiCreateRecords(streamID, tsID);
+  cdi_create_records(streamptr, tsID);
 
   nrecords = streamptr->tsteps[tsID].nallrecs;
-  streamptr->tsteps[1].recIDs = (int *) malloc(nrecords*sizeof(int));
+  if ( nrecords ) streamptr->tsteps[1].recIDs = (int *) malloc(nrecords*sizeof(int));
   streamptr->tsteps[1].nrecs = 0;
   for ( recID = 0; recID < nrecords; recID++ )
     streamptr->tsteps[1].recIDs[recID] = -1;
@@ -932,18 +948,12 @@ int cgribexScanTimestep2(int streamID)
 
       datetime.date  = vdate;
       datetime.time  = vtime;
-      compVar.param  = param;
-      compVar.level1 = level1;
-      compVar.level2 = level2;
-      compVar.ltype  = ISEC1_LevelType;
+
+      compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType);
+
       for ( recID = 0; recID < nrecords; recID++ )
 	{
-	  compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
-	  compVar0.level1 = streamptr->tsteps[tsID].records[recID].ilevel;
-	  compVar0.level2 = streamptr->tsteps[tsID].records[recID].ilevel2;
-	  compVar0.ltype  = streamptr->tsteps[tsID].records[recID].ltype;
-
-	  if ( memcmp(&compVar0, &compVar, sizeof(compvar_t)) == 0 ) break;
+	  if ( cgribexVarCompare(compVar, streamptr->tsteps[tsID].records[recID]) == 0 ) break;
 	}
 
       if ( recID == nrecords )
@@ -990,12 +1000,7 @@ int cgribexScanTimestep2(int streamID)
 
       streamptr->tsteps[tsID].records[recID].size = recsize;
 
-      compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
-      compVar0.level1 = streamptr->tsteps[tsID].records[recID].ilevel;
-      compVar0.level2 = streamptr->tsteps[tsID].records[recID].ilevel2;
-      compVar0.ltype  = streamptr->tsteps[tsID].records[recID].ltype;
-
-      if ( memcmp(&compVar0, &compVar, sizeof(compvar_t)) != 0 )
+      if ( cgribexVarCompare(compVar, streamptr->tsteps[tsID].records[recID]) != 0 )
 	{
 	  Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
 		  tsID, recID,
@@ -1039,7 +1044,7 @@ int cgribexScanTimestep2(int streamID)
 
   if ( streamptr->ntsteps == -1 )
     {
-      tsID = tstepsNewEntry(streamID);
+      tsID = tstepsNewEntry(streamptr);
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
@@ -1055,7 +1060,7 @@ int cgribexScanTimestep2(int streamID)
 }
 
 
-int cgribexScanTimestep(int streamID)
+int cgribexScanTimestep(stream_t * streamptr)
 {
   int rstatus = 0;
 #if  defined  (HAVE_LIBCGRIBEX)
@@ -1079,18 +1084,13 @@ int cgribexScanTimestep(int streamID)
   int vlistID;
   int rindex, nrecs = 0;
   long unzipsize;
-  compvar_t compVar, compVar0;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
+  compvar_t compVar;
 
-  stream_check_ptr(__func__, streamptr);
-
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
 
   if ( CDI_Debug )
     {
-      Message("streamID = %d", streamID);
+      Message("streamID = %d", streamptr->self);
       Message("cts = %d", streamptr->curTsID);
       Message("rts = %d", streamptr->rtsteps);
       Message("nts = %d", streamptr->ntsteps);
@@ -1110,7 +1110,7 @@ int cgribexScanTimestep(int streamID)
       gribbuffer = (unsigned char *) streamptr->record->buffer;
       buffersize = streamptr->record->buffersize;
 
-      cdiCreateRecords(streamID, tsID);
+      cdi_create_records(streamptr, tsID);
 
       nrecs = streamptr->tsteps[1].nrecs;
 
@@ -1119,7 +1119,7 @@ int cgribexScanTimestep(int streamID)
       for ( recID = 0; recID < nrecs; recID++ )
 	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
 
-      fileID = streamInqFileID(streamID);
+      fileID = streamptr->fileID;
 
       fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
@@ -1215,19 +1215,13 @@ int cgribexScanTimestep(int streamID)
 
 	  datetime.date  = vdate;
 	  datetime.time  = vtime;
-	  compVar.param  = param;
-          compVar.level1 = level1;
-          compVar.level2 = level2;
-          compVar.ltype  = ISEC1_LevelType;
+
+	  compVar = cgribexVarSet(param, level1, level2, ISEC1_LevelType);
+
 	  for ( vrecID = 0; vrecID < nrecs; vrecID++ )
 	    {
 	      recID   = streamptr->tsteps[1].recIDs[vrecID];
-	      compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
-	      compVar0.level1 = streamptr->tsteps[tsID].records[recID].ilevel;
-	      compVar0.level2 = streamptr->tsteps[tsID].records[recID].ilevel2;
-	      compVar0.ltype  = streamptr->tsteps[tsID].records[recID].ltype;
-
-	      if ( memcmp(&compVar0, &compVar, sizeof(compvar_t)) == 0 ) break;
+	      if ( cgribexVarCompare(compVar, streamptr->tsteps[tsID].records[recID]) == 0 ) break;
 	    }
 
 	  if ( vrecID == nrecs )
@@ -1271,12 +1265,7 @@ int cgribexScanTimestep(int streamID)
 	  if ( CDI_Debug )
 	    Message("%4d %8d %4d %8d %8d %6d", rindex+1, (int)recpos, param, level1, vdate, vtime);
 
-	  compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
-	  compVar0.level1 = streamptr->tsteps[tsID].records[recID].ilevel;
-	  compVar0.level2 = streamptr->tsteps[tsID].records[recID].ilevel2;
-	  compVar0.ltype  = streamptr->tsteps[tsID].records[recID].ltype;
-
-	  if ( memcmp(&compVar0, &compVar, sizeof(compvar_t)) != 0 )
+	  if ( cgribexVarCompare(compVar, streamptr->tsteps[tsID].records[recID]) != 0 )
 	    {
 	      Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
 		      tsID, recID,
@@ -1313,7 +1302,7 @@ int cgribexScanTimestep(int streamID)
 
       if ( streamptr->ntsteps != streamptr->rtsteps )
 	{
-	  tsID = tstepsNewEntry(streamID);
+	  tsID = tstepsNewEntry(streamptr);
 	  if ( tsID != streamptr->rtsteps )
 	    Error("Internal error. tsID = %d", tsID);
 
@@ -1493,11 +1482,11 @@ int cgribexDefTimerange(int tsteptype, int factor, int calendar,
 
   cdiDecodeDate(rdate, &year, &month, &day);
   cdiDecodeTime(rtime, &hour, &minute, &second);
-  encode_juldaysec(calendar, year, month, day, hour, minute, &julday1, &secofday1);
+  encode_juldaysec(calendar, year, month, day, hour, minute, second, &julday1, &secofday1);
 
   cdiDecodeDate(vdate, &year, &month, &day);
   cdiDecodeTime(vtime, &hour, &minute, &second);
-  encode_juldaysec(calendar, year, month, day, hour, minute, &julday2, &secofday2);
+  encode_juldaysec(calendar, year, month, day, hour, minute, second, &julday2, &secofday2);
 
   (void) julday_sub(julday1, secofday1, julday2, secofday2, &days, &secs);
 
@@ -1890,6 +1879,7 @@ void cgribexDefGrid(int *isec1, int *isec2, int *isec4, int gridID)
       {
 	Warning("The CGRIBEX library can not store fields on the used grid!");
 	Error("Unsupported grid type: %s", gridNamePtr(gridtype));
+	break;
       }
     }
 }
@@ -1926,6 +1916,27 @@ void cgribexDefLevel(int *isec1, int *isec2, double *fsec2, int zaxisID, int lev
 	ISEC1_Level2    = 0;
 	break;
       }
+    case ZAXIS_CLOUD_BASE:
+      {
+	ISEC1_LevelType = GRIB1_LTYPE_CLOUDBASE;
+	ISEC1_Level1    = 0;
+	ISEC1_Level2    = 0;
+	break;
+      }
+    case ZAXIS_CLOUD_TOP:
+      {
+	ISEC1_LevelType = GRIB1_LTYPE_CLOUDTOP;
+	ISEC1_Level1    = 0;
+	ISEC1_Level2    = 0;
+	break;
+      }
+    case ZAXIS_ISOTHERM_ZERO:
+      {
+	ISEC1_LevelType = GRIB1_LTYPE_ISOTHERM0;
+	ISEC1_Level1    = 0;
+	ISEC1_Level2    = 0;
+	break;
+      }
     case ZAXIS_TOA:
       {
 	ISEC1_LevelType = GRIB1_LTYPE_TOA;
diff --git a/libcdi/src/stream_cgribex.h b/libcdi/src/stream_cgribex.h
index de320c1..8a8ae79 100644
--- a/libcdi/src/stream_cgribex.h
+++ b/libcdi/src/stream_cgribex.h
@@ -1,9 +1,9 @@
 #ifndef _STREAM_CGRIBEX_H
 #define _STREAM_CGRIBEX_H
 
-int cgribexScanTimestep1(int streamID);
-int cgribexScanTimestep2(int streamID);
-int cgribexScanTimestep(int streamID);
+int cgribexScanTimestep1(stream_t * streamptr);
+int cgribexScanTimestep2(stream_t * streamptr);
+int cgribexScanTimestep(stream_t * streamptr);
 
 int cgribexDecode(unsigned char *gribbuffer, int gribsize, double *data, int gridsize,
 		  int unreduced, int *nmiss, int *zip, double missval);
diff --git a/libcdi/src/stream_ext.c b/libcdi/src/stream_ext.c
index 4b32c72..ceafb4b 100644
--- a/libcdi/src/stream_ext.c
+++ b/libcdi/src/stream_ext.c
@@ -29,7 +29,7 @@
 typedef struct {
   int param;
   int level;
-} extcompvar_t; 
+} extcompvar_t;
 
 static
 int extInqDatatype(int prec, int number)
@@ -70,7 +70,7 @@ void extDefDatatype(int datatype, int *prec, int *number)
 }
 
 /* not used
-int extInqRecord(int streamID, int *varID, int *levelID)
+int extInqRecord(stream_t *streamptr, int *varID, int *levelID)
 {
   int status;
   int fileID;
@@ -79,14 +79,9 @@ int extInqRecord(int streamID, int *varID, int *levelID)
   int header[4];
   int vlistID;
   extrec_t *extp;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
-
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
   extp    = streamptr->record->extp;
 
   *varID   = -1;
@@ -107,12 +102,12 @@ int extInqRecord(int streamID, int *varID, int *levelID)
   zaxisID = vlistInqVarZaxis(vlistID, *varID);
 
   *levelID = zaxisInqLevelID(zaxisID, (double) ilevel);
-  
+
   return (1);
 }
 */
 
-int extReadRecord(int streamID, double *data, int *nmiss)
+int extReadRecord(stream_t *streamptr, double *data, int *nmiss)
 {
   int vlistID, fileID;
   int status;
@@ -123,14 +118,9 @@ int extReadRecord(int streamID, double *data, int *nmiss)
   int i, size;
   double missval;
   extrec_t *extp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
   tsID    = streamptr->curTsID;
   vrecID  = streamptr->tsteps[tsID].curRecID;
   recID   = streamptr->tsteps[tsID].recIDs[vrecID];
@@ -176,7 +166,7 @@ int extReadRecord(int streamID, double *data, int *nmiss)
 }
 
 
-int extCopyRecord(int streamID2, int streamID1)
+int extCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
 {
   int fileID1, fileID2;
   int tsID, recID, vrecID;
@@ -184,17 +174,9 @@ int extCopyRecord(int streamID2, int streamID1)
   off_t recpos;
   int status = 0;
   char *buffer;
-  stream_t *streamptr1;
-  stream_t *streamptr2;
 
-  streamptr1 = stream_to_pointer(streamID1);
-  streamptr2 = stream_to_pointer(streamID2);
-
-  stream_check_ptr(__func__, streamptr1);
-  stream_check_ptr(__func__, streamptr2);
-
-  fileID1 = streamInqFileID(streamID1);
-  fileID2 = streamInqFileID(streamID2);
+  fileID1 = streamptr1->fileID;
+  fileID2 = streamptr2->fileID;
 
   tsID    = streamptr1->curTsID;
   vrecID  = streamptr1->tsteps[tsID].curRecID;
@@ -216,18 +198,13 @@ int extCopyRecord(int streamID2, int streamID1)
 }
 
 
-int extDefRecord(int streamID)
+int extDefRecord(stream_t *streamptr)
 {
   int gridID;
   int header[4];
   int status = 0;
   int pdis, pcat, pnum;
   extrec_t *extp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   gridID   = streamptr->record->gridID;
   extp     = streamptr->record->extp;
@@ -246,18 +223,13 @@ int extDefRecord(int streamID)
 }
 
 
-int extWriteRecord(int streamID, const double *data)
+int extWriteRecord(stream_t *streamptr, const double *data)
 {
   int fileID;
   int status = 0;
   extrec_t *extp;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
-
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
   extp   = streamptr->record->extp;
 
   extDefDataDP(extp, data);
@@ -268,7 +240,7 @@ int extWriteRecord(int streamID, const double *data)
 }
 
 static
-void extAddRecord(int streamID, int param, int level, int xysize,
+void extAddRecord(stream_t *streamptr, int param, int level, int xysize,
 		  long recsize, off_t position, int prec, int number)
 {
   int leveltype;
@@ -278,13 +250,10 @@ void extAddRecord(int streamID, int param, int level, int xysize,
   record_t *record;
   grid_t grid;
   int vlistID;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   tsID    = streamptr->curTsID;
-  recID   = recordNewEntry(streamID, tsID);
+  recID   = recordNewEntry(streamptr, tsID);
   record  = &streamptr->tsteps[tsID].records[recID];
 
   (*record).size     = recsize;
@@ -306,7 +275,7 @@ void extAddRecord(int streamID, int param, int level, int xysize,
   */
   leveltype = ZAXIS_GENERIC;
 
-  varAddRecord(recID, param, gridID, leveltype, 0, level, 0,
+  varAddRecord(recID, param, gridID, leveltype, 0, level, 0, 0,
 	       extInqDatatype(prec, number), &varID, &levelID, UNDEFID, 0, 0, NULL, NULL, NULL);
 
   (*record).varID   = varID;
@@ -321,15 +290,12 @@ void extAddRecord(int streamID, int param, int level, int xysize,
 }
 
 
-void extCmpRecord(int streamID, int tsID, int recID, off_t position, int param,
+void extCmpRecord(stream_t *streamptr, int tsID, int recID, off_t position, int param,
 		  int level, int xysize)
 {
   int varID = 0;
   int levelID = 0;
   record_t *record;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   record  = &streamptr->tsteps[tsID].records[recID];
 
@@ -351,8 +317,8 @@ void extCmpRecord(int streamID, int tsID, int recID, off_t position, int param,
 }
 
 static
-void extScanTimestep1(int streamID)
-{  
+void extScanTimestep1(stream_t *streamptr)
+{
   int header[4];
   int status;
   int fileID;
@@ -370,22 +336,17 @@ void extScanTimestep1(int streamID)
   int vlistID;
   extcompvar_t compVar, compVar0;
   extrec_t *extp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   streamptr->curTsID = 0;
 
   extp  = streamptr->record->extp;
-  tsID  = tstepsNewEntry(streamID);
+  tsID  = tstepsNewEntry(streamptr);
   taxis = &streamptr->tsteps[tsID].taxis;
 
   if ( tsID != 0 )
     Error("Internal problem! tstepsNewEntry returns %d", tsID);
 
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
 
   nrecs = 0;
   while ( TRUE )
@@ -437,22 +398,22 @@ void extScanTimestep1(int streamID)
       if ( CDI_Debug )
 	Message("%4d%8d%4d%8d%8d%6d", nrecs, (int)recpos, rcode, rlevel, vdate, vtime);
 
-      extAddRecord(streamID, param, rlevel, rxysize, recsize, recpos, extp->prec, extp->number);
+      extAddRecord(streamptr, param, rlevel, rxysize, recsize, recpos, extp->prec, extp->number);
     }
 
   streamptr->rtsteps = 1;
 
-  cdiGenVars(streamID);
+  cdi_generate_vars(streamptr);
 
   taxisID = taxisCreate(TAXIS_ABSOLUTE);
   taxis->type  = TAXIS_ABSOLUTE;
   taxis->vdate = datetime0.date;
   taxis->vtime = datetime0.time;
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   vlistDefTaxis(vlistID, taxisID);
 
-  cdiCheckContents(streamID);
+  vlist_check_contents(vlistID);
 
   nrecords = streamptr->tsteps[0].nallrecs;
   if ( nrecords < streamptr->tsteps[0].recordSize )
@@ -469,7 +430,7 @@ void extScanTimestep1(int streamID)
 
   if ( streamptr->ntsteps == -1 )
     {
-      tsID = tstepsNewEntry(streamID);
+      tsID = tstepsNewEntry(streamptr);
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
@@ -491,8 +452,8 @@ void extScanTimestep1(int streamID)
 }
 
 static
-int extScanTimestep2(int streamID)
-{  
+int extScanTimestep2(stream_t *streamptr)
+{
   int header[4];
   int status;
   int fileID;
@@ -509,16 +470,11 @@ int extScanTimestep2(int streamID)
   int vlistID;
   extcompvar_t compVar, compVar0;
   extrec_t *extp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   streamptr->curTsID = 1;
 
-  fileID  = streamInqFileID(streamID);
-  vlistID = streamInqVlist(streamID);
+  fileID  = streamptr->fileID;
+  vlistID = streamptr->vlistID;
   extp    = streamptr->record->extp;
 
   tsID = streamptr->rtsteps;
@@ -529,7 +485,7 @@ int extScanTimestep2(int streamID)
 
   fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-  cdiCreateRecords(streamID, tsID);
+  cdi_create_records(streamptr, tsID);
 
   nrecords = streamptr->tsteps[0].nallrecs;
   streamptr->tsteps[1].recIDs = (int *) malloc(nrecords*sizeof(int));
@@ -540,9 +496,9 @@ int extScanTimestep2(int streamID)
   for ( recID = 0; recID < nrecords; recID++ )
     {
       varID = streamptr->tsteps[0].records[recID].varID;
-      streamptr->tsteps[tsID].records[recID].position = 
+      streamptr->tsteps[tsID].records[recID].position =
 	streamptr->tsteps[0].records[recID].position;
-      streamptr->tsteps[tsID].records[recID].size     = 
+      streamptr->tsteps[tsID].records[recID].size     =
 	streamptr->tsteps[0].records[recID].size;
     }
 
@@ -643,7 +599,7 @@ int extScanTimestep2(int streamID)
 
   if ( streamptr->ntsteps == -1 )
     {
-      tsID = tstepsNewEntry(streamID);
+      tsID = tstepsNewEntry(streamptr);
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
@@ -655,23 +611,18 @@ int extScanTimestep2(int streamID)
 }
 
 
-int extInqContents(int streamID)
+int extInqContents(stream_t *streamptr)
 {
   int fileID;
   int status = 0;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
 
   streamptr->curTsID = 0;
 
-  extScanTimestep1(streamID);
- 
-  if ( streamptr->ntsteps == -1 ) status = extScanTimestep2(streamID);
+  extScanTimestep1(streamptr);
+
+  if ( streamptr->ntsteps == -1 ) status = extScanTimestep2(streamptr);
 
   fileSetPos(fileID, 0, SEEK_SET);
 
@@ -679,7 +630,7 @@ int extInqContents(int streamID)
 }
 
 static
-int extScanTimestep(int streamID)
+int extScanTimestep(stream_t *streamptr)
 {
   int header[4];
   int status;
@@ -695,15 +646,10 @@ int extScanTimestep(int streamID)
   int rindex, nrecs = 0;
   extcompvar_t compVar, compVar0;
   extrec_t *extp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   if ( CDI_Debug )
     {
-      Message("streamID = %d", streamID);
+      Message("streamID = %d", streamptr->self);
       Message("cts = %d", streamptr->curTsID);
       Message("rts = %d", streamptr->rtsteps);
       Message("nts = %d", streamptr->ntsteps);
@@ -718,7 +664,7 @@ int extScanTimestep(int streamID)
 
   if ( streamptr->tsteps[tsID].recordSize == 0 )
     {
-      cdiCreateRecords(streamID, tsID);
+      cdi_create_records(streamptr, tsID);
 
       nrecs = streamptr->tsteps[1].nrecs;
 
@@ -727,7 +673,7 @@ int extScanTimestep(int streamID)
       for ( recID = 0; recID < nrecs; recID++ )
 	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
 
-      fileID = streamInqFileID(streamID);
+      fileID = streamptr->fileID;
 
       fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
@@ -763,7 +709,7 @@ int extScanTimestep(int streamID)
 	      taxis->vtime = vtime;
 	    }
 	  /*
-	  extCmpRecord(streamID, tsID, nrecs, recpos, param, rlevel, rxysize);
+	  extCmpRecord(streamptr, tsID, nrecs, recpos, param, rlevel, rxysize);
 	  */
 	  compVar.param  = param;
           compVar.level  = rlevel;
@@ -790,7 +736,7 @@ int extScanTimestep(int streamID)
 
       if ( streamptr->ntsteps != streamptr->rtsteps )
 	{
-	  tsID = tstepsNewEntry(streamID);
+	  tsID = tstepsNewEntry(streamptr);
 	  if ( tsID != streamptr->rtsteps )
 	    Error("Internal error. tsID = %d", tsID);
 
@@ -812,24 +758,19 @@ int extScanTimestep(int streamID)
 }
 
 
-int extInqTimestep(int streamID, int tsID)
+int extInqTimestep(stream_t *streamptr, int tsID)
 {
   int ntsteps, nrecs;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   if ( tsID == 0 && streamptr->rtsteps == 0 )
     Error("Call to cdiInqContents missing!");
 
   if ( CDI_Debug )
     Message("tsID = %d rtsteps = %d", tsID, streamptr->rtsteps);
-  
+
   ntsteps = UNDEFID;
   while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == UNDEFID )
-    ntsteps = extScanTimestep(streamID);
+    ntsteps = extScanTimestep(streamptr);
 
   if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID )
     {
@@ -845,7 +786,7 @@ int extInqTimestep(int streamID, int tsID)
 }
 
 
-void extReadVarDP(int streamID, int varID, double *data, int *nmiss)
+void extReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
 {
   int vlistID, fileID;
   int levID, nlevs, gridID, gridsize;
@@ -856,13 +797,10 @@ void extReadVarDP(int streamID, int varID, double *data, int *nmiss)
   int i;
   double missval;
   extrec_t *extp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   extp     = streamptr->record->extp;
-  vlistID  = streamInqVlist(streamID);
-  fileID   = streamInqFileID(streamID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   nlevs    = streamptr->vars[varID].nlevs;
   missval  = vlistInqVarMissval(vlistID, varID);
   gridID   = vlistInqVarGrid(vlistID, varID);
@@ -907,7 +845,7 @@ void extReadVarDP(int streamID, int varID, double *data, int *nmiss)
 }
 
 
-void extReadVarSliceDP(int streamID, int varID, int levID, double *data, int *nmiss)
+void extReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, int *nmiss)
 {
   int vlistID, fileID;
   int nlevs, gridID, gridsize;
@@ -918,13 +856,10 @@ void extReadVarSliceDP(int streamID, int varID, int levID, double *data, int *nm
   int i;
   double missval;
   extrec_t *extp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   extp     = streamptr->record->extp;
-  vlistID  = streamInqVlist(streamID);
-  fileID   = streamInqFileID(streamID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   nlevs    = streamptr->vars[varID].nlevs;
   missval  = vlistInqVarMissval(vlistID, varID);
   gridID   = vlistInqVarGrid(vlistID, varID);
@@ -968,7 +903,7 @@ void extReadVarSliceDP(int streamID, int varID, int levID, double *data, int *nm
 }
 
 
-void extWriteVarDP(int streamID, int varID, const double *data)
+void extWriteVarDP(stream_t *streamptr, int varID, const double *data)
 {
   int fileID;
   int levID, nlevs, gridID, gridsize;
@@ -979,16 +914,12 @@ void extWriteVarDP(int streamID, int varID, const double *data)
   int vlistID;
   int pdis, pcat, pnum;
   extrec_t *extp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  if ( CDI_Debug )
-    Message("streamID = %d  varID = %d", streamID, varID);
+  if ( CDI_Debug ) Message("streamID = %d  varID = %d", streamptr->self, varID);
 
   extp     = streamptr->record->extp;
-  vlistID  = streamInqVlist(streamID);
-  fileID   = streamInqFileID(streamID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   tsID     = streamptr->curTsID;
   gridID   = vlistInqVarGrid(vlistID, varID);
   gridsize = gridInqSize(gridID);
@@ -1018,7 +949,7 @@ void extWriteVarDP(int streamID, int varID, const double *data)
 }
 
 
-void extWriteVarSliceDP(int streamID, int varID, int levID, const double *data)
+void extWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double *data)
 {
   int fileID;
   int gridID;
@@ -1029,13 +960,10 @@ void extWriteVarSliceDP(int streamID, int varID, int levID, const double *data)
   int vlistID;
   int pdis, pcat, pnum;
   extrec_t *extp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   extp     = streamptr->record->extp;
-  vlistID  = streamInqVlist(streamID);
-  fileID   = streamInqFileID(streamID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   tsID     = streamptr->curTsID;
   gridID   = vlistInqVarGrid(vlistID, varID);
   zaxisID  = vlistInqVarZaxis(vlistID, varID);
diff --git a/libcdi/src/stream_ext.h b/libcdi/src/stream_ext.h
index 90daf79..4fe4918 100644
--- a/libcdi/src/stream_ext.h
+++ b/libcdi/src/stream_ext.h
@@ -5,20 +5,20 @@
 #  include "extra.h"
 #endif
 
-int    extInqContents(int streamID);
-int    extInqTimestep(int streamID, int tsID);
+int    extInqContents(stream_t *streamptr);
+int    extInqTimestep(stream_t *streamptr, int tsID);
 
-int    extInqRecord(int streamID, int *varID, int *levelID);
-int    extDefRecord(int streamID);
-int    extCopyRecord(int streamIDdest, int streamIDsrc);
-int    extReadRecord(int streamID, double *data, int *nmiss);
-int    extWriteRecord(int streamID, const double *data);
+int    extInqRecord(stream_t *streamptr, int *varID, int *levelID);
+int    extDefRecord(stream_t *streamptr);
+int    extCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
+int    extReadRecord(stream_t *streamptr, double *data, int *nmiss);
+int    extWriteRecord(stream_t *streamptr, const double *data);
 
-void   extReadVarDP (int streamID, int varID,       double *data, int *nmiss);
-void   extWriteVarDP(int streamID, int varID, const double *data);
+void   extReadVarDP (stream_t *streamptr, int varID,       double *data, int *nmiss);
+void   extWriteVarDP(stream_t *streamptr, int varID, const double *data);
 
-void   extReadVarSliceDP (int streamID, int varID, int levelID,       double *data, int *nmiss);
-void   extWriteVarSliceDP(int streamID, int varID, int levelID, const double *data);
+void   extReadVarSliceDP (stream_t *streamptr, int varID, int levelID,       double *data, int *nmiss);
+void   extWriteVarSliceDP(stream_t *streamptr, int varID, int levelID, const double *data);
 
 #endif  /* _STREAM_EXT_H */
 /*
diff --git a/libcdi/src/stream_grb.c b/libcdi/src/stream_grb.c
index fcef7d6..0323a49 100644
--- a/libcdi/src/stream_grb.c
+++ b/libcdi/src/stream_grb.c
@@ -26,23 +26,26 @@ int grib1ltypeToZaxisType(int grib_ltype)
 
   switch ( grib_ltype )
     {
-    case GRIB1_LTYPE_SURFACE:         { zaxistype = ZAXIS_SURFACE;           break; }
-    case GRIB1_LTYPE_TOA:             { zaxistype = ZAXIS_TOA;               break; }
-    case GRIB1_LTYPE_SEA_BOTTOM:      { zaxistype = ZAXIS_SEA_BOTTOM;        break; }
-    case GRIB1_LTYPE_ATMOSPHERE:      { zaxistype = ZAXIS_ATMOSPHERE;        break; }
-    case GRIB1_LTYPE_MEANSEA:         { zaxistype = ZAXIS_MEANSEA;           break; }
+    case GRIB1_LTYPE_SURFACE:            { zaxistype = ZAXIS_SURFACE;           break; }
+    case GRIB1_LTYPE_CLOUDBASE:          { zaxistype = ZAXIS_CLOUD_BASE;        break; }
+    case GRIB1_LTYPE_CLOUDTOP:           { zaxistype = ZAXIS_CLOUD_TOP;         break; }
+    case GRIB1_LTYPE_ISOTHERM0:          { zaxistype = ZAXIS_ISOTHERM_ZERO;     break; }
+    case GRIB1_LTYPE_TOA:                { zaxistype = ZAXIS_TOA;               break; }
+    case GRIB1_LTYPE_SEA_BOTTOM:         { zaxistype = ZAXIS_SEA_BOTTOM;        break; }
+    case GRIB1_LTYPE_ATMOSPHERE:         { zaxistype = ZAXIS_ATMOSPHERE;        break; }
+    case GRIB1_LTYPE_MEANSEA:            { zaxistype = ZAXIS_MEANSEA;           break; }
     case GRIB1_LTYPE_99:
-    case GRIB1_LTYPE_ISOBARIC:        { zaxistype = ZAXIS_PRESSURE;          break; }
-    case GRIB1_LTYPE_HEIGHT:          { zaxistype = ZAXIS_HEIGHT;            break; }
-    case GRIB1_LTYPE_ALTITUDE:        { zaxistype = ZAXIS_ALTITUDE;	     break; }
+    case GRIB1_LTYPE_ISOBARIC:           { zaxistype = ZAXIS_PRESSURE;          break; }
+    case GRIB1_LTYPE_HEIGHT:             { zaxistype = ZAXIS_HEIGHT;            break; }
+    case GRIB1_LTYPE_ALTITUDE:           { zaxistype = ZAXIS_ALTITUDE;	     break; }
     case GRIB1_LTYPE_SIGMA:
-    case GRIB1_LTYPE_SIGMA_LAYER:     { zaxistype = ZAXIS_SIGMA;	     break; }
+    case GRIB1_LTYPE_SIGMA_LAYER:        { zaxistype = ZAXIS_SIGMA;	     break; }
     case GRIB1_LTYPE_HYBRID:
-    case GRIB1_LTYPE_HYBRID_LAYER:    { zaxistype = ZAXIS_HYBRID;	     break; }
+    case GRIB1_LTYPE_HYBRID_LAYER:       { zaxistype = ZAXIS_HYBRID;	     break; }
     case GRIB1_LTYPE_LANDDEPTH:
-    case GRIB1_LTYPE_LANDDEPTH_LAYER: { zaxistype = ZAXIS_DEPTH_BELOW_LAND;  break; }
-    case GRIB1_LTYPE_ISENTROPIC:      { zaxistype = ZAXIS_ISENTROPIC;	     break; }
-    case GRIB1_LTYPE_SEADEPTH:        { zaxistype = ZAXIS_DEPTH_BELOW_SEA;   break; }
+    case GRIB1_LTYPE_LANDDEPTH_LAYER:    { zaxistype = ZAXIS_DEPTH_BELOW_LAND;  break; }
+    case GRIB1_LTYPE_ISENTROPIC:         { zaxistype = ZAXIS_ISENTROPIC;	     break; }
+    case GRIB1_LTYPE_SEADEPTH:           { zaxistype = ZAXIS_DEPTH_BELOW_SEA;   break; }
     }
 
   return (zaxistype);
@@ -56,6 +59,9 @@ int grib2ltypeToZaxisType(int grib_ltype)
   switch ( grib_ltype )
     {
     case GRIB2_LTYPE_SURFACE:            { zaxistype = ZAXIS_SURFACE;           break; }
+    case GRIB2_LTYPE_CLOUDBASE:          { zaxistype = ZAXIS_CLOUD_BASE;        break; }
+    case GRIB2_LTYPE_CLOUDTOP:           { zaxistype = ZAXIS_CLOUD_TOP;         break; }
+    case GRIB2_LTYPE_ISOTHERM0:          { zaxistype = ZAXIS_ISOTHERM_ZERO;     break; }
     case GRIB2_LTYPE_TOA:                { zaxistype = ZAXIS_TOA;               break; }
     case GRIB2_LTYPE_SEA_BOTTOM:         { zaxistype = ZAXIS_SEA_BOTTOM;        break; }
     case GRIB2_LTYPE_ATMOSPHERE:         { zaxistype = ZAXIS_ATMOSPHERE;        break; }
@@ -98,24 +104,19 @@ int grbBitsPerValue(int datatype)
 
 
 /*
-int grbInqRecord(int streamID, int *varID, int *levelID)
+int grbInqRecord(stream_t * streamptr, int *varID, int *levelID)
 {
   int status;
 
-  status = cgribexInqRecord(streamID, varID, levelID);
+  status = cgribexInqRecord(streamptr, varID, levelID);
 
   return (status);
 }
 */
 
-int grbDefRecord(int streamID)
+int grbDefRecord(stream_t * streamptr)
 {
   int status = 0;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   return (status);
 }
@@ -132,12 +133,12 @@ int grbDecode(int filetype, unsigned char *gribbuffer, int gribsize, double *dat
   else
 #endif
     status = gribapiDecode(gribbuffer, gribsize, data, gridsize, unreduced, nmiss, zip, missval);
- 
+
   return (status);
 }
 
 
-int grbReadRecord(int streamID, double *data, int *nmiss)
+int grbReadRecord(stream_t * streamptr, double *data, int *nmiss)
 {
   int status = 0;
   unsigned char *gribbuffer;
@@ -150,18 +151,13 @@ int grbReadRecord(int streamID, double *data, int *nmiss)
   int zip;
   int filetype;
   double missval;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   filetype = streamptr->filetype;
 
   gribbuffer = (unsigned char *) streamptr->record->buffer;
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
   tsID    = streamptr->curTsID;
   vrecID  = streamptr->tsteps[tsID].curRecID;
   recID   = streamptr->tsteps[tsID].recIDs[vrecID];
@@ -188,95 +184,84 @@ int grbReadRecord(int streamID, double *data, int *nmiss)
 }
 
 static
-int grbScanTimestep1(int streamID)
+int grbScanTimestep1(stream_t * streamptr)
 {
   int status;
   int filetype;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
   filetype  = streamptr->filetype;
 
 #if  defined  (HAVE_LIBCGRIBEX)
   if ( filetype == FILETYPE_GRB )
     {
-      status = cgribexScanTimestep1(streamID);
+      status = cgribexScanTimestep1(streamptr);
     }
   else
 #endif
     {
-      status = gribapiScanTimestep1(streamID);
+      status = gribapiScanTimestep1(streamptr);
     }
 
   return (status);
 }
 
 static
-int grbScanTimestep2(int streamID)
+int grbScanTimestep2(stream_t * streamptr)
 {
   int status;
   int filetype;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
   filetype  = streamptr->filetype;
 
 #if  defined  (HAVE_LIBCGRIBEX)
   if ( filetype == FILETYPE_GRB )
     {
-      status = cgribexScanTimestep2(streamID);
+      status = cgribexScanTimestep2(streamptr);
     }
   else
 #endif
     {
-      status = gribapiScanTimestep2(streamID);
+      status = gribapiScanTimestep2(streamptr);
     }
 
   return (status);
 }
 
 static
-int grbScanTimestep(int streamID)
+int grbScanTimestep(stream_t * streamptr)
 {
   int status;
   int filetype;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
   filetype  = streamptr->filetype;
 
 #if  defined  (HAVE_LIBCGRIBEX)
   if ( filetype == FILETYPE_GRB )
     {
-      status = cgribexScanTimestep(streamID);
+      status = cgribexScanTimestep(streamptr);
     }
   else
 #endif
     {
-      status = gribapiScanTimestep(streamID);
+      status = gribapiScanTimestep(streamptr);
     }
 
   return (status);
 }
 
 
-int grbInqContents(int streamID)
+int grbInqContents(stream_t * streamptr)
 {
   int fileID;
   int status = 0;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
-
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
 
   streamptr->curTsID = 0;
 
-  status = grbScanTimestep1(streamID);
- 
-  if ( status == 0 && streamptr->ntsteps == -1 ) status = grbScanTimestep2(streamID);
+  status = grbScanTimestep1(streamptr);
+
+  if ( status == 0 && streamptr->ntsteps == -1 ) status = grbScanTimestep2(streamptr);
 
   fileSetPos(fileID, 0, SEEK_SET);
 
@@ -284,25 +269,20 @@ int grbInqContents(int streamID)
 }
 
 
-int grbInqTimestep(int streamID, int tsID)
+int grbInqTimestep(stream_t * streamptr, int tsID)
 {
   int ntsteps, nrecs;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   if ( tsID == 0 && streamptr->rtsteps == 0 )
     Error("Call to cdiInqContents missing!");
 
   if ( CDI_Debug )
     Message("tsid = %d rtsteps = %d", tsID, streamptr->rtsteps);
-  
+
   ntsteps = CDI_UNDEFID;
   while ( (tsID + 1) > streamptr->rtsteps && ntsteps == CDI_UNDEFID )
     {
-      ntsteps = grbScanTimestep(streamID);
+      ntsteps = grbScanTimestep(streamptr);
       if ( ntsteps == CDI_EUFSTRUCT )
 	{
 	  streamptr->ntsteps = streamptr->rtsteps;
@@ -324,7 +304,7 @@ int grbInqTimestep(int streamID, int tsID)
 }
 
 
-void grbReadVarDP(int streamID, int varID, double *data, int *nmiss)
+void grbReadVarDP(stream_t * streamptr, int varID, double *data, int *nmiss)
 {
   int fileID;
   int levelID, nlevs, gridID, gridsize;
@@ -337,18 +317,13 @@ void grbReadVarDP(int streamID, int varID, double *data, int *nmiss)
   int zip;
   int filetype;
   double missval;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   filetype = streamptr->filetype;
 
   gribbuffer = (unsigned char *) streamptr->record->buffer;
 
-  vlistID  = streamInqVlist(streamID);
-  fileID   = streamInqFileID(streamID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   tsID     = streamptr->curTsID;
 
   nlevs    = streamptr->vars[varID].nlevs;
@@ -373,7 +348,7 @@ void grbReadVarDP(int streamID, int varID, double *data, int *nmiss)
 
       missval = vlistInqVarMissval(vlistID, varID);
 
-      grbDecode(filetype, gribbuffer, recsize, &data[levelID*gridsize], gridsize, 
+      grbDecode(filetype, gribbuffer, recsize, &data[levelID*gridsize], gridsize,
 		streamptr->unreduced, &imiss, &zip, missval);
 
       *nmiss += imiss;
@@ -385,7 +360,7 @@ void grbReadVarDP(int streamID, int varID, double *data, int *nmiss)
 }
 
 
-void grbReadVarSliceDP(int streamID, int varID, int levelID, double *data, int *nmiss)
+void grbReadVarSliceDP(stream_t * streamptr, int varID, int levelID, double *data, int *nmiss)
 {
   int fileID;
   int gridID, gridsize;
@@ -397,17 +372,12 @@ void grbReadVarSliceDP(int streamID, int varID, int levelID, double *data, int *
   int zip;
   int filetype;
   double missval;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   filetype = streamptr->filetype;
 
   gribbuffer = (unsigned char *) streamptr->record->buffer;
 
-  vlistID  = streamInqVlist(streamID);
+  vlistID  = streamptr->vlistID;
   gridID   = vlistInqVarGrid(vlistID, varID);
   gridsize = gridInqSize(gridID);
   tsID     = streamptr->curTsID;
@@ -415,7 +385,7 @@ void grbReadVarSliceDP(int streamID, int varID, int levelID, double *data, int *
   if ( CDI_Debug )
     Message("gridID = %d gridsize = %d", gridID, gridsize);
 
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
 
   currentfilepos = fileGetPos(fileID);
 
@@ -442,7 +412,7 @@ void grbReadVarSliceDP(int streamID, int varID, int levelID, double *data, int *
 
 static
 size_t grbEncode(int filetype, int varID, int levelID, int vlistID, int gridID, int zaxisID,
-		 int date, int time, int tsteptype, int numavg, 
+		 int date, int time, int tsteptype, int numavg,
 		 long datasize, const double *data, int nmiss, unsigned char **gribbuffer,
 		 int ljpeg, void *gribContainer)
 {
@@ -456,14 +426,14 @@ size_t grbEncode(int filetype, int varID, int levelID, int vlistID, int gridID,
       *gribbuffer = (unsigned char *) malloc(gribbuffersize);
 
       nbytes = cgribexEncode(varID, levelID, vlistID, gridID, zaxisID,
-			     date, time, tsteptype, numavg, 
+			     date, time, tsteptype, numavg,
 			     datasize, data, nmiss, *gribbuffer, gribbuffersize);
     }
   else
 #endif
     {
       nbytes = gribapiEncode(varID, levelID, vlistID, gridID, zaxisID,
-			     date, time, tsteptype, numavg, 
+			     date, time, tsteptype, numavg,
 			     datasize, data, nmiss, gribbuffer, &gribbuffersize,
 			     ljpeg, gribContainer);
     }
@@ -501,7 +471,7 @@ size_t grbSzip(int filetype, unsigned char *gribbuffer, size_t gribbuffersize)
 }
 
 
-int grbWriteVarSliceDP(int streamID, int varID, int levelID, const double *data, int nmiss)
+int grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, int nmiss)
 {
   size_t nwrite;
   int fileID;
@@ -516,19 +486,15 @@ int grbWriteVarSliceDP(int streamID, int varID, int levelID, const double *data,
   int numavg = 0;
   size_t nbytes;
   int filetype;
-  stream_t *streamptr;
   int ljpeg = 0;
   int ljpeg_warn = 1;
   void *gc = NULL;
 
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
+  if ( memtype == MEMTYPE_FLOAT ) Error("cdf_write_var_slice not implemented for memtype float!");
 
   filetype  = streamptr->filetype;
-
-  fileID    = streamInqFileID(streamID);
-  vlistID   = streamInqVlist(streamID);
+  fileID    = streamptr->fileID;
+  vlistID   = streamptr->vlistID;
   gridID    = vlistInqVarGrid(vlistID, varID);
   zaxisID   = vlistInqVarZaxis(vlistID, varID);
   tsteptype = vlistInqVarTsteptype(vlistID, varID);
@@ -599,12 +565,12 @@ int grbWriteVarSliceDP(int streamID, int varID, int levelID, const double *data,
 }
 
 
-void grbWriteVarDP(int streamID, int varID, const double *data, int nmiss)
+void grb_write_var(stream_t *streamptr, int varID, int memtype, const void *data, int nmiss)
 {
   int vlistID, gridID, zaxisID, levelID, nlevs;
   int gridsize;
 
-  vlistID  = streamInqVlist(streamID);
+  vlistID  = streamptr->vlistID;
   gridID   = vlistInqVarGrid(vlistID, varID);
   gridsize = gridInqSize(gridID);
   zaxisID  = vlistInqVarZaxis(vlistID, varID);
@@ -612,12 +578,15 @@ void grbWriteVarDP(int streamID, int varID, const double *data, int nmiss)
 
   for ( levelID = 0; levelID < nlevs; levelID++ )
     {
-      grbWriteVarSliceDP(streamID, varID, levelID, data+levelID*gridsize, nmiss);
+      if ( memtype == MEMTYPE_FLOAT )
+        grb_write_var_slice(streamptr, varID, levelID, memtype, ((float*)data)+levelID*gridsize, nmiss);
+      else
+        grb_write_var_slice(streamptr, varID, levelID, memtype, ((double*)data)+levelID*gridsize, nmiss);
     }
 }
 
 
-int grbCopyRecord(int streamID2, int streamID1)
+int grbCopyRecord(stream_t * streamptr2, stream_t * streamptr1)
 {
   int fileID1, fileID2;
   int tsID, recID, vrecID;
@@ -630,19 +599,11 @@ int grbCopyRecord(int streamID2, int streamID1)
   size_t nbytes;
   long unzipsize;
   int izip;
-  stream_t *streamptr1;
-  stream_t *streamptr2;
-
-  streamptr1 = stream_to_pointer(streamID1);
-  streamptr2 = stream_to_pointer(streamID2);
-
-  stream_check_ptr(__func__, streamptr1);
-  stream_check_ptr(__func__, streamptr2);
 
   filetype = streamptr1->filetype;
 
-  fileID1 = streamInqFileID(streamID1);
-  fileID2 = streamInqFileID(streamID2);
+  fileID1 = streamptr1->fileID;
+  fileID2 = streamptr2->fileID;
 
   tsID    = streamptr1->curTsID;
   vrecID  = streamptr1->tsteps[tsID].curRecID;
@@ -677,20 +638,15 @@ int grbCopyRecord(int streamID2, int streamID1)
 }
 
 
-int grbWriteRecord(int streamID, const double *data, int nmiss)
+int grb_write_record(stream_t * streamptr, int memtype, const void *data, int nmiss)
 {
   int status = 0;
   int varID, levelID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   varID   = streamptr->record->varID;
   levelID = streamptr->record->levelID;
 
-  status = grbWriteVarSliceDP(streamID, varID, levelID, data, nmiss);
+  status = grb_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss);
 
   return (status);
 }
diff --git a/libcdi/src/stream_grb.h b/libcdi/src/stream_grb.h
index 1d7e3fb..1430b68 100644
--- a/libcdi/src/stream_grb.h
+++ b/libcdi/src/stream_grb.h
@@ -3,20 +3,20 @@
 
 int   grbBitsPerValue(int datatype);
 
-int   grbInqContents(int streamID);
-int   grbInqTimestep(int streamID, int tsID);
+int   grbInqContents(stream_t * streamptr);
+int   grbInqTimestep(stream_t * streamptr, int tsID);
 
-int   grbInqRecord(int streamID, int *varID, int *levelID);
-int   grbDefRecord(int streamID);
-int   grbWriteRecord(int streamID, const double *data, int nmiss);
-int   grbReadRecord(int streamID, double *data, int *nmiss);
-int   grbCopyRecord(int streamIDdest, int streamIDsrc);
+int   grbInqRecord(stream_t * streamptr, int *varID, int *levelID);
+int   grbDefRecord(stream_t * streamptr);
+int   grb_write_record(stream_t * streamptr, int memtype, const void *data, int nmiss);
+int   grbReadRecord(stream_t * streamptr, double *data, int *nmiss);
+int   grbCopyRecord(stream_t * streamptr2, stream_t * streamptr1);
 
-void  grbReadVarDP(int streamID, int varID, double *data, int *nmiss);
-void  grbWriteVarDP(int streamID, int varID, const double *data, int nmiss);
+void  grbReadVarDP(stream_t * streamptr, int varID, double *data, int *nmiss);
+void  grb_write_var(stream_t * streamptr, int varID, int memtype, const void *data, int nmiss);
 
-void  grbReadVarSliceDP(int streamID, int varID, int levelID, double *data, int *nmiss);
-int   grbWriteVarSliceDP(int streamID, int varID, int levelID, const double *data, int nmiss);
+void  grbReadVarSliceDP(stream_t * streamptr, int varID, int levelID, double *data, int *nmiss);
+int   grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, const void *data, int nmiss);
 
 int   grib1ltypeToZaxisType(int grib_ltype);
 int   grib2ltypeToZaxisType(int grib_ltype);
diff --git a/libcdi/src/stream_gribapi.c b/libcdi/src/stream_gribapi.c
index afd00e7..2cf4ef0 100644
--- a/libcdi/src/stream_gribapi.c
+++ b/libcdi/src/stream_gribapi.c
@@ -21,6 +21,7 @@
 #  include "grib_api.h"
 #endif
 
+#define  NINT(x)  ((x) < 0 ? (int)((x)-.5) : (int)((x)+.5))
 
 extern int cdiInventoryMode;
 
@@ -29,6 +30,7 @@ typedef struct {
   int level1;
   int level2;
   int ltype;
+  char name[32];
 } compvar2_t;
 
 
@@ -37,12 +39,14 @@ static
 int gribapiGetGridType(grib_handle *gh)
 {
   int gridtype = GRID_GENERIC;
-  int gribgridtype;
+  int gribgridtype = -1;
   long lpar;
 
     {
-      GRIB_CHECK(grib_get_long(gh, "gridDefinitionTemplateNumber", &lpar), 0);
-      gribgridtype = (int) lpar;
+      int status;
+      status = grib_get_long(gh, "gridDefinitionTemplateNumber", &lpar);
+
+      if ( status ==  0 ) gribgridtype = (int) lpar;
 
       switch (gribgridtype)
 	{
@@ -71,15 +75,15 @@ static
 int gribapiGetIsRotated(grib_handle *gh)
 {
   int isRotated = 0;
-  int gribgridtype;
+  int gribgridtype = -1;
   long lpar;
+  int status;
 
-    {
-      GRIB_CHECK(grib_get_long(gh, "gridDefinitionTemplateNumber", &lpar), 0);
-      gribgridtype = (int) lpar;
+  status = grib_get_long(gh, "gridDefinitionTemplateNumber", &lpar);
 
-      if ( gribgridtype == GRIB2_GTYPE_LATLON_ROT ) isRotated = 1;
-    }
+  if ( status ==  0 ) gribgridtype = (int) lpar;
+
+  if ( gribgridtype == GRIB2_GTYPE_LATLON_ROT ) isRotated = 1;
 
   return (isRotated);
 }
@@ -144,34 +148,16 @@ double timeunit_factor(int tu1, int tu2)
 }
 
 static
-int gribapiGetEndStep(grib_handle *gh, int startStep, int timeunits)
-{
-  int endStep = startStep;
-  int timeunits2;
-  long unitsOfTime;
-  long lpar;
-
-  GRIB_CHECK(grib_get_long(gh, "stepUnits", &unitsOfTime), 0);
-
-  timeunits2 = getTimeunits(unitsOfTime);
-
-  GRIB_CHECK(grib_get_long(gh, "endStep", &lpar), 0);
-
-  endStep = (int)  ((lpar * timeunit_factor(timeunits, timeunits2)) + 0.5);
-
-  return (endStep);
-}
-
-static
 int gribapiGetTimeUnits(grib_handle *gh)
 {
   int timeunits = -1;
-  long unitsOfTime;
+  long unitsOfTime = -1;
+  int status;
   // size_t len = 8;
   //char stepunits[8];
   //static int lprint = TRUE;
 
-  GRIB_CHECK(grib_get_long(gh, "indicatorOfUnitOfTimeRange", &unitsOfTime), 0);
+  status = grib_get_long(gh, "indicatorOfUnitOfTimeRange", &unitsOfTime);
 
   timeunits = getTimeunits(unitsOfTime);
 
@@ -200,6 +186,29 @@ int gribapiGetTimeUnits(grib_handle *gh)
 }
 
 static
+int gribapiGetEndStep(grib_handle *gh, int startStep, int timeunits)
+{
+  int endStep = startStep;
+  int timeunits2;
+  int status;
+  long unitsOfTime;
+  long lpar;
+
+  // status = grib_get_long(gh, "stepUnits", &unitsOfTime);
+
+  // timeunits2 = getTimeunits(unitsOfTime);
+  timeunits2 = gribapiGetTimeUnits(gh);
+
+  status = grib_get_long(gh, "endStep", &lpar);
+
+  if ( status == 0 )
+    endStep = (int) ((lpar * timeunit_factor(timeunits, timeunits2)) + 0.5);
+  // printf("%d %d %d %d %d %g\n", startStep, endStep, lpar, timeunits, timeunits2, timeunit_factor(timeunits, timeunits2));
+
+  return (endStep);
+}
+
+static
 int gribapiTimeIsFC(grib_handle *gh)
 {
   long editionNumber;
@@ -258,12 +267,31 @@ int gribapiGetTsteptype(grib_handle *gh)
 }
 
 static
+void gribapiGetDataDateTime(grib_handle *gh, int *datadate, int *datatime)
+{
+  long lpar;
+
+  GRIB_CHECK(grib_get_long(gh, "dataDate", &lpar), 0);
+  *datadate = (int) lpar;
+  GRIB_CHECK(grib_get_long(gh, "dataTime", &lpar), 0);
+  *datatime = (int) lpar*100;
+}
+
+static
+void gribapiSetDataDateTime(grib_handle *gh, int datadate, int datatime)
+{
+  GRIB_CHECK(grib_set_long(gh, "dataDate", datadate), 0);
+  GRIB_CHECK(grib_set_long(gh, "dataTime", datatime/100), 0);
+}
+
+static
 int gribapiGetValidityDateTime(grib_handle *gh, int *vdate, int *vtime)
 {
   int rdate, rtime;
-  int timeUnits, startStep, endStep;
+  int timeUnits, startStep = 0, endStep;
   int tstepRange = 0;
   int range;
+  int status;
   long lpar;
   long sigofrtime = 3;
   long editionNumber;
@@ -277,19 +305,14 @@ int gribapiGetValidityDateTime(grib_handle *gh, int *vdate, int *vtime)
 
   if ( sigofrtime == 3 )
     {
-      GRIB_CHECK(grib_get_long(gh, "dataDate", &lpar), 0);
-      *vdate = (int) lpar;
-      GRIB_CHECK(grib_get_long(gh, "dataTime", &lpar), 0);
-      *vtime = (int) lpar*100;
+      gribapiGetDataDateTime(gh, vdate, vtime);
     }
   else
     {
-      GRIB_CHECK(grib_get_long(gh, "dataDate", &lpar), 0);
-      rdate = (int) lpar;
-      GRIB_CHECK(grib_get_long(gh, "dataTime", &lpar), 0);
-      rtime = (int) lpar*100;
-      GRIB_CHECK(grib_get_long(gh, "forecastTime", &lpar), 0);
-      startStep = (int) lpar;
+      gribapiGetDataDateTime(gh, &rdate, &rtime);
+
+      status = grib_get_long(gh, "forecastTime", &lpar);
+      if ( status == 0 ) startStep = (int) lpar;
       timeUnits = gribapiGetTimeUnits(gh);
       endStep = gribapiGetEndStep(gh, startStep, timeUnits);
 
@@ -329,14 +352,13 @@ int gribapiGetValidityDateTime(grib_handle *gh, int *vdate, int *vtime)
 	        Warning("Time unit %d unsupported", timeUnits);
 		lprint = FALSE;
 	      }
+	    break;
 	  }
 
 	julday_add_seconds(addsec, &julday, &secofday);
 
 	decode_caldaysec(grib_calendar, julday, secofday, &ryear, &rmonth, &rday, &rhour, &rminute, &rsecond);
-	/*
-	  printf("new %d/%d/%d %d:%d\n", ryear, rmonth, rday, rhour, rminute);
-	*/
+
 	*vdate = cdiEncodeDate(ryear, rmonth, rday);
 	*vtime = cdiEncodeTime(rhour, rminute, rsecond);
       }
@@ -389,8 +411,7 @@ void gribapiGetGrid(grib_handle *gh, grid_t *grid)
           }
 
 	if ( numberOfPoints != nlon*nlat )
-	  Error("numberOfPoints (%d) and gridSize (%d) differ!",
-		(int)numberOfPoints, nlon*nlat);
+	  Error("numberOfPoints (%d) and gridSize (%d) differ!", (int)numberOfPoints, nlon*nlat);
 
 	grid->size  = numberOfPoints;
 	grid->xsize = nlon;
@@ -567,27 +588,26 @@ void gribapiGetGrid(grib_handle *gh, grid_t *grid)
     case GRID_REFERENCE:
       {
         char uuid[17];
-	char reference_link[8192];
-	size_t len = sizeof(reference_link);
-	reference_link[0] = 0;
+    	char reference_link[8192];
+        size_t len = sizeof(reference_link);
+        reference_link[0] = 0;
 
-	grid->size  = numberOfPoints;
-	if ( grib_get_long(gh, "numberOfGridUsed", &lpar) == 0 )
-	  {
-	    grid->number   = lpar;
-	    if ( grib_get_long(gh, "numberOfGridInReference", &lpar) == 0 ) grid->position = lpar;
-	    if ( grib_get_string(gh, "gridDescriptionFile", reference_link, &len) == 0 )
-	      {
-		if ( strncmp(reference_link, "file://", 7) == 0 )
-		  grid->reference = strdupx(reference_link);
-	      }
+    	grid->size  = numberOfPoints;
+        if ( grib_get_long(gh, "numberOfGridUsed", &lpar) == 0 )
+          {
+            grid->number   = lpar;
+            if ( grib_get_long(gh, "numberOfGridInReference", &lpar) == 0 ) grid->position = lpar;
+            if ( grib_get_string(gh, "gridDescriptionFile", reference_link, &len) == 0 )
+              {
+                if ( strncmp(reference_link, "file://", 7) == 0 )
+                  grid->reference = strdupx(reference_link);
+              }
             len = (size_t) 16;
-            if ( grib_get_string(gh, "uuidOfHGrid", uuid, &len) == 0)
+            if ( grib_get_bytes(gh, "uuidOfHGrid", (unsigned char *) uuid, &len) == 0)
               {
                 strncpy(grid->uuid, uuid, 16);
               }
-	  }
-
+          }
 	break;
       }
     case GRID_GENERIC:
@@ -682,7 +702,7 @@ void grib1GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, i
 }
 
 static
-void grib2GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, int *level2)
+void grib2GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, int *level2, int *level_sf)
 {
   int status;
   int leveltype2 = -1;
@@ -694,6 +714,7 @@ void grib2GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, i
   *lbounds = 0;
   *level1  = 0;
   *level2  = 0;
+  *level_sf = 0;
 
   status = grib_get_long(gh, "typeOfFirstFixedSurface", &lpar);
   if ( status == 0 )
@@ -711,9 +732,11 @@ void grib2GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, i
 	    {
 	      GRIB_CHECK(grib_get_long(gh, "scaleFactorOfFirstFixedSurface", &factor), 0);
 	      GRIB_CHECK(grib_get_double(gh, "scaledValueOfFirstFixedSurface", &dlevel), 0);
-	      if      ( factor == 0 ) dlevel *= 100;   //  m to cm
-	      else if ( factor == 1 ) dlevel *=  10;   // dm to cm
-	      else if ( factor == 3 ) dlevel *=   0.1; // mm to cm
+	      if      ( factor == 0 ) dlevel *= 1000;  //  m to mm
+	      else if ( factor == 1 ) dlevel *=  100;  // dm to mm
+	      else if ( factor == 2 ) dlevel *=   10;  // cm to mm
+	      else if ( factor == 3 ) dlevel *=    1;  // mm to mm
+              *level_sf = 77;
 	    }
 	  else
 	    {
@@ -732,16 +755,19 @@ void grib2GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, i
 	    {
 	      GRIB_CHECK(grib_get_long(gh, "scaleFactorOfFirstFixedSurface", &factor), 0);
 	      GRIB_CHECK(grib_get_double(gh, "scaledValueOfFirstFixedSurface", &dlevel), 0);
-	      if      ( factor == 0 ) dlevel *= 100;   //  m to cm
-	      else if ( factor == 1 ) dlevel *=  10;   // dm to cm
-	      else if ( factor == 3 ) dlevel *=   0.1; // mm to cm
+	      if      ( factor == 0 ) dlevel *= 1000;  //  m to mm
+	      else if ( factor == 1 ) dlevel *=  100;  // dm to mm
+	      else if ( factor == 2 ) dlevel *=   10;  // cm to mm
+	      else if ( factor == 3 ) dlevel *=    1;  // mm to mm
 	      *level1 = (int) dlevel;
 	      GRIB_CHECK(grib_get_long(gh, "scaleFactorOfSecondFixedSurface", &factor), 0);
 	      GRIB_CHECK(grib_get_double(gh, "scaledValueOfSecondFixedSurface", &dlevel), 0);
-	      if      ( factor == 0 ) dlevel *= 100;   //  m to cm
-	      else if ( factor == 1 ) dlevel *=  10;   // dm to cm
-	      else if ( factor == 3 ) dlevel *=   0.1; // mm to cm
+	      if      ( factor == 0 ) dlevel *= 1000;  //  m to mm
+	      else if ( factor == 1 ) dlevel *=  100;  // dm to mm
+	      else if ( factor == 2 ) dlevel *=   10;  // cm to mm
+	      else if ( factor == 3 ) dlevel *=    1;  // mm to mm
 	      *level2 = (int) dlevel;
+              *level_sf = 77;
 	    }
 	  else
 	    {
@@ -755,34 +781,39 @@ void grib2GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, i
 }
 
 static
-void gribapiAddRecord(int streamID, int param, grib_handle *gh,
-		      long recsize, off_t position, int datatype, int comptype)
+void gribapiGetString(grib_handle *gh, const char *key, char *string, size_t length)
+{
+  string[0] = 0;
+
+  GRIB_CHECK(grib_get_string(gh, key, string, &length), 0);
+  if      ( length == 8 && memcmp(string, "unknown", length) == 0 ) string[0] = 0;
+  else if ( length == 2 && memcmp(string, "~", length)       == 0 ) string[0] = 0;
+}
+
+static
+void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
+		      long recsize, off_t position, int datatype, int comptype, size_t len, const char *varname,
+                      int leveltype, int lbounds, int level1, int level2, int level_sf)
 {
   long editionNumber;
   int zaxistype;
   int gridID = CDI_UNDEFID, varID;
   int levelID = 0;
   int tsID, recID;
-  int level1 = 0, level2 = 0;
   int numavg;
   int tsteptype;
-  int lbounds = 0;
   record_t *record;
   grid_t grid;
   int vlistID;
-  stream_t *streamptr;
-  int leveltype;
   long lpar;
   int status;
-  char name[256], longname[256], units[256];
+  char longname[256], units[256];
   size_t vlen;
   long ens_index = 0, ens_count = 0, ens_forecast_type = 0;
 
-  streamptr = stream_to_pointer(streamID);
-
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   tsID    = streamptr->curTsID;
-  recID   = recordNewEntry(streamID, tsID);
+  recID   = recordNewEntry(streamptr, tsID);
   record  = &streamptr->tsteps[tsID].records[recID];
 
   tsteptype = gribapiGetTsteptype(gh);
@@ -791,11 +822,6 @@ void gribapiAddRecord(int streamID, int param, grib_handle *gh,
 
   GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
 
-  if ( editionNumber <= 1 )
-    grib1GetLevel(gh, &leveltype, &lbounds, &level1, &level2);
-  else
-    grib2GetLevel(gh, &leveltype, &lbounds, &level1, &level2);
-
   // fprintf(stderr, "param %d %d %d %d\n", param, level1, level2, leveltype);
 
   (*record).size     = recsize;
@@ -804,6 +830,7 @@ void gribapiAddRecord(int streamID, int param, grib_handle *gh,
   (*record).ilevel   = level1;
   (*record).ilevel2  = level2;
   (*record).ltype    = leveltype;
+  memcpy((*record).varname, varname, len);
 
   gribapiGetGrid(gh, &grid);
 
@@ -836,19 +863,21 @@ void gribapiAddRecord(int streamID, int param, grib_handle *gh,
       {
         size_t len;
         char uuid[17];
+        double dtmp;
         long nlev, nvgrid;
 
         GRIB_CHECK(grib_get_long(gh, "NV", &lpar), 0);
-        if ( lpar != 3 )
+        if ( lpar != 6 )
           {
             fprintf(stderr, "Warning ...\n");
           }
-        GRIB_CHECK(grib_get_long(gh, "nlev", &nlev), 0);
-        GRIB_CHECK(grib_get_long(gh, "numberOfVGridUsed", &nvgrid), 0);
-
+        GRIB_CHECK(grib_get_double(gh, "nlev", &dtmp), 0);
+        nlev = (int) NINT(dtmp);
+        GRIB_CHECK(grib_get_double(gh, "numberOfVGridUsed", &dtmp), 0);
+        nvgrid = NINT(dtmp);
         len = (size_t) 16;
         uuid[16] = 0;
-        GRIB_CHECK(grib_get_string(gh, "uuidOfVGrid", uuid, &len), 0);
+        GRIB_CHECK(grib_get_bytes(gh, "uuidOfVGrid", (unsigned char *) uuid, &len), 0);
         varDefZAxisReference((int) nlev, (int) nvgrid, uuid);
         break;
       }
@@ -857,29 +886,21 @@ void gribapiAddRecord(int streamID, int param, grib_handle *gh,
   // if ( datatype > 32 ) datatype = DATATYPE_PACK32;
   if ( datatype <  0 ) datatype = DATATYPE_PACK;
 
-  name[0] = 0;
   longname[0] = 0;
   units[0] = 0;
 
-  vlen = 256;
-  GRIB_CHECK(grib_get_string(gh, "shortName", name, &vlen), 0);
-  if      ( vlen == 8 && memcmp(name, "unknown", vlen) == 0 ) name[0] = 0;
-  else if ( vlen == 2 && memcmp(name, "~", vlen)       == 0 ) name[0] = 0;
-
-  if ( name[0] != 0 )
+  if ( varname[0] != 0 )
     {
       vlen = 256;
-      GRIB_CHECK(grib_get_string(gh, "name", longname, &vlen), 0);
-      if ( vlen == 8 && memcmp(longname, "unknown", vlen) == 0 ) longname[0] = 0;
+      gribapiGetString(gh, "name", longname, vlen);
       vlen = 256;
-      GRIB_CHECK(grib_get_string(gh, "units", units, &vlen), 0);
-      if ( vlen == 8 && memcmp(units, "unknown", vlen) == 0 ) units[0] = 0;
+      gribapiGetString(gh, "units", units, vlen);
     }
-  // fprintf(stderr, "param %d name %s %s %s\n", param, name, longname, units); 
+  // fprintf(stderr, "param %d name %s %s %s\n", param, name, longname, units);
 
-  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2,
+  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, level_sf,
 	       datatype, &varID, &levelID, tsteptype, numavg, leveltype,
-	       name, longname, units);
+	       varname, longname, units);
 
   (*record).varID   = varID;
   (*record).levelID = levelID;
@@ -888,7 +909,7 @@ void gribapiAddRecord(int streamID, int param, grib_handle *gh,
 
   /*
     Get the ensemble Info from the grib-2 Tables and update the intermediate datastructure.
-    Further update to the "vlist" is handled in the same way as for GRIB-1 by "cdiGenVars"
+    Further update to the "vlist" is handled in the same way as for GRIB-1 by "cdi_generate_vars"
   */
   {
     int status;
@@ -955,9 +976,67 @@ void gribapiAddRecord(int streamID, int param, grib_handle *gh,
     Message("varID = %d  param = %d  zaxistype = %d  gridID = %d  levelID = %d",
 	    varID, param, zaxistype, gridID, levelID);
 }
+
+static
+int gribapiGetParam(grib_handle *gh)
+{
+  int pdis = 0, pcat = 0, pnum = 0;
+  int param = 0;
+  int status;
+  long lpar;
+
+  GRIB_CHECK(grib_get_long(gh, "discipline", &lpar), 0);
+  pdis = (int) lpar;
+
+  status = grib_get_long(gh, "parameterCategory", &lpar);
+  if ( status == 0 ) pcat = (int) lpar;
+
+  status = grib_get_long(gh, "parameterNumber", &lpar);
+  if ( status == 0 ) pnum = (int) lpar;
+
+  param = cdiEncodeParam(pnum, pcat, pdis);
+
+  return (param);
+}
+
+static
+compvar2_t gribapiVarSet(int param, int level1, int level2, int leveltype, char *name)
+{
+  compvar2_t compVar;
+  size_t maxlen = sizeof(compVar.name);
+  size_t len = strlen(name);
+  if ( len > maxlen ) len = maxlen;
+
+  compVar.param  = param;
+  compVar.level1 = level1;
+  compVar.level2 = level2;
+  compVar.ltype  = leveltype;
+  memset(compVar.name, 0, maxlen);
+  memcpy(compVar.name, name, len);
+
+  return (compVar);
+}
+
+static
+int gribapiVarCompare(compvar2_t compVar, record_t record)
+{
+  int rstatus;
+  compvar2_t compVar0;
+  size_t maxlen = sizeof(compVar.name);
+
+  compVar0.param  = record.param;
+  compVar0.level1 = record.ilevel;
+  compVar0.level2 = record.ilevel2;
+  compVar0.ltype  = record.ltype;
+  memcpy(compVar0.name, record.varname, maxlen);
+
+  rstatus = memcmp(&compVar0, &compVar, sizeof(compvar2_t));
+
+  return (rstatus);
+}
 #endif
 
-int gribapiScanTimestep1(int streamID)
+int gribapiScanTimestep1(stream_t * streamptr)
 {
 #if  defined  (HAVE_LIBGRIB_API)
   off_t recpos = 0;
@@ -975,6 +1054,7 @@ int gribapiScanTimestep1(int streamID)
   int varID;
   size_t readsize;
   int nrecords, nrecs, recID;
+  int nrecs_scanned;
   int datatype;
   long recsize = 0;
   int warn_time = TRUE;
@@ -985,31 +1065,30 @@ int gribapiScanTimestep1(int streamID)
   int vlistID;
   int comptype;
   long unzipsize;
-  compvar2_t compVar, compVar0;
-  stream_t *streamptr;
+  compvar2_t compVar;
   grib_handle *gh = NULL;
   int leveltype;
-  int pdis = 0, pcat = 0, pnum = 0;
   long editionNumber;
   long lpar;
+  size_t len;
   int bitsPerValue;
   int lieee = FALSE;
   int lbounds;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
+  int level_sf;
+  char paramstr[32];
+  char varname[256];
 
   streamptr->curTsID = 0;
 
-  tsID  = tstepsNewEntry(streamID);
+  tsID  = tstepsNewEntry(streamptr);
   taxis = &streamptr->tsteps[tsID].taxis;
 
   if ( tsID != 0 )
     Error("Internal problem! tstepsNewEntry returns %d", tsID);
 
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
 
+  nrecs_scanned = 0;
   nrecs = 0;
   while ( TRUE )
     {
@@ -1047,6 +1126,7 @@ int gribapiScanTimestep1(int streamID)
 	    }
 	}
 
+      nrecs_scanned++;
       gh = grib_handle_new_from_message(NULL, (void *) gribbuffer, recsize);
       GRIB_CHECK(grib_set_double(gh, "missingValue", cdiDefaultMissval), 0);
 
@@ -1062,6 +1142,7 @@ int gribapiScanTimestep1(int streamID)
 	  param = cdiEncodeParam(rcode, rtabnum, 255);
 
 	  grib1GetLevel(gh, &leveltype, &lbounds, &level1, &level2);
+          level_sf = 0;
 	}
       else
 	{
@@ -1076,19 +1157,18 @@ int gribapiScanTimestep1(int streamID)
 	      else if ( strncmp(typeOfPacking, "grid_ieee", len) == 0 ) lieee = TRUE;
 	    }
 
-	  GRIB_CHECK(grib_get_long(gh, "discipline", &lpar), 0);
-	  pdis = (int) lpar;
-
-	  GRIB_CHECK(grib_get_long(gh, "parameterCategory", &lpar), 0);
-	  pcat = (int) lpar;
+	  param = gribapiGetParam(gh);
 
-	  GRIB_CHECK(grib_get_long(gh, "parameterNumber", &lpar), 0);
-	  pnum = (int) lpar;
+	  grib2GetLevel(gh, &leveltype, &lbounds, &level1, &level2, &level_sf);
+	}
 
-	  param = cdiEncodeParam(pnum, pcat, pdis);
+      cdiParamToString(param, paramstr, sizeof(paramstr));
 
-	  grib2GetLevel(gh, &leveltype, &lbounds, &level1, &level2);
-	}
+      varname[0] = 0;
+      gribapiGetString(gh, "shortName", varname, sizeof(varname));
+      len = strlen(varname);
+      if ( len > 32 ) len = 32;
+      //printf("param = %s  name = %s   l1 = %d  l2 = %d\n", paramstr, varname, level1, level2);
 
       gribapiGetValidityDateTime(gh, &vdate, &vtime);
       /*
@@ -1116,10 +1196,9 @@ int gribapiScanTimestep1(int streamID)
 	{
 	  datetime0.date = vdate;
 	  datetime0.time = vtime;
-	  GRIB_CHECK(grib_get_long(gh, "dataDate", &lpar), 0);
-	  rdate = (int) lpar;
-	  GRIB_CHECK(grib_get_long(gh, "dataTime", &lpar), 0);
-	  rtime = (int) lpar*100;
+
+          gribapiGetDataDateTime(gh, &rdate, &rtime);
+
 	  fcast = gribapiTimeIsFC(gh);
 	  if ( fcast ) tunit = gribapiGetTimeUnits(gh);
 	}
@@ -1128,23 +1207,10 @@ int gribapiScanTimestep1(int streamID)
 	  datetime.date  = vdate;
 	  datetime.time  = vtime;
 
-	  compVar.param  = param;
-          compVar.level1 = level1;
-          compVar.level2 = level2;
-	  compVar.ltype  = leveltype;
+	  compVar = gribapiVarSet(param, level1, level2, leveltype, varname);
 
 	  for ( recID = 0; recID < nrecs; recID++ )
-	    {
-	      compVar0.param  = streamptr->tsteps[0].records[recID].param;
-	      compVar0.level1 = streamptr->tsteps[0].records[recID].ilevel;
-	      compVar0.level2 = streamptr->tsteps[0].records[recID].ilevel2;
-	      compVar0.ltype  = streamptr->tsteps[0].records[recID].ltype;
-	      /*
-	      printf("var0: %d %d %d %d %d\n", recID, compVar0.param, compVar0.level1, compVar0.level2, compVar0.ltype);
-	      printf("var1: %d %d %d %d %d\n", recID, compVar.param, compVar.level1, compVar.level2, compVar.ltype);
-	      */
-	      if ( memcmp(&compVar0, &compVar, sizeof(compvar2_t)) == 0 ) break;
-	    }
+            if ( gribapiVarCompare(compVar, streamptr->tsteps[0].records[recID]) == 0 ) break;
 
 	  if ( cdiInventoryMode == 1 )
 	    {
@@ -1152,8 +1218,6 @@ int gribapiScanTimestep1(int streamID)
 	      if ( warn_time )
 		if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 )
 		  {
-		    char paramstr[32];
-		    cdiParamToString(param, paramstr, sizeof(paramstr));
 		    Warning("Inconsistent verification time (param=%s level=%d)", paramstr, level1);
 		    warn_time = FALSE;
 		  }
@@ -1164,9 +1228,7 @@ int gribapiScanTimestep1(int streamID)
 
 	      if ( recID < nrecs )
 		{
-		  char paramstr[32];
-		  cdiParamToString(param, paramstr, sizeof(paramstr));
-		  Warning("Param=%s level=%d already exist, skipped!", paramstr, level1);
+		  Warning("Param=%s level=%d (record %d) already exist, skipped!", paramstr, level1, nrecs_scanned);
 		  continue;
 		}
 	    }
@@ -1191,7 +1253,8 @@ int gribapiScanTimestep1(int streamID)
       if ( CDI_Debug )
 	Message("%4d %8d %4d  %8d %8d %6d", nrecs, (int)recpos, param, level1, vdate, vtime);
 
-      gribapiAddRecord(streamID, param, gh, recsize, recpos, datatype, comptype);
+      gribapiAddRecord(streamptr, param, gh, recsize, recpos, datatype, comptype, len, varname,
+                       leveltype, lbounds, level1, level2, level_sf);
 
       grib_handle_delete(gh);
       gh = NULL;
@@ -1203,7 +1266,7 @@ int gribapiScanTimestep1(int streamID)
 
   if ( nrecs == 0 ) return (CDI_EUFSTRUCT);
 
-  cdiGenVars(streamID);
+  cdi_generate_vars(streamptr);
 
   if ( fcast )
     {
@@ -1222,7 +1285,7 @@ int gribapiScanTimestep1(int streamID)
   taxis->vdate = datetime0.date;
   taxis->vtime = datetime0.time;
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   vlistDefTaxis(vlistID, taxisID);
 
   nrecords = streamptr->tsteps[0].nallrecs;
@@ -1243,7 +1306,7 @@ int gribapiScanTimestep1(int streamID)
 
   if ( streamptr->ntsteps == -1 )
     {
-      tsID = tstepsNewEntry(streamID);
+      tsID = tstepsNewEntry(streamptr);
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
@@ -1270,7 +1333,7 @@ int gribapiScanTimestep1(int streamID)
 }
 
 
-int gribapiScanTimestep2(int streamID)
+int gribapiScanTimestep2(stream_t * streamptr)
 {
   int rstatus = 0;
 #if  defined  (HAVE_LIBGRIB_API)
@@ -1293,24 +1356,21 @@ int gribapiScanTimestep2(int streamID)
   taxis_t *taxis;
   int vlistID;
   long unzipsize;
-  compvar2_t compVar, compVar0;
-  stream_t *streamptr;
+  compvar2_t compVar;
   grib_handle *gh = NULL;
   int leveltype;
-  int pdis = 0, pcat = 0, pnum = 0;
   int param = 0;
   long editionNumber;
   long lpar;
   int lbounds;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
+  int level_sf;
+  char paramstr[32];
+  char varname[256];
 
   streamptr->curTsID = 1;
 
-  fileID  = streamInqFileID(streamID);
-  vlistID = streamInqVlist(streamID);
+  fileID  = streamptr->fileID;
+  vlistID = streamptr->vlistID;
   taxisID = vlistInqTaxis(vlistID);
 
   gribbuffer = (unsigned char *) streamptr->record->buffer;
@@ -1324,7 +1384,7 @@ int gribapiScanTimestep2(int streamID)
 
   fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-  cdiCreateRecords(streamID, tsID);
+  cdi_create_records(streamptr, tsID);
 
   nrecords = streamptr->tsteps[tsID].nallrecs;
   streamptr->tsteps[1].recIDs = (int *) malloc(nrecords*sizeof(int));
@@ -1386,22 +1446,19 @@ int gribapiScanTimestep2(int streamID)
 	  param = cdiEncodeParam(rcode, rtabnum, 255);
 
 	  grib1GetLevel(gh, &leveltype, &lbounds, &level1, &level2);
+          level_sf = 0;
 	}
       else
 	{
-	  GRIB_CHECK(grib_get_long(gh, "discipline", &lpar), 0);
-	  pdis = (int) lpar;
+	  param = gribapiGetParam(gh);
 
-	  GRIB_CHECK(grib_get_long(gh, "parameterCategory", &lpar), 0);
-	  pcat = (int) lpar;
+	  grib2GetLevel(gh, &leveltype, &lbounds, &level1, &level2, &level_sf);
+	}
 
-	  GRIB_CHECK(grib_get_long(gh, "parameterNumber", &lpar), 0);
-	  pnum = (int) lpar;
+      cdiParamToString(param, paramstr, sizeof(paramstr));
 
-	  param = cdiEncodeParam(pnum, pcat, pdis);
-
-	  grib2GetLevel(gh, &leveltype, &lbounds, &level1, &level2);
-	}
+      varname[0] = 0;
+      gribapiGetString(gh, "shortName", varname, sizeof(varname));
 
       gribapiGetValidityDateTime(gh, &vdate, &vtime);
 
@@ -1410,10 +1467,9 @@ int gribapiScanTimestep2(int streamID)
 	  if ( taxisInqType(taxisID) == TAXIS_RELATIVE )
 	    {
 	      taxis->type  = TAXIS_RELATIVE;
-	      GRIB_CHECK(grib_get_long(gh, "dataDate", &lpar), 0);
-	      taxis->rdate = (int) lpar;
-	      GRIB_CHECK(grib_get_long(gh, "dataTime", &lpar), 0);
-	      taxis->rtime = (int) lpar*100;
+
+              gribapiGetDataDateTime(gh, &(taxis->rdate), &(taxis->rtime));
+
 	      taxis->unit  = gribapiGetTimeUnits(gh);
 	    }
 	  else
@@ -1444,70 +1500,39 @@ int gribapiScanTimestep2(int streamID)
       */
       datetime.date  = vdate;
       datetime.time  = vtime;
-      compVar.param  = param;
-      compVar.level1 = level1;
-      compVar.level2 = level2;
-      compVar.ltype  = leveltype;
-      for ( recID = 0; recID < nrecords; recID++ )
-	{
-	  compVar0.param = streamptr->tsteps[tsID].records[recID].param;
-	  compVar0.level1 = streamptr->tsteps[tsID].records[recID].ilevel;
-	  compVar0.level2 = streamptr->tsteps[tsID].records[recID].ilevel2;
-	  compVar0.ltype  = streamptr->tsteps[tsID].records[recID].ltype;
 
-	  if ( memcmp(&compVar0, &compVar, sizeof(compvar2_t)) == 0 ) break;
-	}
+      compVar = gribapiVarSet(param, level1, level2, leveltype, varname);
+
+      for ( recID = 0; recID < nrecords; recID++ )
+        if ( gribapiVarCompare(compVar, streamptr->tsteps[tsID].records[recID]) == 0 ) break;
 
       if ( recID == nrecords )
 	{
-	  char paramstr[32];
-	  cdiParamToString(param, paramstr, sizeof(paramstr));
-	  Warning("Param=%s level=%d not defined at timestep 1!", paramstr, level1);
+	  Warning("Param=%s (%s) l1=%d l2=%d not defined at timestep 1!", paramstr, varname, level1, level2);
 	  return (CDI_EUFSTRUCT);
 	}
 
-      if ( cdiInventoryMode == 1 )
-	{
-	  if ( streamptr->tsteps[tsID].records[recID].used )
-	    {
-	      break;
-	    }
-	  else
-	    {
-	      streamptr->tsteps[tsID].records[recID].used = TRUE;
-	      streamptr->tsteps[tsID].recIDs[rindex] = recID;
-	    }    
-	}
-      else
-	{
-	  if ( streamptr->tsteps[tsID].records[recID].used )
+      if ( streamptr->tsteps[tsID].records[recID].used )
+        {
+          if ( cdiInventoryMode == 1 ) break;
+          else
 	    {
-	      char paramstr[32];
-	      cdiParamToString(param, paramstr, sizeof(paramstr));
-
 	      if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;
 
 	      Warning("Param=%s level=%d already exist, skipped!", paramstr, level1);
 	      continue;
 	    }
-	  else
-	    {
-	      streamptr->tsteps[tsID].records[recID].used = TRUE;
-	      streamptr->tsteps[tsID].recIDs[rindex] = recID;
-	    }    
 	}
 
+      streamptr->tsteps[tsID].records[recID].used = TRUE;
+      streamptr->tsteps[tsID].recIDs[rindex] = recID;
+
       if ( CDI_Debug )
 	Message("%4d %8d %4d %8d %8d %6d", rindex+1, (int)recpos, param, level1, vdate, vtime);
 
       streamptr->tsteps[tsID].records[recID].size = recsize;
 
-      compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
-      compVar0.level1 = streamptr->tsteps[tsID].records[recID].ilevel;
-      compVar0.level2 = streamptr->tsteps[tsID].records[recID].ilevel2;
-      compVar0.ltype  = streamptr->tsteps[tsID].records[recID].ltype;
-
-      if ( memcmp(&compVar0, &compVar, sizeof(compvar2_t)) != 0 )
+      if ( gribapiVarCompare(compVar, streamptr->tsteps[tsID].records[recID]) != 0 )
 	{
 	  Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
 		  tsID, recID,
@@ -1557,7 +1582,7 @@ int gribapiScanTimestep2(int streamID)
 
   if ( streamptr->ntsteps == -1 )
     {
-      tsID = tstepsNewEntry(streamID);
+      tsID = tstepsNewEntry(streamptr);
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
@@ -1573,7 +1598,7 @@ int gribapiScanTimestep2(int streamID)
 }
 
 
-int gribapiScanTimestep(int streamID)
+int gribapiScanTimestep(stream_t * streamptr)
 {
   int rstatus = 0;
 #if  defined  (HAVE_LIBGRIB_API)
@@ -1594,25 +1619,22 @@ int gribapiScanTimestep(int streamID)
   int vlistID;
   int rindex, nrecs = 0;
   long unzipsize;
-  compvar2_t compVar, compVar0;
-  stream_t *streamptr;
+  compvar2_t compVar;
   grib_handle *gh = NULL;
   int leveltype;
-  int pdis = 0, pcat = 0, pnum = 0;
   int param = 0;
   long editionNumber;
   long lpar;
   int lbounds;
+  int level_sf;
+  char paramstr[32];
+  char varname[256];
 
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
-
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
 
   if ( CDI_Debug )
     {
-      Message("streamID = %d", streamID);
+      Message("streamID = %d", streamptr->self);
       Message("cts = %d", streamptr->curTsID);
       Message("rts = %d", streamptr->rtsteps);
       Message("nts = %d", streamptr->ntsteps);
@@ -1626,7 +1648,7 @@ int gribapiScanTimestep(int streamID)
       gribbuffer = (unsigned char *) streamptr->record->buffer;
       buffersize = streamptr->record->buffersize;
 
-      cdiCreateRecords(streamID, tsID);
+      cdi_create_records(streamptr, tsID);
 
       nrecs = streamptr->tsteps[1].nrecs;
 
@@ -1635,7 +1657,7 @@ int gribapiScanTimestep(int streamID)
       for ( recID = 0; recID < nrecs; recID++ )
 	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
 
-      fileID = streamInqFileID(streamID);
+      fileID = streamptr->fileID;
 
       fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
@@ -1694,22 +1716,19 @@ int gribapiScanTimestep(int streamID)
 	      param = cdiEncodeParam(rcode, rtabnum, 255);
 
 	      grib1GetLevel(gh, &leveltype, &lbounds, &level1, &level2);
+              level_sf = 0;
 	    }
 	  else
 	    {
-	      GRIB_CHECK(grib_get_long(gh, "discipline", &lpar), 0);
-	      pdis = (int) lpar;
+	      param = gribapiGetParam(gh);
 
-	      GRIB_CHECK(grib_get_long(gh, "parameterCategory", &lpar), 0);
-	      pcat = (int) lpar;
+	      grib2GetLevel(gh, &leveltype, &lbounds, &level1, &level2, &level_sf);
+	    }
 
-	      GRIB_CHECK(grib_get_long(gh, "parameterNumber", &lpar), 0);
-	      pnum = (int) lpar;
+          cdiParamToString(param, paramstr, sizeof(paramstr));
 
-	      param = cdiEncodeParam(pnum, pcat, pdis);
-
-	      grib2GetLevel(gh, &leveltype, &lbounds, &level1, &level2);
-	    }
+          varname[0] = 0;
+	  gribapiGetString(gh, "shortName", varname, sizeof(varname));
 
 	  gribapiGetValidityDateTime(gh, &vdate, &vtime);
 
@@ -1721,10 +1740,9 @@ int gribapiScanTimestep(int streamID)
 	      if ( taxisInqType(taxisID) == TAXIS_RELATIVE )
 		{
 		  taxis->type  = TAXIS_RELATIVE;
-		  GRIB_CHECK(grib_get_long(gh, "dataDate", &lpar), 0);
-		  taxis->rdate = (int) lpar;
-		  GRIB_CHECK(grib_get_long(gh, "dataTime", &lpar), 0);
-		  taxis->rtime = (int) lpar*100;
+
+                  gribapiGetDataDateTime(gh, &(taxis->rdate), &(taxis->rtime));
+
 		  taxis->unit  = gribapiGetTimeUnits(gh);
 		}
 	      else
@@ -1753,25 +1771,17 @@ int gribapiScanTimestep(int streamID)
 	  */
 	  datetime.date  = vdate;
 	  datetime.time  = vtime;
-	  compVar.param  = param;
-          compVar.level1 = level1;
-          compVar.level2 = level2;
-          compVar.ltype  = leveltype;
+
+	  compVar = gribapiVarSet(param, level1, level2, leveltype, varname);
+
 	  for ( vrecID = 0; vrecID < nrecs; vrecID++ )
 	    {
 	      recID   = streamptr->tsteps[1].recIDs[vrecID];
-	      compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
-	      compVar0.level1 = streamptr->tsteps[tsID].records[recID].ilevel;
-	      compVar0.level2 = streamptr->tsteps[tsID].records[recID].ilevel2;
-	      compVar0.ltype  = streamptr->tsteps[tsID].records[recID].ltype;
-
-	      if ( memcmp(&compVar0, &compVar, sizeof(compvar2_t)) == 0 ) break;
+	      if ( gribapiVarCompare(compVar, streamptr->tsteps[tsID].records[recID]) == 0 ) break;
 	    }
 
 	  if ( vrecID == nrecs )
 	    {
-	      char paramstr[32];
-	      cdiParamToString(param, paramstr, sizeof(paramstr));
 	      Warning("Param=%s level=%d not available at timestep %d!", paramstr, level1, tsID+1);
 
 	      if ( cdiInventoryMode == 1 )
@@ -1780,18 +1790,10 @@ int gribapiScanTimestep(int streamID)
 		continue;
 	    }
 
-	  if ( cdiInventoryMode == 1 )
-	    {
-	      streamptr->tsteps[tsID].records[recID].used = TRUE;
-	      streamptr->tsteps[tsID].recIDs[rindex] = recID;
-	    }
-	  else
+	  if ( cdiInventoryMode != 1 )
 	    {
 	      if ( streamptr->tsteps[tsID].records[recID].used )
 		{
-		  char paramstr[32];
-		  cdiParamToString(param, paramstr, sizeof(paramstr));
-
 		  if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;
 
 		  if ( CDI_Debug )
@@ -1799,22 +1801,15 @@ int gribapiScanTimestep(int streamID)
 
 		  continue;
 		}
-	      else
-		{
-		  streamptr->tsteps[tsID].records[recID].used = TRUE;
-		  streamptr->tsteps[tsID].recIDs[rindex] = recID;
-		}
 	    }
 
+          streamptr->tsteps[tsID].records[recID].used = TRUE;
+          streamptr->tsteps[tsID].recIDs[rindex] = recID;
+
 	  if ( CDI_Debug )
 	    Message("%4d %8d %4d %8d %8d %6d", rindex+1, (int)recpos, param, level1, vdate, vtime);
 
-	  compVar0.param  = streamptr->tsteps[tsID].records[recID].param;
-	  compVar0.level1 = streamptr->tsteps[tsID].records[recID].ilevel;
-	  compVar0.level2 = streamptr->tsteps[tsID].records[recID].ilevel2;
-	  compVar0.ltype  = streamptr->tsteps[tsID].records[recID].ltype;
-
-	  if ( memcmp(&compVar0, &compVar, sizeof(compvar2_t)) != 0 )
+	  if ( gribapiVarCompare(compVar, streamptr->tsteps[tsID].records[recID]) != 0 )
 	    {
 	      Message("tsID = %d recID = %d param = %3d new %3d  level = %3d new %3d",
 		      tsID, recID,
@@ -1845,7 +1840,6 @@ int gribapiScanTimestep(int streamID)
 
       if ( vrecID < nrecs )
 	{
-	  char paramstr[32];
 	  cdiParamToString(streamptr->tsteps[tsID].records[recID].param, paramstr, sizeof(paramstr));
 	  Warning("Param %d level %d not found at timestep %d!",
 		  paramstr, streamptr->tsteps[tsID].records[recID].ilevel, tsID+1);
@@ -1856,7 +1850,7 @@ int gribapiScanTimestep(int streamID)
 
       if ( streamptr->ntsteps != streamptr->rtsteps )
 	{
-	  tsID = tstepsNewEntry(streamID);
+	  tsID = tstepsNewEntry(streamptr);
 	  if ( tsID != streamptr->rtsteps )
 	    Error("Internal error. tsID = %d", tsID);
 
@@ -2100,8 +2094,7 @@ void gribapiDefDateTimeAbs(int editionNumber, grib_handle *gh, int date, int tim
   if ( editionNumber > 1 ) GRIB_CHECK(grib_set_long(gh, "stepRange", 0), 0);
 
   if ( date == 0 ) date = 10101;
-  GRIB_CHECK(grib_set_long(gh, "dataDate", date), 0);
-  GRIB_CHECK(grib_set_long(gh, "dataTime", time/100), 0);
+  gribapiSetDataDateTime(gh, date, time);
 
   (void ) gribapiDefSteptype(editionNumber, gh, tsteptype, gcinit);
 }
@@ -2118,11 +2111,11 @@ int gribapiDefDateTimeRel(int editionNumber, grib_handle *gh, int rdate, int rti
 
   cdiDecodeDate(rdate, &year, &month, &day);
   cdiDecodeTime(rtime, &hour, &minute, &second);
-  encode_juldaysec(calendar, year, month, day, hour, minute, &julday1, &secofday1);
+  encode_juldaysec(calendar, year, month, day, hour, minute, second, &julday1, &secofday1);
 
   cdiDecodeDate(vdate, &year, &month, &day);
   cdiDecodeTime(vtime, &hour, &minute, &second);
-  encode_juldaysec(calendar, year, month, day, hour, minute, &julday2, &secofday2);
+  encode_juldaysec(calendar, year, month, day, hour, minute, second, &julday2, &secofday2);
 
   (void) julday_sub(julday1, secofday1, julday2, secofday2, &days, &secs);
 
@@ -2134,10 +2127,9 @@ int gribapiDefDateTimeRel(int editionNumber, grib_handle *gh, int rdate, int rti
       if ( editionNumber > 1 ) GRIB_CHECK(grib_set_long(gh, "stepRange", 0), 0);
 
       if ( rdate == 0 ) rdate = 10101;
-      GRIB_CHECK(grib_set_long(gh, "dataDate", rdate), 0);
-      GRIB_CHECK(grib_set_long(gh, "dataTime", rtime/100), 0);
+      gribapiSetDataDateTime(gh, rdate, rtime);
 
-      // printf(">>>>> tsteptype %d  startStep %d  endStep %d\n", tsteptype, startStep, endStep);
+      // printf(">>>>> tsteptype %d  startStep %ld  endStep %ld\n", tsteptype, startStep, endStep);
 
       proDefTempNum = gribapiDefSteptype(editionNumber, gh, tsteptype, gcinit);
 
@@ -2542,7 +2534,7 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int ljpeg, i
 	    GRIB_CHECK(grib_set_long(gh, "numberOfGridUsed", gridInqNumber(gridID)), 0);
 	    GRIB_CHECK(grib_set_long(gh, "numberOfGridInReference", gridInqPosition(gridID)), 0);
             len = 16;
-            GRIB_CHECK(grib_set_string(gh, "uuidOfHGrid", gridInqUUID(gridID, uuid), &len), 0);
+            GRIB_CHECK(grib_set_bytes(gh, "uuidOfHGrid", (unsigned char *) gridInqUUID(gridID, uuid), &len), 0);
 	  }
 
 	break;
@@ -2550,11 +2542,24 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int ljpeg, i
     default:
       {
 	Error("Unsupported grid type: %s", gridNamePtr(gridtype));
+	break;
       }
     }
 }
 
 static
+void getLevelFactor(double level, long *factor, double *scale)
+{
+  double dum;
+
+  if      ( level >= 1     && (int)(1000*modf(level,      &dum)) == 0 ) { *factor = 0; *scale = 1; }
+  else if ( level >= 0.1   && (int)(1000*modf(level*10,   &dum)) == 0 ) { *factor = 1; *scale = 10; }
+  else if ( level >= 0.01  && (int)(1000*modf(level*100,  &dum)) == 0 ) { *factor = 2; *scale = 100; }
+  else if ( level >= 0.001 && (int)(1000*modf(level*1000, &dum)) == 0 ) { *factor = 3; *scale = 1000; }
+  else                                                                  { *factor = 2; *scale = 10; }
+}
+
+static
 void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID, int levelID, int gcinit)
 {
   double level;
@@ -2571,8 +2576,7 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
   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");
@@ -2595,6 +2599,45 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
 
 	break;
       }
+    case ZAXIS_CLOUD_BASE:
+      {
+	if ( editionNumber <= 1 )
+          {
+            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_CLOUDBASE), 0);
+          }
+        else
+          {
+            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_CLOUDBASE), 0);
+          }
+
+        break;
+      }
+    case ZAXIS_CLOUD_TOP:
+      {
+	if ( editionNumber <= 1 )
+          {
+            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_CLOUDTOP), 0);
+          }
+        else
+          {
+            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_CLOUDTOP), 0);
+          }
+
+        break;
+      }
+    case ZAXIS_ISOTHERM_ZERO:
+      {
+	if ( editionNumber <= 1 )
+          {
+            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_ISOTHERM0), 0);
+          }
+        else
+          {
+            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_ISOTHERM0), 0);
+          }
+
+        break;
+      }
     case ZAXIS_TOA:
       {
 	if ( editionNumber <= 1 )
@@ -2806,29 +2849,37 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
 	else
 	  {
 	    long factor;
-	    if      ( memcmp(units, "mm", 2) == 0 ) factor = 3;
-	    else if ( memcmp(units, "cm", 2) == 0 ) factor = 2;
-	    else if ( memcmp(units, "dm", 2) == 0 ) factor = 1;
-	    else                                    factor = 0; // meter
+            double scale;
+            double scalefactor;
+
+	    if      ( memcmp(units, "mm", 2) == 0 ) scalefactor = 0.001;
+	    else if ( memcmp(units, "cm", 2) == 0 ) scalefactor = 0.01;
+	    else if ( memcmp(units, "dm", 2) == 0 ) scalefactor = 0.1;
+	    else                                    scalefactor = 1; // meter
 
 	    if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
 	      {
 		double level1, level2;
-		level1 = zaxisInqLbound(zaxisID, levelID);
-		level2 = zaxisInqUbound(zaxisID, levelID);
+		level1 = scalefactor*zaxisInqLbound(zaxisID, levelID);
+		level2 = scalefactor*zaxisInqUbound(zaxisID, levelID);
 
+                getLevelFactor(level1, &factor, &scale);
 		if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_LANDDEPTH), 0);
 		GRIB_CHECK(grib_set_long(gh, "scaleFactorOfFirstFixedSurface", factor), 0);
-		GRIB_CHECK(grib_set_double(gh, "scaledValueOfFirstFixedSurface", level1), 0);
+		GRIB_CHECK(grib_set_double(gh, "scaledValueOfFirstFixedSurface", level1*scale), 0);
+
+                getLevelFactor(level, &factor, &scale);
 		if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfSecondFixedSurface", GRIB2_LTYPE_LANDDEPTH), 0);
 		GRIB_CHECK(grib_set_long(gh, "scaleFactorOfSecondFixedSurface", factor), 0);
-		GRIB_CHECK(grib_set_double(gh, "scaledValueOfSecondFixedSurface", level2), 0);
+		GRIB_CHECK(grib_set_double(gh, "scaledValueOfSecondFixedSurface", level2*scale), 0);
 	      }
 	    else
 	      {
+                level *= scalefactor;
+                getLevelFactor(level, &factor, &scale);
 		if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_LANDDEPTH), 0);
 		GRIB_CHECK(grib_set_long(gh, "scaleFactorOfFirstFixedSurface", factor), 0);
-	       	GRIB_CHECK(grib_set_double(gh, "scaledValueOfFirstFixedSurface", level), 0);
+	       	GRIB_CHECK(grib_set_double(gh, "scaledValueOfFirstFixedSurface", level*scale), 0);
 	      }
 	  }
 
@@ -2872,13 +2923,12 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
           {
             reference = zaxisInqReference(zaxisID);
             if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_REFERENCE), 0);
-            GRIB_CHECK(grib_set_double(gh, "level", level), 0);
-
-            GRIB_CHECK(grib_set_long(gh, "NV", 3), 0);
-            GRIB_CHECK(grib_set_long(gh, "nlev", (long) zaxisInqSize(zaxisID)), 0);
-            GRIB_CHECK(grib_set_long(gh, "numberOfVGridUsed", reference), 0);
+            GRIB_CHECK(grib_set_long(gh, "NV", 6), 0);
+            GRIB_CHECK(grib_set_double(gh, "nlev", (double) zaxisInqSize(zaxisID)), 0);
+            GRIB_CHECK(grib_set_double(gh, "numberOfVGridUsed", (double) reference), 0);
             len = 16;
-            GRIB_CHECK(grib_set_string(gh, "uuidOfVGrid", zaxisInqUUID(zaxisID, uuid), &len), 0);
+            GRIB_CHECK(grib_set_bytes(gh, "uuidOfVGrid", (unsigned char *) zaxisInqUUID(zaxisID, uuid), &len), 0);
+            GRIB_CHECK(grib_set_double(gh, "level", level), 0);
           }
 
         break;
@@ -2992,6 +3042,27 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
 
   gribapiDefLevel(editionNumber, gh, param, zaxisID, levelID, gc->init);
 
+  /* ---------------------------------- */
+  /* Local change: 2013-01-28, FP (DWD) */
+  /* ---------------------------------- */
+
+  vlist_t *vlistptr;
+  vlistptr = vlist_to_pointer(vlistID);
+  if (!gc->init) {
+    int i;
+    for (i=0; i<vlistptr->vars[varID].opt_grib_dbl_nentries; i++)
+      {
+	GRIB_CHECK(grib_set_double(gh, vlistptr->vars[varID].opt_grib_dbl_keyword[i],
+				   vlistptr->vars[varID].opt_grib_dbl_val[i]), 0);
+      }
+    for (i=0; i<vlistptr->vars[varID].opt_grib_int_nentries; i++)
+      {
+	GRIB_CHECK(grib_set_long(gh, vlistptr->vars[varID].opt_grib_int_keyword[i],
+				 vlistptr->vars[varID].opt_grib_int_val[i]), 0);
+      }
+  }
+
+
   if ( nmiss > 0 )
     {
       GRIB_CHECK(grib_set_long(gh, "bitmapPresent", 1), 0);
diff --git a/libcdi/src/stream_gribapi.h b/libcdi/src/stream_gribapi.h
index b068f3e..380d0d6 100644
--- a/libcdi/src/stream_gribapi.h
+++ b/libcdi/src/stream_gribapi.h
@@ -1,9 +1,9 @@
 #ifndef _STREAM_GRIBAPI_H
 #define _STREAM_GRIBAPI_H
 
-int gribapiScanTimestep1(int streamID);
-int gribapiScanTimestep2(int streamID);
-int gribapiScanTimestep(int streamID);
+int gribapiScanTimestep1(stream_t * streamptr);
+int gribapiScanTimestep2(stream_t * streamptr);
+int gribapiScanTimestep(stream_t * streamptr);
 
 int gribapiDecode(unsigned char *gribbuffer, int gribsize, double *data, int gridsize,
 		  int unreduced, int *nmiss, int *zip, double missval);
diff --git a/libcdi/src/stream_history.c b/libcdi/src/stream_history.c
index 41e4693..558482c 100644
--- a/libcdi/src/stream_history.c
+++ b/libcdi/src/stream_history.c
@@ -27,7 +27,7 @@ void streamDefHistory(int streamID, int length, const char *history)
 	  if ( len )
 	    {
 	      histstring = strdupx(history);
-	      cdfDefHistory(streamID, length, histstring);
+	      cdfDefHistory(streamptr, length, histstring);
 	      free(histstring);
 	    }
 	}
@@ -47,7 +47,7 @@ int streamInqHistorySize(int streamID)
        streamptr->filetype == FILETYPE_NC4 ||
        streamptr->filetype == FILETYPE_NC4C )
     {
-      size = cdfInqHistorySize(streamID);
+      size = cdfInqHistorySize(streamptr);
     }
 
   return (size);
@@ -65,7 +65,7 @@ void streamInqHistoryString(int streamID, char *history)
        streamptr->filetype == FILETYPE_NC4 ||
        streamptr->filetype == FILETYPE_NC4C )
     {
-      cdfInqHistoryString(streamID, history);
+      cdfInqHistoryString(streamptr, history);
     }
 }
 /*
diff --git a/libcdi/src/stream_ieg.c b/libcdi/src/stream_ieg.c
index 40481fe..1c48d27 100644
--- a/libcdi/src/stream_ieg.c
+++ b/libcdi/src/stream_ieg.c
@@ -31,7 +31,7 @@
 typedef struct {
   int param;
   int level;
-} IEGCOMPVAR; 
+} IEGCOMPVAR;
 
 
 int iegInqDatatype(int prec)
@@ -62,7 +62,7 @@ int iegDefDatatype(int datatype)
 }
 
 /* not used
-int iegInqRecord(int streamID, int *varID, int *levelID)
+int iegInqRecord(stream_t *streamptr, int *varID, int *levelID)
 {
   int status;
   int fileID;
@@ -70,14 +70,9 @@ int iegInqRecord(int streamID, int *varID, int *levelID)
   int zaxisID = -1;
   int vlistID;
   iegrec_t *iegp;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
-
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
   iegp    = streamptr->record->iegp;
 
   *varID   = -1;
@@ -99,12 +94,12 @@ int iegInqRecord(int streamID, int *varID, int *levelID)
   zaxisID = vlistInqVarZaxis(vlistID, *varID);
 
   *levelID = zaxisInqLevelID(zaxisID, (double) ilevel);
-  
+
   return (1);
 }
 */
 
-int iegReadRecord(int streamID, double *data, int *nmiss)
+int iegReadRecord(stream_t *streamptr, double *data, int *nmiss)
 {
   int vlistID, fileID;
   int status;
@@ -114,14 +109,9 @@ int iegReadRecord(int streamID, double *data, int *nmiss)
   int i, size;
   double missval;
   iegrec_t *iegp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
   tsID    = streamptr->curTsID;
   vrecID  = streamptr->tsteps[tsID].curRecID;
   recID   = streamptr->tsteps[tsID].recIDs[vrecID];
@@ -536,7 +526,7 @@ void iegDefLevel(int *pdb, int *gdb, double *vct, int zaxisID, int levelID)
 }
 
 
-int iegCopyRecord(int streamID2, int streamID1)
+int iegCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
 {
   int fileID1, fileID2;
   int tsID, recID, vrecID;
@@ -544,17 +534,9 @@ int iegCopyRecord(int streamID2, int streamID1)
   off_t recpos;
   int status = 0;
   char *buffer;
-  stream_t *streamptr1;
-  stream_t *streamptr2;
 
-  streamptr1 = stream_to_pointer(streamID1);
-  streamptr2 = stream_to_pointer(streamID2);
-
-  stream_check_ptr(__func__, streamptr1);
-  stream_check_ptr(__func__, streamptr2);
-
-  fileID1 = streamInqFileID(streamID1);
-  fileID2 = streamInqFileID(streamID2);
+  fileID1 = streamptr1->fileID;
+  fileID2 = streamptr2->fileID;
 
   tsID    = streamptr1->curTsID;
   vrecID  = streamptr1->tsteps[tsID].curRecID;
@@ -576,7 +558,7 @@ int iegCopyRecord(int streamID2, int streamID1)
 }
 
 
-int iegDefRecord(int streamID)
+int iegDefRecord(stream_t *streamptr)
 {
   int status = 0;
   int vlistID;
@@ -588,13 +570,8 @@ int iegDefRecord(int streamID)
   int varID, levelID, tsID, zaxisID;
   int byteorder;
   iegrec_t *iegp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   iegp    = streamptr->record->iegp;
   byteorder = streamptr->byteorder;
 
@@ -604,7 +581,7 @@ int iegDefRecord(int streamID)
 
   gridID  = vlistInqVarGrid(vlistID, varID);
   zaxisID = vlistInqVarZaxis(vlistID, varID);
-  
+
   iegInitMem(iegp);
   for ( i = 0; i < 37; i++ ) iegp->ipdb[i] = -1;
 
@@ -629,23 +606,18 @@ int iegDefRecord(int streamID)
 }
 
 
-int iegWriteRecord(int streamID, const double *data)
+int iegWriteRecord(stream_t *streamptr, const double *data)
 {
   int fileID;
   int status = 0;
   int i, gridsize, gridID;
   double refval;
   iegrec_t *iegp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
-  stream_check_ptr(__func__, streamptr);
-
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
   iegp   = streamptr->record->iegp;
   gridID = streamptr->record->gridID;
-  
+
   gridsize = gridInqSize(gridID);
 
   refval = data[0];
@@ -662,7 +634,7 @@ int iegWriteRecord(int streamID, const double *data)
 }
 
 static
-void iegAddRecord(int streamID, int param, int *pdb, int *gdb, double *vct,
+void iegAddRecord(stream_t *streamptr, int param, int *pdb, int *gdb, double *vct,
 		  long recsize, off_t position, int prec)
 {
   int leveltype;
@@ -676,13 +648,10 @@ void iegAddRecord(int streamID, int param, int *pdb, int *gdb, double *vct,
   record_t *record;
   grid_t grid;
   int vlistID;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   tsID    = streamptr->curTsID;
-  recID   = recordNewEntry(streamID, tsID);
+  recID   = recordNewEntry(streamptr, tsID);
   record  = &streamptr->tsteps[tsID].records[recID];
 
   if ( IEG_P_LevelType(pdb) == IEG_LTYPE_HYBRID_LAYER )
@@ -783,7 +752,7 @@ void iegAddRecord(int streamID, int param, int *pdb, int *gdb, double *vct,
   gridID = varDefGrid(vlistID, grid, 0);
 
   leveltype = iegGetZaxisType(IEG_P_LevelType(pdb));
-  
+
   if ( leveltype == ZAXIS_HYBRID )
     {
       int i;
@@ -800,7 +769,7 @@ void iegAddRecord(int streamID, int param, int *pdb, int *gdb, double *vct,
 
   datatype = iegInqDatatype(prec);
 
-  varAddRecord(recID, param, gridID, leveltype, lbounds, level1, level2,
+  varAddRecord(recID, param, gridID, leveltype, lbounds, level1, level2, 0,
 	       datatype, &varID, &levelID, UNDEFID, 0, 0, NULL, NULL, NULL);
 
   (*record).varID   = varID;
@@ -816,15 +785,12 @@ void iegAddRecord(int streamID, int param, int *pdb, int *gdb, double *vct,
 
 #if 0
 static
-void iegCmpRecord(int streamID, int tsID, int recID, off_t position, int param,
+void iegCmpRecord(stream_t *streamptr, int tsID, int recID, off_t position, int param,
 		  int level, int xsize, int ysize)
 {
   int varID = 0;
   int levelID = 0;
   record_t *record;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   record  = &streamptr->tsteps[tsID].records[recID];
 
@@ -865,8 +831,8 @@ void iegDateTime(int *pdb, int *date, int *time)
 }
 
 static
-void iegScanTimestep1(int streamID)
-{  
+void iegScanTimestep1(stream_t *streamptr)
+{
   int prec = 0;
   int status;
   int fileID;
@@ -884,22 +850,17 @@ void iegScanTimestep1(int streamID)
   int vlistID;
   IEGCOMPVAR compVar, compVar0;
   iegrec_t *iegp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   streamptr->curTsID = 0;
 
   iegp  = streamptr->record->iegp;
-  tsID  = tstepsNewEntry(streamID);
+  tsID  = tstepsNewEntry(streamptr);
   taxis = &streamptr->tsteps[tsID].taxis;
 
   if ( tsID != 0 )
     Error("Internal problem! tstepsNewEntry returns %d", tsID);
 
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
 
   nrecs = 0;
   while ( TRUE )
@@ -955,22 +916,22 @@ void iegScanTimestep1(int streamID)
       if ( CDI_Debug )
 	Message("%4d%8d%4d%8d%8d%6d", nrecs, (int)recpos, param, rlevel, vdate, vtime);
 
-      iegAddRecord(streamID, param, iegp->ipdb, iegp->igdb, iegp->vct, recsize, recpos, prec);
+      iegAddRecord(streamptr, param, iegp->ipdb, iegp->igdb, iegp->vct, recsize, recpos, prec);
     }
 
   streamptr->rtsteps = 1;
 
-  cdiGenVars(streamID);
+  cdi_generate_vars(streamptr);
 
   taxisID = taxisCreate(TAXIS_ABSOLUTE);
   taxis->type  = TAXIS_ABSOLUTE;
   taxis->vdate = datetime0.date;
   taxis->vtime = datetime0.time;
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   vlistDefTaxis(vlistID, taxisID);
 
-  cdiCheckContents(streamID);
+  vlist_check_contents(vlistID);
 
   nrecords = streamptr->tsteps[0].nallrecs;
   if ( nrecords < streamptr->tsteps[0].recordSize )
@@ -987,7 +948,7 @@ void iegScanTimestep1(int streamID)
 
   if ( streamptr->ntsteps == -1 )
     {
-      tsID = tstepsNewEntry(streamID);
+      tsID = tstepsNewEntry(streamptr);
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
@@ -1009,8 +970,8 @@ void iegScanTimestep1(int streamID)
 }
 
 static
-int iegScanTimestep2(int streamID)
-{  
+int iegScanTimestep2(stream_t *streamptr)
+{
   int status;
   int fileID;
   int tabnum;
@@ -1026,16 +987,11 @@ int iegScanTimestep2(int streamID)
   int vlistID;
   IEGCOMPVAR compVar, compVar0;
   iegrec_t *iegp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   streamptr->curTsID = 1;
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
   iegp    = streamptr->record->iegp;
 
   tsID = streamptr->rtsteps;
@@ -1046,7 +1002,7 @@ int iegScanTimestep2(int streamID)
 
   fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-  cdiCreateRecords(streamID, tsID);
+  cdi_create_records(streamptr, tsID);
 
   nrecords = streamptr->tsteps[0].nallrecs;
   streamptr->tsteps[1].recIDs = (int *) malloc(nrecords*sizeof(int));
@@ -1057,9 +1013,9 @@ int iegScanTimestep2(int streamID)
   for ( recID = 0; recID < nrecords; recID++ )
     {
       varID = streamptr->tsteps[0].records[recID].varID;
-      streamptr->tsteps[tsID].records[recID].position = 
+      streamptr->tsteps[tsID].records[recID].position =
 	streamptr->tsteps[0].records[recID].position;
-      streamptr->tsteps[tsID].records[recID].size     = 
+      streamptr->tsteps[tsID].records[recID].size     =
 	streamptr->tsteps[0].records[recID].size;
     }
 
@@ -1165,7 +1121,7 @@ int iegScanTimestep2(int streamID)
 
   if ( streamptr->ntsteps == -1 )
     {
-      tsID = tstepsNewEntry(streamID);
+      tsID = tstepsNewEntry(streamptr);
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
@@ -1177,23 +1133,18 @@ int iegScanTimestep2(int streamID)
 }
 
 
-int iegInqContents(int streamID)
+int iegInqContents(stream_t *streamptr)
 {
   int fileID;
   int status = 0;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
-
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
 
   streamptr->curTsID = 0;
 
-  iegScanTimestep1(streamID);
- 
-  if ( streamptr->ntsteps == -1 ) status = iegScanTimestep2(streamID);
+  iegScanTimestep1(streamptr);
+
+  if ( streamptr->ntsteps == -1 ) status = iegScanTimestep2(streamptr);
 
   fileSetPos(fileID, 0, SEEK_SET);
 
@@ -1201,7 +1152,7 @@ int iegInqContents(int streamID)
 }
 
 static
-int iegScanTimestep(int streamID)
+int iegScanTimestep(stream_t *streamptr)
 {
   int status;
   int fileID;
@@ -1216,15 +1167,10 @@ int iegScanTimestep(int streamID)
   int rindex, nrecs = 0;
   IEGCOMPVAR compVar, compVar0;
   iegrec_t *iegp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   if ( CDI_Debug )
     {
-      Message("streamID = %d", streamID);
+      Message("streamID = %d", streamptr->self);
       Message("cts = %d", streamptr->curTsID);
       Message("rts = %d", streamptr->rtsteps);
       Message("nts = %d", streamptr->ntsteps);
@@ -1239,7 +1185,7 @@ int iegScanTimestep(int streamID)
 
   if ( streamptr->tsteps[tsID].recordSize == 0 )
     {
-      cdiCreateRecords(streamID, tsID);
+      cdi_create_records(streamptr, tsID);
 
       nrecs = streamptr->tsteps[1].nrecs;
 
@@ -1248,7 +1194,7 @@ int iegScanTimestep(int streamID)
       for ( recID = 0; recID < nrecs; recID++ )
 	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
 
-      fileID = streamInqFileID(streamID);
+      fileID = streamptr->fileID;
 
       fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
@@ -1312,7 +1258,7 @@ int iegScanTimestep(int streamID)
 
       if ( streamptr->ntsteps != streamptr->rtsteps )
 	{
-	  tsID = tstepsNewEntry(streamID);
+	  tsID = tstepsNewEntry(streamptr);
 	  if ( tsID != streamptr->rtsteps )
 	    Error("Internal error. tsID = %d", tsID);
 
@@ -1334,24 +1280,19 @@ int iegScanTimestep(int streamID)
 }
 
 
-int iegInqTimestep(int streamID, int tsID)
+int iegInqTimestep(stream_t *streamptr, int tsID)
 {
   int ntsteps, nrecs;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   if ( tsID == 0 && streamptr->rtsteps == 0 )
     Error("Call to cdiInqContents missing!");
 
   if ( CDI_Debug )
     Message("tsID = %d rtsteps = %d", tsID, streamptr->rtsteps);
-  
+
   ntsteps = UNDEFID;
   while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == UNDEFID )
-    ntsteps = iegScanTimestep(streamID);
+    ntsteps = iegScanTimestep(streamptr);
 
   if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID )
     {
@@ -1367,7 +1308,7 @@ int iegInqTimestep(int streamID, int tsID)
 }
 
 
-void iegReadVarDP(int streamID, int varID, double *data, int *nmiss)
+void iegReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
 {
   int vlistID, fileID;
   int levID, nlevs, gridID, gridsize;
@@ -1377,13 +1318,10 @@ void iegReadVarDP(int streamID, int varID, double *data, int *nmiss)
   int i;
   double missval;
   iegrec_t *iegp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   iegp     = streamptr->record->iegp;
-  vlistID  = streamInqVlist(streamID);
-  fileID   = streamInqFileID(streamID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   nlevs    = streamptr->vars[varID].nlevs;
   missval  = vlistInqVarMissval(vlistID, varID);
   gridID   = vlistInqVarGrid(vlistID, varID);
@@ -1415,7 +1353,7 @@ void iegReadVarDP(int streamID, int varID, double *data, int *nmiss)
 }
 
 
-void iegReadVarSliceDP(int streamID, int varID, int levID, double *data, int *nmiss)
+void iegReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, int *nmiss)
 {
   int vlistID, fileID;
   int nlevs, gridID, gridsize;
@@ -1425,13 +1363,10 @@ void iegReadVarSliceDP(int streamID, int varID, int levID, double *data, int *nm
   int i;
   double missval;
   iegrec_t *iegp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   iegp     = streamptr->record->iegp;
-  vlistID  = streamInqVlist(streamID);
-  fileID   = streamInqFileID(streamID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   nlevs    = streamptr->vars[varID].nlevs;
   missval  = vlistInqVarMissval(vlistID, varID);
   gridID   = vlistInqVarGrid(vlistID, varID);
@@ -1462,7 +1397,7 @@ void iegReadVarSliceDP(int streamID, int varID, int levID, double *data, int *nm
 }
 
 
-void iegWriteVarDP(int streamID, int varID, const double *data)
+void iegWriteVarDP(stream_t *streamptr, int varID, const double *data)
 {
   int fileID;
   int levID, nlevs, gridID, gridsize;
@@ -1475,20 +1410,17 @@ void iegWriteVarDP(int streamID, int varID, const double *data)
   int param, pdis, pcat, pnum;
   double refval;
   iegrec_t *iegp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   if ( CDI_Debug )
-    Message("streamID = %d  varID = %d", streamID, varID);
+    Message("streamID = %d  varID = %d", streamptr->self, varID);
 
   iegp     = streamptr->record->iegp;
 
   iegInitMem(iegp);
   for ( i = 0; i < 37; i++ ) iegp->ipdb[i] = -1;
 
-  vlistID  = streamInqVlist(streamID);
-  fileID   = streamInqFileID(streamID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   tsID     = streamptr->curTsID;
   gridID   = vlistInqVarGrid(vlistID, varID);
   gridsize = gridInqSize(gridID);
@@ -1528,7 +1460,7 @@ void iegWriteVarDP(int streamID, int varID, const double *data)
 }
 
 
-void iegWriteVarSliceDP(int streamID, int varID, int levID, const double *data)
+void iegWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double *data)
 {
   int fileID;
   int gridID;
@@ -1539,13 +1471,10 @@ void iegWriteVarSliceDP(int streamID, int varID, int levID, const double *data)
   int vlistID;
   /* int param, date, time, datasize; */
   iegrec_t *iegp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   iegp     = streamptr->record->iegp;
-  vlistID  = streamInqVlist(streamID);
-  fileID   = streamInqFileID(streamID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   /* tsID     = streamptr->curTsID; */
   gridID   = vlistInqVarGrid(vlistID, varID);
   zaxisID  = vlistInqVarZaxis(vlistID, varID);
diff --git a/libcdi/src/stream_ieg.h b/libcdi/src/stream_ieg.h
index 7b5c76f..860cedb 100644
--- a/libcdi/src/stream_ieg.h
+++ b/libcdi/src/stream_ieg.h
@@ -5,20 +5,20 @@
 #  include "ieg.h"
 #endif
 
-int    iegInqContents(int streamID);
-int    iegInqTimestep(int streamID, int tsID);
+int    iegInqContents(stream_t *streamptr);
+int    iegInqTimestep(stream_t *streamptr, int tsID);
 
-int    iegInqRecord(int streamID, int *varID, int *levelID);
-int    iegDefRecord(int streamID);
-int    iegCopyRecord(int streamIDdest, int streamIDsrc);
-int    iegReadRecord(int streamID, double *data, int *nmiss);
-int    iegWriteRecord(int streamID, const double *data);
+int    iegInqRecord(stream_t *streamptr, int *varID, int *levelID);
+int    iegDefRecord(stream_t *streamptr);
+int    iegCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
+int    iegReadRecord(stream_t *streamptr, double *data, int *nmiss);
+int    iegWriteRecord(stream_t *streamptr, const double *data);
 
-void   iegReadVarDP (int streamID, int varID,       double *data, int *nmiss);
-void   iegWriteVarDP(int streamID, int varID, const double *data);
+void   iegReadVarDP (stream_t *streamptr, int varID,       double *data, int *nmiss);
+void   iegWriteVarDP(stream_t *streamptr, int varID, const double *data);
 
-void   iegReadVarSliceDP (int streamID, int varID, int levelID,       double *data, int *nmiss);
-void   iegWriteVarSliceDP(int streamID, int varID, int levelID, const double *data);
+void   iegReadVarSliceDP (stream_t *streamptr, int varID, int levelID,       double *data, int *nmiss);
+void   iegWriteVarSliceDP(stream_t *streamptr, int varID, int levelID, const double *data);
 
 #endif  /* _STREAM_IEG_H */
 /*
diff --git a/libcdi/src/stream_int.c b/libcdi/src/stream_int.c
index 8bcab29..cf69623 100644
--- a/libcdi/src/stream_int.c
+++ b/libcdi/src/stream_int.c
@@ -33,6 +33,7 @@ int cdiChunkType       = CHUNK_GRID;
 int cdiSplitLtype105   = CDI_UNDEFID;
 
 int cdiIgnoreAttCoordinates = FALSE;
+int cdiIgnoreValidRange     = FALSE;
 int cdiSkipRecords          = 0;
 int cdiInventoryMode        = 1;
 
@@ -48,6 +49,7 @@ char *Filetypes[] = {
   "netCDF",
   "netCDF2",
   "netCDF4",
+  "netCDF4c",
   "SERVICE",
   "EXTRA",
   "IEG",
@@ -112,6 +114,7 @@ long cdiGetenvInt(char *envName)
 		  fact = 0;
 		  Message("Invalid number string in %s: %s", envName, envString);
 		  Warning("%s must comprise only digits [0-9].",envName);
+		  break;
 		}
 	      break;
 	    }
@@ -128,8 +131,8 @@ long cdiGetenvInt(char *envName)
 static
 void cdiSetChunk(const char *chunkAlgo)
 {
-  char *pch;
-  size_t len = strlen(chunkAlgo);
+  //char *pch;
+  //size_t len = strlen(chunkAlgo);
   int algo = -1;
 
   if      ( strcmp("auto",  chunkAlgo)   == 0 ) algo = CHUNK_AUTO;
@@ -207,6 +210,9 @@ void cdiInitialize(void)
       envString = getenv("IGNORE_ATT_COORDINATES");
       if ( envString ) cdiIgnoreAttCoordinates = atoi(envString);
 
+      envString = getenv("IGNORE_VALID_RANGE");
+      if ( envString ) cdiIgnoreValidRange = atoi(envString);
+
       envString = getenv("CDI_SKIP_RECORDS");
       if ( envString )
 	{
@@ -268,7 +274,7 @@ char *strfiletype(int filetype)
   if ( filetype > 0 && filetype < size )
     name = Filetypes[filetype];
   else
-    name = Filetypes[0];  
+    name = Filetypes[0];
 
   return (name);
 }
@@ -423,17 +429,10 @@ double cdiInqMissval(void)
 }
 
 
-void cdiCheckContents(int streamID)
+void vlist_check_contents(int vlistID)
 {
   int index, nzaxis, zaxisID;
-  int vlistID;
-  stream_t *streamptr;
-
-  streamptr = ( stream_t *) reshGetVal ( streamID, &streamOps );
-
-  stream_check_ptr(__func__, streamptr);
 
-  vlistID = streamInqVlist(streamID);
   nzaxis = vlistNzaxis(vlistID);
 
   for ( index = 0; index < nzaxis; index++ )
@@ -467,7 +466,7 @@ void streamDefineTaxis(int streamID)
       int varID, nvars;
       int vlistID;
 
-      vlistID = streamInqVlist(streamID);
+      vlistID = streamptr->vlistID;
 
       nvars = vlistNvars(vlistID);
       for ( varID = 0; varID < nvars; varID++ )
diff --git a/libcdi/src/stream_int.h b/libcdi/src/stream_int.h
index 2559b75..f6c3bc9 100644
--- a/libcdi/src/stream_int.h
+++ b/libcdi/src/stream_int.h
@@ -154,6 +154,7 @@ typedef struct
   short     used;
   short     varID;
   short     levelID;
+  char      varname[32]; /* needed for grib decoding with GRIB_API */
 }
 record_t;
 
@@ -250,6 +251,12 @@ typedef struct {
   void       *gribContainers;
 #endif
   int         vlistIDorig;
+
+  /* ---------------------------------- */
+  /* Local change: 2013-02-18, FP (DWD) */
+  /* ---------------------------------- */
+
+  void *gh; // grib handle
 }
 stream_t;
 
@@ -285,21 +292,21 @@ void    streamDefineTaxis(int streamID);
 
 int     streamsNewEntry(int filetype);
 void    streamsInitEntry(int streamID);
-int     streamNewVar(int streamID, int gridID, int zaxisID);
+int     stream_new_var(stream_t *streamptr, int gridID, int zaxisID);
 
-int     tstepsNewEntry(int streamID);
+int     tstepsNewEntry(stream_t *streamptr);
 
 char   *strfiletype(int filetype);
 
-void    cdiGenVars(int streamID);
+void    cdi_generate_vars(stream_t *streamptr);
 
-void    cdiCheckContents(int streamID);
+void    vlist_check_contents(int vlistID);
 
-void    cdiCreateRecords(int streamID, int tsID);
+void    cdi_create_records(stream_t *streamptr, int tsID);
 
-int     recordNewEntry(int streamID, int tsID);
+int     recordNewEntry(stream_t *streamptr, int tsID);
 
-void    cdiCreateTimesteps(int streamID);
+void    cdiCreateTimesteps(stream_t *streamptr);
 
 void    recordInitEntry(record_t *record);
 
@@ -323,6 +330,9 @@ void  cdiInitialize(void);
 
 void stream_write_record(int streamID, int memtype, const void *data, int nmiss);
 
+void uuid2str(const char *uuid, char *uuidstr);
+void str2uuid(const char *uuidstr, char *uuid);
+
 
 #endif  /* _STREAM_INT_H */
 /*
diff --git a/libcdi/src/stream_record.c b/libcdi/src/stream_record.c
index 46d884d..28a55f6 100644
--- a/libcdi/src/stream_record.c
+++ b/libcdi/src/stream_record.c
@@ -26,17 +26,15 @@ void recordInitEntry(record_t *record)
   (*record).used     = FALSE;
   (*record).varID    = CDI_UNDEFID;
   (*record).levelID  = CDI_UNDEFID;
+  memset((*record).varname, 0, sizeof((*record).varname));
 }
 
 
-int recordNewEntry(int streamID, int tsID)
+int recordNewEntry(stream_t *streamptr, int tsID)
 {
   int recordID = 0;
   int recordSize;
   record_t *records;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   recordSize = streamptr->tsteps[tsID].recordSize;
   records    = streamptr->tsteps[tsID].records;
@@ -97,13 +95,9 @@ int recordNewEntry(int streamID, int tsID)
   return (recordID);
 }
 
-
-void cdiInitRecord(int streamID)
+static
+void cdiInitRecord(stream_t *streamptr)
 {
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
   streamptr->record = (Record *) malloc(sizeof(Record));
 
   streamptr->record->used       = 0;
@@ -140,7 +134,7 @@ void streamInqRecord(int streamID, int *varID, int *levelID)
 
   cdiDefAccesstype(streamID, TYPE_REC);
 
-  if ( ! streamptr->record ) cdiInitRecord(streamID);
+  if ( ! streamptr->record ) cdiInitRecord(streamptr);
 
   tsID   = streamptr->curTsID;
   rindex = streamptr->tsteps[tsID].curRecID + 1;
@@ -178,7 +172,7 @@ void streamInqRecord(int streamID, int *varID, int *levelID)
       }
     case FILETYPE_SRV:
       {
-        rec = srvInqRecord(streamID, varID, levelID);
+        rec = srvInqRecord(streamptr, varID, levelID);
 	break;
       }
 #if  defined  (HAVE_LIBNETCDF)
@@ -222,9 +216,9 @@ void streamDefRecord(int streamID, int varID, int levelID)
       streamDefTimestep(streamID, tsID);
     }
 
-  if ( ! streamptr->record ) cdiInitRecord(streamID);
+  if ( ! streamptr->record ) cdiInitRecord(streamptr);
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   gridID  = vlistInqVarGrid(vlistID, varID);
   zaxisID = vlistInqVarZaxis(vlistID, varID);
   param   = vlistInqVarParam(vlistID, varID);
@@ -248,28 +242,28 @@ void streamDefRecord(int streamID, int varID, int levelID)
     case FILETYPE_GRB:
     case FILETYPE_GRB2:
       {
-        status = grbDefRecord(streamID);
+        status = grbDefRecord(streamptr);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBSERVICE)
     case FILETYPE_SRV:
       {
-        status = srvDefRecord(streamID);
+        status = srvDefRecord(streamptr);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBEXTRA)
     case FILETYPE_EXT:
       {
-        status = extDefRecord(streamID);
+        status = extDefRecord(streamptr);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBIEG)
     case FILETYPE_IEG:
       {
-        status = iegDefRecord(streamID);
+        status = iegDefRecord(streamptr);
 	break;
       }
 #endif
@@ -279,8 +273,8 @@ void streamDefRecord(int streamID, int varID, int levelID)
     case FILETYPE_NC4:
     case FILETYPE_NC4C:
       {
-	if ( streamptr->accessmode == 0 ) cdfEndDef(streamID);
-	status = cdfDefRecord(streamID);
+	if ( streamptr->accessmode == 0 ) cdfEndDef(streamptr);
+	status = cdfDefRecord(streamptr);
 	break;
       }
 #endif
@@ -316,28 +310,28 @@ void streamReadRecord(int streamID, double *data, int *nmiss)
     case FILETYPE_GRB:
     case FILETYPE_GRB2:
       {
-        status = grbReadRecord(streamID, data, nmiss);
+        status = grbReadRecord(streamptr, data, nmiss);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBSERVICE)
     case FILETYPE_SRV:
       {
-        status = srvReadRecord(streamID, data, nmiss);
+        status = srvReadRecord(streamptr, data, nmiss);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBEXTRA)
     case FILETYPE_EXT:
       {
-        status = extReadRecord(streamID, data, nmiss);
+        status = extReadRecord(streamptr, data, nmiss);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBIEG)
     case FILETYPE_IEG:
       {
-        status = iegReadRecord(streamID, data, nmiss);
+        status = iegReadRecord(streamptr, data, nmiss);
 	break;
       }
 #endif
@@ -347,7 +341,7 @@ void streamReadRecord(int streamID, double *data, int *nmiss)
     case FILETYPE_NC4:
     case FILETYPE_NC4C:
       {
-	status = cdfReadRecord(streamID, data, nmiss);
+	status = cdfReadRecord(streamptr, data, nmiss);
 	break;
       }
 #endif
@@ -380,8 +374,7 @@ void stream_write_record(int streamID, int memtype, const void *data, int nmiss)
     case FILETYPE_GRB:
     case FILETYPE_GRB2:
       {
-        if ( memtype == MEMTYPE_FLOAT ) Error("grbWriteRecord not implemented for memtype float!");
-        status = grbWriteRecord(streamID, data, nmiss);
+        status = grb_write_record(streamptr, memtype, data, nmiss);
 	break;
       }
 #endif
@@ -389,7 +382,7 @@ void stream_write_record(int streamID, int memtype, const void *data, int nmiss)
     case FILETYPE_SRV:
       {
         if ( memtype == MEMTYPE_FLOAT ) Error("srvWriteRecord not implemented for memtype float!");
-        status = srvWriteRecord(streamID, data);
+        status = srvWriteRecord(streamptr, data);
 	break;
       }
 #endif
@@ -397,7 +390,7 @@ void stream_write_record(int streamID, int memtype, const void *data, int nmiss)
     case FILETYPE_EXT:
       {
         if ( memtype == MEMTYPE_FLOAT ) Error("extWriteRecord not implemented for memtype float!");
-        status = extWriteRecord(streamID, data);
+        status = extWriteRecord(streamptr, data);
 	break;
       }
 #endif
@@ -405,7 +398,7 @@ void stream_write_record(int streamID, int memtype, const void *data, int nmiss)
     case FILETYPE_IEG:
       {
         if ( memtype == MEMTYPE_FLOAT ) Error("iegWriteRecord not implemented for memtype float!");
-        status = iegWriteRecord(streamID, data);
+        status = iegWriteRecord(streamptr, data);
 	break;
       }
 #endif
@@ -415,7 +408,7 @@ void stream_write_record(int streamID, int memtype, const void *data, int nmiss)
     case FILETYPE_NC4:
     case FILETYPE_NC4C:
       {
-	cdf_write_record(streamID, memtype, data, nmiss);
+	cdf_write_record(streamptr, memtype, data, nmiss);
 	break;
       }
 #endif
@@ -456,6 +449,8 @@ void streamCopyRecord(int streamID2, int streamID1)
   filetype2 = streamptr2->filetype;
 
   if ( filetype1 == filetype2 ) filetype = filetype2;
+  else
+    Error("Streams have different file types (%s -> %s)!", strfiletype(filetype1), strfiletype(filetype2));
 
   switch (filetype)
     {
@@ -463,55 +458,60 @@ void streamCopyRecord(int streamID2, int streamID1)
     case FILETYPE_GRB:
     case FILETYPE_GRB2:
       {
-	status = grbCopyRecord(streamID2, streamID1);
+	status = grbCopyRecord(streamptr2, streamptr1);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBSERVICE)
     case FILETYPE_SRV:
       {
-	status = srvCopyRecord(streamID2, streamID1);
+	status = srvCopyRecord(streamptr2, streamptr1);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBEXTRA)
     case FILETYPE_EXT:
       {
-	status = extCopyRecord(streamID2, streamID1);
+	status = extCopyRecord(streamptr2, streamptr1);
 	break;
       }
 #endif
 #if  defined  (HAVE_LIBIEG)
     case FILETYPE_IEG:
       {
-	status = iegCopyRecord(streamID2, streamID1);
+	status = iegCopyRecord(streamptr2, streamptr1);
+	break;
+      }
+#endif
+#if  defined  (HAVE_LIBNETCDF)
+    case FILETYPE_NC:
+    case FILETYPE_NC2:
+    case FILETYPE_NC4:
+    case FILETYPE_NC4C:
+      {
+	status = cdfCopyRecord(streamptr2, streamptr1);
 	break;
       }
 #endif
     default:
       {
-	status = cdfCopyRecord(streamID2, streamID1);
+	Error("%s support not compiled in!", strfiletype(filetype));
 	break;
       }
     }
 }
 
 
-void cdiCreateRecords(int streamID, int tsID)
+void cdi_create_records(stream_t *streamptr, int tsID)
 {
   int nrecords, maxrecords;
   int nvars, varID, recID;
   record_t *records;
   int vlistID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   if ( streamptr->tsteps[tsID].records ) return;
 
-  vlistID  = streamInqVlist(streamID);
+  vlistID  = streamptr->vlistID;
 
   if ( tsID == 0 )
     {
diff --git a/libcdi/src/stream_srv.c b/libcdi/src/stream_srv.c
index 1367c33..51131b3 100644
--- a/libcdi/src/stream_srv.c
+++ b/libcdi/src/stream_srv.c
@@ -29,7 +29,7 @@
 typedef struct {
   int param;
   int level;
-} SRVCOMPVAR; 
+} SRVCOMPVAR;
 
 
 int srvInqDatatype(int prec)
@@ -60,7 +60,7 @@ int srvDefDatatype(int datatype)
 }
 
 /* not used
-int srvInqRecord(int streamID, int *varID, int *levelID)
+int srvInqRecord(stream_t *streamptr, int *varID, int *levelID)
 {
   int status;
   int fileID;
@@ -69,14 +69,9 @@ int srvInqRecord(int streamID, int *varID, int *levelID)
   int header[8];
   int vlistID;
   srvrec_t *srvp;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
-
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
   srvp    = streamptr->record->srvp;
 
   *varID   = -1;
@@ -97,12 +92,12 @@ int srvInqRecord(int streamID, int *varID, int *levelID)
   zaxisID = vlistInqVarZaxis(vlistID, *varID);
 
   *levelID = zaxisInqLevelID(zaxisID, (double) ilevel);
-  
+
   return (1);
 }
 */
 
-int srvReadRecord(int streamID, double *data, int *nmiss)
+int srvReadRecord(stream_t *streamptr, double *data, int *nmiss)
 {
   int vlistID, fileID;
   int status;
@@ -113,14 +108,9 @@ int srvReadRecord(int streamID, double *data, int *nmiss)
   int i, size;
   double missval;
   srvrec_t *srvp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
   tsID    = streamptr->curTsID;
   vrecID  = streamptr->tsteps[tsID].curRecID;
   recID   = streamptr->tsteps[tsID].recIDs[vrecID];
@@ -154,7 +144,7 @@ int srvReadRecord(int streamID, double *data, int *nmiss)
 }
 
 
-int srvCopyRecord(int streamID2, int streamID1)
+int srvCopyRecord(stream_t *streamptr2, stream_t *streamptr1)
 {
   int fileID1, fileID2;
   int tsID, recID, vrecID;
@@ -162,17 +152,9 @@ int srvCopyRecord(int streamID2, int streamID1)
   off_t recpos;
   int status = 0;
   char *buffer;
-  stream_t *streamptr1;
-  stream_t *streamptr2;
 
-  streamptr1 = stream_to_pointer(streamID1);
-  streamptr2 = stream_to_pointer(streamID2);
-
-  stream_check_ptr(__func__, streamptr1);
-  stream_check_ptr(__func__, streamptr2);
-
-  fileID1 = streamInqFileID(streamID1);
-  fileID2 = streamInqFileID(streamID2);
+  fileID1 = streamptr1->fileID;
+  fileID2 = streamptr2->fileID;
 
   tsID    = streamptr1->curTsID;
   vrecID  = streamptr1->tsteps[tsID].curRecID;
@@ -194,7 +176,7 @@ int srvCopyRecord(int streamID2, int streamID1)
 }
 
 
-int srvDefRecord(int streamID)
+int srvDefRecord(stream_t *streamptr)
 {
   int gridID;
   int header[8];
@@ -203,11 +185,6 @@ int srvDefRecord(int streamID)
   int datatype;
   int pdis, pcat, pnum;
   srvrec_t *srvp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   gridID = streamptr->record->gridID;
   srvp   = streamptr->record->srvp;
@@ -244,18 +221,13 @@ int srvDefRecord(int streamID)
 }
 
 
-int srvWriteRecord(int streamID, const double *data)
+int srvWriteRecord(stream_t *streamptr, const double *data)
 {
   int fileID;
   int status = 0;
   srvrec_t *srvp;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
-
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
   srvp   = streamptr->record->srvp;
 
   srvDefDataDP(srvp, data);
@@ -265,9 +237,9 @@ int srvWriteRecord(int streamID, const double *data)
   return (status);
 }
 
-
-void srvAddRecord(int streamID, int param, int level, int xsize, int ysize,
-		  long recsize, off_t position, int prec)
+static
+void srv_add_record(stream_t *streamptr, int param, int level, int xsize, int ysize,
+                    long recsize, off_t position, int prec)
 {
   int leveltype;
   int gridID = UNDEFID;
@@ -277,13 +249,10 @@ void srvAddRecord(int streamID, int param, int level, int xsize, int ysize,
   record_t *record;
   grid_t grid;
   int vlistID;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   tsID    = streamptr->curTsID;
-  recID   = recordNewEntry(streamID, tsID);
+  recID   = recordNewEntry(streamptr, tsID);
   record  = &streamptr->tsteps[tsID].records[recID];
 
   (*record).size     = recsize;
@@ -292,7 +261,7 @@ void srvAddRecord(int streamID, int param, int level, int xsize, int ysize,
   (*record).ilevel   = level;
 
   memset(&grid, 0, sizeof(grid_t));
-  grid.type  = GRID_GENERIC; 
+  grid.type  = GRID_GENERIC;
   grid.size  = xsize*ysize;
   grid.xsize = xsize;
   grid.ysize = ysize;
@@ -307,7 +276,7 @@ void srvAddRecord(int streamID, int param, int level, int xsize, int ysize,
 
   datatype = srvInqDatatype(prec);
 
-  varAddRecord(recID, param, gridID, leveltype, 0, level, 0,
+  varAddRecord(recID, param, gridID, leveltype, 0, level, 0, 0,
 	       datatype, &varID, &levelID, UNDEFID, 0, 0, NULL, NULL, NULL);
 
   (*record).varID   = varID;
@@ -322,15 +291,12 @@ void srvAddRecord(int streamID, int param, int level, int xsize, int ysize,
 }
 
 
-void srvCmpRecord(int streamID, int tsID, int recID, off_t position, int param,
+void srvCmpRecord(stream_t *streamptr, int tsID, int recID, off_t position, int param,
 		  int level, int xsize, int ysize)
 {
   int varID = 0;
   int levelID = 0;
   record_t *record;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   record  = &streamptr->tsteps[tsID].records[recID];
 
@@ -352,8 +318,8 @@ void srvCmpRecord(int streamID, int tsID, int recID, off_t position, int param,
 }
 
 static
-void srvScanTimestep1(int streamID)
-{  
+void srvScanTimestep1(stream_t *streamptr)
+{
   int header[8];
   int prec = 0;
   int status;
@@ -372,22 +338,17 @@ void srvScanTimestep1(int streamID)
   int vlistID;
   SRVCOMPVAR compVar, compVar0;
   srvrec_t *srvp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   streamptr->curTsID = 0;
 
   srvp  = streamptr->record->srvp;
-  tsID  = tstepsNewEntry(streamID);
+  tsID  = tstepsNewEntry(streamptr);
   taxis = &streamptr->tsteps[tsID].taxis;
 
   if ( tsID != 0 )
     Error("Internal problem! tstepsNewEntry returns %d", tsID);
 
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
 
   nrecs = 0;
   while ( TRUE )
@@ -441,22 +402,22 @@ void srvScanTimestep1(int streamID)
       if ( CDI_Debug )
 	Message("%4d%8d%4d%8d%8d%6d", nrecs, (int)recpos, rcode, rlevel, vdate, vtime);
 
-      srvAddRecord(streamID, param, rlevel, rxsize, rysize, recsize, recpos, prec);
+      srv_add_record(streamptr, param, rlevel, rxsize, rysize, recsize, recpos, prec);
     }
 
   streamptr->rtsteps = 1;
 
-  cdiGenVars(streamID);
+  cdi_generate_vars(streamptr);
 
   taxisID = taxisCreate(TAXIS_ABSOLUTE);
   taxis->type  = TAXIS_ABSOLUTE;
   taxis->vdate = datetime0.date;
   taxis->vtime = datetime0.time;
 
-  vlistID = streamInqVlist(streamID);
+  vlistID = streamptr->vlistID;
   vlistDefTaxis(vlistID, taxisID);
 
-  cdiCheckContents(streamID);
+  vlist_check_contents(vlistID);
 
   nrecords = streamptr->tsteps[0].nallrecs;
   if ( nrecords < streamptr->tsteps[0].recordSize )
@@ -473,7 +434,7 @@ void srvScanTimestep1(int streamID)
 
   if ( streamptr->ntsteps == -1 )
     {
-      tsID = tstepsNewEntry(streamID);
+      tsID = tstepsNewEntry(streamptr);
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
@@ -495,8 +456,8 @@ void srvScanTimestep1(int streamID)
 }
 
 static
-int srvScanTimestep2(int streamID)
-{  
+int srvScanTimestep2(stream_t *streamptr)
+{
   int header[8];
   int status;
   int fileID;
@@ -512,16 +473,11 @@ int srvScanTimestep2(int streamID)
   int vlistID;
   SRVCOMPVAR compVar, compVar0;
   srvrec_t *srvp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   streamptr->curTsID = 1;
 
-  vlistID = streamInqVlist(streamID);
-  fileID  = streamInqFileID(streamID);
+  vlistID = streamptr->vlistID;
+  fileID  = streamptr->fileID;
   srvp    = streamptr->record->srvp;
 
   tsID = streamptr->rtsteps;
@@ -532,7 +488,7 @@ int srvScanTimestep2(int streamID)
 
   fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-  cdiCreateRecords(streamID, tsID);
+  cdi_create_records(streamptr, tsID);
 
   nrecords = streamptr->tsteps[0].nallrecs;
   streamptr->tsteps[1].recIDs = (int *) malloc(nrecords*sizeof(int));
@@ -543,9 +499,9 @@ int srvScanTimestep2(int streamID)
   for ( recID = 0; recID < nrecords; recID++ )
     {
       varID = streamptr->tsteps[0].records[recID].varID;
-      streamptr->tsteps[tsID].records[recID].position = 
+      streamptr->tsteps[tsID].records[recID].position =
 	streamptr->tsteps[0].records[recID].position;
-      streamptr->tsteps[tsID].records[recID].size     = 
+      streamptr->tsteps[tsID].records[recID].size     =
 	streamptr->tsteps[0].records[recID].size;
     }
 
@@ -645,7 +601,7 @@ int srvScanTimestep2(int streamID)
 
   if ( streamptr->ntsteps == -1 )
     {
-      tsID = tstepsNewEntry(streamID);
+      tsID = tstepsNewEntry(streamptr);
       if ( tsID != streamptr->rtsteps )
 	Error("Internal error. tsID = %d", tsID);
 
@@ -657,23 +613,18 @@ int srvScanTimestep2(int streamID)
 }
 
 
-int srvInqContents(int streamID)
+int srvInqContents(stream_t *streamptr)
 {
   int fileID;
   int status = 0;
-  stream_t *streamptr;
 
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
-
-  fileID = streamInqFileID(streamID);
+  fileID = streamptr->fileID;
 
   streamptr->curTsID = 0;
 
-  srvScanTimestep1(streamID);
- 
-  if ( streamptr->ntsteps == -1 ) status = srvScanTimestep2(streamID);
+  srvScanTimestep1(streamptr);
+
+  if ( streamptr->ntsteps == -1 ) status = srvScanTimestep2(streamptr);
 
   fileSetPos(fileID, 0, SEEK_SET);
 
@@ -681,7 +632,7 @@ int srvInqContents(int streamID)
 }
 
 static
-int srvScanTimestep(int streamID)
+int srvScanTimestep(stream_t *streamptr)
 {
   int header[8];
   int status;
@@ -697,15 +648,10 @@ int srvScanTimestep(int streamID)
   int rindex, nrecs = 0;
   SRVCOMPVAR compVar, compVar0;
   srvrec_t *srvp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   if ( CDI_Debug )
     {
-      Message("streamID = %d", streamID);
+      Message("streamID = %d", streamptr->self);
       Message("cts = %d", streamptr->curTsID);
       Message("rts = %d", streamptr->rtsteps);
       Message("nts = %d", streamptr->ntsteps);
@@ -720,7 +666,7 @@ int srvScanTimestep(int streamID)
 
   if ( streamptr->tsteps[tsID].recordSize == 0 )
     {
-      cdiCreateRecords(streamID, tsID);
+      cdi_create_records(streamptr, tsID);
 
       nrecs = streamptr->tsteps[1].nrecs;
 
@@ -729,7 +675,7 @@ int srvScanTimestep(int streamID)
       for ( recID = 0; recID < nrecs; recID++ )
 	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
 
-      fileID = streamInqFileID(streamID);
+      fileID = streamptr->fileID;
 
       fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
@@ -766,7 +712,7 @@ int srvScanTimestep(int streamID)
 	      taxis->vtime = vtime;
 	    }
 	  /*
-	  srvCmpRecord(streamID, tsID, nrecs, recpos, param, rlevel, rxsize, rysize);
+	  srvCmpRecord(streamptr, tsID, nrecs, recpos, param, rlevel, rxsize, rysize);
 	  */
 	  compVar.param  = param;
           compVar.level  = rlevel;
@@ -793,7 +739,7 @@ int srvScanTimestep(int streamID)
 
       if ( streamptr->ntsteps != streamptr->rtsteps )
 	{
-	  tsID = tstepsNewEntry(streamID);
+	  tsID = tstepsNewEntry(streamptr);
 	  if ( tsID != streamptr->rtsteps )
 	    Error("Internal error. tsID = %d", tsID);
 
@@ -815,24 +761,19 @@ int srvScanTimestep(int streamID)
 }
 
 
-int srvInqTimestep(int streamID, int tsID)
+int srvInqTimestep(stream_t *streamptr, int tsID)
 {
   int ntsteps, nrecs;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
-  stream_check_ptr(__func__, streamptr);
 
   if ( tsID == 0 && streamptr->rtsteps == 0 )
     Error("Call to cdiInqContents missing!");
 
   if ( CDI_Debug )
     Message("tsID = %d rtsteps = %d", tsID, streamptr->rtsteps);
-  
+
   ntsteps = UNDEFID;
   while ( ( tsID + 1 ) > streamptr->rtsteps && ntsteps == UNDEFID )
-    ntsteps = srvScanTimestep(streamID);
+    ntsteps = srvScanTimestep(streamptr);
 
   if ( tsID >= streamptr->ntsteps && streamptr->ntsteps != CDI_UNDEFID )
     {
@@ -848,7 +789,7 @@ int srvInqTimestep(int streamID, int tsID)
 }
 
 
-void srvReadVarDP(int streamID, int varID, double *data, int *nmiss)
+void srvReadVarDP(stream_t *streamptr, int varID, double *data, int *nmiss)
 {
   int vlistID, fileID;
   int levID, nlevs, gridID, gridsize;
@@ -859,13 +800,10 @@ void srvReadVarDP(int streamID, int varID, double *data, int *nmiss)
   int i;
   double missval;
   srvrec_t *srvp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   srvp     = streamptr->record->srvp;
-  vlistID  = streamInqVlist(streamID);
-  fileID   = streamInqFileID(streamID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   nlevs    = streamptr->vars[varID].nlevs;
   missval  = vlistInqVarMissval(vlistID, varID);
   gridID   = vlistInqVarGrid(vlistID, varID);
@@ -898,7 +836,7 @@ void srvReadVarDP(int streamID, int varID, double *data, int *nmiss)
 }
 
 
-void srvReadVarSliceDP(int streamID, int varID, int levID, double *data, int *nmiss)
+void srvReadVarSliceDP(stream_t *streamptr, int varID, int levID, double *data, int *nmiss)
 {
   int vlistID, fileID;
   int nlevs, gridID, gridsize;
@@ -909,13 +847,10 @@ void srvReadVarSliceDP(int streamID, int varID, int levID, double *data, int *nm
   int i;
   double missval;
   srvrec_t *srvp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   srvp     = streamptr->record->srvp;
-  vlistID  = streamInqVlist(streamID);
-  fileID   = streamInqFileID(streamID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   nlevs    = streamptr->vars[varID].nlevs;
   missval  = vlistInqVarMissval(vlistID, varID);
   gridID   = vlistInqVarGrid(vlistID, varID);
@@ -947,7 +882,7 @@ void srvReadVarSliceDP(int streamID, int varID, int levID, double *data, int *nm
 }
 
 
-void srvWriteVarDP(int streamID, int varID, const double *data)
+void srvWriteVarDP(stream_t *streamptr, int varID, const double *data)
 {
   int fileID;
   int levID, nlevs, gridID, gridsize;
@@ -960,16 +895,13 @@ void srvWriteVarDP(int streamID, int varID, const double *data)
   int vlistID;
   int pdis, pcat, pnum;
   srvrec_t *srvp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   if ( CDI_Debug )
-    Message("streamID = %d  varID = %d", streamID, varID);
+    Message("streamID = %d  varID = %d", streamptr->self, varID);
 
   srvp     = streamptr->record->srvp;
-  vlistID  = streamInqVlist(streamID);
-  fileID   = streamInqFileID(streamID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   tsID     = streamptr->curTsID;
   gridID   = vlistInqVarGrid(vlistID, varID);
   gridsize = gridInqSize(gridID);
@@ -1017,7 +949,7 @@ void srvWriteVarDP(int streamID, int varID, const double *data)
 }
 
 
-void srvWriteVarSliceDP(int streamID, int varID, int levID, const double *data)
+void srvWriteVarSliceDP(stream_t *streamptr, int varID, int levID, const double *data)
 {
   int fileID;
   int gridID;
@@ -1030,13 +962,10 @@ void srvWriteVarSliceDP(int streamID, int varID, int levID, const double *data)
   int vlistID;
   int pdis, pcat, pnum;
   srvrec_t *srvp;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   srvp     = streamptr->record->srvp;
-  vlistID  = streamInqVlist(streamID);
-  fileID   = streamInqFileID(streamID);
+  vlistID  = streamptr->vlistID;
+  fileID   = streamptr->fileID;
   tsID     = streamptr->curTsID;
   gridID   = vlistInqVarGrid(vlistID, varID);
   zaxisID  = vlistInqVarZaxis(vlistID, varID);
diff --git a/libcdi/src/stream_srv.h b/libcdi/src/stream_srv.h
index cd45262..5989808 100644
--- a/libcdi/src/stream_srv.h
+++ b/libcdi/src/stream_srv.h
@@ -5,20 +5,20 @@
 #  include "service.h"
 #endif
 
-int    srvInqContents(int streamID);
-int    srvInqTimestep(int streamID, int tsID);
+int    srvInqContents(stream_t *streamptr);
+int    srvInqTimestep(stream_t *streamptr, int tsID);
 
-int    srvInqRecord(int streamID, int *varID, int *levelID);
-int    srvDefRecord(int streamID);
-int    srvCopyRecord(int streamIDdest, int streamIDsrc);
-int    srvReadRecord(int streamID, double *data, int *nmiss);
-int    srvWriteRecord(int streamID, const double *data);
+int    srvInqRecord(stream_t *streamptr, int *varID, int *levelID);
+int    srvDefRecord(stream_t *streamptr);
+int    srvCopyRecord(stream_t *streamptr2, stream_t *streamptr1);
+int    srvReadRecord(stream_t *streamptr, double *data, int *nmiss);
+int    srvWriteRecord(stream_t *streamptr, const double *data);
 
-void   srvReadVarDP (int streamID, int varID,       double *data, int *nmiss);
-void   srvWriteVarDP(int streamID, int varID, const double *data);
+void   srvReadVarDP (stream_t *streamptr, int varID,       double *data, int *nmiss);
+void   srvWriteVarDP(stream_t *streamptr, int varID, const double *data);
 
-void   srvReadVarSliceDP (int streamID, int varID, int levelID,       double *data, int *nmiss);
-void   srvWriteVarSliceDP(int streamID, int varID, int levelID, const double *data);
+void   srvReadVarSliceDP (stream_t *streamptr, int varID, int levelID,       double *data, int *nmiss);
+void   srvWriteVarSliceDP(stream_t *streamptr, int varID, int levelID, const double *data);
 
 #endif  /* _STREAM_SRV_H */
 /*
diff --git a/libcdi/src/stream_var.c b/libcdi/src/stream_var.c
index 3dbb92a..a069e5e 100644
--- a/libcdi/src/stream_var.c
+++ b/libcdi/src/stream_var.c
@@ -12,12 +12,8 @@
 
 
 static
-void streamvarInitEntry(int streamID, int varID)
+void streamvar_init_entry(stream_t *streamptr, int varID)
 {
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
   streamptr->vars[varID].ncvarid      = CDI_UNDEFID;
   streamptr->vars[varID].defmiss      = 0;
   streamptr->vars[varID].nlevs        = 0;
@@ -32,14 +28,11 @@ void streamvarInitEntry(int streamID, int varID)
 }
 
 static
-int streamvarNewEntry(int streamID)
+int streamvar_new_entry(stream_t *streamptr)
 {
   int varID = 0;
   int streamvarSize;
   svarinfo_t *streamvar;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   streamvarSize = streamptr->varsAllocated;
   streamvar     = streamptr->vars;
@@ -93,7 +86,7 @@ int streamvarNewEntry(int streamID)
   streamptr->varsAllocated = streamvarSize;
   streamptr->vars          = streamvar;
 
-  streamvarInitEntry(streamID, varID);
+  streamvar_init_entry(streamptr, varID);
 
   streamptr->vars[varID].isUsed = TRUE;
 
@@ -101,21 +94,18 @@ int streamvarNewEntry(int streamID)
 }
 
 
-int streamNewVar(int streamID, int gridID, int zaxisID)
+int stream_new_var(stream_t *streamptr, int gridID, int zaxisID)
 {
   int varID;
   int *level;
   int *lindex;
   int nlevs;
   int levID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   if ( CDI_Debug )
     Message("gridID = %d  zaxisID = %d", gridID, zaxisID);
 
-  varID = streamvarNewEntry(streamID);
+  varID = streamvar_new_entry(streamptr);
 
   streamptr->nvars++;
 
diff --git a/libcdi/src/taxis.c b/libcdi/src/taxis.c
index 0ba140c..eb6640b 100644
--- a/libcdi/src/taxis.c
+++ b/libcdi/src/taxis.c
@@ -1015,8 +1015,6 @@ double vtime2timeval(int vdate, int vtime, taxis_t *taxis)
     {
       int nmonth, dpm;
 
-      dpm = days_per_month(calendar, year, month);
-
       value = (year-ryear)*12 - rmonth + month;
 
       nmonth = (int) value;
@@ -1025,6 +1023,8 @@ double vtime2timeval(int vdate, int vtime, taxis_t *taxis)
       while ( month > 12 ) { month -= 12; year++; }
       while ( month <  1 ) { month += 12; year--; }
 
+      dpm = days_per_month(calendar, year, month);
+
       encode_caldaysec(calendar, year, month, day, hour, minute, second, &julday2, &secofday2);
 
       julday_sub(julday1, secofday1, julday2, secofday2, &days, &secs);
diff --git a/libcdi/src/timebase.c b/libcdi/src/timebase.c
index 3c9a86d..01e3549 100644
--- a/libcdi/src/timebase.c
+++ b/libcdi/src/timebase.c
@@ -1,4 +1,5 @@
 #include <stdio.h>
+#include <stdint.h>
 #include <math.h>		/* for floor() */
 
 #include "cdi.h"
@@ -136,9 +137,9 @@ int sec_to_time(int secofday)
 }
 
 static
-void adjust_seconds(int *julday, int *secofday)
+void adjust_seconds(int *julday, int64_t *secofday)
 {
-  int secperday = 86400;
+  int64_t secperday = 86400;
 
   while ( *secofday >= secperday ) 
     { 
@@ -154,52 +155,66 @@ void adjust_seconds(int *julday, int *secofday)
 }
 
 
-void julday_add_seconds(int seconds, int *julday, int *secofday)
+void julday_add_seconds(int64_t seconds, int *julday, int *secofday)
 {
-  *secofday += seconds;
+  int64_t sec_of_day = *secofday;
 
-  adjust_seconds(julday, secofday);
+  sec_of_day += seconds;
+
+  adjust_seconds(julday, &sec_of_day);
+
+  *secofday = (int) sec_of_day;
 }
 
 /* add days and secs to julday/secofday */
 void julday_add(int days, int secs, int *julday, int *secofday)
 {
-  *julday   += days;
-  *secofday += secs;
+  int64_t sec_of_day = *secofday;
+
+  sec_of_day += secs;
+  *julday    += days;
 
-  adjust_seconds(julday, secofday);
+  adjust_seconds(julday, &sec_of_day);
+
+  *secofday = (int) sec_of_day;
 }
 
 /* subtract julday1/secofday1 from julday2/secofday2 and returns the result in seconds */
 double julday_sub(int julday1, int secofday1, int julday2, int secofday2, int *days, int *secs)
 {
-  int seconds;
+  int64_t sec_of_day;
+  int64_t seconds;
 
   *days = julday2 - julday1;
   *secs = secofday2 - secofday1;
 
-  adjust_seconds(days, secs);
+  sec_of_day = *secs;
+
+  adjust_seconds(days, &sec_of_day);
+
+  *secs = (int) sec_of_day;
 
-  seconds = *days*86400. + *secs;
+  seconds = *days*86400. + sec_of_day;
 
   return (seconds);
 }
 
 
-void encode_juldaysec(int calendar, int year, int month, int day, int hour, int minute, int *julday, int *secofday)
+void encode_juldaysec(int calendar, int year, int month, int day, int hour, int minute, int second, int *julday, int *secofday)
 {
   *julday = encode_julday(calendar, year, month, day);
 
-  *secofday = (hour*60 + minute)*60;
+  *secofday = (hour*60 + minute)*60 + second;
 }
 
 
-void decode_juldaysec(int calendar, int julday, int secofday, int *year, int *month, int *day, int *hour, int *minute)
+void decode_juldaysec(int calendar, int julday, int secofday, int *year, int *month, int *day, int *hour, int *minute, int *second)
 {
   decode_julday(calendar, julday, year, month, day);
 
   *hour   = secofday/3600;
   *minute = secofday/60 - *hour*60;
+  *second = secofday - *hour*3600 - *minute*60;
 }
 
 
@@ -213,6 +228,7 @@ int main(void)
   int i, j = 0;
   int year, mon, day, hour, minute, second;
   int julday, secofday;
+  int calendar = CALENDAR_STANDARD;
 
   /* 1 - Check valid range of years */
 
@@ -302,36 +318,28 @@ int main(void)
 {
   int i;
   int julday, secofday;
-  int year, month, day, hour, minute;
+  int year, month, day, hour, minute, second;
   int value = 30;
   int factor = 86400;
+  int calendar = CALENDAR_STANDARD;
 
-  year=1979; month=1; day=15; hour=12; minute=30;
+  year=1979; month=1; day=15; hour=12; minute=30, second=17;
 
-  printf("%d/%02d/%02d %02d:%02d\n", year, month, day, hour, minute);
+  printf("%d/%02d/%02d %02d:%02d:%02d\n", year, month, day, hour, minute, second);
 
-  encode_juldaysec(calendar, year, month, day, hour, minute, &julday, &secofday);
+  encode_juldaysec(calendar, year, month, day, hour, minute, second, &julday, &secofday);
 
-  decode_juldaysec(calendar, julday, secofday, &year, &month, &day, &hour, &minute);
-  printf("%d/%02d/%02d %02d:%02d   %d %d\n", year, month, day, hour, minute, julday, secofday);
+  decode_juldaysec(calendar, julday, secofday, &year, &month, &day, &hour, &minute, &second);
+  printf("%d/%02d/%02d %02d:%02d:%02d   %d %d\n", year, month, day, hour, minute, second, julday, secofday);
 
   for ( i = 0; i < 420; i++ )
     {
 
-      decode_juldaysec(calendar, julday, secofday, &year, &month, &day, &hour, &minute);
-      printf("%2d %d/%02d/%02d %02d:%02d\n", i, year, month, day, hour, minute);
+      decode_juldaysec(calendar, julday, secofday, &year, &month, &day, &hour, &minute, &second);
+      printf("%2d %d/%02d/%02d %02d:%02d:%02d\n", i, year, month, day, hour, minute, second);
       julday_add_seconds(value*factor, &julday, &secofday);
     }
 
   return (0);
 }
 #endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
diff --git a/libcdi/src/timebase.h b/libcdi/src/timebase.h
index 483a978..d298f17 100644
--- a/libcdi/src/timebase.h
+++ b/libcdi/src/timebase.h
@@ -13,20 +13,11 @@ int julday_to_date(int calendar, int julday);
 int time_to_sec(int time);
 int sec_to_time(int secofday);
 
-void   julday_add_seconds(int seconds, int *julday, int *secofday);
+void   julday_add_seconds(int64_t seconds, int *julday, int *secofday);
 void   julday_add(int days, int secs, int *julday, int *secofday);
 double julday_sub(int julday1, int secofday1, int julday2, int secofday2, int *days, int *secs);
 
-void encode_juldaysec(int calendar, int year, int month, int day, int hour, int minute, int *julday, int *secofday);
-void decode_juldaysec(int calendar, int julday, int secofday, int *year, int *month, int *day, int *hour, int *minute);
+void encode_juldaysec(int calendar, int year, int month, int day, int hour, int minute, int second, int *julday, int *secofday);
+void decode_juldaysec(int calendar, int julday, int secofday, int *year, int *month, int *day, int *hour, int *minute, int *second);
 
 #endif  /* _TIMEBASE_H */
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
diff --git a/libcdi/src/tsteps.c b/libcdi/src/tsteps.c
index 0d33d94..1cc139a 100644
--- a/libcdi/src/tsteps.c
+++ b/libcdi/src/tsteps.c
@@ -8,12 +8,9 @@
 #include "stream_int.h"
 
 
-static void tstepsInitEntry(int streamID, int tsID)
+static
+void tstepsInitEntry(stream_t *streamptr, int tsID)
 {
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
-
   streamptr->tsteps[tsID].curRecID     = CDI_UNDEFID;
   streamptr->tsteps[tsID].position     = 0;
   streamptr->tsteps[tsID].records      = NULL;
@@ -26,14 +23,12 @@ static void tstepsInitEntry(int streamID, int tsID)
   ptaxisInit(&streamptr->tsteps[tsID].taxis);
 }
 
-int tstepsNewEntry(int streamID)
+
+int tstepsNewEntry(stream_t *streamptr)
 {
   int tsID = 0;
   int tstepsTableSize;
   tsteps_t *tstepsTable;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   tsID            = streamptr->tstepsNextID++;
   tstepsTableSize = streamptr->tstepsTableSize;
@@ -57,20 +52,18 @@ int tstepsNewEntry(int streamID)
   streamptr->tstepsTableSize = tstepsTableSize;
   streamptr->tsteps          = tstepsTable;
 
-  tstepsInitEntry(streamID, tsID);
+  tstepsInitEntry(streamptr, tsID);
 
   streamptr->tsteps[tsID].taxis.used = TRUE;
 
   return (tsID);
 }
 
-void cdiCreateTimesteps(int streamID)
+
+void cdiCreateTimesteps(stream_t *streamptr)
 {
   int ntsteps;
   int tsID;
-  stream_t *streamptr;
-
-  streamptr = stream_to_pointer(streamID);
 
   if ( streamptr->ntsteps < 0 || streamptr->tstepsTableSize > 0 )
     return;
@@ -87,7 +80,7 @@ void cdiCreateTimesteps(int streamID)
 
   for ( tsID = 0; tsID < ntsteps; tsID++ )
     {
-      tstepsInitEntry(streamID, tsID);
+      tstepsInitEntry(streamptr, tsID);
       streamptr->tsteps[tsID].taxis.used = TRUE;
     }
 }
diff --git a/libcdi/src/util.c b/libcdi/src/util.c
index 4d18c5a..6a0f540 100644
--- a/libcdi/src/util.c
+++ b/libcdi/src/util.c
@@ -20,27 +20,27 @@ void cdiPrintDatatypes(void)
   /* IsBigendian returns 1 for big endian byte order */
   static union {unsigned long l; unsigned char c[sizeof(long)];} u_byteorder = {1};
 
-  fprintf (stderr, "+-------------+-------+\n"); 
-  fprintf (stderr, "| types       | bytes |\n"); 
-  fprintf (stderr, "+-------------+-------+\n"); 
+  fprintf (stderr, "+-------------+-------+\n");
+  fprintf (stderr, "| types       | bytes |\n");
+  fprintf (stderr, "+-------------+-------+\n");
   fprintf (stderr, "| void *      |   %3d |\n", (int) sizeof(void *));
-  fprintf (stderr, "+-------------+-------+\n"); 
+  fprintf (stderr, "+-------------+-------+\n");
   fprintf (stderr, "| char        |   %3d |\n", (int) sizeof(char));
-  fprintf (stderr, "+-------------+-------+\n"); 
+  fprintf (stderr, "+-------------+-------+\n");
   fprintf (stderr, "| short       |   %3d |\n", (int) sizeof(short));
   fprintf (stderr, "| int         |   %3d |\n", (int) sizeof(int));
   fprintf (stderr, "| long        |   %3d |\n", (int) sizeof(long));
   fprintf (stderr, "| long long   |   %3d |\n", (int) sizeof(long long));
   fprintf (stderr, "| size_t      |   %3d |\n", (int) sizeof(size_t));
   fprintf (stderr, "| off_t       |   %3d |\n", (int) sizeof(off_t));
-  fprintf (stderr, "+-------------+-------+\n"); 
+  fprintf (stderr, "+-------------+-------+\n");
   fprintf (stderr, "| float       |   %3d |\n", (int) sizeof(float));
   fprintf (stderr, "| double      |   %3d |\n", (int) sizeof(double));
   fprintf (stderr, "| long double |   %3d |\n", (int) sizeof(long double));
-  fprintf (stderr, "+-------------+-------+\n\n"); 
+  fprintf (stderr, "+-------------+-------+\n\n");
 #define XSTRING(x)	#x
 #define STRING(x)	XSTRING(x)
-  fprintf (stderr, "+-------------+-----------+\n"); 
+  fprintf (stderr, "+-------------+-----------+\n");
   fprintf (stderr, "| INT32       | %-9s |\n", STRING(INT32));
   fprintf (stderr, "| INT64       | %-9s |\n", STRING(INT64));
   fprintf (stderr, "| FLT32       | %-9s |\n", STRING(FLT32));
@@ -52,6 +52,51 @@ void cdiPrintDatatypes(void)
   else
     fprintf (stderr, "\n  byte ordering is LITTLEENDIAN\n\n");
 }
+
+
+void uuid2str(const char *uuid, char *uuidstr)
+{
+  int iret;
+  unsigned int ui[16];
+
+  if ( uuid == NULL ) return;
+  if ( uuidstr == NULL ) return;
+
+  uuidstr[0] = 0;
+
+  for ( int i = 0; i < 16; ++i ) ui[i] = (unsigned char) uuid[i];
+
+  iret = sprintf(uuidstr, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+		 ui[0], ui[1], ui[2], ui[3], ui[4], ui[5], ui[6], ui[7],
+		 ui[8], ui[9], ui[10], ui[11], ui[12], ui[13], ui[14], ui[15]);
+
+  if ( iret != 36 ) uuidstr[0] = 0;
+}
+
+
+void str2uuid(const char *uuidstr, char *uuid)
+{
+  int iret;
+  unsigned int ui[16];
+
+  if ( uuid == NULL ) return;
+  if ( uuidstr == NULL ) return;
+
+  uuid[0] = 0;
+
+  if ( strlen(uuidstr) != 36 ) return;
+
+  iret = sscanf(uuidstr, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+		&ui[0], &ui[1], &ui[2], &ui[3], &ui[4], &ui[5], &ui[6], &ui[7],
+		&ui[8], &ui[9], &ui[10], &ui[11], &ui[12], &ui[13], &ui[14], &ui[15]);
+
+  if ( iret != 16 ) return;
+
+  for ( int i = 0; i < 16; ++i ) uuid[i] = ui[i];
+
+  uuid[16] = 0;
+}
+
 /*
  * Local Variables:
  * c-file-style: "Java"
diff --git a/libcdi/src/varscan.c b/libcdi/src/varscan.c
index 90c3d53..f4a3a3f 100644
--- a/libcdi/src/varscan.c
+++ b/libcdi/src/varscan.c
@@ -11,6 +11,7 @@
 #include "varscan.h"
 #include "vlist.h"
 #include "grid.h"
+#include "zaxis.h"
 
 
 extern void zaxisGetIndexList ( int, int * );
@@ -46,6 +47,7 @@ typedef struct
   int         zaxistype;
   int         ltype;     /* GRIB level type */
   int         lbounds;
+  int         level_sf;
   int         zaxisID;
   int         nlevels;
   int         levelTableSize;
@@ -82,6 +84,8 @@ void paramInitEntry(int varID, int param)
   vartable[varID].gridID         = UNDEFID;
   vartable[varID].zaxistype      = 0;
   vartable[varID].ltype          = 0;
+  vartable[varID].lbounds        = 0;
+  vartable[varID].level_sf       = 0;
   vartable[varID].levelTable     = NULL;
   vartable[varID].levelTableSize = 0;
   vartable[varID].nlevels        = 0;
@@ -99,7 +103,7 @@ void paramInitEntry(int varID, int param)
 }
 
 static
-int varGetEntry(int param, int zaxistype, int ltype)
+int varGetEntry(int param, int zaxistype, int ltype, const char *name)
 {
   int varID;
 
@@ -108,7 +112,16 @@ int varGetEntry(int param, int zaxistype, int ltype)
       if ( vartable[varID].param     == param     &&
 	   vartable[varID].zaxistype == zaxistype &&
 	   vartable[varID].ltype     == ltype )
-	return (varID);
+        {
+          if ( name && name[0] && vartable[varID].name && vartable[varID].name[0] )
+            {
+              if ( strcmp(name, vartable[varID].name) == 0 ) return (varID);
+            }
+          else
+            {
+              return (varID);
+            }
+        }
     }
 
   return (UNDEFID);
@@ -201,9 +214,9 @@ int levelNewEntry(int varID, int level1, int level2)
 	levelTable[i].recID = UNDEFID;
     }
 
-  levelTable[levelID].level1 = level1;
-  levelTable[levelID].level2 = level2;
-  levelTable[levelID].lindex = levelID;
+  levelTable[levelID].level1   = level1;
+  levelTable[levelID].level2   = level2;
+  levelTable[levelID].lindex   = levelID;
 
   vartable[varID].nlevels = levelID+1;
   vartable[varID].levelTableSize = levelTableSize;
@@ -273,7 +286,7 @@ int paramNewEntry(int param)
 
 
 void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
-		  int level1, int level2, int prec,
+		  int level1, int level2, int level_sf, int prec,
 		  int *pvarID, int *plevelID, int tsteptype, int numavg, int ltype,
 		  const char *name, const char *longname, const char *units)
 {
@@ -281,7 +294,7 @@ void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
   int levelID = -1;
 
   if ( ! (cdiSplitLtype105 == 1 && zaxistype == ZAXIS_HEIGHT) )
-    varID = varGetEntry(param, zaxistype, ltype);
+    varID = varGetEntry(param, zaxistype, ltype, name);
 
   if ( varID == UNDEFID )
     {
@@ -291,6 +304,7 @@ void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
       vartable[varID].zaxistype = zaxistype;
       vartable[varID].ltype     = ltype;
       vartable[varID].lbounds   = lbounds;
+      vartable[varID].level_sf  = level_sf;
       if ( tsteptype != UNDEFID ) vartable[varID].tsteptype = tsteptype;
       if ( numavg ) vartable[varID].timave = 1;
 
@@ -300,17 +314,16 @@ void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
     }
   else
     {
+      char paramstr[32];
+      cdiParamToString(param, paramstr, sizeof(paramstr));
+
       if ( vartable[varID].gridID != gridID )
 	{
-	  char paramstr[32];
-	  cdiParamToString(param, paramstr, sizeof(paramstr));
 	  Message("param = %s gridID = %d", paramstr, gridID);
 	  Error("horizontal grid must not change for same param!");
 	}
       if ( vartable[varID].zaxistype != zaxistype )
 	{
-	  char paramstr[32];
-	  cdiParamToString(param, paramstr, sizeof(paramstr));
 	  Message("param = %s zaxistype = %d", paramstr, zaxistype);
 	  Error("zaxistype must not change for same param!");
 	}
@@ -327,7 +340,7 @@ void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
   *pvarID   = varID;
   *plevelID = levelID;
 }
-
+/*
 static
 int dblcmp(const void *s1, const void *s2)
 {
@@ -338,7 +351,7 @@ int dblcmp(const void *s1, const void *s2)
 
   return (cmp);
 }
-
+*/
 static
 int cmpLevelTable(const void *s1, const void *s2)
 {
@@ -392,7 +405,7 @@ int cmpltype(const void *s1, const void *s2)
 }
 
 
-void cdiGenVars(int streamID)
+void cdi_generate_vars(stream_t *streamptr)
 {
   int varID, gridID, zaxisID, levelID;
   int instID, modelID, tableID;
@@ -408,11 +421,9 @@ void cdiGenVars(int streamID)
   double *dlevels2 = NULL;
   int vlistID;
   int *varids, index, varid;
-  stream_t *streamptr;
+  double level_sf = 1;
 
-  streamptr = stream_to_pointer(streamID);
-
-  vlistID =  streamInqVlist(streamID);
+  vlistID =  streamptr->vlistID;
 
   varids = (int *) malloc(nvars*sizeof(int));
   for ( varID = 0; varID < nvars; varID++ ) varids[varID] = varID;
@@ -464,6 +475,9 @@ void cdiGenVars(int streamID)
       timaccu   = vartable[varid].timaccu;
       comptype  = vartable[varid].comptype;
 
+      level_sf  = 1;
+      if ( vartable[varid].level_sf == 77 ) level_sf = 0.001;
+
       zaxisID = UNDEFID;
 
       if ( ltype == 0 && zaxistype == ZAXIS_GENERIC && nlevels == 1 &&
@@ -474,11 +488,11 @@ void cdiGenVars(int streamID)
 
       if ( lbounds && zaxistype != ZAXIS_HYBRID && zaxistype != ZAXIS_HYBRID_HALF )
 	for ( levelID = 0; levelID < nlevels; levelID++ )
-	  dlevels[levelID] = (vartable[varid].levelTable[levelID].level1 +
-	                      vartable[varid].levelTable[levelID].level2)/2;
+	  dlevels[levelID] = (level_sf*vartable[varid].levelTable[levelID].level1 +
+	                      level_sf*vartable[varid].levelTable[levelID].level2)/2;
       else
 	for ( levelID = 0; levelID < nlevels; levelID++ )
-	  dlevels[levelID] = vartable[varid].levelTable[levelID].level1;
+	  dlevels[levelID] = level_sf*vartable[varid].levelTable[levelID].level1;
 
       if ( nlevels > 1 )
 	{
@@ -504,16 +518,15 @@ void cdiGenVars(int streamID)
 		  /*
 		  qsort(dlevels, nlevels, sizeof(double), dblcmp);
 		  */
-		  qsort(vartable[varid].levelTable, nlevels, 
-			sizeof(leveltable_t), cmpLevelTable);
+		  qsort(vartable[varid].levelTable, nlevels, sizeof(leveltable_t), cmpLevelTable);
 
 		  if ( lbounds && zaxistype != ZAXIS_HYBRID && zaxistype != ZAXIS_HYBRID_HALF )
 		    for ( levelID = 0; levelID < nlevels; levelID++ )
-		      dlevels[levelID] = (vartable[varid].levelTable[levelID].level1 +
-					  vartable[varid].levelTable[levelID].level2)/2.;
+		      dlevels[levelID] = (level_sf*vartable[varid].levelTable[levelID].level1 +
+					  level_sf*vartable[varid].levelTable[levelID].level2)/2.;
 		  else
 		    for ( levelID = 0; levelID < nlevels; levelID++ )
-		      dlevels[levelID] = vartable[varid].levelTable[levelID].level1;
+		      dlevels[levelID] = level_sf*vartable[varid].levelTable[levelID].level1;
 		}
 	    }
 	}
@@ -522,20 +535,24 @@ void cdiGenVars(int streamID)
 	{
 	  dlevels1 = (double *) malloc(nlevels*sizeof(double));
 	  for ( levelID = 0; levelID < nlevels; levelID++ )
-	    dlevels1[levelID] = vartable[varid].levelTable[levelID].level1;
+	    dlevels1[levelID] = level_sf*vartable[varid].levelTable[levelID].level1;
 	  dlevels2 = (double *) malloc(nlevels*sizeof(double));
 	  for ( levelID = 0; levelID < nlevels; levelID++ )
-	    dlevels2[levelID] = vartable[varid].levelTable[levelID].level2;
+	    dlevels2[levelID] = level_sf*vartable[varid].levelTable[levelID].level2;
 	}
 
-      zaxisID = varDefZaxis(vlistID, zaxistype, nlevels, dlevels, lbounds, dlevels1, dlevels2,
-			    Vctsize, Vct, NULL, NULL, NULL, 0, 0, ltype);
+      if ( vartable[varid].level_sf == 77 )
+        zaxisID = varDefZaxis(vlistID, zaxistype, nlevels, dlevels, lbounds, dlevels1, dlevels2,
+                              Vctsize, Vct, NULL, NULL, "m", 0, 0, ltype);
+      else
+        zaxisID = varDefZaxis(vlistID, zaxistype, nlevels, dlevels, lbounds, dlevels1, dlevels2,
+                              Vctsize, Vct, NULL, NULL, NULL, 0, 0, ltype);
 
       if ( lbounds ) free(dlevels1);
       if ( lbounds ) free(dlevels2);
       free(dlevels);
 
-      varID = streamNewVar(streamID, gridID, zaxisID);
+      varID = stream_new_var(streamptr, gridID, zaxisID);
       varID = vlistDefVar(vlistID, gridID, zaxisID, tsteptype);
 
       vlistDefVarParam(vlistID, varID, param);
@@ -605,8 +622,7 @@ void cdiGenVars(int streamID)
       */
       for ( levelID = 0; levelID < nlevels; levelID++ )
 	{
-	  streamptr->vars[varID].level[levelID] =
-	    vartable[varid].levelTable[levelID].recID;
+	  streamptr->vars[varID].level[levelID] = vartable[varid].levelTable[levelID].recID;
 	  for ( lindex = 0; lindex < nlevels; lindex++ )
 	    if ( levelID == vartable[varid].levelTable[lindex].lindex ) break;
 
diff --git a/libcdi/src/varscan.h b/libcdi/src/varscan.h
index 1bb0600..f24f162 100644
--- a/libcdi/src/varscan.h
+++ b/libcdi/src/varscan.h
@@ -7,7 +7,7 @@
 
 
 void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
-		  int level1, int level2, int prec,
+		  int level1, int level2, int level_sf, int prec,
 		  int *pvarID, int *plevelID, int tsteptype, int numavg, int ltype,
 		  const char *name, const char *longname, const char *units);
 
diff --git a/libcdi/src/vlist.c b/libcdi/src/vlist.c
index de4e0e6..adfabf6 100644
--- a/libcdi/src/vlist.c
+++ b/libcdi/src/vlist.c
@@ -6,6 +6,7 @@
 #include "cdi.h"
 #include "stream_int.h"
 #include "vlist.h"
+#include "zaxis.h"
 #include "varscan.h"
 #include "namespace.h"
 #include "pio_util.h"
@@ -225,6 +226,16 @@ void vlistDestroy(int vlistID)
 
       if ( vlistptr->vars[varID].ensdata )  free(vlistptr->vars[varID].ensdata);
 
+      int i;
+      for (i=0; i<vlistptr->vars[varID].opt_grib_int_nentries; i++) {
+	if ( vlistptr->vars[varID].opt_grib_int_keyword[i] )
+	  free(vlistptr->vars[varID].opt_grib_int_keyword[i]);
+      }
+      for (i=0; i<vlistptr->vars[varID].opt_grib_dbl_nentries; i++) {
+	if ( vlistptr->vars[varID].opt_grib_dbl_keyword[i] )
+	  free(vlistptr->vars[varID].opt_grib_dbl_keyword[i]);
+      }
+
       vlistDelAtts(vlistID, varID);
     }
 
@@ -291,6 +302,26 @@ void vlistCopy(int vlistID2, int vlistID1)
                      vlistptr1->vars[varID].ensdata, sizeof(ensinfo_t));
             }
 
+          /* ---------------------------------- */
+          /* Local change: 2013-01-28, FP (DWD) */
+          /* ---------------------------------- */
+
+	  int i;
+	  vlistptr2->vars[varID].opt_grib_int_nentries = vlistptr1->vars[varID].opt_grib_int_nentries;
+	  for (i=0; i<vlistptr1->vars[varID].opt_grib_int_nentries; i++) {
+	    if ( vlistptr1->vars[varID].opt_grib_int_keyword[i] ) {
+	      vlistptr2->vars[varID].opt_grib_int_keyword[i] = strdupx(vlistptr1->vars[varID].opt_grib_int_keyword[i]);
+	      vlistptr2->vars[varID].opt_grib_int_val[i]     = vlistptr1->vars[varID].opt_grib_int_val[i];
+	    }
+	  }
+	  vlistptr2->vars[varID].opt_grib_dbl_nentries = vlistptr1->vars[varID].opt_grib_dbl_nentries;
+	  for (i=0; i<vlistptr1->vars[varID].opt_grib_dbl_nentries; i++) {
+	    if ( vlistptr1->vars[varID].opt_grib_dbl_keyword[i] ) {
+	      vlistptr2->vars[varID].opt_grib_dbl_keyword[i] = strdupx(vlistptr1->vars[varID].opt_grib_dbl_keyword[i]);
+	      vlistptr2->vars[varID].opt_grib_dbl_val[i]     = vlistptr1->vars[varID].opt_grib_dbl_val[i];
+	    }
+	  }
+
 	  vlistptr2->vars[varID].atts.nelems = 0;
 	  vlistCopyVarAtts(vlistID1, varID, vlistID2, varID);
 
@@ -520,6 +551,26 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
                        vlistptr1->vars[varID].ensdata, sizeof(ensinfo_t));
               }
 
+	    /* ---------------------------------- */
+	    /* Local change: 2013-01-28, FP (DWD) */
+	    /* ---------------------------------- */
+
+	    int i;
+	    vlistptr2->vars[varID2].opt_grib_int_nentries = vlistptr1->vars[varID].opt_grib_int_nentries;
+	    for (i=0; i<vlistptr1->vars[varID].opt_grib_int_nentries; i++) {
+	      if ( vlistptr1->vars[varID].opt_grib_int_keyword[i] ) {
+		vlistptr2->vars[varID2].opt_grib_int_keyword[i] = strdupx(vlistptr1->vars[varID].opt_grib_int_keyword[i]);
+		vlistptr2->vars[varID2].opt_grib_int_val[i]     = vlistptr1->vars[varID].opt_grib_int_val[i];
+	      }
+	    }
+	    vlistptr2->vars[varID2].opt_grib_dbl_nentries = vlistptr1->vars[varID].opt_grib_dbl_nentries;
+	    for (i=0; i<vlistptr1->vars[varID].opt_grib_dbl_nentries; i++) {
+	      if ( vlistptr1->vars[varID].opt_grib_dbl_keyword[i] ) {
+		vlistptr2->vars[varID2].opt_grib_dbl_keyword[i] = strdupx(vlistptr1->vars[varID].opt_grib_dbl_keyword[i]);
+		vlistptr2->vars[varID2].opt_grib_dbl_val[i]     = vlistptr1->vars[varID].opt_grib_dbl_val[i];
+	      }
+	    }
+
 	    vlistptr2->vars[varID2].atts.nelems = 0;
 	    vlistCopyVarAtts(vlistID1, varID, vlistID2, varID2);
 
@@ -719,6 +770,26 @@ void vlistCat(int vlistID2, int vlistID1)
           memcpy(vlistptr2->vars[varID2].ensdata, vlistptr1->vars[varID].ensdata, sizeof(ensinfo_t));
         }
 
+      /* ---------------------------------- */
+      /* Local change: 2013-01-28, FP (DWD) */
+      /* ---------------------------------- */
+
+      int i;
+      vlistptr2->vars[varID2].opt_grib_int_nentries = vlistptr1->vars[varID].opt_grib_int_nentries;
+      for (i=0; i<vlistptr1->vars[varID].opt_grib_int_nentries; i++) {
+	if ( vlistptr1->vars[varID].opt_grib_int_keyword[i] ) {
+	  vlistptr2->vars[varID2].opt_grib_int_keyword[i] = strdupx(vlistptr1->vars[varID].opt_grib_int_keyword[i]);
+	  vlistptr2->vars[varID2].opt_grib_int_val[i]     = vlistptr1->vars[varID].opt_grib_int_val[i];
+	}
+      }
+      vlistptr2->vars[varID2].opt_grib_dbl_nentries = vlistptr1->vars[varID].opt_grib_dbl_nentries;
+      for (i=0; i<vlistptr1->vars[varID].opt_grib_dbl_nentries; i++) {
+	if ( vlistptr1->vars[varID].opt_grib_dbl_keyword[i] ) {
+	  vlistptr2->vars[varID2].opt_grib_dbl_keyword[i] = strdupx(vlistptr1->vars[varID].opt_grib_dbl_keyword[i]);
+	  vlistptr2->vars[varID2].opt_grib_dbl_val[i]     = vlistptr1->vars[varID].opt_grib_dbl_val[i];
+	}
+      }
+
       vlistptr2->vars[varID2].atts.nelems = 0;
       vlistCopyVarAtts(vlistID1, varID, vlistID2, varID2);
 
diff --git a/libcdi/src/vlist.h b/libcdi/src/vlist.h
index db35667..a49f394 100644
--- a/libcdi/src/vlist.h
+++ b/libcdi/src/vlist.h
@@ -68,6 +68,13 @@ typedef struct
 }
 ensinfo_t;
 
+/* ---------------------------------- */
+/* Local change: 2013-01-28, FP (DWD) */
+/* ---------------------------------- */
+
+/* Length of optional keyword/value pair list */
+#define MAX_OPT_GRIB_ENTRIES 50
+
 
 typedef struct
 {
@@ -107,6 +114,18 @@ typedef struct
   int         decoSize;
   deco_t     *deco;
 
+  /* ---------------------------------- */
+  /* Local change: 2013-01-28, FP (DWD) */
+  /* ---------------------------------- */
+
+  /* (Optional) list of keyword/double value pairs */
+  int    opt_grib_dbl_nentries;
+  char*  opt_grib_dbl_keyword[MAX_OPT_GRIB_ENTRIES];
+  double opt_grib_dbl_val[MAX_OPT_GRIB_ENTRIES];
+  /* (Optional) list of keyword/integer value pairs */
+  int    opt_grib_int_nentries;
+  char*  opt_grib_int_keyword[MAX_OPT_GRIB_ENTRIES];
+  int    opt_grib_int_val[MAX_OPT_GRIB_ENTRIES];
 }
 var_t;
 
diff --git a/libcdi/src/vlist_var.c b/libcdi/src/vlist_var.c
index ad6331e..20bbbe6 100644
--- a/libcdi/src/vlist_var.c
+++ b/libcdi/src/vlist_var.c
@@ -63,6 +63,20 @@ void vlistvarInitEntry(int vlistID, int varID)
   vlistptr->vars[varID].iorank        = CDI_UNDEFID;
   vlistptr->vars[varID].decoSize      = 0;
   vlistptr->vars[varID].deco          = NULL;
+
+  /* ---------------------------------- */
+  /* Local change: 2013-01-28, FP (DWD) */
+  /* ---------------------------------- */
+
+  vlistptr->vars[varID].opt_grib_dbl_nentries = 0;
+  vlistptr->vars[varID].opt_grib_int_nentries = 0;
+  int i;
+  for (i=0; i<MAX_OPT_GRIB_ENTRIES; i++) {
+    vlistptr->vars[varID].opt_grib_dbl_val[i] = 0.0;
+    vlistptr->vars[varID].opt_grib_int_val[i] =   0;
+    vlistptr->vars[varID].opt_grib_int_keyword[i] = NULL;
+    vlistptr->vars[varID].opt_grib_dbl_keyword[i] = NULL;
+  } // for
 }
 
 static
@@ -660,7 +674,7 @@ void vlistInqVarStdname(int vlistID, int varID, char *stdname)
   if ( vlistptr->vars[varID].stdname == NULL )
     {
       stdname[0] = '\0';
-    }  
+    }
   else
     strcpy(stdname, vlistptr->vars[varID].stdname);
 
@@ -675,7 +689,7 @@ void vlistInqVarStdname(int vlistID, int varID, char *stdname)
 @Parameter
     @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
     @Item  varID    Variable identifier.
-    @Item  units    Units of the variable. The caller must allocate space for the 
+    @Item  units    Units of the variable. The caller must allocate space for the
                     returned string. The maximum possible length, in characters, of
                     the string is given by the predefined constant @func{CDI_MAX_NAME}.
 
@@ -1798,6 +1812,110 @@ int vlistInqVarEnsemble( int vlistID, int varID, int *ensID, int *ensCount, int
   return (status);
 }
 
+/* ---------------------------------- */
+/* Local change: 2013-01-28, FP (DWD) */
+/* ---------------------------------- */
+
+/* vlistDefVarIntKey: Set an arbitrary keyword/integer value pair for GRIB API */
+void vlistDefVarIntKey(int vlistID, int varID, const char *name, int value)
+{
+  vlist_t *vlistptr;
+  vlistptr = vlist_to_pointer(vlistID);
+
+  int idx = vlistptr->vars[varID].opt_grib_int_nentries;
+  vlistptr->vars[varID].opt_grib_int_nentries++;
+  if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/integer value pairs!");
+  vlistptr->vars[varID].opt_grib_int_val[idx] = value;
+  if ( name )
+    vlistptr->vars[varID].opt_grib_int_keyword[idx] = strdupx(name);
+  else
+    Error("Internal error!");
+}
+
+/* vlistDefVarDblKey: Set an arbitrary keyword/double value pair for GRIB API */
+void vlistDefVarDblKey(int vlistID, int varID, const char *name, double value)
+{
+  vlist_t *vlistptr;
+  vlistptr = vlist_to_pointer(vlistID);
+
+  int idx = vlistptr->vars[varID].opt_grib_dbl_nentries;
+  vlistptr->vars[varID].opt_grib_dbl_nentries++;
+  if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/double value pairs!");
+  vlistptr->vars[varID].opt_grib_dbl_val[idx] = value;
+  if ( name )
+    vlistptr->vars[varID].opt_grib_dbl_keyword[idx] = strdupx(name);
+  else
+    Error("Internal error!");
+}
+
+#if  defined  (HAVE_LIBGRIB_API)
+#  include "file.h"
+#  include "grib_api.h"
+#endif
+
+/* vlistInqVarRawBegin: Open GRIB record to retrieve raw meta-data in subsequent calls */
+void vlistInqVarRawBegin(int streamID, int varID)
+{
+#if  defined  (HAVE_LIBGRIB_API)
+  stream_t *streamptr;
+  int       recID, tsID, fileID;
+  long      recpos, recsize;
+
+  streamptr = stream_to_pointer(streamID);
+  stream_check_ptr(__func__, streamptr);
+
+  fileID  = streamInqFileID(streamID);
+  tsID    = streamptr->curTsID;
+
+  // determine record ID for varID in current time step
+  for (recID=0; (recID<streamptr->tsteps[0].nrecs) && (varID != streamptr->tsteps[tsID].records[recID].varID); recID++);
+  recpos  = streamptr->tsteps[tsID].records[recID].position;
+  recsize = streamptr->tsteps[tsID].records[recID].size;
+
+  fileSetPos(fileID, recpos, SEEK_SET);
+  fileRead(fileID, streamptr->record->buffer, (size_t) recsize);
+
+  streamptr->gh = (void *) grib_handle_new_from_message(NULL, (void *) streamptr->record->buffer, recsize);
+#endif
+}
+
+
+/* vlistInqVarDblKey: raw access to GRIB meta-data */
+double vlistInqVarDblKey(int streamID, const char* name)
+{
+  double value = 0;
+#if  defined  (HAVE_LIBGRIB_API)
+  stream_t *streamptr = stream_to_pointer(streamID);
+  stream_check_ptr(__func__, streamptr);
+  GRIB_CHECK(grib_get_double((grib_handle*) streamptr->gh, name, &value), 0);
+#endif
+  return value;
+}
+
+
+/* vlistInqVarIntKey: raw access to GRIB meta-data */
+int vlistInqVarIntKey(int streamID, const char* name)
+{
+  long int value = 0;
+#if  defined  (HAVE_LIBGRIB_API)
+  stream_t *streamptr = stream_to_pointer(streamID);
+  stream_check_ptr(__func__, streamptr);
+  GRIB_CHECK(grib_get_long((grib_handle*) streamptr->gh, name, &value), 0);
+#endif
+  return (int) value;
+}
+
+
+/* vlistInqVarRawEnd: Free previously opened GRIB record */
+void vlistInqVarRawEnd(int streamID)
+{
+#if  defined  (HAVE_LIBGRIB_API)
+  stream_t *streamptr = stream_to_pointer(streamID);
+  stream_check_ptr(__func__, streamptr);
+  grib_handle_delete((grib_handle*) streamptr->gh);
+#endif
+}
+
 
 void vlistDefVarDeco ( int vlistID, int varID, int decoSize, deco_t * deco )
 {
diff --git a/libcdi/src/zaxis.c b/libcdi/src/zaxis.c
index 276e500..cc9ac86 100644
--- a/libcdi/src/zaxis.c
+++ b/libcdi/src/zaxis.c
@@ -44,7 +44,10 @@ ZaxistypeEntry[] = {
   { /* 13 */ 0, "toa",        "top_of_atmosphere", "",               ""},
   { /* 14 */ 0, "seabottom",  "sea_bottom",        "",               ""},
   { /* 15 */ 0, "atmosphere", "atmosphere",        "",               ""},
-  { /* 16 */ 0, "height",     "generalized height","height",         "m"},
+  { /* 16 */ 0, "cloudbase",  "cloud_base",        "",               ""},
+  { /* 17 */ 0, "cloudtop",   "cloud_top",         "",               ""},
+  { /* 18 */ 0, "isotherm0",  "isotherm_zero",     "",               ""},
+  { /* 19 */ 0, "height",     "generalized height","height",         "m"},
 };
 
 static int CDI_MaxZaxistype = sizeof(ZaxistypeEntry) / sizeof(ZaxistypeEntry[0]);
@@ -178,6 +181,9 @@ int zaxisSize(void)
     @Item  zaxistype  The type of the Z-axis, one of the set of predefined CDI Z-axis types.
                       The valid CDI Z-axis types are @func{ZAXIS_GENERIC}, @func{ZAXIS_SURFACE},
                       @func{ZAXIS_HYBRID}, @func{ZAXIS_SIGMA}, @func{ZAXIS_PRESSURE}, @func{ZAXIS_HEIGHT},
+                      @func{ZAXIS_ISENTROPIC}, @func{ZAXIS_ALTITUDE}, @func{ZAXIS_MEANSEA}, @func{ZAXIS_TOA},
+                      @func{ZAXIS_SEA_BOTTOM}, @func{ZAXIS_ATMOSPHERE}, @func{ZAXIS_CLOUD_BASE},
+                      @func{ZAXIS_CLOUD_TOP}, @func{ZAXIS_ISOTHERM_ZERO}, 
                       @func{ZAXIS_DEPTH_BELOW_SEA} and @func{ZAXIS_DEPTH_BELOW_LAND}.
     @Item  size       Number of levels.
 
@@ -987,6 +993,9 @@ The function @func{zaxisInqType} returns the type of a Z-axis.
 one of the set of predefined CDI Z-axis types.
 The valid CDI Z-axis types are @func{ZAXIS_GENERIC}, @func{ZAXIS_SURFACE},
 @func{ZAXIS_HYBRID}, @func{ZAXIS_SIGMA}, @func{ZAXIS_PRESSURE}, @func{ZAXIS_HEIGHT},
+ at func{ZAXIS_ISENTROPIC}, @func{ZAXIS_ALTITUDE}, @func{ZAXIS_MEANSEA}, @func{ZAXIS_TOA},
+ at func{ZAXIS_SEA_BOTTOM}, @func{ZAXIS_ATMOSPHERE}, @func{ZAXIS_CLOUD_BASE},
+ at func{ZAXIS_CLOUD_TOP}, @func{ZAXIS_ISOTHERM_ZERO}, 
 @func{ZAXIS_DEPTH_BELOW_SEA} and @func{ZAXIS_DEPTH_BELOW_LAND}.
 
 @EndFunction
@@ -1476,7 +1485,7 @@ int  zaxisCompareP ( void * zaxisptr1, void * zaxisptr2 )
       if ( !z2->vals ) return differ;
 
       for ( i = 0; i < z1->size; i++ )
-        if ( z1->vals[i] != z2->vals[i] ) return differ;
+        if ( IS_NOT_EQUAL(z1->vals[i], z2->vals[i]) ) return differ;
     }
   else if ( z2->vals )
     return differ;
@@ -1488,7 +1497,7 @@ int  zaxisCompareP ( void * zaxisptr1, void * zaxisptr2 )
       if ( !z2->lbounds ) return differ;
 
       for ( i = 0; i < z1->size; i++ )
-        if ( z1->lbounds[i] != z2->lbounds[i] ) return differ;
+        if ( IS_NOT_EQUAL(z1->lbounds[i], z2->lbounds[i]) ) return differ;
     }
   else if ( z2->lbounds )
     return differ;
@@ -1500,7 +1509,7 @@ int  zaxisCompareP ( void * zaxisptr1, void * zaxisptr2 )
       if ( !z2->ubounds ) return differ;
 
       for ( i = 0; i < z1->size; i++ )
-        if ( z1->ubounds[i] != z2->ubounds[i] ) return differ;
+        if ( IS_NOT_EQUAL(z1->ubounds[i], z2->ubounds[i]) ) return differ;
     }
   else if ( z2->ubounds )
     return differ;
@@ -1512,7 +1521,7 @@ int  zaxisCompareP ( void * zaxisptr1, void * zaxisptr2 )
       if ( !z2->weights ) return differ;
 
       for ( i = 0; i < z1->size; i++ )
-        if ( z1->weights[i] != z2->weights[i] ) return differ;
+        if ( IS_NOT_EQUAL(z1->weights[i], z2->weights[i]) ) return differ;
     }
   else if ( z2->weights )
     return differ;
@@ -1524,7 +1533,7 @@ int  zaxisCompareP ( void * zaxisptr1, void * zaxisptr2 )
       if ( !z2->vct ) return differ;
 
       for ( i = 0; i < z1->vctsize; i++ )
-        if ( z1->vct[i] != z2->vct[i] ) return differ;
+        if ( IS_NOT_EQUAL(z1->vct[i], z2->vct[i]) ) return differ;
     }
   else if ( z2->vct )
     return differ;
diff --git a/libcdi/src/zaxis.h b/libcdi/src/zaxis.h
new file mode 100644
index 0000000..366c7b1
--- /dev/null
+++ b/libcdi/src/zaxis.h
@@ -0,0 +1,6 @@
+#ifndef _ZAXIS_H
+#define _ZAXIS_H
+
+int zaxisSize(void);
+
+#endif
diff --git a/src/._CdoMagicsMapper.h b/src/._CdoMagicsMapper.h
index 0bda91d..41970ee 100644
Binary files a/src/._CdoMagicsMapper.h and b/src/._CdoMagicsMapper.h differ
diff --git a/src/._Maggraph.c b/src/._Maggraph.c
index 472aa7d..ac9f42c 100644
Binary files a/src/._Maggraph.c and b/src/._Maggraph.c differ
diff --git a/src/._Magplot.c b/src/._Magplot.c
index ef299d7..39512cd 100644
Binary files a/src/._Magplot.c and b/src/._Magplot.c differ
diff --git a/src/._Magvector.c b/src/._Magvector.c
index b5a6e81..db92965 100644
Binary files a/src/._Magvector.c and b/src/._Magvector.c differ
diff --git a/src/._Rhopot.c b/src/._Rhopot.c
new file mode 100644
index 0000000..70fd267
Binary files /dev/null and b/src/._Rhopot.c differ
diff --git a/src/._StringUtilities.c b/src/._StringUtilities.c
index 20e83f7..fa730a7 100644
Binary files a/src/._StringUtilities.c and b/src/._StringUtilities.c differ
diff --git a/src/._StringUtilities.h b/src/._StringUtilities.h
index 6ce7dd4..6c0ff55 100644
Binary files a/src/._StringUtilities.h and b/src/._StringUtilities.h differ
diff --git a/src/._magics_template_parser.c b/src/._magics_template_parser.c
index 02252b0..11d1ace 100644
Binary files a/src/._magics_template_parser.c and b/src/._magics_template_parser.c differ
diff --git a/src/._results_template_parser.c b/src/._results_template_parser.c
index 9925b5a..d92da7d 100644
Binary files a/src/._results_template_parser.c and b/src/._results_template_parser.c differ
diff --git a/src/._template_parser.c b/src/._template_parser.c
index 2ef88bc..14c70a0 100644
Binary files a/src/._template_parser.c and b/src/._template_parser.c differ
diff --git a/src/._template_parser.h b/src/._template_parser.h
index 344ec2a..64de6c5 100644
Binary files a/src/._template_parser.h and b/src/._template_parser.h differ
diff --git a/src/Rhopot.c b/src/Adisit.c
similarity index 55%
copy from src/Rhopot.c
copy to src/Adisit.c
index 4bbe592..880f5ea 100644
--- a/src/Rhopot.c
+++ b/src/Adisit.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -18,7 +18,7 @@
 /*
    This module contains the following operators:
 
-      Rhopot      rhopot          potential density
+      Adisit      adisit          potential temperature
 */
 
 #include <ctype.h>
@@ -43,9 +43,9 @@
 !!
 */
 
-/* compute density from potential temperature directly */
+/* compute insitu temperature from potential temperature */
 static
-double potrho_1(double tpot, double sal, double p)
+double adisit_1(double tpot, double sal, double p)
 {
   double a_a1 = 3.6504E-4, a_a2 = 8.3198E-5, a_a3 = 5.4065E-7,
          a_a4 = 4.0274E-9,
@@ -54,26 +54,7 @@ double potrho_1(double tpot, double sal, double p)
          a_d = 4.1057E-9,
          a_e1 = 1.6056E-10, a_e2 = 5.0484E-12;
 
-  double r_a0 = 999.842594, r_a1 = 6.793952e-2, r_a2 = -9.095290e-3,
-         r_a3 = 1.001685e-4, r_a4 = -1.120083e-6, r_a5 = 6.536332e-9,
-         r_b0 = 8.24493e-1, r_b1 = -4.0899e-3, r_b2 = 7.6438e-5,
-         r_b3 = -8.2467e-7, r_b4 = 5.3875e-9,
-         r_c0 = -5.72466e-3, r_c1 = 1.0227e-4, r_c2 = -1.6546e-6,
-         r_d0 = 4.8314e-4,
-         r_e0 = 19652.21, r_e1 = 148.4206, r_e2 = -2.327105,
-         r_e3 = 1.360477e-2, r_e4 = -5.155288e-5,
-         r_f0 = 54.6746, r_f1 = -0.603459, r_f2 = 1.09987e-2,
-         r_f3 = -6.1670e-5,
-         r_g0 = 7.944e-2, r_g1 = 1.6483e-2, r_g2 = -5.3009e-4,
-         r_h0 = 3.239908, r_h1 = 1.43713e-3, r_h2 = 1.16092e-4,
-         r_h3 = -5.77905e-7,
-         r_ai0 = 2.2838e-3, r_ai1 = -1.0981e-5, r_ai2 = -1.6078e-6,
-         r_aj0 = 1.91075e-4,
-         r_ak0 = 8.50935e-5, r_ak1 = -6.12293e-6, r_ak2 = 5.2787e-8,
-         r_am0 = -9.9348e-7, r_am1 = 2.0816e-8, r_am2 = 9.1697e-10;
-
-  double dc, dv, dvs, fne, fst, qc, qn3, qnq, qv, qvs, s, s3h, t, tpo;
-  double rho;
+  double dc, dv, dvs, fne, fst, qc, qn3, qnq, qv, qvs, t, tpo;
 
   qc = p * (a_a1 + p * (a_c1 - a_e1 * p));
   qv = p * (a_b1 - a_d * p);
@@ -90,96 +71,46 @@ double potrho_1(double tpot, double sal, double p)
       fne = - qvs + t*(dvs + t*(qnq + t*qn3)) - tpo;
       fst = dvs + t*(2.*qnq + 3.*qn3*t);
       t = t - fne/fst;
-      s = MAX(sal, 0.0);
-      s3h = sqrt(s*s*s);
-
-      rho = (r_a0 + t * (r_a1 + t * (r_a2 + t * (r_a3 + t * (r_a4 + t * r_a5))))
-            + s * (r_b0 + t * (r_b1 + t * (r_b2 + t * (r_b3 + t * r_b4))))    
-            + r_d0 * s*s                 
-            + s3h * (r_c0 + t * (r_c1 + r_c2 * t)))                           
-           / (1.                                                            
-             - p / (p * (r_h0 + t * (r_h1 + t * (r_h2 + t * r_h3))            
-                         + s * (r_ai0 + t * (r_ai1 + r_ai2 * t))              
-                         + r_aj0 * s3h                                        
-                         + (r_ak0 + t * (r_ak1 + t * r_ak2)                   
-                         + s * (r_am0 + t * (r_am1 + t * r_am2))) * p)        
-                    + r_e0 + t * (r_e1 + t * (r_e2 + t * (r_e3 + t * r_e4)))  
-                    + s * (r_f0 + t * (r_f1 + t * (r_f2 + t * r_f3)))         
-                    + s3h * (r_g0 + t * (r_g1 + r_g2 * t))));
     }
 
-  return (rho);
+  return (t);
 }
 
-/*
-#define N 4
-int main (int argc, char *argv[])
-{
-  int i;
-  {
-    double p    = 0;
-    double t[N] = {22, 25, 28, 31};
-    double s[N] = {35, 35, 35, 35};
-    double x[N] = {24.219, 23.343, 22.397, 21.384};
-    double r[N];
-  
-    potrho_1d(t, s, p, r, N);
-
-    for ( i = 0; i < N; ++i )
-      printf("%d %5g %3g %8g %8g %8g %10.3f\n", i, p, s[i], t[i], x[i], r[i], r[i]-x[i]);
-  }
-
-  {
-    double p    = 300;
-    double t[N] = {-2.140, -0.186, 1.771, 3.728};
-    double s[N] = {35, 35, 35, 35};
-    double x[N] = {42.191, 41.941, 41.649, 41.319};
-    double r[N];
-  
-    potrho_1d(t, s, p, r, N);
-
-    for ( i = 0; i < N; ++i )
-      printf("%d %5g %3g %8g %8g %8g %10.3f\n", i, p, s[i], t[i], x[i], r[i], r[i]-x[i]);
-  }
-
-  return (0);
-}
-*/
 
 static
-void calc_rhopot(long gridsize, long nlevel, double *pressure, field_t tho, field_t sao, field_t rho)
+void calc_adisit(long gridsize, long nlevel, double *pressure, field_t tho, field_t sao, field_t tis)
 {
   /* pressure units: hPa     */
   /* tho units:      Celsius */
   /* sao units:      psu     */
 
   long i, levelID, offset;
-  double *rhoptr, *thoptr, *saoptr;
+  double *tisptr, *thoptr, *saoptr;
 
   for ( levelID = 0; levelID < nlevel; ++levelID )
     {
       offset = gridsize*levelID;
       thoptr = tho.ptr + offset;
       saoptr = sao.ptr + offset;
-      rhoptr = rho.ptr + offset;
+      tisptr = tis.ptr + offset;
 
       for ( i = 0; i < gridsize; ++i )
 	{
 	  if ( DBL_IS_EQUAL(thoptr[i], tho.missval) ||
 	       DBL_IS_EQUAL(saoptr[i], sao.missval) )
 	    {
-	      rhoptr[i] = rho.missval;
+	      tisptr[i] = tis.missval;
 	    }
 	  else
 	    {
-	      rhoptr[i] = potrho_1(thoptr[i], saoptr[i], pressure[levelID]); 
+	      tisptr[i] = adisit_1(thoptr[i], saoptr[i], pressure[levelID]); 
 	    }
 	}
     }
 }
 
 
-void *Rhopot(void *argument)
+void *Adisit(void *argument)
 {
   int streamID1, streamID2;
   int nrecs;
@@ -193,12 +124,13 @@ void *Rhopot(void *argument)
   int i;
   int nmiss;
   int thoID = -1, saoID = -1;
+  int tisID2, saoID2;
   char varname[CDI_MAX_NAME], stdname[CDI_MAX_NAME];
   int taxisID1, taxisID2;
   double pin = -1;
   double *pressure;
   double *single;
-  field_t tho, sao, rho;
+  field_t tho, sao, tis;
 
   cdoInitialize(argument);
 
@@ -215,25 +147,29 @@ void *Rhopot(void *argument)
       gridID  = vlistInqVarGrid(vlistID1, varID);
 
       code = vlistInqVarCode(vlistID1, varID);
-      vlistInqVarName(vlistID1, varID, varname);
-      vlistInqVarStdname(vlistID1,varID, stdname);
-      strtolower(varname);
 
-      if      ( strcmp(varname, "tho")   == 0 ) code = 2;
-      else if ( strcmp(varname, "sao")   == 0 ) code = 5;
+      if ( code <= 0 )
+	{
+	  vlistInqVarName(vlistID1, varID, varname);
+	  vlistInqVarStdname(vlistID1,varID, stdname);
+	  strtolower(varname);
+
+	  if      ( strcmp(varname, "tho")   == 0 ) code = 2;
+	  else if ( strcmp(varname, "sao")   == 0 ) code = 5;
 
-      else if ( strcmp(varname, "t")     == 0 ) code = 2;
-      else if ( strcmp(varname, "s")     == 0 ) code = 5;
+	  else if ( strcmp(varname, "s")     == 0 ) code = 5;
+	  else if ( strcmp(varname, "t")     == 0 ) code = 2;
 
-      else if ( strcmp(stdname, "sea_water_potential_temperature") == 0 ) code = 2;
-      else if ( strcmp(stdname, "sea_water_salinity")              == 0 ) code = 5;
+	  else if ( strcmp(stdname, "sea_water_salinity")              == 0 ) code = 5;
+	  else if ( strcmp(stdname, "sea_water_potential_temperature") == 0 ) code = 2;
+	}
 
       if      ( code == 2 ) thoID = varID;
       else if ( code == 5 ) saoID = varID;
     }
 
-  if ( thoID == -1 ) cdoAbort("Potential temperature not found!");
   if ( saoID == -1 ) cdoAbort("Sea water salinity not found!");
+  if ( thoID == -1 ) cdoAbort("Potential temperature not found!");
 
   ngrids = vlistNgrids(vlistID1);
   gridID = vlistGrid(vlistID1, 0);
@@ -272,25 +208,34 @@ void *Rhopot(void *argument)
 
   tho.ptr = (double *) malloc(gridsize*nlevel*sizeof(double));
   sao.ptr = (double *) malloc(gridsize*nlevel*sizeof(double));
-  rho.ptr = (double *) malloc(gridsize*nlevel*sizeof(double));
+  tis.ptr = (double *) malloc(gridsize*nlevel*sizeof(double));
 
   tho.nmiss = 0;
   sao.nmiss = 0;
-  rho.nmiss = 0;
+  tis.nmiss = 0;
   
   tho.missval = vlistInqVarMissval(vlistID1, thoID);
   sao.missval = vlistInqVarMissval(vlistID1, saoID);
-  rho.missval = tho.missval;
+  tis.missval = tho.missval;
 
 
   vlistID2 = vlistCreate();
-  varID = vlistDefVar(vlistID2, gridID, zaxisID, TSTEP_INSTANT);
-  vlistDefVarParam(vlistID2, varID, cdiEncodeParam(18, 255, 255));
-  vlistDefVarName(vlistID2, varID, "rhopot");
-  vlistDefVarLongname(vlistID2, varID, "Sea water potential density");
-  vlistDefVarStdname(vlistID2, varID, "sea_water_potential_density");
-  vlistDefVarUnits(vlistID2, varID, "kg m-3");
-  vlistDefVarMissval(vlistID2, varID, rho.missval);
+
+  tisID2 = vlistDefVar(vlistID2, gridID, zaxisID, TIME_VARIABLE);
+  vlistDefVarParam(vlistID2, tisID2, cdiEncodeParam(20, 255, 255));
+  vlistDefVarName(vlistID2, tisID2, "to");
+  vlistDefVarLongname(vlistID2, tisID2, "Sea water temperature");
+  vlistDefVarStdname(vlistID2, tisID2, "sea_water_temperature");
+  vlistDefVarUnits(vlistID2, tisID2, "K");
+  vlistDefVarMissval(vlistID2, tisID2, tis.missval);
+
+  saoID2 = vlistDefVar(vlistID2, gridID, zaxisID, TIME_VARIABLE);
+  vlistDefVarParam(vlistID2, saoID2, cdiEncodeParam(5, 255, 255));
+  vlistDefVarName(vlistID2, saoID2, "sao");
+  vlistDefVarLongname(vlistID2, saoID2, "Sea water salinity");
+  vlistDefVarStdname(vlistID2, saoID2, "sea_water_salinity");
+  vlistDefVarUnits(vlistID2, saoID2, "psu");
+  vlistDefVarMissval(vlistID2, saoID2, sao.missval);
 
 
   taxisID1 = vlistInqTaxis(vlistID1);
@@ -318,18 +263,28 @@ void *Rhopot(void *argument)
 	  if ( varID == saoID ) streamReadRecord(streamID1, sao.ptr+offset, &(sao.nmiss));
 	}
 
-      calc_rhopot(gridsize, nlevel, pressure, tho, sao, rho); 
+      calc_adisit(gridsize, nlevel, pressure, tho, sao, tis); 
 
       for ( levelID = 0; levelID < nlevel; ++levelID )
 	{
 	  offset = gridsize*levelID;
-	  single = rho.ptr+offset;
+
+	  single = tis.ptr+offset;
+
+	  nmiss = 0;
+	  for ( i = 0; i < gridsize; ++i )
+	    if ( DBL_IS_EQUAL(single[i], tis.missval) ) nmiss++;
+ 
+	  streamDefRecord(streamID2, tisID2, levelID);
+	  streamWriteRecord(streamID2, single, nmiss);     
+
+	  single = sao.ptr+offset;
 
 	  nmiss = 0;
 	  for ( i = 0; i < gridsize; ++i )
-	    if ( DBL_IS_EQUAL(single[i], rho.missval) ) nmiss++;
+	    if ( DBL_IS_EQUAL(single[i], sao.missval) ) nmiss++;
  
-	  streamDefRecord(streamID2, 0, levelID);
+	  streamDefRecord(streamID2, saoID2, levelID);
 	  streamWriteRecord(streamID2, single, nmiss);     
 	}
 
@@ -342,7 +297,7 @@ void *Rhopot(void *argument)
   vlistDestroy(vlistID2);
 
   free(pressure);
-  free(rho.ptr);
+  free(tis.ptr);
   free(tho.ptr);
   free(sao.ptr);
 
diff --git a/src/Arith.c b/src/Arith.c
index 0aeafb0..b43503f 100644
--- a/src/Arith.c
+++ b/src/Arith.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Arithc.c b/src/Arithc.c
index e627ba1..fea20bb 100644
--- a/src/Arithc.c
+++ b/src/Arithc.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Arithdays.c b/src/Arithdays.c
index ba069dc..83558ea 100644
--- a/src/Arithdays.c
+++ b/src/Arithdays.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -143,8 +143,7 @@ void *Arithdays(void *argument)
 	}
 
       if ( cdoVerbose )
-	cdoPrint("calendar %d  year %d  month %d  result %g",
-		 calendar, year, month, rconst);
+	cdoPrint("calendar %d  year %d  month %d  result %g", calendar, year, month, rconst);
 
       for ( recID = 0; recID < nrecs; recID++ )
 	{
diff --git a/src/Arithlat.c b/src/Arithlat.c
index 5a2cc8d..45a88f7 100644
--- a/src/Arithlat.c
+++ b/src/Arithlat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/CDIread.c b/src/CDIread.c
index 75ef5cd..904b755 100644
--- a/src/CDIread.c
+++ b/src/CDIread.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/CDItest.c b/src/CDItest.c
index 2188ef7..84f8f67 100644
--- a/src/CDItest.c
+++ b/src/CDItest.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/CDIwrite.c b/src/CDIwrite.c
index a318928..590afed 100644
--- a/src/CDIwrite.c
+++ b/src/CDIwrite.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Cat.c b/src/Cat.c
index 62e5d08..e0424e0 100644
--- a/src/Cat.c
+++ b/src/Cat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Change.c b/src/Change.c
index d418005..4b81e11 100644
--- a/src/Change.c
+++ b/src/Change.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Change_e5slm.c b/src/Change_e5slm.c
index 78d8130..d0965bc 100644
--- a/src/Change_e5slm.c
+++ b/src/Change_e5slm.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Cloudlayer.c b/src/Cloudlayer.c
index eb44993..19be733 100644
--- a/src/Cloudlayer.c
+++ b/src/Cloudlayer.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Command.c b/src/Command.c
index 74b3462..0f3f01f 100644
--- a/src/Command.c
+++ b/src/Command.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Comp.c b/src/Comp.c
index d636426..8d4e199 100644
--- a/src/Comp.c
+++ b/src/Comp.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Compc.c b/src/Compc.c
index add89a3..4b8744a 100644
--- a/src/Compc.c
+++ b/src/Compc.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Complextorect.c b/src/Complextorect.c
index 4b7c014..20e3caf 100644
--- a/src/Complextorect.c
+++ b/src/Complextorect.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Cond.c b/src/Cond.c
index e3066e4..e2576d5 100644
--- a/src/Cond.c
+++ b/src/Cond.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Cond2.c b/src/Cond2.c
index 6f82f5f..b1ab0d0 100644
--- a/src/Cond2.c
+++ b/src/Cond2.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Condc.c b/src/Condc.c
index 7dc6ea5..b1ae7fe 100644
--- a/src/Condc.c
+++ b/src/Condc.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Consecstat.c b/src/Consecstat.c
index d8c954b..a6384c1 100644
--- a/src/Consecstat.c
+++ b/src/Consecstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -223,6 +223,7 @@ void *Consecstat (void *argument)
         break;
       default:
         printf (SWITCHWARN,__func__);
+        break;
     }
 
     for ( recID = 0; recID < nrecs; recID++ )
@@ -257,6 +258,7 @@ void *Consecstat (void *argument)
           break;
         default:
           printf (SWITCHWARN,__func__);
+          break;
       }
     }
     histvdate = vdate;
diff --git a/src/Copy.c b/src/Copy.c
index 90b7faa..a28d0be 100644
--- a/src/Copy.c
+++ b/src/Copy.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -30,7 +30,7 @@
 
 void *Copy(void *argument)
 {
-  int COPY, SELALL, SZIP;
+  int SELALL, SZIP;
   int operatorID;
   int streamID1, streamID2 = CDI_UNDEFID;
   int nrecs;
@@ -47,7 +47,7 @@ void *Copy(void *argument)
 
   cdoInitialize(argument);
 
-  COPY    = cdoOperatorAdd("copy",   0, 0, NULL);
+            cdoOperatorAdd("copy",   0, 0, NULL);
   SELALL  = cdoOperatorAdd("selall", 0, 0, NULL);
   SZIP    = cdoOperatorAdd("szip",   0, 0, NULL);
 
diff --git a/src/Deltime.c b/src/Deltime.c
index db8937d..ca5c490 100644
--- a/src/Deltime.c
+++ b/src/Deltime.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Derivepar.c b/src/Derivepar.c
index 03b688b..4a6a03f 100644
--- a/src/Derivepar.c
+++ b/src/Derivepar.c
@@ -154,10 +154,10 @@ void *Derivepar(void *argument)
   int vlistID1, vlistID2;
   int gridsize, ngp = 0;
   int recID, nrecs;
-  int i, offset, iv;
+  int i, offset;
   int tsID, varID, levelID;
   int nvars;
-  int zaxisID2, zaxisIDh = -1, nzaxis, surfaceID;
+  int zaxisIDh = -1, nzaxis;
   int ngrids, gridID = -1, zaxisID;
   int nlevel;
   int nvct;
@@ -170,7 +170,6 @@ void *Derivepar(void *argument)
   int taxisID1, taxisID2;
   int lhavevct;
   int nhlevf = 0;
-  double *lev2;
   double *vct = NULL;
   double *geop = NULL, *ps = NULL, *temp = NULL, *hum = NULL;
   // double *lwater = NULL, *iwater = NULL;
@@ -180,9 +179,6 @@ void *Derivepar(void *argument)
   double *array = NULL;
   double *half_press = NULL;
   double minval, maxval;
-  double missval = 0;
-  double cconst = 1.E-6;
-  const char *fname;
   int instNum, tableNum;
   int useTable;
 
diff --git a/src/Detrend.c b/src/Detrend.c
index 721efe6..5e20169 100644
--- a/src/Detrend.c
+++ b/src/Detrend.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Diff.c b/src/Diff.c
index c911326..350fb66 100644
--- a/src/Diff.c
+++ b/src/Diff.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -30,8 +30,9 @@
 
 void *Diff(void *argument)
 {
-  int DIFF, DIFF2, DIFFP, DIFFN, DIFFC, SDIFF;
+  int DIFF, DIFF2, DIFFP, DIFFN, DIFFC;
   int operatorID;
+  int lhead = TRUE;
   int i;
   int indg;
   int varID1, varID2, recID;
@@ -50,7 +51,7 @@ void *Diff(void *argument)
   int ndrec = 0, nd2rec = 0, ngrec = 0;
   char varname[CDI_MAX_NAME];
   char paramstr[32];
-  char vdatestr[32], vtimestr[32];	  
+  char vdatestr[32], vtimestr[32];
   double *array1, *array2;
   double absm, relm;
   double missval1, missval2;
@@ -62,7 +63,6 @@ void *Diff(void *argument)
   DIFFP = cdoOperatorAdd("diffp", 0, 0, NULL);
   DIFFN = cdoOperatorAdd("diffn", 0, 0, NULL);
   DIFFC = cdoOperatorAdd("diffc", 0, 0, NULL);
-  SDIFF = cdoOperatorAdd("sdiff", 0, 0, NULL);
 
   operatorID = cdoOperatorID();
 
@@ -79,27 +79,6 @@ void *Diff(void *argument)
   array1 = (double *) malloc(gridsize*sizeof(double));
   array2 = (double *) malloc(gridsize*sizeof(double));
 
-  if ( ! cdoSilentMode )
-    {
-      if ( operatorID != SDIFF )
-	{
-	  fprintf(stdout, "               Date     Time   Level Gridsize    Miss ");
-
-	  if ( operatorID == DIFF2 ) fprintf(stdout, "   Diff ");
-
-	  fprintf(stdout, ": S Z  Max_Absdiff Max_Reldiff");
-
-	  if ( operatorID == DIFFN )
-	    fprintf(stdout, " : Parameter name");
-	  else if ( operatorID == DIFF || operatorID == DIFF2 || operatorID == DIFFP )
-	    fprintf(stdout, " : Parameter ID");
-	  else if ( operatorID == DIFFC )
-	    fprintf(stdout, " : Code number");
-
-	  fprintf(stdout, "\n");
-	}
-    }
-
   indg = 0;
   tsID = 0;
   taxisID = vlistInqTaxis(vlistID1);
@@ -136,16 +115,6 @@ void *Diff(void *argument)
 
 	  cdiParamToString(param, paramstr, sizeof(paramstr));
 
-	  if ( ! cdoSilentMode )
-	    if ( operatorID != SDIFF )
-	      {
-		if ( operatorID == DIFFN ) vlistInqVarName(vlistID1, varID1, varname);
-		
-		fprintf(stdout, "%6d :%s %s ", indg, vdatestr, vtimestr);
-
-		fprintf(stdout, "%7g ", zaxisInqLevel(zaxisID, levelID));
-	      }
-
 	  streamReadRecord(streamID1, array1, &nmiss1);
 	  streamReadRecord(streamID2, array2, &nmiss2);
 
@@ -178,10 +147,36 @@ void *Diff(void *argument)
 		}
 	    }
 
-	  if ( ! cdoSilentMode )
+	  if ( ! cdoSilentMode || cdoVerbose )
 	    {
-	      if ( operatorID != SDIFF )
+	      if ( absm > 0 || relm > 0 || cdoVerbose )
 		{
+		  if ( lhead )
+		    {
+		      lhead = FALSE;
+
+		      fprintf(stdout, "               Date     Time   Level Gridsize    Miss ");
+			
+		      if ( operatorID == DIFF2 ) fprintf(stdout, "   Diff ");
+
+		      fprintf(stdout, ": S Z  Max_Absdiff Max_Reldiff");
+
+		      if ( operatorID == DIFFN )
+			fprintf(stdout, " : Parameter name");
+		      else if ( operatorID == DIFF || operatorID == DIFF2 || operatorID == DIFFP )
+			fprintf(stdout, " : Parameter ID");
+		      else if ( operatorID == DIFFC )
+			fprintf(stdout, " : Code number");
+
+		      fprintf(stdout, "\n");
+		    }
+
+		  if ( operatorID == DIFFN ) vlistInqVarName(vlistID1, varID1, varname);
+		
+		  fprintf(stdout, "%6d :%s %s ", indg, vdatestr, vtimestr);
+
+		  fprintf(stdout, "%7g ", zaxisInqLevel(zaxisID, levelID));
+
 		  fprintf(stdout, "%8d %7d ", gridsize, MAX(nmiss1, nmiss2));
 
 		  if ( operatorID == DIFF2 )  fprintf(stdout, "%7d ", ndiff);
@@ -195,7 +190,7 @@ void *Diff(void *argument)
 		    fprintf(stdout, " : %-11s", paramstr);
 		  else if ( operatorID == DIFFC )
 		    fprintf(stdout, " : %4d", code);
-
+		      
 		  fprintf(stdout, "\n");
 		}
 	    }
diff --git a/src/Duplicate.c b/src/Duplicate.c
index 8ef649f..08d55e5 100644
--- a/src/Duplicate.c
+++ b/src/Duplicate.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/EOFs.c b/src/EOFs.c
index 76fd4e7..b44a7ed 100644
--- a/src/EOFs.c
+++ b/src/EOFs.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Echam5ini.c b/src/Echam5ini.c
index 6d23869..be47bfe 100644
--- a/src/Echam5ini.c
+++ b/src/Echam5ini.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Enlarge.c b/src/Enlarge.c
index 781693c..a65ae6d 100644
--- a/src/Enlarge.c
+++ b/src/Enlarge.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Enlargegrid.c b/src/Enlargegrid.c
index 7d6b303..64db2cc 100644
--- a/src/Enlargegrid.c
+++ b/src/Enlargegrid.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Ensstat.c b/src/Ensstat.c
index 44fa0ee..8bac853 100644
--- a/src/Ensstat.c
+++ b/src/Ensstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -24,7 +24,9 @@
       Ensstat    ensmean         Ensemble mean
       Ensstat    ensavg          Ensemble average
       Ensstat    ensstd          Ensemble standard deviation
+      Ensstat    ensstd1         Ensemble standard deviation
       Ensstat    ensvar          Ensemble variance
+      Ensstat    ensvar1         Ensemble variance
       Ensstat    enspctl         Ensemble percentiles
 
       Ensstat    enscrps         Ensemble cumulative ranked probability score
@@ -70,9 +72,7 @@ void *Ensstat(void *argument)
     double *array;
   } ens_file_t;
   ens_file_t *ef = NULL;
-  /* RQ */
   int pn = 0;
-  /* QR */
 
   cdoInitialize(argument);
 
@@ -81,21 +81,17 @@ void *Ensstat(void *argument)
   cdoOperatorAdd("enssum",  func_sum,  0, NULL);
   cdoOperatorAdd("ensmean", func_mean, 0, NULL);
   cdoOperatorAdd("ensavg",  func_avg,  0, NULL);
-  cdoOperatorAdd("ensvar",  func_var,  0, NULL);
   cdoOperatorAdd("ensstd",  func_std,  0, NULL);
-  /* RQ */
+  cdoOperatorAdd("ensstd1", func_std1, 0, NULL);
+  cdoOperatorAdd("ensvar",  func_var,  0, NULL);
+  cdoOperatorAdd("ensvar1", func_var1, 0, NULL);
   cdoOperatorAdd("enspctl", func_pctl, 0, NULL);
-  /* QR */
-
-  /* >>> Cedrick Ansorge 18.10.2010 */
   cdoOperatorAdd("enscrps", func_crps, 0, NULL);
   cdoOperatorAdd("ensbrs",  func_brs,  0, NULL);
-  /* <<< Cedrick Ansorge 18.10.2010 */
 
   operatorID = cdoOperatorID();
   operfunc = cdoOperatorF1(operatorID);
 
-  /* RQ */
   if ( operfunc == func_pctl )
     {
       operatorInputArg("percentile number");
@@ -104,7 +100,6 @@ void *Ensstat(void *argument)
       if ( pn < 1 || pn > 99 )
         cdoAbort("Illegal argument: percentile number %d is not in the range 1..99!", pn);
     }
-  /* QR */
     
   nfiles = cdoStreamCnt() - 1;
 
@@ -222,12 +217,10 @@ void *Ensstat(void *argument)
 		    field[ompthID].nmiss++;
 		}
 
-	      /* RQ */
 	      if ( operfunc == func_pctl )
 	        array2[i] = fldpctl(field[ompthID], pn);
 	      else  
 	        array2[i] = fldfun(field[ompthID], operfunc);
-	      /* QR */
 
 	      if ( DBL_IS_EQUAL(array2[i], field[ompthID].missval) )
 		{
diff --git a/src/Ensstat3.c b/src/Ensstat3.c
index 8ee1828..33b1052 100644
--- a/src/Ensstat3.c
+++ b/src/Ensstat3.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -60,14 +60,14 @@ void *Ensstat3(void *argument)
   int nvars,nbins, nrecs = 0, nrecs0, nmiss, nens, nfiles;;
   int cum;
   int chksum;                  // for check of histogram population 
-  int levelID, varID, recID, tsID, binID = 0, ensID;
+  int levelID, varID, recID, tsID, binID = 0;
   int gridsize = 0;
   int gridID, gridID2;
   int have_miss = 0;
   int streamID = 0, streamID2 = 0;
   int vlistID, vlistID1, vlistID2;
   int taxisID1, taxisID2;
-  int zaxisID,zaxisID2;
+  int zaxisID2;
   int ompthID;
   int *varID2;
   int time_mode;
@@ -160,9 +160,9 @@ void *Ensstat3(void *argument)
   vlistID1 = ef[0].vlistID;
   vlistID2 = vlistCreate();
   nvars = vlistNvars(vlistID1);
-  varID2 = (int *) malloc( nvars*sizeof(int));
+  varID2 = (int *) malloc(nvars*sizeof(int));
 
-  levs = (double*) calloc ( nfiles, sizeof(double) );
+  levs = (double*) calloc (nfiles, sizeof(double) );
   zaxisID2 = zaxisCreate(ZAXIS_GENERIC, nfiles);
   for ( i=0; i<nfiles; i++ )
     levs[i] = i;
@@ -279,7 +279,7 @@ void *Ensstat3(void *argument)
 	{
 #if defined (_OPENMP)
 #pragma omp parallel for default(shared) private(fileID, streamID, nmiss) \
-  lastprivate(binID, varID, levelID)
+                                     lastprivate(varID, levelID)
 #endif
 	  for ( fileID = 0; fileID < nfiles; fileID++ )
 	    {
@@ -296,8 +296,9 @@ void *Ensstat3(void *argument)
 	  if ( datafunc == TIME && operfunc == func_rank) 
 	    for ( binID=0;binID<nfiles;binID++ )
 	      array2[binID][0] = 0;
+
 #if defined (_OPENMP)
-#pragma omp parallel for default(shared) private(i, ompthID, fileID)
+#pragma omp parallel for default(shared) private(i, binID, ompthID, fileID)
 #endif
 	  for ( i = 0; i < gridsize; i++ )
 	    {
@@ -329,10 +330,13 @@ void *Ensstat3(void *argument)
 		      /* ****************/
 		      /* RANK HISTOGRAM */
 		      /* ************** */
-		      //		      for ( j=0; j<nfiles; j++ )
-		      //			fprintf(stderr,"%5.2g ",field[ompthID].ptr[j]);
-		      //		      binID = (int) fldfun(field[ompthID], operfunc);
-		      //		      fprintf(stderr,"-->%i\n",binID);
+		      // for ( j=0; j<nfiles; j++ )
+		      //   fprintf(stderr,"%5.2g ",field[ompthID].ptr[j]);
+#if defined (_OPENMP)
+#pragma omp critical
+#endif
+		      binID = (int) fldfun(field[ompthID], operfunc);
+		      // fprintf(stderr,"-->%i\n",binID);
 		      
 		      if ( datafunc == SPACE && ! have_miss) 
 			array2[binID][i]++;
@@ -405,7 +409,7 @@ void *Ensstat3(void *argument)
 		streamDefRecord(streamID2, varID2[varID], binID);
 		streamWriteRecord(streamID2,&val, nmiss);
 	      }
-	      fprintf(stderr,"\n");
+	      //fprintf(stderr,"\n");
 	    }
 	  else if ( operfunc == func_roc ) 
 	    {
@@ -440,12 +444,23 @@ void *Ensstat3(void *argument)
 
 
   if ( operfunc == func_rank )
-    for ( binID=0; binID<nfiles; binID++ ) {
-      double *tmpdoub = (double *)malloc (gridsize*sizeof(double));
-      for(i=0; i<gridsize; i++ )
-	tmpdoub[i] = (double) array2[binID][i];
-      streamDefRecord(streamID2,varID2[varID],binID);
-      streamWriteRecord(streamID2,tmpdoub,nmiss);
+    {
+      double *tmpdoub;
+      int osize = gridsize;
+
+      if ( datafunc == TIME ) osize = 1;
+      tmpdoub = (double *) malloc(osize*sizeof(double));
+
+      for ( binID = 0; binID < nfiles; binID++ )
+	{
+	  for ( i = 0; i < osize; i++ )
+	    tmpdoub[i] = (double) array2[binID][i];
+
+	  streamDefRecord(streamID2, varID2[varID], binID);
+	  streamWriteRecord(streamID2, tmpdoub, nmiss);
+	}
+
+      free(tmpdoub);
     }
   else if ( operfunc == func_roc ) {
     fprintf(stdout, "#             :     TP     FP     FN     TN         TPR        FPR\n");
diff --git a/src/Ensval.c b/src/Ensval.c
index a6eb3e0..0f0a87f 100644
--- a/src/Ensval.c
+++ b/src/Ensval.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Eof3d.c b/src/Eof3d.c
index f6ecb15..e606793 100644
--- a/src/Eof3d.c
+++ b/src/Eof3d.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Eofcoeff.c b/src/Eofcoeff.c
index 38abe24..5044909 100644
--- a/src/Eofcoeff.c
+++ b/src/Eofcoeff.c
@@ -2,7 +2,7 @@
  This file is part of CDO. CDO is a collection of Operators to
  manipulate and analyse Climate model Data.
  
- Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+ Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
  See COPYING file for copying and redistribution conditions.
  
  This program is free software; you can redistribute it and/or modify
diff --git a/src/Eofcoeff3d.c b/src/Eofcoeff3d.c
index 2d8d091..6944c33 100644
--- a/src/Eofcoeff3d.c
+++ b/src/Eofcoeff3d.c
@@ -2,7 +2,7 @@
  This file is part of CDO. CDO is a collection of Operators to
  manipulate and analyse Climate model Data.
  
- Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+ Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
  See COPYING file for copying and redistribution conditions.
  
  This program is free software; you can redistribute it and/or modify
diff --git a/src/Exprf.c b/src/Exprf.c
index 9691ff7..36105b5 100644
--- a/src/Exprf.c
+++ b/src/Exprf.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/FC.c b/src/FC.c
index 8301590..3eab604 100644
--- a/src/FC.c
+++ b/src/FC.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Filedes.c b/src/Filedes.c
index 3941727..fa5bb9b 100644
--- a/src/Filedes.c
+++ b/src/Filedes.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -239,6 +239,7 @@ void filedes(int streamID)
       break;
     default:
       printf("  unsupported filetype %d\n" , filetype);
+      break;
     }
   
   printf("\n");
diff --git a/src/Fillmiss.c b/src/Fillmiss.c
index 25030d7..2f9ba5a 100644
--- a/src/Fillmiss.c
+++ b/src/Fillmiss.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Filter.c b/src/Filter.c
index c7bea04..4ac3c87 100644
--- a/src/Filter.c
+++ b/src/Filter.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -46,7 +46,7 @@ void fft2(double *real, double *imag, int n, int isign)
   int nn, mmax, m, j, istep, i;
   double wtemp, wr, wpr, wpi, wi, theta, tempr, tempi, tmp;   
   
-  if ( n < 2 || n&(n-1) ) printf("n must be power of 2\n");
+  if ( n < 2 || (n&(n-1)) ) printf("n must be power of 2\n");
   nn = n << 1;
   j = 1;
   
diff --git a/src/Fldrms.c b/src/Fldrms.c
index e7ab539..c5339a2 100644
--- a/src/Fldrms.c
+++ b/src/Fldrms.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Fldstat.c b/src/Fldstat.c
index 056603c..188049c 100644
--- a/src/Fldstat.c
+++ b/src/Fldstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -24,7 +24,9 @@
       Fldstat    fldmean         Field mean
       Fldstat    fldavg          Field average
       Fldstat    fldstd          Field standard deviation
+      Fldstat    fldstd1         Field standard deviation
       Fldstat    fldvar          Field variance
+      Fldstat    fldvar1         Field variance
       Fldstat    fldpctl         Field percentiles
 */
 
@@ -101,9 +103,7 @@ void *Fldstat(void *argument)
   double sglval;
   field_t field;
   int taxisID1, taxisID2;
-  /* RQ */
   int pn = 0;
-  /* QR */
 
   cdoInitialize(argument);
 
@@ -112,16 +112,15 @@ void *Fldstat(void *argument)
   cdoOperatorAdd("fldsum",  func_sum,  0, NULL);
   cdoOperatorAdd("fldmean", func_mean, 0, NULL);
   cdoOperatorAdd("fldavg",  func_avg,  0, NULL);
-  cdoOperatorAdd("fldvar",  func_var,  0, NULL);
   cdoOperatorAdd("fldstd",  func_std,  0, NULL);
-  /* RQ */
+  cdoOperatorAdd("fldstd1", func_std1, 0, NULL);
+  cdoOperatorAdd("fldvar",  func_var,  0, NULL);
+  cdoOperatorAdd("fldvar1", func_var1, 0, NULL);
   cdoOperatorAdd("fldpctl", func_pctl, 0, NULL);
-  /* QR */
 
   operatorID = cdoOperatorID();
   operfunc = cdoOperatorF1(operatorID);
 
-  /* RQ */
   if ( operfunc == func_pctl )
     {
       operatorInputArg("percentile number");
@@ -130,10 +129,10 @@ void *Fldstat(void *argument)
       if ( pn < 1 || pn > 99 )
         cdoAbort("Illegal argument: percentile number %d is not in the range 1..99!", pn);
     }
-  /* QR */
 
   if ( operfunc == func_mean || operfunc == func_avg ||
-       operfunc == func_var  || operfunc == func_std )
+       operfunc == func_var  || operfunc == func_std ||
+       operfunc == func_var1 || operfunc == func_std1 )
     needWeights = TRUE;
 
   streamID1 = streamOpenRead(cdoStreamName(0));
diff --git a/src/Fldstat2.c b/src/Fldstat2.c
index cc6276a..9af8566 100644
--- a/src/Fldstat2.c
+++ b/src/Fldstat2.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Fourier.c b/src/Fourier.c
index 4c6b559..b74794d 100644
--- a/src/Fourier.c
+++ b/src/Fourier.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Gather.c b/src/Gather.c
index 1411539..b372ad0 100644
--- a/src/Gather.c
+++ b/src/Gather.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Gengrid.c b/src/Gengrid.c
index 7cf9004..fc3d6ff 100644
--- a/src/Gengrid.c
+++ b/src/Gengrid.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Gradsdes.c b/src/Gradsdes.c
index 6ab2506..3a43eba 100644
--- a/src/Gradsdes.c
+++ b/src/Gradsdes.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Gridboxstat.c b/src/Gridboxstat.c
index 642bd46..3c8e55c 100644
--- a/src/Gridboxstat.c
+++ b/src/Gridboxstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Gridcell.c b/src/Gridcell.c
index 5c937f4..2d0f0bb 100644
--- a/src/Gridcell.c
+++ b/src/Gridcell.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -99,6 +99,7 @@ void *Gridcell(void *argument)
 
   vlistID2 = vlistCreate();
   varID    = vlistDefVar(vlistID2, gridID, zaxisID, TSTEP_CONSTANT);
+  vlistDefNtsteps(vlistID2, 0);
 
   if ( operatorID == GRIDAREA )
     {
@@ -106,10 +107,12 @@ void *Gridcell(void *argument)
       vlistDefVarStdname(vlistID2, varID, "area");
       vlistDefVarLongname(vlistID2, varID, "area of grid cell");
       vlistDefVarUnits(vlistID2, varID, "m2");
+      vlistDefVarDatatype(vlistID2, varID, DATATYPE_FLT64);
     }
   else if ( operatorID == GRIDWGTS )
     {
       vlistDefVarName(vlistID2, varID, "cell_weights");
+      vlistDefVarDatatype(vlistID2, varID, DATATYPE_FLT64);
     }
   else if ( operatorID == GRIDMASK )
     {
@@ -315,10 +318,8 @@ void *Gridcell(void *argument)
   varID   = 0;
   levelID = 0;
   streamDefRecord(streamID2, varID, levelID);
-
   streamWriteRecord(streamID2, array, 0);
 
-
   streamClose(streamID2);
   streamClose(streamID1);
 
diff --git a/src/Harmonic.c b/src/Harmonic.c
index 88ddad1..f879490 100644
--- a/src/Harmonic.c
+++ b/src/Harmonic.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Histogram.c b/src/Histogram.c
index 3b7ba62..2179c14 100644
--- a/src/Histogram.c
+++ b/src/Histogram.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Importamsr.c b/src/Importamsr.c
index 62f2f7a..89c8f40 100644
--- a/src/Importamsr.c
+++ b/src/Importamsr.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Importbinary.c b/src/Importbinary.c
index 04b96a4..f6bf1c8 100644
--- a/src/Importbinary.c
+++ b/src/Importbinary.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Importcmsaf.c b/src/Importcmsaf.c
index c5a3fa5..ab2b734 100644
--- a/src/Importcmsaf.c
+++ b/src/Importcmsaf.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -66,8 +66,9 @@ typedef struct {
   int lmetadata;
   dset_obj_t obj[MAX_DSETS];
 }
-dsets_t;
+datasets_t;
 
+#define  NINT(x)   ((x) < 0 ? (int)((x)-0.5) : (int)((x)+0.5))
 
 #if  defined  (HAVE_LIBHDF5)
 static
@@ -96,10 +97,6 @@ void print_filter(hid_t dset_id, char *varname)
 
   H5Pclose(plist);
 }
-#endif
-
-
-#define  NINT(x)   ((x) < 0 ? (int)((x)-0.5) : (int)((x)+0.5))
 
 static
 void get_grid_info(double c0, double re, int *nrxp, int *nryp,
@@ -352,7 +349,6 @@ int scan_pcs_def(char *pcs_def, char proj[128], double *a, double *lon0, double
   return (nfound);
 }
 
-#if  defined  (HAVE_LIBHDF5)
 static
 int read_geolocation(hid_t loc_id, int nx, int ny, int lprojtype)
 {
@@ -617,9 +613,7 @@ int read_geolocation(hid_t loc_id, int nx, int ny, int lprojtype)
 
   return (gridID);
 }
-#endif
 
-#if  defined  (HAVE_LIBHDF5)
 static
 int read_region(hid_t loc_id, int nx, int ny)
 {
@@ -759,9 +753,7 @@ int read_region(hid_t loc_id, int nx, int ny)
 
   return (gridID);
 }
-#endif
 
-#if  defined  (HAVE_LIBHDF5)
 static
 void read_dataset(hid_t loc_id, const char *name, void *opdata)
 {
@@ -866,7 +858,7 @@ void read_dataset(hid_t loc_id, const char *name, void *opdata)
 
 
   len = (int) strlen(varname);
-  if ( ((dsets_t *) opdata)->mergelevel )
+  if ( ((datasets_t *) opdata)->mergelevel )
     if ( isdigit(varname[len-1]) && memcmp(varname, "Data", 4) != 0 )
       {
 	if ( nt > 1 ) cdoAbort("Combination of nlevel > 1 and ntime > 1 not implemented!");
@@ -878,15 +870,15 @@ void read_dataset(hid_t loc_id, const char *name, void *opdata)
   gridsize = nx*ny;
 
   if ( nz == 1 )
-    nset = ((dsets_t *) opdata)->nsets;
+    nset = ((datasets_t *) opdata)->nsets;
   else
     {
-      for ( nset = 0; nset < ((dsets_t *) opdata)->nsets; ++nset )
+      for ( nset = 0; nset < ((datasets_t *) opdata)->nsets; ++nset )
 	{
-	  if ( strcmp(varname, ((dsets_t *) opdata)->obj[nset].name) == 0 ) break;
+	  if ( strcmp(varname, ((datasets_t *) opdata)->obj[nset].name) == 0 ) break;
 	}
 
-      if ( nset >= ((dsets_t *) opdata)->nsets )
+      if ( nset >= ((datasets_t *) opdata)->nsets )
 	cdoAbort("3D var %s not found!", varname);
     }
 
@@ -1038,28 +1030,28 @@ void read_dataset(hid_t loc_id, const char *name, void *opdata)
 	  else if ( strcmp(attname, "description") == 0 )
 	    {
 	      H5Aread(attr, atype_mem, attstring);
-	      if ( ((dsets_t *) opdata)->obj[nset].description )
-		free(((dsets_t *) opdata)->obj[nset].description);
-	      ((dsets_t *) opdata)->obj[nset].description = strdup(attstring);
+	      if ( ((datasets_t *) opdata)->obj[nset].description )
+		free(((datasets_t *) opdata)->obj[nset].description);
+	      ((datasets_t *) opdata)->obj[nset].description = strdup(attstring);
 	    }
 	  else if ( strcmp(attname, "title") == 0 )
 	    {
 	      H5Aread(attr, atype_mem, attstring);
-	      if ( ((dsets_t *) opdata)->obj[nset].title )
-		free(((dsets_t *) opdata)->obj[nset].title);
-	      ((dsets_t *) opdata)->obj[nset].title = strdup(attstring);
+	      if ( ((datasets_t *) opdata)->obj[nset].title )
+		free(((datasets_t *) opdata)->obj[nset].title);
+	      ((datasets_t *) opdata)->obj[nset].title = strdup(attstring);
 	    }
 	  else if ( strcmp(attname, "time") == 0 )
 	    {
 	      H5Aread(attr, atype_mem, attstring);
-	      if ( ((dsets_t *) opdata)->obj[nset].time )
-		free(((dsets_t *) opdata)->obj[nset].time);
-	      ((dsets_t *) opdata)->obj[nset].time = strdup(attstring);
+	      if ( ((datasets_t *) opdata)->obj[nset].time )
+		free(((datasets_t *) opdata)->obj[nset].time);
+	      ((datasets_t *) opdata)->obj[nset].time = strdup(attstring);
 	    }
 	  else if ( strcmp(attname, "unit") == 0 )
 	    {
 	      H5Aread(attr, atype_mem, attstring);
-	      ((dsets_t *) opdata)->obj[nset].units = strdup(attstring);
+	      ((datasets_t *) opdata)->obj[nset].units = strdup(attstring);
 	    }
 
 	  H5Tclose(atype_mem);
@@ -1068,9 +1060,9 @@ void read_dataset(hid_t loc_id, const char *name, void *opdata)
 	}
       
       offset = gridsize*(nz-1);
-      array  = ((dsets_t *) opdata)->obj[nset].array;
+      array  = ((datasets_t *) opdata)->obj[nset].array;
       array  = (double *) realloc(array, gridsize*nz*nt*sizeof(double));
-      ((dsets_t *) opdata)->obj[nset].array    = array;
+      ((datasets_t *) opdata)->obj[nset].array    = array;
       array  = array+offset;
 
       if ( ftype )
@@ -1104,29 +1096,29 @@ void read_dataset(hid_t loc_id, const char *name, void *opdata)
 	  free(iarray);
 	}
 
-      ((dsets_t *) opdata)->obj[nset].name     = strdup(varname);
-      ((dsets_t *) opdata)->obj[nset].nx       = nx;
-      ((dsets_t *) opdata)->obj[nset].ny       = ny;
-      ((dsets_t *) opdata)->obj[nset].nz       = nz;
-      ((dsets_t *) opdata)->obj[nset].nt       = nt;
-      ((dsets_t *) opdata)->obj[nset].gridsize = gridsize;
+      ((datasets_t *) opdata)->obj[nset].name     = strdup(varname);
+      ((datasets_t *) opdata)->obj[nset].nx       = nx;
+      ((datasets_t *) opdata)->obj[nset].ny       = ny;
+      ((datasets_t *) opdata)->obj[nset].nz       = nz;
+      ((datasets_t *) opdata)->obj[nset].nt       = nt;
+      ((datasets_t *) opdata)->obj[nset].gridsize = gridsize;
 
       if ( nz > 1 )
 	{
-	  if ( ((dsets_t *) opdata)->obj[nset].dtype != dtype )
+	  if ( ((datasets_t *) opdata)->obj[nset].dtype != dtype )
 	    cdoWarning("Data type changes over levels!");
 
-	  if ( laddoffset && !DBL_IS_EQUAL(((dsets_t *) opdata)->obj[nset].offset, addoffset) )
+	  if ( laddoffset && !DBL_IS_EQUAL(((datasets_t *) opdata)->obj[nset].offset, addoffset) )
 	    cdoWarning("Offset changes over levels!");
 
-	  if ( lscalefactor && !DBL_IS_EQUAL(((dsets_t *) opdata)->obj[nset].scale, scalefactor) )
+	  if ( lscalefactor && !DBL_IS_EQUAL(((datasets_t *) opdata)->obj[nset].scale, scalefactor) )
 	    cdoWarning("Scalefactor changes over levels!");
 
-	  if ( lmissval && !DBL_IS_EQUAL(((dsets_t *) opdata)->obj[nset].missval, missval) )
+	  if ( lmissval && !DBL_IS_EQUAL(((datasets_t *) opdata)->obj[nset].missval, missval) )
 	    cdoWarning("Missing value changes over levels!");	       
 	}
 
-      if ( nz == 1 ) ((dsets_t *) opdata)->nsets++;
+      if ( nz == 1 ) ((datasets_t *) opdata)->nsets++;
 
       mask = (short *) malloc(gridsize*nt*sizeof(short));
       memset(mask, 0, gridsize*nt*sizeof(short));
@@ -1212,13 +1204,13 @@ void read_dataset(hid_t loc_id, const char *name, void *opdata)
 	    }
 	}
 
-      ((dsets_t *) opdata)->obj[nset].dtype    = dtype;
-      ((dsets_t *) opdata)->obj[nset].loffset  = laddoffset;
-      ((dsets_t *) opdata)->obj[nset].lscale   = lscalefactor;
-      ((dsets_t *) opdata)->obj[nset].lmissval = lmissval;
-      ((dsets_t *) opdata)->obj[nset].offset   = addoffset;
-      ((dsets_t *) opdata)->obj[nset].scale    = scalefactor;
-      ((dsets_t *) opdata)->obj[nset].missval  = missval;
+      ((datasets_t *) opdata)->obj[nset].dtype    = dtype;
+      ((datasets_t *) opdata)->obj[nset].loffset  = laddoffset;
+      ((datasets_t *) opdata)->obj[nset].lscale   = lscalefactor;
+      ((datasets_t *) opdata)->obj[nset].lmissval = lmissval;
+      ((datasets_t *) opdata)->obj[nset].offset   = addoffset;
+      ((datasets_t *) opdata)->obj[nset].scale    = scalefactor;
+      ((datasets_t *) opdata)->obj[nset].missval  = missval;
 
       free(mask); 
       mask = NULL;
@@ -1236,19 +1228,13 @@ void read_dataset(hid_t loc_id, const char *name, void *opdata)
   H5Dclose(dset_id);
   H5Tclose(type_id);
 }
-#endif
 
-#if  defined  (HAVE_LIBHDF5)
 static herr_t
 obj_info(hid_t loc_id, const char *name, void *opdata)
 {
   H5G_obj_t obj_type;
   H5G_stat_t statbuf;
 
-  /* avoid compiler warnings */
-  loc_id = loc_id;
-  opdata = opdata;
-
   H5Gget_objinfo(loc_id, name, FALSE, &statbuf);
 
   obj_type = statbuf.type;
@@ -1258,16 +1244,16 @@ obj_info(hid_t loc_id, const char *name, void *opdata)
     if ( cdoVerbose ) cdoPrint(" Object with name %s is a group", name);
     if ( strcmp(name, "Data") == 0 )
       {
-	((dsets_t *) opdata)->mergelevel = TRUE;	
+	((datasets_t *) opdata)->mergelevel = TRUE;	
 	H5Giterate(loc_id, name, NULL, obj_info, opdata);
       }
     else if ( strcmp(name, "Geolocation") == 0 )
       {
-	((dsets_t *) opdata)->lgeoloc = TRUE;
+	((datasets_t *) opdata)->lgeoloc = TRUE;
       }
     else if ( strcmp(name, "Metadata") == 0 )
       {
-	((dsets_t *) opdata)->lmetadata = TRUE;
+	((datasets_t *) opdata)->lmetadata = TRUE;
       }
     break;
   case H5G_DATASET: 
@@ -1279,7 +1265,7 @@ obj_info(hid_t loc_id, const char *name, void *opdata)
     /*else if ( strstr(name, "egion") ) */
     else if ( strcmp(name, "region") == 0 )
       {
-	((dsets_t *) opdata)->lregion = TRUE;
+	((datasets_t *) opdata)->lregion = TRUE;
       }
     else
       {
@@ -1291,19 +1277,17 @@ obj_info(hid_t loc_id, const char *name, void *opdata)
     if ( cdoVerbose ) cdoPrint(" Object with name %s is a named datatype", name);
     if ( strcmp(name, "ProjType") == 0 )
       {
-	((dsets_t *) opdata)->lprojtype = TRUE;
+	((datasets_t *) opdata)->lprojtype = TRUE;
       }
     break;
   default:
     cdoAbort(" Unable to identify an object %s", name);
+    break;
   }
 
   return 0;
 }
-#endif
 
-
-#if  defined  (HAVE_LIBHDF5)
 static
 void get_global_att(hid_t file_id, const char *obj_path, int vlistID)
 {
@@ -1357,7 +1341,6 @@ void get_global_att(hid_t file_id, const char *obj_path, int vlistID)
   if ( grp_id >= 0 ) H5Gclose(grp_id);	
 
 }
-#endif
 
 static
 int get_vdate(int vlistID)
@@ -1391,7 +1374,7 @@ int get_vdate(int vlistID)
 }
 
 static
-void dsets_init(dsets_t *dsets)
+void dsets_init(datasets_t *dsets)
 {
   int i;
 
@@ -1420,7 +1403,7 @@ void dsets_init(dsets_t *dsets)
       dsets->obj[i].array       = NULL;   
     }
 }
-
+#endif
 
 void *Importcmsaf(void *argument)
 {
@@ -1436,7 +1419,7 @@ void *Importcmsaf(void *argument)
   double missval, minval, maxval;
   hid_t	  file_id;	/* HDF5 File ID	        	*/
   herr_t  status;	/* Generic return value		*/
-  dsets_t dsets;
+  datasets_t dsets;
   int vdate, vtime;
   int *vtimes = NULL;
 #endif
diff --git a/src/Importobs.c b/src/Importobs.c
index 232fdb4..13a3012 100644
--- a/src/Importobs.c
+++ b/src/Importobs.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Info.c b/src/Info.c
index 403b6d9..3bb7a45 100644
--- a/src/Info.c
+++ b/src/Info.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Input.c b/src/Input.c
index 5fc4639..49d89e2 100644
--- a/src/Input.c
+++ b/src/Input.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Intgrid.c b/src/Intgrid.c
index 2673fcf..d9d4e16 100644
--- a/src/Intgrid.c
+++ b/src/Intgrid.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Intgridtraj.c b/src/Intgridtraj.c
index 081442f..ea84450 100644
--- a/src/Intgridtraj.c
+++ b/src/Intgridtraj.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Intlevel.c b/src/Intlevel.c
index 28fb303..914b427 100644
--- a/src/Intlevel.c
+++ b/src/Intlevel.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Intlevel3d.c b/src/Intlevel3d.c
index 2b4ffaf..96b4658 100644
--- a/src/Intlevel3d.c
+++ b/src/Intlevel3d.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Intntime.c b/src/Intntime.c
index a1c624e..b1356fa 100644
--- a/src/Intntime.c
+++ b/src/Intntime.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Inttime.c b/src/Inttime.c
index 98bf623..a5462f7 100644
--- a/src/Inttime.c
+++ b/src/Inttime.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Intyear.c b/src/Intyear.c
index b1c0b15..37f6f27 100644
--- a/src/Intyear.c
+++ b/src/Intyear.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Invert.c b/src/Invert.c
index 24f7c6b..534bad4 100644
--- a/src/Invert.c
+++ b/src/Invert.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Invertlev.c b/src/Invertlev.c
index ab85616..c645f1f 100644
--- a/src/Invertlev.c
+++ b/src/Invertlev.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Isosurface.c b/src/Isosurface.c
index 9e181c6..2ad316c 100644
--- a/src/Isosurface.c
+++ b/src/Isosurface.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Kvl.c b/src/Kvl.c
index 8e253f6..11fce76 100644
--- a/src/Kvl.c
+++ b/src/Kvl.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Log.c b/src/Log.c
index ce4dfd9..4f299a9 100644
--- a/src/Log.c
+++ b/src/Log.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Maggraph.c b/src/Maggraph.c
index a43307d..a788e18 100644
--- a/src/Maggraph.c
+++ b/src/Maggraph.c
@@ -2,6 +2,8 @@
 #  include "config.h" /* HAVE_LIBMAGICS */
 #endif
 
+#include<limits.h>  /* TEMPORARY FIX, UNTIL NEXT MAGICS LIBRARY RELEASE */ 
+
 #include <cdi.h>
 #include "cdo.h"
 #include "cdo_int.h"
@@ -585,6 +587,12 @@ void maggraph(const char *plotfile, const char *varname,const char *varunits, lo
 	mag_set1c("graph_curve_date_x_values",(const char**)date_time_str[0], ntime_steps);
       else
 	mag_set1c("graph_curve_date_x_values",(const char**)date_time_str[i], nts[i]);
+
+      /* TEMPORARY FIX, UNITL NEW MAGICS LIBRARY RELEASE *  begin**/
+      mag_setr("graph_x_suppress_below",LLONG_MIN);
+      mag_setr("graph_x_suppress_above",LLONG_MAX);
+      /* TEMPORARY FIX, UNITL NEW MAGICS LIBRARY RELEASE *  end  **/
+
       mag_set1r("graph_curve_y_values", datatab[i], nts[i]);
       mag_graph ();
     }
@@ -595,6 +603,12 @@ void maggraph(const char *plotfile, const char *varname,const char *varunits, lo
       sprintf(legend_text_data, "%s","Obsv" );
       mag_setc("legend_user_text", legend_text_data);
       mag_set1c("graph_curve_date_x_values",(const char**)date_time_str[0], nts[0]);
+
+      /* TEMPORARY FIX, UNITL NEW MAGICS LIBRARY RELEASE *  begin**/
+      mag_setr("graph_x_suppress_below",LLONG_MIN);
+      mag_setr("graph_x_suppress_above",LLONG_MAX);
+      /* TEMPORARY FIX, UNITL NEW MAGICS LIBRARY RELEASE *  end  **/
+
       mag_set1r("graph_curve_y_values", datatab[0], nts[0]);
       mag_setc("graph_line_style", "dot" );
       mag_seti("graph_line_thickness", 10 );
@@ -613,6 +627,12 @@ void maggraph(const char *plotfile, const char *varname,const char *varunits, lo
       mag_setc("graph_line_colour", "grey" );
       mag_setc("graph_line_style", "dash" );
       mag_set1c("graph_curve_date_x_values", (const char**)date_time_str[0], ntime_steps);
+
+      /* TEMPORARY FIX, UNITL NEW MAGICS LIBRARY RELEASE *  begin**/
+      mag_setr("graph_x_suppress_below",LLONG_MIN);
+      mag_setr("graph_x_suppress_above",LLONG_MAX);
+      /* TEMPORARY FIX, UNITL NEW MAGICS LIBRARY RELEASE *  end  **/
+
       mag_set1r("graph_curve_y_values",mean_val, ntime_steps);
       sprintf(legend_text_data, "Mean");
       mag_setc("legend_user_text", legend_text_data);
@@ -630,6 +650,12 @@ void maggraph(const char *plotfile, const char *varname,const char *varunits, lo
       mag_setc("graph_shade_colour", "grey");
       sprintf(legend_text_data, "%dSigma", num_sigma);
       mag_setc("legend_user_text", legend_text_data);
+
+      /* TEMPORARY FIX, UNITL NEW MAGICS LIBRARY RELEASE *  begin**/
+      mag_setr("graph_x_suppress_below",LLONG_MIN);
+      mag_setr("graph_x_suppress_above",LLONG_MAX);
+      /* TEMPORARY FIX, UNITL NEW MAGICS LIBRARY RELEASE *  end  **/
+
       mag_graph ();
     }
   
diff --git a/src/Magplot.c b/src/Magplot.c
index 116920e..d38d50e 100644
--- a/src/Magplot.c
+++ b/src/Magplot.c
@@ -65,7 +65,7 @@ int STYLE_COUNT = sizeof( STYLE_TABLE )/ sizeof( char *);
 char *DEVICE_TABLE[] = { "PS","EPS","PDF","PNG","GIF","GIF_ANIMATION","JPEG","SVG","KML"};
 int DEVICE_COUNT = sizeof( DEVICE_TABLE )/ sizeof( char *);
 
-int ANIM_FLAG = 0, STEP_FREQ = 1;
+int ANIM_FLAG = 0, STEP_FREQ = 0; /* '0' for static images like jpeg,ps, etc.. , '1' for animation formats */
 
 
 int checkcolour( char *colour_in );
@@ -109,152 +109,57 @@ void magplot( const char *plotfile, int operatorID, const char *varname, long nl
       for( i = 0; i< nparam; i++ )
 	fprintf(stderr, "Param %s\n", params[i]);
       fflush( stderr );
-    }
   
-  for( i = 0; i < nparam; ++i )
-    {
-      split_str_count = 0;
-      sep_char = "=";
-      split_str_count = StringSplitWithSeperator( params[i], sep_char, &split_str );
+      for( i = 0; i < nparam; ++i )
+        {
+           split_str_count = 0;
+           sep_char = "=";
+           split_str_count = StringSplitWithSeperator( params[i], sep_char, &split_str );
 	
-      if( !strcmp( split_str[0],"min" ) )
-	{
-	  YMIN = atof( split_str[1] );
-	  if( DBG )
-	    fprintf(stderr," Min Val %g\n",YMIN );
-	}
+           if( !strcmp( split_str[0],"min" ) )
+	     fprintf(stderr," Min Val %g\n",YMIN );
 	
-      if( !strcmp( split_str[0],"max" ) )
-	{
-	  YMAX = atof( split_str[1] );
-	  if( DBG )
-	    fprintf(stderr,"Max Val %g\n",YMAX );
-	}
+           if( !strcmp( split_str[0],"max" ) )
+	     fprintf(stderr,"Max Val %g\n",YMAX );
 	
-      if( !strcmp( split_str[0],"resolution" ) )
-	{
-	  RESOLUTION = atoi( split_str[1] );
-	  if( DBG )
-	    fprintf( stderr,"RESOLUTION %g\n",RESOLUTION );
-	}	
+           if( !strcmp( split_str[0],"resolution" ) )
+	     fprintf( stderr,"RESOLUTION %g\n",RESOLUTION );
 	
-      if( !strcmp( split_str[0],"colour" ) ) 
-	{  
-	  temp_str = strdup( split_str[1] );  
-	  if( !isRGB )
-	    StrToLowerCase( temp_str );
-	  else
-	    {
-	      StrToUpperCase( temp_str );
-	      StrReplaceChar( temp_str, orig_char, rep_char ); /* replace ';' in RGB format to ',' */
-	    }
-          COLOUR = temp_str;
-	  if( DBG )
-	    fprintf(stderr,"COLOUR %s\n",COLOUR );
-	}
+           if( !strcmp( split_str[0],"colour" ) ) 
+	     fprintf(stderr,"COLOUR %s\n",COLOUR );
 	
-      if( !strcmp( split_str[0],"colour_min" ) ) 
-	{  
-	  temp_str = strdup( split_str[1] );    
-          if( !isRGB )
-	    StrToLowerCase( temp_str );
-	  else
-	    {
-	      StrToUpperCase( temp_str );
-	      StrReplaceChar( temp_str, orig_char, rep_char ); /* replace ';' in RGB format to ',' */
-	    }
-	  COLOUR_MIN = temp_str;
-	  if( DBG )
-	    fprintf(stderr,"COLOUR %s\n",COLOUR_MIN );
-	}
+           if( !strcmp( split_str[0],"colour_min" ) ) 
+	     fprintf(stderr,"COLOUR %s\n",COLOUR_MIN );
 	
-      if( !strcmp( split_str[0],"colour_max" ) ) 
-	{  
-	  temp_str = strdup( split_str[1] );    
-          if( !isRGB )
-	    StrToLowerCase( temp_str );
-	  else
-	    {
-	      StrToUpperCase( temp_str );
-	      StrReplaceChar( temp_str, orig_char, rep_char ); /* replace ';' in RGB format to ',' */
-	    }
-	  COLOUR_MAX = temp_str;
-	  if( DBG )
-	    fprintf(stderr,"COLOUR %s\n",COLOUR_MAX );
-	}			
+           if( !strcmp( split_str[0],"colour_max" ) ) 
+	     fprintf(stderr,"COLOUR %s\n",COLOUR_MAX );
 	
-      if( !strcmp( split_str[0],"interval" ) )
-	{
-	  INTERVAL = atof( split_str[1] );
-	  
-	  if( DBG )
-	    fprintf( stderr,"INTERVAL %f\n",INTERVAL );
-	}
+           if( !strcmp( split_str[0],"interval" ) )
+	     fprintf( stderr,"INTERVAL %f\n",INTERVAL );
 	
-      if( !strcmp( split_str[0],"count" ) )
-	{
-	  COUNT = atoi( split_str[1] );
-	  if( DBG )
-	    fprintf( stderr,"COUNT %d\n",COUNT );
-	}
+           if( !strcmp( split_str[0],"count" ) )
+	     fprintf( stderr,"COUNT %d\n",COUNT );
 	
-      if( !strcmp( split_str[0],"list" ) ) /* To be Done */
-	{
-	  sep_char = ";";
-	  split_str_count1 = 0;
-	  split_str_count1 = StringSplitWithSeperator( split_str[1], sep_char, &split_str1 );
-	  if( split_str_count1 )
-	    {
-	      NUM_LEVELS = split_str_count1;
-	      LEV_LIST = ( double *) malloc( sizeof( double ) * split_str_count1 );
-	      for( j = 0; j < split_str_count1; j++ )
-		{
-		  LEV_LIST[j] = atof( split_str1[j] );
-		}
-	      free( split_str1 );
-	    }
-	  if( DBG )
-	    {
-	      for( j = 0; j < split_str_count1; j++ )
-		{
-		  fprintf( stderr,"LIST %f\n",LEV_LIST[j] ); 
-		}
-	    }
-	}   
+           if( !strcmp( split_str[0],"list" ) ) 
+	     {
+	        for( j = 0; j < split_str_count1; j++ )
+	           fprintf( stderr,"LIST %f\n",LEV_LIST[j] ); 
+	     }
 	
-      if( !strcmp( split_str[0],"thickness" ) )
-	{
-	  THICKNESS = atoi( split_str[1] );
-	  if( DBG )
-	    fprintf( stderr,"THICKNESS %d\n",THICKNESS );
-	}
+           if( !strcmp( split_str[0],"thickness" ) )
+	     fprintf( stderr,"THICKNESS %d\n",THICKNESS );
 	
-      if( !strcmp( split_str[0],"style" ) ) 
-	{  
-	  temp_str = strdup( split_str[1] );    
-	  StrToUpperCase( temp_str );
-	  STYLE = temp_str;
-	  if( DBG )
-	    fprintf( stderr,"STYLE %s\n",STYLE );
-	}
+           if( !strcmp( split_str[0],"style" ) )
+	     fprintf( stderr,"STYLE %s\n",STYLE );
 	
-      if( !strcmp( split_str[0],"device" ) ) 
-	{  
-	  temp_str = strdup( split_str[1] );    
-	  StrToUpperCase( temp_str );
-	  DEVICE = temp_str;
-	  if( DBG )
-	    fprintf( stderr,"DEVICE %s\n",DEVICE );
-          mag_setc ("output_format", DEVICE );
-	}
+           if( !strcmp( split_str[0],"device" ) )
+	     fprintf( stderr,"DEVICE %s\n",DEVICE );
 
-      if( !strcmp( split_str[0],"step_freq" ) ) 
-	{  
-	  STEP_FREQ = atoi( split_str[1] );
-	  if( DBG )
-	    fprintf( stderr,"STEP_FREQ %d\n",STEP_FREQ );
-	}
-      free( split_str );
+           if( !strcmp( split_str[0],"step_freq" ) )
+	     fprintf( stderr,"STEP_FREQ %d\n",STEP_FREQ );
+
+           free( split_str );
+        }
     }
 
   if ( nlon > 1 )
@@ -272,9 +177,6 @@ void magplot( const char *plotfile, int operatorID, const char *varname, long nl
   titlename = strdup( plotfilename );
   sprintf( plotfilename, "%s_%s", plotfile, varname );
 
-/* #if  defined  (HAVE_LIBMAGICS) */
-
-
   mag_setc ("output_name",      plotfilename);
   mag_new( "page");
 
@@ -302,6 +204,15 @@ void magplot( const char *plotfile, int operatorID, const char *varname, long nl
   /* mag_setc ("map_coastline_colour", "khaki"); */
   /* mag_setc ("map_grid_colour",      "grey");  */ 
 
+
+  /* Parameters common to all operators */
+  if( DEVICE )                                
+    {
+      mag_setc ("output_format", DEVICE );
+    }
+
+
+
   /* define the contouring parameters */
   if ( operatorID == SHADED )
     {
@@ -316,9 +227,6 @@ void magplot( const char *plotfile, int operatorID, const char *varname, long nl
 	   mag_setr( "contour_shade_min_level", YMIN );
 	   mag_setr( "contour_min_level", YMIN );
         }
-
-
-
       
       if( YMAX > -1.0e+200 )
         {
@@ -485,7 +393,7 @@ void magplot( const char *plotfile, int operatorID, const char *varname, long nl
 	  mag_set1r( "contour_level_list", LEV_LIST, NUM_LEVELS );
 	}
 	
-      if( USR_COLOUR_COUNT ) 
+      if( USR_COLOUR_COUNT )
 	{
 	  mag_setc( "contour_shade_colour_method", "LIST" );
 	  mag_set1c( "contour_shade_colour_list",( const char ** ) USR_COLOUR_TABLE, USR_COLOUR_COUNT ); 
@@ -676,6 +584,18 @@ void *Magplot(void *argument)
 		continue;
             }
 	}
+      else 	
+        {
+          if( STEP_FREQ )
+	    {
+          	if( tsID % STEP_FREQ )
+	    	  {
+                     tsID++;
+	             cdoWarning("NOT PLOTTING STEP %d!!!\n",tsID);
+	             continue;
+	    	  }
+            }
+        }
       
       vdate = taxisInqVdate(taxisID);
       vtime = taxisInqVtime(taxisID);
@@ -715,15 +635,20 @@ void *Magplot(void *argument)
       if( DBG )
         fprintf( stderr,"TimeStep %d\n",tsID );
 
-      if( ANIM_FLAG )
-        tsID++;
-      else
+       
+      if( !STEP_FREQ )
         {
 	   cdoWarning("File variables have values at more than one time step! Images created for first time step!!!");
-           if( STEP_FREQ > 1 ) 
-             cdoWarning("Step frequency parameter ignored!!!");
+           cdoWarning("To plot steps at a particular interval, set 'step_freq' to the frequency of the steps to be plotted!!!");
+           cdoWarning("To plot steps at random interval, set 'step_freq' to '1' and select the steps using the selection operators!!!");
        	   break;
 	}
+      else
+        {
+      	   tsID++;
+           if( DBG )
+             fprintf( stderr,"TimeStep %d\n",tsID );
+	}
     }
 
   if( ANIM_FLAG )
@@ -758,6 +683,7 @@ void VerifyPlotParameters( int num_param, char **param_names, int opID )
   char **split_str = NULL, **split_str1 = NULL;
   char *sep_char = "=";
   char *temp_str;
+  char  orig_char = ';', rep_char = ',';
   FILE *fp;
 
 /*  
@@ -806,7 +732,7 @@ void VerifyPlotParameters( int num_param, char **param_names, int opID )
 		      !strcmp( split_str[0],"RGB" )        || !strcmp( split_str[0],"colour_triad" )||
 		      !strcmp( split_str[0],"device")      || !strcmp( split_str[0],"file_split" )
 		    )
-		    {  
+		    {
 		      if( IsNumeric( split_str[1] ) )
 			syntax = FALSE;
 		      else
@@ -845,6 +771,51 @@ void VerifyPlotParameters( int num_param, char **param_names, int opID )
 			      
 			      if( checkcolour( split_str[1] ) )
 				syntax = FALSE;
+                              else
+                                {
+      				   if( !strcmp( split_str[0],"colour" ) ) 
+	                             {  
+	                               temp_str = strdup( split_str[1] );  
+	                               if( !isRGB )
+	                                 StrToLowerCase( temp_str );
+	                               else
+	                                 {
+	                                    StrToUpperCase( temp_str );
+	                                    StrReplaceChar( temp_str, orig_char, rep_char ); /* replace ';' in RGB format to ',' */
+	                                 }
+                                       COLOUR = temp_str;
+	                               if( DBG )
+	                                 fprintf(stderr,"COLOUR %s\n",COLOUR );
+	                             }
+                                   if( !strcmp( split_str[0],"colour_min" ) ) 
+	                             {  
+	                               temp_str = strdup( split_str[1] );    
+                                       if( !isRGB )
+	                                 StrToLowerCase( temp_str );
+	                               else
+	                                 {
+	                                   StrToUpperCase( temp_str );
+	                                   StrReplaceChar( temp_str, orig_char, rep_char ); /* replace ';' in RGB format to ',' */
+	                                 }
+	                               COLOUR_MIN = temp_str;
+	                               if( DBG )
+	                                 fprintf(stderr,"COLOUR %s\n",COLOUR_MIN );
+	                             }
+                                   if( !strcmp( split_str[0],"colour_max" ) ) 
+	                             {
+	                               temp_str = strdup( split_str[1] );    
+                                       if( !isRGB )
+	                                 StrToLowerCase( temp_str );
+	                               else
+	                                 {
+	                                   StrToUpperCase( temp_str );
+	                                   StrReplaceChar( temp_str, orig_char, rep_char ); /* replace ';' in RGB format to ',' */
+	                                 }
+	                               COLOUR_MAX = temp_str;
+	                               if( DBG )
+	                                 fprintf(stderr,"COLOUR %s\n",COLOUR_MAX );
+	                             }
+			        }
 			    }
 			  else if( !strcmp( split_str[0],"device" ) )
 			    {
@@ -856,19 +827,19 @@ void VerifyPlotParameters( int num_param, char **param_names, int opID )
 			      temp_str = strdup( split_str[1] );    
 			      StrToUpperCase( temp_str );
 			      if( strcmp( temp_str,"CW" ) && strcmp( temp_str,"ACW" ) )
-				    syntax = FALSE;      
+				syntax = FALSE;      
 			      else
-				    {
-				  		if( DBG )
-				    	  fprintf( stderr, "TRIAD check  %s!\n",temp_str);
-					    if( !strcmp( temp_str,"CW" ) )
-						  COLOUR_TRIAD = "clockwise";
-					    else
-						  COLOUR_TRIAD = "anti_clockwise";
-				    }
+				{
+				   if( DBG )
+				     fprintf( stderr, "TRIAD check  %s!\n",temp_str);
+				   if( !strcmp( temp_str,"CW" ) )
+				     COLOUR_TRIAD = "clockwise";
+				   else
+				     COLOUR_TRIAD = "anti_clockwise";
+				}
 			    }
 			}
-		    } 
+		    }
 		      
 		  if( !strcmp( split_str[0],"min" )      ||  !strcmp( split_str[0],"max" )     ||
 		      !strcmp( split_str[0],"count" )     ||  !strcmp( split_str[0],"interval" ) ||
@@ -877,7 +848,38 @@ void VerifyPlotParameters( int num_param, char **param_names, int opID )
                     )
 		    {
 		      if( !IsNumeric( split_str[1] ) )
-			syntax = FALSE;       
+			syntax = FALSE;
+		      else
+			{
+                           if( !strcmp( split_str[0],"min" ) )
+	                     {
+	                        YMIN = atof( split_str[1] );
+			     }
+                           if( !strcmp( split_str[0],"max" ) )
+	                     {
+	  		        YMAX = atof( split_str[1] );
+			     }
+		           if( !strcmp( split_str[0],"count" ) )
+			     {
+	                        COUNT = atoi( split_str[1] );
+			     }
+                           if( !strcmp( split_str[0],"interval" ) )
+	                     {
+	  		        INTERVAL = atof( split_str[1] );
+	                     }
+		           if( !strcmp( split_str[0],"thickness" ) )
+			     {
+	  		        THICKNESS = atoi( split_str[1] );
+			     }
+                           if( !strcmp( split_str[0],"resolution" ) )
+	                     {
+	                        RESOLUTION = atoi( split_str[1] );
+	                     }	
+		           if( !strcmp( split_str[0],"step_freq" ) )
+			     {
+	  	                STEP_FREQ = atoi( split_str[1] );
+			     }
+	                }
 		    }
 		    
 		  if( !strcmp( split_str[0],"colourtable" ) )
@@ -899,21 +901,31 @@ void VerifyPlotParameters( int num_param, char **param_names, int opID )
 		      split_str_count = StringSplitWithSeperator( split_str[1], sep_char, &split_str1 );
 		      if( !split_str_count )
 			{
-			  syntax = FALSE; 
+			  syntax = FALSE;
 			}
 		      else
-		      {
-			for( k = 0; k < split_str_count; k++ )
-			  {
-			    if( !IsNumeric( split_str1[k] ) )
-			      syntax = FALSE;
+		        {
+			  for( k = 0; k < split_str_count; k++ )
+			    {
+			      if( !IsNumeric( split_str1[k] ) )
+			        syntax = FALSE;
+			    }
+			  if( syntax == TRUE )
+			    {
+	                       NUM_LEVELS = split_str_count;
+	                       LEV_LIST = ( double *) malloc( sizeof( double ) * split_str_count );
+			       for( k = 0; k < split_str_count; k++ )
+		                 {
+		                    LEV_LIST[k] = atof( split_str1[k] );
+		                 }
+	                       free( split_str1 );
+	                    }
 			  }
 		      }
-		      sep_char = "=";
-		    }
-		}
-	    }
-	}
+		  sep_char = "=";
+		} /*** if( !strcmp( split_str[0], params[j] ) )  ***/
+	    } /*** Loop over param count ***/
+	} /*** ( split_str_count > 1 ) ***/
       else
 	{
 	  syntax = FALSE;
@@ -932,12 +944,12 @@ void VerifyPlotParameters( int num_param, char **param_names, int opID )
 	
       if( split_str ) 	  
 	free( split_str );
-    }
+    } /*** Loop over params ****/
       
     if( halt_flag == TRUE )
-    {
-      exit(0);
-    }
+      {
+        exit(0);
+      }
     
 }
 
@@ -1122,6 +1134,7 @@ int checkstyle( char *style_in )
 	if( !strcmp( STYLE_TABLE[i], style_in ) )
 	  {
 	    found = TRUE;
+	    STYLE = style_in;
 	    return 0;
 	  }
       }
@@ -1146,8 +1159,16 @@ int checkdevice( char *device_in )
 	if( !strcmp( DEVICE_TABLE[i], device_in ) )
 	  {
 	    found = TRUE;
+
+	    DEVICE = device_in;
+	    if( DBG )
+	      fprintf( stderr,"DEVICE %s\n",DEVICE );
+
 	    if( !strcmp( "GIF_ANIMATION" , device_in ) || !strcmp( "KML", device_in )  )
-	      ANIM_FLAG = 1;
+              {
+	         ANIM_FLAG = 1;
+		 STEP_FREQ = 1;
+	      }
 	    return 0;
 	  }
       }
diff --git a/src/Makefile.am b/src/Makefile.am
index c3e7ea8..040686c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -3,7 +3,8 @@
 bin_PROGRAMS = cdo
 #
 cdo_SOURCES  = cdo.c
-cdo_SOURCES += Arith.c         \
+cdo_SOURCES += Adisit.c        \
+               Arith.c         \
                Arithc.c        \
                Arithdays.c     \
                Arithlat.c      \
@@ -163,6 +164,7 @@ cdo_SOURCES += Arith.c         \
                Writegrid.c     \
                Writerandom.c   \
                YAR.c           \
+               Yearmonstat.c   \
                Ydayarith.c     \
                Ydaypctl.c      \
                Ydaystat.c      \
diff --git a/src/Makefile.in b/src/Makefile.in
index 8e94ecd..994687c 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -86,57 +86,57 @@ CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 am__installdirs = "$(DESTDIR)$(bindir)"
 PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
-am__cdo_SOURCES_DIST = cdo.c Arith.c Arithc.c Arithdays.c Arithlat.c \
-	CDItest.c CDIread.c CDIwrite.c Cat.c Change.c Change_e5slm.c \
-	Cloudlayer.c Command.c Comp.c Compc.c Complextorect.c Cond.c \
-	Cond2.c Condc.c Consecstat.c Copy.c Deltime.c Derivepar.c \
-	Detrend.c Diff.c Duplicate.c EOFs.c Eof3d.c EcaIndices.c \
-	Echam5ini.c Enlarge.c Enlargegrid.c Ensstat.c Ensstat3.c \
-	Ensval.c Eofcoeff.c Eofcoeff3d.c Exprf.c FC.c Filedes.c \
-	Fillmiss.c Filter.c Fldrms.c Fldstat.c Fldstat2.c Fourier.c \
-	Gather.c Gengrid.c Gradsdes.c Gridboxstat.c Gridcell.c \
-	Harmonic.c Hi.c Histogram.c Importamsr.c Importbinary.c \
-	Importcmsaf.c Importobs.c Info.c Input.c Intgrid.c \
-	Intgridtraj.c Intlevel.c Intlevel3d.c Intntime.c Inttime.c \
-	Intyear.c Invert.c Invertlev.c Isosurface.c Kvl.c Log.c \
-	Maskbox.c Mastrfu.c Math.c Merge.c Mergegrid.c Mergetime.c \
-	Merstat.c Monarith.c Mrotuv.c Mrotuvb.c Ninfo.c Nmltest.c \
-	Output.c Outputgmt.c Pinfo.c Pressure.c Regres.c Remap.c \
-	Remapeta.c Replace.c Replacevalues.c Rhopot.c Rotuv.c \
-	Runpctl.c Runstat.c Scatter.c Seascount.c Seaspctl.c \
-	Seasstat.c Selbox.c Select.c Seloperator.c Selrec.c Seltime.c \
-	Selvar.c Set.c Setbox.c Setgatt.c Setgrid.c Sethalo.c \
-	Setmiss.c Setpartab.c Setrcaname.c Settime.c Setzaxis.c \
-	Showinfo.c Sinfo.c Smooth9.c Sort.c Sorttimestamp.c Specinfo.c \
-	Spectral.c Spectrum.c Split.c Splitrec.c Splitsel.c \
-	Splittime.c Splityear.c SSOpar.c Subtrend.c Tee.c Templates.c \
-	Test.c Tests.c Timcount.c Timpctl.c Timselpctl.c Timselstat.c \
-	Timsort.c Timstat.c Timstat2.c Timstat3.c Tinfo.c Tocomplex.c \
-	Transpose.c Trend.c Trms.c Tstepcount.c Vardup.c Vargen.c \
-	Varrms.c Vertint.c Vertstat.c Vertwind.c Wct.c Wind.c \
-	Writegrid.c Writerandom.c YAR.c Ydayarith.c Ydaypctl.c \
-	Ydaystat.c Ydrunpctl.c Ydrunstat.c Yhourarith.c Yhourstat.c \
-	Ymonarith.c Ymonpctl.c Ymonstat.c Yseaspctl.c Yseasstat.c \
-	Zonstat.c cdo.h cdo_int.h cdo_pthread.c cdo_vlist.c color.c \
-	color.h commandline.c const.h counter.h dmemory.h dtypes.h \
-	ecacore.c ecacore.h ecautil.c ecautil.h error.h etopo.h temp.h \
-	mask.h exception.c expr.c expr.h expr_lex.c expr_yacc.c \
-	expr_yacc.h field.c field.h field2.c fieldc.c fieldmem.c \
-	fieldmer.c fieldzon.c fouriertrans.c functs.h gradsdeslib.c \
-	gradsdeslib.h grid.c grid.h grid_gme.c grid_lcc.c grid_rot.c \
-	griddes.c griddes.h griddes_h5.c griddes_nc.c hetaeta.c \
-	hetaeta.h history.c institution.c interpol.c interpol.h job.c \
-	juldate.c kvlist.c kvlist.h legendre.c list.c list.h \
-	merge_sort2.c merge_sort2.h modules.c modules.h namelist.c \
-	namelist.h normal.c nth_element.c nth_element.h \
-	operator_help.h par_io.c par_io.h percentiles.c percentiles.h \
-	pipe.c pipe.h printinfo.h process.c process.h pstream.c \
-	pstream.h pstream_int.h pthread_debug.c pthread_debug.h \
-	readline.c realtime.c remap.h remaplib.c remapsort.c \
-	specspace.c specspace.h statistic.c statistic.h table.c \
-	timebase.h timer.c userlog.c util.c util.h vinterp.c vinterp.h \
-	zaxis.c Magplot.c Magvector.c Maggraph.c template_parser.h \
-	template_parser.c results_template_parser.h \
+am__cdo_SOURCES_DIST = cdo.c Adisit.c Arith.c Arithc.c Arithdays.c \
+	Arithlat.c CDItest.c CDIread.c CDIwrite.c Cat.c Change.c \
+	Change_e5slm.c Cloudlayer.c Command.c Comp.c Compc.c \
+	Complextorect.c Cond.c Cond2.c Condc.c Consecstat.c Copy.c \
+	Deltime.c Derivepar.c Detrend.c Diff.c Duplicate.c EOFs.c \
+	Eof3d.c EcaIndices.c Echam5ini.c Enlarge.c Enlargegrid.c \
+	Ensstat.c Ensstat3.c Ensval.c Eofcoeff.c Eofcoeff3d.c Exprf.c \
+	FC.c Filedes.c Fillmiss.c Filter.c Fldrms.c Fldstat.c \
+	Fldstat2.c Fourier.c Gather.c Gengrid.c Gradsdes.c \
+	Gridboxstat.c Gridcell.c Harmonic.c Hi.c Histogram.c \
+	Importamsr.c Importbinary.c Importcmsaf.c Importobs.c Info.c \
+	Input.c Intgrid.c Intgridtraj.c Intlevel.c Intlevel3d.c \
+	Intntime.c Inttime.c Intyear.c Invert.c Invertlev.c \
+	Isosurface.c Kvl.c Log.c Maskbox.c Mastrfu.c Math.c Merge.c \
+	Mergegrid.c Mergetime.c Merstat.c Monarith.c Mrotuv.c \
+	Mrotuvb.c Ninfo.c Nmltest.c Output.c Outputgmt.c Pinfo.c \
+	Pressure.c Regres.c Remap.c Remapeta.c Replace.c \
+	Replacevalues.c Rhopot.c Rotuv.c Runpctl.c Runstat.c Scatter.c \
+	Seascount.c Seaspctl.c Seasstat.c Selbox.c Select.c \
+	Seloperator.c Selrec.c Seltime.c Selvar.c Set.c Setbox.c \
+	Setgatt.c Setgrid.c Sethalo.c Setmiss.c Setpartab.c \
+	Setrcaname.c Settime.c Setzaxis.c Showinfo.c Sinfo.c Smooth9.c \
+	Sort.c Sorttimestamp.c Specinfo.c Spectral.c Spectrum.c \
+	Split.c Splitrec.c Splitsel.c Splittime.c Splityear.c SSOpar.c \
+	Subtrend.c Tee.c Templates.c Test.c Tests.c Timcount.c \
+	Timpctl.c Timselpctl.c Timselstat.c Timsort.c Timstat.c \
+	Timstat2.c Timstat3.c Tinfo.c Tocomplex.c Transpose.c Trend.c \
+	Trms.c Tstepcount.c Vardup.c Vargen.c Varrms.c Vertint.c \
+	Vertstat.c Vertwind.c Wct.c Wind.c Writegrid.c Writerandom.c \
+	YAR.c Yearmonstat.c Ydayarith.c Ydaypctl.c Ydaystat.c \
+	Ydrunpctl.c Ydrunstat.c Yhourarith.c Yhourstat.c Ymonarith.c \
+	Ymonpctl.c Ymonstat.c Yseaspctl.c Yseasstat.c Zonstat.c cdo.h \
+	cdo_int.h cdo_pthread.c cdo_vlist.c color.c color.h \
+	commandline.c const.h counter.h dmemory.h dtypes.h ecacore.c \
+	ecacore.h ecautil.c ecautil.h error.h etopo.h temp.h mask.h \
+	exception.c expr.c expr.h expr_lex.c expr_yacc.c expr_yacc.h \
+	field.c field.h field2.c fieldc.c fieldmem.c fieldmer.c \
+	fieldzon.c fouriertrans.c functs.h gradsdeslib.c gradsdeslib.h \
+	grid.c grid.h grid_gme.c grid_lcc.c grid_rot.c griddes.c \
+	griddes.h griddes_h5.c griddes_nc.c hetaeta.c hetaeta.h \
+	history.c institution.c interpol.c interpol.h job.c juldate.c \
+	kvlist.c kvlist.h legendre.c list.c list.h merge_sort2.c \
+	merge_sort2.h modules.c modules.h namelist.c namelist.h \
+	normal.c nth_element.c nth_element.h operator_help.h par_io.c \
+	par_io.h percentiles.c percentiles.h pipe.c pipe.h printinfo.h \
+	process.c process.h pstream.c pstream.h pstream_int.h \
+	pthread_debug.c pthread_debug.h readline.c realtime.c remap.h \
+	remaplib.c remapsort.c specspace.c specspace.h statistic.c \
+	statistic.h table.c timebase.h timer.c userlog.c util.c util.h \
+	vinterp.c vinterp.h zaxis.c Magplot.c Magvector.c Maggraph.c \
+	template_parser.h template_parser.c results_template_parser.h \
 	results_template_parser.c magics_template_parser.h \
 	magics_template_parser.c StringUtilities.h StringUtilities.c \
 	CdoMagicsMapper.h CdoMagicsMapper.c
@@ -148,13 +148,13 @@ am__cdo_SOURCES_DIST = cdo.c Arith.c Arithc.c Arithdays.c Arithlat.c \
 @ENABLE_MAGICS_TRUE@	cdo-magics_template_parser.$(OBJEXT) \
 @ENABLE_MAGICS_TRUE@	cdo-StringUtilities.$(OBJEXT) \
 @ENABLE_MAGICS_TRUE@	cdo-CdoMagicsMapper.$(OBJEXT)
-am_cdo_OBJECTS = cdo-cdo.$(OBJEXT) cdo-Arith.$(OBJEXT) \
-	cdo-Arithc.$(OBJEXT) cdo-Arithdays.$(OBJEXT) \
-	cdo-Arithlat.$(OBJEXT) cdo-CDItest.$(OBJEXT) \
-	cdo-CDIread.$(OBJEXT) cdo-CDIwrite.$(OBJEXT) cdo-Cat.$(OBJEXT) \
-	cdo-Change.$(OBJEXT) cdo-Change_e5slm.$(OBJEXT) \
-	cdo-Cloudlayer.$(OBJEXT) cdo-Command.$(OBJEXT) \
-	cdo-Comp.$(OBJEXT) cdo-Compc.$(OBJEXT) \
+am_cdo_OBJECTS = cdo-cdo.$(OBJEXT) cdo-Adisit.$(OBJEXT) \
+	cdo-Arith.$(OBJEXT) cdo-Arithc.$(OBJEXT) \
+	cdo-Arithdays.$(OBJEXT) cdo-Arithlat.$(OBJEXT) \
+	cdo-CDItest.$(OBJEXT) cdo-CDIread.$(OBJEXT) \
+	cdo-CDIwrite.$(OBJEXT) cdo-Cat.$(OBJEXT) cdo-Change.$(OBJEXT) \
+	cdo-Change_e5slm.$(OBJEXT) cdo-Cloudlayer.$(OBJEXT) \
+	cdo-Command.$(OBJEXT) cdo-Comp.$(OBJEXT) cdo-Compc.$(OBJEXT) \
 	cdo-Complextorect.$(OBJEXT) cdo-Cond.$(OBJEXT) \
 	cdo-Cond2.$(OBJEXT) cdo-Condc.$(OBJEXT) \
 	cdo-Consecstat.$(OBJEXT) cdo-Copy.$(OBJEXT) \
@@ -222,19 +222,20 @@ am_cdo_OBJECTS = cdo-cdo.$(OBJEXT) cdo-Arith.$(OBJEXT) \
 	cdo-Vertint.$(OBJEXT) cdo-Vertstat.$(OBJEXT) \
 	cdo-Vertwind.$(OBJEXT) cdo-Wct.$(OBJEXT) cdo-Wind.$(OBJEXT) \
 	cdo-Writegrid.$(OBJEXT) cdo-Writerandom.$(OBJEXT) \
-	cdo-YAR.$(OBJEXT) cdo-Ydayarith.$(OBJEXT) \
-	cdo-Ydaypctl.$(OBJEXT) cdo-Ydaystat.$(OBJEXT) \
-	cdo-Ydrunpctl.$(OBJEXT) cdo-Ydrunstat.$(OBJEXT) \
-	cdo-Yhourarith.$(OBJEXT) cdo-Yhourstat.$(OBJEXT) \
-	cdo-Ymonarith.$(OBJEXT) cdo-Ymonpctl.$(OBJEXT) \
-	cdo-Ymonstat.$(OBJEXT) cdo-Yseaspctl.$(OBJEXT) \
-	cdo-Yseasstat.$(OBJEXT) cdo-Zonstat.$(OBJEXT) \
-	cdo-cdo_pthread.$(OBJEXT) cdo-cdo_vlist.$(OBJEXT) \
-	cdo-color.$(OBJEXT) cdo-commandline.$(OBJEXT) \
-	cdo-ecacore.$(OBJEXT) cdo-ecautil.$(OBJEXT) \
-	cdo-exception.$(OBJEXT) cdo-expr.$(OBJEXT) \
-	cdo-expr_lex.$(OBJEXT) cdo-expr_yacc.$(OBJEXT) \
-	cdo-field.$(OBJEXT) cdo-field2.$(OBJEXT) cdo-fieldc.$(OBJEXT) \
+	cdo-YAR.$(OBJEXT) cdo-Yearmonstat.$(OBJEXT) \
+	cdo-Ydayarith.$(OBJEXT) cdo-Ydaypctl.$(OBJEXT) \
+	cdo-Ydaystat.$(OBJEXT) cdo-Ydrunpctl.$(OBJEXT) \
+	cdo-Ydrunstat.$(OBJEXT) cdo-Yhourarith.$(OBJEXT) \
+	cdo-Yhourstat.$(OBJEXT) cdo-Ymonarith.$(OBJEXT) \
+	cdo-Ymonpctl.$(OBJEXT) cdo-Ymonstat.$(OBJEXT) \
+	cdo-Yseaspctl.$(OBJEXT) cdo-Yseasstat.$(OBJEXT) \
+	cdo-Zonstat.$(OBJEXT) cdo-cdo_pthread.$(OBJEXT) \
+	cdo-cdo_vlist.$(OBJEXT) cdo-color.$(OBJEXT) \
+	cdo-commandline.$(OBJEXT) cdo-ecacore.$(OBJEXT) \
+	cdo-ecautil.$(OBJEXT) cdo-exception.$(OBJEXT) \
+	cdo-expr.$(OBJEXT) cdo-expr_lex.$(OBJEXT) \
+	cdo-expr_yacc.$(OBJEXT) cdo-field.$(OBJEXT) \
+	cdo-field2.$(OBJEXT) cdo-fieldc.$(OBJEXT) \
 	cdo-fieldmem.$(OBJEXT) cdo-fieldmer.$(OBJEXT) \
 	cdo-fieldzon.$(OBJEXT) cdo-fouriertrans.$(OBJEXT) \
 	cdo-gradsdeslib.$(OBJEXT) cdo-grid.$(OBJEXT) \
@@ -321,6 +322,7 @@ ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 ENABLE_CDI_LIB = @ENABLE_CDI_LIB@
 ENABLE_CGRIBEX = @ENABLE_CGRIBEX@
+ENABLE_DATA = @ENABLE_DATA@
 ENABLE_EXTRA = @ENABLE_EXTRA@
 ENABLE_GRIB = @ENABLE_GRIB@
 ENABLE_IEG = @ENABLE_IEG@
@@ -451,8 +453,8 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 #
-cdo_SOURCES = cdo.c Arith.c Arithc.c Arithdays.c Arithlat.c CDItest.c \
-	CDIread.c CDIwrite.c Cat.c Change.c Change_e5slm.c \
+cdo_SOURCES = cdo.c Adisit.c Arith.c Arithc.c Arithdays.c Arithlat.c \
+	CDItest.c CDIread.c CDIwrite.c Cat.c Change.c Change_e5slm.c \
 	Cloudlayer.c Command.c Comp.c Compc.c Complextorect.c Cond.c \
 	Cond2.c Condc.c Consecstat.c Copy.c Deltime.c Derivepar.c \
 	Detrend.c Diff.c Duplicate.c EOFs.c Eof3d.c EcaIndices.c \
@@ -479,28 +481,28 @@ cdo_SOURCES = cdo.c Arith.c Arithc.c Arithdays.c Arithlat.c CDItest.c \
 	Timsort.c Timstat.c Timstat2.c Timstat3.c Tinfo.c Tocomplex.c \
 	Transpose.c Trend.c Trms.c Tstepcount.c Vardup.c Vargen.c \
 	Varrms.c Vertint.c Vertstat.c Vertwind.c Wct.c Wind.c \
-	Writegrid.c Writerandom.c YAR.c Ydayarith.c Ydaypctl.c \
-	Ydaystat.c Ydrunpctl.c Ydrunstat.c Yhourarith.c Yhourstat.c \
-	Ymonarith.c Ymonpctl.c Ymonstat.c Yseaspctl.c Yseasstat.c \
-	Zonstat.c cdo.h cdo_int.h cdo_pthread.c cdo_vlist.c color.c \
-	color.h commandline.c const.h counter.h dmemory.h dtypes.h \
-	ecacore.c ecacore.h ecautil.c ecautil.h error.h etopo.h temp.h \
-	mask.h exception.c expr.c expr.h expr_lex.c expr_yacc.c \
-	expr_yacc.h field.c field.h field2.c fieldc.c fieldmem.c \
-	fieldmer.c fieldzon.c fouriertrans.c functs.h gradsdeslib.c \
-	gradsdeslib.h grid.c grid.h grid_gme.c grid_lcc.c grid_rot.c \
-	griddes.c griddes.h griddes_h5.c griddes_nc.c hetaeta.c \
-	hetaeta.h history.c institution.c interpol.c interpol.h job.c \
-	juldate.c kvlist.c kvlist.h legendre.c list.c list.h \
-	merge_sort2.c merge_sort2.h modules.c modules.h namelist.c \
-	namelist.h normal.c nth_element.c nth_element.h \
-	operator_help.h par_io.c par_io.h percentiles.c percentiles.h \
-	pipe.c pipe.h printinfo.h process.c process.h pstream.c \
-	pstream.h pstream_int.h pthread_debug.c pthread_debug.h \
-	readline.c realtime.c remap.h remaplib.c remapsort.c \
-	specspace.c specspace.h statistic.c statistic.h table.c \
-	timebase.h timer.c userlog.c util.c util.h vinterp.c vinterp.h \
-	zaxis.c $(am__append_1)
+	Writegrid.c Writerandom.c YAR.c Yearmonstat.c Ydayarith.c \
+	Ydaypctl.c Ydaystat.c Ydrunpctl.c Ydrunstat.c Yhourarith.c \
+	Yhourstat.c Ymonarith.c Ymonpctl.c Ymonstat.c Yseaspctl.c \
+	Yseasstat.c Zonstat.c cdo.h cdo_int.h cdo_pthread.c \
+	cdo_vlist.c color.c color.h commandline.c const.h counter.h \
+	dmemory.h dtypes.h ecacore.c ecacore.h ecautil.c ecautil.h \
+	error.h etopo.h temp.h mask.h exception.c expr.c expr.h \
+	expr_lex.c expr_yacc.c expr_yacc.h field.c field.h field2.c \
+	fieldc.c fieldmem.c fieldmer.c fieldzon.c fouriertrans.c \
+	functs.h gradsdeslib.c gradsdeslib.h grid.c grid.h grid_gme.c \
+	grid_lcc.c grid_rot.c griddes.c griddes.h griddes_h5.c \
+	griddes_nc.c hetaeta.c hetaeta.h history.c institution.c \
+	interpol.c interpol.h job.c juldate.c kvlist.c kvlist.h \
+	legendre.c list.c list.h merge_sort2.c merge_sort2.h modules.c \
+	modules.h namelist.c namelist.h normal.c nth_element.c \
+	nth_element.h operator_help.h par_io.c par_io.h percentiles.c \
+	percentiles.h pipe.c pipe.h printinfo.h process.c process.h \
+	pstream.c pstream.h pstream_int.h pthread_debug.c \
+	pthread_debug.h readline.c realtime.c remap.h remaplib.c \
+	remapsort.c specspace.c specspace.h statistic.c statistic.h \
+	table.c timebase.h timer.c userlog.c util.c util.h vinterp.c \
+	vinterp.h zaxis.c $(am__append_1)
 cdo_CPPFLAGS = -I$(top_srcdir)/libcdi/src
 cdo_LDADD = $(top_builddir)/libcdi/src/libcdi.la
 cdo_LDFLAGS = $(am__append_2)
@@ -630,6 +632,7 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Adisit.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Arith.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Arithc.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Arithdays.Po at am__quote@
@@ -800,6 +803,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Ydaystat.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Ydrunpctl.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Ydrunstat.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Yearmonstat.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Yhourarith.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Yhourstat.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Ymonarith.Po at am__quote@
@@ -906,6 +910,20 @@ cdo-cdo.obj: cdo.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-cdo.obj `if test -f 'cdo.c'; then $(CYGPATH_W) 'cdo.c'; else $(CYGPATH_W) '$(srcdir)/cdo.c'; fi`
 
+cdo-Adisit.o: Adisit.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-Adisit.o -MD -MP -MF $(DEPDIR)/cdo-Adisit.Tpo -c -o cdo-Adisit.o `test -f 'Adisit.c' || echo '$(srcdir)/'`Adisit.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-Adisit.Tpo $(DEPDIR)/cdo-Adisit.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='Adisit.c' object='cdo-Adisit.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-Adisit.o `test -f 'Adisit.c' || echo '$(srcdir)/'`Adisit.c
+
+cdo-Adisit.obj: Adisit.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-Adisit.obj -MD -MP -MF $(DEPDIR)/cdo-Adisit.Tpo -c -o cdo-Adisit.obj `if test -f 'Adisit.c'; then $(CYGPATH_W) 'Adisit.c'; else $(CYGPATH_W) '$(srcdir)/Adisit.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-Adisit.Tpo $(DEPDIR)/cdo-Adisit.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='Adisit.c' object='cdo-Adisit.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-Adisit.obj `if test -f 'Adisit.c'; then $(CYGPATH_W) 'Adisit.c'; else $(CYGPATH_W) '$(srcdir)/Adisit.c'; fi`
+
 cdo-Arith.o: Arith.c
 @am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-Arith.o -MD -MP -MF $(DEPDIR)/cdo-Arith.Tpo -c -o cdo-Arith.o `test -f 'Arith.c' || echo '$(srcdir)/'`Arith.c
 @am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-Arith.Tpo $(DEPDIR)/cdo-Arith.Po
@@ -3146,6 +3164,20 @@ cdo-YAR.obj: YAR.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-YAR.obj `if test -f 'YAR.c'; then $(CYGPATH_W) 'YAR.c'; else $(CYGPATH_W) '$(srcdir)/YAR.c'; fi`
 
+cdo-Yearmonstat.o: Yearmonstat.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-Yearmonstat.o -MD -MP -MF $(DEPDIR)/cdo-Yearmonstat.Tpo -c -o cdo-Yearmonstat.o `test -f 'Yearmonstat.c' || echo '$(srcdir)/'`Yearmonstat.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-Yearmonstat.Tpo $(DEPDIR)/cdo-Yearmonstat.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='Yearmonstat.c' object='cdo-Yearmonstat.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-Yearmonstat.o `test -f 'Yearmonstat.c' || echo '$(srcdir)/'`Yearmonstat.c
+
+cdo-Yearmonstat.obj: Yearmonstat.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-Yearmonstat.obj -MD -MP -MF $(DEPDIR)/cdo-Yearmonstat.Tpo -c -o cdo-Yearmonstat.obj `if test -f 'Yearmonstat.c'; then $(CYGPATH_W) 'Yearmonstat.c'; else $(CYGPATH_W) '$(srcdir)/Yearmonstat.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-Yearmonstat.Tpo $(DEPDIR)/cdo-Yearmonstat.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='Yearmonstat.c' object='cdo-Yearmonstat.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-Yearmonstat.obj `if test -f 'Yearmonstat.c'; then $(CYGPATH_W) 'Yearmonstat.c'; else $(CYGPATH_W) '$(srcdir)/Yearmonstat.c'; fi`
+
 cdo-Ydayarith.o: Ydayarith.c
 @am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-Ydayarith.o -MD -MP -MF $(DEPDIR)/cdo-Ydayarith.Tpo -c -o cdo-Ydayarith.o `test -f 'Ydayarith.c' || echo '$(srcdir)/'`Ydayarith.c
 @am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-Ydayarith.Tpo $(DEPDIR)/cdo-Ydayarith.Po
diff --git a/src/Maskbox.c b/src/Maskbox.c
index 33cc628..5742708 100644
--- a/src/Maskbox.c
+++ b/src/Maskbox.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -109,122 +109,9 @@ int ReadCoords(double *xvals, double *yvals, const char *polyfile, FILE *fp)
 }
 
 
-void genlonlatbox(double xlon1, double xlon2, double xlat1, double xlat2,
-		  int nlon1, int nlat1, double *xvals1, double *yvals1,
-		  int *lat1, int *lat2, int *lon11, int *lon12, int *lon21, int *lon22);
+void genlonlatbox(int argc_offset, int gridID1, int *lat1, int *lat2, int *lon11, int *lon12, int *lon21, int *lon22);
 
-static
-void genlonlatgrid(int gridID1, int *lat1, int *lat2, int *lon11, int *lon12, int *lon21, int *lon22)
-{
-  int nlon1, nlat1;
-  double *xvals1, *yvals1;
-  double xlon1, xlon2, xlat1, xlat2;
-
-  operatorCheckArgc(4);
-
-  xlon1 = atof(operatorArgv()[0]);
-  xlon2 = atof(operatorArgv()[1]);
-  xlat1 = atof(operatorArgv()[2]);
-  xlat2 = atof(operatorArgv()[3]);
-
-  nlon1 = gridInqXsize(gridID1);
-  nlat1 = gridInqYsize(gridID1);
-
-  xvals1 = (double *) malloc(nlon1*sizeof(double));
-  yvals1 = (double *) malloc(nlat1*sizeof(double));
-
-  gridInqXvals(gridID1, xvals1);
-  gridInqYvals(gridID1, yvals1);
-
-  /* Convert lat/lon units if required */
-  {
-    char units[CDI_MAX_NAME];
-    gridInqXunits(gridID1, units);
-    gridToDegree(units, "grid center lon", nlon1, xvals1);
-    gridInqYunits(gridID1, units);
-    gridToDegree(units, "grid center lat", nlat1, yvals1);
-  }
-
-  genlonlatbox(xlon1, xlon2, xlat1, xlat2,
-	       nlon1, nlat1, xvals1, yvals1,
-	       lat1, lat2, lon11, lon12, lon21, lon22);
-
-  free(xvals1);
-  free(yvals1);
-}
-
-
-static
-void genindexbox(int gridID1, int *lat1, int *lat2, int *lon11, int *lon12, int *lon21, int *lon22)
-{
-  int nlon1, nlat1;
-  int temp;
-
-  operatorCheckArgc(4);
-
-  *lon11 = atoi(operatorArgv()[0]);
-  *lon12 = atoi(operatorArgv()[1]);
-  *lat1  = atoi(operatorArgv()[2]);
-  *lat2  = atoi(operatorArgv()[3]);
-
-  if ( *lat1 > *lat2 )
-    {
-      temp = *lat1;
-      *lat1 = *lat2;
-      *lat2 = temp;
-    }
-
-  nlon1 = gridInqXsize(gridID1);
-  nlat1 = gridInqYsize(gridID1);
-
-  if ( *lat1 < 1 )
-    {
-      cdoWarning("first latitude index out of range. Set to 1.");
-      *lat1 = 1;
-    }
-  if ( *lat2 > nlat1 )
-    {
-      cdoWarning("last latitude index out of range. Set to %d.", nlat1);
-      *lat2 = nlat1;
-    }
-  if ( *lon11 < 1 )
-    {
-      cdoWarning("first longitude index out of range. Set to 1.");
-      *lon11 = 1;
-    }
-  if ( *lon12 > nlon1+1 )
-    {
-      cdoWarning("last longitude index out of range. Set to %d.", nlon1);
-      *lon12 = nlon1;
-    }
-
-  (*lon11)--;
-  (*lon12)--;
-  (*lat1)--;
-  (*lat2)--;
-
-  if ( *lon11 > *lon12 )
-    {
-      *lon21 = *lon11;
-      *lon22 = nlon1 - 1;
-      *lon11 = 0;
-    }
-  else
-    {
-      if ( *lon12 > nlon1-1 )
-	{
-	  *lon21 = *lon11;
-	  *lon22 = nlon1 - 1;
-	  *lon11 = 0;
-	  *lon12 = 0;
-	}
-      else
-	{
-	  *lon21 = 0;
-	  *lon22 = -1;
-	}
-    }
-}
+void genindexbox(int argc_offset, int gridID1, int *lat1, int *lat2, int *lon11, int *lon12, int *lon21, int *lon22);
 
 
 static
@@ -379,6 +266,8 @@ void *Maskbox(void *argument)
 
   operatorID = cdoOperatorID();
 
+  operatorInputArg(cdoOperatorEnter(operatorID));
+
   streamID1 = streamOpenRead(cdoStreamName(0));
 
   vlistID1 = streamInqVlist(streamID1);
@@ -393,10 +282,11 @@ void *Maskbox(void *argument)
     {
       gridID   = vlistGrid(vlistID1, index);
       gridtype = gridInqType(gridID);
+
       if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN ) break;
-      if ( operatorID == MASKINDEXBOX && gridtype == GRID_CURVILINEAR ) break;
+      if ( gridtype == GRID_CURVILINEAR ) break;
       if ( operatorID == MASKINDEXBOX && gridtype == GRID_GENERIC &&
-	   gridInqXsize(gridID) > 0 && gridInqYsize(gridID) > 0 ) break;
+	  gridInqXsize(gridID) > 0 && gridInqYsize(gridID) > 0 ) break;
     }
 
   if ( gridInqType(gridID) == GRID_GAUSSIAN_REDUCED )
@@ -434,12 +324,12 @@ void *Maskbox(void *argument)
  
   if ( operatorID == MASKLONLATBOX )
     {
-      genlonlatgrid(gridID, &lat1, &lat2, &lon11, &lon12, &lon21, &lon22);
+      genlonlatbox(0, gridID, &lat1, &lat2, &lon11, &lon12, &lon21, &lon22);
       maskbox(mask, gridID, lat1, lat2, lon11, lon12, lon21, lon22);
     }
   if ( operatorID == MASKINDEXBOX )
     {
-      genindexbox(gridID, &lat1, &lat2, &lon11, &lon12, &lon21, &lon22);
+      genindexbox(0, gridID, &lat1, &lat2, &lon11, &lon12, &lon21, &lon22);
       maskbox(mask, gridID, lat1, lat2, lon11, lon12, lon21, lon22);
     }
   if ( operatorID == MASKREGION )
@@ -485,7 +375,7 @@ void *Maskbox(void *argument)
              
 	      for ( i = 0; i < gridsize; i++ )
 		{
-		  if( mask[i] ) array[i] = missval;
+		  if ( mask[i] ) array[i] = missval;
 		}
 		
 	      nmiss = 0;
diff --git a/src/Mastrfu.c b/src/Mastrfu.c
index d5579f2..26aa05d 100644
--- a/src/Mastrfu.c
+++ b/src/Mastrfu.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Math.c b/src/Math.c
index 66f87c8..11f69b0 100644
--- a/src/Math.c
+++ b/src/Math.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -190,6 +190,7 @@ void *Math(void *argument)
 	      break;
 	    default:
 	      cdoAbort("operator not implemented!");
+	      break;
 	    }
 
 	  nmiss2 = 0;
diff --git a/src/Merge.c b/src/Merge.c
index edccb89..6bd32a9 100644
--- a/src/Merge.c
+++ b/src/Merge.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -190,7 +190,7 @@ void *Merge(void *argument)
 
   if ( ! lcopy )
     {
-      gridsize = vlistGridsizeMax(vlistID1);
+      gridsize = vlistGridsizeMax(vlistID2);
       array = (double *) malloc(gridsize*sizeof(double));
     }
 
diff --git a/src/Mergegrid.c b/src/Mergegrid.c
index db1b6a1..96f854f 100644
--- a/src/Mergegrid.c
+++ b/src/Mergegrid.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Mergetime.c b/src/Mergetime.c
index 37ce681..126d71c 100644
--- a/src/Mergetime.c
+++ b/src/Mergetime.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Merstat.c b/src/Merstat.c
index 1a7e329..5955bae 100644
--- a/src/Merstat.c
+++ b/src/Merstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Monarith.c b/src/Monarith.c
index b321f10..53caa43 100644
--- a/src/Monarith.c
+++ b/src/Monarith.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Mrotuv.c b/src/Mrotuv.c
index 879c3c6..c602f41 100644
--- a/src/Mrotuv.c
+++ b/src/Mrotuv.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Mrotuvb.c b/src/Mrotuvb.c
index a3211ad..66c7227 100644
--- a/src/Mrotuvb.c
+++ b/src/Mrotuvb.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Ninfo.c b/src/Ninfo.c
index 7f34267..7983f66 100644
--- a/src/Ninfo.c
+++ b/src/Ninfo.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -147,6 +147,7 @@ void *Ninfo(void *argument)
       break;
     default:
       cdoAbort("operator not implemented!");
+      break;
     }
 
   streamClose(streamID);
diff --git a/src/Nmltest.c b/src/Nmltest.c
index 2621894..05499d9 100644
--- a/src/Nmltest.c
+++ b/src/Nmltest.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Output.c b/src/Output.c
index d9f10e9..4b97cba 100644
--- a/src/Output.c
+++ b/src/Output.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Outputgmt.c b/src/Outputgmt.c
index 451e31b..e7bd776 100644
--- a/src/Outputgmt.c
+++ b/src/Outputgmt.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Pinfo.c b/src/Pinfo.c
index 78ff27a..b08cefc 100644
--- a/src/Pinfo.c
+++ b/src/Pinfo.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Pressure.c b/src/Pressure.c
index 7421c3e..414554f 100644
--- a/src/Pressure.c
+++ b/src/Pressure.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Regres.c b/src/Regres.c
index bbeb46b..ffb117c 100644
--- a/src/Regres.c
+++ b/src/Regres.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Remap.c b/src/Remap.c
index 97c16c7..7c945ad 100644
--- a/src/Remap.c
+++ b/src/Remap.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -90,6 +90,7 @@ void get_map_type(int operfunc, int *map_type, int *submap_type, int *remap_orde
       break;
     default:
       cdoAbort("Unknown mapping method");
+      break;
     }
 }
 
diff --git a/src/Replace.c b/src/Replace.c
index dd7690b..833d6a3 100644
--- a/src/Replace.c
+++ b/src/Replace.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Replacevalues.c b/src/Replacevalues.c
index 31b90f4..349fb7c 100644
--- a/src/Replacevalues.c
+++ b/src/Replacevalues.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Rhopot.c b/src/Rhopot.c
index 4bbe592..ab25a9d 100644
--- a/src/Rhopot.c
+++ b/src/Rhopot.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -43,17 +43,10 @@
 !!
 */
 
-/* compute density from potential temperature directly */
+/* compute density from insitu temperature */
 static
-double potrho_1(double tpot, double sal, double p)
+double potrho_1(double t, double sal, double p)
 {
-  double a_a1 = 3.6504E-4, a_a2 = 8.3198E-5, a_a3 = 5.4065E-7,
-         a_a4 = 4.0274E-9,
-         a_b1 = 1.7439E-5, a_b2 = 2.9778E-7,
-         a_c1 = 8.9309E-7, a_c2 = 3.1628E-8, a_c3 = 2.1987E-10,
-         a_d = 4.1057E-9,
-         a_e1 = 1.6056E-10, a_e2 = 5.0484E-12;
-
   double r_a0 = 999.842594, r_a1 = 6.793952e-2, r_a2 = -9.095290e-3,
          r_a3 = 1.001685e-4, r_a4 = -1.120083e-6, r_a5 = 6.536332e-9,
          r_b0 = 8.24493e-1, r_b1 = -4.0899e-3, r_b2 = 7.6438e-5,
@@ -72,24 +65,10 @@ double potrho_1(double tpot, double sal, double p)
          r_ak0 = 8.50935e-5, r_ak1 = -6.12293e-6, r_ak2 = 5.2787e-8,
          r_am0 = -9.9348e-7, r_am1 = 2.0816e-8, r_am2 = 9.1697e-10;
 
-  double dc, dv, dvs, fne, fst, qc, qn3, qnq, qv, qvs, s, s3h, t, tpo;
+  double s, s3h; 
   double rho;
 
-  qc = p * (a_a1 + p * (a_c1 - a_e1 * p));
-  qv = p * (a_b1 - a_d * p);
-  dc = 1. + p * (-a_a2 + p * (a_c2 - a_e2 * p));
-  dv = a_b2 * p;
-  qnq  = -p * (-a_a3 + p * a_c3);
-  qn3  = -p * a_a4;
-
     {
-      tpo = tpot;
-      qvs = qv*(sal - 35.) + qc;
-      dvs = dv*(sal - 35.) + dc;
-      t   = (tpo + qvs)/dvs;
-      fne = - qvs + t*(dvs + t*(qnq + t*qn3)) - tpo;
-      fst = dvs + t*(2.*qnq + 3.*qn3*t);
-      t = t - fne/fst;
       s = MAX(sal, 0.0);
       s3h = sqrt(s*s*s);
 
@@ -147,32 +126,32 @@ int main (int argc, char *argv[])
 */
 
 static
-void calc_rhopot(long gridsize, long nlevel, double *pressure, field_t tho, field_t sao, field_t rho)
+void calc_rhopot(long gridsize, long nlevel, double *pressure, field_t to, field_t sao, field_t rho)
 {
   /* pressure units: hPa     */
-  /* tho units:      Celsius */
+  /* to units:       Celsius */
   /* sao units:      psu     */
 
   long i, levelID, offset;
-  double *rhoptr, *thoptr, *saoptr;
+  double *rhoptr, *toptr, *saoptr;
 
   for ( levelID = 0; levelID < nlevel; ++levelID )
     {
       offset = gridsize*levelID;
-      thoptr = tho.ptr + offset;
+      toptr = to.ptr + offset;
       saoptr = sao.ptr + offset;
       rhoptr = rho.ptr + offset;
 
       for ( i = 0; i < gridsize; ++i )
 	{
-	  if ( DBL_IS_EQUAL(thoptr[i], tho.missval) ||
+	  if ( DBL_IS_EQUAL(toptr[i], to.missval) ||
 	       DBL_IS_EQUAL(saoptr[i], sao.missval) )
 	    {
 	      rhoptr[i] = rho.missval;
 	    }
 	  else
 	    {
-	      rhoptr[i] = potrho_1(thoptr[i], saoptr[i], pressure[levelID]); 
+	      rhoptr[i] = potrho_1(toptr[i], saoptr[i], pressure[levelID]); 
 	    }
 	}
     }
@@ -192,13 +171,13 @@ void *Rhopot(void *argument)
   int ngrids, nlevel;
   int i;
   int nmiss;
-  int thoID = -1, saoID = -1;
+  int toID = -1, saoID = -1, thoID = -1;
   char varname[CDI_MAX_NAME], stdname[CDI_MAX_NAME];
   int taxisID1, taxisID2;
   double pin = -1;
   double *pressure;
   double *single;
-  field_t tho, sao, rho;
+  field_t to, sao, rho;
 
   cdoInitialize(argument);
 
@@ -215,25 +194,37 @@ void *Rhopot(void *argument)
       gridID  = vlistInqVarGrid(vlistID1, varID);
 
       code = vlistInqVarCode(vlistID1, varID);
-      vlistInqVarName(vlistID1, varID, varname);
-      vlistInqVarStdname(vlistID1,varID, stdname);
-      strtolower(varname);
 
-      if      ( strcmp(varname, "tho")   == 0 ) code = 2;
-      else if ( strcmp(varname, "sao")   == 0 ) code = 5;
+      if ( code <= 0 )
+	{
+	  vlistInqVarName(vlistID1, varID, varname);
+	  vlistInqVarStdname(vlistID1,varID, stdname);
+	  strtolower(varname);
+
+	  if      ( strcmp(varname, "to")    == 0 ) code = 20;
+	  else if ( strcmp(varname, "sao")   == 0 ) code =  5;
+	  else if ( strcmp(varname, "tho")   == 0 ) code =  2;
 
-      else if ( strcmp(varname, "t")     == 0 ) code = 2;
-      else if ( strcmp(varname, "s")     == 0 ) code = 5;
+	  else if ( strcmp(varname, "s")     == 0 ) code = 5;
+	  else if ( strcmp(varname, "t")     == 0 ) code = 2;
 
-      else if ( strcmp(stdname, "sea_water_potential_temperature") == 0 ) code = 2;
-      else if ( strcmp(stdname, "sea_water_salinity")              == 0 ) code = 5;
+	  else if ( strcmp(stdname, "sea_water_salinity")              == 0 ) code = 5;
+	  else if ( strcmp(stdname, "sea_water_potential_temperature") == 0 ) code = 2;
+	}
 
-      if      ( code == 2 ) thoID = varID;
-      else if ( code == 5 ) saoID = varID;
+      if      ( code == 20 ) toID  = varID;
+      else if ( code ==  5 ) saoID = varID;
+      else if ( code ==  2 ) thoID = varID;
     }
 
-  if ( thoID == -1 ) cdoAbort("Potential temperature not found!");
   if ( saoID == -1 ) cdoAbort("Sea water salinity not found!");
+  if ( toID  == -1 && thoID != -1 )
+    {   
+      cdoPrint("Use the CDO operator 'adisit' to convert potential temperature to In-situ temperature.");
+      cdoPrint("Here is an example:");
+      cdoPrint("   cdo rhopot -adisit %s %s", cdoStreamName(0), cdoStreamName(1));
+    }
+  if ( toID  == -1 ) cdoAbort("In-situ temperature not found!");
 
   ngrids = vlistNgrids(vlistID1);
   gridID = vlistGrid(vlistID1, 0);
@@ -249,7 +240,7 @@ void *Rhopot(void *argument)
 
   zaxisID = vlistInqVarZaxis(vlistID1, saoID);
   nlevel1 = zaxisInqSize(zaxisID);
-  zaxisID = vlistInqVarZaxis(vlistID1, thoID);
+  zaxisID = vlistInqVarZaxis(vlistID1, toID);
   nlevel2 = zaxisInqSize(zaxisID);
 
   if ( nlevel1 != nlevel2 ) cdoAbort("temperature and salinity have different number of levels!");
@@ -270,23 +261,23 @@ void *Rhopot(void *argument)
 	cdoPrint("%5d  %g", i+1, pressure[i]);
     }
 
-  tho.ptr = (double *) malloc(gridsize*nlevel*sizeof(double));
+  to.ptr = (double *) malloc(gridsize*nlevel*sizeof(double));
   sao.ptr = (double *) malloc(gridsize*nlevel*sizeof(double));
   rho.ptr = (double *) malloc(gridsize*nlevel*sizeof(double));
 
-  tho.nmiss = 0;
+  to.nmiss = 0;
   sao.nmiss = 0;
   rho.nmiss = 0;
   
-  tho.missval = vlistInqVarMissval(vlistID1, thoID);
+  to.missval = vlistInqVarMissval(vlistID1, toID);
   sao.missval = vlistInqVarMissval(vlistID1, saoID);
-  rho.missval = tho.missval;
+  rho.missval = to.missval;
 
 
   vlistID2 = vlistCreate();
   varID = vlistDefVar(vlistID2, gridID, zaxisID, TSTEP_INSTANT);
   vlistDefVarParam(vlistID2, varID, cdiEncodeParam(18, 255, 255));
-  vlistDefVarName(vlistID2, varID, "rhopot");
+  vlistDefVarName(vlistID2, varID, "rhopoto");
   vlistDefVarLongname(vlistID2, varID, "Sea water potential density");
   vlistDefVarStdname(vlistID2, varID, "sea_water_potential_density");
   vlistDefVarUnits(vlistID2, varID, "kg m-3");
@@ -314,11 +305,11 @@ void *Rhopot(void *argument)
 
 	  offset = gridsize*levelID;
 
-	  if ( varID == thoID ) streamReadRecord(streamID1, tho.ptr+offset, &(tho.nmiss));
+	  if ( varID == toID ) streamReadRecord(streamID1, to.ptr+offset, &(to.nmiss));
 	  if ( varID == saoID ) streamReadRecord(streamID1, sao.ptr+offset, &(sao.nmiss));
 	}
 
-      calc_rhopot(gridsize, nlevel, pressure, tho, sao, rho); 
+      calc_rhopot(gridsize, nlevel, pressure, to, sao, rho); 
 
       for ( levelID = 0; levelID < nlevel; ++levelID )
 	{
@@ -343,7 +334,7 @@ void *Rhopot(void *argument)
 
   free(pressure);
   free(rho.ptr);
-  free(tho.ptr);
+  free(to.ptr);
   free(sao.ptr);
 
   cdoFinish();
diff --git a/src/Rotuv.c b/src/Rotuv.c
index ce75a57..ddcc24f 100644
--- a/src/Rotuv.c
+++ b/src/Rotuv.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Runpctl.c b/src/Runpctl.c
index 247c36f..ae48eab 100644
--- a/src/Runpctl.c
+++ b/src/Runpctl.c
@@ -46,9 +46,9 @@ void *Runpctl(void *argument)
   int *recVarID, *recLevelID;
   double missval, val;
   field_t ***vars1 = NULL;
-  datetime_t *datetime;
+  dtinfo_t *dtinfo;
   int taxisID1, taxisID2;
-  int calendar, dpy;
+  int calendar;
   int pn;
   double *array;
 
@@ -74,7 +74,6 @@ void *Runpctl(void *argument)
   vlistDefTaxis(vlistID2, taxisID2);
 
   calendar = taxisInqCalendar(taxisID1);
-  dpy      = calendar_dpy(calendar);
 
   streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
 
@@ -86,7 +85,7 @@ void *Runpctl(void *argument)
   recVarID   = (int *) malloc(nrecords*sizeof(int));
   recLevelID = (int *) malloc(nrecords*sizeof(int));
 
-  datetime = (datetime_t *) malloc((ndates+1)*sizeof(datetime_t));
+  dtinfo = (dtinfo_t *) malloc((ndates+1)*sizeof(dtinfo_t));
   vars1 = (field_t ***) malloc((ndates+1)*sizeof(field_t **));
   array = (double *) malloc(ndates*sizeof(double));
   
@@ -119,8 +118,7 @@ void *Runpctl(void *argument)
       if ( nrecs == 0 )
         cdoAbort("File has less than %d timesteps!", ndates);
 
-      datetime[tsID].date = taxisInqVdate(taxisID1);
-      datetime[tsID].time = taxisInqVtime(taxisID1);
+      taxisInqDTinfo(taxisID1, &dtinfo[tsID]);
         
       for ( recID = 0; recID < nrecs; recID++ )
         {
@@ -174,10 +172,15 @@ void *Runpctl(void *argument)
             }
         }
      
-      datetime_avg(dpy, ndates, datetime);
+      datetime_avg_dtinfo(calendar, ndates, dtinfo);
 
-      taxisDefVdate(taxisID2, datetime[ndates].date);
-      taxisDefVtime(taxisID2, datetime[ndates].time);
+      if ( taxisHasBounds(taxisID2) )
+	{
+	  dtinfo[ndates].b[0] = dtinfo[0].b[0];
+	  dtinfo[ndates].b[1] = dtinfo[ndates-1].b[1];
+	}
+
+      taxisDefDTinfo(taxisID2, dtinfo[ndates]);
       streamDefTimestep(streamID2, otsID);
 
       for ( recID = 0; recID < nrecords; recID++ )
@@ -193,20 +196,19 @@ void *Runpctl(void *argument)
 
       otsID++;
 
-      datetime[ndates] = datetime[0];
+      dtinfo[ndates] = dtinfo[0];
       vars1[ndates] = vars1[0];
 
       for ( inp = 0; inp < ndates; inp++ )
         {
-          datetime[inp] = datetime[inp+1];
+          dtinfo[inp] = dtinfo[inp+1];
           vars1[inp] = vars1[inp+1];
         }
 
       nrecs = streamInqTimestep(streamID1, tsID);
       if ( nrecs == 0 ) break;
 
-      datetime[ndates-1].date = taxisInqVdate(taxisID1);
-      datetime[ndates-1].time = taxisInqVtime(taxisID1);
+      taxisInqDTinfo(taxisID1, &dtinfo[ndates-1]);
 
       for ( recID = 0; recID < nrecs; recID++ )
         {
diff --git a/src/Runstat.c b/src/Runstat.c
index e2716cb..218d00f 100644
--- a/src/Runstat.c
+++ b/src/Runstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -24,7 +24,9 @@
       Runstat    runmean         Running mean
       Runstat    runavg          Running average
       Runstat    runvar          Running variance
+      Runstat    runvar1         Running variance [Divisor is (n-1)]
       Runstat    runstd          Running standard deviation
+      Runstat    runstd1         Running standard deviation [Divisor is (n-1)]
 */
 
 #include <cdi.h>
@@ -33,6 +35,47 @@
 #include "pstream.h"
 
 
+void datetime_avg_dtinfo(int calendar, int ndates, dtinfo_t *dtinfo)
+{
+  int vdate, vtime;
+  juldate_t juldate1, juldate2, juldatem;
+  double seconds;
+  /*
+  for ( i = 0; i < ndates; i++ )
+    fprintf(stdout, "%4d %d %d\n", i+1, dtinfo[i].v.date, dtinfo[i].v.time);
+  */
+  if ( ndates%2 == 0 )
+    {
+      /*
+      vdate = dtinfo[ndates-1].v.date;
+      vtime = dtinfo[ndates-1].v.time;
+      */
+      vdate = dtinfo[ndates/2-1].v.date;
+      vtime = dtinfo[ndates/2-1].v.time;
+      juldate1 = juldate_encode(calendar, vdate, vtime);
+
+      vdate = dtinfo[ndates/2].v.date;
+      vtime = dtinfo[ndates/2].v.time;
+      juldate2 = juldate_encode(calendar, vdate, vtime);
+
+      seconds = juldate_to_seconds(juldate_sub(juldate2, juldate1)) / 2;
+      juldatem = juldate_add_seconds(NINT(seconds), juldate1);
+      juldate_decode(calendar, juldatem, &vdate, &vtime);
+    }
+  else
+    {
+      vdate = dtinfo[ndates/2].v.date;
+      vtime = dtinfo[ndates/2].v.time;
+    }
+
+  dtinfo[ndates].v.date = vdate;
+  dtinfo[ndates].v.time = vtime;
+  /*
+  fprintf(stdout, "res: %d %d\n\n", dtinfo[ndates].v.date, dtinfo[ndates].v.time);
+  */
+}
+
+
 void datetime_avg(int calendar, int ndates, datetime_t *datetime)
 {
   int vdate, vtime;
@@ -74,6 +117,35 @@ void datetime_avg(int calendar, int ndates, datetime_t *datetime)
 }
 
 
+void get_timestat_date(int *tstat_date)
+{
+  char *envstr;
+
+  envstr = getenv("TIMESTAT_DATE");
+  if ( envstr == NULL ) envstr = getenv("RUNSTAT_DATE");
+  if ( envstr )
+    {
+      int env_date = -1;
+      char envstrl[8];
+
+      memcpy(envstrl, envstr, 8);
+      envstrl[7] = 0;
+      strtolower(envstrl);
+
+      if      ( memcmp(envstrl, "first", 5)  == 0 )  env_date = DATE_FIRST;
+      else if ( memcmp(envstrl, "last", 4)   == 0 )  env_date = DATE_LAST;
+      else if ( memcmp(envstrl, "middle", 6) == 0 )  env_date = DATE_MIDDLE;
+
+      if ( env_date >= 0 )
+	{
+	  *tstat_date = env_date;
+
+	  if ( cdoVerbose ) cdoPrint("Set TIMESTAT_DATE to %s", envstr);
+	}
+    }
+}
+
+
 void *Runstat(void *argument)
 {
   int operatorID;
@@ -82,7 +154,6 @@ void *Runstat(void *argument)
   int i;
   int varID;
   int recID;
-  int gridID;
   int nrecs, nrecords;
   int levelID;
   int tsID;
@@ -93,14 +164,16 @@ void *Runstat(void *argument)
   int nmiss;
   int nvars, nlevel;
   int *recVarID, *recLevelID;
+  int lmean = FALSE, lvarstd = FALSE, lstd = FALSE;
   int *imask;
   double missval;
+  double divisor;
   field_t ***vars1 = NULL, ***vars2 = NULL, ***samp1 = NULL;
-  datetime_t *datetime;
+  dtinfo_t *dtinfo;
   int taxisID1, taxisID2;
   int calendar;
   int runstat_nomiss = 0;
-  int runstat_date = DATE_MIDDLE;
+  int timestat_date = DATE_MIDDLE;
   char *envstr;
 
   cdoInitialize(argument);
@@ -113,29 +186,7 @@ void *Runstat(void *argument)
       if ( envval == 1 ) runstat_nomiss = 1;
     }
 
-  envstr = getenv("RUNSTAT_DATE");
-  if ( envstr )
-    {
-      int env_date = -1;
-
-      if      ( memcmp(envstr, "first", 5) == 0 ||
-		memcmp(envstr, "FIRST", 5) == 0 ||
-		memcmp(envstr, "First", 5) == 0 )  env_date = DATE_FIRST;
-      else if ( memcmp(envstr, "last", 4) == 0 ||
-		memcmp(envstr, "LAST", 4) == 0 ||
-		memcmp(envstr, "Last", 4) == 0 )   env_date = DATE_LAST;
-      else if ( memcmp(envstr, "middle", 6) == 0 ||
-		memcmp(envstr, "MIDDLE", 6) == 0 ||
-		memcmp(envstr, "Middle", 6) == 0 ) env_date = DATE_MIDDLE;
-
-      if ( env_date >= 0 )
-	{
-	  runstat_date = env_date;
-
-	  if ( cdoVerbose )
-	    cdoPrint("Set RUNSTAT_DATE to %s", envstr);
-	}
-    }
+  get_timestat_date(&timestat_date);
 
   cdoOperatorAdd("runmin",  func_min,  0, NULL);
   cdoOperatorAdd("runmax",  func_max,  0, NULL);
@@ -143,7 +194,9 @@ void *Runstat(void *argument)
   cdoOperatorAdd("runmean", func_mean, 0, NULL);
   cdoOperatorAdd("runavg",  func_avg,  0, NULL);
   cdoOperatorAdd("runvar",  func_var,  0, NULL);
+  cdoOperatorAdd("runvar1", func_var1, 0, NULL);
   cdoOperatorAdd("runstd",  func_std,  0, NULL);
+  cdoOperatorAdd("runstd1", func_std1, 0, NULL);
 
   operatorID = cdoOperatorID();
   operfunc = cdoOperatorF1(operatorID);
@@ -151,6 +204,11 @@ void *Runstat(void *argument)
   operatorInputArg("number of timesteps");
   ndates = atoi(operatorArgv()[0]);
 
+  lmean   = operfunc == func_mean || operfunc == func_avg;
+  lstd    = operfunc == func_std || operfunc == func_std1;
+  lvarstd = operfunc == func_std || operfunc == func_var || operfunc == func_std1 || operfunc == func_var1;
+  divisor = operfunc == func_std1 || operfunc == func_var1;
+
   streamID1 = streamOpenRead(cdoStreamName(0));
 
   vlistID1 = streamInqVlist(streamID1);
@@ -172,57 +230,20 @@ void *Runstat(void *argument)
   recVarID   = (int *) malloc(nrecords*sizeof(int));
   recLevelID = (int *) malloc(nrecords*sizeof(int));
 
-  datetime = (datetime_t *) malloc((ndates+1)*sizeof(datetime_t));
+  dtinfo = (dtinfo_t *) malloc((ndates+1)*sizeof(dtinfo_t));
   vars1 = (field_t ***) malloc((ndates+1)*sizeof(field_t **));
   if ( !runstat_nomiss )
     samp1 = (field_t ***) malloc((ndates+1)*sizeof(field_t **));
-  if ( operfunc == func_std || operfunc == func_var )
+  if ( lvarstd )
     vars2 = (field_t ***) malloc((ndates+1)*sizeof(field_t **));
 
   for ( its = 0; its < ndates; its++ )
     {
-      vars1[its] = (field_t **) malloc(nvars*sizeof(field_t *));
+      vars1[its] = field_malloc(vlistID1, FIELD_PTR);
       if ( !runstat_nomiss )
-	samp1[its] = (field_t **) malloc(nvars*sizeof(field_t *));
-      if ( operfunc == func_std || operfunc == func_var )
-	vars2[its] = (field_t **) malloc(nvars*sizeof(field_t *));
-
-      for ( varID = 0; varID < nvars; varID++ )
-	{
-	  gridID   = vlistInqVarGrid(vlistID1, varID);
-	  gridsize = gridInqSize(gridID);
-	  nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-	  missval  = vlistInqVarMissval(vlistID1, varID);
-
-	  vars1[its][varID] = (field_t *)  malloc(nlevel*sizeof(field_t));
-	  if ( !runstat_nomiss )
-	    samp1[its][varID] = (field_t *)  malloc(nlevel*sizeof(field_t));
-	  if ( operfunc == func_std || operfunc == func_var )
-	    vars2[its][varID] = (field_t *)  malloc(nlevel*sizeof(field_t));
-
-	  for ( levelID = 0; levelID < nlevel; levelID++ )
-	    {
-	      vars1[its][varID][levelID].grid    = gridID;
-	      vars1[its][varID][levelID].nmiss   = 0;
-	      vars1[its][varID][levelID].missval = missval;
-	      vars1[its][varID][levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
-	      if ( !runstat_nomiss )
-		{
-		  samp1[its][varID][levelID].grid    = gridID;
-		  samp1[its][varID][levelID].nmiss   = 0;
-		  samp1[its][varID][levelID].missval = missval;
-		  samp1[its][varID][levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
-		}
-
-	      if ( operfunc == func_std || operfunc == func_var )
-		{
-		  vars2[its][varID][levelID].grid    = gridID;
-		  vars2[its][varID][levelID].nmiss   = 0;
-		  vars2[its][varID][levelID].missval = missval;
-		  vars2[its][varID][levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
-		}
-	    }
-	}
+	samp1[its] = field_malloc(vlistID1, FIELD_PTR);
+      if ( lvarstd )
+	vars2[its] = field_malloc(vlistID1, FIELD_PTR);
     }
 
   gridsizemax = vlistGridsizeMax(vlistID1);
@@ -231,11 +252,9 @@ void *Runstat(void *argument)
   for ( tsID = 0; tsID < ndates; tsID++ )
     {
       nrecs = streamInqTimestep(streamID1, tsID);
-      if ( nrecs == 0 )
-	cdoAbort("File has less then %d timesteps!", ndates);
+      if ( nrecs == 0 ) cdoAbort("File has less then %d timesteps!", ndates);
 
-      datetime[tsID].date = taxisInqVdate(taxisID1);
-      datetime[tsID].time = taxisInqVtime(taxisID1);
+      taxisInqDTinfo(taxisID1, &dtinfo[tsID]);
 	
       for ( recID = 0; recID < nrecs; recID++ )
 	{
@@ -277,7 +296,7 @@ void *Runstat(void *argument)
 		}
 	    }
 
-	  if ( operfunc == func_std || operfunc == func_var )
+	  if ( lvarstd )
 	    {
 	      farmoq(&vars2[tsID][varID][levelID], vars1[tsID][varID][levelID]);
 #if defined (_OPENMP)
@@ -305,7 +324,7 @@ void *Runstat(void *argument)
   otsID = 0;
   while ( TRUE )
     {
-      if ( operfunc == func_mean || operfunc == func_avg )
+      if ( lmean )
 	for ( varID = 0; varID < nvars; varID++ )
 	  {
 	    if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
@@ -318,7 +337,7 @@ void *Runstat(void *argument)
 		  fardiv(&vars1[0][varID][levelID], samp1[0][varID][levelID]);
 	      }
 	  }
-      else if ( operfunc == func_std || operfunc == func_var )
+      else if ( lvarstd )
 	for ( varID = 0; varID < nvars; varID++ )
 	  {
 	    if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
@@ -327,39 +346,32 @@ void *Runstat(void *argument)
 	      {
 		if ( runstat_nomiss )
 		  {
-		    if ( operfunc == func_std )
-		      farcstd(&vars1[0][varID][levelID], vars2[0][varID][levelID], 1.0/ndates);
+		    if ( lstd )
+		      farcstdx(&vars1[0][varID][levelID], vars2[0][varID][levelID], ndates, divisor);
 		    else
-		      farcvar(&vars1[0][varID][levelID], vars2[0][varID][levelID], 1.0/ndates);
+		      farcvarx(&vars1[0][varID][levelID], vars2[0][varID][levelID], ndates, divisor);
 		  }
 		else
 		  {
-		    farinv(&samp1[0][varID][levelID]);
-		    if ( operfunc == func_std )
-		      farstd(&vars1[0][varID][levelID], vars2[0][varID][levelID], samp1[0][varID][levelID]);
+		    if ( lstd )
+		      farstdx(&vars1[0][varID][levelID], vars2[0][varID][levelID], samp1[0][varID][levelID], divisor);
 		    else
-		      farvar(&vars1[0][varID][levelID], vars2[0][varID][levelID], samp1[0][varID][levelID]);
+		      farvarx(&vars1[0][varID][levelID], vars2[0][varID][levelID], samp1[0][varID][levelID], divisor);
 		  }
 	      }
 	  }
 
-      if ( runstat_date == DATE_MIDDLE )
-	{
-	  datetime_avg(calendar, ndates, datetime);
-	}
-      else if ( runstat_date == DATE_FIRST )
-	{
-	  datetime[ndates].date = datetime[0].date;
-	  datetime[ndates].time = datetime[0].time;
-	}
-      else if ( runstat_date == DATE_LAST )
+      if      ( timestat_date == DATE_MIDDLE ) datetime_avg_dtinfo(calendar, ndates, dtinfo);
+      else if ( timestat_date == DATE_FIRST  ) dtinfo[ndates].v = dtinfo[0].v;
+      else if ( timestat_date == DATE_LAST   ) dtinfo[ndates].v = dtinfo[ndates-1].v;
+
+      if ( taxisHasBounds(taxisID2) )
 	{
-	  datetime[ndates].date = datetime[ndates-1].date;
-	  datetime[ndates].time = datetime[ndates-1].time;
+	  dtinfo[ndates].b[0] = dtinfo[0].b[0];
+	  dtinfo[ndates].b[1] = dtinfo[ndates-1].b[1];
 	}
 
-      taxisDefVdate(taxisID2, datetime[ndates].date);
-      taxisDefVtime(taxisID2, datetime[ndates].time);
+      taxisDefDTinfo(taxisID2, dtinfo[ndates]);
       streamDefTimestep(streamID2, otsID);
 
       for ( recID = 0; recID < nrecords; recID++ )
@@ -375,28 +387,27 @@ void *Runstat(void *argument)
 
       otsID++;
 
-      datetime[ndates] = datetime[0];
+      dtinfo[ndates] = dtinfo[0];
       vars1[ndates] = vars1[0];
       if ( !runstat_nomiss )
 	samp1[ndates] = samp1[0];
-      if ( operfunc == func_std || operfunc == func_var )
+      if ( lvarstd )
         vars2[ndates] = vars2[0];
 
       for ( inp = 0; inp < ndates; inp++ )
 	{
-	  datetime[inp] = datetime[inp+1];
+	  dtinfo[inp] = dtinfo[inp+1];
 	  vars1[inp] = vars1[inp+1];
 	  if ( !runstat_nomiss )
 	    samp1[inp] = samp1[inp+1];
-	  if ( operfunc == func_std || operfunc == func_var )
+	  if ( lvarstd )
 	    vars2[inp] = vars2[inp+1];
 	}
 
       nrecs = streamInqTimestep(streamID1, tsID);
       if ( nrecs == 0 ) break;
 
-      datetime[ndates-1].date = taxisInqVdate(taxisID1);
-      datetime[ndates-1].time = taxisInqVtime(taxisID1);
+      taxisInqDTinfo(taxisID1, &dtinfo[ndates-1]);
 
       for ( recID = 0; recID < nrecs; recID++ )
 	{
@@ -432,7 +443,7 @@ void *Runstat(void *argument)
 		}
 	    }
 
-	  if ( operfunc == func_std || operfunc == func_var )
+	  if ( lvarstd )
 	    {
 	      farmoq(&vars2[ndates-1][varID][levelID], vars1[ndates-1][varID][levelID]);
 #if defined (_OPENMP)
@@ -461,30 +472,15 @@ void *Runstat(void *argument)
 
   for ( its = 0; its < ndates; its++ )
     {
-      for ( varID = 0; varID < nvars; varID++ )
-	{
-	  nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-	  for ( levelID = 0; levelID < nlevel; levelID++ )
-	    {
-	      free(vars1[its][varID][levelID].ptr);
-	      if ( !runstat_nomiss ) free(samp1[its][varID][levelID].ptr);
-	      if ( operfunc == func_std || operfunc == func_var ) free(vars2[its][varID][levelID].ptr);
-	    }
-
-	  free(vars1[its][varID]);
-	  if ( !runstat_nomiss ) free(samp1[its][varID]);
-	  if ( operfunc == func_std || operfunc == func_var ) free(vars2[its][varID]);
-	}
-
-      free(vars1[its]);
-      if ( !runstat_nomiss ) free(samp1[its]);
-      if ( operfunc == func_std || operfunc == func_var ) free(vars2[its]);
+      field_free(vars1[its], vlistID1);
+      if ( !runstat_nomiss ) field_free(samp1[its], vlistID1);
+      if ( lvarstd ) field_free(vars2[its], vlistID1);
     }
 
-  free(datetime);
+  free(dtinfo);
   free(vars1);
   if ( !runstat_nomiss ) free(samp1);
-  if ( operfunc == func_std || operfunc == func_var ) free(vars2);
+  if ( lvarstd ) free(vars2);
 
   if ( recVarID   ) free(recVarID);
   if ( recLevelID ) free(recLevelID);
diff --git a/src/Scatter.c b/src/Scatter.c
index e62864b..3658b7b 100644
--- a/src/Scatter.c
+++ b/src/Scatter.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Seasstat.c b/src/Seasstat.c
index e1518ca..1328472 100644
--- a/src/Seasstat.c
+++ b/src/Seasstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -49,7 +49,7 @@ void *Seasstat(void *argument)
   int otsID;
   long nsets;
   int i;
-  int year, month, seas, seas0 = 0;
+  int year, month, day, seas, seas0 = 0;
   int streamID1, streamID2;
   int vlistID1, vlistID2, taxisID1, taxisID2;
   int nmiss;
@@ -149,8 +149,7 @@ void *Seasstat(void *argument)
 	{
 	  vdate = taxisInqVdate(taxisID1);
 	  vtime = taxisInqVtime(taxisID1);
-	  year  =  vdate / 10000;
-	  month = (vdate - year*10000) / 100;
+	  cdiDecodeDate(vdate, &year, &month, &day);
 	  if ( month < 1 || month > 12 )
 	    cdoAbort("Month %d out of range!", month);
 
diff --git a/src/Selbox.c b/src/Selbox.c
index 0a2eeb2..a91ac2e 100644
--- a/src/Selbox.c
+++ b/src/Selbox.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -345,9 +345,9 @@ int gengridcell(int gridID1, int gridsize2, int *cellidx)
 }
 
 
-void genlonlatbox(double xlon1, double xlon2, double xlat1, double xlat2,
-		  int nlon1, int nlat1, double *xvals1, double *yvals1,
-		  int *lat1, int *lat2, int *lon11, int *lon12, int *lon21, int *lon22)
+void genlonlatbox_reg(double xlon1, double xlon2, double xlat1, double xlat2,
+		      int nlon1, int nlat1, double *xvals1, double *yvals1,
+		      int *lat1, int *lat2, int *lon11, int *lon12, int *lon21, int *lon22)
 {
   if ( IS_NOT_EQUAL(xlon1, xlon2) )
     {
@@ -414,12 +414,12 @@ void genlonlatbox(double xlon1, double xlon2, double xlat1, double xlat2,
     cdoAbort("Latitudinal dimension is too small!");
 }
 
-static
-int genlonlatgrid(int gridID1, int *lat1, int *lat2, int *lon11, int *lon12, int *lon21, int *lon22)
+
+void genlonlatbox(int argc_offset, int gridID1, int *lat1, int *lat2, int *lon11, int *lon12, int *lon21, int *lon22)
 {
   int ilon, ilat;
   int nlon1, nlat1;
-  int gridtype, gridID2;
+  int gridtype;
   double *xvals1, *yvals1;
   double xlon1, xlon2, xlat1, xlat2;
   int grid_is_circular;
@@ -427,12 +427,12 @@ int genlonlatgrid(int gridID1, int *lat1, int *lat2, int *lon11, int *lon12, int
   char yunits[CDI_MAX_NAME];
   double xfact = 1, yfact = 1;
 
-  operatorCheckArgc(4);
+  operatorCheckArgc(argc_offset+4);
 
-  xlon1 = atof(operatorArgv()[0]);
-  xlon2 = atof(operatorArgv()[1]);
-  xlat1 = atof(operatorArgv()[2]);
-  xlat2 = atof(operatorArgv()[3]);
+  xlon1 = atof(operatorArgv()[argc_offset+0]);
+  xlon2 = atof(operatorArgv()[argc_offset+1]);
+  xlat1 = atof(operatorArgv()[argc_offset+2]);
+  xlat2 = atof(operatorArgv()[argc_offset+3]);
 
   gridtype = gridInqType(gridID1);
 
@@ -463,8 +463,7 @@ int genlonlatgrid(int gridID1, int *lat1, int *lat2, int *lon11, int *lon12, int
 
   if ( gridtype == GRID_CURVILINEAR )
     {
-      double xval, yval, xlast, ylast;
-      int ixmin, ixmax, iymin, iymax;
+      double xval, yval, xfirst, xlast, ylast;
       int lp2 = FALSE;
 
       if ( xlon1 > xlon2 ) 
@@ -484,17 +483,12 @@ int genlonlatgrid(int gridID1, int *lat1, int *lat2, int *lon11, int *lon12, int
       *lon21 = nlon1-1;
       *lon22 = 0;
 
-      ixmin = nlon1-1;
-      ixmax = 0;
-      iymin = nlat1-1;
-      iymax = 0;
-
       for ( ilat = 0; ilat < nlat1; ilat++ )
 	{
 	  xlast = xfact * xvals1[ilat*nlon1 + nlon1-1];
 	  ylast = yfact * yvals1[ilat*nlon1 + nlon1-1];
 	  if ( ylast >= xlat1 && ylast <= xlat2 )
-	    if ( grid_is_circular && xlon1 <= xlast && xlon2 > xlast && (xlon2-xlon1) < 360)
+	    if ( grid_is_circular && xlon1 <= xlast && xlon2 > xlast && (xlon2-xlon1) < 360 )
 	      {
 		*lon11 = nlon1-1;
 		*lon12 = 0;
@@ -504,8 +498,6 @@ int genlonlatgrid(int gridID1, int *lat1, int *lat2, int *lon11, int *lon12, int
 
       for ( ilat = 0; ilat < nlat1; ilat++ )
 	{
-	  xlast = xfact * xvals1[ilat*nlon1 + nlon1-1];
-
 	  for ( ilon = 0; ilon < nlon1; ilon++ )
 	    {
 	      xval = xvals1[ilat*nlon1 + ilon];
@@ -514,11 +506,16 @@ int genlonlatgrid(int gridID1, int *lat1, int *lat2, int *lon11, int *lon12, int
 	      xval *= xfact;
 	      yval *= yfact;
 
-
 	      if ( yval >= xlat1 && yval <= xlat2 )
 		{
 		  if ( lp2 )
 		    {
+		      xfirst = xfact * xvals1[ilat*nlon1];
+		      if ( xfirst < xlon1 ) xfirst = xlon1;
+
+		      xlast = xfact * xvals1[ilat*nlon1 + nlon1-1];
+		      if ( xlast > xlon2 ) xlast = xlon2;
+
 		      if ( xval >= xlon1 && xval <= xlast )
 			{
 			  if ( ilon < *lon21 ) *lon21 = ilon;
@@ -526,7 +523,7 @@ int genlonlatgrid(int gridID1, int *lat1, int *lat2, int *lon11, int *lon12, int
 			  if ( ilat < *lat1 ) *lat1 = ilat;
 			  if ( ilat > *lat2 ) *lat2 = ilat;
 			}
-		      else if ( xval > xlast && xval <= xlon2 )
+		      else if ( xval >= xfirst && xval <= xlon2 )
 			{
 			  if ( ilon < *lon11 ) *lon11 = ilon;
 			  if ( ilon > *lon12 ) *lon12 = ilon;
@@ -536,27 +533,22 @@ int genlonlatgrid(int gridID1, int *lat1, int *lat2, int *lon11, int *lon12, int
 		    }
 		  else
 		    {
-		      if ( ((xval >= xlon1 && xval <= xlon2) ||
+		      if ( ((xval     >= xlon1 && xval     <= xlon2) ||
 			    (xval-360 >= xlon1 && xval-360 <= xlon2) ||
 			    (xval+360 >= xlon1 && xval+360 <= xlon2)) )
 			{
-			  if ( ilon < ixmin ) ixmin = ilon;
-			  if ( ilon > ixmax ) ixmax = ilon;
-			  if ( ilat < iymin ) iymin = ilat;
-			  if ( ilat > iymax ) iymax = ilat;
+			  if ( ilon < *lon21 ) *lon21 = ilon;
+			  if ( ilon > *lon22 ) *lon22 = ilon;
+			  if ( ilat < *lat1 ) *lat1 = ilat;
+			  if ( ilat > *lat2 ) *lat2 = ilat;
 			}
 		    }
 		}
 	    }
 	}
 
-      if ( ! lp2 )
-	{
-	  *lat1 = iymin;
-	  *lat2 = iymax;
-	  *lon21 = ixmin;
-	  *lon22 = ixmax;
-	}      
+      // printf("lon11, lon12, lon21, lon22, lat1, lat2 %d %d %d %d %d %d\n", *lon11, *lon12, *lon21, *lon22, *lat1, *lat2);
+      if ( *lon12 == 0 && *lon11 > 0 ) *lon11 = -1;
 
       if ( *lat2 - *lat1 + 1 <= 0 )
 	cdoAbort("Latitudinal dimension is too small!");
@@ -566,13 +558,21 @@ int genlonlatgrid(int gridID1, int *lat1, int *lat2, int *lon11, int *lon12, int
       for ( ilat = 0; ilat < nlat1; ilat++ ) yvals1[ilat] *= yfact;
       for ( ilon = 0; ilon < nlon1; ilon++ ) xvals1[ilon] *= xfact;
 
-      genlonlatbox(xlon1, xlon2, xlat1, xlat2,
-		   nlon1, nlat1, xvals1, yvals1,
-		   lat1, lat2, lon11, lon12, lon21, lon22);
+      genlonlatbox_reg(xlon1, xlon2, xlat1, xlat2,
+		       nlon1, nlat1, xvals1, yvals1,
+		       lat1, lat2, lon11, lon12, lon21, lon22);
     }
 
   free(xvals1);
   free(yvals1);
+}
+
+static
+int genlonlatgrid(int gridID1, int *lat1, int *lat2, int *lon11, int *lon12, int *lon21, int *lon22)
+{
+  int gridID2;
+
+  genlonlatbox(0, gridID1, lat1, lat2, lon11, lon12, lon21, lon22);
 
   gridID2 = gengrid(gridID1, *lat1, *lat2, *lon11, *lon12, *lon21, *lon22);
 
@@ -592,13 +592,14 @@ int gencellgrid(int gridID1, int *gridsize2, int **cellidx)
   char xunits[CDI_MAX_NAME];
   char yunits[CDI_MAX_NAME];
   double xfact, yfact;
+  int argc_offset = 0;
 
-  operatorCheckArgc(4);
+  operatorCheckArgc(argc_offset+4);
 
-  xlon1 = atof(operatorArgv()[0]);
-  xlon2 = atof(operatorArgv()[1]);
-  xlat1 = atof(operatorArgv()[2]);
-  xlat2 = atof(operatorArgv()[3]);
+  xlon1 = atof(operatorArgv()[argc_offset+0]);
+  xlon2 = atof(operatorArgv()[argc_offset+1]);
+  xlat1 = atof(operatorArgv()[argc_offset+2]);
+  xlat2 = atof(operatorArgv()[argc_offset+3]);
 
   if ( xlon1 >= xlon2 ) { x = xlon1; xlon1 = xlon2; xlon2 = x; }
   if ( xlat1 >= xlat2 ) { x = xlat1; xlat1 = xlat2; xlat2 = x; }
@@ -661,19 +662,18 @@ int gencellgrid(int gridID1, int *gridsize2, int **cellidx)
   return (gridID2);
 }
 
-static
-int genindexgrid(int gridID1, int *lat1, int *lat2, int *lon11, int *lon12, int *lon21, int *lon22)
+
+void genindexbox(int argc_offset, int gridID1, int *lat1, int *lat2, int *lon11, int *lon12, int *lon21, int *lon22)
 {
-  int gridID2;
   int nlon1, nlat1;
   int temp;
 
-  operatorCheckArgc(4);
+  operatorCheckArgc(argc_offset+4);
 
-  *lon11 = atoi(operatorArgv()[0]);
-  *lon12 = atoi(operatorArgv()[1]);
-  *lat1  = atoi(operatorArgv()[2]);
-  *lat2  = atoi(operatorArgv()[3]);
+  *lon11 = atoi(operatorArgv()[argc_offset+0]);
+  *lon12 = atoi(operatorArgv()[argc_offset+1]);
+  *lat1  = atoi(operatorArgv()[argc_offset+2]);
+  *lat2  = atoi(operatorArgv()[argc_offset+3]);
 
   if ( *lat1 > *lat2 )
     {
@@ -742,6 +742,14 @@ int genindexgrid(int gridID1, int *lat1, int *lat2, int *lon11, int *lon12, int
 	  *lon22 = -1;
 	}
     }
+}
+
+static
+int genindexgrid(int gridID1, int *lat1, int *lat2, int *lon11, int *lon12, int *lon21, int *lon22)
+{
+  int gridID2;
+
+  genindexbox(0, gridID1, lat1, lat2, lon11, lon12, lon21, lon22);
 
   gridID2 = gengrid(gridID1, *lat1, *lat2, *lon11, *lon12, *lon21, *lon22);
 
@@ -953,7 +961,7 @@ void *Selbox(void *argument)
 
 	      gridsize2 = gridInqSize(sbox[index].gridID2);
 
-	      if ( operatorID == SELLONLATBOX  && gridtype == GRID_UNSTRUCTURED )
+	      if ( operatorID == SELLONLATBOX && gridtype == GRID_UNSTRUCTURED )
 		window_cell(nwpv, array1, gridID1, array2, gridsize2, sbox[index].cellidx);
  	      else
 		window(nwpv, array1, gridID1, array2, sbox[index].lat1, sbox[index].lat2, sbox[index].lon11, 
diff --git a/src/Select.c b/src/Select.c
index fa04017..3d1fa83 100644
--- a/src/Select.c
+++ b/src/Select.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Seloperator.c b/src/Seloperator.c
index f4c9212..5800303 100644
--- a/src/Seloperator.c
+++ b/src/Seloperator.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Selrec.c b/src/Selrec.c
index 109bf23..1c3f3ec 100644
--- a/src/Selrec.c
+++ b/src/Selrec.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Seltime.c b/src/Seltime.c
index 7c17f64..1b496f0 100644
--- a/src/Seltime.c
+++ b/src/Seltime.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -319,7 +319,9 @@ void *Seltime(void *argument)
 
   vlistID1 = streamInqVlist(streamID1);
   vlistID2 = vlistDuplicate(vlistID1);
-  if ( nsel == 1 && operfunc == func_step )  vlistDefNtsteps(vlistID2, 1);
+
+  if ( nsel == 1 && operfunc == func_step )  vlistDefNtsteps(vlistID2,  1);
+  else                                       vlistDefNtsteps(vlistID2, -1);
 
   taxisID1 = vlistInqTaxis(vlistID1);
   taxisID2 = taxisDuplicate(taxisID1);
@@ -604,9 +606,30 @@ void *Seltime(void *argument)
     {
       if ( selfound[isel] == FALSE )
 	{
+	 
+	  int isel2;
+	  int lcont = FALSE;
+	  for ( isel2 = isel+1; isel2 < nsel; isel2++ )
+	    if ( selfound[isel2] == TRUE ) break;
+	  if ( isel2 == nsel && (nsel-isel) > 1 ) lcont = TRUE;
+
 	  if ( operatorID == SELTIMESTEP )
 	    {
-	      cdoWarning("Time step %d not found!", intarr[isel]);
+	      int lcont2 = FALSE;
+	      if ( lcont )
+		{    
+		  for ( isel2 = isel+1; isel2 < nsel; isel2++ )
+		    if ( intarr[isel2-1] != intarr[isel2]-1 ) break;
+		  if ( isel2 == nsel ) lcont2 = TRUE;
+		}
+
+	      if ( lcont2 )
+		{
+		  cdoWarning("Time steps %d-%d not found!", intarr[isel], intarr[nsel-1]);
+		  break;
+		}
+	      else
+		cdoWarning("Time step %d not found!", intarr[isel]);
 	    }
 	  else if ( operatorID == SELDATE )
 	    {
diff --git a/src/Selvar.c b/src/Selvar.c
index b079d54..ba2a4dd 100644
--- a/src/Selvar.c
+++ b/src/Selvar.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Set.c b/src/Set.c
index 3c1a4a2..421be8e 100644
--- a/src/Set.c
+++ b/src/Set.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Setbox.c b/src/Setbox.c
index 1816c1b..9e4627b 100644
--- a/src/Setbox.c
+++ b/src/Setbox.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -29,124 +29,9 @@
 #include "grid.h"
 
 
-void genlonlatbox(double xlon1, double xlon2, double xlat1, double xlat2,
-		  int nlon1, int nlat1, double *xvals1, double *yvals1,
-		  int *lat1, int *lat2, int *lon11, int *lon12, int *lon21, int *lon22);
+void genlonlatbox(int argc_offset, int gridID1, int *lat1, int *lat2, int *lon11, int *lon12, int *lon21, int *lon22);
 
-static
-void genlonlatgrid(int gridID1, int *lat1, int *lat2, int *lon11, int *lon12, int *lon21, int *lon22, double *constant)
-{
-  int nlon1, nlat1;
-  double *xvals1, *yvals1;
-  double xlon1, xlon2, xlat1, xlat2;
-
-  operatorCheckArgc(5);
-
-  *constant = atof(operatorArgv()[0]);
-  xlon1 = atof(operatorArgv()[1]);
-  xlon2 = atof(operatorArgv()[2]);
-  xlat1 = atof(operatorArgv()[3]);
-  xlat2 = atof(operatorArgv()[4]);
-
-  nlon1 = gridInqXsize(gridID1);
-  nlat1 = gridInqYsize(gridID1);
-
-  xvals1 = (double *) malloc(nlon1*sizeof(double));
-  yvals1 = (double *) malloc(nlat1*sizeof(double));
-
-  gridInqXvals(gridID1, xvals1);
-  gridInqYvals(gridID1, yvals1);
-
-  /* Convert lat/lon units if required */
-  {
-    char units[CDI_MAX_NAME];
-    gridInqXunits(gridID1, units);
-    gridToDegree(units, "grid center lon", nlon1, xvals1);
-    gridInqYunits(gridID1, units);
-    gridToDegree(units, "grid center lat", nlat1, yvals1);
-  }
-
-  genlonlatbox(xlon1, xlon2, xlat1, xlat2,
-	       nlon1, nlat1, xvals1, yvals1,
-	       lat1, lat2, lon11, lon12, lon21, lon22);
-
-  free(xvals1);
-  free(yvals1);
-}
-
-
-static
-void genindexbox(int gridID1, int *lat1, int *lat2, int *lon11, int *lon12, int *lon21, int *lon22, double *constant)
-{
-  int nlon1, nlat1;
-  int temp;
-
-  operatorCheckArgc(5);
-
-  *constant = atof(operatorArgv()[0]);
-  *lon11 = atoi(operatorArgv()[1]);
-  *lon12 = atoi(operatorArgv()[2]);
-  *lat1  = atoi(operatorArgv()[3]);
-  *lat2  = atoi(operatorArgv()[4]);
-
-  if ( *lat1 > *lat2 )
-    {
-      temp = *lat1;
-      *lat1 = *lat2;
-      *lat2 = temp;
-    }
-
-  nlon1 = gridInqXsize(gridID1);
-  nlat1 = gridInqYsize(gridID1);
-
-  if ( *lat1 < 1 )
-    {
-      cdoWarning("first latitude index out of range. Set to 1.");
-      *lat1 = 1;
-    }
-  if ( *lat2 > nlat1 )
-    {
-      cdoWarning("last latitude index out of range. Set to %d.", nlat1);
-      *lat2 = nlat1;
-    }
-  if ( *lon11 < 1 )
-    {
-      cdoWarning("first longitude index out of range. Set to 1.");
-      *lon11 = 1;
-    }
-  if ( *lon12 > nlon1+1 )
-    {
-      cdoWarning("last longitude index out of range. Set to %d.", nlon1);
-      *lon12 = nlon1;
-    }
-
-  (*lon11)--;
-  (*lon12)--;
-  (*lat1)--;
-  (*lat2)--;
-
-  if ( *lon11 > *lon12 )
-    {
-      *lon21 = *lon11;
-      *lon22 = nlon1 - 1;
-      *lon11 = 0;
-    }
-  else
-    {
-      if ( *lon12 > nlon1-1 )
-	{
-	  *lon21 = *lon11;
-	  *lon22 = nlon1 - 1;
-	  *lon11 = 0;
-	  *lon12 = 0;
-	}
-      else
-	{
-	  *lon21 = 0;
-	  *lon22 = -1;
-	}
-    }
-}
+void genindexbox(int argc_offset, int gridID1, int *lat1, int *lat2, int *lon11, int *lon12, int *lon21, int *lon22);
 
 
 static
@@ -194,9 +79,12 @@ void *Setbox(void *argument)
   SETCLONLATBOX = cdoOperatorAdd("setclonlatbox", 0, 0, "constant, western and eastern longitude and southern and northern latitude");
   SETCINDEXBOX  = cdoOperatorAdd("setcindexbox",  0, 0, "constant, index of first and last longitude and index of first and last latitude");
 
-
   operatorID = cdoOperatorID();
 
+  operatorInputArg(cdoOperatorEnter(operatorID));
+
+  constant = atof(operatorArgv()[0]);
+
   streamID1 = streamOpenRead(cdoStreamName(0));
 
   vlistID1 = streamInqVlist(streamID1);
@@ -212,7 +100,7 @@ void *Setbox(void *argument)
       gridID   = vlistGrid(vlistID1, index);
       gridtype = gridInqType(gridID);
       if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN ) break;
-      if ( operatorID == SETCINDEXBOX && gridtype == GRID_CURVILINEAR ) break;
+      if ( gridtype == GRID_CURVILINEAR ) break;
       if ( operatorID == SETCINDEXBOX && gridtype == GRID_GENERIC &&
 	   gridInqXsize(gridID) > 0 && gridInqYsize(gridID) > 0 ) break;
     }
@@ -226,9 +114,9 @@ void *Setbox(void *argument)
   operatorInputArg(cdoOperatorEnter(operatorID));
 
   if ( operatorID == SETCLONLATBOX )
-    genlonlatgrid(gridID, &lat1, &lat2, &lon11, &lon12, &lon21, &lon22, &constant);
+    genlonlatbox(1, gridID, &lat1, &lat2, &lon11, &lon12, &lon21, &lon22);
   else
-    genindexbox(gridID, &lat1, &lat2, &lon11, &lon12, &lon21, &lon22, &constant);
+    genindexbox(1, gridID, &lat1, &lat2, &lon11, &lon12, &lon21, &lon22);
 
   vlistID2 = vlistDuplicate(vlistID1);
 
diff --git a/src/Setgatt.c b/src/Setgatt.c
index ae8e8b5..fd5d5d3 100644
--- a/src/Setgatt.c
+++ b/src/Setgatt.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Setgrid.c b/src/Setgrid.c
index c41d298..78e802f 100644
--- a/src/Setgrid.c
+++ b/src/Setgrid.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Sethalo.c b/src/Sethalo.c
index 3aefe6c..580bb0b 100644
--- a/src/Sethalo.c
+++ b/src/Sethalo.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Setmiss.c b/src/Setmiss.c
index 6fd4c8c..886dc9b 100644
--- a/src/Setmiss.c
+++ b/src/Setmiss.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Setpartab.c b/src/Setpartab.c
index 0e104ff..a90baf3 100644
--- a/src/Setpartab.c
+++ b/src/Setpartab.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -38,6 +38,10 @@
 #include "namelist.h"
 
 
+typedef enum {CODE_NUMBER, PARAMETER_ID, VARIABLE_NAME, STANDARD_NAME} pt_mode_t;
+
+#if defined (HAVE_LIBUDUNITS2)
+
 static void udunitsInitialize(void);
 static int udunitsInit = 0;
 
@@ -59,9 +63,7 @@ static pthread_mutex_t udunitsMutex;
 
 #endif
 
-typedef enum {CODE_NUMBER, PARAMETER_ID, VARIABLE_NAME, STANDARD_NAME} pt_mode_t;
 
-#if defined (HAVE_LIBUDUNITS2)
 ut_system *ut_read = NULL;
 
 static
@@ -163,6 +165,7 @@ void *get_converter(char *src_unit_str, char *tgt_unit_str, int *rstatus)
 
 typedef struct
 {
+  int delete;
   // missing value
   int changemissval;
   double missval_old;
@@ -212,11 +215,11 @@ void defineVarUnits(var_t *vars, int vlistID2, int varID, char *units, char *nam
     {
       if ( len1 > 0 && len2 > 0 )
 	{
-	  int status;
 	  vars[varID].changeunits = TRUE;
 	  strcpy(vars[varID].units_old, units_old);
 	  strcpy(vars[varID].units, units);
 #if defined (HAVE_LIBUDUNITS2)
+	  int status;
 	  UDUNITS_INIT();
 	  UDUNITS_LOCK();
 	  vars[varID].ut_converter = get_converter(units_old, units, &status);
@@ -265,12 +268,12 @@ void read_partab(pt_mode_t ptmode, int nvars, int vlistID2, var_t *vars)
 {
   FILE *fp;
   namelist_t *nml;
-  int nml_code, nml_out_code, nml_table, nml_param, nml_datatype, nml_name, nml_out_name, nml_stdname;
-  int nml_longname, nml_units, nml_comment, nml_ltype, nml_missval, nml_factor;
+  int nml_code, nml_out_code, nml_table, nml_param, nml_chunktype, nml_datatype, nml_type, nml_name, nml_out_name, nml_stdname;
+  int nml_longname, nml_units, nml_comment, nml_ltype, nml_delete, nml_missval, nml_factor;
   int nml_cell_methods, nml_cell_measures;
   int nml_valid_min, nml_valid_max, nml_ok_min_mean_abs, nml_ok_max_mean_abs;
   int locc, i;
-  int code, out_code, table, ltype;
+  int code, out_code, table, ltype, delete;
   int nml_index = 0;
   int codenum, tabnum, levtype, param;
   int varID, tableID;
@@ -279,7 +282,9 @@ void read_partab(pt_mode_t ptmode, int nvars, int vlistID2, var_t *vars)
   double missval, factor;
   double valid_min, valid_max, ok_min_mean_abs, ok_max_mean_abs;
   char *partab = NULL;
+  char *chunktypestr = NULL;
   char *datatypestr = NULL;
+  char *typestr = NULL;
   char *name = NULL, *out_name = NULL, *stdname = NULL, longname[CDI_MAX_NAME] = "", units[CDI_MAX_NAME] = "";
   char cell_methods[CDI_MAX_NAME] = "", cell_measures[CDI_MAX_NAME] = "";
   char varname[CDI_MAX_NAME];
@@ -301,6 +306,7 @@ void read_partab(pt_mode_t ptmode, int nvars, int vlistID2, var_t *vars)
       nml_out_code        = namelistAdd(nml, "out_code",        NML_INT,  0, &out_code, 1);
       nml_table           = namelistAdd(nml, "table",           NML_INT,  0, &table, 1);
       nml_ltype           = namelistAdd(nml, "ltype",           NML_INT,  0, &ltype, 1);
+      nml_delete          = namelistAdd(nml, "delete",          NML_INT,  0, &delete, 1);
       nml_missval         = namelistAdd(nml, "missing_value",   NML_FLT,  0, &missval, 1);
       nml_factor          = namelistAdd(nml, "factor",          NML_FLT,  0, &factor, 1);
       nml_valid_min       = namelistAdd(nml, "valid_min",       NML_FLT,  0, &valid_min, 1);
@@ -308,7 +314,9 @@ void read_partab(pt_mode_t ptmode, int nvars, int vlistID2, var_t *vars)
       nml_ok_min_mean_abs = namelistAdd(nml, "ok_min_mean_abs", NML_FLT,  0, &ok_min_mean_abs, 1);
       nml_ok_max_mean_abs = namelistAdd(nml, "ok_max_mean_abs", NML_FLT,  0, &ok_max_mean_abs, 1);
       nml_param           = namelistAdd(nml, "param",           NML_FLT,  0, &param_dp, 1);
-      nml_datatype        = namelistAdd(nml, "type",            NML_WORD, 0, &datatypestr, 1);
+      nml_chunktype       = namelistAdd(nml, "chunktype",       NML_WORD, 0, &chunktypestr, 1);
+      nml_datatype        = namelistAdd(nml, "datatype",        NML_WORD, 0, &datatypestr, 1);
+      nml_type            = namelistAdd(nml, "type",            NML_WORD, 0, &typestr, 1);
       nml_name            = namelistAdd(nml, "name",            NML_WORD, 0, &name, 1);
       nml_out_name        = namelistAdd(nml, "out_name",        NML_WORD, 0, &out_name, 1);
       nml_stdname         = namelistAdd(nml, "standard_name",   NML_WORD, 0, &stdname, 1);
@@ -386,7 +394,7 @@ void read_partab(pt_mode_t ptmode, int nvars, int vlistID2, var_t *vars)
 		      levtype = zaxisInqLtype(vlistInqVarZaxis(vlistID2, varID));
 		      
 		      //	printf("code = %d  tabnum = %d  ltype = %d\n", codenum, tabnum, levtype);
-		      code = (int) param_dp;
+		      code  = (int) param_dp;
 		      table = (param_dp-code)*1000;
 		      printf("code = %d  tabnum = %d  ltype = %d\n", code, table, levtype);
 		      
@@ -416,11 +424,17 @@ void read_partab(pt_mode_t ptmode, int nvars, int vlistID2, var_t *vars)
 		  if ( nml->entry[nml_comment]->occ  ) defineVarAttText(vlistID2, varID, "comment", comment);
 		  if ( nml->entry[nml_cell_methods]->occ  )  defineVarAttText(vlistID2, varID, "cell_methods", cell_methods);
 		  if ( nml->entry[nml_cell_measures]->occ  ) defineVarAttText(vlistID2, varID, "cell_measures", cell_measures);
+		  if ( nml->entry[nml_delete]->occ && delete == 1 ) vars[varID].delete = TRUE;
 		  if ( nml->entry[nml_datatype]->occ )
 		    {
 		      int datatype = str2datatype(datatypestr);
 		      if ( datatype != -1 ) vlistDefVarDatatype(vlistID2, varID, datatype);
 		    }
+		  if ( nml->entry[nml_type]->occ )
+		    {
+		      int datatype = str2datatype(typestr);
+		      if ( datatype != -1 ) vlistDefVarDatatype(vlistID2, varID, datatype);
+		    }
 		  if ( nml->entry[nml_missval]->occ )
 		    {
 		      double missval_old;
@@ -487,7 +501,7 @@ void read_partab(pt_mode_t ptmode, int nvars, int vlistID2, var_t *vars)
 }
 
 static
-void check_data(int vlistID2, int varID, var_t *vars, long gridsize, double missval, double *array)
+void check_data(int vlistID2, int varID2, int varID, var_t *vars, long gridsize, double missval, double *array)
 {
   char varname[CDI_MAX_NAME];
   int nvals = 0;
@@ -521,7 +535,7 @@ void check_data(int vlistID2, int varID, var_t *vars, long gridsize, double miss
 	}
     }
 
-  vlistInqVarName(vlistID2, varID, varname);
+  vlistInqVarName(vlistID2, varID2, varname);
 
   if ( n_lower_min > 0 )
     cdoWarning("Invalid value(s) detected for variable '%s': %i values were lower than minimum valid value (%.4g).",
@@ -563,9 +577,11 @@ void *Setpartab(void *argument)
   int streamID1, streamID2 = CDI_UNDEFID;
   int nrecs, nvars;
   int tsID1, recID, varID, levelID;
+  int varID2, levelID2;
   int vlistID1, vlistID2;
   int taxisID1, taxisID2;
   int nmiss;
+  int delvars = FALSE;
   long gridsize;
   int tableID = -1;
   int tableformat = 0;
@@ -636,10 +652,6 @@ void *Setpartab(void *argument)
   vlistID2 = vlistDuplicate(vlistID1);
   /* vlistPrint(vlistID2);*/
 
-  taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = taxisDuplicate(taxisID1);
-  vlistDefTaxis(vlistID2, taxisID2);
-
   nvars = vlistNvars(vlistID2);
   vars = (var_t *) malloc(nvars*sizeof(var_t));
   memset(vars, 0, nvars*sizeof(var_t));
@@ -652,8 +664,48 @@ void *Setpartab(void *argument)
   else
     {
       read_partab(ptmode, nvars, vlistID2, vars);
+
+      for ( varID = 0; varID < nvars; ++varID )
+	if ( vars[varID].delete ) break;
+
+      if ( varID < nvars ) delvars = TRUE;
+
+      if ( delvars )
+	{
+	  int levID, nlevs, zaxisID;
+	  int vlistIDx;
+	  vlistClearFlag(vlistID1);
+	  vlistClearFlag(vlistID2);
+
+	  for ( varID = 0; varID < nvars; varID++ )
+	    {
+	      zaxisID  = vlistInqVarZaxis(vlistID2, varID);
+	      nlevs    = zaxisInqSize(zaxisID);
+	      for ( levID = 0; levID < nlevs; levID++ )
+		{
+		  vlistDefFlag(vlistID1, varID, levID, TRUE);
+		  vlistDefFlag(vlistID2, varID, levID, TRUE);
+		  if ( vars[varID].delete )
+		    {
+		      vlistDefFlag(vlistID1, varID, levID, FALSE);
+		      vlistDefFlag(vlistID2, varID, levID, FALSE);
+		    }
+		}
+	    }
+
+	  vlistIDx = vlistCreate();
+	  vlistCopyFlag(vlistIDx, vlistID2);
+
+	  vlistDestroy(vlistID2);
+
+	  vlistID2 = vlistIDx;
+	}
     }
 
+  taxisID1 = vlistInqTaxis(vlistID1);
+  taxisID2 = taxisDuplicate(taxisID1);
+  vlistDefTaxis(vlistID2, taxisID2);
+
   /* vlistPrint(vlistID2);*/
   streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
 
@@ -673,13 +725,28 @@ void *Setpartab(void *argument)
       for ( recID = 0; recID < nrecs; recID++ )
 	{
 	  streamInqRecord(streamID1, &varID, &levelID);
-	  streamDefRecord(streamID2,  varID,  levelID);
+
+	  varID2 = varID;
+	  levelID2 = levelID;
+
+	  if ( delvars )
+	    {
+	      if ( vars[varID].delete ) continue;
+
+	      if ( vlistInqFlag(vlistID1, varID, levelID) == TRUE )
+		{
+		  varID2   = vlistFindVar(vlistID2, varID);
+		  levelID2 = vlistFindLevel(vlistID2, varID, levelID);
+		}
+	    }
+
+	  streamDefRecord(streamID2,  varID2,  levelID2);
 
 	  streamReadRecord(streamID1, array, &nmiss);
 
-	  missval = vlistInqVarMissval(vlistID2, varID);
-	  gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID));
-	  if ( vlistInqVarNumber(vlistID2, varID) != CDI_REAL ) gridsize *= 2;
+	  missval = vlistInqVarMissval(vlistID2, varID2);
+	  gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID2));
+	  if ( vlistInqVarNumber(vlistID2, varID2) != CDI_REAL ) gridsize *= 2;
 
 	  if ( nmiss > 0 && vars[varID].changemissval == TRUE )
 	    {
@@ -721,7 +788,7 @@ void *Setpartab(void *argument)
 	  streamWriteRecord(streamID2, array, nmiss);
 
 	  if ( vars[varID].checkvalid || vars[varID].check_min_mean_abs || vars[varID].check_max_mean_abs )
-	    check_data(vlistID2, varID, vars, gridsize, missval, array);
+	    check_data(vlistID2, varID2, varID, vars, gridsize, missval, array);
 	}
       tsID1++;
     }
diff --git a/src/Setrcaname.c b/src/Setrcaname.c
index 30ccdc8..5a6bb72 100644
--- a/src/Setrcaname.c
+++ b/src/Setrcaname.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Settime.c b/src/Settime.c
index c097512..3873d8a 100644
--- a/src/Settime.c
+++ b/src/Settime.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -140,7 +140,7 @@ void *Settime(void *argument)
   SETTUNITS   = cdoOperatorAdd("settunits",   0,  1, "time units (seconds, minutes, hours, days, months, years)");
   SETTAXIS    = cdoOperatorAdd("settaxis",    0, -2, "date,time<,increment> (format YYYY-MM-DD,hh:mm:ss)");
   SETREFTIME  = cdoOperatorAdd("setreftime",  0, -2, "date,time<,units> (format YYYY-MM-DD,hh:mm:ss)");
-  SETCALENDAR = cdoOperatorAdd("setcalendar", 0,  1, "calendar (standard, proleptic, 360days, 365days, 366days)");
+  SETCALENDAR = cdoOperatorAdd("setcalendar", 0,  1, "calendar (standard, proleptic_gregorian, 360_day, 365_day, 366_day)");
   SHIFTTIME   = cdoOperatorAdd("shifttime",   0,  1, "shift value");
 
   operatorID = cdoOperatorID();
@@ -242,14 +242,18 @@ void *Settime(void *argument)
     }
   else if ( operatorID == SETCALENDAR )
     {
-      size_t len;
       char *cname = operatorArgv()[0];
-      len = strlen(cname);      
-      if      ( memcmp(cname, "standard" , len) == 0 ) { newcalendar = CALENDAR_STANDARD;}
-      else if ( memcmp(cname, "proleptic", len) == 0 ) { newcalendar = CALENDAR_PROLEPTIC;}
-      else if ( memcmp(cname, "360days",   len) == 0 ) { newcalendar = CALENDAR_360DAYS;}
-      else if ( memcmp(cname, "365days",   len) == 0 ) { newcalendar = CALENDAR_365DAYS;}
-      else if ( memcmp(cname, "366days",   len) == 0 ) { newcalendar = CALENDAR_366DAYS;}
+      strtolower(cname);
+      if      ( strcmp(cname, "standard")  == 0 ) newcalendar = CALENDAR_STANDARD;
+      else if ( strcmp(cname, "gregorian") == 0 ) newcalendar = CALENDAR_STANDARD;
+      else if ( strcmp(cname, "proleptic") == 0 ) newcalendar = CALENDAR_PROLEPTIC;
+      else if ( strcmp(cname, "proleptic_gregorian") == 0 ) newcalendar = CALENDAR_PROLEPTIC;
+      else if ( strcmp(cname, "360days")   == 0 ) newcalendar = CALENDAR_360DAYS;
+      else if ( strcmp(cname, "360_day")   == 0 ) newcalendar = CALENDAR_360DAYS;
+      else if ( strcmp(cname, "365days")   == 0 ) newcalendar = CALENDAR_365DAYS;
+      else if ( strcmp(cname, "365_day")   == 0 ) newcalendar = CALENDAR_365DAYS;
+      else if ( strcmp(cname, "366days")   == 0 ) newcalendar = CALENDAR_366DAYS;
+      else if ( strcmp(cname, "366_day")   == 0 ) newcalendar = CALENDAR_366DAYS;
       else cdoAbort("Calendar >%s< unsupported!", cname);
     }
   else
diff --git a/src/Setzaxis.c b/src/Setzaxis.c
index 676c020..723d5bd 100644
--- a/src/Setzaxis.c
+++ b/src/Setzaxis.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Showinfo.c b/src/Showinfo.c
index eafc3f0..0f0710a 100644
--- a/src/Showinfo.c
+++ b/src/Showinfo.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Sinfo.c b/src/Sinfo.c
index a51d6ee..9dfd6fa 100644
--- a/src/Sinfo.c
+++ b/src/Sinfo.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -31,6 +31,32 @@
 
 #define MAXCHARS 82
 
+const char * tunit2str(int tunits)
+{
+  if      ( tunits == TUNIT_YEAR )    return ("years");
+  else if ( tunits == TUNIT_MONTH )   return ("months");
+  else if ( tunits == TUNIT_DAY )     return ("days");
+  else if ( tunits == TUNIT_12HOURS ) return ("12hours");
+  else if ( tunits == TUNIT_6HOURS )  return ("6hours");
+  else if ( tunits == TUNIT_3HOURS )  return ("3hours");
+  else if ( tunits == TUNIT_HOUR )    return ("hours");
+  else if ( tunits == TUNIT_MINUTE )  return ("minutes");
+  else if ( tunits == TUNIT_SECOND )  return ("seconds");
+  else                                return ("unknown");
+}
+
+
+const char * calendar2str(int calendar)
+{
+  if      ( calendar == CALENDAR_STANDARD )  return ("standard");
+  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");
+}
+
+
 void *Sinfo(void *argument)
 {
   enum {func_generic, func_param, func_name, func_code};
@@ -132,7 +158,17 @@ void *Sinfo(void *argument)
 	  /* source info */
 	  modelptr = modelInqNamePtr(vlistInqVarModel(vlistID, varID));
 	  if ( modelptr )
-	    fprintf(stdout, "%-8s ", modelptr);
+	    {
+	      size_t len = strlen(modelptr);
+	      if ( len > 10 )
+		for ( size_t i = 3; i < len; ++i )
+		  if ( modelptr[i] == ' ' )
+		    {
+		      modelptr[i] = 0;
+		      break;
+		    }
+	      fprintf(stdout, "%-8s ", modelptr);
+	    }
 	  else
 	    fprintf(stdout, "unknown  ");
 
@@ -261,10 +297,10 @@ void *Sinfo(void *argument)
 
 	  if ( taxisID != CDI_UNDEFID )
 	    {
-	      int calendar, tunits;
-
 	      if ( taxisInqType(taxisID) == TAXIS_RELATIVE )
 		{
+		  int calendar, tunits;
+
 		  vdate = taxisInqRdate(taxisID);
 		  vtime = taxisInqRtime(taxisID);
 
@@ -274,46 +310,10 @@ void *Sinfo(void *argument)
 		  fprintf(stdout, "     RefTime = %s %s", vdatestr, vtimestr);
 		      
 		  tunits = taxisInqTunit(taxisID);
-		  if ( tunits != CDI_UNDEFID )
-		    {
-		      if ( tunits == TUNIT_YEAR )
-			fprintf(stdout, "  Units = years");
-		      else if ( tunits == TUNIT_MONTH )
-			fprintf(stdout, "  Units = months");
-		      else if ( tunits == TUNIT_DAY )
-			fprintf(stdout, "  Units = days");
-		      else if ( tunits == TUNIT_12HOURS )
-			fprintf(stdout, "  Units = 12hours");
-		      else if ( tunits == TUNIT_6HOURS )
-			fprintf(stdout, "  Units = 6hours");
-		      else if ( tunits == TUNIT_3HOURS )
-			fprintf(stdout, "  Units = 3hours");
-		      else if ( tunits == TUNIT_HOUR )
-			fprintf(stdout, "  Units = hours");
-		      else if ( tunits == TUNIT_MINUTE )
-			fprintf(stdout, "  Units = minutes");
-		      else if ( tunits == TUNIT_SECOND )
-			fprintf(stdout, "  Units = seconds");
-		      else
-			fprintf(stdout, "  Units = unknown");
-		    }
+		  if ( tunits != CDI_UNDEFID )  fprintf(stdout, "  Units = %s", tunit2str(tunits));
 	      
 		  calendar = taxisInqCalendar(taxisID);
-		  if ( calendar != CDI_UNDEFID )
-		    {
-		      if      ( calendar == CALENDAR_STANDARD )
-			fprintf(stdout, "  Calendar = STANDARD");
-		      else if ( calendar == CALENDAR_PROLEPTIC )
-			fprintf(stdout, "  Calendar = PROLEPTIC");
-		      else if ( calendar == CALENDAR_360DAYS )
-			fprintf(stdout, "  Calendar = 360DAYS");
-		      else if ( calendar == CALENDAR_365DAYS )
-			fprintf(stdout, "  Calendar = 365DAYS");
-		      else if ( calendar == CALENDAR_366DAYS )
-			fprintf(stdout, "  Calendar = 366DAYS");
-		      else
-			fprintf(stdout, "  Calendar = unknown");
-		    }
+		  if ( calendar != CDI_UNDEFID )  fprintf(stdout, "  Calendar = %s", calendar2str(calendar));
 
 		  if ( taxisHasBounds(taxisID) )
 		    fprintf(stdout, "  Bounds = true");
diff --git a/src/Smooth9.c b/src/Smooth9.c
index 5e67379..c9050a7 100644
--- a/src/Smooth9.c
+++ b/src/Smooth9.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Sort.c b/src/Sort.c
index 5318ca1..9a9fc29 100644
--- a/src/Sort.c
+++ b/src/Sort.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Sorttimestamp.c b/src/Sorttimestamp.c
index 5f349fa..b63e617 100644
--- a/src/Sorttimestamp.c
+++ b/src/Sorttimestamp.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Specinfo.c b/src/Specinfo.c
index 8735a5b..94bac6c 100644
--- a/src/Specinfo.c
+++ b/src/Specinfo.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -479,12 +479,12 @@ void *Specinfo(void *argument)
   ngp_icon1 = NGP_ICON(nrooti1,nlevel1);
   ngp_icon2 = NGP_ICON(nrooti2,nlevel2);
 
-  fprintf(stdout, "truncation     nsp  nlon  nlat      ngp  gme   ngp_gme  icon  ngp_icon\n");
+  fprintf(stdout, "truncation     nsp  nlon  nlat      ngp  gme    ngp_gme  icon   ngp_icon\n");
 
-  if ( nout1 ) fprintf(stdout, "   T%-4d  %8d %5d %5d %8d  ni%d %8d  R%dL%d  %8d\n",
+  if ( nout1 ) fprintf(stdout, "   T%-4d  %8d %5d %5d %8d  ni%d %8d  R%dB%02d  %8d\n",
 		       ntr1, nsp1, nlon1, nlat1, ngp1, ni1, ngp_gme1, nrooti1, nlevel1, ngp_icon1);
 
-  if ( nout2 ) fprintf(stdout, "   TL%-4d %8d %5d %5d %8d  ni%d %8d  R%dL%d  %8d\n",
+  if ( nout2 ) fprintf(stdout, "   TL%-4d %8d %5d %5d %8d  ni%d %8d  R%dB%02d  %8d\n",
 		       ntr2, nsp2, nlon2, nlat2, ngp2, ni2, ngp_gme2, nrooti2, nlevel2, ngp_icon2);
 
   cdoFinish();
diff --git a/src/Spectral.c b/src/Spectral.c
index b0f9402..4f58092 100644
--- a/src/Spectral.c
+++ b/src/Spectral.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Spectrum.c b/src/Spectrum.c
index ba73a8f..0162e19 100644
--- a/src/Spectrum.c
+++ b/src/Spectrum.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -323,6 +323,7 @@ void *Spectrum(void *argument)
       break;
     default:
       cdoAbort("Invalid window type %d!", which_window);
+      break;
     }
   
   wssum = 0;
diff --git a/src/Split.c b/src/Split.c
index a811636..2637436 100644
--- a/src/Split.c
+++ b/src/Split.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Splitrec.c b/src/Splitrec.c
index 5b557a5..6a9bb42 100644
--- a/src/Splitrec.c
+++ b/src/Splitrec.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Splitsel.c b/src/Splitsel.c
index 7c6b4d7..6ffb8fc 100644
--- a/src/Splitsel.c
+++ b/src/Splitsel.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Splittime.c b/src/Splittime.c
index dd13853..0054469 100644
--- a/src/Splittime.c
+++ b/src/Splittime.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Splityear.c b/src/Splityear.c
index a9fec21..885405b 100644
--- a/src/Splityear.c
+++ b/src/Splityear.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Subtrend.c b/src/Subtrend.c
index 4c9d706..150f0e2 100644
--- a/src/Subtrend.c
+++ b/src/Subtrend.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Tee.c b/src/Tee.c
index 41e8577..2b25fbe 100644
--- a/src/Tee.c
+++ b/src/Tee.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Templates.c b/src/Templates.c
index 0e2668e..ab45331 100644
--- a/src/Templates.c
+++ b/src/Templates.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Test.c b/src/Test.c
index 1003467..c13836b 100644
--- a/src/Test.c
+++ b/src/Test.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Tests.c b/src/Tests.c
index 2b760ab..5ca4878 100644
--- a/src/Tests.c
+++ b/src/Tests.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Timselstat.c b/src/Timselstat.c
index 1d0e932..acd23e1 100644
--- a/src/Timselstat.c
+++ b/src/Timselstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -24,7 +24,9 @@
       Timselstat    timselmean         Time range mean
       Timselstat    timselavg          Time range average
       Timselstat    timselvar          Time range variance
+      Timselstat    timselvar1         Time range variance [Divisor is (n-1)]
       Timselstat    timselstd          Time range standard deviation
+      Timselstat    timselstd1         Time range standard deviation [Divisor is (n-1)]
 */
 
 
@@ -44,7 +46,7 @@ void *Timselstat(void *argument)
   int vdate_lb = 0, vdate_ub = 0, date_lb = 0, date_ub = 0;
   int vtime_lb = 0, vtime_ub = 0, time_lb = 0, time_ub = 0;
   int nrecs = 0, nrecords;
-  int gridID, varID, levelID, recID;
+  int varID, levelID, recID;
   int tsID;
   int otsID;
   int nsets;
@@ -56,7 +58,8 @@ void *Timselstat(void *argument)
   int nvars, nlevel;
   int ndates = 0, noffset = 0, nskip = 0, nargc;
   int *recVarID, *recLevelID;
-  double missval;
+  int lmean = FALSE, lvarstd = FALSE, lstd = FALSE;
+  double divisor;
   field_t **vars1 = NULL, **vars2 = NULL, **samp1 = NULL;
   field_t field;
 
@@ -68,7 +71,9 @@ void *Timselstat(void *argument)
   cdoOperatorAdd("timselmean", func_mean, 0, NULL);
   cdoOperatorAdd("timselavg",  func_avg,  0, NULL);
   cdoOperatorAdd("timselvar",  func_var,  0, NULL);
+  cdoOperatorAdd("timselvar1", func_var1, 0, NULL);
   cdoOperatorAdd("timselstd",  func_std,  0, NULL);
+  cdoOperatorAdd("timselstd1", func_std1, 0, NULL);
 
   operatorID = cdoOperatorID();
   operfunc = cdoOperatorF1(operatorID);
@@ -83,6 +88,11 @@ void *Timselstat(void *argument)
 
   if ( cdoVerbose ) cdoPrint("nsets = %d, noffset = %d, nskip = %d", ndates, noffset, nskip);
 
+  lmean   = operfunc == func_mean || operfunc == func_avg;
+  lstd    = operfunc == func_std || operfunc == func_std1;
+  lvarstd = operfunc == func_std || operfunc == func_var || operfunc == func_std1 || operfunc == func_var1;
+  divisor = operfunc == func_std1 || operfunc == func_var1;
+
   streamID1 = streamOpenRead(cdoStreamName(0));
 
   vlistID1 = streamInqVlist(streamID1);
@@ -107,42 +117,10 @@ void *Timselstat(void *argument)
 
   field.ptr = (double *) malloc(gridsize*sizeof(double));
 
-  vars1 = (field_t **) malloc(nvars*sizeof(field_t *));
-  samp1 = (field_t **) malloc(nvars*sizeof(field_t *));
-  if ( operfunc == func_std || operfunc == func_var )
-    vars2 = (field_t **) malloc(nvars*sizeof(field_t *));
-
-  for ( varID = 0; varID < nvars; varID++ )
-    {
-      gridID   = vlistInqVarGrid(vlistID1, varID);
-      gridsize = gridInqSize(gridID);
-      nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-      missval  = vlistInqVarMissval(vlistID1, varID);
-
-      vars1[varID] = (field_t *)  malloc(nlevel*sizeof(field_t));
-      samp1[varID] = (field_t *)  malloc(nlevel*sizeof(field_t));
-      if ( operfunc == func_std || operfunc == func_var )
-	vars2[varID] = (field_t *)  malloc(nlevel*sizeof(field_t));
-
-      for ( levelID = 0; levelID < nlevel; levelID++ )
-	{
-	  vars1[varID][levelID].grid    = gridID;
-	  vars1[varID][levelID].nmiss   = 0;
-	  vars1[varID][levelID].missval = missval;
-	  vars1[varID][levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
-	  samp1[varID][levelID].grid    = gridID;
-	  samp1[varID][levelID].nmiss   = 0;
-	  samp1[varID][levelID].missval = missval;
-	  samp1[varID][levelID].ptr     = NULL;
-	  if ( operfunc == func_std || operfunc == func_var )
-	    {
-	      vars2[varID][levelID].grid    = gridID;
-	      vars2[varID][levelID].nmiss   = 0;
-	      vars2[varID][levelID].missval = missval;
-	      vars2[varID][levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
-	    }
-	}
-    }
+  vars1 = field_malloc(vlistID1, FIELD_PTR);
+  samp1 = field_malloc(vlistID1, FIELD_NONE);
+  if ( lvarstd )
+    vars2 = field_malloc(vlistID1, FIELD_PTR);
 
   for ( tsID = 0; tsID < noffset; tsID++ )
     {
@@ -241,7 +219,7 @@ void *Timselstat(void *argument)
 			  samp1[varID][levelID].ptr[i]++;
 		    }
 
-		  if ( operfunc == func_std || operfunc == func_var )
+		  if ( lvarstd )
 		    {
 		      farsumq(&vars2[varID][levelID], field);
 		      farsum(&vars1[varID][levelID], field);
@@ -253,7 +231,7 @@ void *Timselstat(void *argument)
 		}
 	    }
 
-	  if ( nsets == 0 && (operfunc == func_std || operfunc == func_var) )
+	  if ( nsets == 0 && lvarstd )
 	    for ( varID = 0; varID < nvars; varID++ )
 	      {
 		if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
@@ -269,7 +247,7 @@ void *Timselstat(void *argument)
 
       if ( nrecs == 0 && nsets == 0 ) break;
 
-      if ( operfunc == func_mean || operfunc == func_avg )
+      if ( lmean )
 	for ( varID = 0; varID < nvars; varID++ )
 	  {
 	    if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
@@ -282,7 +260,7 @@ void *Timselstat(void *argument)
 		  fardiv(&vars1[varID][levelID], samp1[varID][levelID]);
 	      }
 	  }
-      else if ( operfunc == func_std || operfunc == func_var )
+      else if ( lvarstd )
 	for ( varID = 0; varID < nvars; varID++ )
 	  {
 	    if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
@@ -291,18 +269,17 @@ void *Timselstat(void *argument)
 	      {
 		if ( samp1[varID][levelID].ptr == NULL )
 		  {
-		    if ( operfunc == func_std )
-		      farcstd(&vars1[varID][levelID], vars2[varID][levelID], 1.0/nsets);
+		    if ( lstd )
+		      farcstdx(&vars1[varID][levelID], vars2[varID][levelID], nsets, divisor);
 		    else
-		      farcvar(&vars1[varID][levelID], vars2[varID][levelID], 1.0/nsets);
+		      farcvarx(&vars1[varID][levelID], vars2[varID][levelID], nsets, divisor);
 		  }
 		else
 		  {
-		    farinv(&samp1[varID][levelID]);
-		    if ( operfunc == func_std )
-		      farstd(&vars1[varID][levelID], vars2[varID][levelID], samp1[varID][levelID]);
+		    if ( lstd )
+		      farstdx(&vars1[varID][levelID], vars2[varID][levelID], samp1[varID][levelID], divisor);
 		    else
-		      farvar(&vars1[varID][levelID], vars2[varID][levelID], samp1[varID][levelID]);
+		      farvarx(&vars1[varID][levelID], vars2[varID][levelID], samp1[varID][levelID], divisor);
 		  }
 	      }
 	  }
@@ -342,24 +319,10 @@ void *Timselstat(void *argument)
 
  LABEL_END:
 
-  for ( varID = 0; varID < nvars; varID++ )
-    {
-      nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-      for ( levelID = 0; levelID < nlevel; levelID++ )
-	{
-	  free(vars1[varID][levelID].ptr);
-	  if ( samp1[varID][levelID].ptr ) free(samp1[varID][levelID].ptr);
-	  if ( operfunc == func_std || operfunc == func_var ) free(vars2[varID][levelID].ptr);
-	}
-
-      free(vars1[varID]);
-      free(samp1[varID]);
-      if ( operfunc == func_std || operfunc == func_var ) free(vars2[varID]);
-    }
 
-  free(vars1);
-  free(samp1);
-  if ( operfunc == func_std || operfunc == func_var ) free(vars2);
+  field_free(vars1, vlistID1);
+  field_free(samp1, vlistID1);
+  if ( lvarstd ) field_free(vars2, vlistID1);
 
   if ( field.ptr ) free(field.ptr);
 
diff --git a/src/Timsort.c b/src/Timsort.c
index 56597a3..26c0628 100644
--- a/src/Timsort.c
+++ b/src/Timsort.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Timstat.c b/src/Timstat.c
index ba12fe6..3cffe70 100644
--- a/src/Timstat.c
+++ b/src/Timstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -24,35 +24,45 @@
       Timstat    timmean         Time mean
       Timstat    timavg          Time average
       Timstat    timvar          Time variance
+      Timstat    timvar1         Time variance [Divisor is (n-1)]
       Timstat    timstd          Time standard deviation
+      Timstat    timstd1         Time standard deviation [Divisor is (n-1)]
       Hourstat   hourmin         Hourly minimum
       Hourstat   hourmax         Hourly maximum
       Hourstat   hoursum         Hourly sum
       Hourstat   hourmean        Hourly mean
       Hourstat   houravg         Hourly average
       Hourstat   hourvar         Hourly variance
+      Hourstat   hourvar1        Hourly variance [Divisor is (n-1)]
       Hourstat   hourstd         Hourly standard deviation
+      Hourstat   hourstd1        Hourly standard deviation [Divisor is (n-1)]
       Daystat    daymin          Daily minimum
       Daystat    daymax          Daily maximum
       Daystat    daysum          Daily sum
       Daystat    daymean         Daily mean
       Daystat    dayavg          Daily average
       Daystat    dayvar          Daily variance
+      Daystat    dayvar1         Daily variance [Divisor is (n-1)]
       Daystat    daystd          Daily standard deviation
+      Daystat    daystd1         Daily standard deviation [Divisor is (n-1)]
       Monstat    monmin          Monthly minimum
       Monstat    monmax          Monthly maximum
       Monstat    monsum          Monthly sum
       Monstat    monmean         Monthly mean
       Monstat    monavg          Monthly average
       Monstat    monvar          Monthly variance
+      Monstat    monvar1         Monthly variance [Divisor is (n-1)]
       Monstat    monstd          Monthly standard deviation
+      Monstat    monstd1         Monthly standard deviation [Divisor is (n-1)]
       Yearstat   yearmin         Yearly minimum
       Yearstat   yearmax         Yearly maximum
       Yearstat   yearsum         Yearly sum
       Yearstat   yearmean        Yearly mean
       Yearstat   yearavg         Yearly average
       Yearstat   yearvar         Yearly variance
+      Yearstat   yearvar1        Yearly variance [Divisor is (n-1)]
       Yearstat   yearstd         Yearly standard deviation
+      Yearstat   yearstd1        Yearly standard deviation [Divisor is (n-1)]
 */
 
 
@@ -86,53 +96,70 @@ void *Timstat(void *argument)
   int *recVarID, *recLevelID;
   int taxis_has_bounds = FALSE;
   int lvfrac = FALSE;
+  int lmean = FALSE, lvarstd = FALSE, lstd = FALSE;
   char vdatestr[32], vtimestr[32];
   double vfrac = 1;
+  double divisor;
   double missval;
   field_t **vars1 = NULL, **vars2 = NULL, **samp1 = NULL;
   field_t field;
 
   cdoInitialize(argument);
 
-  cdoOperatorAdd("timmin",   func_min,  31, NULL);
-  cdoOperatorAdd("timmax",   func_max,  31, NULL);
-  cdoOperatorAdd("timsum",   func_sum,  31, NULL);
-  cdoOperatorAdd("timmean",  func_mean, 31, NULL);
-  cdoOperatorAdd("timavg",   func_avg,  31, NULL);
-  cdoOperatorAdd("timvar",   func_var,  31, NULL);
-  cdoOperatorAdd("timstd",   func_std,  31, NULL);
-  cdoOperatorAdd("yearmin",  func_min,  10, NULL);
-  cdoOperatorAdd("yearmax",  func_max,  10, NULL);
-  cdoOperatorAdd("yearsum",  func_sum,  10, NULL);
-  cdoOperatorAdd("yearmean", func_mean, 10, NULL);
-  cdoOperatorAdd("yearavg",  func_avg,  10, NULL);
-  cdoOperatorAdd("yearvar",  func_var,  10, NULL);
-  cdoOperatorAdd("yearstd",  func_std,  10, NULL);
-  cdoOperatorAdd("monmin",   func_min,   8, NULL);
-  cdoOperatorAdd("monmax",   func_max,   8, NULL);
-  cdoOperatorAdd("monsum",   func_sum,   8, NULL);
-  cdoOperatorAdd("monmean",  func_mean,  8, NULL);
-  cdoOperatorAdd("monavg",   func_avg,   8, NULL);
-  cdoOperatorAdd("monvar",   func_var,   8, NULL);
-  cdoOperatorAdd("monstd",   func_std,   8, NULL);
-  cdoOperatorAdd("daymin",   func_min,   6, NULL);
-  cdoOperatorAdd("daymax",   func_max,   6, NULL);
-  cdoOperatorAdd("daysum",   func_sum,   6, NULL);
-  cdoOperatorAdd("daymean",  func_mean,  6, NULL);
-  cdoOperatorAdd("dayavg",   func_avg,   6, NULL);
-  cdoOperatorAdd("dayvar",   func_var,   6, NULL);
-  cdoOperatorAdd("daystd",   func_std,   6, NULL);
-  cdoOperatorAdd("hourmin",  func_min,   4, NULL);
-  cdoOperatorAdd("hourmax",  func_max,   4, NULL);
-  cdoOperatorAdd("hoursum",  func_sum,   4, NULL);
-  cdoOperatorAdd("hourmean", func_mean,  4, NULL);
-  cdoOperatorAdd("houravg",  func_avg,   4, NULL);
-  cdoOperatorAdd("hourvar",  func_var,   4, NULL);
-  cdoOperatorAdd("hourstd",  func_std,   4, NULL);
+  cdoOperatorAdd("timmin",    func_min,  31, NULL);
+  cdoOperatorAdd("timmax",    func_max,  31, NULL);
+  cdoOperatorAdd("timsum",    func_sum,  31, NULL);
+  cdoOperatorAdd("timmean",   func_mean, 31, NULL);
+  cdoOperatorAdd("timavg",    func_avg,  31, NULL);
+  cdoOperatorAdd("timvar",    func_var,  31, NULL);
+  cdoOperatorAdd("timvar1",   func_var1, 31, NULL);
+  cdoOperatorAdd("timstd",    func_std,  31, NULL);
+  cdoOperatorAdd("timstd1",   func_std1, 31, NULL);
+  cdoOperatorAdd("yearmin",   func_min,  10, NULL);
+  cdoOperatorAdd("yearmax",   func_max,  10, NULL);
+  cdoOperatorAdd("yearsum",   func_sum,  10, NULL);
+  cdoOperatorAdd("yearmean",  func_mean, 10, NULL);
+  cdoOperatorAdd("yearavg",   func_avg,  10, NULL);
+  cdoOperatorAdd("yearvar",   func_var,  10, NULL);
+  cdoOperatorAdd("yearvar1",  func_var1, 10, NULL);
+  cdoOperatorAdd("yearstd",   func_std,  10, NULL);
+  cdoOperatorAdd("yearstd1",  func_std1, 10, NULL);
+  cdoOperatorAdd("monmin",    func_min,   8, NULL);
+  cdoOperatorAdd("monmax",    func_max,   8, NULL);
+  cdoOperatorAdd("monsum",    func_sum,   8, NULL);
+  cdoOperatorAdd("monmean",   func_mean,  8, NULL);
+  cdoOperatorAdd("monavg",    func_avg,   8, NULL);
+  cdoOperatorAdd("monvar",    func_var,   8, NULL);
+  cdoOperatorAdd("monvar1",   func_var1,  8, NULL);
+  cdoOperatorAdd("monstd",    func_std,   8, NULL);
+  cdoOperatorAdd("monstd1",   func_std1,  8, NULL);
+  cdoOperatorAdd("daymin",    func_min,   6, NULL);
+  cdoOperatorAdd("daymax",    func_max,   6, NULL);
+  cdoOperatorAdd("daysum",    func_sum,   6, NULL);
+  cdoOperatorAdd("daymean",   func_mean,  6, NULL);
+  cdoOperatorAdd("dayavg",    func_avg,   6, NULL);
+  cdoOperatorAdd("dayvar",    func_var,   6, NULL);
+  cdoOperatorAdd("dayvar1",   func_var1,  6, NULL);
+  cdoOperatorAdd("daystd",    func_std,   6, NULL);
+  cdoOperatorAdd("daystd1",   func_std1,  6, NULL);
+  cdoOperatorAdd("hourmin",   func_min,   4, NULL);
+  cdoOperatorAdd("hourmax",   func_max,   4, NULL);
+  cdoOperatorAdd("hoursum",   func_sum,   4, NULL);
+  cdoOperatorAdd("hourmean",  func_mean,  4, NULL);
+  cdoOperatorAdd("houravg",   func_avg,   4, NULL);
+  cdoOperatorAdd("hourvar",   func_var,   4, NULL);
+  cdoOperatorAdd("hourvar1",  func_var1,  4, NULL);
+  cdoOperatorAdd("hourstd",   func_std,   4, NULL);
+  cdoOperatorAdd("hourstd1",  func_std1,  4, NULL);
 
   operatorID = cdoOperatorID();
   operfunc = cdoOperatorF1(operatorID);
 
+  lmean   = operfunc == func_mean || operfunc == func_avg;
+  lstd    = operfunc == func_std || operfunc == func_std1;
+  lvarstd = operfunc == func_std || operfunc == func_var || operfunc == func_std1 || operfunc == func_var1;
+  divisor = operfunc == func_std1 || operfunc == func_var1;
+
   if ( operfunc == func_mean )
     {
       int oargc = operatorArgc();
@@ -204,7 +231,7 @@ void *Timstat(void *argument)
 
   vars1 = field_malloc(vlistID1, FIELD_PTR);
   samp1 = field_malloc(vlistID1, FIELD_NONE);
-  if ( operfunc == func_std || operfunc == func_var )
+  if ( lvarstd )
     vars2 = field_malloc(vlistID1, FIELD_PTR);
 
   tsID    = 0;
@@ -288,7 +315,7 @@ void *Timstat(void *argument)
 			  samp1[varID][levelID].ptr[i]++;
 		    }
 
-		  if ( operfunc == func_std || operfunc == func_var )
+		  if ( lvarstd )
 		    {
 		      farsumq(&vars2[varID][levelID], field);
 		      farsum(&vars1[varID][levelID], field);
@@ -300,7 +327,7 @@ void *Timstat(void *argument)
 		}
 	    }
 
-	  if ( nsets == 0 && (operfunc == func_std || operfunc == func_var) )
+	  if ( nsets == 0 && lvarstd )
 	    for ( varID = 0; varID < nvars; varID++ )
 	      {
 		if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
@@ -317,7 +344,7 @@ void *Timstat(void *argument)
 
       if ( nrecs == 0 && nsets == 0 ) break;
 
-      if ( operfunc == func_mean || operfunc == func_avg )
+      if ( lmean )
 	for ( varID = 0; varID < nvars; varID++ )
 	  {
 	    if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
@@ -330,7 +357,7 @@ void *Timstat(void *argument)
 		  fardiv(&vars1[varID][levelID], samp1[varID][levelID]);
 	      }
 	  }
-      else if ( operfunc == func_std || operfunc == func_var )
+      else if ( lvarstd )
 	for ( varID = 0; varID < nvars; varID++ )
 	  {
 	    if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
@@ -339,18 +366,17 @@ void *Timstat(void *argument)
 	      {
 		if ( samp1[varID][levelID].ptr == NULL )
 		  {
-		    if ( operfunc == func_std )
-		      farcstd(&vars1[varID][levelID], vars2[varID][levelID], 1.0/nsets);
+		    if ( lstd )
+		      farcstdx(&vars1[varID][levelID], vars2[varID][levelID], nsets, divisor);
 		    else
-		      farcvar(&vars1[varID][levelID], vars2[varID][levelID], 1.0/nsets);
+		      farcvarx(&vars1[varID][levelID], vars2[varID][levelID], nsets, divisor);
 		  }
 		else
 		  {
-		    farinv(&samp1[varID][levelID]);
-		    if ( operfunc == func_std )
-		      farstd(&vars1[varID][levelID], vars2[varID][levelID], samp1[varID][levelID]);
+		    if ( lstd )
+		      farstdx(&vars1[varID][levelID], vars2[varID][levelID], samp1[varID][levelID], divisor);
 		    else
-		      farvar(&vars1[varID][levelID], vars2[varID][levelID], samp1[varID][levelID]);
+		      farvarx(&vars1[varID][levelID], vars2[varID][levelID], samp1[varID][levelID], divisor);
 		  }
 	      }
 	  }
@@ -441,8 +467,7 @@ void *Timstat(void *argument)
 
   field_free(vars1, vlistID1);
   field_free(samp1, vlistID1);
-  if ( operfunc == func_std || operfunc == func_var )
-    field_free(vars2, vlistID1);
+  if ( lvarstd ) field_free(vars2, vlistID1);
 
   if ( cdoDiag ) streamClose(streamID3);
   streamClose(streamID2);
diff --git a/src/Timstat2.c b/src/Timstat2.c
index f12ae94..328be19 100644
--- a/src/Timstat2.c
+++ b/src/Timstat2.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Timstat3.c b/src/Timstat3.c
index b047772..0053356 100644
--- a/src/Timstat3.c
+++ b/src/Timstat3.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Tinfo.c b/src/Tinfo.c
index 016d8dd..927539e 100644
--- a/src/Tinfo.c
+++ b/src/Tinfo.c
@@ -36,48 +36,6 @@ enum {TU_SECONDS=0, TU_MINUTES, TU_HOURS, TU_DAYS, TU_MONTHS, TU_YEARS};
 char *tunits[] = {"second", "minute", "hour", "day", "month", "year"};
 int   iunits[] = {1, 60, 3600, 86400, 1, 12};
 
-static
-void printTunit(int unit)
-{
-  if ( unit == TUNIT_YEAR )
-    fprintf(stdout, "  Units = years");
-  else if ( unit == TUNIT_MONTH )
-    fprintf(stdout, "  Units = months");
-  else if ( unit == TUNIT_DAY )
-    fprintf(stdout, "  Units = days");
-  else if ( unit == TUNIT_12HOURS )
-    fprintf(stdout, "  Units = 12hours");
-  else if ( unit == TUNIT_6HOURS )
-    fprintf(stdout, "  Units = 6hours");
-  else if ( unit == TUNIT_3HOURS )
-    fprintf(stdout, "  Units = 3hours");
-  else if ( unit == TUNIT_HOUR )
-    fprintf(stdout, "  Units = hours");
-  else if ( unit == TUNIT_MINUTE )
-    fprintf(stdout, "  Units = minutes");
-  else if ( unit == TUNIT_SECOND )
-    fprintf(stdout, "  Units = seconds");
-  else
-    fprintf(stdout, "  Units = unknown");
-}
-
-static
-void printCalendar(int calendar)
-{
-  if      ( calendar == CALENDAR_STANDARD )
-    fprintf(stdout, "  Calendar = STANDARD");
-  else if ( calendar == CALENDAR_PROLEPTIC )
-    fprintf(stdout, "  Calendar = PROLEPTIC");
-  else if ( calendar == CALENDAR_360DAYS )
-    fprintf(stdout, "  Calendar = 360DAYS");
-  else if ( calendar == CALENDAR_365DAYS )
-    fprintf(stdout, "  Calendar = 365DAYS");
-  else if ( calendar == CALENDAR_366DAYS )
-    fprintf(stdout, "  Calendar = 366DAYS");
-  else
-    fprintf(stdout, "  Calendar = unknown");
-}
-
 
 void getTimeInc(double jdelta, int vdate0, int vdate1, int *incperiod, int *incunit)
 {
@@ -317,10 +275,10 @@ void *Tinfo(void *argument)
 	      fprintf(stdout, "     RefTime = %s %s", vdatestr, vtimestr);
 		      
 	      unit = taxisInqTunit(taxisID);
-	      if ( unit != CDI_UNDEFID ) printTunit(unit);
+	      if ( unit != CDI_UNDEFID )  fprintf(stdout, "  Units = %s", tunit2str(unit));
 	      
 	      calendar = taxisInqCalendar(taxisID);
-	      if ( calendar != CDI_UNDEFID ) printCalendar(calendar);
+	      if ( calendar != CDI_UNDEFID )  fprintf(stdout, "  Calendar = %s", calendar2str(calendar));
 
 	      if ( taxisHasBounds(taxisID) )
 		fprintf(stdout, "  Bounds = true");
diff --git a/src/Tocomplex.c b/src/Tocomplex.c
index b6ff689..76be459 100644
--- a/src/Tocomplex.c
+++ b/src/Tocomplex.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Transpose.c b/src/Transpose.c
index 4b43058..37dfe11 100644
--- a/src/Transpose.c
+++ b/src/Transpose.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Trend.c b/src/Trend.c
index 6b08c0a..7aef5b7 100644
--- a/src/Trend.c
+++ b/src/Trend.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Trms.c b/src/Trms.c
index e906797..019d4e8 100644
--- a/src/Trms.c
+++ b/src/Trms.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Tstepcount.c b/src/Tstepcount.c
index 54a96c2..8776763 100644
--- a/src/Tstepcount.c
+++ b/src/Tstepcount.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Vardup.c b/src/Vardup.c
index 101a601..aab0df0 100644
--- a/src/Vardup.c
+++ b/src/Vardup.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Vargen.c b/src/Vargen.c
index 297f0be..2b63235 100644
--- a/src/Vargen.c
+++ b/src/Vargen.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -24,6 +24,11 @@
                                  the standard atmosphere
 */
 
+
+#if  defined  (HAVE_CONFIG_H)
+#  include "config.h" // ENABLE_DATA
+#endif
+
 #include <cdi.h>
 #include "cdo.h"
 #include "cdo_int.h"
@@ -31,29 +36,22 @@
 #include "list.h"
 
 
-#if defined (__GNUC__)
-#if __GNUC__ > 2
-#  define WITH_DATA 1
-#endif
-#endif
-
-
-#if defined(WITH_DATA)
+#if defined(ENABLE_DATA)
   static double etopo_scale  = 3;
   static double etopo_offset = 11000;
-  static const unsigned short etopo[] = {
+  static const unsigned short const etopo[] = {
 #include "etopo.h"
   };
 
   static double temp_scale  =  500;
   static double temp_offset = -220;
-  static const unsigned short temp[] = {
+  static const unsigned short const temp[] = {
 #include "temp.h"
   };
 
   static double mask_scale  =  1;
   static double mask_offset =  0;
-  static const unsigned short mask[] = {
+  static const unsigned short const mask[] = {
 #include "mask.h"
   };
 #endif
@@ -89,7 +87,7 @@ std_atm_pressure(double height)
 
 void *Vargen(void *argument)
 {
-  int RANDOM, CONST, FOR, TOPO, TEMP, MASK, STDATM;
+  int RANDOM, SINCOS, CONST, FOR, TOPO, TEMP, MASK, STDATM;
   int operatorID;
   int streamID;
   int nvars, ntimesteps, nlevels = 1;
@@ -107,6 +105,7 @@ void *Vargen(void *argument)
   cdoInitialize(argument);
 
   RANDOM = cdoOperatorAdd("random", 0, 0, "grid description file or name, <seed>");
+  SINCOS = cdoOperatorAdd("sincos", 0, 0, "grid description file or name");
   CONST  = cdoOperatorAdd("const",  0, 0, "constant value, grid description file or name");
   FOR    = cdoOperatorAdd("for",    0, 0, "start, end, <increment>");
   TOPO   = cdoOperatorAdd("topo",   0, 0, NULL);
@@ -133,6 +132,13 @@ void *Vargen(void *argument)
         }
       srand(seed);
     }
+  else if ( operatorID == SINCOS )
+    {
+      operatorInputArg(cdoOperatorEnter(operatorID));
+      operatorCheckArgc(1);
+      gridfile = operatorArgv()[0];
+      gridID   = cdoDefineGrid(gridfile);
+    }
   else if ( operatorID == CONST )
     {
       operatorInputArg(cdoOperatorEnter(operatorID));
@@ -252,7 +258,7 @@ void *Vargen(void *argument)
   taxisID = taxisCreate(TAXIS_RELATIVE);
   vlistDefTaxis(vlistID, taxisID);
 
-  if ( operatorID == RANDOM || operatorID == CONST || operatorID == TOPO ||
+  if ( operatorID == RANDOM || operatorID == SINCOS || operatorID == CONST || operatorID == TOPO ||
        operatorID == TEMP || operatorID == MASK || operatorID == STDATM )
     vlistDefNtsteps(vlistID, 1);
 
@@ -266,7 +272,10 @@ void *Vargen(void *argument)
   if ( operatorID == FOR )
     ntimesteps = 1.001 + ((rstop-rstart)/rinc);
   else
-    ntimesteps = 1;
+    {
+      vlistDefNtsteps(vlistID, 0);
+      ntimesteps = 1;
+    }
 
   julday = date_to_julday(CALENDAR_PROLEPTIC, 10101);
 
@@ -293,6 +302,23 @@ void *Vargen(void *argument)
                   for ( i = 0; i < gridsize; i++ )
                     array[i] = rand()/(RAND_MAX+1.0);
                 }
+              else if ( operatorID == SINCOS )
+                {
+		  int nlon = gridInqXsize(gridID);
+		  int nlat = gridInqYsize(gridID);
+		  double dlon = 360./nlon;
+		  double dlat = 180./nlat;
+		  double lon0 = 0;
+		  double lat0 = -90 + dlat/2;
+
+                  for ( i = 0; i < gridsize; i++ )
+		    {
+		      int ilat = (i%gridsize)/ nlon;
+		      int ilon = i%nlon;
+		      array[i] = cos(2.0 * M_PI * (lon0 + ilon*dlon)/360)
+		   	       * sin(2.0 * M_PI * (lat0 + ilat*dlat)/180);
+		    }
+		}
               else if ( operatorID == CONST )
                 {
                   for ( i = 0; i < gridsize; i++ )
@@ -300,7 +326,7 @@ void *Vargen(void *argument)
                 }
               else if ( operatorID == TOPO )
                 {
-#if defined(WITH_DATA)
+#if defined(ENABLE_DATA)
                   for ( i = 0; i < gridsize; i++ )
                     array[i] = etopo[i]/etopo_scale - etopo_offset;
 #else
@@ -309,7 +335,7 @@ void *Vargen(void *argument)
                 }
               else if ( operatorID == TEMP )
                 {
-#if defined(WITH_DATA)
+#if defined(ENABLE_DATA)
                   for ( i = 0; i < gridsize; i++ )
                     array[i] = temp[i]/temp_scale - temp_offset;
 #else
@@ -318,7 +344,7 @@ void *Vargen(void *argument)
                 }
               else if ( operatorID == MASK )
                 {
-#if defined(WITH_DATA)
+#if defined(ENABLE_DATA)
                   for ( i = 0; i < gridsize; i++ )
                     array[i] = mask[i]/mask_scale - mask_offset;
 #else
diff --git a/src/Varrms.c b/src/Varrms.c
index d63e4e7..e498f3b 100644
--- a/src/Varrms.c
+++ b/src/Varrms.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Vertint.c b/src/Vertint.c
index 5805939..50d36dc 100644
--- a/src/Vertint.c
+++ b/src/Vertint.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -311,6 +311,11 @@ void *Vertint(void *argument)
     {
       phlev = (double *) malloc(nplev*sizeof(double));
       h2p(phlev, plev, nplev);
+
+      if ( cdoVerbose )
+	for ( i = 0; i < nplev; ++i )
+	  cdoPrint("level = %d   height = %g   pressure = %g", i+1, plev[i], phlev[i]);
+
       memcpy(plev, phlev, nplev*sizeof(double));
       free(phlev);
     }
diff --git a/src/Vertstat.c b/src/Vertstat.c
index d49be7b..c159001 100644
--- a/src/Vertstat.c
+++ b/src/Vertstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Vertwind.c b/src/Vertwind.c
index 04a6b07..55cd816 100644
--- a/src/Vertwind.c
+++ b/src/Vertwind.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Wind.c b/src/Wind.c
index 66f9892..25ea8fc 100644
--- a/src/Wind.c
+++ b/src/Wind.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Writegrid.c b/src/Writegrid.c
index e37ae5c..26b7718 100644
--- a/src/Writegrid.c
+++ b/src/Writegrid.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Writerandom.c b/src/Writerandom.c
index 58c9283..1cab4c4 100644
--- a/src/Writerandom.c
+++ b/src/Writerandom.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/YAR.c b/src/YAR.c
index 598106d..78e60a5 100644
--- a/src/YAR.c
+++ b/src/YAR.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -29,7 +29,7 @@
 #include "clipping.h"
 #endif
 
-int lout = 0;
+int lout = 1;
 
 static
 void gen_xbounds(int nx, double *xvals, double *xbounds)
@@ -361,6 +361,9 @@ void testint_c(field_t *field1, field_t *field2)
   TargetCell.coordinates_y = malloc ( 4 * sizeof(*TargetCell.coordinates_y) );
 
   unsigned const * curr_deps;
+  struct polygons polygons;
+
+  polygon_create ( &polygons );
 
   for ( int i = 0; i < num_elements; ++i )
     {
@@ -414,7 +417,8 @@ void testint_c(field_t *field1, field_t *field2)
 	    }
 	}
       
-      polygon_partial_weights (num_deps, SourceCell, TargetCell, weight );
+      polygon_partial_weights(num_deps, SourceCell, TargetCell, weight, &polygons);
+
       for ( int k = 0; k < num_deps; ++k )
 	{
 	  int index1 = curr_deps[k];
@@ -426,6 +430,7 @@ void testint_c(field_t *field1, field_t *field2)
       // correct_weights ( nSourceCells, weight );
     }
 
+  polygon_destroy ( &polygons );
   /*
   for ( int j = 0; j < 10; ++j )
     {
diff --git a/src/Ydayarith.c b/src/Ydayarith.c
index 12870be..c392d78 100644
--- a/src/Ydayarith.c
+++ b/src/Ydayarith.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Ydaystat.c b/src/Ydaystat.c
index 398aa09..988b399 100644
--- a/src/Ydaystat.c
+++ b/src/Ydaystat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -24,7 +24,9 @@
       Ydaystat   ydaymean        Multi-year daily mean
       Ydaystat   ydayavg         Multi-year daily average
       Ydaystat   ydayvar         Multi-year daily variance
+      Ydaystat   ydayvar1        Multi-year daily variance [Divisor is (n-1)]
       Ydaystat   ydaystd         Multi-year daily standard deviation
+      Ydaystat   ydaystd1        Multi-year daily standard deviation [Divisor is (n-1)]
 */
 
 #include <cdi.h>
@@ -44,7 +46,6 @@ void *Ydaystat(void *argument)
   int i;
   int varID;
   int recID;
-  int gridID;
   int vdate, vtime;
   int year, month, day, dayoy;
   int nrecs, nrecords;
@@ -58,7 +59,8 @@ void *Ydaystat(void *argument)
   int nvars, nlevel;
   int *recVarID, *recLevelID;
   int vdates[NDAY], vtimes[NDAY];
-  double missval;
+  int lmean = FALSE, lvarstd = FALSE, lstd = FALSE;
+  double divisor;
   field_t **vars1[NDAY], **vars2[NDAY], **samp1[NDAY];
   field_t field;
 
@@ -70,11 +72,18 @@ void *Ydaystat(void *argument)
   cdoOperatorAdd("ydaymean", func_mean, 0, NULL);
   cdoOperatorAdd("ydayavg",  func_avg,  0, NULL);
   cdoOperatorAdd("ydayvar",  func_var,  0, NULL);
+  cdoOperatorAdd("ydayvar1", func_var1, 0, NULL);
   cdoOperatorAdd("ydaystd",  func_std,  0, NULL);
+  cdoOperatorAdd("ydaystd1", func_std1, 0, NULL);
 
   operatorID = cdoOperatorID();
   operfunc = cdoOperatorF1(operatorID);
 
+  lmean   = operfunc == func_mean || operfunc == func_avg;
+  lstd    = operfunc == func_std || operfunc == func_std1;
+  lvarstd = operfunc == func_std || operfunc == func_var || operfunc == func_std1 || operfunc == func_var1;
+  divisor = operfunc == func_std1 || operfunc == func_var1;
+
   for ( dayoy = 0; dayoy < NDAY; dayoy++ )
     {
       vars1[dayoy] = NULL;
@@ -130,42 +139,10 @@ void *Ydaystat(void *argument)
 
       if ( vars1[dayoy] == NULL )
 	{
-	  vars1[dayoy] = (field_t **) malloc(nvars*sizeof(field_t *));
-	  samp1[dayoy] = (field_t **) malloc(nvars*sizeof(field_t *));
-	  if ( operfunc == func_std || operfunc == func_var )
-	    vars2[dayoy] = (field_t **) malloc(nvars*sizeof(field_t *));
-
-	  for ( varID = 0; varID < nvars; varID++ )
-	    {
-	      gridID   = vlistInqVarGrid(vlistID1, varID);
-	      gridsize = gridInqSize(gridID);
-	      nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-	      missval  = vlistInqVarMissval(vlistID1, varID);
-
-	      vars1[dayoy][varID] = (field_t *)  malloc(nlevel*sizeof(field_t));
-	      samp1[dayoy][varID] = (field_t *)  malloc(nlevel*sizeof(field_t));
-	      if ( operfunc == func_std || operfunc == func_var )
-		vars2[dayoy][varID] = (field_t *)  malloc(nlevel*sizeof(field_t));
-	      
-	      for ( levelID = 0; levelID < nlevel; levelID++ )
-		{
-		  vars1[dayoy][varID][levelID].grid    = gridID;
-		  vars1[dayoy][varID][levelID].nmiss   = 0;
-		  vars1[dayoy][varID][levelID].missval = missval;
-		  vars1[dayoy][varID][levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
-		  samp1[dayoy][varID][levelID].grid    = gridID;
-		  samp1[dayoy][varID][levelID].nmiss   = 0;
-		  samp1[dayoy][varID][levelID].missval = missval;
-		  samp1[dayoy][varID][levelID].ptr     = NULL;
-		  if ( operfunc == func_std || operfunc == func_var )
-		    {
-		      vars2[dayoy][varID][levelID].grid    = gridID;
-		      vars2[dayoy][varID][levelID].nmiss   = 0;
-		      vars2[dayoy][varID][levelID].missval = missval;
-		      vars2[dayoy][varID][levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
-		    }
-		}
-	    }
+	  vars1[dayoy] = field_malloc(vlistID1, FIELD_PTR);
+	  samp1[dayoy] = field_malloc(vlistID1, FIELD_NONE);
+	  if ( lvarstd )
+	    vars2[dayoy] = field_malloc(vlistID1, FIELD_PTR);
 	}
 
       for ( recID = 0; recID < nrecs; recID++ )
@@ -218,7 +195,7 @@ void *Ydaystat(void *argument)
 		      samp1[dayoy][varID][levelID].ptr[i]++;
 		}
 
-	      if ( operfunc == func_std || operfunc == func_var )
+	      if ( lvarstd )
 		{
 		  farsumq(&vars2[dayoy][varID][levelID], field);
 		  farsum(&vars1[dayoy][varID][levelID], field);
@@ -230,7 +207,7 @@ void *Ydaystat(void *argument)
 	    }
 	}
 
-      if ( nsets[dayoy] == 0 && (operfunc == func_std || operfunc == func_var) )
+      if ( nsets[dayoy] == 0 && lvarstd )
 	for ( varID = 0; varID < nvars; varID++ )
 	  {
 	    if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
@@ -247,7 +224,7 @@ void *Ydaystat(void *argument)
   for ( dayoy = 0; dayoy < NDAY; dayoy++ )
     if ( nsets[dayoy] )
       {
-	if ( operfunc == func_mean || operfunc == func_avg )
+	if ( lmean )
 	  for ( varID = 0; varID < nvars; varID++ )
 	    {
 	      if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
@@ -260,7 +237,7 @@ void *Ydaystat(void *argument)
 		    fardiv(&vars1[dayoy][varID][levelID], samp1[dayoy][varID][levelID]);
 		}
 	    }
-	else if ( operfunc == func_std || operfunc == func_var )
+	else if ( lvarstd )
 	  for ( varID = 0; varID < nvars; varID++ )
 	    {
 	      if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
@@ -269,18 +246,17 @@ void *Ydaystat(void *argument)
 		{
 		  if ( samp1[dayoy][varID][levelID].ptr == NULL )
 		    {
-		      if ( operfunc == func_std )
-			farcstd(&vars1[dayoy][varID][levelID], vars2[dayoy][varID][levelID], 1.0/nsets[dayoy]);
+		      if ( lstd )
+			farcstdx(&vars1[dayoy][varID][levelID], vars2[dayoy][varID][levelID], nsets[dayoy], divisor);
 		      else
-			farcvar(&vars1[dayoy][varID][levelID], vars2[dayoy][varID][levelID], 1.0/nsets[dayoy]);
+			farcvarx(&vars1[dayoy][varID][levelID], vars2[dayoy][varID][levelID], nsets[dayoy], divisor);
 		    }
 		  else
 		    {
-		      farinv(&samp1[dayoy][varID][levelID]);
-		      if ( operfunc == func_std )
-			farstd(&vars1[dayoy][varID][levelID], vars2[dayoy][varID][levelID], samp1[dayoy][varID][levelID]);
+		      if ( lstd )
+			farstdx(&vars1[dayoy][varID][levelID], vars2[dayoy][varID][levelID], samp1[dayoy][varID][levelID], divisor);
 		      else
-			farvar(&vars1[dayoy][varID][levelID], vars2[dayoy][varID][levelID], samp1[dayoy][varID][levelID]);
+			farvarx(&vars1[dayoy][varID][levelID], vars2[dayoy][varID][levelID], samp1[dayoy][varID][levelID], divisor);
 		    }
 		}
 	    }
@@ -308,24 +284,9 @@ void *Ydaystat(void *argument)
     {
       if ( vars1[dayoy] != NULL )
 	{
-	  for ( varID = 0; varID < nvars; varID++ )
-	    {
-	      nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-	      for ( levelID = 0; levelID < nlevel; levelID++ )
-		{
-		  free(vars1[dayoy][varID][levelID].ptr);
-		  if ( samp1[dayoy][varID][levelID].ptr ) free(samp1[dayoy][varID][levelID].ptr);
-		  if ( operfunc == func_std || operfunc == func_var ) free(vars2[dayoy][varID][levelID].ptr);
-		}
-	      
-	      free(vars1[dayoy][varID]);
-	      free(samp1[dayoy][varID]);
-	      if ( operfunc == func_std || operfunc == func_var ) free(vars2[dayoy][varID]);
-	    }
-
-	  free(vars1[dayoy]);
-	  free(samp1[dayoy]);
-	  if ( operfunc == func_std || operfunc == func_var ) free(vars2[dayoy]);
+	  field_free(vars1[dayoy], vlistID1);
+	  field_free(samp1[dayoy], vlistID1);
+	  if ( lvarstd ) field_free(vars2[dayoy], vlistID1);
 	}
     }
 
diff --git a/src/Ydrunstat.c b/src/Ydrunstat.c
index ca8de8f..ce4759e 100644
--- a/src/Ydrunstat.c
+++ b/src/Ydrunstat.c
@@ -24,7 +24,9 @@
       Ydrunstat    ydrunmean         Multi-year daily running mean
       Ydrunstat    ydrunavg          Multi-year daily running average
       Ydrunstat    ydrunvar          Multi-year daily running variance
+      Ydrunstat    ydrunvar1         Multi-year daily running variance [Divisor is (n-1)]
       Ydrunstat    ydrunstd          Multi-year daily running standard deviation
+      Ydrunstat    ydrunstd1         Multi-year daily running standard deviation [Divisor is (n-1)]
 */
 
 #include <cdi.h>
@@ -37,12 +39,12 @@
 
 
 typedef struct {
-  int     vdate[NDAY];
-  int     vtime[NDAY];  
+  int       vdate[NDAY];
+  int       vtime[NDAY];  
   field_t **vars1[NDAY]; 
   field_t **vars2[NDAY];
-  int     nsets[NDAY];
-  int     vlist;
+  int       nsets[NDAY];
+  int       vlist;
 }
 YDAY_STATS;
 
@@ -74,7 +76,9 @@ void *Ydrunstat(void *argument)
   int nmiss;
   int nvars, nlevels;
   int *recVarID, *recLevelID;
+  int lmean = FALSE, lvarstd = FALSE, lstd = FALSE;
   double missval;
+  double divisor;
   field_t ***vars1 = NULL, ***vars2 = NULL;
   datetime_t *datetime;
   int taxisID1, taxisID2;
@@ -91,13 +95,20 @@ void *Ydrunstat(void *argument)
   cdoOperatorAdd("ydrunmean", func_mean, 0, NULL);
   cdoOperatorAdd("ydrunavg",  func_avg,  0, NULL);
   cdoOperatorAdd("ydrunvar",  func_var,  0, NULL);
+  cdoOperatorAdd("ydrunvar1", func_var1, 0, NULL);
   cdoOperatorAdd("ydrunstd",  func_std,  0, NULL);
+  cdoOperatorAdd("ydrunstd1", func_std1, 0, NULL);
 
   operatorID = cdoOperatorID();
   operfunc = cdoOperatorF1(operatorID);
 
   operatorInputArg("number of timesteps");
   ndates = atoi(operatorArgv()[0]);
+
+  lmean   = operfunc == func_mean || operfunc == func_avg;
+  lstd    = operfunc == func_std || operfunc == func_std1;
+  lvarstd = operfunc == func_std || operfunc == func_var || operfunc == func_std1 || operfunc == func_var1;
+  divisor = operfunc == func_std1 || operfunc == func_var1;
   
   streamID1 = streamOpenRead(cdoStreamName(0));
 
@@ -126,13 +137,13 @@ void *Ydrunstat(void *argument)
   
   stats = ydstatCreate(vlistID1);
   vars1 = (field_t ***) malloc((ndates+1)*sizeof(field_t **));
-  if ( operfunc == func_std || operfunc == func_var )
+  if ( lvarstd )
     vars2 = (field_t ***) malloc((ndates+1)*sizeof(field_t **));
   
   for ( its = 0; its < ndates; its++ )
     {
       vars1[its] = (field_t **) malloc(nvars*sizeof(field_t *));
-      if ( operfunc == func_std || operfunc == func_var )
+      if ( lvarstd )
 	vars2[its] = (field_t **) malloc(nvars*sizeof(field_t *));
 
       for ( varID = 0; varID < nvars; varID++ )
@@ -143,7 +154,7 @@ void *Ydrunstat(void *argument)
 	  missval  = vlistInqVarMissval(vlistID1, varID);
 
 	  vars1[its][varID] = (field_t *) malloc(nlevels*sizeof(field_t));
-	  if ( operfunc == func_std || operfunc == func_var )
+	  if ( lvarstd )
 	    vars2[its][varID] = (field_t *) malloc(nlevels*sizeof(field_t));
 
 	  for ( levelID = 0; levelID < nlevels; levelID++ )
@@ -152,7 +163,7 @@ void *Ydrunstat(void *argument)
 	      vars1[its][varID][levelID].nmiss   = 0;
 	      vars1[its][varID][levelID].missval = missval;
 	      vars1[its][varID][levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
-	      if ( operfunc == func_std || operfunc == func_var )
+	      if ( lvarstd )
 		{
 		  vars2[its][varID][levelID].grid    = gridID;
 		  vars2[its][varID][levelID].nmiss   = 0;
@@ -185,7 +196,7 @@ void *Ydrunstat(void *argument)
 	  streamReadRecord(streamID1, vars1[tsID][varID][levelID].ptr, &nmiss);
 	  vars1[tsID][varID][levelID].nmiss = nmiss;
 
-	  if ( operfunc == func_std || operfunc == func_var )
+	  if ( lvarstd )
 	    {
 	      farmoq(&vars2[tsID][varID][levelID], vars1[tsID][varID][levelID]);
 	      for ( inp = 0; inp < tsID; inp++ )
@@ -211,21 +222,21 @@ void *Ydrunstat(void *argument)
       vdate = datetime[ndates].date;
       vtime = datetime[ndates].time;
       
-      if ( operfunc == func_std || operfunc == func_var )   
+      if ( lvarstd )   
         ydstatUpdate(stats, vdate, vtime, vars1[0], vars2[0], ndates, operfunc);
       else
         ydstatUpdate(stats, vdate, vtime, vars1[0], NULL, ndates, operfunc);
         
       datetime[ndates] = datetime[0];
       vars1[ndates] = vars1[0];
-      if ( operfunc == func_std || operfunc == func_var )
+      if ( lvarstd )
         vars2[ndates] = vars2[0];
 
       for ( inp = 0; inp < ndates; inp++ )
 	{
 	  datetime[inp] = datetime[inp+1];
 	  vars1[inp] = vars1[inp+1];
-	  if ( operfunc == func_std || operfunc == func_var )
+	  if ( lvarstd )
 	    vars2[inp] = vars2[inp+1];
 	}
 
@@ -242,7 +253,7 @@ void *Ydrunstat(void *argument)
 	  streamReadRecord(streamID1, vars1[ndates-1][varID][levelID].ptr, &nmiss);
 	  vars1[ndates-1][varID][levelID].nmiss = nmiss;
 
-	  if ( operfunc == func_std || operfunc == func_var )
+	  if ( lvarstd )
 	    {
 	      for ( inp = 0; inp < ndates-1; inp++ )
 		{
@@ -296,19 +307,19 @@ void *Ydrunstat(void *argument)
 	  for ( levelID = 0; levelID < nlevels; levelID++ )
 	    {
 	      free(vars1[its][varID][levelID].ptr);
-	      if ( operfunc == func_std || operfunc == func_var ) free(vars2[its][varID][levelID].ptr);
+	      if ( lvarstd ) free(vars2[its][varID][levelID].ptr);
 	    }
 
 	  free(vars1[its][varID]);
-	  if ( operfunc == func_std || operfunc == func_var ) free(vars2[its][varID]);
+	  if ( lvarstd ) free(vars2[its][varID]);
 	}
 	free(vars1[its]);
-	if ( operfunc == func_std || operfunc == func_var ) free(vars2[its]);
+	if ( lvarstd ) free(vars2[its]);
     }
   
   ydstatDestroy(stats);
   free(vars1);
-  if ( operfunc == func_std || operfunc == func_var ) free(vars2);
+  if ( lvarstd ) free(vars2);
 
   if ( datetime ) free(datetime);
 
@@ -448,6 +459,9 @@ void ydstatUpdate(YDAY_STATS *stats, int vdate, int vtime,
   int varID, levelID, nvars, nlevels;
   int gridsize;
   int year, month, day, dayoy;
+  int lvarstd;
+
+  lvarstd = vars2 != NULL;
 
   nvars = vlistNvars(stats->vlist);
   
@@ -469,7 +483,7 @@ void ydstatUpdate(YDAY_STATS *stats, int vdate, int vtime,
   if ( stats->vars1[dayoy] == NULL )
     {
       ydstatCreateVars1(stats, dayoy);
-      if ( operfunc == func_std || operfunc == func_var )
+      if ( lvarstd )
 	ydstatCreateVars2(stats, dayoy);
     }
 
@@ -487,7 +501,7 @@ void ydstatUpdate(YDAY_STATS *stats, int vdate, int vtime,
 	      memcpy(stats->vars1[dayoy][varID][levelID].ptr, vars1[varID][levelID].ptr, gridsize * sizeof(double));
 	      stats->vars1[dayoy][varID][levelID].nmiss = vars1[varID][levelID].nmiss;
 	       
-	      if ( operfunc == func_std || operfunc == func_var )
+	      if ( lvarstd )
 	        {
 	          memcpy(stats->vars2[dayoy][varID][levelID].ptr, vars2[varID][levelID].ptr, gridsize * sizeof(double));
 	          stats->vars2[dayoy][varID][levelID].nmiss = vars2[varID][levelID].nmiss;
@@ -495,7 +509,7 @@ void ydstatUpdate(YDAY_STATS *stats, int vdate, int vtime,
 	    }
 	  else
 	    {
-	      if ( operfunc == func_std || operfunc == func_var )
+	      if ( lvarstd )
 	        {
 		  farsum(&stats->vars1[dayoy][varID][levelID], vars1[varID][levelID]);
 		  farsum(&stats->vars2[dayoy][varID][levelID], vars2[varID][levelID]);
@@ -516,7 +530,10 @@ void ydstatFinalize(YDAY_STATS *stats, int operfunc)
 {
   int varID, levelID, nvars, nlevels;
   int dayoy;
-  
+  double divisor;
+
+  divisor = operfunc == func_std1 || operfunc == func_var1;
+
   nvars = vlistNvars(stats->vlist);
   
   for ( dayoy = 0; dayoy < NDAY; dayoy++ )
@@ -524,7 +541,8 @@ void ydstatFinalize(YDAY_STATS *stats, int operfunc)
       {
       	switch ( operfunc )
       	  {
-	    case func_avg: case func_mean:
+	    case func_avg:
+	    case func_mean:
 	      for ( varID = 0; varID < nvars; varID++ )
 	        {
 	          if ( vlistInqVarTsteptype(stats->vlist, varID) == TSTEP_CONSTANT ) continue;
@@ -535,24 +553,26 @@ void ydstatFinalize(YDAY_STATS *stats, int operfunc)
 	      break;
 	      
 	    case func_std:
+	    case func_std1:
 	      for ( varID = 0; varID < nvars; varID++ )
 	        {
 	          if ( vlistInqVarTsteptype(stats->vlist, varID) == TSTEP_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],
-		      1.0 / stats->nsets[dayoy]);
+		    farcstdx(&stats->vars1[dayoy][varID][levelID], stats->vars2[dayoy][varID][levelID],
+			     stats->nsets[dayoy], divisor);
 	        }
 	      break;
 	      
 	    case func_var:
+	    case func_var1:
 	      for ( varID = 0; varID < nvars; varID++ )
 	        {
 	          if ( vlistInqVarTsteptype(stats->vlist, varID) == TSTEP_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],
-		      1.0 / stats->nsets[dayoy]);
+		    farcvarx(&stats->vars1[dayoy][varID][levelID], stats->vars2[dayoy][varID][levelID],
+			    stats->nsets[dayoy], divisor);
 	        }
 	      break;
       	  }
diff --git a/src/Yearmonstat.c b/src/Yearmonstat.c
new file mode 100644
index 0000000..3c38915
--- /dev/null
+++ b/src/Yearmonstat.c
@@ -0,0 +1,259 @@
+/*
+  This file is part of CDO. CDO is a collection of Operators to
+  manipulate and analyse Climate model Data.
+
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  See COPYING file for copying and redistribution conditions.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; version 2 of the License.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+*/
+
+/*
+   This module contains the following operators:
+
+      Yearmonstat   yearmonmean        Yearly mean from monthly data
+      Yearmonstat   yearmonavg         Yearly average from monthly data
+*/
+
+
+#include <cdi.h>
+#include "cdo.h"
+#include "cdo_int.h"
+#include "pstream.h"
+
+
+void *Yearmonstat(void *argument)
+{
+  int operatorID;
+  int operfunc;
+  int gridsize;
+  int vdate = 0, vtime = 0;
+  int vdate0 = 0, vtime0 = 0;
+  int nrecs, nrecords;
+  int varID, levelID, recID;
+  int tsID;
+  int otsID;
+  long nsets;
+  double dsets;
+  int i;
+  int dpm;
+  int year0, month0;
+  int year, month, day;
+  int calendar;
+  int streamID1, streamID2;
+  int vlistID1, vlistID2, taxisID1, taxisID2;
+  int nmiss;
+  int nvars, nlevel;
+  int *recVarID, *recLevelID;
+  char vdatestr[32], vtimestr[32];
+  field_t **vars1 = NULL, **samp1 = NULL;
+  field_t field;
+  int timestat_date = DATE_MIDDLE;
+  dtinfo_t dtinfo[13];
+
+  cdoInitialize(argument);
+
+  get_timestat_date(&timestat_date);
+
+  cdoOperatorAdd("yearmonmean",  func_mean, 0, NULL);
+  cdoOperatorAdd("yearmonavg",   func_avg,  0, NULL);
+
+  operatorID = cdoOperatorID();
+  operfunc = cdoOperatorF1(operatorID);
+
+  streamID1 = streamOpenRead(cdoStreamName(0));
+
+  vlistID1 = streamInqVlist(streamID1);
+  vlistID2 = vlistDuplicate(vlistID1);
+
+  taxisID1 = vlistInqTaxis(vlistID1);
+  taxisID2 = taxisDuplicate(taxisID1);
+  vlistDefTaxis(vlistID2, taxisID2);
+
+  calendar = taxisInqCalendar(taxisID1);
+
+  streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+
+  streamDefVlist(streamID2, vlistID2);
+
+  nvars    = vlistNvars(vlistID1);
+  nrecords = vlistNrecs(vlistID1);
+
+  recVarID   = (int *) malloc(nrecords*sizeof(int));
+  recLevelID = (int *) malloc(nrecords*sizeof(int));
+
+  gridsize = vlistGridsizeMax(vlistID1);
+
+  field.ptr = (double *) malloc(gridsize*sizeof(double));
+
+  vars1 = field_malloc(vlistID1, FIELD_PTR);
+  samp1 = field_malloc(vlistID1, FIELD_NONE);
+
+  tsID    = 0;
+  otsID   = 0;
+  while ( TRUE )
+    {
+      nsets = 0;
+      dsets = 0;
+      while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
+	{
+	  taxisInqDTinfo(taxisID1, &dtinfo[nsets]);
+	  vdate = dtinfo[nsets].v.date;
+	  vtime = dtinfo[nsets].v.time;
+	  cdiDecodeDate(vdate, &year, &month, &day);
+
+	  if ( nsets == 0 ) year0 = year;
+
+	  if ( year != year0 ) break;
+
+	  if ( nsets > 0 && month == month0 )
+	    {
+	      date2str(vdate0, vdatestr, sizeof(vdatestr));
+	      time2str(vtime0, vtimestr, sizeof(vtimestr));
+	      cdoWarning("   last timestep: %s %s", vdatestr, vtimestr);
+	      date2str(vdate, vdatestr, sizeof(vdatestr));
+	      time2str(vtime, vtimestr, sizeof(vtimestr));
+	      cdoWarning("current timestep: %s %s", vdatestr, vtimestr);
+	      cdoAbort("Month does not change!");
+	    }
+
+	  dpm = days_per_month(calendar, year, month);
+
+	  for ( recID = 0; recID < nrecs; recID++ )
+	    {
+	      streamInqRecord(streamID1, &varID, &levelID);
+
+	      if ( tsID == 0 )
+		{
+		  recVarID[recID]   = varID;
+		  recLevelID[recID] = levelID;
+		}
+
+	      gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
+
+	      if ( nsets == 0 )
+		{
+		  streamReadRecord(streamID1, vars1[varID][levelID].ptr, &nmiss);
+		  vars1[varID][levelID].nmiss = nmiss;
+
+		  farcmul(&vars1[varID][levelID], dpm);
+
+		  if ( nmiss > 0 || samp1[varID][levelID].ptr )
+		    {
+		      if ( samp1[varID][levelID].ptr == NULL )
+			samp1[varID][levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+
+		      for ( i = 0; i < gridsize; i++ )
+			if ( DBL_IS_EQUAL(vars1[varID][levelID].ptr[i], vars1[varID][levelID].missval) )
+			  samp1[varID][levelID].ptr[i] = 0;
+			else
+			  samp1[varID][levelID].ptr[i] = dpm;
+		    }
+		}
+	      else
+		{
+		  streamReadRecord(streamID1, field.ptr, &field.nmiss);
+		  field.grid    = vars1[varID][levelID].grid;
+		  field.missval = vars1[varID][levelID].missval;
+
+		  farcmul(&field, dpm);
+
+		  if ( field.nmiss > 0 || samp1[varID][levelID].ptr )
+		    {
+		      if ( samp1[varID][levelID].ptr == NULL )
+			{
+			  samp1[varID][levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+			  for ( i = 0; i < gridsize; i++ )
+			    samp1[varID][levelID].ptr[i] = dsets;
+			}
+
+		      for ( i = 0; i < gridsize; i++ )
+			if ( !DBL_IS_EQUAL(field.ptr[i], vars1[varID][levelID].missval) )
+			  samp1[varID][levelID].ptr[i] += dpm;
+		    }
+
+		  farfun(&vars1[varID][levelID], field, operfunc);
+		}
+	    }
+
+	  month0 = month;
+	  vdate0 = vdate;
+	  vtime0 = vtime;
+	  nsets++;
+	  dsets += dpm;
+	  tsID++;
+	}
+
+      if ( nrecs == 0 && nsets == 0 ) break;
+
+      for ( varID = 0; varID < nvars; varID++ )
+	{
+	  if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+	  nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
+	  for ( levelID = 0; levelID < nlevel; levelID++ )
+	    {
+	      if ( samp1[varID][levelID].ptr == NULL )
+		farcmul(&vars1[varID][levelID], 1.0/dsets);
+	      else
+		fardiv(&vars1[varID][levelID], samp1[varID][levelID]);
+	    }
+	}
+
+      if ( cdoVerbose )
+	{
+	  date2str(vdate0, vdatestr, sizeof(vdatestr));
+	  time2str(vtime0, vtimestr, sizeof(vtimestr));
+	  cdoPrint("%s %s  nsets = %d", vdatestr, vtimestr, nsets);
+	}
+
+      if      ( timestat_date == DATE_MIDDLE ) datetime_avg_dtinfo(calendar, nsets, dtinfo);
+      else if ( timestat_date == DATE_FIRST  ) dtinfo[nsets].v = dtinfo[0].v;
+      else if ( timestat_date == DATE_LAST   ) dtinfo[nsets].v = dtinfo[nsets-1].v;
+
+      if ( taxisHasBounds(taxisID2) )
+	{
+	  dtinfo[nsets].b[0] = dtinfo[0].b[0];
+	  dtinfo[nsets].b[1] = dtinfo[nsets-1].b[1];
+	}
+
+      taxisDefDTinfo(taxisID2, dtinfo[nsets]);
+      streamDefTimestep(streamID2, otsID);
+
+      for ( recID = 0; recID < nrecords; recID++ )
+	{
+	  varID   = recVarID[recID];
+	  levelID = recLevelID[recID];
+
+	  if ( otsID && vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
+
+	  streamDefRecord(streamID2, varID, levelID);
+	  streamWriteRecord(streamID2, vars1[varID][levelID].ptr,  vars1[varID][levelID].nmiss);
+	}
+
+      if ( nrecs == 0 ) break;
+      otsID++;
+    }
+
+
+  field_free(vars1, vlistID1);
+  field_free(samp1, vlistID1);
+
+  streamClose(streamID2);
+  streamClose(streamID1);
+
+  if ( field.ptr ) free(field.ptr);
+
+  if ( recVarID   ) free(recVarID);
+  if ( recLevelID ) free(recLevelID);
+
+  cdoFinish();
+
+  return (0);
+}
diff --git a/src/Yhourarith.c b/src/Yhourarith.c
index cc6ee50..4392de5 100644
--- a/src/Yhourarith.c
+++ b/src/Yhourarith.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Yhourstat.c b/src/Yhourstat.c
index 1d64723..00fc863 100644
--- a/src/Yhourstat.c
+++ b/src/Yhourstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -24,7 +24,9 @@
       Yhourstat   yhourmean        Multi-year hourly mean
       Yhourstat   yhouravg         Multi-year hourly average
       Yhourstat   yhourvar         Multi-year hourly variance
+      Yhourstat   yhourvar1        Multi-year hourly variance [Divisor is (n-1)]
       Yhourstat   yhourstd         Multi-year hourly standard deviation
+      Yhourstat   yhourstd1        Multi-year hourly standard deviation [Divisor is (n-1)]
 */
 
 #include <cdi.h>
@@ -69,7 +71,6 @@ void *Yhourstat(void *argument)
   int i;
   int varID;
   int recID;
-  int gridID;
   int vdate, vtime;
   int houroy;
   int nrecs, nrecords;
@@ -83,7 +84,8 @@ void *Yhourstat(void *argument)
   int nvars, nlevel;
   int *recVarID, *recLevelID;
   int vdates[MAX_HOUR], vtimes[MAX_HOUR];
-  double missval;
+  int lmean = FALSE, lvarstd = FALSE, lstd = FALSE;
+  double divisor;
   field_t **vars1[MAX_HOUR], **vars2[MAX_HOUR], **samp1[MAX_HOUR];
   field_t field;
 
@@ -95,11 +97,18 @@ void *Yhourstat(void *argument)
   cdoOperatorAdd("yhourmean", func_mean, 0, NULL);
   cdoOperatorAdd("yhouravg",  func_avg,  0, NULL);
   cdoOperatorAdd("yhourvar",  func_var,  0, NULL);
+  cdoOperatorAdd("yhourvar1", func_var1, 0, NULL);
   cdoOperatorAdd("yhourstd",  func_std,  0, NULL);
+  cdoOperatorAdd("yhourstd1", func_std1, 0, NULL);
 
   operatorID = cdoOperatorID();
   operfunc = cdoOperatorF1(operatorID);
 
+  lmean   = operfunc == func_mean || operfunc == func_avg;
+  lstd    = operfunc == func_std || operfunc == func_std1;
+  lvarstd = operfunc == func_std || operfunc == func_var || operfunc == func_std1 || operfunc == func_var1;
+  divisor = operfunc == func_std1 || operfunc == func_var1;
+
   for ( houroy = 0; houroy < MAX_HOUR; ++houroy )
     {
       vars1[houroy] = NULL;
@@ -147,42 +156,10 @@ void *Yhourstat(void *argument)
 
       if ( vars1[houroy] == NULL )
 	{
-	  vars1[houroy] = (field_t **) malloc(nvars*sizeof(field_t *));
-	  samp1[houroy] = (field_t **) malloc(nvars*sizeof(field_t *));
-	  if ( operfunc == func_std || operfunc == func_var )
-	    vars2[houroy] = (field_t **) malloc(nvars*sizeof(field_t *));
-
-	  for ( varID = 0; varID < nvars; varID++ )
-	    {
-	      gridID   = vlistInqVarGrid(vlistID1, varID);
-	      gridsize = gridInqSize(gridID);
-	      nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-	      missval  = vlistInqVarMissval(vlistID1, varID);
-
-	      vars1[houroy][varID] = (field_t *)  malloc(nlevel*sizeof(field_t));
-	      samp1[houroy][varID] = (field_t *)  malloc(nlevel*sizeof(field_t));
-	      if ( operfunc == func_std || operfunc == func_var )
-		vars2[houroy][varID] = (field_t *)  malloc(nlevel*sizeof(field_t));
-	      
-	      for ( levelID = 0; levelID < nlevel; levelID++ )
-		{
-		  vars1[houroy][varID][levelID].grid    = gridID;
-		  vars1[houroy][varID][levelID].nmiss   = 0;
-		  vars1[houroy][varID][levelID].missval = missval;
-		  vars1[houroy][varID][levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
-		  samp1[houroy][varID][levelID].grid    = gridID;
-		  samp1[houroy][varID][levelID].nmiss   = 0;
-		  samp1[houroy][varID][levelID].missval = missval;
-		  samp1[houroy][varID][levelID].ptr     = NULL;
-		  if ( operfunc == func_std || operfunc == func_var )
-		    {
-		      vars2[houroy][varID][levelID].grid    = gridID;
-		      vars2[houroy][varID][levelID].nmiss   = 0;
-		      vars2[houroy][varID][levelID].missval = missval;
-		      vars2[houroy][varID][levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
-		    }
-		}
-	    }
+	  vars1[houroy] = field_malloc(vlistID1, FIELD_PTR);
+	  samp1[houroy] = field_malloc(vlistID1, FIELD_NONE);
+	  if ( lvarstd )
+	    vars2[houroy] = field_malloc(vlistID1, FIELD_PTR);
 	}
 
       for ( recID = 0; recID < nrecs; recID++ )
@@ -235,7 +212,7 @@ void *Yhourstat(void *argument)
 		      samp1[houroy][varID][levelID].ptr[i]++;
 		}
 
-	      if ( operfunc == func_std || operfunc == func_var )
+	      if ( lvarstd )
 		{
 		  farsumq(&vars2[houroy][varID][levelID], field);
 		  farsum(&vars1[houroy][varID][levelID], field);
@@ -247,7 +224,7 @@ void *Yhourstat(void *argument)
 	    }
 	}
 
-      if ( nsets[houroy] == 0 && (operfunc == func_std || operfunc == func_var) )
+      if ( nsets[houroy] == 0 && lvarstd )
 	for ( varID = 0; varID < nvars; varID++ )
 	  {
 	    if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
@@ -264,7 +241,7 @@ void *Yhourstat(void *argument)
   for ( houroy = 0; houroy < MAX_HOUR; ++houroy )
     if ( nsets[houroy] )
       {
-	if ( operfunc == func_mean || operfunc == func_avg )
+	if ( lmean )
 	  for ( varID = 0; varID < nvars; varID++ )
 	    {
 	      if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
@@ -277,7 +254,7 @@ void *Yhourstat(void *argument)
 		    fardiv(&vars1[houroy][varID][levelID], samp1[houroy][varID][levelID]);
 		}
 	    }
-	else if ( operfunc == func_std || operfunc == func_var )
+	else if ( lvarstd )
 	  for ( varID = 0; varID < nvars; varID++ )
 	    {
 	      if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
@@ -286,18 +263,17 @@ void *Yhourstat(void *argument)
 		{
 		  if ( samp1[houroy][varID][levelID].ptr == NULL )
 		    {
-		      if ( operfunc == func_std )
-			farcstd(&vars1[houroy][varID][levelID], vars2[houroy][varID][levelID], 1.0/nsets[houroy]);
+		      if ( lstd )
+			farcstdx(&vars1[houroy][varID][levelID], vars2[houroy][varID][levelID], nsets[houroy], divisor);
 		      else
-			farcvar(&vars1[houroy][varID][levelID], vars2[houroy][varID][levelID], 1.0/nsets[houroy]);
+			farcvarx(&vars1[houroy][varID][levelID], vars2[houroy][varID][levelID], nsets[houroy], divisor);
 		    }
 		  else
 		    {
-		      farinv(&samp1[houroy][varID][levelID]);
-		      if ( operfunc == func_std )
-			farstd(&vars1[houroy][varID][levelID], vars2[houroy][varID][levelID], samp1[houroy][varID][levelID]);
+		      if ( lstd )
+			farstdx(&vars1[houroy][varID][levelID], vars2[houroy][varID][levelID], samp1[houroy][varID][levelID], divisor);
 		      else
-			farvar(&vars1[houroy][varID][levelID], vars2[houroy][varID][levelID], samp1[houroy][varID][levelID]);
+			farvarx(&vars1[houroy][varID][levelID], vars2[houroy][varID][levelID], samp1[houroy][varID][levelID], divisor);
 		    }
 		}
 	    }
@@ -325,24 +301,9 @@ void *Yhourstat(void *argument)
     {
       if ( vars1[houroy] != NULL )
 	{
-	  for ( varID = 0; varID < nvars; varID++ )
-	    {
-	      nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-	      for ( levelID = 0; levelID < nlevel; levelID++ )
-		{
-		  free(vars1[houroy][varID][levelID].ptr);
-		  if ( samp1[houroy][varID][levelID].ptr ) free(samp1[houroy][varID][levelID].ptr);
-		  if ( operfunc == func_std || operfunc == func_var ) free(vars2[houroy][varID][levelID].ptr);
-		}
-	      
-	      free(vars1[houroy][varID]);
-	      free(samp1[houroy][varID]);
-	      if ( operfunc == func_std || operfunc == func_var ) free(vars2[houroy][varID]);
-	    }
-
-	  free(samp1[houroy]);
-	  free(vars1[houroy]);
-	  if ( operfunc == func_std || operfunc == func_var ) free(vars2[houroy]);
+	  field_free(samp1[houroy], vlistID1);
+	  field_free(vars1[houroy], vlistID1);
+	  if ( lvarstd ) field_free(vars2[houroy], vlistID1);
 	}
     }
 
diff --git a/src/Ymonarith.c b/src/Ymonarith.c
index d6b1204..ad376e0 100644
--- a/src/Ymonarith.c
+++ b/src/Ymonarith.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/Ymonstat.c b/src/Ymonstat.c
index 2b909fc..efd79d0 100644
--- a/src/Ymonstat.c
+++ b/src/Ymonstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -24,7 +24,9 @@
       Ymonstat   ymonmean        Multi-year monthly mean
       Ymonstat   ymonavg         Multi-year monthly average
       Ymonstat   ymonvar         Multi-year monthly variance
+      Ymonstat   ymonvar1        Multi-year monthly variance [Divisor is (n-1)]
       Ymonstat   ymonstd         Multi-year monthly standard deviation
+      Ymonstat   ymonstd1        Multi-year monthly standard deviation [Divisor is (n-1)]
 */
 
 
@@ -59,7 +61,6 @@ void *Ymonstat(void *argument)
   int i;
   int varID;
   int recID;
-  int gridID;
   int vdate, vtime;
   int year, month, day;
   int nrecs, nrecords;
@@ -75,7 +76,8 @@ void *Ymonstat(void *argument)
   int vdates[NMONTH], vtimes[NMONTH];
   int mon[NMONTH];
   int nmon = 0;
-  double missval;
+  int lmean = FALSE, lvarstd = FALSE, lstd = FALSE;
+  double divisor;
   field_t **vars1[NMONTH], **vars2[NMONTH], **samp1[NMONTH];
   field_t field;
 
@@ -87,11 +89,18 @@ void *Ymonstat(void *argument)
   cdoOperatorAdd("ymonmean", func_mean, 0, NULL);
   cdoOperatorAdd("ymonavg",  func_avg,  0, NULL);
   cdoOperatorAdd("ymonvar",  func_var,  0, NULL);
+  cdoOperatorAdd("ymonvar1", func_var1, 0, NULL);
   cdoOperatorAdd("ymonstd",  func_std,  0, NULL);
+  cdoOperatorAdd("ymonstd1", func_std1, 0, NULL);
 
   operatorID = cdoOperatorID();
   operfunc = cdoOperatorF1(operatorID);
 
+  lmean   = operfunc == func_mean || operfunc == func_avg;
+  lstd    = operfunc == func_std || operfunc == func_std1;
+  lvarstd = operfunc == func_std || operfunc == func_var || operfunc == func_std1 || operfunc == func_var1;
+  divisor = operfunc == func_std1 || operfunc == func_var1;
+
   for ( month = 0; month < NMONTH; month++ )
     {
       vars1[month] = NULL;
@@ -143,42 +152,10 @@ void *Ymonstat(void *argument)
       if ( vars1[month] == NULL )
 	{
 	  mon[nmon++] = month;
-	  vars1[month] = (field_t **) malloc(nvars*sizeof(field_t *));
-	  samp1[month] = (field_t **) malloc(nvars*sizeof(field_t *));
-	  if ( operfunc == func_std || operfunc == func_var )
-	    vars2[month] = (field_t **) malloc(nvars*sizeof(field_t *));
-
-	  for ( varID = 0; varID < nvars; varID++ )
-	    {
-	      gridID   = vlistInqVarGrid(vlistID1, varID);
-	      gridsize = gridInqSize(gridID);
-	      nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-	      missval  = vlistInqVarMissval(vlistID1, varID);
-
-	      vars1[month][varID] = (field_t *)  malloc(nlevel*sizeof(field_t));
-	      samp1[month][varID] = (field_t *)  malloc(nlevel*sizeof(field_t));
-	      if ( operfunc == func_std || operfunc == func_var )
-		vars2[month][varID] = (field_t *)  malloc(nlevel*sizeof(field_t));
-	      
-	      for ( levelID = 0; levelID < nlevel; levelID++ )
-		{
-		  vars1[month][varID][levelID].grid    = gridID;
-		  vars1[month][varID][levelID].nmiss   = 0;
-		  vars1[month][varID][levelID].missval = missval;
-		  vars1[month][varID][levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
-		  samp1[month][varID][levelID].grid    = gridID;
-		  samp1[month][varID][levelID].nmiss   = 0;
-		  samp1[month][varID][levelID].missval = missval;
-		  samp1[month][varID][levelID].ptr     = NULL;
-		  if ( operfunc == func_std || operfunc == func_var )
-		    {
-		      vars2[month][varID][levelID].grid    = gridID;
-		      vars2[month][varID][levelID].nmiss   = 0;
-		      vars2[month][varID][levelID].missval = missval;
-		      vars2[month][varID][levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
-		    }
-		}
-	    }
+	  vars1[month] = field_malloc(vlistID1, FIELD_PTR);
+	  samp1[month] = field_malloc(vlistID1, FIELD_NONE);
+	  if ( lvarstd )
+	    vars2[month] = field_malloc(vlistID1, FIELD_PTR);
 	}
 
       for ( recID = 0; recID < nrecs; recID++ )
@@ -231,7 +208,7 @@ void *Ymonstat(void *argument)
 		      samp1[month][varID][levelID].ptr[i]++;
 		}
 
-	      if ( operfunc == func_std || operfunc == func_var )
+	      if ( lvarstd )
 		{
 		  farsumq(&vars2[month][varID][levelID], field);
 		  farsum(&vars1[month][varID][levelID], field);
@@ -243,7 +220,7 @@ void *Ymonstat(void *argument)
 	    }
 	}
 
-      if ( nsets[month] == 0 && (operfunc == func_std || operfunc == func_var) )
+      if ( nsets[month] == 0 && lvarstd )
 	for ( varID = 0; varID < nvars; varID++ )
 	  {
 	    if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
@@ -281,7 +258,7 @@ void *Ymonstat(void *argument)
       month = mon[i];
       if ( nsets[month] == 0 ) cdoAbort("Internal problem, nsets[%d] not defined!", month);
 
-      if ( operfunc == func_mean || operfunc == func_avg )
+      if ( lmean )
 	for ( varID = 0; varID < nvars; varID++ )
 	  {
 	    if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
@@ -294,7 +271,7 @@ void *Ymonstat(void *argument)
 		  fardiv(&vars1[month][varID][levelID], samp1[month][varID][levelID]);
 	      }
 	  }
-      else if ( operfunc == func_std || operfunc == func_var )
+      else if ( lvarstd )
 	for ( varID = 0; varID < nvars; varID++ )
 	  {
 	    if ( vlistInqVarTsteptype(vlistID1, varID) == TSTEP_CONSTANT ) continue;
@@ -303,18 +280,17 @@ void *Ymonstat(void *argument)
 	      {
 		if ( samp1[month][varID][levelID].ptr == NULL )
 		  {
-		    if ( operfunc == func_std )
-		      farcstd(&vars1[month][varID][levelID], vars2[month][varID][levelID], 1.0/nsets[month]);
+		    if ( lstd )
+		      farcstdx(&vars1[month][varID][levelID], vars2[month][varID][levelID], nsets[month], divisor);
 		    else
-		      farcvar(&vars1[month][varID][levelID], vars2[month][varID][levelID], 1.0/nsets[month]);
+		      farcvarx(&vars1[month][varID][levelID], vars2[month][varID][levelID], nsets[month], divisor);
 		  }
 		else
 		  {
-		    farinv(&samp1[month][varID][levelID]);
-		    if ( operfunc == func_std )
-		      farstd(&vars1[month][varID][levelID], vars2[month][varID][levelID], samp1[month][varID][levelID]);
+		    if ( lstd )
+		      farstdx(&vars1[month][varID][levelID], vars2[month][varID][levelID], samp1[month][varID][levelID], divisor);
 		    else
-		      farvar(&vars1[month][varID][levelID], vars2[month][varID][levelID], samp1[month][varID][levelID]);
+		      farvarx(&vars1[month][varID][levelID], vars2[month][varID][levelID], samp1[month][varID][levelID], divisor);
 		  }
 	      }
 	  }
@@ -342,24 +318,9 @@ void *Ymonstat(void *argument)
     {
       if ( vars1[month] != NULL )
 	{
-	  for ( varID = 0; varID < nvars; varID++ )
-	    {
-	      nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-	      for ( levelID = 0; levelID < nlevel; levelID++ )
-		{
-		  free(vars1[month][varID][levelID].ptr);
-		  if ( samp1[month][varID][levelID].ptr ) free(samp1[month][varID][levelID].ptr);
-		  if ( operfunc == func_std || operfunc == func_var ) free(vars2[month][varID][levelID].ptr);
-		}
-	      
-	      free(vars1[month][varID]);
-	      free(samp1[month][varID]);
-	      if ( operfunc == func_std || operfunc == func_var ) free(vars2[month][varID]);
-	    }
-
-	  free(vars1[month]);
-	  free(samp1[month]);
-	  if ( operfunc == func_std || operfunc == func_var ) free(vars2[month]);
+	  field_free(vars1[month], vlistID1);
+	  field_free(samp1[month], vlistID1);
+	  if ( lvarstd ) field_free(vars2[month], vlistID1);
 	}
     }
 
diff --git a/src/Yseasstat.c b/src/Yseasstat.c
index f585935..a31b5dd 100644
--- a/src/Yseasstat.c
+++ b/src/Yseasstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Zonstat.c b/src/Zonstat.c
index bb71214..bbdc39a 100644
--- a/src/Zonstat.c
+++ b/src/Zonstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.1
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/cdo.c b/src/cdo.c
index 85ef5bb..ef8ef0f 100644
--- a/src/cdo.c
+++ b/src/cdo.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -52,6 +52,7 @@
 
 #include "modules.h"
 #include "util.h"
+#include "error.h"
 
 #if defined (_OPENMP)
 #  include <omp.h>
@@ -100,6 +101,14 @@ char **cdoVarnames       = NULL;
 
 char cdo_file_suffix[32];
 
+
+static int Debug = 0;
+static int Version = 0;
+static int Help = 0;
+static int DebugLevel = 0;
+static int numThreads = 0;
+
+
 int cdoExpMode           = -1;
 char *cdoExpName         = NULL;
 void exp_run(int argc, char *argv[], char *cdoExpName);
@@ -239,6 +248,7 @@ void usage(void)
 
   fprintf(stderr, "    -V             Print the version number\n");
   fprintf(stderr, "    -v             Print extra details for some operators\n");
+  fprintf(stderr, "    -W             Print extra warning messages\n");
   fprintf(stderr, "    -z szip        SZIP compression of GRIB1 records\n");
   fprintf(stderr, "       jpeg        JPEG compression of GRIB2 records\n");
   fprintf(stderr, "        zip[_1-9]  Deflate compression of netCDF4 variables\n");
@@ -248,7 +258,7 @@ void usage(void)
   operatorPrintAll();
 
   fprintf(stderr, "\n");
-  fprintf(stderr, "  CDO version %s, Copyright (C) 2003-2012 Uwe Schulzweida\n", VERSION);
+  fprintf(stderr, "  CDO version %s, Copyright (C) 2003-2013 Uwe Schulzweida\n", VERSION);
   //  fprintf(stderr, "  Available from <http://code.zmaw.de/projects/cdo>\n");
   fprintf(stderr, "  This is free software and comes with ABSOLUTELY NO WARRANTY\n");
   fprintf(stderr, "  Report bugs to <http://code.zmaw.de/projects/cdo>\n");
@@ -312,11 +322,11 @@ void cdoSetDebug(int level)
    */
   cdiDebug(level);
 
-  if ( level == 1 || level &  32 ) cdoDebug = 1;
-  if ( level == 1 || level &  64 ) pstreamDebug(1);
+  if ( level == 1 || (level &  32) ) cdoDebug = 1;
+  if ( level == 1 || (level &  64) ) pstreamDebug(1);
 #if  defined  (HAVE_LIBPTHREAD)
-  if ( level == 1 || level & 128 ) pipeDebug(1);
-  if ( level == 1 || level & 256 ) Pthread_debug(1);
+  if ( level == 1 || (level & 128) ) pipeDebug(1);
+  if ( level == 1 || (level & 256) ) Pthread_debug(1);
 #endif
 }
 
@@ -792,42 +802,168 @@ void get_env_vars(void)
     }
 }
 
-
-int main(int argc, char *argv[])
+static
+void print_system_info()
 {
-  int c;
-  int Debug = 0;
-  int Version = 0;
-  int Help = 0;
-  int DebugLevel = 0;
-  int lstop = FALSE;
-  int noff = 0;
-  int status = 0;
-  int numThreads = 0;
-  char *operatorName = NULL;
-  char *operatorArg = NULL;
-  char *argument = NULL;
-  extern int dmemory_ExitOnError;
+  char *envstr;
 
-  init_is_tty();
+  if ( DebugLevel == 0 ) DebugLevel = 1;
+  cdoSetDebug(DebugLevel);
+  fprintf(stderr, "\n");
+  fprintf(stderr, "cdoDefaultFileType  = %d\n", cdoDefaultFileType);
+  fprintf(stderr, "cdoDefaultDataType  = %d\n", cdoDefaultDataType);
+  fprintf(stderr, "cdoDefaultByteorder = %d\n", cdoDefaultByteorder);
+  fprintf(stderr, "cdoDefaultTableID   = %d\n", cdoDefaultTableID);
+  fprintf(stderr, "\n");
 
-  dmemory_ExitOnError = 1;
+  envstr = getenv("HOSTTYPE");
+  if ( envstr ) fprintf(stderr, "HOSTTYPE            = %s\n", envstr);
+  envstr = getenv("VENDOR");
+  if ( envstr ) fprintf(stderr, "VENDOR              = %s\n", envstr);
+  envstr = getenv("OSTYPE");
+  if ( envstr ) fprintf(stderr, "OSTYPE              = %s\n", envstr);
+  envstr = getenv("MACHTYPE");
+  if ( envstr ) fprintf(stderr, "MACHTYPE            = %s\n", envstr);
+  fprintf(stderr, "\n");
 
-  /* mallopt(M_MMAP_MAX, 0); */
- 
-  setCommandLine(argc, argv);
+#if defined (__SSE2__)
+  fprintf(stderr, "Predefined: __SSE2__\n");
+#endif 
+#if defined (__SSE3__)
+  fprintf(stderr, "Predefined: __SSE3__\n");
+#endif 
+#if defined (__SSE4_1__)
+  fprintf(stderr, "Predefined: __SSE4_1__\n");
+#endif 
+#if defined (__SSE4_2__)
+  fprintf(stderr, "Predefined: __SSE4_2__\n");
+#endif 
+#if defined (__AVX__)
+  fprintf(stderr, "Predefined: __AVX__\n");
+#endif 
+  fprintf(stderr, "\n");
 
-  Progname = getProgname(argv[0]);
+  fprintf(stderr, "mem alignment       = %d\n\n", getMemAlignment());
 
-  if ( memcmp(Progname, "cdo", 3) == 0 && strlen(Progname) > 3 ) noff = 3;
+#if defined (HAVE_MMAP)
+  fprintf(stderr, "HAVE_MMAP\n");
+#endif
+#if defined (HAVE_MEMORY_H)
+  fprintf(stderr, "HAVE_MEMORY_H\n");
+#endif
+  fprintf(stderr, "\n");
+      
+#if defined (_OPENACC)
+  fprintf(stderr, "OPENACC VERSION     = %d\n", _OPENACC);
+#endif
+#if defined (_OPENMP)
+  fprintf(stderr, "OPENMP VERSION      = %d\n", _OPENMP);
+#endif
+#if defined (__GNUC__)
+  fprintf(stderr, "GNUC VERSION        = %d\n", __GNUC__);
+#endif
+#if defined (__ICC)
+  fprintf(stderr, "ICC VERSION         = %d\n", __ICC);
+#endif
+#if defined (__STDC__)
+  fprintf(stderr, "STD ANSI C          = %d\n", __STDC__);
+#endif
+#if defined (__STD_VERSION__)
+  fprintf(stderr, "STD VERSION         = %ld\n", __STD_VERSION__);
+#endif
+#if defined (__STDC_VERSION__)
+  fprintf(stderr, "STDC VERSION        = %ld\n", __STDC_VERSION__);
+#endif
+#if defined (__STD_HOSTED__)
+  fprintf(stderr, "STD HOSTED          = %d\n", __STD_HOSTED__);
+#endif
+#if defined (FLT_EVAL_METHOD)
+  fprintf(stderr, "FLT_EVAL_METHOD     = %d\n", FLT_EVAL_METHOD);
+#endif
+#if defined (FP_FAST_FMA)
+  fprintf(stderr, "FP_FAST_FMA         = defined\n");
+#endif
+  fprintf(stderr, "\n");
+
+#if defined (_SC_VERSION)
+  fprintf(stderr, "POSIX.1 VERSION     = %ld\n", sysconf(_SC_VERSION));
+#endif
+#if defined (_SC_ARG_MAX)
+  fprintf(stderr, "POSIX.1 ARG_MAX     = %ld\n", sysconf(_SC_ARG_MAX));
+#endif
+#if defined (_SC_CHILD_MAX)
+  fprintf(stderr, "POSIX.1 CHILD_MAX   = %ld\n", sysconf(_SC_CHILD_MAX));
+#endif
+#if defined (_SC_STREAM_MAX)
+  fprintf(stderr, "POSIX.1 STREAM_MAX  = %ld\n", sysconf(_SC_STREAM_MAX));
+#endif
+#if defined (_SC_OPEN_MAX)
+  fprintf(stderr, "POSIX.1 OPEN_MAX    = %ld\n", sysconf(_SC_OPEN_MAX));
+#endif
+#if defined (_SC_PAGESIZE)
+  fprintf(stderr, "POSIX.1 PAGESIZE    = %ld\n", sysconf(_SC_PAGESIZE));
+#endif
 
-  /* old versions !!!! */
-  if ( memcmp(Progname, "gdo", 3) == 0 && strlen(Progname) > 3 ) noff = 3;
-  if ( memcmp(Progname, "gm",  2) == 0 && strlen(Progname) > 2 ) noff = 2;
+  fprintf(stderr, "\n");
 
-  if ( noff ) setDefaultFileType(Progname+noff, 0);
+#if defined (HAVE_GETRLIMIT)
+#if defined (RLIMIT_FSIZE)
+  PRINT_RLIMIT(RLIMIT_FSIZE);
+#endif
+#if defined (RLIMIT_NOFILE)
+  PRINT_RLIMIT(RLIMIT_NOFILE);
+#endif
+#if defined (RLIMIT_STACK)
+  PRINT_RLIMIT(RLIMIT_STACK);
+#endif
+#endif
+  fprintf(stderr, "\n");
+}
+
+static
+void check_stacksize()
+{
+#if defined (HAVE_GETRLIMIT)
+#if defined (RLIMIT_STACK)
+  {
+#define  MIN_STACK_SIZE  67108864L  /* 64MB */
+    int status;
+    struct rlimit rlim;
+    RLIM_T min_stack_size = MIN_STACK_SIZE;
+
+    status = getrlimit(RLIMIT_STACK, &rlim);
+
+    if ( status == 0 )
+      {
+	if ( min_stack_size > rlim.rlim_max ) min_stack_size = rlim.rlim_max;
+	if ( rlim.rlim_cur < min_stack_size )
+	  {
+	    rlim.rlim_cur = min_stack_size;
+
+	    status = setrlimit(RLIMIT_STACK, &rlim);
+	    if ( Debug )
+	      {
+		if ( status == 0 )
+		  {
+		    fprintf(stderr, "Set stack size to %ld\n", (long) min_stack_size);
+		    PRINT_RLIMIT(RLIMIT_STACK);
+		  }
+		else
+		  fprintf(stderr, "Set stack size to %ld failed!\n", (long) min_stack_size);
+	      }
+	  }
+      }
+  }
+#endif
+#endif
+}
 
-  while ( (c = cdoGetopt(argc, argv, "f:b:e:P:p:g:i:k:l:m:n:t:D:z:aBcdhLMOQRrsSTuVvXZ")) != -1 )
+static
+void parse_options(int argc, char *argv[])
+{
+  int c;
+
+  while ( (c = cdoGetopt(argc, argv, "f:b:e:P:p:g:i:k:l:m:n:t:D:z:aBcdhLMOQRrsSTuVvWXZ")) != -1 )
     {
       switch (c)
 	{
@@ -943,6 +1079,9 @@ int main(int argc, char *argv[])
 	case 'v':
 	  cdoVerbose = TRUE;
 	  break;
+	case 'W': /* Warning messages */
+	  _Verbose = 1;
+	  break;
 	case 'X': /* multi threaded I/O */
 	  cdoParIO = TRUE;
 	  break;
@@ -958,166 +1097,46 @@ int main(int argc, char *argv[])
 	  break;
 	}
     }
+}
 
-  get_env_vars();
 
-  if ( Debug || Version ) cdo_version();
+int main(int argc, char *argv[])
+{
+  int lstop = FALSE;
+  int noff = 0;
+  int status = 0;
+  char *operatorName = NULL;
+  char *operatorArg = NULL;
+  char *argument = NULL;
+  extern int dmemory_ExitOnError;
 
-  if ( Debug )
-    {
-      char *envstr;
-
-      if ( DebugLevel == 0 ) DebugLevel = 1;
-      cdoSetDebug(DebugLevel);
-      fprintf(stderr, "\n");
-      fprintf(stderr, "cdoDefaultFileType  = %d\n", cdoDefaultFileType);
-      fprintf(stderr, "cdoDefaultDataType  = %d\n", cdoDefaultDataType);
-      fprintf(stderr, "cdoDefaultByteorder = %d\n", cdoDefaultByteorder);
-      fprintf(stderr, "cdoDefaultTableID   = %d\n", cdoDefaultTableID);
-      fprintf(stderr, "\n");
-
-      envstr = getenv("HOSTTYPE");
-      if ( envstr ) fprintf(stderr, "HOSTTYPE            = %s\n", envstr);
-      envstr = getenv("VENDOR");
-      if ( envstr ) fprintf(stderr, "VENDOR              = %s\n", envstr);
-      envstr = getenv("OSTYPE");
-      if ( envstr ) fprintf(stderr, "OSTYPE              = %s\n", envstr);
-      envstr = getenv("MACHTYPE");
-      if ( envstr ) fprintf(stderr, "MACHTYPE            = %s\n", envstr);
-      fprintf(stderr, "\n");
+  init_is_tty();
 
-#if defined (__SSE2__)
-      fprintf(stderr, "Predefined: __SSE2__\n");
-#endif 
-#if defined (__SSE3__)
-      fprintf(stderr, "Predefined: __SSE3__\n");
-#endif 
-#if defined (__SSE4_1__)
-      fprintf(stderr, "Predefined: __SSE4_1__\n");
-#endif 
-#if defined (__SSE4_2__)
-      fprintf(stderr, "Predefined: __SSE4_2__\n");
-#endif 
-#if defined (__AVX__)
-      fprintf(stderr, "Predefined: __AVX__\n");
-#endif 
-      fprintf(stderr, "\n");
+  dmemory_ExitOnError = 1;
 
-      fprintf(stderr, "mem alignment       = %d\n\n", getMemAlignment());
+  _Verbose = 0;
 
-#if defined (HAVE_MMAP)
-      fprintf(stderr, "HAVE_MMAP\n");
-#endif
-#if defined (HAVE_MEMORY_H)
-      fprintf(stderr, "HAVE_MEMORY_H\n");
-#endif
-      fprintf(stderr, "\n");
+  /* mallopt(M_MMAP_MAX, 0); */
+ 
+  setCommandLine(argc, argv);
 
-#if defined (_OPENACC)
-      fprintf(stderr, "OPENACC VERSION     = %d\n", _OPENACC);
-#endif
-#if defined (_OPENMP)
-      fprintf(stderr, "OPENMP VERSION      = %d\n", _OPENMP);
-#endif
-#if defined (__GNUC__)
-      fprintf(stderr, "GNUC VERSION        = %d\n", __GNUC__);
-#endif
-#if defined (__ICC)
-      fprintf(stderr, "ICC VERSION         = %d\n", __ICC);
-#endif
-#if defined (__STDC__)
-      fprintf(stderr, "STD ANSI C          = %d\n", __STDC__);
-#endif
-#if defined (__STD_VERSION__)
-      fprintf(stderr, "STD VERSION         = %ld\n", __STD_VERSION__);
-#endif
-#if defined (__STDC_VERSION__)
-      fprintf(stderr, "STDC VERSION        = %ld\n", __STDC_VERSION__);
-#endif
-#if defined (__STD_HOSTED__)
-      fprintf(stderr, "STD HOSTED          = %d\n", __STD_HOSTED__);
-#endif
-#if defined (FLT_EVAL_METHOD)
-      fprintf(stderr, "FLT_EVAL_METHOD     = %d\n", FLT_EVAL_METHOD);
-#endif
-#if defined (FP_FAST_FMA)
-      fprintf(stderr, "FP_FAST_FMA         = defined\n");
-#endif
-      fprintf(stderr, "\n");
+  Progname = getProgname(argv[0]);
 
-#if defined (_SC_VERSION)
-      fprintf(stderr, "POSIX.1 VERSION     = %ld\n", sysconf(_SC_VERSION));
-#endif
-#if defined (_SC_ARG_MAX)
-      fprintf(stderr, "POSIX.1 ARG_MAX     = %ld\n", sysconf(_SC_ARG_MAX));
-#endif
-#if defined (_SC_CHILD_MAX)
-      fprintf(stderr, "POSIX.1 CHILD_MAX   = %ld\n", sysconf(_SC_CHILD_MAX));
-#endif
-#if defined (_SC_STREAM_MAX)
-      fprintf(stderr, "POSIX.1 STREAM_MAX  = %ld\n", sysconf(_SC_STREAM_MAX));
-#endif
-#if defined (_SC_OPEN_MAX)
-      fprintf(stderr, "POSIX.1 OPEN_MAX    = %ld\n", sysconf(_SC_OPEN_MAX));
-#endif
-#if defined (_SC_PAGESIZE)
-      fprintf(stderr, "POSIX.1 PAGESIZE    = %ld\n", sysconf(_SC_PAGESIZE));
-#endif
+  if ( memcmp(Progname, "cdo", 3) == 0 && strlen(Progname) > 3 ) noff = 3;
 
-      fprintf(stderr, "\n");
+  if ( noff ) setDefaultFileType(Progname+noff, 0);
 
-#if defined (HAVE_GETRLIMIT)
-#if defined (RLIMIT_FSIZE)
-      PRINT_RLIMIT(RLIMIT_FSIZE);
-#endif
-#if defined (RLIMIT_NOFILE)
-      PRINT_RLIMIT(RLIMIT_NOFILE);
-#endif
-#if defined (RLIMIT_STACK)
-      PRINT_RLIMIT(RLIMIT_STACK);
-#endif
-#endif
-      fprintf(stderr, "\n");
-    }
+  parse_options(argc, argv);
 
-#if defined (HAVE_GETRLIMIT)
-#if defined (RLIMIT_STACK)
-  {
-#define  MIN_STACK_SIZE  67108864L  /* 64MB */
-    int status;
-    struct rlimit rlim;
-    RLIM_T min_stack_size = MIN_STACK_SIZE;
+  get_env_vars();
 
-    status = getrlimit(RLIMIT_STACK, &rlim);
+  if ( Debug || Version ) cdo_version();
 
-    if ( status == 0 )
-      {
-	if ( min_stack_size > rlim.rlim_max ) min_stack_size = rlim.rlim_max;
-	if ( rlim.rlim_cur < min_stack_size )
-	  {
-	    rlim.rlim_cur = min_stack_size;
+  if ( Debug ) print_system_info();
 
-	    status = setrlimit(RLIMIT_STACK, &rlim);
-	    if ( Debug )
-	      {
-		if ( status == 0 )
-		  {
-		    fprintf(stderr, "Set stack size to %ld\n", (long) min_stack_size);
-		    PRINT_RLIMIT(RLIMIT_STACK);
-		  }
-		else
-		  fprintf(stderr, "Set stack size to %ld failed!\n", (long) min_stack_size);
-	      }
-	  }
-      }
-  }
-#endif
-#endif
+  check_stacksize();
 
-  if ( Debug )
-    {
-      print_pthread_info();
-    }
+  if ( Debug ) print_pthread_info();
 
 #if defined (_OPENMP)
   if ( numThreads <= 0 ) numThreads = 1;
diff --git a/src/cdo.h b/src/cdo.h
index 9c80c3e..85e0b3d 100644
--- a/src/cdo.h
+++ b/src/cdo.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -35,7 +35,7 @@
 #undef   NINTD
 #define  NINTD(x)   ((x) < 0 ? ((x)-0.5) : ((x)+0.5))
 
-#define  UNCHANGED_RECORD  (processSelf() == 0 && *cdoStreamName(0) != '-' && cdoRegulargrid == FALSE && cdoDefaultDataType == -1 && cdoDefaultByteorder == -1 )
+#define  UNCHANGED_RECORD  (processSelf() == 0 && *cdoStreamName(0) != '-' && cdoRegulargrid == FALSE && cdoDefaultFileType == -1 && cdoDefaultDataType == -1 && cdoDefaultByteorder == -1 )
 
 
 typedef struct {
diff --git a/src/cdo_int.h b/src/cdo_int.h
index 979a2ce..9f9dcf2 100644
--- a/src/cdo_int.h
+++ b/src/cdo_int.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -139,6 +139,10 @@ void param2str(int param, char *paramstr, int maxlen);
 void date2str(int date, char *datestr, int maxlen);
 void time2str(int time, char *timestr, int maxlen);
 
+const char * tunit2str(int tunits);
+const char * calendar2str(int calendar);
+
+
 typedef struct {
   int   date;
   int   time;
@@ -162,7 +166,9 @@ juldate_t juldate_sub(juldate_t juldate2, juldate_t juldate1);
 juldate_t juldate_add_seconds(int seconds, juldate_t juldate);
 double    juldate_to_seconds(juldate_t juldate);
 
+void    get_timestat_date(int *tstat_date);
 void    datetime_avg(int dpy, int ndates, datetime_t *datetime);
+void    datetime_avg_dtinfo(int dpy, int ndates, dtinfo_t *dtinfo);
 void    taxisInqDTinfo(int taxisID, dtinfo_t *dtinfo);
 void    taxisDefDTinfo(int taxisID, dtinfo_t dtinfo);
 
diff --git a/src/cdo_pthread.c b/src/cdo_pthread.c
index 9720bba..c5173c9 100644
--- a/src/cdo_pthread.c
+++ b/src/cdo_pthread.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/cdo_vlist.c b/src/cdo_vlist.c
index 9ffd213..3903534 100644
--- a/src/cdo_vlist.c
+++ b/src/cdo_vlist.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/commandline.c b/src/commandline.c
index 431c02e..88c8919 100644
--- a/src/commandline.c
+++ b/src/commandline.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/config.h.in b/src/config.h.in
index 58956e8..d07b305 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -6,6 +6,9 @@
 /* Compiler version */
 #undef COMP_VERSION
 
+/* Define to 1 for DATA support */
+#undef ENABLE_DATA
+
 /* Define to 1 if you have the declaration of `isnan', and to 0 if you don't.
    */
 #undef HAVE_DECL_ISNAN
@@ -22,6 +25,9 @@
 /* Define to 1 if you have the `getrlimit' function. */
 #undef HAVE_GETRLIMIT
 
+/* Define to 1 if you have the <glob.h> header file. */
+#undef HAVE_GLOB_H
+
 /* Define to 1 if you have the <grib_api.h> header file. */
 #undef HAVE_GRIB_API_H
 
diff --git a/src/expr.c b/src/expr.c
index cd1f968..b3cbf03 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -71,7 +71,7 @@ nodeType *expr_con_con(int oper, nodeType *p1, nodeType *p2)
     case '*':  p->u.con.value = p1->u.con.value * p2->u.con.value; break;
     case '/':  p->u.con.value = p1->u.con.value / p2->u.con.value; break;
     case '^':  p->u.con.value = pow(p1->u.con.value, p2->u.con.value); break;
-    default:   cdoAbort("%s: operator %c unsupported!", __func__, oper);
+    default:   cdoAbort("%s: operator %c unsupported!", __func__, oper); break;
     }
 
   return (p);
@@ -165,6 +165,7 @@ nodeType *expr_con_var(int oper, nodeType *p1, nodeType *p2)
       break;
     default:
       cdoAbort("%s: operator %c unsupported!", __func__, oper);
+      break;
     }
 
   nmiss = 0;
@@ -272,6 +273,7 @@ nodeType *expr_var_con(int oper, nodeType *p1, nodeType *p2)
       break;
     default:
       cdoAbort("%s: operator %c unsupported!", __func__, oper);
+      break;
     }
 
   nmiss = 0;
@@ -398,7 +400,12 @@ nodeType *expr_var_var(int oper, nodeType *p1, nodeType *p2)
 	  else
 	    {
 	      for ( i = 0; i < ngp; i++ )
-		p->data[i+k*ngp] = p1->data[i+loff1] / p2->data[i+loff2];
+		{
+		  if ( IS_EQUAL(p2->data[i+loff2], 0.) )
+		    p->data[i+k*ngp] = missval1;
+		  else
+		    p->data[i+k*ngp] = p1->data[i+loff1] / p2->data[i+loff2];
+		}
 	    }
 	  break;
 	case '^':
@@ -415,6 +422,7 @@ nodeType *expr_var_var(int oper, nodeType *p1, nodeType *p2)
 	  break;
 	default:
 	  cdoAbort("%s: operator %c unsupported!", __func__, oper);
+          break;
 	}
     }
 
@@ -442,6 +450,9 @@ void ex_copy(nodeType *p2, nodeType *p1)
   ngp1 = gridInqSize(p1->gridID);
   ngp2 = gridInqSize(p2->gridID);
 
+  if ( ngp1 != ngp2 )
+    cdoAbort("number of grid points differ. ngp1 = %d, ngp2 = %d", ngp1, ngp2);
+
   ngp = ngp2;
   nlev = zaxisInqSize(p2->zaxisID);
 
@@ -913,7 +924,9 @@ nodeType *expr_run(nodeType *p, parse_parm_t *parse_arg)
 	      rnode = expr(p->u.opr.oper, expr_run(p->u.opr.op[0], parse_arg),
 			                  expr_run(p->u.opr.op[1], parse_arg));
 	    }
+          break;
         }
+      break;
     }
 
   return (rnode);
diff --git a/src/field.c b/src/field.c
index 0d687fd..7cbcbda 100644
--- a/src/field.c
+++ b/src/field.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -23,40 +23,40 @@
 #include "merge_sort2.h"
 /* QR */
 
-double crps_det_integrate(double *a, const double d, const int n);
+double crps_det_integrate(double *a, const double d, const size_t n);
 
-double _FADD_(double x, double y, double missval1, double missval2)
+double _FADD_(const double x, const double y, const double missval1, const double missval2)
 {
   return FADD(x,y);
 }
 
-double _FSUB_(double x, double y, double missval1, double missval2)
+double _FSUB_(const double x, const double y, const double missval1, const double missval2)
 {
   return FSUB(x, y);
 }
 
-double _FMUL_(double x, double y, double missval1, double missval2)
+double _FMUL_(const double x, const double y, const double missval1, const double missval2)
 {
   return FMUL(x, y);
 }
 
-double _FDIV_(double x, double y, double missval1, double missval2)
+double _FDIV_(const double x, const double y, const double missval1, const double missval2)
 {
   return FDIV(x, y);
 }
 
-double _FPOW_(double x, double y, double missval1, double missval2)
+double _FPOW_(const double x, const double y, const double missval1, const double missval2)
 {
   return FPOW(x, y);
 }
 
-double _FSQRT_(double x, double missval1)
+double _FSQRT_(const double x, const double missval1)
 {
   return FSQRT(x);
 }
 
 
-double fldfun(field_t field, int function)
+double fldfun(field_t field, const int function)
 {
   double rval = 0;
 
@@ -67,33 +67,35 @@ double fldfun(field_t field, int function)
   else if ( function == func_mean )  rval = fldmean(field);
   else if ( function == func_avg  )  rval = fldavg(field);
   else if ( function == func_std  )  rval = fldstd(field);
+  else if ( function == func_std1 )  rval = fldstd1(field);
   else if ( function == func_var  )  rval = fldvar(field);
+  else if ( function == func_var1 )  rval = fldvar1(field);
   
   else if ( function == func_crps )  rval = fldcrps(field);
   else if ( function == func_brs )   rval = fldbrs(field);
 
   else if ( function == func_rank )  rval = fldrank(field);
   else if ( function == func_roc )   rval = fldroc(field);
-  else cdoAbort("function %d not implemented!", function);
+  else cdoAbort("%s: function %d not implemented!", __func__, function);
 
   return rval;
 }
 
+
 double fldrank(field_t field) 
 {
   double res = 0;
   // Using first value as reference (observation)
   double *array  =  &(field.ptr[1]);
   double val     = array[-1];
-  double missval = field.missval;
+  const double missval = field.missval;
   int nmiss      = field.nmiss;
-  long len       = field.size-1;
-  int j;
+  const size_t len       = field.size-1;
+  size_t j;
   
-  if ( nmiss ) 
-    return(missval);
+  if ( nmiss )  return(missval);
 
-  sort_iter_single(len,array,1);
+  sort_iter_single(len,array, 1);
 
   if ( val > array[len-1] ) 
     res=(double)len;
@@ -103,6 +105,7 @@ double fldrank(field_t field)
 	res=(double)j; 
 	break;
       }
+
   return res;
 }
 
@@ -114,8 +117,8 @@ double fldroc(field_t field)
 
 double fldcrps(field_t field)
 {
-  long   len     = field.size;
-  int    nmiss   = field.nmiss;
+  const size_t len     = field.size;
+  const int    nmiss   = field.nmiss;
   double *array  = field.ptr;
 
   if ( nmiss > 0 ) 
@@ -128,20 +131,20 @@ double fldcrps(field_t field)
 
   // Use first value as reference
   sort_iter_single(len-1,&array[1],ompNumThreads);
-  return crps_det_integrate(&array[1],array[0],len-1);
 
+  return crps_det_integrate(&array[1],array[0],len-1);
 }
 
 
 double fldbrs(field_t field) 
 {
-  long      len   = field.size;
-  int     nmiss   = field.nmiss;
+  const size_t    len   = field.size;
+  const int     nmiss   = field.nmiss;
   double *array   = field.ptr;
-  double missval  = field.missval;
+  const double missval  = field.missval;
 
   double brs = 0;
-  int i,count=0;
+  size_t i, count=0;
 
   // Using first value as reference
   if ( nmiss == 0 ) 
@@ -168,10 +171,10 @@ double fldbrs(field_t field)
 
 double fldmin(field_t field)
 {
-  long   i;
-  long   len     = field.size;
-  int    nmiss   = field.nmiss;
-  double missval = field.missval;
+  size_t   i;
+  const size_t len     = field.size;
+  const int    nmiss   = field.nmiss;
+  const double missval = field.missval;
   double *array  = field.ptr;
   double rmin = 0;
 
@@ -198,10 +201,10 @@ double fldmin(field_t field)
 
 double fldmax(field_t field)
 {
-  long   i;
-  long   len     = field.size;
-  int    nmiss   = field.nmiss;
-  double missval = field.missval;
+  size_t   i;
+  const size_t len     = field.size;
+  const int    nmiss   = field.nmiss;
+  const double missval = field.missval;
   double *array  = field.ptr;
   double rmax = 0;
 
@@ -228,11 +231,11 @@ double fldmax(field_t field)
 
 double fldsum(field_t field)
 {
-  long   i;
-  long   nvals   = 0;
-  long   len     = field.size;
-  int    nmiss   = field.nmiss;
-  double missval = field.missval;
+  size_t   i;
+  size_t   nvals   = 0;
+  const size_t len     = field.size;
+  const int    nmiss   = field.nmiss;
+  const double missval = field.missval;
   double *array  = field.ptr;
   double rsum = 0;
 
@@ -259,11 +262,11 @@ double fldsum(field_t field)
 
 double fldmean(field_t field)
 {
-  long   i;
-  long   len      = field.size;
-  int    nmiss    = field.nmiss;
-  double missval1 = field.missval;
-  double missval2 = field.missval;
+  size_t   i;
+  const size_t len      = field.size;
+  const int    nmiss    = field.nmiss;
+  const double missval1 = field.missval;
+  const double missval2 = field.missval;
   double *array   = field.ptr;
   double *w       = field.weight;
   double rsum = 0, rsumw = 0, ravg = 0;
@@ -294,11 +297,11 @@ double fldmean(field_t field)
 
 double fldavg(field_t field)
 {
-  long   i;
-  long   len      = field.size;
-  int    nmiss    = field.nmiss;
-  double missval1 = field.missval;
-  double missval2 = field.missval;
+  size_t   i;
+  const size_t len      = field.size;
+  const int    nmiss    = field.nmiss;
+  const double missval1 = field.missval;
+  const double missval2 = field.missval;
   double *array   = field.ptr;
   double *w       = field.weight;
   double rsum = 0, rsumw = 0, ravg = 0;
@@ -326,39 +329,49 @@ double fldavg(field_t field)
   return (ravg);
 }
 
-
-double fldvar(field_t field)
-{
-  long   i;
-  long   len     = field.size;
-  int    nmiss   = field.nmiss;
-  double missval = field.missval;
-  double *array  = field.ptr;
-  double *w      = field.weight;
-  double rsum = 0, rsumw = 0, rvar = 0;
-  double rsumq = 0, rsumwq = 0;
+static
+void prevarsum(const double *restrict array, const double *restrict w, size_t len, const int nmiss, 
+	       double missval, double *rsum, double *rsumw, double *rsumq, double *rsumwq)
+{ 
+  size_t i;
+  *rsum = *rsumw = 0;
+  *rsumq = *rsumwq = 0;
 
   if ( nmiss > 0 )
     {
       for ( i = 0; i < len; i++ ) 
         if ( !DBL_IS_EQUAL(array[i], missval) && !DBL_IS_EQUAL(w[i], missval) )
           {
-            rsum   += w[i] * array[i];
-            rsumq  += w[i] * array[i] * array[i];
-            rsumw  += w[i];
-            rsumwq += w[i] * w[i];
+            *rsum   += w[i] * array[i];
+            *rsumq  += w[i] * array[i] * array[i];
+            *rsumw  += w[i];
+            *rsumwq += w[i] * w[i];
           }
     }
   else
     {
       for ( i = 0; i < len; i++ ) 
         {
-          rsum   += w[i] * array[i];
-          rsumq  += w[i] * array[i] * array[i];
-          rsumw  += w[i];
-          rsumwq += w[i] * w[i];
+          *rsum   += w[i] * array[i];
+          *rsumq  += w[i] * array[i] * array[i];
+          *rsumw  += w[i];
+          *rsumwq += w[i] * w[i];
         }
     }
+}
+
+
+double fldvar(field_t field)
+{
+  const size_t len     = field.size;
+  const int    nmiss   = field.nmiss;
+  const double missval = field.missval;
+  double *array  = field.ptr;
+  double *w      = field.weight;
+  double rsum, rsumw, rvar;
+  double rsumq, rsumwq;
+
+  prevarsum(array, w, len, nmiss, missval, &rsum, &rsumw, &rsumq, &rsumwq);
 
   rvar = IS_NOT_EQUAL(rsumw, 0) ? (rsumq*rsumw - rsum*rsum) / (rsumw*rsumw) : missval;
   if ( rvar < 0 && rvar > -1.e-5 ) rvar = 0;
@@ -367,9 +380,28 @@ double fldvar(field_t field)
 }
 
 
+double fldvar1(field_t field)
+{
+  const size_t len     = field.size;
+  const int    nmiss   = field.nmiss;
+  const double missval = field.missval;
+  double *array  = field.ptr;
+  double *w      = field.weight;
+  double rsum, rsumw, rvar;
+  double rsumq, rsumwq;
+
+  prevarsum(array, w, len, nmiss, missval, &rsum, &rsumw, &rsumq, &rsumwq);
+
+  rvar = (rsumw*rsumw > rsumwq) ? (rsumq*rsumw - rsum*rsum) / (rsumw*rsumw - rsumwq) : missval;
+  if ( rvar < 0 && rvar > -1.e-5 ) rvar = 0;
+
+  return (rvar);
+}
+
+
 double fldstd(field_t field)
 {
-  double missval = field.missval;
+  const double missval = field.missval;
   double rvar, rstd;
 
   rvar = fldvar(field);
@@ -387,9 +419,30 @@ double fldstd(field_t field)
 }
 
 
+double fldstd1(field_t field)
+{
+  const double missval = field.missval;
+  double rvar, rstd;
+
+  rvar = fldvar1(field);
+
+  if ( DBL_IS_EQUAL(rvar, missval) || rvar < 0 )
+    {
+      rstd = missval;
+    }
+  else
+    {
+      rstd = IS_NOT_EQUAL(rvar, 0) ? sqrt(rvar) : 0;
+    }
+
+  return (rstd);
+}
+
+
 void fldrms(field_t field, field_t field2, field_t *field3)
 {
-  long   i, len;
+  size_t   i;
+  size_t len;
   int    rnmiss = 0;
   int    grid1    = field.grid;
   //  int    nmiss1   = field.nmiss;
@@ -397,13 +450,13 @@ void fldrms(field_t field, field_t field2, field_t *field3)
   int    grid2    = field2.grid;
   //  int    nmiss2   = field2.nmiss;
   double *array2  = field2.ptr;
-  double missval1 = field.missval;
-  double missval2 = field2.missval;
+  const double missval1 = field.missval;
+  const double missval2 = field2.missval;
   double *w       = field.weight;
   double rsum = 0, rsumw = 0, ravg = 0;
 
   len    = gridInqSize(grid1);
-  if ( len != gridInqSize(grid2) )
+  if ( len != (size_t) gridInqSize(grid2) )
     cdoAbort("fields have different size!");
 
   /*
@@ -440,7 +493,7 @@ void fldrms(field_t field, field_t field2, field_t *field3)
 
 void varrms(field_t field, field_t field2, field_t *field3)
 {
-  long   i, k, nlev, len;
+  size_t   i, k, nlev, len;
   int    rnmiss = 0;
   int    zaxis    = field.zaxis;
   int    grid1    = field.grid;
@@ -449,14 +502,14 @@ void varrms(field_t field, field_t field2, field_t *field3)
   int    grid2    = field2.grid;
   //  int    nmiss2   = field2.nmiss;
   double *array2  = field2.ptr;
-  double missval1 = field.missval;
-  double missval2 = field2.missval;
+  const double missval1 = field.missval;
+  const double missval2 = field2.missval;
   double *w       = field.weight;
   double rsum = 0, rsumw = 0, ravg = 0;
 
   nlev   = zaxisInqSize(zaxis);
   len    = gridInqSize(grid1);
-  if ( len != gridInqSize(grid2) )
+  if ( len != (size_t) gridInqSize(grid2) )
     cdoAbort("fields have different size!");
 
   /*
@@ -492,15 +545,15 @@ void varrms(field_t field, field_t field2, field_t *field3)
 }
 
 /* RQ */
-double fldpctl(field_t field, int p)
+double fldpctl(field_t field, const int p)
 {
-  long   len     = field.size;
-  int    nmiss   = field.nmiss;
-  double missval = field.missval;
+  const size_t len     = field.size;
+  const int    nmiss   = field.nmiss;
+  const double missval = field.missval;
   double *array  = field.ptr;
   double *array2;
 
-  long i, j;
+  size_t i, j;
   double pctl = missval;
 
   if ( len - nmiss > 0 )
@@ -531,7 +584,7 @@ double fldpctl(field_t field, int p)
 /*  update the number non missing values */
 void fldunm(field_t *field)
 {
-  long i;
+  size_t i;
 
   field->nmiss = 0;
   for ( i = 0; i < field->size; i++ )
@@ -539,23 +592,23 @@ void fldunm(field_t *field)
 }
 
 /*  check for non missval values */
-int fldhvs(field_t *fieldPtr, int nlevels)
+int fldhvs(field_t *fieldPtr, const size_t nlevels)
 {
-  int level;
+  size_t level;
   field_t field;
 
   for ( level = 0; level < nlevels; level++)
     {
       field = fieldPtr[level];
-      if ( field.nmiss != field.size )
+      if ( (size_t)field.nmiss != field.size )
         return TRUE;
     }
+
   return FALSE;
 }
 
 
-
-double crps_det_integrate(double *a, const double d, const int n)
+double crps_det_integrate(double *a, const double d, const size_t n)
 {
   /* *************************************************************************** */
   /* This routine finds the area between the cdf described by the ordered array  */
@@ -571,7 +624,7 @@ double crps_det_integrate(double *a, const double d, const int n)
 
   double area = 0; 
   //  double tmp;
-  int i;
+  size_t i;
 #if defined (_OPENMP)
 #pragma omp parallel for if ( n>10000 ) shared(a) private(i) \
   reduction(+:area) schedule(static,10000) 
diff --git a/src/field.h b/src/field.h
index ae746c5..3795964 100644
--- a/src/field.h
+++ b/src/field.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -32,12 +32,12 @@
 #define  FSQRT(x)   (DBL_IS_EQUAL((x),missval1) || (x)<0 ? missval1 : sqrt(x))
 
 
-double _FADD_(double x, double y, double missval1, double missval2);
-double _FSUB_(double x, double y, double missval1, double missval2);
-double _FMUL_(double x, double y, double missval1, double missval2);
-double _FDIV_(double x, double y, double missval1, double missval2);
-double _FPOW_(double x, double y, double missval1, double missval2);
-double _FSQRT_(double x, double missval1);
+double _FADD_(const double x, const double y, const double missval1, const double missval2);
+double _FSUB_(const double x, const double y, const double missval1, const double missval2);
+double _FMUL_(const double x, const double y, const double missval1, const double missval2);
+double _FDIV_(const double x, const double y, const double missval1, const double missval2);
+double _FPOW_(const double x, const double y, const double missval1, const double missval2);
+double _FSQRT_(const double x, const double missval1);
 
 
 #define ADD(x,y)  _FADD_(x, y, missval1, missval2)
@@ -51,7 +51,7 @@ double _FSQRT_(double x, double missval1);
 typedef struct {
   int      grid;
   int      zaxis;
-  int      size;
+  size_t   size;
   int      nsamp;
   int      nmiss;
   double   missval;
@@ -62,25 +62,27 @@ field_t;
 
 /* fieldmem.c */
 
-field_t **field_malloc(int vlistID, int ptype);
-field_t **field_calloc(int vlistID, int ptype);
-void      field_free(field_t **field, int vlistID);
+field_t **field_malloc(const int vlistID, const int ptype);
+field_t **field_calloc(const int vlistID, const int ptype);
+void      field_free(field_t **field, const int vlistID);
 
 /* field.c */
 
-double fldfun(field_t field, int function);
+double fldfun(field_t field, const int function);
 double fldmin(field_t field);
 double fldmax(field_t field);
 double fldsum(field_t field);
 double fldavg(field_t field);
 double fldmean(field_t field);
 double fldstd(field_t field);
+double fldstd1(field_t field);
 double fldvar(field_t field);
+double fldvar1(field_t field);
 /* RQ */
-double fldpctl(field_t field, int k);
+double fldpctl(field_t field, const int k);
 /* QR */
 void   fldunm(field_t *field);
-int    fldhvs(field_t *field, int nlevels);
+int    fldhvs(field_t *field, const size_t nlevels);
 
 /* ENS VALIDATION */
 double fldcrps(field_t field);
@@ -90,7 +92,7 @@ double fldroc(field_t field);
 
 /* fieldzon.c */
 
-void zonfun(field_t field1, field_t *field2, int function);
+void zonfun(field_t field1, field_t *field2, const int function);
 void zonmin(field_t field1, field_t *field2);
 void zonmax(field_t field1, field_t *field2);
 void zonrange(field_t field1, field_t *field2);
@@ -100,12 +102,12 @@ void zonmean(field_t field1, field_t *field2);
 void zonstd(field_t field1, field_t *field2);
 void zonvar(field_t field1, field_t *field2);
 /* RQ */
-void zonpctl(field_t field1, field_t *field2, int k);
+void zonpctl(field_t field1, field_t *field2, const int k);
 /* QR */
 
 /* fieldmer.c */
 
-void merfun(field_t field1, field_t *field2, int function);
+void merfun(field_t field1, field_t *field2, const int function);
 void mermin(field_t field1, field_t *field2);
 void mermax(field_t field1, field_t *field2);
 void mersum(field_t field1, field_t *field2);
@@ -114,7 +116,7 @@ void mermean(field_t field1, field_t *field2);
 void merstd(field_t field1, field_t *field2);
 void mervar(field_t field1, field_t *field2);
 /* RQ */
-void merpctl(field_t field1, field_t *field2, int k);
+void merpctl(field_t field1, field_t *field2, const int k);
 /* QR */
 
 void fldrms(field_t field1, field_t field2, field_t *field3);
@@ -123,25 +125,25 @@ void varrms(field_t field1, field_t field2, field_t *field3);
 
 /* fieldc.c */
 
-void farcfun(field_t *field, double rconst, int function);
+void farcfun(field_t *field, const double rconst, const int function);
 
-void farcmul(field_t *field, double rconst);
-void farcdiv(field_t *field, double rconst);
-void farcadd(field_t *field, double rconst);
-void farcsub(field_t *field, double rconst);
+void farcmul(field_t *field, const double rconst);
+void farcdiv(field_t *field, const double rconst);
+void farcadd(field_t *field, const double rconst);
+void farcsub(field_t *field, const double rconst);
 
-void farmod(field_t *field, double divisor);
+void farmod(field_t *field, const double divisor);
 
 void farinv(field_t *field);
 
 /* field2.c */
 
-void farfun(field_t *field1, field_t field2, int function);
+void farfun(field_t *field1, field_t field2, const int function);
 
 void faradd(field_t *field1, field_t field2);
 void farsum(field_t *field1, field_t field2);
 void farsumq(field_t *field1, field_t field2);
-void farsumtr(field_t *field1, field_t field2, double refval);
+void farsumtr(field_t *field1, field_t field2, const double refval);
 void farsub(field_t *field1, field_t field2);
 void farmul(field_t *field1, field_t field2);
 void fardiv(field_t *field1, field_t field2);
@@ -149,8 +151,12 @@ void farmin(field_t *field1, field_t field2);
 void farmax(field_t *field1, field_t field2);
 void farvar(field_t *field1, field_t field2, field_t field3);
 void farstd(field_t *field1, field_t field2, field_t field3);
-void farcvar(field_t *field1, field_t field2, double rconst1);
-void farcstd(field_t *field1, field_t field2, double rconst1);
+void farvarx(field_t *field1, field_t field2, field_t field3, const double divisor);
+void farstdx(field_t *field1, field_t field2, field_t field3, const double divisor);
+void farcvar(field_t *field1, field_t field2, const double rconst1);
+void farcstd(field_t *field1, field_t field2, const double rconst1);
+void farcvarx(field_t *field1, field_t field2, const double rconst1, const double divisor);
+void farcstdx(field_t *field1, field_t field2, const double rconst1, const double divisor);
 void farmoq(field_t *field1, field_t field2);
 void faratan2(field_t *field1, field_t field2);
 
diff --git a/src/field2.c b/src/field2.c
index b36f46c..8c102a9 100644
--- a/src/field2.c
+++ b/src/field2.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -23,7 +23,7 @@
 #include <emmintrin.h>
 #endif
 
-void farfun(field_t *field1, field_t field2, int function)
+void farfun(field_t *field1, field_t field2, const int function)
 {
   if      ( function == func_add   ) faradd(field1, field2);
   else if ( function == func_min   ) farmin(field1, field2);
@@ -35,19 +35,19 @@ void farfun(field_t *field1, field_t field2, int function)
   else if ( function == func_mul   ) farmul(field1, field2);
   else if ( function == func_div   ) fardiv(field1, field2);
   else if ( function == func_atan2 ) faratan2(field1, field2);
-  else cdoAbort("function %d not implemented!", function);
+  else cdoAbort("%s: function %d not implemented!", __func__, function);
 }
 
 static
-void arradd(const long n, double * const restrict a, const double * const restrict b)
+void arradd(const size_t n, double * const restrict a, const double * const restrict b)
 {
-  long i;
+  size_t i;
  
   // SSE2 version is 15% faster than the original loop (tested with gcc47)
 #if 0
   //#ifdef __SSE2__ /*__SSE2__*/ // bug in this code!!!
-  long residual =  n % 8;
-  long ofs = n - residual;
+  const size_t residual =  n % 8;
+  const size_t ofs = n - residual;
 
   __m128d *av = (__m128d *) a; // assume 16-byte aligned
   __m128d *bv = (__m128d *) b; // assume 16-byte aligned
@@ -68,22 +68,23 @@ void arradd(const long n, double * const restrict a, const double * const restri
 #endif
 }
 
+
 void faradd(field_t *field1, field_t field2)
 {
-  long   i, len;
-  int    grid1    = field1->grid;
-  int    nmiss1   = field1->nmiss;
-  double missval1 = field1->missval;
+  size_t   i, len;
+  const int    grid1    = field1->grid;
+  const int    nmiss1   = field1->nmiss;
+  const double missval1 = field1->missval;
   double *array1  = field1->ptr;
   /*  double *weight1 = field1->weight; */
-  int    grid2    = field2.grid;
-  int    nmiss2   = field2.nmiss;
-  double missval2 = field2.missval;
+  const int    grid2    = field2.grid;
+  const int    nmiss2   = field2.nmiss;
+  const double missval2 = field2.missval;
   double *array2  = field2.ptr;
 
-  len = gridInqSize(grid1);
+  len = (size_t) gridInqSize(grid1);
 
-  if ( len != gridInqSize(grid2) )
+  if ( len != (size_t) gridInqSize(grid2) )
     cdoAbort("Fields have different gridsize (%s)", __func__);
 
   if ( nmiss1 > 0 || nmiss2 > 0 )
@@ -104,20 +105,20 @@ void faradd(field_t *field1, field_t field2)
 
 void farsum(field_t *field1, field_t field2)
 {
-  long   i, len;
-  int    grid1    = field1->grid;
-  int    nmiss1   = field1->nmiss;
-  double missval1 = field1->missval;
+  size_t   i, len;
+  const int    grid1    = field1->grid;
+  const int    nmiss1   = field1->nmiss;
+  const double missval1 = field1->missval;
   double *array1  = field1->ptr;
   /*  double *weight1 = field1->weight; */
-  int    grid2    = field2.grid;
-  int    nmiss2   = field2.nmiss;
-  double missval2 = field2.missval;
+  const int    grid2    = field2.grid;
+  const int    nmiss2   = field2.nmiss;
+  const double missval2 = field2.missval;
   double *array2  = field2.ptr;
 
-  len = gridInqSize(grid1);
+  len = (size_t) gridInqSize(grid1);
 
-  if ( len != gridInqSize(grid2) )
+  if ( len != (size_t) gridInqSize(grid2) )
     cdoAbort("Fields have different gridsize (%s)", __func__);
 
   if ( nmiss1 > 0 || nmiss2 > 0 )
@@ -149,16 +150,16 @@ void farsum(field_t *field1, field_t field2)
  * values do not change anything (they do not start a non-period by setting
  * occurrence to zero).
  */
-void farsumtr(field_t *occur, field_t field, double refval)
+void farsumtr(field_t *occur, field_t field, const double refval)
 {
-  long   i, len;
+  size_t   i, len;
   double omissval = occur->missval;
   double  *oarray = occur->ptr;
   double fmissval = field.missval;
   double  *farray = field.ptr;
 
-  len    = gridInqSize(occur->grid);
-  if ( len != gridInqSize(field.grid) )
+  len    = (size_t) gridInqSize(occur->grid);
+  if ( len != (size_t) gridInqSize(field.grid) )
     cdoAbort("Fields have different gridsize (%s)", __func__);
 
   if ( occur->nmiss > 0 || field.nmiss > 0 )
@@ -197,20 +198,20 @@ void farsumtr(field_t *occur, field_t field, double refval)
 
 void farsumq(field_t *field1, field_t field2)
 {
-  long   i, len;
-  int    grid1    = field1->grid;
-  int    nmiss1   = field1->nmiss;
-  double missval1 = field1->missval;
+  size_t   i, len;
+  const int    grid1    = field1->grid;
+  const int    nmiss1   = field1->nmiss;
+  const double missval1 = field1->missval;
   double *array1  = field1->ptr;
   /*  double *weight1 = field1->weight; */
-  int    grid2    = field2.grid;
-  int    nmiss2   = field2.nmiss;
-  double missval2 = field2.missval;
+  const int    grid2    = field2.grid;
+  const int    nmiss2   = field2.nmiss;
+  const double missval2 = field2.missval;
   double *array2  = field2.ptr;
 
-  len    = gridInqSize(grid1);
+  len    = (size_t) gridInqSize(grid1);
 
-  if ( len != gridInqSize(grid2) )
+  if ( len != (size_t) gridInqSize(grid2) )
     cdoAbort("Fields have different gridsize (%s)", __func__);
 
   if ( nmiss1 > 0 || nmiss2 > 0 )
@@ -238,19 +239,19 @@ void farsumq(field_t *field1, field_t field2)
 
 void farsub(field_t *field1, field_t field2)
 {
-  long   i, len;
-  int    grid1    = field1->grid;
-  int    nmiss1   = field1->nmiss;
-  double missval1 = field1->missval;
+  size_t   i, len;
+  const int    grid1    = field1->grid;
+  const int    nmiss1   = field1->nmiss;
+  const double missval1 = field1->missval;
   double *array1  = field1->ptr;
-  int    grid2    = field2.grid;
-  int    nmiss2   = field2.nmiss;
-  double missval2 = field2.missval;
+  const int    grid2    = field2.grid;
+  const int    nmiss2   = field2.nmiss;
+  const double missval2 = field2.missval;
   double *array2  = field2.ptr;
 
-  len    = gridInqSize(grid1);
+  len    = (size_t) gridInqSize(grid1);
 
-  if ( len != gridInqSize(grid2) )
+  if ( len != (size_t) gridInqSize(grid2) )
     cdoAbort("Fields have different gridsize (%s)", __func__);
 
   if ( nmiss1 > 0 || nmiss2 > 0 )
@@ -272,19 +273,19 @@ void farsub(field_t *field1, field_t field2)
 
 void farmul(field_t *field1, field_t field2)
 {
-  long   i, len;
-  int    grid1    = field1->grid;
-  int    nmiss1   = field1->nmiss;
-  double missval1 = field1->missval;
+  size_t   i, len;
+  const int    grid1    = field1->grid;
+  const int    nmiss1   = field1->nmiss;
+  const double missval1 = field1->missval;
   double *array1  = field1->ptr;
-  int    grid2    = field2.grid;
-  int    nmiss2   = field2.nmiss;
-  double missval2 = field2.missval;
+  const int    grid2    = field2.grid;
+  const int    nmiss2   = field2.nmiss;
+  const double missval2 = field2.missval;
   double *array2  = field2.ptr;
 
-  len    = gridInqSize(grid1);
+  len    = (size_t) gridInqSize(grid1);
 
-  if ( len != gridInqSize(grid2) )
+  if ( len != (size_t) gridInqSize(grid2) )
     cdoAbort("Fields have different gridsize (%s)", __func__);
 
   if ( nmiss1 > 0 || nmiss2 > 0 )
@@ -306,17 +307,17 @@ void farmul(field_t *field1, field_t field2)
 
 void fardiv(field_t *field1, field_t field2)
 {
-  long   i, len;
-  int    grid1    = field1->grid;
-  double missval1 = field1->missval;
+  size_t   i, len;
+  const int    grid1    = field1->grid;
+  const double missval1 = field1->missval;
   double *array1  = field1->ptr;
-  int    grid2    = field2.grid;
-  double missval2 = field2.missval;
+  const int    grid2    = field2.grid;
+  const double missval2 = field2.missval;
   double *array2  = field2.ptr;
 
-  len    = gridInqSize(grid1);
+  len    = (size_t) gridInqSize(grid1);
 
-  if ( len != gridInqSize(grid2) )
+  if ( len != (size_t) gridInqSize(grid2) )
     cdoAbort("Fields have different gridsize (%s)", __func__);
 
   for ( i = 0; i < len; i++ ) 
@@ -330,17 +331,17 @@ void fardiv(field_t *field1, field_t field2)
 
 void faratan2(field_t *field1, field_t field2)
 {
-  long   i, len;
-  int    grid1    = field1->grid;
-  double missval1 = field1->missval;
+  size_t   i, len;
+  const int    grid1    = field1->grid;
+  const double missval1 = field1->missval;
   double *array1  = field1->ptr;
-  int    grid2    = field2.grid;
-  double missval2 = field2.missval;
+  const int    grid2    = field2.grid;
+  const double missval2 = field2.missval;
   double *array2  = field2.ptr;
 
-  len    = gridInqSize(grid1);
+  len    = (size_t) gridInqSize(grid1);
 
-  if ( len != gridInqSize(grid2) )
+  if ( len != (size_t) gridInqSize(grid2) )
     cdoAbort("Fields have different gridsize (%s)", __func__);
 
   for ( i = 0; i < len; i++ ) 
@@ -354,19 +355,19 @@ void faratan2(field_t *field1, field_t field2)
 
 void farmin(field_t *field1, field_t field2)
 {
-  long   i, len;
-  int    grid1    = field1->grid;
-  int    nmiss1   = field1->nmiss;
-  double missval1 = field1->missval;
+  size_t   i, len;
+  const int    grid1    = field1->grid;
+  const int    nmiss1   = field1->nmiss;
+  const double missval1 = field1->missval;
   double *array1  = field1->ptr;
-  int    grid2    = field2.grid;
-  int    nmiss2   = field2.nmiss;
-  double missval2 = field2.missval;
+  const int    grid2    = field2.grid;
+  const int    nmiss2   = field2.nmiss;
+  const double missval2 = field2.missval;
   double *array2  = field2.ptr;
 
-  len    = gridInqSize(grid1);
+  len    = (size_t) gridInqSize(grid1);
 
-  if ( len != gridInqSize(grid2) )
+  if ( len != (size_t) gridInqSize(grid2) )
     cdoAbort("Fields have different gridsize (%s)", __func__);
 
   if ( nmiss1 > 0 || nmiss2 > 0 )
@@ -392,19 +393,19 @@ void farmin(field_t *field1, field_t field2)
 
 void farmax(field_t *field1, field_t field2)
 {
-  long   i, len;
-  int    grid1    = field1->grid;
-  int    nmiss1   = field1->nmiss;
-  double missval1 = field1->missval;
+  size_t   i, len;
+  const int    grid1    = field1->grid;
+  const int    nmiss1   = field1->nmiss;
+  const double missval1 = field1->missval;
   double *array1  = field1->ptr;
-  int    grid2    = field2.grid;
-  int    nmiss2   = field2.nmiss;
-  double missval2 = field2.missval;
+  const int    grid2    = field2.grid;
+  const int    nmiss2   = field2.nmiss;
+  const double missval2 = field2.missval;
   double *array2  = field2.ptr;
 
-  len    = gridInqSize(grid1);
+  len    = (size_t) gridInqSize(grid1);
 
-  if ( len != gridInqSize(grid2) )
+  if ( len != (size_t) gridInqSize(grid2) )
     cdoAbort("Fields have different gridsize (%s)", __func__);
 
   if ( nmiss1 > 0 || nmiss2 > 0 )
@@ -430,32 +431,36 @@ void farmax(field_t *field1, field_t field2)
 
 void farvar(field_t *field1, field_t field2, field_t field3)
 {
-  long   i, len;
-  int    grid1    = field1->grid;
-  int    nmiss1   = field1->nmiss;
-  double missval1 = field1->missval;
+  size_t   i, len;
+  const int    grid1    = field1->grid;
+  const int    nmiss1   = field1->nmiss;
+  const double missval1 = field1->missval;
   double *array1  = field1->ptr;
-  int    grid2    = field2.grid;
-  int    nmiss2   = field2.nmiss;
-  double missval2 = field2.missval;
+  const int    grid2    = field2.grid;
+  const int    nmiss2   = field2.nmiss;
+  const double missval2 = field2.missval;
   double *array2  = field2.ptr;
+  const int    nmiss3   = field3.nmiss;
+  const double missval3 = field3.missval;
   double *array3  = field3.ptr;
 
-  len    = gridInqSize(grid1);
+  len    = (size_t) gridInqSize(grid1);
 
-  if ( len != gridInqSize(grid2) )
+  if ( len != (size_t) gridInqSize(grid2) )
     cdoAbort("Fields have different gridsize (%s)", __func__);
 
-  if ( nmiss1 > 0 || nmiss2 > 0 )
+  if ( nmiss1 > 0 || nmiss2 > 0 || nmiss3 > 0 )
     {
       for ( i = 0; i < len; i++ )
-	if ( !DBL_IS_EQUAL(array1[i], missval1) && !DBL_IS_EQUAL(array2[i], missval2) )
-	  {
-	    array1[i] = array2[i]*array3[i] - (array1[i]*array3[i])*(array1[i]*array3[i]);
-	    if ( array1[i] < 0 && array1[i] > -1.e-5 ) array1[i] = 0;
-	  }
-	else
-	  array1[i] = missval1;
+	{
+	  if ( !DBL_IS_EQUAL(array1[i], missval1) && !DBL_IS_EQUAL(array2[i], missval2) && !DBL_IS_EQUAL(array3[i], missval3) )
+	    {
+	      array1[i] = array2[i]*array3[i] - (array1[i]*array3[i])*(array1[i]*array3[i]);
+	      if ( array1[i] < 0 && array1[i] > -1.e-5 ) array1[i] = 0;
+	    }
+	  else
+	    array1[i] = missval1;
+	}
     }
   else
     {
@@ -476,17 +481,51 @@ void farvar(field_t *field1, field_t field2, field_t field3)
 }
 
 
+void farvarx(field_t *field1, field_t field2, field_t field3, const double divisor)
+{
+  size_t   i, len;
+  const int    grid1    = field1->grid;
+  const double missval1 = field1->missval;
+  double *array1  = field1->ptr;
+  const int    grid2    = field2.grid;
+  const double missval2 = field2.missval;
+  double *array2  = field2.ptr;
+  double *array3  = field3.ptr;
+  double temp;
+
+  len    = (size_t) gridInqSize(grid1);
+
+  if ( len != (size_t) gridInqSize(grid2) )
+    cdoAbort("Fields have different gridsize (%s)", __func__);
+
+  for ( i = 0; i < len; i++ )
+    {
+      temp      = DIV( MUL(array1[i], array1[i]), array3[i]);
+      array1[i] = DIV( SUB(array2[i], temp), array3[i]-divisor);
+      if ( array1[i] < 0 && array1[i] > -1.e-5 ) array1[i] = 0;
+    }
+
+  field1->nmiss = 0;
+  for ( i = 0; i < len; i++ )
+    if ( DBL_IS_EQUAL(array1[i], missval1) || array1[i] < 0 )
+      {
+	array1[i] = missval1;
+	field1->nmiss++;
+      }
+}
+
+
 void farstd(field_t *field1, field_t field2, field_t field3)
 {
-  long   i, len;
-  int    grid1    = field1->grid;
-  double missval1 = field1->missval;
+  size_t   i, len;
+  const int    grid1    = field1->grid;
+  const double missval1 = field1->missval;
   double *array1  = field1->ptr;
   int    grid2    = field2.grid;
 
-  len    = gridInqSize(grid1);
+  len    = (size_t) gridInqSize(grid1);
 
-  if ( len != gridInqSize(grid2) )
+  if ( len != (size_t) gridInqSize(grid2) )
     cdoAbort("Fields have different gridsize (%s)", __func__);
 
   farvar(field1, field2, field3);
@@ -505,33 +544,67 @@ void farstd(field_t *field1, field_t field2, field_t field3)
 }
 
 
-void farcvar(field_t *field1, field_t field2, double rconst1)
+void farstdx(field_t *field1, field_t field2, field_t field3, const double divisor)
 {
-  long   i, len;
-  int    grid1    = field1->grid;
-  int    nmiss1   = field1->nmiss;
-  double missval1 = field1->missval;
+  size_t   i, len;
+  const int    grid1    = field1->grid;
+  const double missval1 = field1->missval;
   double *array1  = field1->ptr;
-  int    grid2    = field2.grid;
-  int    nmiss2   = field2.nmiss;
-  double missval2 = field2.missval;
+  const int    grid2    = field2.grid;
+
+  len    = (size_t) gridInqSize(grid1);
+
+  if ( len != (size_t) gridInqSize(grid2) )
+    cdoAbort("Fields have different gridsize (%s)", __func__);
+
+  farvarx(field1, field2, field3, divisor);
+
+  field1->nmiss = 0;
+  for ( i = 0; i < len; i++ )
+    if ( DBL_IS_EQUAL(array1[i], missval1) || array1[i] < 0 )
+      {
+	array1[i] = missval1;
+	field1->nmiss++;
+      }
+    else
+      {
+	array1[i] = IS_NOT_EQUAL(array1[i], 0) ? sqrt(array1[i]) : 0;
+      }
+}
+
+
+void farcvar(field_t *field1, field_t field2, const double rconst1)
+{
+  size_t   i, len;
+  const int    grid1    = field1->grid;
+  const int    nmiss1   = field1->nmiss;
+  const double missval1 = field1->missval;
+  double *array1  = field1->ptr;
+  const int    grid2    = field2.grid;
+  const int    nmiss2   = field2.nmiss;
+  const double missval2 = field2.missval;
   double *array2  = field2.ptr;
+  int    nmiss3   = 0;
 
-  len    = gridInqSize(grid1);
+  len    = (size_t) gridInqSize(grid1);
 
-  if ( len != gridInqSize(grid2) )
+  if ( len != (size_t) gridInqSize(grid2) )
     cdoAbort("Fields have different gridsize (%s)", __func__);
 
-  if ( nmiss1 > 0 || nmiss2 > 0 )
+  if ( DBL_IS_EQUAL(rconst1, missval1) ) nmiss3 = 1;
+
+  if ( nmiss1 > 0 || nmiss2 > 0 || nmiss3 > 0 )
     {
       for ( i = 0; i < len; i++ )
-	if ( !DBL_IS_EQUAL(array1[i], missval1) && !DBL_IS_EQUAL(array2[i], missval2) )
-	  {
-	    array1[i] = array2[i]*rconst1 - (array1[i]*rconst1)*(array1[i]*rconst1);
-	    if ( array1[i] < 0 && array1[i] > -1.e-5 ) array1[i] = 0;
-	  }
-	else
-	  array1[i] = missval1;
+	{
+	  if ( !DBL_IS_EQUAL(array1[i], missval1) && !DBL_IS_EQUAL(array2[i], missval2) && nmiss3 == 0 )
+	    {
+	      array1[i] = array2[i]*rconst1 - (array1[i]*rconst1)*(array1[i]*rconst1);
+	      if ( array1[i] < 0 && array1[i] > -1.e-5 ) array1[i] = 0;
+	    }
+	  else
+	    array1[i] = missval1;
+	}
     }
   else
     {
@@ -552,17 +625,50 @@ void farcvar(field_t *field1, field_t field2, double rconst1)
 }
 
 
-void farcstd(field_t *field1, field_t field2, double rconst1)
+void farcvarx(field_t *field1, field_t field2, const double rconst1, const double divisor)
 {
-  long   i, len;
-  int    grid1    = field1->grid;
-  double missval1 = field1->missval;
+  size_t   i, len;
+  const int    grid1    = field1->grid;
+  const double missval1 = field1->missval;
   double *array1  = field1->ptr;
-  int    grid2    = field2.grid;
+  const int    grid2    = field2.grid;
+  const double missval2 = field2.missval;
+  double *array2  = field2.ptr;
+  double temp;
 
-  len    = gridInqSize(grid1);
+  len    = (size_t) gridInqSize(grid1);
 
-  if ( len != gridInqSize(grid2) )
+  if ( len != (size_t) gridInqSize(grid2) )
+    cdoAbort("Fields have different gridsize (%s)", __func__);
+
+  for ( i = 0; i < len; i++ )
+    {
+      temp      = DIV( MUL(array1[i], array1[i]), rconst1);
+      array1[i] = DIV( SUB(array2[i], temp), rconst1-divisor);
+      if ( array1[i] < 0 && array1[i] > -1.e-5 ) array1[i] = 0;
+    }
+
+  field1->nmiss = 0;
+  for ( i = 0; i < len; i++ )
+    if ( DBL_IS_EQUAL(array1[i], missval1) || array1[i] < 0 )
+      {
+	array1[i] = missval1;
+	field1->nmiss++;
+      }
+}
+
+
+void farcstd(field_t *field1, field_t field2, const double rconst1)
+{
+  size_t   i, len;
+  const int    grid1    = field1->grid;
+  const double missval1 = field1->missval;
+  double *array1  = field1->ptr;
+  const int    grid2    = field2.grid;
+
+  len    = (size_t) gridInqSize(grid1);
+
+  if ( len != (size_t) gridInqSize(grid2) )
     cdoAbort("Fields have different gridsize (%s)", __func__);
 
   farcvar(field1, field2, rconst1);
@@ -581,20 +687,49 @@ void farcstd(field_t *field1, field_t field2, double rconst1)
 }
 
 
+void farcstdx(field_t *field1, field_t field2, const double rconst1, const double divisor)
+{
+  size_t   i, len;
+  const int    grid1    = field1->grid;
+  const double missval1 = field1->missval;
+  double *array1  = field1->ptr;
+  const int    grid2    = field2.grid;
+
+  len    = (size_t) gridInqSize(grid1);
+
+  if ( len != (size_t) gridInqSize(grid2) )
+    cdoAbort("Fields have different gridsize (%s)", __func__);
+
+  farcvarx(field1, field2, rconst1, divisor);
+
+  field1->nmiss = 0;
+  for ( i = 0; i < len; i++ )
+    if ( DBL_IS_EQUAL(array1[i], missval1) || array1[i] < 0 )
+      {
+	array1[i] = missval1;
+	field1->nmiss++;
+      }
+    else
+      {
+	array1[i] = IS_NOT_EQUAL(array1[i], 0) ? sqrt(array1[i]) : 0;
+      }
+}
+
+
 void farmoq(field_t *field1, field_t field2)
 {
-  long   i, len;
-  int    grid1    = field1->grid;
-  double missval1 = field1->missval;
+  size_t   i, len;
+  const int    grid1    = field1->grid;
+  const double missval1 = field1->missval;
   double *array1  = field1->ptr;
-  int    grid2    = field2.grid;
-  int    nmiss2   = field2.nmiss;
+  const int    grid2    = field2.grid;
+  const int    nmiss2   = field2.nmiss;
   double missval2 = field2.missval;
   double *array2  = field2.ptr;
 
-  len    = gridInqSize(grid1);
+  len    = (size_t) gridInqSize(grid1);
 
-  if ( len != gridInqSize(grid2) )
+  if ( len != (size_t) gridInqSize(grid2) )
     cdoAbort("Fields have different gridsize (%s)", __func__);
 
   if ( nmiss2 > 0 )
@@ -633,20 +768,20 @@ void farmoq(field_t *field1, field_t field2)
  */  
 void farcount(field_t *field1, field_t field2)
 {
-  long   i, len;
-  int    grid1    = field1->grid;
-  int    nmiss1   = field1->nmiss;
-  double missval1 = field1->missval;
+  size_t   i, len;
+  const int    grid1    = field1->grid;
+  const int    nmiss1   = field1->nmiss;
+  const double missval1 = field1->missval;
   double *array1  = field1->ptr;
   /*  double *weight1 = field1->weight; */
-  int    grid2    = field2.grid;
-  int    nmiss2   = field2.nmiss;
-  double missval2 = field2.missval;
+  const int    grid2    = field2.grid;
+  const int    nmiss2   = field2.nmiss;
+  const double missval2 = field2.missval;
   double *array2  = field2.ptr;
 
-  len    = gridInqSize(grid1);
+  len    = (size_t) gridInqSize(grid1);
 
-  if ( len != gridInqSize(grid2) )
+  if ( len != (size_t) gridInqSize(grid2) )
     cdoAbort("Fields have different gridsize (%s)", __func__);
 
   if ( nmiss1 > 0 || nmiss2 > 0 )
diff --git a/src/fieldc.c b/src/fieldc.c
index bfbbb43..3a1cdeb 100644
--- a/src/fieldc.c
+++ b/src/fieldc.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -27,7 +27,7 @@ void farcfun(field_t *field, double rconst, int function)
   else if ( function == func_mul ) farcmul(field, rconst);
   else if ( function == func_div ) farcdiv(field, rconst);
   else if ( function == func_mod ) farmod(field, rconst);
-  else    cdoAbort("function %d not implemented!", function);
+  else    cdoAbort("%s: function %d not implemented!", __func__, function);
 }
 
 void farcmul(field_t *field, double rconst)
diff --git a/src/fieldmem.c b/src/fieldmem.c
index 8953299..e2789aa 100644
--- a/src/fieldmem.c
+++ b/src/fieldmem.c
@@ -1,3 +1,4 @@
+#include <stdio.h>
 #include <string.h>
 
 #include <cdi.h>
diff --git a/src/fieldmer.c b/src/fieldmer.c
index 1711503..9af558c 100644
--- a/src/fieldmer.c
+++ b/src/fieldmer.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/fieldzon.c b/src/fieldzon.c
index 8e0b74b..2d45f67 100644
--- a/src/fieldzon.c
+++ b/src/fieldzon.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/functs.h b/src/functs.h
index 02d943f..da92a63 100644
--- a/src/functs.h
+++ b/src/functs.h
@@ -11,12 +11,15 @@
 #define  func_sum      13
 #define  func_avg      14
 #define  func_mean     15
-#define  func_var      16
 #define  func_std      17
-#define  func_pctl     18
+#define  func_std1     18
+#define  func_var      19
+#define  func_var1     20
 
-#define  func_cor      20
-#define  func_covar    21
+#define  func_pctl     21
+
+#define  func_cor      22
+#define  func_covar    23
 
 #define  func_crps     30
 #define  func_brs      31
diff --git a/src/gradsdeslib.c b/src/gradsdeslib.c
index ec0dd7e..ce11181 100644
--- a/src/gradsdeslib.c
+++ b/src/gradsdeslib.c
@@ -7,7 +7,6 @@
 #include <cdi.h>
 #include "gradsdeslib.h"
 
-extern int cdoDefaultDataType;
 
 static char pout[512];
 FILE *descr;             /* File descriptor pointer */
diff --git a/src/grid.c b/src/grid.c
index 185d560..40cd811 100644
--- a/src/grid.c
+++ b/src/grid.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/grid_gme.c b/src/grid_gme.c
index ef2795a..fb7fe9a 100644
--- a/src/grid_gme.c
+++ b/src/grid_gme.c
@@ -1214,7 +1214,7 @@ void initmask(int *mask, int ni, int nd)
 	*((int *)ptmp2) = 0;
 	ptmp2 += section.dim[0].mult;
       }
-
+      break;
     }
   }
 
@@ -1310,6 +1310,7 @@ void gme_grid_restore(double *p, int ni, int nd)
       for (j = 0; j <= ni; j++) {
 	p[ni+tmp4*(j+1)+tmp5*10+tmp3] = p[ni-j+tmp4*(ni+1)+tmp5*5+tmp3];
       }
+      break;
     }
   }
 
diff --git a/src/griddes.c b/src/griddes.c
index 0804432..76b3a9a 100644
--- a/src/griddes.c
+++ b/src/griddes.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -58,7 +58,7 @@ void extClose(int fileID);
 #define MAX_LINE_LEN 65536
 
 
-void gridInit(grid_t *grid)
+void gridInit(griddes_t *grid)
 {
   grid->mask          = NULL;
   grid->xvals         = NULL;
@@ -121,6 +121,7 @@ void gridInit(grid_t *grid)
   grid->ni3           = 0;
   grid->number        = 0;
   grid->position      = 0;
+  grid->uuid[0]       = 0;
   grid->path[0]       = 0;
   grid->xname[0]      = 0;
   grid->xlongname[0]  = 0;
@@ -168,7 +169,7 @@ int getoptname(char *optname, const char *optstring, int nopt)
 }
 
 
-int gridDefine(grid_t grid)
+int gridDefine(griddes_t grid)
 {
   int gridID = UNDEFID;
   int i;
@@ -498,9 +499,13 @@ int gridDefine(grid_t grid)
 	  Error("Undefined grid type!");
 	else
 	  Error("Unsupported grid type: %s", gridNamePtr(grid.type));
+
+	break;
       }
     }
 
+  if ( *grid.uuid ) gridDefUUID(gridID, grid.uuid);
+
   if ( grid.xname[0]     ) gridDefXname(gridID, grid.xname);
   if ( grid.xlongname[0] ) gridDefXlongname(gridID, grid.xlongname);
   if ( grid.xunits[0]    ) gridDefXunits(gridID, grid.xunits);
@@ -579,7 +584,7 @@ void fnmexp2(char *out, char *in1, const char *in2)
 }
 
 /*
-double *readfield(grid_t *grid, int record, char *format, char *filename)
+double *readfield(griddes_t *grid, int record, char *format, char *filename)
 {
   int fileID, rxysize, ierr, irec;
   double *vals;
@@ -614,7 +619,7 @@ double *readfield(grid_t *grid, int record, char *format, char *filename)
 }
 */
 /*
-double *readfield4(grid_t *grid, int record, char *format, char *filename)
+double *readfield4(griddes_t *grid, int record, char *format, char *filename)
 {
   int fileID, rxysize, ierr, irec;
   double *vals;
@@ -650,15 +655,15 @@ double *readfield4(grid_t *grid, int record, char *format, char *filename)
 }
 */
 
-double readflt(const char *name, const char *pline)
+double readflt(const char *filename, const char *name, const char *pline)
 {
   double val;
   char *endptr;
 
   val = strtod(pline, &endptr);
   if ( pline == endptr )
-    Warning("Couldn't read value for %s, set to zero!", name);
-
+    cdoAbort("Couldn't read value for %s (grid description file: %s)!", name, filename);
+ 
   return (val);
 }
 
@@ -668,8 +673,9 @@ int gridFromFile(FILE *gfp, const char *dname)
   char line[MAX_LINE_LEN], *pline;
   int gridID = -1;
   int size;
-  size_t len;
-  grid_t grid;
+  int lerror;
+  size_t i, len;
+  griddes_t grid;
 
   gridInit(&grid);
 
@@ -677,6 +683,17 @@ int gridFromFile(FILE *gfp, const char *dname)
     {
       if ( line[0] == '#' ) continue;
       if ( line[0] == '\0' ) continue;
+      len = strlen(line);
+
+      lerror = FALSE;
+      for ( i = 0; i < len; ++i )
+	if ( !(line[i] == 9 || (line[i] > 31 && line[i] < 127)) )
+	  {
+	    lerror = TRUE;
+	    line[i] = '#';
+	  }
+      if ( lerror ) cdoAbort("Grid description file >%s< contains illegal characters (line: %s)!", dname, line);
+
       pline = line;
       while ( isspace((int) *pline) ) pline++;
       if ( pline[0] == '\0' ) continue;
@@ -722,7 +739,7 @@ int gridFromFile(FILE *gfp, const char *dname)
 	  else if ( cmpstr(pline, "generic", len)  == 0 )
 	    grid.type = GRID_GENERIC;
 	  else
-	    Warning("Invalid grid name : %s", pline);
+	    cdoAbort("Invalid grid name : %s (grid description file: %s)", pline, dname);
 	}
       else if ( cmpstr(pline, "gridprec", len)  == 0 )
 	{
@@ -789,6 +806,12 @@ int gridFromFile(FILE *gfp, const char *dname)
 	{
 	  strcpy(grid.path, skipSeparator(pline + len));
 	}
+      else if ( cmpstr(pline, "uuid", len)  == 0 )
+	{
+	  char uuidOfHGridStr[256];
+	  strcpy(uuidOfHGridStr, skipSeparator(pline + len));
+	  str2uuid(uuidOfHGridStr, grid.uuid);
+	}
       else if ( cmpstr(pline, "xsize", len)  == 0 )
 	{
 	  grid.xsize = atol(skipSeparator(pline + len));
@@ -807,87 +830,87 @@ int gridFromFile(FILE *gfp, const char *dname)
 	}
       else if ( cmpstr(pline, "xfirst", len)  == 0 )
 	{
-	  grid.xfirst = readflt("xfirst", skipSeparator(pline + len));
+	  grid.xfirst = readflt(dname, "xfirst", skipSeparator(pline + len));
 	  grid.def_xfirst = TRUE;
 	}
       else if ( cmpstr(pline, "lonfirst", len)  == 0 )
 	{
-	  grid.xfirst = readflt("lonfirst", skipSeparator(pline + len));
+	  grid.xfirst = readflt(dname, "lonfirst", skipSeparator(pline + len));
 	  grid.def_xfirst = TRUE;
 	}
       else if ( cmpstr(pline, "yfirst", len)  == 0 )
 	{
-	  grid.yfirst = readflt("yfirst", skipSeparator(pline + len));
+	  grid.yfirst = readflt(dname, "yfirst", skipSeparator(pline + len));
 	  grid.def_yfirst = TRUE;
 	}
       else if ( cmpstr(pline, "latfirst", len)  == 0 )
 	{
-	  grid.yfirst = readflt("latfirst", skipSeparator(pline + len));
+	  grid.yfirst = readflt(dname, "latfirst", skipSeparator(pline + len));
 	  grid.def_yfirst = TRUE;
 	}
       else if ( cmpstr(pline, "xlast", len)  == 0 )
 	{
-	  grid.xlast = readflt("xlast", skipSeparator(pline + len));
+	  grid.xlast = readflt(dname, "xlast", skipSeparator(pline + len));
 	  grid.def_xlast = TRUE;
 	}
       else if ( cmpstr(pline, "lonlast", len)  == 0 )
 	{
-	  grid.xlast = readflt("lonlast", skipSeparator(pline + len));
+	  grid.xlast = readflt(dname, "lonlast", skipSeparator(pline + len));
 	  grid.def_xlast = TRUE;
 	}
       else if ( cmpstr(pline, "ylast", len)  == 0 )
 	{
-	  grid.ylast = readflt("ylast", skipSeparator(pline + len));
+	  grid.ylast = readflt(dname, "ylast", skipSeparator(pline + len));
 	  grid.def_ylast = TRUE;
 	}
       else if ( cmpstr(pline, "latlast", len)  == 0 )
 	{
-	  grid.ylast = readflt("latlast", skipSeparator(pline + len));
+	  grid.ylast = readflt(dname, "latlast", skipSeparator(pline + len));
 	  grid.def_ylast = TRUE;
 	}
       else if ( cmpstr(pline, "xinc", len)  == 0 )
 	{
-	  grid.xinc = readflt("xinc", skipSeparator(pline + len));
+	  grid.xinc = readflt(dname, "xinc", skipSeparator(pline + len));
 	  grid.def_xinc = TRUE;
 	}
       else if ( cmpstr(pline, "loninc", len)  == 0 )
 	{
-	  grid.xinc = readflt("loninc", skipSeparator(pline + len));
+	  grid.xinc = readflt(dname, "loninc", skipSeparator(pline + len));
 	  grid.def_xinc = TRUE;
 	}
       else if ( cmpstr(pline, "yinc", len)  == 0 )
 	{
-	  grid.yinc = readflt("yinc", skipSeparator(pline + len));
+	  grid.yinc = readflt(dname, "yinc", skipSeparator(pline + len));
 	  grid.def_yinc = TRUE;
 	}
       else if ( cmpstr(pline, "latinc", len)  == 0 )
 	{
-	  grid.yinc = readflt("latinc", skipSeparator(pline + len));
+	  grid.yinc = readflt(dname, "latinc", skipSeparator(pline + len));
 	  grid.def_yinc = TRUE;
 	}
       else if ( cmpstr(pline, "originLon", len)  == 0 )
 	{
-	  grid.originLon = readflt("originLon", skipSeparator(pline + len));
+	  grid.originLon = readflt(dname, "originLon", skipSeparator(pline + len));
 	  grid.def_originLon = TRUE;
 	}
       else if ( cmpstr(pline, "originLat", len)  == 0 )
 	{
-	  grid.originLat = readflt("originLat", skipSeparator(pline + len));
+	  grid.originLat = readflt(dname, "originLat", skipSeparator(pline + len));
 	  grid.def_originLat = TRUE;
 	}
       else if ( cmpstr(pline, "lonParY", len)  == 0 )
 	{
-	  grid.lonParY = readflt("lonParY", skipSeparator(pline + len));
+	  grid.lonParY = readflt(dname, "lonParY", skipSeparator(pline + len));
 	  grid.def_lonParY = TRUE;
 	}
       else if ( cmpstr(pline, "lat1", len)  == 0 )
 	{
-	  grid.lat1 = readflt("lat1", skipSeparator(pline + len));
+	  grid.lat1 = readflt(dname, "lat1", skipSeparator(pline + len));
 	  grid.def_lat1 = TRUE;
 	}
       else if ( cmpstr(pline, "lat2", len)  == 0 )
 	{
-	  grid.lat2 = readflt("lat2", skipSeparator(pline + len));
+	  grid.lat2 = readflt(dname, "lat2", skipSeparator(pline + len));
 	  grid.def_lat2 = TRUE;
 	}
       else if ( cmpstr(pline, "projection", len)  == 0 )
@@ -904,50 +927,50 @@ int gridFromFile(FILE *gfp, const char *dname)
 	      grid.scanflag = 64;
 	    }
 	  else
-	    Warning("Invalid projection : %s", pline);
+	    cdoAbort("Invalid projection : %s (grid description file: %s)", pline, dname);
 	}
       else if ( cmpstr(pline, "a", len)  == 0 )
 	{
-	  grid.a = readflt("a", skipSeparator(pline + len));
+	  grid.a = readflt(dname, "a", skipSeparator(pline + len));
 	}
       else if ( cmpstr(pline, "lon_0", len)  == 0 )
 	{
-	  grid.lon_0 = readflt("lon_0", skipSeparator(pline + len));
+	  grid.lon_0 = readflt(dname, "lon_0", skipSeparator(pline + len));
 	  grid.def_lon_0 = TRUE;
 	}
       else if ( cmpstr(pline, "lat_0", len)  == 0 )
 	{
-	  grid.lat_0 = readflt("lat_0", skipSeparator(pline + len));
+	  grid.lat_0 = readflt(dname, "lat_0", skipSeparator(pline + len));
 	  grid.def_lat_0 = TRUE;
 	}
       else if ( cmpstr(pline, "lat_1", len)  == 0 )
 	{
-	  grid.lat_1 = readflt("lat_1", skipSeparator(pline + len));
+	  grid.lat_1 = readflt(dname, "lat_1", skipSeparator(pline + len));
 	  grid.def_lat_1 = TRUE;
 	}
       else if ( cmpstr(pline, "lat_2", len)  == 0 )
 	{
-	  grid.lat_2 = readflt("lat_2", skipSeparator(pline + len));
+	  grid.lat_2 = readflt(dname, "lat_2", skipSeparator(pline + len));
 	  grid.def_lat_2 = TRUE;
 	}
       else if ( cmpstr(pline, "xnpole", len)  == 0 )
 	{
-	  grid.xpole = readflt("xnpole", skipSeparator(pline + len));
+	  grid.xpole = readflt(dname, "xnpole", skipSeparator(pline + len));
 	  grid.isRotated = TRUE;
 	}
       else if ( cmpstr(pline, "lonpole", len)  == 0 )
 	{
-	  grid.xpole = readflt("lonpole", skipSeparator(pline + len));
+	  grid.xpole = readflt(dname, "lonpole", skipSeparator(pline + len));
 	  grid.isRotated = TRUE;
 	}
       else if ( cmpstr(pline, "ynpole", len)  == 0 )
 	{
-	  grid.ypole = readflt("ynpole", skipSeparator(pline + len));
+	  grid.ypole = readflt(dname, "ynpole", skipSeparator(pline + len));
 	  grid.isRotated = TRUE;
 	}
       else if ( cmpstr(pline, "latpole", len)  == 0 )
 	{
-	  grid.ypole = readflt("latpole", skipSeparator(pline + len));
+	  grid.ypole = readflt(dname, "latpole", skipSeparator(pline + len));
 	  grid.isRotated = TRUE;
 	}
       else if ( cmpstr(pline, "gridlatlon", len)  == 0 )
@@ -961,10 +984,8 @@ int gridFromFile(FILE *gfp, const char *dname)
 	  for ( i = 0; i < (int) grid.size; i++ )
 	    {
 	      if ( ! readline(gfp, line, MAX_LINE_LEN) )
-		{
-		  Warning("Incomplete command: >gridlatlon<");
-		  break;
-		}
+		cdoAbort("Incomplete command: >gridlatlon< (grid description file: %s)", dname);
+
 	      sscanf(line, "%lg %lg", &flat, &flon);
 	      grid.yvals[i] = flat;
 	      grid.xvals[i] = flon;
@@ -991,10 +1012,8 @@ int gridFromFile(FILE *gfp, const char *dname)
 		  if ( pline == endptr )
 		    {
 		      if ( ! readline(gfp, line, MAX_LINE_LEN) )
-			{
-			  Warning("Incomplete command: >mask<");
-			  break;
-			}
+			cdoAbort("Incomplete command: >mask< (grid description file: %s)", dname);
+
 		      pline = line;
 		      lval = strtol(pline, &endptr, 10);
 		    }
@@ -1010,7 +1029,7 @@ int gridFromFile(FILE *gfp, const char *dname)
 		}
 	    }
 	  else
-	    Warning("gridsize undefined!");
+	    cdoAbort("gridsize undefined (grid description file: %s)!", dname);
 	}
       else if ( cmpstr(pline, "xvals", len)  == 0 )
 	{
@@ -1035,10 +1054,8 @@ int gridFromFile(FILE *gfp, const char *dname)
 		  if ( pline == endptr )
 		    {
 		      if ( ! readline(gfp, line, MAX_LINE_LEN) )
-			{
-			  Warning("Incomplete command: >xvals<");
-			  break;
-			}
+			cdoAbort("Incomplete command: >xvals< (grid description file: %s)", dname);
+
 		      pline = line;
 		      fval = strtod(pline, &endptr);
 		    }
@@ -1047,7 +1064,7 @@ int gridFromFile(FILE *gfp, const char *dname)
 		}
 	    }
 	  else
-	    Warning("xsize or gridsize undefined!");
+	    cdoAbort("xsize or gridsize undefined (grid description file: %s)!", dname);
 	}
       else if ( cmpstr(pline, "yvals", len)  == 0 )
 	{
@@ -1072,10 +1089,8 @@ int gridFromFile(FILE *gfp, const char *dname)
 		  if ( pline == endptr )
 		    {
 		      if ( ! readline(gfp, line, MAX_LINE_LEN) )
-			{
-			  Warning("Incomplete command: >yvals<");
-			  break;
-			}
+			cdoAbort("Incomplete command: >yvals< (grid description file: %s)", dname);
+
 		      pline = line;
 		      fval = strtod(pline, &endptr);
 		    }
@@ -1084,7 +1099,7 @@ int gridFromFile(FILE *gfp, const char *dname)
 		}
 	    }
 	  else
-	    Warning("ysize or gridsize undefined!");
+	    cdoAbort("ysize or gridsize undefined (grid description file: %s)!", dname);
 	}
       else if ( cmpstr(pline, "xbounds", len)  == 0 )
 	{
@@ -1114,10 +1129,8 @@ int gridFromFile(FILE *gfp, const char *dname)
 		  if ( pline == endptr )
 		    {
 		      if ( ! readline(gfp, line, MAX_LINE_LEN) )
-			{
-			  Warning("Incomplete command: >xbounds<");
-			  break;
-			}
+			cdoAbort("Incomplete command: >xbounds< (grid description file: %s)", dname);
+
 		      pline = line;
 		      fval = strtod(pline, &endptr);
 		    }
@@ -1127,8 +1140,8 @@ int gridFromFile(FILE *gfp, const char *dname)
 	    }
 	  else
 	    {
-	      if ( size         == 0 ) Warning("xsize or gridsize undefined!");
-	      if ( grid.nvertex == 0 ) Warning("nvertex undefined!");
+	      if ( size         == 0 ) cdoAbort("xsize or gridsize undefined (grid description file: %s)!", dname);
+	      if ( grid.nvertex == 0 ) cdoAbort("nvertex undefined (grid description file: %s)!", dname);
 	    }
 	}
       else if ( cmpstr(pline, "ybounds", len)  == 0 )
@@ -1159,10 +1172,8 @@ int gridFromFile(FILE *gfp, const char *dname)
 		  if ( pline == endptr )
 		    {
 		      if ( ! readline(gfp, line, MAX_LINE_LEN) )
-			{
-			  Warning("Incomplete command: >ybounds<");
-			  break;
-			}
+			cdoAbort("Incomplete command: >ybounds< (grid description file: %s)", dname);
+
 		      pline = line;
 		      fval = strtod(pline, &endptr);
 		    }
@@ -1172,14 +1183,14 @@ int gridFromFile(FILE *gfp, const char *dname)
 	    }
 	  else
 	    {
-	      if ( grid.ysize   == 0 ) Warning("ysize or gridsize undefined!");
-	      if ( grid.nvertex == 0 ) Warning("nvertex undefined!");
+	      if ( grid.ysize   == 0 ) cdoAbort("ysize or gridsize undefined (grid description file: %s)!", dname);
+	      if ( grid.nvertex == 0 ) cdoAbort("nvertex undefined!", dname);
 	    }
 	}
       else
 	{
 	  if ( grid.type != UNDEFID )
-	    Warning("Invalid grid command : >%s<", pline);
+	    cdoAbort("Invalid grid command : >%s< (grid description file: %s)", pline, dname);
 	}
     }
   /*
@@ -1260,7 +1271,7 @@ int gridFromPingo(FILE *gfp, const char *dname)
   int i;
   int nlon, nlat;
   int lgauss = FALSE;
-  grid_t grid;
+  griddes_t grid;
 
   gridInit(&grid);
 
@@ -1470,7 +1481,7 @@ int compNlon(int nlat)
 }
 
 static
-void gen_grid_lonlat(grid_t *grid, const char *pline, double inc, double lon1, double lon2, double lat1, double lat2)
+void gen_grid_lonlat(griddes_t *grid, const char *pline, double inc, double lon1, double lon2, double lat1, double lat2)
 {
   int nlon, nlat, i;
   int gridtype = GRID_LONLAT;
@@ -1511,7 +1522,7 @@ int gridFromName(const char *gridname)
 {
   const char *pline;
   int gridID = UNDEFID;
-  grid_t grid;
+  griddes_t grid;
   size_t len;
   char *endptr;
 
diff --git a/src/griddes.h b/src/griddes.h
index 50b5837..50c3907 100644
--- a/src/griddes.h
+++ b/src/griddes.h
@@ -53,6 +53,7 @@ typedef struct {
   int     def_yinc;
   int     nd, ni, ni2, ni3;
   int     number, position;
+  char    uuid[17];
   char    path[16384];
   char    xname[CDI_MAX_NAME];
   char    xlongname[CDI_MAX_NAME];
@@ -61,10 +62,10 @@ typedef struct {
   char    ylongname[CDI_MAX_NAME];
   char    yunits[CDI_MAX_NAME];
 }
-grid_t;
+griddes_t;
 
-void gridInit(grid_t *grid);
-int gridDefine(grid_t grid);
+void gridInit(griddes_t *grid);
+int gridDefine(griddes_t grid);
 
 int gridFromNCfile(const char *gridfile);
 int gridFromH5file(const char *gridfile);
diff --git a/src/griddes_h5.c b/src/griddes_h5.c
index 22e917f..66115ab 100644
--- a/src/griddes_h5.c
+++ b/src/griddes_h5.c
@@ -16,20 +16,6 @@
 
 
 #if  defined  (HAVE_LIBHDF5)
-static
-void nce(int istat)
-{
-  /*
-    This routine provides a simple interface to netCDF error message routine.
-  */
-  /*
-  if ( istat != NC_NOERR ) cdoAbort(nc_strerror(istat));
-  */
-}
-#endif
-
-
-#if  defined  (HAVE_LIBHDF5)
 static herr_t
 obj_info(hid_t loc_id, const char *name, void *objname)
 {
@@ -313,7 +299,7 @@ int gridFromH5file(const char *gridfile)
   hsize_t dims_out[9];  /* dataset dimensions           */
   herr_t  status;	/* Generic return value		*/
   int     rank;
-  grid_t    grid;
+  griddes_t    grid;
 
 
   gridInit(&grid);
diff --git a/src/griddes_nc.c b/src/griddes_nc.c
index edfa39e..a1e7209 100644
--- a/src/griddes_nc.c
+++ b/src/griddes_nc.c
@@ -64,7 +64,7 @@ int gridFromNCfile(const char *gridfile)
   size_t attlen;
   size_t grid_rank, grid_size, grid_nvertex;
   int grid_dims[2];
-  grid_t grid;
+  griddes_t grid;
 
 
   gridInit(&grid);
diff --git a/src/history.c b/src/history.c
index 5da8c0d..fe40dff 100644
--- a/src/history.c
+++ b/src/history.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/institution.c b/src/institution.c
index adb1579..d011d23 100644
--- a/src/institution.c
+++ b/src/institution.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/interpol.c b/src/interpol.c
index de1bc23..dbed041 100644
--- a/src/interpol.c
+++ b/src/interpol.c
@@ -73,7 +73,7 @@ long find_element(double x, long nelem, const double *array)
 
   return (mid);
 }
-
+/*
 static
 long find_element_old(double x, long nelem, const double *array)
 {
@@ -92,7 +92,7 @@ long find_element_old(double x, long nelem, const double *array)
 
   return (ii);
 }
-
+*/
 
 double intlinarr2p(long nxm, long nym, double **fieldm, const double *xm, const double *ym,
 		   double x, double y)
@@ -325,7 +325,8 @@ void interpolate(field_t *field1, field_t *field2)
   int i;
   double *lono_array, *lato_array, *lono, *lato;
   double *lon_array, *lat_array, *lon, *lat;
-  int gridsize_i, gridsize_o;
+  //int gridsize_i
+  int gridsize_o;
   int gridIDi;
   double *arrayIn;
   int gridIDo;
@@ -358,7 +359,7 @@ void interpolate(field_t *field1, field_t *field2)
   arrayOut = field2->ptr;
   missval  = field1->missval;
 
-  gridsize_i = gridInqSize(gridIDi);
+  //gridsize_i = gridInqSize(gridIDi);
   gridsize_o = gridInqSize(gridIDo);
 
   nlon  = gridInqXsize(gridIDi);
diff --git a/src/kvlist.c b/src/kvlist.c
index 68002b1..0d2333b 100644
--- a/src/kvlist.c
+++ b/src/kvlist.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/kvlist.h b/src/kvlist.h
index 45de11f..174f4fc 100644
--- a/src/kvlist.h
+++ b/src/kvlist.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/list.c b/src/list.c
index 3cc8f57..4a79b50 100644
--- a/src/list.c
+++ b/src/list.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/list.h b/src/list.h
index f20c9be..2dfdf41 100644
--- a/src/list.h
+++ b/src/list.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/modules.c b/src/modules.c
index 9e9cbc3..0a5c72b 100644
--- a/src/modules.c
+++ b/src/modules.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -42,6 +42,7 @@ typedef struct {
 modules_t;
 
 
+void *Adisit(void *argument);
 void *Arith(void *argument);
 void *Arithc(void *argument);
 void *Arithdays(void *argument);
@@ -202,6 +203,7 @@ void *Wind(void *argument);
 void *Writegrid(void *argument);
 void *Writerandom(void *argument);
 void *YAR(void *argument);
+void *Yearmonstat(void *argument);
 void *Ydayarith(void *argument);
 void *Ydaypctl(void *argument);
 void *Ydaystat(void *argument);
@@ -258,7 +260,7 @@ void *Strbre(void *argument);
 void *Strgal(void *argument);
 void *Hurr(void *argument);
 
-void *Hi(void *argument);
+//void *Hi(void *argument);
 void *Wct(void *argument);
 
 #if defined(HAVE_LIBMAGICS) && defined(HAVE_LIBXML2)
@@ -268,6 +270,7 @@ void *Maggraph(void *argument);
 #endif
 
 
+#define  AdisitOperators        {"adisit"}
 #define  ArithOperators         {"add",  "sub",  "mul",  "div", "min", "max", "atan2"}
 #define  ArithcOperators        {"addc", "subc", "mulc", "divc", "mod"}
 #define  ArithdaysOperators     {"muldpm", "divdpm", "muldpy", "divdpy", "muldoy"}
@@ -291,13 +294,13 @@ void *Maggraph(void *argument);
 #define  DeltimeOperators       {"delday", "del29feb"}
 #define  DeriveparOperators     {"geopotheight"}
 #define  DetrendOperators       {"detrend"}
-#define  DiffOperators          {"diff", "diff2", "diffp", "diffn", "diffc", "sdiff"}
+#define  DiffOperators          {"diff", "diff2", "diffp", "diffn", "diffc"}
 #define  DuplicateOperators     {"duplicate"}
 #define  Echam5iniOperators     {"import_e5ml", "import_e5res", \
                                  "export_e5ml", "export_e5res"}
 #define  EnlargeOperators       {"enlarge"}
 #define  EnlargegridOperators   {"enlargegrid"}
-#define  EnsstatOperators       {"ensmin", "ensmax", "enssum", "ensmean", "ensavg", "ensvar", "ensstd", "enspctl"}
+#define  EnsstatOperators       {"ensmin", "ensmax", "enssum", "ensmean", "ensavg", "ensvar", "ensvar1", "ensstd", "ensstd1", "enspctl"}
 #define  Ensstat3Operators      {"ensrkhist_space","ensrkhist_time","ensroc"}
 #define  EnsvalOperators        {"enscrps","ensbrs"}
 #define  EofcoeffOperators      {"eofcoeff"}
@@ -311,15 +314,14 @@ void *Maggraph(void *argument);
 #define  FillmissOperators      {"fillmiss"}
 #define  FilterOperators        {"bandpass", "highpass", "lowpass"}
 #define  FldrmsOperators        {"fldrms"}
-#define  FldstatOperators       {"fldmin", "fldmax", "fldsum", "fldmean", "fldavg", "fldvar", "fldstd", "fldpctl"}
+#define  FldstatOperators       {"fldmin", "fldmax", "fldsum", "fldmean", "fldavg", "fldstd", "fldstd1", "fldvar", "fldvar1", "fldpctl"}
 #define  FldcorOperators        {"fldcor"}
 #define  FldcovarOperators      {"fldcovar"}
 #define  FourierOperators       {"fourier"}
 #define  GatherOperators        {"gather"}
 #define  GengridOperators       {"gengrid"}
 #define  GradsdesOperators      {"gradsdes1", "gradsdes2", "dumpmap"}
-#define  GridboxstatOperators   {"gridboxmin", "gridboxmax", "gridboxsum", "gridboxmean", "gridboxavg", \
-                                 "gridboxvar", "gridboxstd"}
+#define  GridboxstatOperators   {"gridboxmin", "gridboxmax", "gridboxsum", "gridboxmean", "gridboxavg", "gridboxvar", "gridboxstd"}
 #define  GridcellOperators      {"gridarea", "gridweights", "gridmask", "griddx", "griddy"}
 #define  HarmonicOperators      {"harmonic"}
 #define  HistogramOperators     {"histcount", "histsum", "histmean", "histfreq"}
@@ -373,7 +375,7 @@ void *Maggraph(void *argument);
 #define  RhopotOperators        {"rhopot"}
 #define  RotuvOperators         {"rotuvb"}
 #define  RunpctlOperators       {"runpctl"}
-#define  RunstatOperators       {"runmin",  "runmax",  "runsum",  "runmean",  "runavg",  "runvar",  "runstd"}
+#define  RunstatOperators       {"runmin",  "runmax",  "runsum",  "runmean",  "runavg",  "runstd",  "runstd1",  "runvar",  "runvar1"}
 #define  SeascountOperators     {"seascount"}
 #define  SeaspctlOperators      {"seaspctl"}
 #define  SeasstatOperators      {"seasmin",  "seasmax",  "seassum",  "seasmean",  "seasavg",  "seasvar",  "seasstd"}
@@ -432,12 +434,12 @@ void *Maggraph(void *argument);
 #define    DaypctlOperators     {"daypctl"}
 #define    HourpctlOperators    {"hourpctl"}
 #define  TimselpctlOperators    {"timselpctl"}
-#define  TimselstatOperators    {"timselmin", "timselmax", "timselsum", "timselmean", "timselavg", "timselvar", "timselstd"}
-#define  TimstatOperators       {"timmin",  "timmax",  "timsum",  "timmean",  "timavg",  "timvar",  "timstd"}
-#define    YearstatOperators    {"yearmin", "yearmax", "yearsum", "yearmean", "yearavg", "yearvar", "yearstd"}
-#define    MonstatOperators     {"monmin",  "monmax",  "monsum",  "monmean",  "monavg",  "monvar",  "monstd"}
-#define    DaystatOperators     {"daymin",  "daymax",  "daysum",  "daymean",  "dayavg",  "dayvar",  "daystd"}
-#define    HourstatOperators    {"hourmin", "hourmax", "hoursum", "hourmean", "houravg", "hourvar", "hourstd"}
+#define  TimselstatOperators    {"timselmin", "timselmax", "timselsum", "timselmean", "timselavg", "timselvar", "timselvar1", "timselstd", "timselstd1"}
+#define  TimstatOperators       {"timmin",  "timmax",  "timsum",  "timmean",  "timavg",  "timvar",  "timvar1",  "timstd",  "timstd1"}
+#define    YearstatOperators    {"yearmin", "yearmax", "yearsum", "yearmean", "yearavg", "yearvar", "yearvar1", "yearstd", "yearstd1"}
+#define    MonstatOperators     {"monmin",  "monmax",  "monsum",  "monmean",  "monavg",  "monvar",  "monvar1",  "monstd",  "monstd1"}
+#define    DaystatOperators     {"daymin",  "daymax",  "daysum",  "daymean",  "dayavg",  "dayvar",  "dayvar1",  "daystd",  "daystd1"}
+#define    HourstatOperators    {"hourmin", "hourmax", "hoursum", "hourmean", "houravg", "hourvar", "hourvar1", "hourstd", "hourstd1"}
 #define  TimcorOperators        {"timcor"}
 #define  TimcovarOperators      {"timcovar"}
 #define  Timstat3Operators      {"meandiff2test", "varquot2test"}
@@ -448,7 +450,7 @@ void *Maggraph(void *argument);
 #define  TrmsOperators          {"trms"}
 #define  TstepcountOperators    {"tstepcount"}
 #define  VardupOperators        {"pardup", "parmul"}
-#define  VargenOperators        {"random", "const", "for", "topo", "temp", "mask", "stdatm"}
+#define  VargenOperators        {"random", "const", "sincos", "for", "topo", "temp", "mask", "stdatm"}
 #define  VarrmsOperators        {"varrms"}
 #define  VertintOperators       {"ml2pl", "ml2hl", "ml2plx", "ml2hlx", \
                                  "ml2pl_lp", "ml2hl_lp", "ml2plx_lp", "ml2hlx_lp"}
@@ -458,16 +460,17 @@ void *Maggraph(void *argument);
 #define  WritegridOperators     {"writegrid"}
 #define  WriterandomOperators   {"writerandom"}
 #define  YAROperators           {"yarbil", "yarnn", "yarcon"}
+#define  YearmonstatOperators   {"yearmonmean", "yearmonavg"}
 #define  YdayarithOperators     {"ydayadd", "ydaysub", "ydaymul", "ydaydiv"}
 #define  YdaypctlOperators      {"ydaypctl"}
-#define  YdaystatOperators      {"ydaymin", "ydaymax", "ydaysum", "ydaymean", "ydayavg", "ydayvar", "ydaystd"}
+#define  YdaystatOperators      {"ydaymin", "ydaymax", "ydaysum", "ydaymean", "ydayavg", "ydaystd", "ydaystd1", "ydayvar", "ydayvar1"}
 #define  YdrunpctlOperators     {"ydrunpctl"}
-#define  YdrunstatOperators     {"ydrunmin", "ydrunmax", "ydrunsum", "ydrunmean", "ydrunavg", "ydrunvar", "ydrunstd"}
+#define  YdrunstatOperators     {"ydrunmin", "ydrunmax", "ydrunsum", "ydrunmean", "ydrunavg", "ydrunstd", "ydrunstd1", "ydrunvar", "ydrunvar1"}
 #define  YhourarithOperators    {"yhouradd", "yhoursub", "yhourmul", "yhourdiv"}
-#define  YhourstatOperators     {"yhourmin", "yhourmax", "yhoursum", "yhourmean", "yhouravg", "yhourvar", "yhourstd"}
+#define  YhourstatOperators     {"yhourmin", "yhourmax", "yhoursum", "yhourmean", "yhouravg", "yhourstd", "yhourstd1", "yhourvar", "yhourvar1"}
 #define  YmonarithOperators     {"ymonadd", "ymonsub", "ymonmul", "ymondiv"}
 #define  YmonpctlOperators      {"ymonpctl"}
-#define  YmonstatOperators      {"ymonmin", "ymonmax", "ymonsum", "ymonmean", "ymonavg", "ymonvar", "ymonstd"}
+#define  YmonstatOperators      {"ymonmin", "ymonmax", "ymonsum", "ymonmean", "ymonavg", "ymonstd", "ymonstd1", "ymonvar", "ymonvar1"}
 #define  YseaspctlOperators     {"yseaspctl"}
 #define  YseasstatOperators     {"yseasmin", "yseasmax", "yseassum", "yseasmean", "yseasavg", "yseasvar", "yseasstd"}
 #define  ZonstatOperators       {"zonmin", "zonmax", "zonrange", "zonsum", "zonmean", "zonavg", "zonvar", "zonstd", "zonpctl"}
@@ -535,6 +538,7 @@ static modules_t Modules[] =
     function        help function      operator names          number     num streams
                                                                type       in  out
   */
+  { Adisit,         AdisitHelp,        AdisitOperators,        CDI_REAL,  1,  1 },
   { Arith,          ArithHelp,         ArithOperators,         CDI_REAL,  2,  1 },
   { Arithc,         ArithcHelp,        ArithcOperators,        CDI_REAL,  1,  1 },
   { Arithdays,      ArithdaysHelp,     ArithdaysOperators,     CDI_REAL,  1,  1 },
@@ -559,7 +563,7 @@ static modules_t Modules[] =
   { Derivepar,      NULL,              DeriveparOperators,     CDI_REAL,  1,  1 },
   { Detrend,        DetrendHelp,       DetrendOperators,       CDI_REAL,  1,  1 },
   { Diff,           DiffHelp,          DiffOperators,          CDI_REAL,  2,  0 },
-  { Duplicate,      NULL,              DuplicateOperators,     CDI_REAL,  1,  1 },
+  { Duplicate,      DuplicateHelp,     DuplicateOperators,     CDI_REAL,  1,  1 },
   { Echam5ini,      NULL,              Echam5iniOperators,     CDI_REAL,  1,  1 },
   { Enlarge,        EnlargeHelp,       EnlargeOperators,       CDI_REAL,  1,  1 },
   { Enlargegrid,    NULL,              EnlargegridOperators,   CDI_REAL,  1,  1 },
@@ -610,8 +614,8 @@ static modules_t Modules[] =
   { Mastrfu,        MastrfuHelp,       MastrfuOperators,       CDI_REAL,  1,  1 },
   { Math,           MathHelp,          MathOperators,          CDI_REAL,  1,  1 },
   { Merge,          MergeHelp,         MergeOperators,         CDI_REAL, -1,  1 },
-  { Mergegrid,      NULL,              MergegridOperators,     CDI_REAL,  2,  1 },
   { Mergetime,      MergeHelp,         MergetimeOperators,     CDI_REAL, -1,  1 },
+  { Mergegrid,      MergegridHelp,     MergegridOperators,     CDI_REAL,  2,  1 },
   { Merstat,        MerstatHelp,       MerstatOperators,       CDI_REAL,  1,  1 },
   { Monarith,       MonarithHelp,      MonarithOperators,      CDI_REAL,  2,  1 },
   { Mrotuv,         NULL,              MrotuvOperators,        CDI_REAL,  1,  2 },
@@ -629,7 +633,7 @@ static modules_t Modules[] =
   { Remapeta,       RemapetaHelp,      RemapetaOperators,      CDI_REAL,  1,  1 },
   { Replace,        ReplaceHelp,       ReplaceOperators,       CDI_REAL,  2,  1 },
   { Replacevalues,  ReplacevaluesHelp, ReplacevaluesOperators, CDI_REAL,  1,  1 },
-  { Rhopot,         NULL,              RhopotOperators,        CDI_REAL,  1,  1 },
+  { Rhopot,         RhopotHelp,        RhopotOperators,        CDI_REAL,  1,  1 },
   { Rotuv,          RotuvHelp,         RotuvOperators,         CDI_REAL,  1,  1 },
   { Runpctl,        RunpctlHelp,       RunpctlOperators,       CDI_REAL,  1,  1 },
   { Runstat,        RunstatHelp,       RunstatOperators,       CDI_REAL,  1,  1 },
@@ -637,7 +641,7 @@ static modules_t Modules[] =
   { Seaspctl,       SeaspctlHelp,      SeaspctlOperators,      CDI_REAL,  3,  1 },
   { Seasstat,       SeasstatHelp,      SeasstatOperators,      CDI_REAL,  1,  1 },
   { Selbox,         SelboxHelp,        SelboxOperators,        CDI_BOTH,  1,  1 },
-  { Select,         NULL,              SelectOperators,        CDI_BOTH, -1,  1 },
+  { Select,         SelectHelp,        SelectOperators,        CDI_BOTH, -1,  1 },
   { Selvar,         SelvarHelp,        SelvarOperators,        CDI_BOTH,  1,  1 },
   { Selrec,         SelvarHelp,        SelrecOperators,        CDI_BOTH,  1,  1 },
   { Seloperator,    NULL,              SeloperatorOperators,   CDI_REAL,  1,  1 },
@@ -712,6 +716,7 @@ static modules_t Modules[] =
   { Writegrid,      NULL,              WritegridOperators,     CDI_REAL,  1,  1 },  /* no cdi output */
   { Writerandom,    NULL,              WriterandomOperators,   CDI_REAL,  1,  1 },
   { YAR,            NULL,              YAROperators,           CDI_REAL,  1,  1 },
+  { Yearmonstat,    YearmonmeanHelp,   YearmonstatOperators,   CDI_REAL,  1,  1 },
   { Ydayarith,      YdayarithHelp,     YdayarithOperators,     CDI_REAL,  2,  1 },
   { Ydaypctl,       YdaypctlHelp,      YdaypctlOperators,      CDI_REAL,  3,  1 },
   { Ydaystat,       YdaystatHelp,      YdaystatOperators,      CDI_REAL,  1,  1 },
diff --git a/src/modules.h b/src/modules.h
index e02a657..0a97a33 100644
--- a/src/modules.h
+++ b/src/modules.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/namelist.c b/src/namelist.c
index d5f68a8..9b4bfbe 100644
--- a/src/namelist.c
+++ b/src/namelist.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/namelist.h b/src/namelist.h
index 4378e43..12bdae1 100644
--- a/src/namelist.h
+++ b/src/namelist.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/nth_element.c b/src/nth_element.c
index ae47a86..7627b6c 100644
--- a/src/nth_element.c
+++ b/src/nth_element.c
@@ -14,6 +14,8 @@
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
 */
+#include <stdio.h>
+#include <string.h>
 #include <assert.h>
 #include <stdlib.h>
 #include "nth_element.h"
diff --git a/src/operator_help.h b/src/operator_help.h
index c96d1ca..b50b524 100644
--- a/src/operator_help.h
+++ b/src/operator_help.h
@@ -212,11 +212,43 @@ static char *ReplaceHelp[] = {
     "    replace  ifile1 ifile2 ofile",
     "",
     "DESCRIPTION",
-    "    The replace operator replaces variables of ifile1 with variables from ifile2 and write",
+    "    The replace operator replaces variables of ifile1 by variables from ifile2 and write",
     "    the result to ofile. Both input datasets need to have the same number of timesteps.",
     NULL
 };
 
+static char *DuplicateHelp[] = {
+    "NAME",
+    "    duplicate - Duplicates a dataset",
+    "",
+    "SYNOPSIS",
+    "    duplicate[,ndup]  ifile ofile",
+    "",
+    "DESCRIPTION",
+    "    This operator duplicates the contents of ifile and writes the result to ofile.",
+    "    The optional parameter sets the number of duplicates, the default is 1.",
+    "",
+    "PARAMETER",
+    "    ndup  INTEGER  Number of duplicates, default is 1.",
+    NULL
+};
+
+static char *MergegridHelp[] = {
+    "NAME",
+    "    mergegrid - Merge grid",
+    "",
+    "SYNOPSIS",
+    "    mergegrid  ifile1 ifile2 ofile",
+    "",
+    "DESCRIPTION",
+    "    Merges grid points of all variables from ifile2 to ifile1 and write the result to ofile.",
+    "    Only the non missing values of ifile2 will be used. The horizontal grid of ifile2 should ",
+    "    be smaller or equal to the grid of ifile1 and the resolution must be the same.",
+    "    Only regular rectangular grids are supported. Both input files need to have the same variables ",
+    "    and the same number of timesteps.",
+    NULL
+};
+
 static char *MergeHelp[] = {
     "NAME",
     "    merge, mergetime - Merge datasets",
@@ -362,14 +394,47 @@ static char *SplitselHelp[] = {
     NULL
 };
 
+static char *SelectHelp[] = {
+    "NAME",
+    "    select, delete - Select fields",
+    "",
+    "SYNOPSIS",
+    "    <operator>,params  ifiles ofile",
+    "",
+    "DESCRIPTION",
+    "    This module selects some fields from ifiles and writes them to ofile.",
+    "    ifiles is an unlimited number of input files. All input files need to have ",
+    "    the same structure with the same variables on different timesteps.",
+    "    The fields selected depends on the chosen parameters. Parameter is a comma",
+    "    separated list of key-value pairs.",
+    "",
+    "OPERATORS",
+    "    select  Select fields",
+    "            Selects all fields with parameters in a user given list.",
+    "    delete  Delete fields",
+    "            Deletes all fields with parameters in a user given list.",
+    "",
+    "PARAMETER",
+    "    name      STRING  Comma separated list of variable names",
+    "    param     STRING  Comma separated list of parameter identifiers",
+    "    code      INTEGER Comma separated list of code numbers",
+    "    ltype     INTEGER Comma separated list of GRIB level types",
+    "    levidx    INTEGER Comma separated list of index of levels",
+    "    level     FLOAT   Comma separated list of vertical levels",
+    "    day       INTEGER Comma separated list of days",
+    "    month     INTEGER Comma separated list of months",
+    "    year      INTEGER Comma separated list of years",
+    "    timestep  INTEGER Comma separated list of timesteps",
+    NULL
+};
+
 static char *SelvarHelp[] = {
     "NAME",
     "    selparam, delparam, selcode, delcode, selname, delname, selstdname, sellevel, ",
     "    sellevidx, selgrid, selzaxis, selltype, seltabnum - Select fields",
     "",
     "SYNOPSIS",
-    "    selparam,params  ifile ofile",
-    "    delparam,params  ifile ofile",
+    "    <operator>,params  ifile ofile",
     "    selcode,codes  ifile ofile",
     "    delcode,codes  ifile ofile",
     "    selname,names  ifile ofile",
@@ -419,7 +484,7 @@ static char *SelvarHelp[] = {
     "    codes     INTEGER  Comma separated list of code numbers",
     "    names     STRING   Comma separated list of variable names",
     "    stdnames  STRING   Comma separated list of standard names",
-    "    levels    FLOAT    Comma separated list of levels",
+    "    levels    FLOAT    Comma separated list of vertical levels",
     "    levidx    INTEGER  Comma separated list of index of levels",
     "    ltypes    INTEGER  Comma separated list of GRIB level types",
     "    grids     STRING   Comma separated list of grid names or numbers",
@@ -775,7 +840,7 @@ static char *SettimeHelp[] = {
     "    date      STRING   Date (format: YYYY-MM-DD)",
     "    time      STRING   Time (format: hh:mm:ss)",
     "    inc       STRING   Optional increment (seconds, minutes, hours, days, months, years) [default: 0hour]",
-    "    calendar  STRING   Calendar (standard, proleptic, 360days, 365days, 366days)",
+    "    calendar  STRING   Calendar (standard, proleptic_gregorian, 360_day, 365_day, 366_day)",
     "    sval      STRING   Shift value (e.g. -3hour)",
     NULL
 };
@@ -1398,17 +1463,11 @@ static char *ConsecstatHelp[] = {
 
 static char *EnsstatHelp[] = {
     "NAME",
-    "    ensmin, ensmax, enssum, ensmean, ensavg, ensvar, ensstd, enspctl - ",
-    "    Statistical values over an ensemble",
+    "    ensmin, ensmax, enssum, ensmean, ensavg, ensstd, ensstd1, ensvar, ensvar1, ",
+    "    enspctl - Statistical values over an ensemble",
     "",
     "SYNOPSIS",
-    "    ensmin  ifiles ofile",
-    "    ensmax  ifiles ofile",
-    "    enssum  ifiles ofile",
-    "    ensmean  ifiles ofile",
-    "    ensavg  ifiles ofile",
-    "    ensvar  ifiles ofile",
-    "    ensstd  ifiles ofile",
+    "    <operator>  ifiles ofile",
     "    enspctl,p  ifiles ofile",
     "",
     "DESCRIPTION",
@@ -1430,10 +1489,22 @@ static char *EnsstatHelp[] = {
     "             o(t,x) = mean{i1(t,x), i2(t,x), ..., in(t,x)}",
     "    ensavg   Ensemble average",
     "             o(t,x) = avg{i1(t,x), i2(t,x), ..., in(t,x)}",
-    "    ensvar   Ensemble variance",
-    "             o(t,x) = var{i1(t,x), i2(t,x), ..., in(t,x)}",
     "    ensstd   Ensemble standard deviation",
+    "             Divisor is n.",
+    "             ",
     "             o(t,x) = std{i1(t,x), i2(t,x), ..., in(t,x)}",
+    "    ensstd1  Ensemble standard deviation",
+    "             Divisor is (n-1).",
+    "             ",
+    "             o(t,x) = std1{i1(t,x), i2(t,x), ..., in(t,x)}",
+    "    ensvar   Ensemble variance",
+    "             Divisor is n.",
+    "             ",
+    "             o(t,x) = var{i1(t,x), i2(t,x), ..., in(t,x)}",
+    "    ensvar1  Ensemble variance",
+    "             Divisor is (n-1).",
+    "             ",
+    "             o(t,x) = var1{i1(t,x), i2(t,x), ..., in(t,x)}",
     "    enspctl  Ensemble percentiles",
     "             o(t,x) = pth percentile {i1(t,x), i2(t,x), ..., in(t,x)}",
     "",
@@ -1547,24 +1618,17 @@ static char *EnsvalHelp[] = {
 
 static char *FldstatHelp[] = {
     "NAME",
-    "    fldmin, fldmax, fldsum, fldmean, fldavg, fldvar, fldstd, fldpctl - ",
-    "    Statistical values over a field",
+    "    fldmin, fldmax, fldsum, fldmean, fldavg, fldstd, fldstd1, fldvar, fldvar1, ",
+    "    fldpctl - Statistical values over a field",
     "",
     "SYNOPSIS",
-    "    fldmin  ifile ofile",
-    "    fldmax  ifile ofile",
-    "    fldsum  ifile ofile",
-    "    fldmean  ifile ofile",
-    "    fldavg  ifile ofile",
-    "    fldvar  ifile ofile",
-    "    fldstd  ifile ofile",
+    "    <operator>  ifile ofile",
     "    fldpctl,p  ifile ofile",
     "",
     "DESCRIPTION",
-    "    This module computes statistical values of the input fields.",
-    "    According to the chosen operator the field minimum, maximum,",
-    "    sum, average, variance, standard deviation or a certain percentile",
-    "    is written to ofile.",
+    "    This module computes statistical values of the input fields. According to the chosen ",
+    "    operator the field minimum, maximum, sum, average, variance, standard deviation or ",
+    "    a certain percentile is written to ofile.",
     "",
     "OPERATORS",
     "    fldmin   Field minimum",
@@ -1589,15 +1653,25 @@ static char *FldstatHelp[] = {
     "             ",
     "             o(t,1) = avg{i(t,x'), x_1<x'<=x_n}",
     "             weighted by area weights obtained by the input field.",
+    "    fldstd   Field standard deviation",
+    "             Divisor is n. For every gridpoint x_1, ..., x_n of the same field it is:",
+    "             ",
+    "             o(t,1) = std{i(t,x'), x_1<x'<=x_n}",
+    "             weighted by area weights obtained by the input field.",
+    "    fldstd1  Field standard deviation",
+    "             Divisor is (n-1). For every gridpoint x_1, ..., x_n of the same field it is:",
+    "             ",
+    "             o(t,1) = std1{i(t,x'), x_1<x'<=x_n}",
+    "             weighted by area weights obtained by the input field.",
     "    fldvar   Field variance",
-    "             For every gridpoint x_1, ..., x_n of the same field it is:",
+    "             Divisor is n. For every gridpoint x_1, ..., x_n of the same field it is:",
     "             ",
     "             o(t,1) = var{i(t,x'), x_1<x'<=x_n}",
     "             weighted by area weights obtained by the input field.",
-    "    fldstd   Field standard deviation",
-    "             For every gridpoint x_1, ..., x_n of the same field it is:",
+    "    fldvar1  Field variance",
+    "             Divisor is (n-1). For every gridpoint x_1, ..., x_n of the same field it is:",
     "             ",
-    "             o(t,1) = std{i(t,x'), x_1<x'<=x_n}",
+    "             o(t,1) = var1{i(t,x'), x_1<x'<=x_n}",
     "             weighted by area weights obtained by the input field.",
     "    fldpctl  Field percentiles",
     "             For every gridpoint x_1, ..., x_n of the same field it is:",
@@ -1615,13 +1689,7 @@ static char *ZonstatHelp[] = {
     "    Zonal statistical values",
     "",
     "SYNOPSIS",
-    "    zonmin  ifile ofile",
-    "    zonmax  ifile ofile",
-    "    zonsum  ifile ofile",
-    "    zonmean  ifile ofile",
-    "    zonavg  ifile ofile",
-    "    zonvar  ifile ofile",
-    "    zonstd  ifile ofile",
+    "    <operator>  ifile ofile",
     "    zonpctl,p  ifile ofile",
     "",
     "DESCRIPTION",
@@ -1629,7 +1697,7 @@ static char *ZonstatHelp[] = {
     "    According to the chosen operator the zonal minimum, maximum, ",
     "    sum, average, variance, standard deviation or a certain percentile",
     "    is written to ofile. All input fields need to have the same",
-    "    regular lonlat grid. ",
+    "    regular lon/lat grid. ",
     "",
     "OPERATORS",
     "    zonmin   Zonal minimum",
@@ -1660,13 +1728,7 @@ static char *MerstatHelp[] = {
     "    Meridional statistical values",
     "",
     "SYNOPSIS",
-    "    mermin  ifile ofile",
-    "    mermax  ifile ofile",
-    "    mersum  ifile ofile",
-    "    mermean  ifile ofile",
-    "    meravg  ifile ofile",
-    "    mervar  ifile ofile",
-    "    merstd  ifile ofile",
+    "    <operator>  ifile ofile",
     "    merpctl,p  ifile ofile",
     "",
     "DESCRIPTION",
@@ -1761,18 +1823,17 @@ static char *VertstatHelp[] = {
 
 static char *TimselstatHelp[] = {
     "NAME",
-    "    timselmin, timselmax, timselsum, timselmean, timselavg, timselvar, timselstd - ",
-    "    Time range statistical values",
+    "    timselmin, timselmax, timselsum, timselmean, timselavg, timselstd, ",
+    "    timselstd1, timselvar, timselvar1 - Time range statistical values",
     "",
     "SYNOPSIS",
     "    <operator>,nsets[,noffset[,nskip]]  ifile ofile",
     "",
     "DESCRIPTION",
-    "    This module computes statistical values for a selected number of timesteps.",
-    "    According to the chosen operator the minimum, maximum, sum, average,",
-    "    variance or standard deviation of the selected timesteps is written to ofile.",
-    "    The date information of a timestep in ofile is the date of the last ",
-    "    contributing timestep in ifile.",
+    "    This module computes statistical values for a selected number of timesteps. According to ",
+    "    the chosen operator the minimum, maximum, sum, average, variance or standard deviation of ",
+    "    the selected timesteps is written to ofile.",
+    "    The date information of a timestep in ofile is the date of the last contributing timestep in ifile.",
     "",
     "OPERATORS",
     "    timselmin   Time range minimum",
@@ -1800,16 +1861,26 @@ static char *TimselstatHelp[] = {
     "                selected time range it is",
     "                ",
     "                o(t,x) = avg{i(t',x), t1 < t' <= tn}",
+    "    timselstd   Time range standard deviation",
+    "                Divisor is n. For every adjacent sequence t1, ...., tn of timesteps of the same ",
+    "                selected time range it is",
+    "                ",
+    "                o(t,x) = std{i(t',x), t1 < t' <= tn}",
+    "    timselstd1  Time range standard deviation",
+    "                Divisor is (n-1). For every adjacent sequence t1, ...., tn of timesteps of the same ",
+    "                selected time range it is",
+    "                ",
+    "                o(t,x) = std1{i(t',x), t1 < t' <= tn}",
     "    timselvar   Time range variance",
-    "                For every adjacent sequence t1, ...., tn of timesteps of the same ",
+    "                Divisor is n. For every adjacent sequence t1, ...., tn of timesteps of the same ",
     "                selected time range it is",
     "                ",
     "                o(t,x) = var{i(t',x), t1 < t' <= tn}",
-    "    timselstd   Time range standard deviation",
-    "                For every adjacent sequence t1, ...., tn of timesteps of the same ",
+    "    timselvar1  Time range variance",
+    "                Divisor is (n-1). For every adjacent sequence t1, ...., tn of timesteps of the same ",
     "                selected time range it is",
     "                ",
-    "                o(t,x) = std{i(t',x), t1 < t' <= tn}",
+    "                o(t,x) = var1{i(t',x), t1 < t' <= tn}",
     "",
     "PARAMETER",
     "    nsets    INTEGER  Number of input timesteps for each output timestep ",
@@ -1826,16 +1897,12 @@ static char *TimselpctlHelp[] = {
     "    timselpctl,p,nsets[,noffset[,nskip]]  ifile1 ifile2 ifile3 ofile",
     "",
     "DESCRIPTION",
-    "    This operator computes percentile values over a selected number of time",
-    "    steps in ifile1.",
-    "    The algorithm uses histograms with minimum and maximum bounds given in",
-    "    ifile2 and ifile3, respectively. The default number of",
-    "    histogram bins is 101. The default can be overridden by setting the",
-    "    environment variable CDO_PCTL_NBINS to a different value. The files",
-    "    ifile2 and ifile3 should be the result of corresponding",
-    "    timselmin and timselmax operations, respectively.",
-    "    The date information of a timestep in ofile is the date of the last ",
-    "    contributing timestep in ifile.",
+    "    This operator computes percentile values over a selected number of time steps in ifile1.",
+    "    The algorithm uses histograms with minimum and maximum bounds given in ifile2 and ifile3,",
+    "    respectively. The default number of histogram bins is 101. The default can be overridden by setting the",
+    "    environment variable CDO_PCTL_NBINS to a different value. The files ifile2 and ifile3 ",
+    "    should be the result of corresponding timselmin and timselmax operations, respectively.",
+    "    The date information of a timestep in ofile is the date of the last contributing timestep in ifile.",
     "    For every adjacent sequence t1, ...., tn of timesteps of the same ",
     "    selected time range it is",
     "    ",
@@ -1855,18 +1922,17 @@ static char *TimselpctlHelp[] = {
 
 static char *RunstatHelp[] = {
     "NAME",
-    "    runmin, runmax, runsum, runmean, runavg, runvar, runstd - ",
+    "    runmin, runmax, runsum, runmean, runavg, runstd, runstd1, runvar, runvar1 - ",
     "    Running statistical values",
     "",
     "SYNOPSIS",
     "    <operator>,nts  ifile ofile",
     "",
     "DESCRIPTION",
-    "    This module computes running statistical values over a selected number",
-    "    of timesteps. Depending on the chosen operator the minimum, maximum,",
-    "    sum, average, variance or standard deviation of a selected number of consecutive ",
-    "    timesteps read from ifile is written to ofile. The date information ",
-    "    in ofile is the date of the middle contributing timestep in ifile.",
+    "    This module computes running statistical values over a selected number of timesteps. Depending on ",
+    "    the chosen operator the minimum, maximum, sum, average, variance or standard deviation of a selected ",
+    "    number of consecutive timesteps read from ifile is written to ofile. ",
+    "    The date information in ofile is the date of the middle contributing timestep in ifile.",
     "",
     "OPERATORS",
     "    runmin   Running minimum",
@@ -1879,18 +1945,29 @@ static char *RunstatHelp[] = {
     "             o(t+(nts-1)/2,x) = mean{i(t,x), i(t+1,x), ..., i(t+nts-1,x)}",
     "    runavg   Running average",
     "             o(t+(nts-1)/2,x) = avg{i(t,x), i(t+1,x), ..., i(t+nts-1,x)}",
-    "    runvar   Running variance",
-    "             o(t+(nts-1)/2,x) = var{i(t,x), i(t+1,x), ..., i(t+nts-1,x)}",
     "    runstd   Running standard deviation",
+    "             Divisor is n. ",
+    "             ",
     "             o(t+(nts-1)/2,x) = std{i(t,x), i(t+1,x), ..., i(t+nts-1,x)}",
+    "    runstd1  Running standard deviation",
+    "             Divisor is (n-1). ",
+    "             ",
+    "             o(t+(nts-1)/2,x) = std1{i(t,x), i(t+1,x), ..., i(t+nts-1,x)}",
+    "    runvar   Running variance",
+    "             Divisor is n. ",
+    "             ",
+    "             o(t+(nts-1)/2,x) = var{i(t,x), i(t+1,x), ..., i(t+nts-1,x)}",
+    "    runvar1  Running variance",
+    "             Divisor is (n-1). ",
+    "             ",
+    "             o(t+(nts-1)/2,x) = var1{i(t,x), i(t+1,x), ..., i(t+nts-1,x)}",
     "",
     "PARAMETER",
     "    nts  INTEGER  Number of timesteps",
     "",
     "ENVIRONMENT",
-    "    RUNSTAT_DATE",
-    "        Sets the date information in ofile to the \"first\", \"last\" or \"middle\" contributing",
-    "        timestep in ifile.",
+    "    TIMESTAT_DATE",
+    "        Sets the date information in ofile to the \"first\", \"last\" or \"middle\" contributing timestep in ifile.",
     NULL
 };
 
@@ -1902,10 +1979,8 @@ static char *RunpctlHelp[] = {
     "    runpctl,p,nts  ifile1 ofile",
     "",
     "DESCRIPTION",
-    "    This module computes running percentiles over a selected number of time",
-    "    steps in ifile1.",
-    "    The date information in ofile is the date of the medium contributing",
-    "    timestep in ifile1.",
+    "    This module computes running percentiles over a selected number of time steps in ifile1.",
+    "    The date information in ofile is the date of the medium contributing timestep in ifile1.",
     "    ",
     "    o(t+(nts-1)/2,x) = pth percentile {i(t,x), i(t+1,x), ..., i(t+nts-1,x)}",
     "",
@@ -1917,18 +1992,17 @@ static char *RunpctlHelp[] = {
 
 static char *TimstatHelp[] = {
     "NAME",
-    "    timmin, timmax, timsum, timmean, timavg, timvar, timstd - ",
+    "    timmin, timmax, timsum, timmean, timavg, timstd, timstd1, timvar, timvar1 - ",
     "    Statistical values over all timesteps",
     "",
     "SYNOPSIS",
     "    <operator>  ifile ofile",
     "",
     "DESCRIPTION",
-    "    This module computes statistical  values over all timesteps in ifile.",
-    "    Depending on the chosen operator the minimum, maximum, sum, average, variance",
-    "    or standard deviation of all timesteps read from ifile is written to ofile.",
-    "    The date information of a timestep in ofile is the date of the last ",
-    "    contributing timestep in ifile.",
+    "    This module computes statistical  values over all timesteps in ifile. Depending on ",
+    "    the chosen operator the minimum, maximum, sum, average, variance or standard deviation of ",
+    "    all timesteps read from ifile is written to ofile.",
+    "    The date information of a timestep in ofile is the date of the last contributing timestep in ifile.",
     "",
     "OPERATORS",
     "    timmin   Time minimum",
@@ -1941,10 +2015,22 @@ static char *TimstatHelp[] = {
     "             o(1,x) = mean{i(t',x), t_1<t'<=t_n}",
     "    timavg   Time average",
     "             o(1,x) = avg{i(t',x), t_1<t'<=t_n}",
-    "    timvar   Time variance",
-    "             o(1,x) = var{i(t',x), t_1<t'<=t_n}",
     "    timstd   Time standard deviation",
+    "             Divisor is n. ",
+    "             ",
     "             o(1,x) = std{i(t',x), t_1<t'<=t_n}",
+    "    timstd1  Time standard deviation",
+    "             Divisor is (n-1). ",
+    "             ",
+    "             o(1,x) = std1{i(t',x), t_1<t'<=t_n}",
+    "    timvar   Time variance",
+    "             Divisor is n. ",
+    "             ",
+    "             o(1,x) = var{i(t',x), t_1<t'<=t_n}",
+    "    timvar1  Time variance",
+    "             Divisor is (n-1). ",
+    "             ",
+    "             o(1,x) = var1{i(t',x), t_1<t'<=t_n}",
     NULL
 };
 
@@ -1979,8 +2065,8 @@ static char *TimpctlHelp[] = {
 
 static char *HourstatHelp[] = {
     "NAME",
-    "    hourmin, hourmax, hoursum, hourmean, houravg, hourvar, hourstd - ",
-    "    Hourly statistical values",
+    "    hourmin, hourmax, hoursum, hourmean, houravg, hourstd, hourstd1, hourvar, ",
+    "    hourvar1 - Hourly statistical values",
     "",
     "SYNOPSIS",
     "    <operator>  ifile ofile",
@@ -2013,14 +2099,22 @@ static char *HourstatHelp[] = {
     "              For every adjacent sequence t_1, ...,t_n of timesteps of the same hour it is:",
     "              ",
     "              o(t,x) = avg{i(t',x), t_1<t'<=t_n}",
+    "    hourstd   Hourly standard deviation",
+    "              Divisor is n. For every adjacent sequence t_1, ...,t_n of timesteps of the same hour it is:",
+    "              ",
+    "              o(t,x) = std{i(t',x), t_1<t'<=t_n}",
+    "    hourstd1  Hourly standard deviation",
+    "              Divisor is (n-1). For every adjacent sequence t_1, ...,t_n of timesteps of the same hour it is:",
+    "              ",
+    "              o(t,x) = std1{i(t',x), t_1<t'<=t_n}",
     "    hourvar   Hourly variance",
-    "              For every adjacent sequence t_1, ...,t_n of timesteps of the same hour it is:",
+    "              Divisor is n. For every adjacent sequence t_1, ...,t_n of timesteps of the same hour it is:",
     "              ",
     "              o(t,x) = var{i(t',x), t_1<t'<=t_n}",
-    "    hourstd   Hourly standard deviation",
-    "              For every adjacent sequence t_1, ...,t_n of timesteps of the same hour it is:",
+    "    hourvar1  Hourly variance",
+    "              Divisor is (n-1). For every adjacent sequence t_1, ...,t_n of timesteps of the same hour it is:",
     "              ",
-    "              o(t,x) = std{i(t',x), t_1<t'<=t_n}",
+    "              o(t,x) = var1{i(t',x), t_1<t'<=t_n}",
     NULL
 };
 
@@ -2056,7 +2150,7 @@ static char *HourpctlHelp[] = {
 
 static char *DaystatHelp[] = {
     "NAME",
-    "    daymin, daymax, daysum, daymean, dayavg, dayvar, daystd - ",
+    "    daymin, daymax, daysum, daymean, dayavg, daystd, daystd1, dayvar, dayvar1 - ",
     "    Daily statistical values",
     "",
     "SYNOPSIS",
@@ -2090,14 +2184,22 @@ static char *DaystatHelp[] = {
     "             For every adjacent sequence t_1, ...,t_n of timesteps of the same day it is",
     "             ",
     "             o(t,x) = avg{i(t',x), t_1<t'<=t_n}",
+    "    daystd   Daily standard deviation",
+    "             Divisor is n. For every adjacent sequence t_1, ...,t_n of timesteps of the same day it is",
+    "             ",
+    "             o(t,x) = std{i(t',x), t_1<t'<=t_n}",
+    "    daystd1  Daily standard deviation",
+    "             Divisor is (n-1). For every adjacent sequence t_1, ...,t_n of timesteps of the same day it is",
+    "             ",
+    "             o(t,x) = std1{i(t',x), t_1<t'<=t_n}",
     "    dayvar   Daily variance",
-    "             For every adjacent sequence t_1, ...,t_n of timesteps of the same day it is",
+    "             Divisor is n. For every adjacent sequence t_1, ...,t_n of timesteps of the same day it is",
     "             ",
     "             o(t,x) = var{i(t',x), t_1<t'<=t_n}",
-    "    daystd   Daily standard deviation",
-    "             For every adjacent sequence t_1, ...,t_n of timesteps of the same day it is",
+    "    dayvar1  Daily variance",
+    "             Divisor is (n-1). For every adjacent sequence t_1, ...,t_n of timesteps of the same day it is",
     "             ",
-    "             o(t,x) = std{i(t',x), t_1<t'<=t_n}",
+    "             o(t,x) = var1{i(t',x), t_1<t'<=t_n}",
     NULL
 };
 
@@ -2133,7 +2235,7 @@ static char *DaypctlHelp[] = {
 
 static char *MonstatHelp[] = {
     "NAME",
-    "    monmin, monmax, monsum, monmean, monavg, monvar, monstd - ",
+    "    monmin, monmax, monsum, monmean, monavg, monstd, monstd1, monvar, monvar1 - ",
     "    Monthly statistical values",
     "",
     "SYNOPSIS",
@@ -2167,14 +2269,22 @@ static char *MonstatHelp[] = {
     "             For every adjacent sequence t_1, ...,t_n of timesteps of the same month it is",
     "             ",
     "             o(t,x) = avg{i(t',x), t_1<t'<=t_n}",
+    "    monstd   Monthly standard deviation",
+    "             Divisor is n. For every adjacent sequence t_1, ...,t_n of timesteps of the same month it is",
+    "             ",
+    "             o(t,x) = std{i(t',x), t_1 < t' <= t_n}",
+    "    monstd1  Monthly standard deviation",
+    "             Divisor is (n-1). For every adjacent sequence t_1, ...,t_n of timesteps of the same month it is",
+    "             ",
+    "             o(t,x) = std1{i(t',x), t_1 < t' <= t_n}",
     "    monvar   Monthly variance",
-    "             For every adjacent sequence t_1, ...,t_n of timesteps of the same month it is",
+    "             Divisor is n. For every adjacent sequence t_1, ...,t_n of timesteps of the same month it is",
     "             ",
     "             o(t,x) = var{i(t',x), t_1 < t' <= t_n}",
-    "    monstd   Monthly standard deviation",
-    "             For every adjacent sequence t_1, ...,t_n of timesteps of the same month it is",
+    "    monvar1  Monthly variance",
+    "             Divisor is (n-1). For every adjacent sequence t_1, ...,t_n of timesteps of the same month it is",
     "             ",
-    "             o(t,x) = std{i(t',x), t_1 < t' <= t_n}",
+    "             o(t,x) = var1{i(t',x), t_1 < t' <= t_n}",
     NULL
 };
 
@@ -2208,10 +2318,32 @@ static char *MonpctlHelp[] = {
     NULL
 };
 
+static char *YearmonmeanHelp[] = {
+    "NAME",
+    "    yearmonmean - Yearly mean from monthly data",
+    "",
+    "SYNOPSIS",
+    "    yearmonmean  ifile ofile",
+    "",
+    "DESCRIPTION",
+    "    This operator computes the yearly mean of a monthly time series.",
+    "    Each month is weighted with the number of days per month. ",
+    "    The date information in ofile is the date of the middle contributing timestep in ifile.",
+    "    ",
+    "    For every adjacent sequence t_1, ...,t_n of timesteps of the same year it is",
+    "    ",
+    "    o(t,x) = mean{i(t',x), t_1<t'<=t_n}",
+    "",
+    "ENVIRONMENT",
+    "    TIMESTAT_DATE",
+    "        Sets the date information in ofile to the \"first\", \"last\" or \"middle\" contributing timestep in ifile.",
+    NULL
+};
+
 static char *YearstatHelp[] = {
     "NAME",
-    "    yearmin, yearmax, yearsum, yearmean, yearavg, yearvar, yearstd - ",
-    "    Yearly statistical values",
+    "    yearmin, yearmax, yearsum, yearmean, yearavg, yearstd, yearstd1, yearvar, ",
+    "    yearvar1 - Yearly statistical values",
     "",
     "SYNOPSIS",
     "    <operator>  ifile ofile",
@@ -2244,14 +2376,22 @@ static char *YearstatHelp[] = {
     "              For every adjacent sequence t_1, ...,t_n of timesteps of the same year it is",
     "              ",
     "              o(t,x) = avg{i(t',x), t_1<t'<=t_n}",
+    "    yearstd   Yearly standard deviation",
+    "              Divisor is n. For every adjacent sequence t_1, ...,t_n of timesteps of the same year it is",
+    "              ",
+    "              o(t,x) = std{i(t',x), t_1 < t' <= t_n}",
+    "    yearstd1  Yearly standard deviation",
+    "              Divisor is (n-1). For every adjacent sequence t_1, ...,t_n of timesteps of the same year it is",
+    "              ",
+    "              o(t,x) = std1{i(t',x), t_1 < t' <= t_n}",
     "    yearvar   Yearly variance",
-    "              For every adjacent sequence t_1, ...,t_n of timesteps of the same year it is",
+    "              Divisor is n. For every adjacent sequence t_1, ...,t_n of timesteps of the same year it is",
     "              ",
     "              o(t,x) = var{i(t',x), t_1 < t' <= t_n}",
-    "    yearstd   Yearly standard deviation",
-    "              For every adjacent sequence t_1, ...,t_n of timesteps of the same year it is",
+    "    yearvar1  Yearly variance",
+    "              Divisor is (n-1). For every adjacent sequence t_1, ...,t_n of timesteps of the same year it is",
     "              ",
-    "              o(t,x) = std{i(t',x), t_1 < t' <= t_n}",
+    "              o(t,x) = var1{i(t',x), t_1 < t' <= t_n}",
     NULL
 };
 
@@ -2368,8 +2508,8 @@ static char *SeaspctlHelp[] = {
 
 static char *YhourstatHelp[] = {
     "NAME",
-    "    yhourmin, yhourmax, yhoursum, yhourmean, yhouravg, yhourvar, yhourstd - ",
-    "    Multi-year hourly statistical values",
+    "    yhourmin, yhourmax, yhoursum, yhourmean, yhouravg, yhourstd, yhourstd1, ",
+    "    yhourvar, yhourvar1 - Multi-year hourly statistical values",
     "",
     "SYNOPSIS",
     "    <operator>  ifile ofile",
@@ -2401,21 +2541,37 @@ static char *YhourstatHelp[] = {
     "               o(0001,x) = avg{i(t,x), day(i(t)) = 0001}",
     "                                ...",
     "               o(8784,x) = avg{i(t,x), day(i(t)) = 8784}",
+    "    yhourstd   Multi-year hourly standard deviation",
+    "               Divisor is n. ",
+    "               ",
+    "               o(0001,x) = std{i(t,x), day(i(t)) = 0001}",
+    "                                ...",
+    "               o(8784,x) = std{i(t,x), day(i(t)) = 8784}",
+    "    yhourstd1  Multi-year hourly standard deviation",
+    "               Divisor is (n-1). ",
+    "               ",
+    "               o(0001,x) = std1{i(t,x), day(i(t)) = 0001}",
+    "                                ...",
+    "               o(8784,x) = std1{i(t,x), day(i(t)) = 8784}",
     "    yhourvar   Multi-year hourly variance",
+    "               Divisor is n. ",
+    "               ",
     "               o(0001,x) = var{i(t,x), day(i(t)) = 0001}",
     "                                ...",
     "               o(8784,x) = var{i(t,x), day(i(t)) = 8784}",
-    "    yhourstd   Multi-year hourly standard deviation",
-    "               o(0001,x) = std{i(t,x), day(i(t)) = 0001}",
+    "    yhourvar1  Multi-year hourly variance",
+    "               Divisor is (n-1). ",
+    "               ",
+    "               o(0001,x) = var1{i(t,x), day(i(t)) = 0001}",
     "                                ...",
-    "               o(8784,x) = std{i(t,x), day(i(t)) = 8784}",
+    "               o(8784,x) = var1{i(t,x), day(i(t)) = 8784}",
     NULL
 };
 
 static char *YdaystatHelp[] = {
     "NAME",
-    "    ydaymin, ydaymax, ydaysum, ydaymean, ydayavg, ydayvar, ydaystd - ",
-    "    Multi-year daily statistical values",
+    "    ydaymin, ydaymax, ydaysum, ydaymean, ydayavg, ydaystd, ydaystd1, ydayvar, ",
+    "    ydayvar1 - Multi-year daily statistical values",
     "",
     "SYNOPSIS",
     "    <operator>  ifile ofile",
@@ -2447,14 +2603,30 @@ static char *YdaystatHelp[] = {
     "              o(001,x) = avg{i(t,x), day(i(t)) = 001}",
     "                               ...",
     "              o(366,x) = avg{i(t,x), day(i(t)) = 366}",
+    "    ydaystd   Multi-year daily standard deviation",
+    "              Divisor is n. ",
+    "              ",
+    "              o(001,x) = std{i(t,x), day(i(t)) = 001}",
+    "                               ...",
+    "              o(366,x) = std{i(t,x), day(i(t)) = 366}",
+    "    ydaystd1  Multi-year daily standard deviation",
+    "              Divisor is (n-1). ",
+    "              ",
+    "              o(001,x) = std1{i(t,x), day(i(t)) = 001}",
+    "                               ...",
+    "              o(366,x) = std1{i(t,x), day(i(t)) = 366}",
     "    ydayvar   Multi-year daily variance",
+    "              Divisor is n. ",
+    "              ",
     "              o(001,x) = var{i(t,x), day(i(t)) = 001}",
     "                               ...",
     "              o(366,x) = var{i(t,x), day(i(t)) = 366}",
-    "    ydaystd   Multi-year daily standard deviation",
-    "              o(001,x) = std{i(t,x), day(i(t)) = 001}",
+    "    ydayvar1  Multi-year daily variance",
+    "              Divisor is (n-1). ",
+    "              ",
+    "              o(001,x) = var1{i(t,x), day(i(t)) = 001}",
     "                               ...",
-    "              o(366,x) = std{i(t,x), day(i(t)) = 366}",
+    "              o(366,x) = var1{i(t,x), day(i(t)) = 366}",
     NULL
 };
 
@@ -2491,8 +2663,8 @@ static char *YdaypctlHelp[] = {
 
 static char *YmonstatHelp[] = {
     "NAME",
-    "    ymonmin, ymonmax, ymonsum, ymonmean, ymonavg, ymonvar, ymonstd - ",
-    "    Multi-year monthly statistical values",
+    "    ymonmin, ymonmax, ymonsum, ymonmean, ymonavg, ymonstd, ymonstd1, ymonvar, ",
+    "    ymonvar1 - Multi-year monthly statistical values",
     "",
     "SYNOPSIS",
     "    <operator>  ifile ofile",
@@ -2524,14 +2696,30 @@ static char *YmonstatHelp[] = {
     "              o(01,x) = avg{i(t,x), month(i(t)) = 01}",
     "                               ...",
     "              o(12,x) = avg{i(t,x), month(i(t)) = 12}",
+    "    ymonstd   Multi-year monthly standard deviation",
+    "              Divisor is n. ",
+    "              ",
+    "              o(01,x) = std{i(t,x), month(i(t)) = 01}",
+    "                               ...",
+    "              o(12,x) = std{i(t,x), month(i(t)) = 12}",
+    "    ymonstd1  Multi-year monthly standard deviation",
+    "              Divisor is (n-1). ",
+    "              ",
+    "              o(01,x) = std1{i(t,x), month(i(t)) = 01}",
+    "                               ...",
+    "              o(12,x) = std1{i(t,x), month(i(t)) = 12}",
     "    ymonvar   Multi-year monthly variance",
+    "              Divisor is n. ",
+    "              ",
     "              o(01,x) = var{i(t,x), month(i(t)) = 01}",
     "                               ...",
     "              o(12,x) = var{i(t,x), month(i(t)) = 12}",
-    "    ymonstd   Multi-year monthly standard deviation",
-    "              o(01,x) = std{i(t,x), month(i(t)) = 01}",
+    "    ymonvar1  Multi-year monthly variance",
+    "              Divisor is (n-1). ",
+    "              ",
+    "              o(01,x) = var1{i(t,x), month(i(t)) = 01}",
     "                               ...",
-    "              o(12,x) = std{i(t,x), month(i(t)) = 12}",
+    "              o(12,x) = var1{i(t,x), month(i(t)) = 12}",
     NULL
 };
 
@@ -2653,8 +2841,8 @@ static char *YseaspctlHelp[] = {
 
 static char *YdrunstatHelp[] = {
     "NAME",
-    "    ydrunmin, ydrunmax, ydrunsum, ydrunmean, ydrunavg, ydrunvar, ydrunstd - ",
-    "    Multi-year daily running statistical values",
+    "    ydrunmin, ydrunmax, ydrunsum, ydrunmean, ydrunavg, ydrunstd, ydrunstd1, ",
+    "    ydrunvar, ydrunvar1 - Multi-year daily running statistical values",
     "",
     "SYNOPSIS",
     "    <operator>,nts  ifile ofile",
@@ -2696,14 +2884,30 @@ static char *YdrunstatHelp[] = {
     "               o(001,x) = avg{i(t,x), i(t+1,x), ..., i(t+nts-1,x); day[(i(t+(nts-1)/2)] = 001}",
     "                                ...",
     "               o(366,x) = avg{i(t,x), i(t+1,x), ..., i(t+nts-1,x); day[(i(t+(nts-1)/2)] = 366}",
+    "    ydrunstd   Multi-year daily running standard deviation",
+    "               Divisor is n. ",
+    "               ",
+    "               o(001,x) = std{i(t,x), i(t+1,x), ..., i(t+nts-1,x); day[i(t+(nts-1)/2)] = 001}",
+    "                                ...",
+    "               o(366,x) = std{i(t,x), i(t+1,x), ..., i(t+nts-1,x); day[i(t+(nts-1)/2)] = 366}",
+    "    ydrunstd1  Multi-year daily running standard deviation",
+    "               Divisor is (n-1). ",
+    "               ",
+    "               o(001,x) = std1{i(t,x), i(t+1,x), ..., i(t+nts-1,x); day[i(t+(nts-1)/2)] = 001}",
+    "                                ...",
+    "               o(366,x) = std1{i(t,x), i(t+1,x), ..., i(t+nts-1,x); day[i(t+(nts-1)/2)] = 366}",
     "    ydrunvar   Multi-year daily running variance",
+    "               Divisor is n. ",
+    "               ",
     "               o(001,x) = var{i(t,x), i(t+1,x), ..., i(t+nts-1,x); day[(i(t+(nts-1)/2)] = 001}",
     "                                ...",
     "               o(366,x) = var{i(t,x), i(t+1,x), ..., i(t+nts-1,x); day[(i(t+(nts-1)/2)] = 366}",
-    "    ydrunstd   Multi-year daily running standard deviation",
-    "               o(001,x) = std{i(t,x), i(t+1,x), ..., i(t+nts-1,x); day[i(t+(nts-1)/2)] = 001}",
+    "    ydrunvar1  Multi-year daily running variance",
+    "               Divisor is (n-1). ",
+    "               ",
+    "               o(001,x) = var1{i(t,x), i(t+1,x), ..., i(t+nts-1,x); day[(i(t+(nts-1)/2)] = 001}",
     "                                ...",
-    "               o(366,x) = std{i(t,x), i(t+1,x), ..., i(t+nts-1,x); day[i(t+(nts-1)/2)] = 366}",
+    "               o(366,x) = var1{i(t,x), i(t+1,x), ..., i(t+nts-1,x); day[(i(t+(nts-1)/2)] = 366}",
     "",
     "PARAMETER",
     "    nts  INTEGER  Number of timesteps",
@@ -3024,8 +3228,7 @@ static char *RemapgridHelp[] = {
     "ENVIRONMENT",
     "    REMAP_EXTRAPOLATE",
     "        This variable is used to switch the extrapolation feature 'on' or 'off'.",
-    "        By default the extrapolation is enabled for remapdis, remapnn",
-    "        and for circular grids.",
+    "        By default the extrapolation is enabled for remapdis, remapnn and for circular grids.",
     "    REMAP_AREA_MIN   ",
     "        This variable is used to set the minimum destination area fraction. The default",
     "        of this variable is 0.0.",
@@ -3110,8 +3313,7 @@ static char *RemapHelp[] = {
     "ENVIRONMENT",
     "    REMAP_EXTRAPOLATE",
     "        This variable is used to switch the extrapolation feature 'on' or 'off'.",
-    "        By default the extrapolation is enabled for remapdis, remapnn",
-    "        and for circular grids.",
+    "        By default the extrapolation is enabled for remapdis, remapnn and for circular grids.",
     "    REMAP_AREA_MIN   ",
     "        This variable is used to set the minimum destination area fraction. The default",
     "        of this variable is 0.0.",
@@ -3307,10 +3509,7 @@ static char *SpectralHelp[] = {
     "    sp2gp, sp2gpl, gp2sp, gp2spl, sp2sp - Spectral transformation",
     "",
     "SYNOPSIS",
-    "    sp2gp  ifile ofile",
-    "    sp2gpl  ifile ofile",
-    "    gp2sp  ifile ofile",
-    "    gp2spl  ifile ofile",
+    "    <operator>  ifile ofile",
     "    sp2sp,trunc  ifile ofile",
     "",
     "DESCRIPTION",
@@ -3758,15 +3957,12 @@ static char *VargenHelp[] = {
     "    stdatm,levels  ofile",
     "",
     "DESCRIPTION",
-    "    Generates a dataset with one or more fields. The field size",
-    "    is specified by the user given grid description.",
-    "    According to the chosen operator all field elements",
-    "    are constant or filled with random numbers.",
+    "    Generates a dataset with one or more fields. The field size is specified by the user given grid description.",
+    "    According to the chosen operator all field elements are constant or filled with random numbers.",
     "",
     "OPERATORS",
     "    const   Create a constant field",
-    "            Creates a constant field. All field elements of the grid",
-    "            have the same value.",
+    "            Creates a constant field. All field elements of the grid have the same value.",
     "    random  Create a field with random numbers",
     "            Creates a field with rectangularly distrubuted random numbers in the interval [0,1].",
     "    stdatm  Create values for pressure and temperature for hydrostatic atmosphere",
@@ -3823,10 +4019,46 @@ static char *MastrfuHelp[] = {
     "    mastrfu  ifile ofile",
     "",
     "DESCRIPTION",
-    "    This is a special operator for the post processing of the atmospheric ",
-    "    general circulation model ECHAM. It computes the mass stream function ",
-    "    (code number 272). The input dataset have to be a zonal mean of v-velocity [m/s]",
-    "    (code number 132) on pressure levels.",
+    "    This is a special operator for the post processing of the atmospheric general circulation",
+    "    model ECHAM. It computes the mass stream function (code=272). The input dataset have ",
+    "    to be a zonal mean of v-velocity [m/s] (code=132) on pressure levels.",
+    NULL
+};
+
+static char *AdisitHelp[] = {
+    "NAME",
+    "    adisit - Potential temperature to in-situ temperature",
+    "",
+    "SYNOPSIS",
+    "    adisit[,pressure]  ifile ofile",
+    "",
+    "DESCRIPTION",
+    "    This is a special operator for the post processing of the ocean and sea ice model MPIOM.",
+    "    It converts potential temperature adiabatically to in-situ temperature to(tho, sao, p).",
+    "    Required input fields are sea water potential temperature (name=tho; code=2) and sea water salinity (name=sao; code=5).",
+    "    Pressure is calculated from the level information or can be specified by the optional parameter.",
+    "    Output fields are sea water temperature (name=to; code=20) and sea water salinity (name=sao; code=5).",
+    "",
+    "PARAMETER",
+    "    pressure  FLOAT   Pressure in bar (constant value assigned to all levels)",
+    NULL
+};
+
+static char *RhopotHelp[] = {
+    "NAME",
+    "    rhopot - Calculates potential density",
+    "",
+    "SYNOPSIS",
+    "    rhopot[,pressure]  ifile ofile",
+    "",
+    "DESCRIPTION",
+    "    This is a special operator for the post processing of the ocean and sea ice model MPIOM.",
+    "    It calculates the sea water potential density (name=rhopoto; code=18). Required input fields ",
+    "    are sea water in-situ temperature (name=to; code=20) and sea water salinity (name=sao; code=5).",
+    "    Pressure is calculated from the level information or can be specified by the optional parameter.",
+    "",
+    "PARAMETER",
+    "    pressure  FLOAT   Pressure in bar (constant value assigned to all levels)",
     NULL
 };
 
diff --git a/src/pipe.c b/src/pipe.c
index 82b57c7..86e14e8 100644
--- a/src/pipe.c
+++ b/src/pipe.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/pipe.h b/src/pipe.h
index ed460ca..324a5c4 100644
--- a/src/pipe.h
+++ b/src/pipe.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/printinfo.h b/src/printinfo.h
index cb1bd9a..c7ab8e7 100644
--- a/src/printinfo.h
+++ b/src/printinfo.h
@@ -1,6 +1,8 @@
 #define DATE_FORMAT "%5.4d-%2.2d-%2.2d"
 #define TIME_FORMAT "%2.2d:%2.2d:%2.2d"
 
+void uuid2str(const char *uuid, char *uuidstr);
+
 void date2str(int date, char *datestr, int maxlen)
 {
   int year, month, day;
@@ -66,6 +68,7 @@ void printFiletype(int streamID, int vlistID)
       break;
     default:
       printf("  File format: unsupported filetype %d" , filetype);
+      break;
     }
 
   if ( filetype == FILETYPE_SRV || filetype == FILETYPE_EXT || filetype == FILETYPE_IEG )
@@ -133,6 +136,7 @@ void printGridInfo(int vlistID)
   int gridID, gridtype, trunc, gridsize, xsize, ysize;
   int nbyte0;
   char xname[CDI_MAX_NAME], yname[CDI_MAX_NAME], xunits[CDI_MAX_NAME], yunits[CDI_MAX_NAME];
+  char uuidOfHGrid[17];
 
   ngrids = vlistNgrids(vlistID);
   for ( index = 0; index < ngrids; index++ )
@@ -154,9 +158,11 @@ void printGridInfo(int vlistID)
 	   gridtype == GRID_LCC2 ||
 	   gridtype == GRID_LAEA ||
 	   gridtype == GRID_SINUSOIDAL ||
+	   gridtype == GRID_GENERIC ||
 	   gridtype == GRID_GAUSSIAN ||
 	   gridtype == GRID_GAUSSIAN_REDUCED )
 	{
+          int lxcoord = 1, lycoord = 1;
 	  double xfirst = 0.0, xlast = 0.0;
 	  double yfirst = 0.0, ylast = 0.0;
 	  double xinc = 0.0, yinc = 0.0;
@@ -168,14 +174,17 @@ void printGridInfo(int vlistID)
 	  if ( gridtype == GRID_GAUSSIAN_REDUCED )
 	    fprintf(stdout, "size : dim = %d  nlat = %d", gridsize, ysize);
 	  else
-	    fprintf(stdout, "size      : dim = %d  nlon = %d  nlat = %d", gridsize, xsize, ysize);
-	  
+	    fprintf(stdout, "size      : dim = %d  nx = %d  ny = %d", gridsize, xsize, ysize);
+
 	  if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_GAUSSIAN_REDUCED )
 	    fprintf(stdout, "  np = %d", gridInqNP(gridID));
 
 	  fprintf(stdout, "\n");
 
-	  if ( xsize > 0 )
+          if ( gridInqXvals(gridID, NULL) == 0 ) lxcoord = 0;
+          if ( gridInqYvals(gridID, NULL) == 0 ) lycoord = 0;
+
+	  if ( xsize > 0 && lxcoord )
 	    {
 	      if ( gridtype == GRID_GAUSSIAN_REDUCED )
 		{
@@ -194,19 +203,18 @@ void printGridInfo(int vlistID)
 		  if ( IS_NOT_EQUAL(xinc, 0) )
 		    fprintf(stdout, "  inc = %.9g", xinc);
 		  fprintf(stdout, "  %s", xunits);
-		  if ( gridIsCircular(gridID) )
-		    fprintf(stdout, "  circular");
+		  if ( gridIsCircular(gridID) ) fprintf(stdout, "  circular");
 		  fprintf(stdout, "\n");
 		}
 	    }
 
-	  if ( ysize > 0 )
+	  if ( ysize > 0 && lycoord )
 	    {
 	      fprintf(stdout, "%*s", nbyte0, "");
 	      fprintf(stdout, "%-9s : first = %.9g", yname, yfirst);
 	      if ( ysize > 1 ) fprintf(stdout, "  last = %.9g", ylast);
-	      if ( IS_NOT_EQUAL(yinc, 0) && 
-		   (gridtype == GRID_LONLAT || gridtype == GRID_SINUSOIDAL || 
+	      if ( IS_NOT_EQUAL(yinc, 0) &&
+		   (gridtype == GRID_LONLAT || gridtype == GRID_SINUSOIDAL ||
 		    gridtype == GRID_LCC2 || gridtype == GRID_LAEA) )
 		fprintf(stdout, "  inc = %.9g", yinc);
 	      fprintf(stdout, "  %s", yunits);
@@ -231,6 +239,7 @@ void printGridInfo(int vlistID)
 	      fprintf(stdout, "available :");
 	      if ( gridInqXbounds(gridID, NULL) ) fprintf(stdout, " xbounds");
 	      if ( gridInqYbounds(gridID, NULL) ) fprintf(stdout, " ybounds");
+	      if ( gridHasArea(gridID) )          fprintf(stdout, " area");
 	      if ( gridInqMask(gridID, NULL) )    fprintf(stdout, " mask");
 	      fprintf(stdout, "\n");
 	    }
@@ -317,12 +326,11 @@ void printGridInfo(int vlistID)
 
 	      fprintf(stdout, "%*s", nbyte0, "");
 	      fprintf(stdout, "%-9s : min = %.9g  max = %.9g  %s", xname, xfirst, xlast, xunits);
-	      if ( gridIsCircular(gridID) )
-		fprintf(stdout, "  circular");
+	      if ( gridIsCircular(gridID) ) fprintf(stdout, "  circular");
 	      fprintf(stdout, "\n");
 	      fprintf(stdout, "%*s", nbyte0, "");
 	      fprintf(stdout, "%-9s : min = %.9g  max = %.9g  %s\n", yname, yfirst, ylast, yunits);
- 
+
 	      free(xvals);
 	      free(yvals);
 	    }
@@ -352,18 +360,10 @@ void printGridInfo(int vlistID)
 	  if ( ysize == 0 )
 	    fprintf(stdout, "size      : dim = %d\n", gridsize);
 	  else
-	    {
-	      fprintf(stdout, "size      : dim = %d  nx = %d  ny = %d\n", gridsize, xsize, ysize);
-	      if ( gridIsCircular(gridID) )
-		{
-		  fprintf(stdout, "%*s", nbyte0, "");
-		  fprintf(stdout, "longitude :  circular\n");
-		}
-	    }
+            fprintf(stdout, "size      : dim = %d  nx = %d  ny = %d\n", gridsize, xsize, ysize);
 	}
 
-      if ( gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED ||
-	   gridtype == GRID_GENERIC || gridtype == GRID_LCC )
+      if ( gridtype == GRID_CURVILINEAR || gridtype == GRID_UNSTRUCTURED || gridtype == GRID_LCC )
 	{
 	  if ( gridInqXvals(gridID, NULL) || gridInqYvals(gridID, NULL) || gridHasArea(gridID) ||
 	       gridInqXbounds(gridID, NULL) || gridInqYbounds(gridID, NULL) )
@@ -379,5 +379,26 @@ void printGridInfo(int vlistID)
 	      fprintf(stdout, "\n");
 	    }
 	}
+
+      gridInqUUID(gridID, uuidOfHGrid);
+      if ( uuidOfHGrid[0] != 0 )
+        {
+          char uuidOfHGridStr[37];
+          uuid2str(uuidOfHGrid, uuidOfHGridStr);
+          if ( uuidOfHGridStr[0] != 0  && strlen(uuidOfHGridStr) == 36 )
+            {
+	      fprintf(stdout, "%*s", nbyte0, "");
+	      fprintf(stdout, "uuid      : %s\n", uuidOfHGridStr);
+            }
+        }
     }
 }
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
diff --git a/src/process.c b/src/process.c
index 9eb2da0..90a685e 100644
--- a/src/process.c
+++ b/src/process.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -25,7 +25,10 @@
 
 #include <stdio.h>
 #include <string.h>
+
+#if  defined  (HAVE_GLOB_H)
 #include <glob.h>
+#endif
 
 #include "cdo.h"
 #include "cdo_int.h"
@@ -221,16 +224,20 @@ void processAddStream(int streamID)
   int sindex;
 
   if ( pstreamIsPipe(streamID) ) Process[processID].nchild++;
-
   sindex = Process[processID].nstream++;
 
   if ( sindex >= MAX_STREAM )
-    Error("limit of %d streams per process reached!", MAX_STREAM);
+    Error("limit of %d streams per process reached (processID = %d)!", MAX_STREAM, processID);
 
   Process[processID].streams[sindex] = streamID;
 }
 
 
+void processDelStream(int streamID)
+{
+}
+
+
 void processDefCputime(int processID, double cputime)
 {
   Process[processID].cputime = cputime;
@@ -553,6 +560,7 @@ int expand_wildcards(int processID, int streamCnt)
   for ( i = 0; i < len; ++i ) if ( streamname0[i] == '?' || streamname0[i] == '*' ) break;
   if ( i < len )
     {
+#if  defined  (HAVE_GLOB_H)
       char *pattern = glob_pattern(streamname0);
       if ( strcmp(streamname0, pattern) != 0 )
 	{
@@ -604,6 +612,9 @@ int expand_wildcards(int processID, int streamCnt)
 	}
       
       free(pattern);
+#else
+      cdoAbort("Wildcards support not compiled in!");
+#endif
     }
 
   return 1;
@@ -825,9 +836,9 @@ void processDelete(void)
   //fprintf(stderr, "delete processID %d\n", processID);
 #if  defined  (HAVE_LIBPTHREAD)
   pthread_mutex_lock(&processMutex);
-#endif
 
   Process[processID].l_threadID = 0;
+#endif
   NumProcessActive--;
 
 #if  defined  (HAVE_LIBPTHREAD)
diff --git a/src/process.h b/src/process.h
index 2693775..bb8a7ef 100644
--- a/src/process.h
+++ b/src/process.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -29,6 +29,7 @@ int  processInqVarNum(void);
 int  processInqStreamNum(void);
 int  processInqStreamID(int streamindex);
 void processAddStream(int streamID);
+void processDelStream(int streamID);
 void processDefVarNum(int nvars, int streamID);
 void processDefArgument(const char *argument);
 
diff --git a/src/pstream.c b/src/pstream.c
index 87da21c..8bae20f 100644
--- a/src/pstream.c
+++ b/src/pstream.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -171,7 +171,7 @@ int pstream_from_pointer(pstream_t *ptr)
 	    Message("Pointer %p has idx %d from pstream list", ptr, idx);
 	}
       else
-	Warning("Too many open pstreams (limit is %d)!", _pstream_max);
+	Error("Too many open pstreams (limit is %d)!", _pstream_max);
 
       PSTREAM_UNLOCK();
     }
@@ -643,8 +643,7 @@ int pstreamOpenWrite(const char *argument, int filetype)
 #if  defined  (HAVE_LIBPTHREAD)
       if ( PSTREAM_Debug ) Message("pipe %s", argument);
       pstreamID = pstreamFindID(argument);
-      if ( pstreamID == -1 )
-	Error("%s not open", argument);
+      if ( pstreamID == -1 ) Error("%s is not open!", argument);
 
       pstreamptr = pstream_to_pointer(pstreamID);
 
@@ -860,6 +859,8 @@ void pstreamClose(int pstreamID)
 	    }
 	  pthread_mutex_unlock(pipe->mutex);
 	}
+
+      processDelStream(pstreamID);
 #else
       cdoAbort("Cannot use pipes, pthread support not compiled in!");
 #endif
@@ -1647,8 +1648,8 @@ void cdoFinish(void)
       pstreamID = processInqStreamID(sindex);
       pstreamptr = pstream_to_pointer(pstreamID);
       if ( PSTREAM_Debug )
-	Message("process %d  stream %d  close streamID %d",
-		processID, sindex, pstreamID);
+	Message("process %d  stream %d  close streamID %d", processID, sindex, pstreamID);
+
       if ( pstreamptr ) pstreamClose(pstreamID);
     }
 
diff --git a/src/pstream.h b/src/pstream.h
index a9bf19f..4d98d21 100644
--- a/src/pstream.h
+++ b/src/pstream.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/pstream_int.h b/src/pstream_int.h
index f2561b2..90d5e95 100644
--- a/src/pstream_int.h
+++ b/src/pstream_int.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/pthread_debug.c b/src/pthread_debug.c
index 9063e71..0c3b12d 100644
--- a/src/pthread_debug.c
+++ b/src/pthread_debug.c
@@ -184,6 +184,7 @@ void Pthread_mutex_lock(const char *caller, pthread_mutex_t *mutex)
 	  break;
 	default:
 	  Error("Status %d unknown!", status, (void *) mutex);
+	  break;
 	}
     }
 
@@ -210,6 +211,7 @@ void Pthread_mutex_unlock(const char *caller, pthread_mutex_t *mutex)
 	  break;
 	default:
 	  Error("Status %d unknown!", status);
+	  break;
 	}
     }
 
diff --git a/src/readline.c b/src/readline.c
index 82a7b97..c2768c1 100644
--- a/src/readline.c
+++ b/src/readline.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/remaplib.c b/src/remaplib.c
index 740bc02..b9934de 100644
--- a/src/remaplib.c
+++ b/src/remaplib.c
@@ -2904,6 +2904,39 @@ void grid_search_nbr1(remapgrid_t *rg, int *restrict nbr_add, double *restrict n
   nbr_dist[0] = BIGNUM;
 
   // printf("%g %g  min %d  max %d  range %d\n", plon, plat, min_add, max_add, max_add-min_add);
+  //#define TESTVECTOR
+
+#ifdef  TESTVECTOR
+  long i = 0;
+  long ni = max_add - min_add + 1;
+  double *distvect = malloc(ni*sizeof(double));
+
+  for ( i = 0; i < ni; ++i )
+    {
+      nadd = min_add + i;
+      /* Find distance to this point */
+      distvect[i] =  sinlat_dst*sinlat[nadd] + coslat_dst*coslat[nadd]*
+	            (coslon_dst*coslon[nadd] + sinlon_dst*sinlon[nadd]);
+      /* 2008-07-30 Uwe Schulzweida: check that distance is inside the range of -1 to 1,
+                                     otherwise the result of acos(distance) is NaN */
+      if ( distvect[i] >  1 ) distvect[i] =  1;
+      if ( distvect[i] < -1 ) distvect[i] = -1;
+    }
+
+  for ( i = 0; i < ni; ++i )
+    distvect[i] = acos(distvect[i]);
+
+  /* Store the address and distance if this is the smallest so far */
+  for ( i = 0; i < ni; ++i )
+    if ( distvect[i] < nbr_dist[0] )
+      {
+	nbr_add[0]  = min_add + i + 1;
+	nbr_dist[0] = distvect[i];
+      }
+
+  free(distvect);
+
+#else
   for ( nadd = min_add; nadd <= max_add; ++nadd )
     {
       /* Find distance to this point */
@@ -2922,44 +2955,11 @@ void grid_search_nbr1(remapgrid_t *rg, int *restrict nbr_add, double *restrict n
 	  nbr_dist[0] = distance;
         }
     }
+#endif
 
 }  /*  grid_search_nbr1  */
 
 /*
-  This routine stores the address and weight for this link in
-  the appropriate address and weight arrays and resizes those
-  arrays if necessary.
-*/
-static
-void store_link_nbr1(remapvars_t *rv, int add1, int add2, double weights)
-{
-  /*
-    Input variables:
-    int  add1         ! address on grid1
-    int  add2         ! address on grid2
-    double weights    ! remapping weight for this link
-  */
-  long nlink;
-
-  /*
-     Increment number of links and check to see if remap arrays need
-     to be increased to accomodate the new link.  Then store the link.
-  */
-  nlink = rv->num_links;
-
-  rv->num_links++;
-  if ( rv->num_links >= rv->max_links ) 
-    resize_remap_vars(rv, rv->resize_increment);
-
-  rv->grid1_add[nlink] = add1;
-  rv->grid2_add[nlink] = add2;
-
-  rv->wts[nlink] = weights;
-
-} /* store_link_nbr1 */
-
-
-/*
   -----------------------------------------------------------------------
 
    This routine computes the inverse-distance weights for a
@@ -3067,7 +3067,7 @@ void remap_distwgt1(remapgrid_t *rg, remapvars_t *rv)
 #if defined (_OPENMP)
 #pragma omp critical
 #endif
-	  store_link_nbr1(rv, nbr_add-1, dst_add, wgtstmp);
+	  store_link_nbr(rv, nbr_add-1, dst_add, wgtstmp);
 	}
 
     } /* grid_loop1 */
diff --git a/src/remapsort.c b/src/remapsort.c
index b0b40f3..19ab522 100644
--- a/src/remapsort.c
+++ b/src/remapsort.c
@@ -27,7 +27,7 @@ int isSorted(int *restrict array1, int *restrict array2, const long size)
 
   return 1;
 }
-
+/*
 static
 void swap(int *restrict v1, int *restrict v2)
 {
@@ -69,12 +69,13 @@ void heapify(const long pos, const long size, int *restrict arr1, int *restrict
 	}
     }
 }
-
+*/
 /* remap_heapsort is 30% faster than remap_heapsort_recursiv ! */
+/*
 static
 void remap_heapsort_recursiv(const long num_links, int *restrict arr1, int *restrict arr2, int *restrict arr3)
 {
-  long lvl;     /* level indexes for heap sort levels */
+  long lvl;     // level indexes for heap sort levels
 
   for ( lvl = num_links/2-1; lvl >= 0; --lvl )
     {
@@ -89,6 +90,7 @@ void remap_heapsort_recursiv(const long num_links, int *restrict arr1, int *rest
       heapify(0, lvl, arr1, arr2, arr3);
     }
 }
+*/
 
 static
 void remap_heapsort(const long num_links, int *restrict add1, int *restrict add2, int *restrict idx)
@@ -602,7 +604,7 @@ void sort_par(long num_links, long num_wts, int *restrict add1, int *restrict ad
   int nl[nsplit];                            /* number of links in each sub-array              */
   int who_am_i,depth;                        /* 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 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     */
@@ -635,7 +637,7 @@ void sort_par(long num_links, long num_wts, int *restrict add1, int *restrict ad
   add1s[0]   = &add1[add_srt[0]];  add1s[1]   = &add1[add_srt[1]];
   add2s[0]   = &add2[add_srt[0]];  add2s[1]   = &add2[add_srt[1]];
   nl[0]      = num_links/nsplit;   nl[1]      = num_links-nl[0];
-  add_end[0] = nl[0];              add_end[1] = num_links;
+  //add_end[0] = nl[0];              add_end[1] = num_links;
 
   depth = (int) (log(parent)/log(2));
 
diff --git a/src/specspace.c b/src/specspace.c
index be50f9e..c433fee 100644
--- a/src/specspace.c
+++ b/src/specspace.c
@@ -616,10 +616,10 @@ void trans_uv2dv(SPTRANS *sptrans, int nlev,
   double *fpwork1, *fpwork2;
 
   if ( gridInqType(gridID1) != GRID_GAUSSIAN )
-    Warning("unexpected grid1 type: %s", gridNamePtr(gridInqType(gridID1)));
+    Error("unexpected grid1 type: %s instead of Gaussian", gridNamePtr(gridInqType(gridID1)));
 
   if ( gridInqType(gridID2) != GRID_SPECTRAL )
-    Warning("unexpected grid2 type: %s", gridNamePtr(gridInqType(gridID2)));
+    Error("unexpected grid2 type: %s instead of spectral", gridNamePtr(gridInqType(gridID2)));
     
   ntr  = gridInqTrunc(gridID2);
   nlon = gridInqXsize(gridID1);
diff --git a/src/table.c b/src/table.c
index 2738af6..639a246 100644
--- a/src/table.c
+++ b/src/table.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/timer.c b/src/timer.c
index 0e11391..a465f43 100644
--- a/src/timer.c
+++ b/src/timer.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/util.c b/src/util.c
index 56b907c..8a8cc64 100644
--- a/src/util.c
+++ b/src/util.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/util.h b/src/util.h
index 5bb0f52..b588903 100644
--- a/src/util.h
+++ b/src/util.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.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/zaxis.c b/src/zaxis.c
index 21e80b0..1d135f3 100644
--- a/src/zaxis.c
+++ b/src/zaxis.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2012 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -149,10 +149,12 @@ static char *skipSeparator(char *pline)
 }
 
 
-int zaxisFromFile(FILE *gfp)
+int zaxisFromFile(FILE *gfp, const char *dname)
 {
   char line[MAX_LINE_LEN], *pline;
   int zaxisID;
+  int lerror;
+  size_t i, len;
   zaxis_t zaxis;
 
   zaxisInit(&zaxis);
@@ -161,6 +163,17 @@ int zaxisFromFile(FILE *gfp)
     {
       if ( line[0] == '#' ) continue;
       if ( line[0] == '\0' ) continue;
+      len = strlen(line);
+
+      lerror = FALSE;
+      for ( i = 0; i < len; ++i )
+	if ( !(line[i] == 9 || (line[i] > 31 && line[i] < 127)) )
+	  {
+	    lerror = TRUE;
+	    line[i] = '#';
+	  }
+      if ( lerror ) cdoAbort("Zaxis description file >%s< contains illegal characters (line: %s)!", dname, line);
+
       pline = line;
       while ( isspace((int) *pline) ) pline++;
       if ( pline[0] == '\0' ) continue;
@@ -193,7 +206,7 @@ int zaxisFromFile(FILE *gfp)
 	  else if ( memcmp(pline, "generic", 7)  == 0 )
 	    zaxis.type = ZAXIS_GENERIC;
 	  else
-	    Warning("Invalid zaxisname : %s", pline);
+	    cdoAbort("Invalid zaxisname : %s (zaxis description file: %s)", pline, dname);
 	}
       else if ( memcmp(pline, "size", 4)  == 0 )
 	{
@@ -231,10 +244,8 @@ int zaxisFromFile(FILE *gfp)
 		  if ( strlen(pline) == 0 )
 		    {
 		      if ( ! readline(gfp, line, MAX_LINE_LEN) )
-			{
-			  Warning("Incomplete command: >levels<");
-			  break;
-			}
+			cdoAbort("Incomplete command: >levels< (zaxis description file: %s)", dname);
+
 		      pline = line;
 		      pline = skipSeparator(pline);
 		    }
@@ -248,7 +259,7 @@ int zaxisFromFile(FILE *gfp)
 	    }
 	  else
 	    {
-	      Warning("size undefined!");
+	      cdoAbort("size undefined (zaxis description file: %s)!", dname);
 	    }
 	}
       else if ( memcmp(pline, "vct", 3)  == 0 )
@@ -267,10 +278,8 @@ int zaxisFromFile(FILE *gfp)
 		  if ( strlen(pline) == 0 )
 		    {
 		      if ( ! readline(gfp, line, MAX_LINE_LEN) )
-			{
-			  Warning("Incomplete command: >vct<");
-			  break;
-			}
+			cdoAbort("Incomplete command: >vct< (zaxis description file: %s)", dname);
+
 		      pline = line;
 		      pline = skipSeparator(pline);
 		    }
@@ -284,7 +293,7 @@ int zaxisFromFile(FILE *gfp)
 	    }
 	  else
 	    {
-	      Warning("vctsize undefined!");
+	      cdoAbort("vctsize undefined (zaxis description file: %s)!", dname);
 	    }
 	}
       else if ( memcmp(pline, "lbounds", 7)  == 0 )
@@ -303,10 +312,8 @@ int zaxisFromFile(FILE *gfp)
 		  if ( strlen(pline) == 0 )
 		    {
 		      if ( ! readline(gfp, line, MAX_LINE_LEN) )
-			{
-			  Warning("Incomplete command: >lbounds<");
-			  break;
-			}
+			cdoAbort("Incomplete command: >lbounds< (zaxis description file: %s)", dname);
+
 		      pline = line;
 		      pline = skipSeparator(pline);
 		    }
@@ -320,7 +327,7 @@ int zaxisFromFile(FILE *gfp)
 	    }
 	  else
 	    {
-	      Warning("size undefined!");
+	      cdoAbort("size undefined (zaxis description file: %s)!", dname);
 	    }
 	}
       else if ( memcmp(pline, "ubounds", 7)  == 0 )
@@ -339,10 +346,8 @@ int zaxisFromFile(FILE *gfp)
 		  if ( strlen(pline) == 0 )
 		    {
 		      if ( ! readline(gfp, line, MAX_LINE_LEN) )
-			{
-			  Warning("Incomplete command: >ubounds<");
-			  break;
-			}
+			cdoAbort("Incomplete command: >ubounds< (zaxis description file: %s)", dname);
+
 		      pline = line;
 		      pline = skipSeparator(pline);
 		    }
@@ -356,11 +361,11 @@ int zaxisFromFile(FILE *gfp)
 	    }
 	  else
 	    {
-	      Warning("size undefined!");
+	      cdoAbort("size undefined (zaxis description file: %s)!", dname);
 	    }
 	}
       else
-	Warning("Invalid zaxis command : >%s<", pline);
+	cdoAbort("Invalid zaxis command : >%s< (zaxis description file: %s)", pline, dname);
     }
 
   zaxisID = zaxisDefine(zaxis);
@@ -406,7 +411,7 @@ int cdoDefineZaxis(const char *zaxisfile)
     }
   else
     {
-      zaxisID = zaxisFromFile(zfp);
+      zaxisID = zaxisFromFile(zfp, zaxisfile);
       fclose(zfp);
     }
 
diff --git a/test/Makefile.in b/test/Makefile.in
index baa05f5..fee302a 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -105,6 +105,7 @@ ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 ENABLE_CDI_LIB = @ENABLE_CDI_LIB@
 ENABLE_CGRIBEX = @ENABLE_CGRIBEX@
+ENABLE_DATA = @ENABLE_DATA@
 ENABLE_EXTRA = @ENABLE_EXTRA@
 ENABLE_GRIB = @ENABLE_GRIB@
 ENABLE_IEG = @ENABLE_IEG@

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