[cdo] 26/84: 1.6.1 upstream

Alastair McKinstry mckinstry at moszumanska.debian.org
Sat Jun 13 16:48:27 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 9e296bded4cf6f51d0d8691d06157004cd6238df
Author: Alastair McKinstry <mckinstry at debian.org>
Date:   Tue Aug 27 22:15:16 2013 +0100

    1.6.1 upstream
---
 ChangeLog                              |   52 +
 NEWS                                   |   16 +
 cdo.spec                               |    2 +-
 config/default                         |   27 +-
 configure                              |  111 ++-
 configure.ac                           |    2 +-
 contrib/cdoCompletion.bash             |    2 +
 contrib/cdoCompletion.tcsh             |    2 +
 contrib/cdoCompletion.zsh              |    2 +
 doc/cdo.pdf                            |  Bin 1426317 -> 1426651 bytes
 doc/cdo_refcard.pdf                    |  Bin 95662 -> 95763 bytes
 libcdi/ChangeLog                       |   79 ++
 libcdi/NEWS                            |   13 +
 libcdi/app/cdi.c                       |   17 +-
 libcdi/config/default                  |    4 +-
 libcdi/configure                       |  125 ++-
 libcdi/configure.ac                    |   53 +-
 libcdi/doc/cdi_cman.pdf                |  Bin 436900 -> 437006 bytes
 libcdi/doc/cdi_fman.pdf                |  Bin 477119 -> 477310 bytes
 libcdi/examples/Makefile.am            |    5 +-
 libcdi/examples/Makefile.in            |   19 +-
 libcdi/examples/cdi_write_hybrid.c     |  122 +++
 libcdi/src/Makefile.am                 |    7 +-
 libcdi/src/Makefile.in                 |   18 +-
 libcdi/src/calendar.c                  |    2 +-
 libcdi/src/cdf.c                       |    2 +-
 libcdi/src/cdf_int.c                   |    6 +-
 libcdi/src/cdi.h                       |   44 +-
 libcdi/src/cdi.inc                     |   81 +-
 libcdi/src/cdiFortran.c                |   43 +-
 libcdi/src/cdiFortran.h                |   20 +
 libcdi/src/{stream_int.c => cdi_int.c} |    8 +-
 libcdi/src/{stream_int.h => cdi_int.h} |   18 +-
 libcdi/src/cdi_util.c                  |   24 +
 libcdi/src/cdilib.c                    | 1668 ++++++++++++++++++++------------
 libcdi/src/cfortran.h                  |    7 +
 libcdi/src/cgribexlib.c                |   21 +-
 libcdi/src/config.h.in                 |    6 +
 libcdi/src/file.c                      |   84 +-
 libcdi/src/gribapi.c                   |    2 +-
 libcdi/src/gribapi.h                   |    1 +
 libcdi/src/grid.c                      |   11 +-
 libcdi/src/institution.c               |   14 +-
 libcdi/src/model.c                     |    6 +-
 libcdi/src/pio_interface.c             |    2 +-
 libcdi/src/pio_server.c                |    2 +-
 libcdi/src/stream.c                    |   42 +-
 libcdi/src/stream_cdf.c                |  132 ++-
 libcdi/src/stream_cgribex.c            |    4 +-
 libcdi/src/stream_ext.c                |    4 +-
 libcdi/src/stream_grb.c                |   34 +-
 libcdi/src/stream_gribapi.c            |  489 +++++-----
 libcdi/src/stream_gribapi.h            |    2 +-
 libcdi/src/stream_history.c            |    2 +-
 libcdi/src/stream_ieg.c                |    4 +-
 libcdi/src/stream_record.c             |    2 +-
 libcdi/src/stream_srv.c                |    4 +-
 libcdi/src/stream_var.c                |    4 +-
 libcdi/src/table.c                     |    2 +-
 libcdi/src/taxis.c                     |    2 +-
 libcdi/src/timebase.c                  |    2 +-
 libcdi/src/timebase.h                  |    2 +
 libcdi/src/tsteps.c                    |    2 +-
 libcdi/src/util.c                      |    2 +-
 libcdi/src/varscan.c                   |  109 ++-
 libcdi/src/varscan.h                   |    6 +-
 libcdi/src/vlist.c                     |   16 +-
 libcdi/src/vlist.h                     |    8 +
 libcdi/src/vlist_att.c                 |   43 +-
 libcdi/src/vlist_var.c                 |  201 +++-
 libcdi/src/zaxis.c                     |   17 +-
 libcdi/tests/cksum_write.c             |   14 +-
 m4/acx_options.m4                      |   15 +
 src/._CdoMagicsMapper.h                |  Bin 205 -> 205 bytes
 src/._Maggraph.c                       |  Bin 205 -> 0 bytes
 src/._Magplot.c                        |  Bin 205 -> 0 bytes
 src/._Magvector.c                      |  Bin 205 -> 0 bytes
 src/._Rhopot.c                         |  Bin 205 -> 0 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/Arith.c                            |   16 +-
 src/Arithc.c                           |    2 +
 src/CDIread.c                          |    2 +-
 src/CDIwrite.c                         |    2 +-
 src/Cat.c                              |    6 +-
 src/CdoMagicsMapper.c                  |    1 +
 src/Change_e5slm.c                     |    4 +-
 src/Command.c                          |    2 +-
 src/Comp.c                             |    8 +-
 src/Cond.c                             |    6 +-
 src/Cond2.c                            |    6 +-
 src/Copy.c                             |    5 +-
 src/Echam5ini.c                        |    8 +-
 src/Enlargegrid.c                      |   10 +-
 src/Ensstat.c                          |   13 +-
 src/Ensstat3.c                         |   15 +-
 src/Ensval.c                           |   58 +-
 src/Eofcoeff.c                         |   11 +-
 src/Eofcoeff3d.c                       |   11 +-
 src/Exprf.c                            |    7 +-
 src/Fillmiss.c                         |    1 -
 src/Filter.c                           |   20 +-
 src/Fldstat2.c                         |   37 +-
 src/Gather.c                           |   10 +-
 src/Gradsdes.c                         |   64 +-
 src/Gridboxstat.c                      |    8 +-
 src/Harmonic.c                         |    6 +-
 src/Importamsr.c                       |    6 +-
 src/Importbinary.c                     |    2 +-
 src/Importcmsaf.c                      |    4 +-
 src/Importobs.c                        |   10 +-
 src/Info.c                             |   31 +-
 src/Intgrid.c                          |   13 +-
 src/Intgridtraj.c                      |    2 +-
 src/Intlevel3d.c                       |    4 +-
 src/Inttime.c                          |    5 +-
 src/Intyear.c                          |    8 +-
 src/Log.c                              |   10 +-
 src/Maggraph.c                         |   12 +-
 src/Magplot.c                          |   30 +-
 src/Magvector.c                        |   31 +-
 src/Makefile.am                        |    1 +
 src/Makefile.in                        |   25 +-
 src/Maskbox.c                          |    4 +-
 src/Mastrfu.c                          |    1 +
 src/Merge.c                            |    6 +-
 src/Mergegrid.c                        |   12 +-
 src/Mergetime.c                        |    6 +-
 src/Monarith.c                         |    4 +-
 src/Mrotuv.c                           |    6 +-
 src/Mrotuvb.c                          |   96 +-
 src/Output.c                           |    4 +-
 src/Outputgmt.c                        |   10 +-
 src/Pack.c                             |  290 ++++++
 src/Remap.c                            |    2 +-
 src/Remapeta.c                         |    4 +-
 src/Rhopot.c                           |    2 +-
 src/Rotuv.c                            |    8 +-
 src/SSOpar.c                           |    2 +-
 src/Scatter.c                          |   70 +-
 src/Seaspctl.c                         |    8 +-
 src/Selbox.c                           |    1 +
 src/Select.c                           |   67 +-
 src/Seltime.c                          |    1 +
 src/Setgrid.c                          |    8 +-
 src/Sethalo.c                          |    2 +-
 src/Sinfo.c                            |   46 +-
 src/Split.c                            |   48 +-
 src/Splitrec.c                         |    6 +-
 src/Splitsel.c                         |    6 +-
 src/Splittime.c                        |    7 +-
 src/Splityear.c                        |    6 +-
 src/Timpctl.c                          |   10 +-
 src/Timselpctl.c                       |    8 +-
 src/Timstat.c                          |    6 +-
 src/Vargen.c                           |    3 +-
 src/Writegrid.c                        |    2 +-
 src/YAR.c                              |  505 ++++++++--
 src/Ydaypctl.c                         |   10 +-
 src/Ydrunpctl.c                        |   10 +-
 src/Ymonpctl.c                         |   10 +-
 src/Yseaspctl.c                        |   10 +-
 src/cdo.c                              |   33 +-
 src/cdo.h                              |   12 +-
 src/cdo_int.h                          |   12 +-
 src/commandline.c                      |    2 +-
 src/config.h.in                        |    6 +
 src/ecacore.c                          |   11 -
 src/expr.c                             |   60 +-
 src/grid.c                             |   74 +-
 src/grid.h                             |   20 +-
 src/grid_rot.c                         |   72 +-
 src/griddes.c                          |    6 +-
 src/interpol.c                         |  690 ++++++++++++-
 src/interpol.h                         |    3 +-
 src/list.c                             |   51 +-
 src/modules.c                          |   11 +-
 src/operator_help.h                    |  157 +--
 src/pipe.h                             |    1 +
 src/process.c                          |  249 ++---
 src/process.h                          |    2 +-
 src/pstream.c                          |  142 +--
 src/pstream.h                          |    6 +-
 src/realtime.c                         |   18 +-
 src/remap.h                            |    2 +
 src/remaplib.c                         |  192 ++--
 src/timebase.h                         |    8 +-
 src/userlog.c                          |    2 +-
 src/util.c                             |  105 +-
 src/util.h                             |   15 +-
 src/zaxis.c                            |    1 -
 195 files changed, 5288 insertions(+), 2429 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 4fcc38c..f465cd4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,55 @@
+2013-06-28  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* using CDI library version 1.6.1
+	* Version 1.6.1 released
+
+2013-06-10  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* select: added support for key >minute< [request: Beate Gayer]
+
+2013-06-03  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* inttime: removes last time step [Bug #3611]
+
+2013-05-24  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* mrotuvb: added option >noint< to disable the interpolation to the grid cell centre
+
+2013-05-14  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* scatter: fails with missing values [Bug #3492]
+
+2013-04-19  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* gradsdes: added support for netCDF files
+
+2013-04-18  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* Info: add chunking information of netcdf files (only with verbose output) [Feature #3489]
+
+2013-04-17 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* select: added support to expand integer parameter
+	* select: added support for key >hour<
+
+2013-04-10 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* shifttime: wrong result for negative hours and days [Bug #3440]
+	* selmon: month not found for negative years [Bug #3439]
+	* splitmon: month not found for negative years
+
+2013-04-05 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* expr: wrong results if left operand has one level and right operand has more than one level (bug fix) [report: Walter Sauf]
+
+2013-04-02 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* enscrps: wrong result since CDO version 1.5.6 [Bug #3403]
+
+2013-03-19 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* fldcor: check missing value of 2. input file (bug fix) [report: Hans-J�rgen Panitz]
+
 2013-03-14 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
 
 	* using CDI library version 1.6.0
diff --git a/NEWS b/NEWS
index 2d90388..a61a967 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,21 @@
 CDO NEWS
 --------
+
+Version 1.6.1 (27 June 2013):
+
+   New features:
+     * support of blanks in filenames and parameter
+   Changed operators:
+     * gradsdes: added support for netCDF files
+     * Info: add chunking information of netcdf files (only with verbose output) [Feature #3489]
+     * select: added support for key >hour<
+   Fixed bugs:
+     * fldcor: check missing value of 2. input file
+     * enscrps: wrong result since CDO version 1.5.6 [Bug #3403]
+     * selmon: month not found for negative years [Bug #3439]
+     * shifttime: wrong result for negative hours and days [Bug #3440]
+     * inttime: removes last time step [Bug #3611]
+
 Version 1.6.0 (14 March 2013):
 
    New operators:
diff --git a/cdo.spec b/cdo.spec
index a74d62f..92e0240 100644
--- a/cdo.spec
+++ b/cdo.spec
@@ -4,7 +4,7 @@
 
 Name:           cdo
 #BuildRequires:  
-Version:        1.6.0
+Version:        1.6.1
 Release:        1
 Summary:        Climate Data Operators
 License:        GNU GENERAL PUBLIC LICENSE Version 2, June 1991
diff --git a/config/default b/config/default
index 2e3e086..49d808b 100755
--- a/config/default
+++ b/config/default
@@ -21,7 +21,7 @@ case "${HOSTNAME}" in
 	${CONFPATH}configure --prefix=$HOME/local \
                     --enable-maintainer-mode \
                     --with-jasper=$HOME/local \
-                    --with-grib_api=$HOME/local/gribapi-1.9.16cgribex \
+                    --with-grib_api=$HOME/local/gribapi-1.9.16 \
                     --with-netcdf=$HOME/local \
                     --with-hdf5=$HOME/local \
                     --with-szlib=$HOME/local \
@@ -36,7 +36,7 @@ case "${HOSTNAME}" in
 	${CONFPATH}configure --prefix=$HOME/local \
                     --enable-maintainer-mode \
                     --with-jasper=$HOME/local \
-                    --with-grib_api=$HOME/local/gribapi-1.9.16cgribex \
+                    --with-grib_api=$HOME/local/gribapi-1.10.4 \
                     --with-netcdf=$HOME/local \
                     --with-hdf5=$HOME/local \
                     --with-szlib=$HOME/local \
@@ -57,6 +57,8 @@ case "${HOSTNAME}" in
                     --with-netcdf=/opt/local \
                     --with-szlib=$HOME/local \
                     --with-proj=/opt/local \
+                    --with-libxml2=/usr \
+                    --with-magics=/Users/m214003/local/Magics-2.18.14nio \
 	            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/Users/m214003/cdt/work/YAC/src -lyac"
 	;;
@@ -84,25 +86,28 @@ case "${HOSTNAME}" in
 	;;
 # x86_64-squeeze-x64-linux
     thunder*)
-        ${CONFPATH}configure --prefix=$HOME/local --exec_prefix=$HOME/local/squeeze-x64 \
+        ${CONFPATH}configure --prefix=$HOME/local --exec_prefix=$HOME/local/thunder \
+                    --enable-all-static \
                     --with-jasper=/sw/squeeze-x64/jasper-1.900.1-static \
                     --with-grib_api=/sw/squeeze-x64/grib_api-1.9.9-static \
                     --with-netcdf=/sw/squeeze-x64/netcdf-4.2-static \
                     --with-hdf5=/sw/squeeze-x64/hdf5-1.8.8-static \
                     --with-szlib=/sw/squeeze-x64/szip-2.1 \
+                    --with-udunits2=/sw/squeeze-x64/udunits-2.1.19 \
                     --with-proj=/sw/squeeze-x64/proj-4.7.0 \
                     CC=gcc CFLAGS='-g -Wall -O3 -march=native -fopenmp'
 	;;
 # x86_64-lenny-linux-gnu
     squall*)
-        ${CONFPATH}configure --prefix=$HOME/local --exec_prefix=$HOME/local/lenny-x64 \
-                    --with-jasper=/sw/lenny-x64/jasper-1.900.1-static \
-                    --with-grib_api=/sw/lenny-x64/grib_api-1.9.9-static \
-                    --with-netcdf=/sw/lenny-x64/netcdf-4.2-static \
-                    --with-hdf5=/sw/lenny-x64/hdf5-1.8.8-static \
-                    --with-szlib=/sw/lenny-x64/szip-2.1 \
-                    --with-udunits2=/sw/lenny-x64/udunits-2.1.19 \
-                    --with-proj=/sw/lenny-x64/proj-4.7.0 \
+        ${CONFPATH}configure --prefix=$HOME/local --exec_prefix=$HOME/local/squeeze-x64 \
+                    --enable-all-static \
+                    --with-jasper=/sw/squeeze-x64/jasper-1.900.1-static \
+                    --with-grib_api=/sw/squeeze-x64/grib_api-1.9.9-static \
+                    --with-netcdf=/sw/squeeze-x64/netcdf-4.2-static \
+                    --with-hdf5=/sw/squeeze-x64/hdf5-1.8.8-static \
+                    --with-szlib=/sw/squeeze-x64/szip-2.1 \
+                    --with-udunits2=/sw/squeeze-x64/udunits-2.1.19 \
+                    --with-proj=/sw/squeeze-x64/proj-4.7.0 \
                     CC=gcc CFLAGS='-g -Wall -O3 -fopenmp'
 	;;
 # x86_64-archlinux
diff --git a/configure b/configure
index 3c64ac3..08e83ed 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.6.0.
+# Generated by GNU Autoconf 2.68 for cdo 1.6.1.
 #
 # 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.6.0'
-PACKAGE_STRING='cdo 1.6.0'
+PACKAGE_VERSION='1.6.1'
+PACKAGE_STRING='cdo 1.6.1'
 PACKAGE_BUGREPORT='http://code.zmaw.de/projects/cdo'
 PACKAGE_URL=''
 
@@ -808,6 +808,7 @@ enable_cgribex
 enable_service
 enable_extra
 enable_ieg
+with_fftw3
 with_proj
 with_udunits2
 with_magics
@@ -1370,7 +1371,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures cdo 1.6.0 to adapt to many kinds of systems.
+\`configure' configures cdo 1.6.1 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1440,7 +1441,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of cdo 1.6.0:";;
+     short | recursive ) echo "Configuration of cdo 1.6.1:";;
    esac
   cat <<\_ACEOF
 
@@ -1495,6 +1496,7 @@ Optional Packages:
                           library for grib2 compression; if a directory is
                           given, it will be used as a value for
                           --with-jasper-root
+  --without-fftw3         disable support for fftw3
   --with-proj=<directory> Specify location of PROJ library for cartographic
                           projections.
   --with-udunits2=<directory>
@@ -1584,7 +1586,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-cdo configure 1.6.0
+cdo configure 1.6.1
 generated by GNU Autoconf 2.68
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -2177,7 +2179,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by cdo $as_me 1.6.0, which was
+It was created by cdo $as_me 1.6.1, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
@@ -3071,7 +3073,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='cdo'
- VERSION='1.6.0'
+ VERSION='1.6.1'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -18333,6 +18335,95 @@ $as_echo "$enable_ieg" >&6; }
 ENABLE_IEG=$enable_ieg
 
 #  ----------------------------------------------------------------------
+#  Compile with fftw support
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for FFTW3 support" >&5
+$as_echo_n "checking for FFTW3 support... " >&6; }
+
+# Check whether --with-fftw3 was given.
+if test "${with_fftw3+set}" = set; then :
+  withval=$with_fftw3;
+else
+  with_fftw3=yes
+fi
+
+
+  if test "x$with_fftw3" != xno; then :
+  for ac_header in fftw3.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "fftw3.h" "ac_cv_header_fftw3_h" "$ac_includes_default"
+if test "x$ac_cv_header_fftw3_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_FFTW3_H 1
+_ACEOF
+
+fi
+
+done
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing fftw_cleanup" >&5
+$as_echo_n "checking for library containing fftw_cleanup... " >&6; }
+if ${ac_cv_search_fftw_cleanup+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char fftw_cleanup ();
+int
+main ()
+{
+return fftw_cleanup ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' fftw3; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_fftw_cleanup=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_fftw_cleanup+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_fftw_cleanup+:} false; then :
+
+else
+  ac_cv_search_fftw_cleanup=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_fftw_cleanup" >&5
+$as_echo "$ac_cv_search_fftw_cleanup" >&6; }
+ac_res=$ac_cv_search_fftw_cleanup
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+$as_echo "#define HAVE_LIBFFTW3 1" >>confdefs.h
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: Could not link to fftw3 library" >&5
+$as_echo "Could not link to fftw3 library" >&6; }
+fi
+
+fi
+
+#  ----------------------------------------------------------------------
 #  Checks for PROJ.4 library
 
 # Check whether --with-proj was given.
@@ -19735,7 +19826,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by cdo $as_me 1.6.0, which was
+This file was extended by cdo $as_me 1.6.1, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -19801,7 +19892,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.6.0
+cdo config.status 1.6.1
 configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index d291ac8..8bb8f32 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.6.0], [http://code.zmaw.de/projects/cdo])
+AC_INIT([cdo], [1.6.1], [http://code.zmaw.de/projects/cdo])
 
 CONFIG_ABORT=yes
 AC_CONFIG_AUX_DIR(config)
diff --git a/contrib/cdoCompletion.bash b/contrib/cdoCompletion.bash
index de56d7a..5731c48 100644
--- a/contrib/cdoCompletion.bash
+++ b/contrib/cdoCompletion.bash
@@ -283,6 +283,7 @@ int -int \
 interpolate -interpolate \
 intgrid -intgrid \
 intgridbil -intgridbil \
+intgridcon -intgridcon \
 intgridtraj -intgridtraj \
 intlevel -intlevel \
 intlevel3d -intlevel3d \
@@ -400,6 +401,7 @@ outputts -outputts \
 outputvector -outputvector \
 outputvrml -outputvrml \
 outputxyz -outputxyz \
+pack -pack \
 pardes -pardes \
 pardup -pardup \
 parmul -parmul \
diff --git a/contrib/cdoCompletion.tcsh b/contrib/cdoCompletion.tcsh
index c6ad742..cb4c76f 100644
--- a/contrib/cdoCompletion.tcsh
+++ b/contrib/cdoCompletion.tcsh
@@ -283,6 +283,7 @@ int \
 interpolate \
 intgrid \
 intgridbil \
+intgridcon \
 intgridtraj \
 intlevel \
 intlevel3d \
@@ -400,6 +401,7 @@ outputts \
 outputvector \
 outputvrml \
 outputxyz \
+pack \
 pardes \
 pardup \
 parmul \
diff --git a/contrib/cdoCompletion.zsh b/contrib/cdoCompletion.zsh
index e4738fd..626cbfc 100644
--- a/contrib/cdoCompletion.zsh
+++ b/contrib/cdoCompletion.zsh
@@ -283,6 +283,7 @@ int -int \
 interpolate -interpolate \
 intgrid -intgrid \
 intgridbil -intgridbil \
+intgridcon -intgridcon \
 intgridtraj -intgridtraj \
 intlevel -intlevel \
 intlevel3d -intlevel3d \
@@ -400,6 +401,7 @@ outputts -outputts \
 outputvector -outputvector \
 outputvrml -outputvrml \
 outputxyz -outputxyz \
+pack -pack \
 pardes -pardes \
 pardup -pardup \
 parmul -parmul \
diff --git a/doc/cdo.pdf b/doc/cdo.pdf
index a68cc8a..a3b78db 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 fe12eed..e6be4c8 100644
Binary files a/doc/cdo_refcard.pdf and b/doc/cdo_refcard.pdf differ
diff --git a/libcdi/ChangeLog b/libcdi/ChangeLog
index c64a7e0..7dcfe4c 100644
--- a/libcdi/ChangeLog
+++ b/libcdi/ChangeLog
@@ -1,3 +1,82 @@
+2013-06-28  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* Version 1.6.1 released
+
+2013-06-27  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* file.c: added env. var. FILE_TYPE_WRITE (1:open; 2:fopen)
+
+2013-06-11  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* GRIB2: added support for snow level (level type 114)
+	* GRIB2: added support for layers with zaxis type ZAXIS_PRESSURE
+
+2013-06-06  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* cdfDefVarMissval: changed xtype from NC_BYTE to NC_INT for missvals > 127 (workaround for a netCDF bug)
+	* use 'number_of_grid_used' only for undefined grid types
+
+2013-06-03  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* added patch from Florian Prill: Lesen von 'number_of_grid_used', GRID_REFERENCE (bug fix)
+
+2013-05-29  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* netCDF: skip 4D variables without time dimension (bug fix)
+
+2013-05-28  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* GRIB2: added support for pressure levels with 3 fractional digits
+
+2013-05-27  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* gribapiGetEndStep: use stepUnits for timeunits2
+	* grib2GetLevel: set level bounds if  0 < leveltype2 < 255
+
+2013-05-23  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* netCDF: missing_value attribute removed [Bug #3592]
+
+2013-05-17  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* added CDI function cdiHaveFiletype() to check whether a filetype is available
+
+2013-05-13  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* added patch from Florian Prill: Lesen von "Nicht-Standard" GRIB-Keys (bug fix)
+
+2013-04-26  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* added patch from Florian Prill: Lesen von "Nicht-Standard" GRIB-Keys
+
+2013-04-25  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* institutInq: check contents of name and longname (bug fix) [Bug #3419]
+
+2013-04-23  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* cfortran.h::kill_trailing: wrong result with gcc -O3, use prama for -O2 (bug fix) [report: Luis Kornblueh]
+	* vlistXXXAttTxt: use cdi fortran datatype CBUF (char *) for the last argument (bug fix) [report: Luis Kornblueh]
+	* gridXXXUUID: use cdi fortran datatype CBUF (char *) for the last argument (bug fix) [Bug #3424]
+	* zaxisXXXUUID: use cdi fortran datatype CBUF (char *) for the last argument (bug fix)
+
+2013-04-19  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* stream_gribapi: replaced function getLevelFactor() [Bug #3446]
+
+2013-04-18  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* added function vlistDefVarExtra() and vlistInqVarExtra()
+
+2013-04-04  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* vlistDefVarDatatype: changed default missing values of signed integers to -TYPE_MAX
+
+2013-04-02  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* cdi.h: changed >char*< to >char *< (bug fix for fortran interface)
+	* make_cdilib: changed position of error.c and error.h (bug fix)
+
 2013-03-14  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
 
 	* Version 1.6.0 released
diff --git a/libcdi/NEWS b/libcdi/NEWS
index ae614eb..c6825e7 100644
--- a/libcdi/NEWS
+++ b/libcdi/NEWS
@@ -1,6 +1,19 @@
 CDI NEWS
 --------
 
+Version 1.6.1 (18 June 2013):
+
+   New features:
+     * GRIB2: added support for snow level (level type 114)
+     * GRIB2: added support for layers with zaxis type ZAXIS_PRESSURE
+   New functions:
+     * cdiHaveFiletype(): Check whether a filetype is available
+   Fixed bugs:
+     * stream_gribapi: replaced function getLevelFactor() [Bug #3446]
+     * gridXXXUUID: use cdi fortran datatype CBUF (char *) for the last argument (bug fix) [Bug #3424]
+     * institutInq: check contents of name and longname (bug fix) [Bug #3419]
+     * netCDF: missing_value attribute removed [Bug #3592]
+
 Version 1.6.0 (14 March 2013):
 
    New features:
diff --git a/libcdi/app/cdi.c b/libcdi/app/cdi.c
index 92138b0..76c4a18 100644
--- a/libcdi/app/cdi.c
+++ b/libcdi/app/cdi.c
@@ -56,6 +56,9 @@ int complevel = 0;              // Compression level
 static
 void version(void)
 {
+  int   filetypes[] = {FILETYPE_SRV, FILETYPE_EXT, FILETYPE_IEG, FILETYPE_GRB, FILETYPE_GRB2, FILETYPE_NC, FILETYPE_NC2, FILETYPE_NC4, FILETYPE_NC4C};
+  char *typenames[] = {        "srv",        "ext",        "ieg",        "grb",        "grb2",        "nc",        "nc2",        "nc4",        "nc4c"};
+
   fprintf(stderr, "CDI version 1.8\n");
 #if defined (COMPILER)
   fprintf(stderr, "Compiler: %s\n", COMPILER);
@@ -63,6 +66,16 @@ void version(void)
 #if defined (COMP_VERSION)
   fprintf(stderr, " version: %s\n", COMP_VERSION);
 #endif
+#if defined (USER_NAME) && defined(HOST_NAME) && defined(SYSTEM_TYPE)
+  fprintf(stderr, "Compiled: by %s on %s (%s) %s %s\n",
+	  USER_NAME, HOST_NAME, SYSTEM_TYPE, __DATE__, __TIME__);
+#endif
+
+  fprintf(stderr, "filetype: ");
+  for ( size_t i = 0; i < sizeof(filetypes)/sizeof(int); ++i )
+    if ( cdiHaveFiletype(filetypes[i]) ) fprintf(stderr, "%s ", typenames[i]);
+  fprintf(stderr, "\n");
+
   fprintf(stderr, "    with:");
 #if defined (HAVE_LIBPTHREAD)
   fprintf(stderr, " PTHREADS");
@@ -95,10 +108,6 @@ void version(void)
   fprintf(stderr, " CURL");
 #endif
   fprintf(stderr, "\n");
-#if defined (USER_NAME) && defined(HOST_NAME) && defined(SYSTEM_TYPE)
-  fprintf(stderr, "Compiled: by %s on %s (%s) %s %s\n",
-	  USER_NAME, HOST_NAME, SYSTEM_TYPE, __DATE__, __TIME__);
-#endif
   cdiPrintVersion();
   fprintf(stderr, "\n");
 /*
diff --git a/libcdi/config/default b/libcdi/config/default
index 0599021..d477177 100755
--- a/libcdi/config/default
+++ b/libcdi/config/default
@@ -18,10 +18,10 @@ case "${HOSTNAME}" in
                     --enable-swig \
                     --enable-python \
                     --with-jasper=/opt/local \
-                    --with-grib_api=$HOME/local/gribapi-1.9.16 \
+                    --with-grib_api=$HOME/local/gribapi-1.10.4 \
                     --with-netcdf=$HOME/local \
                     --with-szlib=$HOME/local \
-	            CC=gcc CFLAGS="-g -pipe -D_REENTRANT -Wall -W -Wfloat-equal -pedantic -O3 -march=native -Df2cFortran" LIBS="-L/opt/local/lib -lopenjpeg"
+	            CC=gcc CFLAGS="-g -pipe -D_REENTRANT -Wall -W -Wfloat-equal -pedantic -O3 -march=native -Df2cFortran"
 	;;
     cinglung*|feilung*|wanglung*)
 	./configure --prefix=$HOME/local \
diff --git a/libcdi/configure b/libcdi/configure
index b7b8067..c395507 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.6.0.
+# Generated by GNU Autoconf 2.68 for cdi 1.6.1.
 #
 # 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.6.0'
-PACKAGE_STRING='cdi 1.6.0'
+PACKAGE_VERSION='1.6.1'
+PACKAGE_STRING='cdi 1.6.1'
 PACKAGE_BUGREPORT='http://code.zmaw.de/projects/cdi'
 PACKAGE_URL=''
 
@@ -674,6 +674,9 @@ PTHREAD_CFLAGS
 PTHREAD_LIBS
 PTHREAD_CC
 ax_pthread_config
+SYSTEM_TYPE
+HOST_NAME
+USER_NAME
 AS
 CXXCPP
 am__fastdepCXX_FALSE
@@ -758,9 +761,6 @@ am__isrc
 INSTALL_DATA
 INSTALL_SCRIPT
 INSTALL_PROGRAM
-SYSTEM_TYPE
-HOST_NAME
-USER_NAME
 host_os
 host_vendor
 host_cpu
@@ -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.6.0 to adapt to many kinds of systems.
+\`configure' configures cdi 1.6.1 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.6.0:";;
+     short | recursive ) echo "Configuration of cdi 1.6.1:";;
    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.6.0
+cdi configure 1.6.1
 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.6.0, which was
+It was created by cdi $as_me 1.6.1, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
@@ -2849,41 +2849,6 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
 
 
 
-# Checks for username, hostname and system type
-USERNAME=$LOGNAME
-if test -z "$USERNAME" ; then USERNAME=$USER; fi;
-if test -z "$USERNAME" ; then USERNAME="unknown"; fi;
-
-cat >>confdefs.h <<_ACEOF
-#define USER_NAME "$USERNAME"
-_ACEOF
-
-USER_NAME="$USERNAME"
-
-if test -z "$HOST"; then :
-  HOST=unknown
-       if test -x /bin/hostname; then :
-  HOST=$(hostname)
-else
-  if test -x /bin/uname; then :
-  HOST=$(uname -n)
-fi
-fi
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define HOST_NAME "$HOST"
-_ACEOF
-
-HOST_NAME="$HOST"
-
-
-cat >>confdefs.h <<_ACEOF
-#define SYSTEM_TYPE "$ac_cv_build"
-_ACEOF
-
-SYSTEM_TYPE="$ac_cv_build"
-
 
 am__api_version='1.11'
 
@@ -3323,7 +3288,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='cdi'
- VERSION='1.6.0'
+ VERSION='1.6.1'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -23887,6 +23852,62 @@ cat >>confdefs.h <<_ACEOF
 #define HAVE_DECL_ISNAN $ac_have_decl
 _ACEOF
 
+
+# Check compiler version
+case "$CC" in
+  pgcc*)  COMP_VERSION=`$CC -V | head -2 | tail -n 1`;;
+  *gcc*)  COMP_VERSION=`$CC --version | head -n 1`;;
+  g++*)   COMP_VERSION=`$CC --version | head -n 1`;;
+  clang*) COMP_VERSION=`$CC --version | head -n 1`;;
+  sxc*)   COMP_VERSION=`$CC -V 2>&1   | tail -n 1`;;
+  xlc*)   COMP_VERSION=`$CC -qversion 2>&1   | head -n 1`;;
+  *)      COMP_VERSION=`$CC -V 2>&1   | head -n 1`;;
+esac
+
+if test -z "$COMP_VERSION" ; then COMP_VERSION="unknown"; fi;
+
+cat >>confdefs.h <<_ACEOF
+#define COMP_VERSION "$COMP_VERSION"
+_ACEOF
+
+
+# Checks for username, hostname and system type
+USERNAME=$LOGNAME
+if test -z "$USERNAME" ; then USERNAME=$USER; fi;
+if test -z "$USERNAME" ; then USERNAME="unknown"; fi;
+
+cat >>confdefs.h <<_ACEOF
+#define USER_NAME "$USERNAME"
+_ACEOF
+
+USER_NAME="$USERNAME"
+
+
+if test -z "$HOST"; then :
+  HOST=unknown
+       if test -x /bin/hostname; then :
+  HOST=$(hostname)
+else
+  if test -x /bin/uname; then :
+  HOST=$(uname -n)
+fi
+fi
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HOST_NAME "$HOST"
+_ACEOF
+
+HOST_NAME="$HOST"
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SYSTEM_TYPE "$ac_cv_build"
+_ACEOF
+
+SYSTEM_TYPE="$ac_cv_build"
+
 #  ----------------------------------------------------------------------
 #  Check for math library
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for floor in -lm" >&5
@@ -26841,6 +26862,14 @@ fi
 
 
 
+# Checks for compiler
+COMPILER="$CC $CFLAGS"
+
+cat >>confdefs.h <<_ACEOF
+#define COMPILER "$COMPILER"
+_ACEOF
+
+
 ac_config_files="$ac_config_files tests/test_cksum_grib tests/test_cksum_nc tests/test_cksum_nc2 tests/test_cksum_nc4 tests/test_cksum_extra tests/test_cksum_service tests/test_cksum_ieg tests/pio_write_run tests/pio_cksum_mpinonb tests/pio_cksum_fpguard tests/pio_cksum_asynch tests/pio_cksum_writer util/serialrun"
 
 
@@ -27424,7 +27453,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by cdi $as_me 1.6.0, which was
+This file was extended by cdi $as_me 1.6.1, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -27490,7 +27519,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.6.0
+cdi config.status 1.6.1
 configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
diff --git a/libcdi/configure.ac b/libcdi/configure.ac
index 59a6a02..572104a 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.6.0], [http://code.zmaw.de/projects/cdi])
+AC_INIT([cdi], [1.6.1], [http://code.zmaw.de/projects/cdi])
 
 echo "configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}"
 
@@ -10,21 +10,6 @@ AC_CONFIG_MACRO_DIR([m4])
 AC_CANONICAL_HOST
 AC_CANONICAL_BUILD
 
-# Checks for username, hostname and system type
-USERNAME=$LOGNAME
-if test -z "$USERNAME" ; then USERNAME=$USER; fi;
-if test -z "$USERNAME" ; then USERNAME="unknown"; fi;
-AC_DEFINE_UNQUOTED([USER_NAME],["$USERNAME"], [User name])
-AC_SUBST([USER_NAME],["$USERNAME"])
-AS_IF([test -z "$HOST"],
-      [HOST=unknown
-       AS_IF([test -x /bin/hostname],[HOST=$(hostname)],
-             [AS_IF([test -x /bin/uname],
-                    [HOST=$(uname -n)])])])
-AC_DEFINE_UNQUOTED([HOST_NAME],["$HOST"],[Host name])
-AC_SUBST([HOST_NAME],["$HOST"])
-AC_DEFINE_UNQUOTED([SYSTEM_TYPE],["$ac_cv_build"], [System type])
-AC_SUBST([SYSTEM_TYPE],["$ac_cv_build"])
 
 AM_INIT_AUTOMAKE
 AC_CONFIG_HEADERS([src/config.h])
@@ -80,6 +65,38 @@ AC_CHECK_FUNCS([getline])
 # Checks for the availability of ANSI-C99 functions
 AC_CHECK_DECLS([isnan],,,[AC_INCLUDES_DEFAULT
 @%:@include <math.h>])
+
+# Check compiler version
+case "$CC" in
+  pgcc*)  COMP_VERSION=`$CC -V | head -2 | tail -n 1`;;
+  *gcc*)  COMP_VERSION=`$CC --version | head -n 1`;;
+  g++*)   COMP_VERSION=`$CC --version | head -n 1`;;
+  clang*) COMP_VERSION=`$CC --version | head -n 1`;;
+  sxc*)   COMP_VERSION=`$CC -V 2>&1   | tail -n 1`;;
+  xlc*)   COMP_VERSION=`$CC -qversion 2>&1   | head -n 1`;;
+  *)      COMP_VERSION=`$CC -V 2>&1   | head -n 1`;;
+esac
+
+if test -z "$COMP_VERSION" ; then COMP_VERSION="unknown"; fi;
+AC_DEFINE_UNQUOTED(COMP_VERSION, ["$COMP_VERSION"], [Compiler version])
+
+# Checks for username, hostname and system type
+USERNAME=$LOGNAME
+if test -z "$USERNAME" ; then USERNAME=$USER; fi;
+if test -z "$USERNAME" ; then USERNAME="unknown"; fi;
+AC_DEFINE_UNQUOTED([USER_NAME],["$USERNAME"], [User name])
+AC_SUBST([USER_NAME],["$USERNAME"])
+
+AS_IF([test -z "$HOST"],
+      [HOST=unknown
+       AS_IF([test -x /bin/hostname],[HOST=$(hostname)],
+             [AS_IF([test -x /bin/uname],
+                    [HOST=$(uname -n)])])])
+AC_DEFINE_UNQUOTED([HOST_NAME],["$HOST"],[Host name])
+AC_SUBST([HOST_NAME],["$HOST"])
+
+AC_DEFINE_UNQUOTED([SYSTEM_TYPE],["$ac_cv_build"], [System type])
+AC_SUBST([SYSTEM_TYPE],["$ac_cv_build"])
 #  ----------------------------------------------------------------------
 #  Check for math library
 AC_CHECK_LIB(m, floor)
@@ -179,6 +196,10 @@ AM_CONDITIONAL([USE_FC],[test -n "$FC" && test "X$FC" != "Xno" && test x$acx_cv_
 
 AC_SUBST([CPPFLAGS])
 
+# Checks for compiler
+COMPILER="$CC $CFLAGS"
+AC_DEFINE_UNQUOTED(COMPILER, ["$COMPILER"], [Compiler])
+
 AC_CONFIG_FILES([tests/test_cksum_grib \
                  tests/test_cksum_nc \
                  tests/test_cksum_nc2 \
diff --git a/libcdi/doc/cdi_cman.pdf b/libcdi/doc/cdi_cman.pdf
index 5a0b50c..e576acd 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 922bc90..fde69ee 100644
Binary files a/libcdi/doc/cdi_fman.pdf and b/libcdi/doc/cdi_fman.pdf differ
diff --git a/libcdi/examples/Makefile.am b/libcdi/examples/Makefile.am
index 850875f..4baab3a 100644
--- a/libcdi/examples/Makefile.am
+++ b/libcdi/examples/Makefile.am
@@ -2,7 +2,7 @@
 #
 EXTRA_DIST = cdi_read_f2003.f90 cdi_write_f2003.f90
 #
-noinst_PROGRAMS = cdi_write cdi_write_ens cdi_read cdi_copy
+noinst_PROGRAMS = cdi_write cdi_write_ens cdi_write_hybrid cdi_read cdi_copy
 if CREATE_ISOC
   noinst_PROGRAMS += cdi_read_f2003 cdi_write_f2003
 endif
@@ -16,6 +16,9 @@ cdi_write_LDADD         = $(top_builddir)/src/libcdi.la
 cdi_write_ens_SOURCES   = cdi_write_ens.c
 cdi_write_ens_LDADD     = $(top_builddir)/src/libcdi.la
 #
+cdi_write_hybrid_SOURCES   = cdi_write_hybrid.c
+cdi_write_hybrid_LDADD     = $(top_builddir)/src/libcdi.la
+#
 cdi_read_SOURCES        = cdi_read.c
 cdi_read_LDADD          = $(top_builddir)/src/libcdi.la
 #
diff --git a/libcdi/examples/Makefile.in b/libcdi/examples/Makefile.in
index af319b6..31c5962 100644
--- a/libcdi/examples/Makefile.in
+++ b/libcdi/examples/Makefile.in
@@ -52,7 +52,8 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 noinst_PROGRAMS = cdi_write$(EXEEXT) cdi_write_ens$(EXEEXT) \
-	cdi_read$(EXEEXT) cdi_copy$(EXEEXT) $(am__EXEEXT_1)
+	cdi_write_hybrid$(EXEEXT) cdi_read$(EXEEXT) cdi_copy$(EXEEXT) \
+	$(am__EXEEXT_1)
 @CREATE_ISOC_TRUE at am__append_1 = cdi_read_f2003 cdi_write_f2003
 subdir = examples
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
@@ -113,6 +114,9 @@ cdi_write_f2003_DEPENDENCIES = $(top_builddir)/src/libcdi.la \
 cdi_write_f2003_LINK = $(LIBTOOL) --tag=FC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(FCLD) $(AM_FCFLAGS) $(FCFLAGS) \
 	$(cdi_write_f2003_LDFLAGS) $(LDFLAGS) -o $@
+am_cdi_write_hybrid_OBJECTS = cdi_write_hybrid.$(OBJEXT)
+cdi_write_hybrid_OBJECTS = $(am_cdi_write_hybrid_OBJECTS)
+cdi_write_hybrid_DEPENDENCIES = $(top_builddir)/src/libcdi.la
 DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)/src
 depcomp = $(SHELL) $(top_srcdir)/config/depcomp
 am__depfiles_maybe = depfiles
@@ -135,10 +139,12 @@ FCLINK = $(LIBTOOL) --tag=FC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
 	$(LDFLAGS) -o $@
 SOURCES = $(cdi_copy_SOURCES) $(cdi_read_SOURCES) \
 	$(cdi_read_f2003_SOURCES) $(cdi_write_SOURCES) \
-	$(cdi_write_ens_SOURCES) $(cdi_write_f2003_SOURCES)
+	$(cdi_write_ens_SOURCES) $(cdi_write_f2003_SOURCES) \
+	$(cdi_write_hybrid_SOURCES)
 DIST_SOURCES = $(cdi_copy_SOURCES) $(cdi_read_SOURCES) \
 	$(cdi_read_f2003_SOURCES) $(cdi_write_SOURCES) \
-	$(cdi_write_ens_SOURCES) $(cdi_write_f2003_SOURCES)
+	$(cdi_write_ens_SOURCES) $(cdi_write_f2003_SOURCES) \
+	$(cdi_write_hybrid_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -334,6 +340,9 @@ cdi_write_LDADD = $(top_builddir)/src/libcdi.la
 cdi_write_ens_SOURCES = cdi_write_ens.c
 cdi_write_ens_LDADD = $(top_builddir)/src/libcdi.la
 #
+cdi_write_hybrid_SOURCES = cdi_write_hybrid.c
+cdi_write_hybrid_LDADD = $(top_builddir)/src/libcdi.la
+#
 cdi_read_SOURCES = cdi_read.c
 cdi_read_LDADD = $(top_builddir)/src/libcdi.la
 #
@@ -410,6 +419,9 @@ cdi_write_ens$(EXEEXT): $(cdi_write_ens_OBJECTS) $(cdi_write_ens_DEPENDENCIES) $
 cdi_write_f2003$(EXEEXT): $(cdi_write_f2003_OBJECTS) $(cdi_write_f2003_DEPENDENCIES) $(EXTRA_cdi_write_f2003_DEPENDENCIES) 
 	@rm -f cdi_write_f2003$(EXEEXT)
 	$(cdi_write_f2003_LINK) $(cdi_write_f2003_OBJECTS) $(cdi_write_f2003_LDADD) $(LIBS)
+cdi_write_hybrid$(EXEEXT): $(cdi_write_hybrid_OBJECTS) $(cdi_write_hybrid_DEPENDENCIES) $(EXTRA_cdi_write_hybrid_DEPENDENCIES) 
+	@rm -f cdi_write_hybrid$(EXEEXT)
+	$(LINK) $(cdi_write_hybrid_OBJECTS) $(cdi_write_hybrid_LDADD) $(LIBS)
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
@@ -421,6 +433,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdi_read.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdi_write.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdi_write_ens.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdi_write_hybrid.Po at am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
diff --git a/libcdi/examples/cdi_write_hybrid.c b/libcdi/examples/cdi_write_hybrid.c
new file mode 100644
index 0000000..dd4fc73
--- /dev/null
+++ b/libcdi/examples/cdi_write_hybrid.c
@@ -0,0 +1,122 @@
+#include <stdio.h>
+#include "cdi.h"
+
+#define  nlon   12 // Number of longitudes
+#define  nlat    6 // Number of latitudes 
+#define  nhlev   6 // Number of half hybrid levels    
+#define  nflev   5 // Number of full hybrid levels    
+#define  nts     3 // Number of time steps
+
+int main(void)
+{
+  int gridID, zaxisID1, zaxisID2, zaxisID3, zaxisID4, taxisID;
+  int vlistID, varID1, varID2, varID3, varID4, streamID, tsID;
+  int i, k, nmiss = 0;
+  double lons[nlon] = {0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330};
+  double lats[nlat] = {-75, -45, -15, 15, 45, 75};
+  double levs[nhlev] = {1, 2, 3, 4, 5, 6};
+  double levs2[nhlev] = {2, 3, 4, 5, 6, -1};
+  double vct[2*nhlev] = {0, 6000, 10000, 16000, 8000, 0, 0, 0.0004, 0.03, 0.2, 0.7, 1.0};
+  double var1[nlon*nlat];
+  double var2[nlon*nlat*nflev];
+  double var3[nlon*nlat*nhlev];
+  double var4[nlon*nlat*nflev];
+
+
+  // Create a regular lon/lat grid
+  gridID = gridCreate(GRID_LONLAT, nlon*nlat);
+  gridDefXsize(gridID, nlon);
+  gridDefYsize(gridID, nlat);
+  gridDefXvals(gridID, lons);
+  gridDefYvals(gridID, lats);
+
+  // Create a surface level Z-axis
+  zaxisID1 = zaxisCreate(ZAXIS_SURFACE, 1);
+
+  // Create a hybrid level Z-axis
+  zaxisID2 = zaxisCreate(ZAXIS_HYBRID, nflev);
+  zaxisDefLevels(zaxisID2, levs);
+  zaxisDefVct(zaxisID2, nhlev*2, vct);
+
+  // Create a hybrid half level Z-axis
+  zaxisID3 = zaxisCreate(ZAXIS_HYBRID, nhlev);
+  zaxisDefLevels(zaxisID3, levs);
+  zaxisDefVct(zaxisID3, nhlev*2, vct);
+
+  // Create a hybrid level Z-axis
+  zaxisID4 = zaxisCreate(ZAXIS_HYBRID, nflev);
+  zaxisDefLevels(zaxisID4, levs);
+  zaxisDefLbounds(zaxisID4, levs);
+  zaxisDefUbounds(zaxisID4, levs2);
+  zaxisDefVct(zaxisID4, nhlev*2, vct);
+ 
+  // Create a variable list
+  vlistID = vlistCreate();
+
+  // Define the variables
+  varID1 = vlistDefVar(vlistID, gridID, zaxisID1, TIME_VARIABLE);
+  varID2 = vlistDefVar(vlistID, gridID, zaxisID2, TIME_VARIABLE);
+  varID3 = vlistDefVar(vlistID, gridID, zaxisID3, TIME_VARIABLE);
+  varID4 = vlistDefVar(vlistID, gridID, zaxisID4, TIME_VARIABLE);
+
+  // Define the variable names
+  vlistDefVarName(vlistID, varID1, "sp");
+  vlistDefVarName(vlistID, varID2, "t");
+  vlistDefVarName(vlistID, varID3, "w");
+  vlistDefVarName(vlistID, varID4, "u");
+
+  // Create a Time axis
+  taxisID = taxisCreate(TAXIS_ABSOLUTE);
+
+  // Assign the Time axis to the variable list
+  vlistDefTaxis(vlistID, taxisID);
+
+  // Create a dataset in netCDF format
+  streamID = streamOpenWrite("example.nc", FILETYPE_NC);
+  if ( streamID < 0 )
+    {
+      fprintf(stderr, "%s\n", cdiStringError(streamID));
+      return(1);
+    }
+
+  // Assign the variable list to the dataset
+  streamDefVlist(streamID, vlistID);
+
+  // Loop over the number of time steps
+  for ( tsID = 0; tsID < nts; tsID++ )
+    {
+      // Set the verification date to 1985-01-01 + tsID
+      taxisDefVdate(taxisID, 19850101+tsID);
+      // Set the verification time to 12:00:00
+      taxisDefVtime(taxisID, 120000);
+      // Define the time step
+      streamDefTimestep(streamID, tsID);
+
+      // Init var1 and var2
+      for ( i = 0; i < nlon*nlat; ++i ) var1[i] = 1.1;
+      for ( k = 0; k < nflev; ++k )
+	for ( i = 0; i < nlon*nlat; ++i ) var2[i+k*nlon*nlat] = 2.2+k;
+      for ( k = 0; k < nhlev; ++k )
+	for ( i = 0; i < nlon*nlat; ++i ) var3[i+k*nlon*nlat] = -2.2-k;
+      for ( k = 0; k < nflev; ++k )
+	for ( i = 0; i < nlon*nlat; ++i ) var4[i+k*nlon*nlat] = 100+k;
+ 
+      // Write var1 and var2
+      streamWriteVar(streamID, varID1, var1, nmiss);
+      streamWriteVar(streamID, varID2, var2, nmiss);
+      streamWriteVar(streamID, varID3, var3, nmiss);
+      streamWriteVar(streamID, varID4, var4, nmiss);
+    }
+
+  // Close the output stream
+  streamClose(streamID);
+
+  // Destroy the objects
+  vlistDestroy(vlistID);
+  taxisDestroy(taxisID);
+  zaxisDestroy(zaxisID1);
+  zaxisDestroy(zaxisID2);
+  gridDestroy(gridID);
+
+  return 0;
+}
diff --git a/libcdi/src/Makefile.am b/libcdi/src/Makefile.am
index e11dea4..32433c1 100644
--- a/libcdi/src/Makefile.am
+++ b/libcdi/src/Makefile.am
@@ -26,6 +26,7 @@ libcdi_la_SOURCES = 	 \
 	cdi_limits.h	 \
 	cdi_util.c       \
 	cdiFortran.c     \
+	cdiFortran.h     \
 	cfortran.h       \
 	cgribex.h	 \
 	cgribexlib.c  	 \
@@ -67,7 +68,7 @@ libcdi_la_SOURCES = 	 \
 	pio_posixasynch.c\
 	pio_posixfpguardsendrecv.c \
 	pio_posixnonb.c  \
-	pio_list_set.c			\
+	pio_list_set.c	 \
 	pio_rpc.c        \
 	pio_rpc.h        \
 	pio_server.c     \
@@ -91,8 +92,8 @@ libcdi_la_SOURCES = 	 \
 	stream_history.c \
 	stream_ieg.c     \
 	stream_ieg.h	 \
-	stream_int.c     \
-	stream_int.h	 \
+	cdi_int.c        \
+	cdi_int.h	 \
 	stream_record.c  \
 	stream_srv.c     \
 	stream_srv.h	 \
diff --git a/libcdi/src/Makefile.in b/libcdi/src/Makefile.in
index a230c5a..1acc867 100644
--- a/libcdi/src/Makefile.in
+++ b/libcdi/src/Makefile.in
@@ -118,11 +118,10 @@ am_libcdi_la_OBJECTS = basetime.lo binary.lo calendar.lo cdf.lo \
 	pio_posixnonb.lo pio_list_set.lo pio_rpc.lo pio_server.lo \
 	pio_util.lo resource_handle.lo servicelib.lo stream_cdf.lo \
 	stream_cgribex.lo stream_ext.lo stream_grb.lo \
-	stream_gribapi.lo stream_history.lo stream_ieg.lo \
-	stream_int.lo stream_record.lo stream_srv.lo stream_var.lo \
-	table.lo taxis.lo timebase.lo tsteps.lo util.lo varscan.lo \
-	version.lo vlist.lo vlist_att.lo vlist_var.lo zaxis.lo \
-	stream.lo swap.lo
+	stream_gribapi.lo stream_history.lo stream_ieg.lo cdi_int.lo \
+	stream_record.lo stream_srv.lo stream_var.lo table.lo taxis.lo \
+	timebase.lo tsteps.lo util.lo varscan.lo version.lo vlist.lo \
+	vlist_att.lo vlist_var.lo zaxis.lo stream.lo swap.lo
 libcdi_la_OBJECTS = $(am_libcdi_la_OBJECTS)
 @ENABLE_CDI_LIB_FALSE at am_libcdi_la_rpath =
 @ENABLE_CDI_LIB_TRUE at am_libcdi_la_rpath = -rpath $(libdir)
@@ -347,6 +346,7 @@ libcdi_la_SOURCES = \
 	cdi_limits.h	 \
 	cdi_util.c       \
 	cdiFortran.c     \
+	cdiFortran.h     \
 	cfortran.h       \
 	cgribex.h	 \
 	cgribexlib.c  	 \
@@ -388,7 +388,7 @@ libcdi_la_SOURCES = \
 	pio_posixasynch.c\
 	pio_posixfpguardsendrecv.c \
 	pio_posixnonb.c  \
-	pio_list_set.c			\
+	pio_list_set.c	 \
 	pio_rpc.c        \
 	pio_rpc.h        \
 	pio_server.c     \
@@ -412,8 +412,8 @@ libcdi_la_SOURCES = \
 	stream_history.c \
 	stream_ieg.c     \
 	stream_ieg.h	 \
-	stream_int.c     \
-	stream_int.h	 \
+	cdi_int.c        \
+	cdi_int.h	 \
 	stream_record.c  \
 	stream_srv.c     \
 	stream_srv.h	 \
@@ -552,6 +552,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdf_int.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdiFortran.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdi_error.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdi_int.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdi_util.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cgribexlib.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/dmemory.Plo at am__quote@
@@ -588,7 +589,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/stream_gribapi.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/stream_history.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/stream_ieg.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/stream_int.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/stream_record.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/stream_srv.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/stream_var.Plo at am__quote@
diff --git a/libcdi/src/calendar.c b/libcdi/src/calendar.c
index e98bf8e..fdb5fc0 100644
--- a/libcdi/src/calendar.c
+++ b/libcdi/src/calendar.c
@@ -302,7 +302,7 @@ int main(void)
   int year, month, day, hour, minute, second;
   int value = 30;
   int factor = 86400;
-  
+
   calendar = CALENDAR_360DAYS;
 
   year=1979; month=1; day=15; hour=12; minute=30; second = 0;
diff --git a/libcdi/src/cdf.c b/libcdi/src/cdf.c
index 0d25ff8..3c9bc95 100644
--- a/libcdi/src/cdf.c
+++ b/libcdi/src/cdf.c
@@ -10,7 +10,7 @@
 
 #include "cdf.h"
 #include "cdi.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "cdf_int.h"
 
 
diff --git a/libcdi/src/cdf_int.c b/libcdi/src/cdf_int.c
index 4a67fae..af8cddc 100644
--- a/libcdi/src/cdf_int.c
+++ b/libcdi/src/cdf_int.c
@@ -8,7 +8,7 @@
 #include <string.h>
 
 #include "cdi.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "cdf_int.h"
 
 
@@ -67,11 +67,11 @@ void cdf_create(const char *path, int cmode, int *ncidp)
   if ( CDF_Debug || status != NC_NOERR )
     Message("chunksizehint %d", chunksizehint);
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  if ( status != NC_NOERR ) Error("%s: %s", path, nc_strerror(status));
 
   status = nc_set_fill(*ncidp, NC_NOFILL, &oldfill);
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  if ( status != NC_NOERR ) Error("%s: %s", path, nc_strerror(status));
 }
 
 
diff --git a/libcdi/src/cdi.h b/libcdi/src/cdi.h
index 0342077..edb3132 100644
--- a/libcdi/src/cdi.h
+++ b/libcdi/src/cdi.h
@@ -158,7 +158,8 @@ extern "C" {
 #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                  */
+#define  ZAXIS_SNOW              19  /* Snow level                              */
+#define  ZAXIS_REFERENCE         20  /* zaxis reference number                  */
 
 /* TIME types */
 
@@ -243,6 +244,8 @@ void    cdiDebug(int debug);
 char   *cdiLibraryVersion(void);
 void    cdiPrintVersion(void);
 
+int     cdiHaveFiletype(int filetype);
+
 void    cdiDefMissval(double missval);
 double  cdiInqMissval(void);
 void    cdiDefGlobal(const char *string, int val);
@@ -503,6 +506,12 @@ void    vlistDefVarMissval(int vlistID, int varID, double missval);
 /*      vlistInqVarMissval: Get the missing value of a Variable */
 double  vlistInqVarMissval(int vlistID, int varID);
 
+/*      vlistDefVarExtra: Define extra information of a Variable */
+void    vlistDefVarExtra(int vlistID, int varID, const char *extra);
+
+/*      vlistInqVarExtra: Get extra information of a Variable */
+void    vlistInqVarExtra(int vlistID, int varID, char *extra);
+
 void    vlistDefVarScalefactor(int vlistID, int varID, double scalefactor);
 double  vlistInqVarScalefactor(int vlistID, int varID);
 void    vlistDefVarAddoffset(int vlistID, int varID, double addoffset);
@@ -528,27 +537,22 @@ 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) */
-/* ---------------------------------- */
+/* cdiClearAdditionalKeys: Clear the list of additional GRIB keys. */
+void    cdiClearAdditionalKeys();
+/* cdiDefAdditionalKey: Register an additional GRIB key which is read when file is opened. */
+void    cdiDefAdditionalKey(const char *string);
 
 /* 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);
+/* vlistHasVarKey: returns 1 if meta-data key was read, 0 otherwise. */
+int     vlistHasVarKey(int vlistID, int varID, const char *name);
 /* vlistInqVarDblKey: raw access to GRIB meta-data */
-double  vlistInqVarDblKey(int streamID, const char* name);
+double  vlistInqVarDblKey(int vlistID, int varID, 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);
+int     vlistInqVarIntKey(int vlistID, int varID, const char *name);
 
 
 /* VLIST attributes */
@@ -564,14 +568,14 @@ int     vlistDefAttInt(int vlistID, int varID, const char *name, int type, int l
 /*      vlistDefAttFlt: Define a floating point attribute */
 int     vlistDefAttFlt(int vlistID, int varID, const char *name, int type, int len, const double *dp_vec);
 /*      vlistDefAttTxt: Define a text attribute */
-int     vlistDefAttTxt(int vlistID, int varID, const char *name, int len, const char *tp);
+int     vlistDefAttTxt(int vlistID, int varID, const char *name, int len, const char *tp_cbuf);
 
 /*      vlistInqAttInt: Get the value(s) of an integer attribute */
 int     vlistInqAttInt(int vlistID, int varID, const char *name, int mlen, int *ip_vec);
 /*      vlistInqAttFlt: Get the value(s) of a floating point attribute */
 int     vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double *dp_vec);
 /*      vlistInqAttTxt: Get the value(s) of a text attribute */
-int     vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp);
+int     vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp_cbuf);
 
 
 /* GRID routines */
@@ -718,8 +722,8 @@ int     gridInqPosition(int gridID);
 void    gridDefPosition(int gridID, int position);
 int     gridInqReference(int gridID, char *reference);
 void    gridDefReference(int gridID, const char *reference);
-char   *gridInqUUID(int gridID, char *uuid);
-void    gridDefUUID(int gridID, const char *uuid);
+char   *gridInqUUID(int gridID, char *uuid_cbuf);
+void    gridDefUUID(int gridID, const char *uuid_cbuf);
 
 
 /* Lambert Conformal Conic grid (GRIB version) */
@@ -803,10 +807,10 @@ double  zaxisInqLevel(int zaxisID, int levelID);
 void    zaxisDefReference(int zaxisID, int refID);
 
 /*      zaxisDefUUID: Define the uuid of a generalized Z-axis */
-void    zaxisDefUUID(int zaxisID, const char *uuid);
+void    zaxisDefUUID(int zaxisID, const char *uuid_cbuf);
 
 /*      zaxisInqUUID: Get the reference of a generalized Z-axis */
-char   *zaxisInqUUID(int zaxisID, char *uuid);
+char   *zaxisInqUUID(int zaxisID, char *uuid_cbuf);
 
 /*      zaxisInqReference: Get the reference of a generalized Z-axis */
 int     zaxisInqReference(int zaxisID);
diff --git a/libcdi/src/cdi.inc b/libcdi/src/cdi.inc
index a6bd108..803cc92 100644
--- a/libcdi/src/cdi.inc
+++ b/libcdi/src/cdi.inc
@@ -1,10 +1,10 @@
 ! This file was automatically generated, don't edit!
 !
-! Fortran interface for CDI library version 1.6.0
+! Fortran interface for CDI library version 1.6.1
 !
 ! Author:
 ! -------
-! Uwe Schulzweida, MPI-MET, Hamburg,   March 2013
+! Uwe Schulzweida, MPI-MET, Hamburg,   June 2013
 !
 
       INTEGER    CDI_MAX_NAME          
@@ -266,8 +266,10 @@
       PARAMETER (ZAXIS_CLOUD_TOP        = 17)
       INTEGER    ZAXIS_ISOTHERM_ZERO   
       PARAMETER (ZAXIS_ISOTHERM_ZERO    = 18)
+      INTEGER    ZAXIS_SNOW            
+      PARAMETER (ZAXIS_SNOW             = 19)
       INTEGER    ZAXIS_REFERENCE       
-      PARAMETER (ZAXIS_REFERENCE        = 19)
+      PARAMETER (ZAXIS_REFERENCE        = 20)
 !
 !  TIME types
 !
@@ -424,6 +426,10 @@
 !                     cdiPrintVersion
       EXTERNAL        cdiPrintVersion
 
+      INTEGER         cdiHaveFiletype
+!                                    (INTEGER         filetype)
+      EXTERNAL        cdiHaveFiletype
+
 !                     cdiDefMissval
 !                                    (DOUBLEPRECISION missval)
       EXTERNAL        cdiDefMissval
@@ -1067,6 +1073,18 @@
 !                                     INTEGER         varID)
       EXTERNAL        vlistInqVarMissval
 
+!                     vlistDefVarExtra
+!                                    (INTEGER         vlistID,
+!                                     INTEGER         varID,
+!                                     CHARACTER*(*)   extra)
+      EXTERNAL        vlistDefVarExtra
+
+!                     vlistInqVarExtra
+!                                    (INTEGER         vlistID,
+!                                     INTEGER         varID,
+!                                     CHARACTER*(*)   extra)
+      EXTERNAL        vlistInqVarExtra
+
 !                     vlistDefVarScalefactor
 !                                    (INTEGER         vlistID,
 !                                     INTEGER         varID,
@@ -1183,15 +1201,10 @@
 !                                     INTEGER         forecast_type)
       EXTERNAL        vlistInqVarEnsemble
 
-!
-!  ----------------------------------
-!
-!
-!  Local change: 2013-01-28, FP (DWD)
-!
-!
-!  ----------------------------------
-!
+!                     cdiDefAdditionalKey
+!                                    (CHARACTER*(*)   string)
+      EXTERNAL        cdiDefAdditionalKey
+
 !                     vlistDefVarIntKey
 !                                    (INTEGER         vlistID,
 !                                     INTEGER         varID,
@@ -1206,23 +1219,23 @@
 !                                     DOUBLEPRECISION value)
       EXTERNAL        vlistDefVarDblKey
 
-!
-!  ----------------------------------
-!
-!
-!  Local change: 2013-02-18, FP (DWD)
-!
-!
-!  ----------------------------------
-!
-!                     vlistInqVarRawBegin
-!                                    (INTEGER         streamID,
-!                                     INTEGER         varID)
-      EXTERNAL        vlistInqVarRawBegin
+      INTEGER         vlistHasVarKey
+!                                    (INTEGER         vlistID,
+!                                     INTEGER         varID,
+!                                     CHARACTER*(*)   name)
+      EXTERNAL        vlistHasVarKey
 
-!                     vlistInqVarRawEnd
-!                                    (INTEGER         streamID)
-      EXTERNAL        vlistInqVarRawEnd
+      DOUBLEPRECISION vlistInqVarDblKey
+!                                    (INTEGER         vlistID,
+!                                     INTEGER         varID,
+!                                     CHARACTER*(*)   name)
+      EXTERNAL        vlistInqVarDblKey
+
+      INTEGER         vlistInqVarIntKey
+!                                    (INTEGER         vlistID,
+!                                     INTEGER         varID,
+!                                     CHARACTER*(*)   name)
+      EXTERNAL        vlistInqVarIntKey
 
 !
 !  VLIST attributes
@@ -1271,7 +1284,7 @@
 !                                     INTEGER         varID,
 !                                     CHARACTER*(*)   name,
 !                                     INTEGER         len,
-!                                     CHARACTER*(*)   tp)
+!                                     CHARACTER*(*)   tp_cbuf)
       EXTERNAL        vlistDefAttTxt
 
       INTEGER         vlistInqAttInt
@@ -1295,7 +1308,7 @@
 !                                     INTEGER         varID,
 !                                     CHARACTER*(*)   name,
 !                                     INTEGER         mlen,
-!                                     CHARACTER*(*)   tp)
+!                                     CHARACTER*(*)   tp_cbuf)
       EXTERNAL        vlistInqAttTxt
 
 !
@@ -1620,12 +1633,12 @@
 
       CHARACTER(80)   gridInqUUID
 !                                    (INTEGER         gridID,
-!                                     CHARACTER*(*)   uuid)
+!                                     CHARACTER*(*)   uuid_cbuf)
       EXTERNAL        gridInqUUID
 
 !                     gridDefUUID
 !                                    (INTEGER         gridID,
-!                                     CHARACTER*(*)   uuid)
+!                                     CHARACTER*(*)   uuid_cbuf)
       EXTERNAL        gridDefUUID
 
 !
@@ -1829,12 +1842,12 @@
 
 !                     zaxisDefUUID
 !                                    (INTEGER         zaxisID,
-!                                     CHARACTER*(*)   uuid)
+!                                     CHARACTER*(*)   uuid_cbuf)
       EXTERNAL        zaxisDefUUID
 
       CHARACTER(80)   zaxisInqUUID
 !                                    (INTEGER         zaxisID,
-!                                     CHARACTER*(*)   uuid)
+!                                     CHARACTER*(*)   uuid_cbuf)
       EXTERNAL        zaxisInqUUID
 
       INTEGER         zaxisInqReference
diff --git a/libcdi/src/cdiFortran.c b/libcdi/src/cdiFortran.c
index 47014c8..9ec4949 100644
--- a/libcdi/src/cdiFortran.c
+++ b/libcdi/src/cdiFortran.c
@@ -14,6 +14,10 @@
 #  include "cfortran.h"
 #endif
 
+#if ! defined (_CDIFORTRAN_H)
+#  include "cdiFortran.h"
+#endif
+
 
 /*  Byte order  */
 
@@ -78,6 +82,7 @@ FCALLSCFUN1 (STRING, cdiStringError, CDISTRINGERROR, cdistringerror, INT)
 FCALLSCSUB1 (cdiDebug, CDIDEBUG, cdidebug, INT)
 FCALLSCFUN0 (STRING, cdiLibraryVersion, CDILIBRARYVERSION, cdilibraryversion)
 FCALLSCSUB0 (cdiPrintVersion, CDIPRINTVERSION, cdiprintversion)
+FCALLSCFUN1 (INT, cdiHaveFiletype, CDIHAVEFILETYPE, cdihavefiletype, INT)
 FCALLSCSUB1 (cdiDefMissval, CDIDEFMISSVAL, cdidefmissval, DOUBLE)
 FCALLSCFUN0 (DOUBLE, cdiInqMissval, CDIINQMISSVAL, cdiinqmissval)
 FCALLSCSUB2 (cdiDefGlobal, CDIDEFGLOBAL, cdidefglobal, STRING, INT)
@@ -225,6 +230,8 @@ FCALLSCSUB3 (vlistDefVarUnits, VLISTDEFVARUNITS, vlistdefvarunits, INT, INT, STR
 FCALLSCSUB3 (vlistInqVarUnits, VLISTINQVARUNITS, vlistinqvarunits, INT, INT, PSTRING)
 FCALLSCSUB3 (vlistDefVarMissval, VLISTDEFVARMISSVAL, vlistdefvarmissval, INT, INT, DOUBLE)
 FCALLSCFUN2 (DOUBLE, vlistInqVarMissval, VLISTINQVARMISSVAL, vlistinqvarmissval, INT, INT)
+FCALLSCSUB3 (vlistDefVarExtra, VLISTDEFVAREXTRA, vlistdefvarextra, INT, INT, STRING)
+FCALLSCSUB3 (vlistInqVarExtra, VLISTINQVAREXTRA, vlistinqvarextra, INT, INT, PSTRING)
 FCALLSCSUB3 (vlistDefVarScalefactor, VLISTDEFVARSCALEFACTOR, vlistdefvarscalefactor, INT, INT, DOUBLE)
 FCALLSCFUN2 (DOUBLE, vlistInqVarScalefactor, VLISTINQVARSCALEFACTOR, vlistinqvarscalefactor, INT, INT)
 FCALLSCSUB3 (vlistDefVarAddoffset, VLISTDEFVARADDOFFSET, vlistdefvaraddoffset, INT, INT, DOUBLE)
@@ -247,28 +254,12 @@ 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)  */
-
-
-/*  ----------------------------------  */
-
+FCALLSCSUB1 (cdiDefAdditionalKey, CDIDEFADDITIONALKEY, cdidefadditionalkey, STRING)
 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)
+FCALLSCFUN3 (INT, vlistHasVarKey, VLISTHASVARKEY, vlisthasvarkey, INT, INT, STRING)
+FCALLSCFUN3 (DOUBLE, vlistInqVarDblKey, VLISTINQVARDBLKEY, vlistinqvardblkey, INT, INT, STRING)
+FCALLSCFUN3 (INT, vlistInqVarIntKey, VLISTINQVARINTKEY, vlistinqvarintkey, INT, INT, STRING)
 
 /*  VLIST attributes  */
 
@@ -277,10 +268,10 @@ FCALLSCFUN6 (INT, vlistInqAtt, VLISTINQATT, vlistinqatt, INT, INT, INT, PSTRING,
 FCALLSCFUN3 (INT, vlistDelAtt, VLISTDELATT, vlistdelatt, INT, INT, STRING)
 FCALLSCFUN6 (INT, vlistDefAttInt, VLISTDEFATTINT, vlistdefattint, INT, INT, STRING, INT, INT, PINT)
 FCALLSCFUN6 (INT, vlistDefAttFlt, VLISTDEFATTFLT, vlistdefattflt, INT, INT, STRING, INT, INT, PDOUBLE)
-FCALLSCFUN5 (INT, vlistDefAttTxt, VLISTDEFATTTXT, vlistdefatttxt, INT, INT, STRING, INT, STRING)
+FCALLSCFUN5 (INT, vlistDefAttTxt, VLISTDEFATTTXT, vlistdefatttxt, INT, INT, STRING, INT, CBUF)
 FCALLSCFUN5 (INT, vlistInqAttInt, VLISTINQATTINT, vlistinqattint, INT, INT, STRING, INT, PINT)
 FCALLSCFUN5 (INT, vlistInqAttFlt, VLISTINQATTFLT, vlistinqattflt, INT, INT, STRING, INT, PDOUBLE)
-FCALLSCFUN5 (INT, vlistInqAttTxt, VLISTINQATTTXT, vlistinqatttxt, INT, INT, STRING, INT, PSTRING)
+FCALLSCFUN5 (INT, vlistInqAttTxt, VLISTINQATTTXT, vlistinqatttxt, INT, INT, STRING, INT, CBUF)
 
 /*  GRID routines  */
 
@@ -357,8 +348,8 @@ FCALLSCFUN1 (INT, gridInqPosition, GRIDINQPOSITION, gridinqposition, INT)
 FCALLSCSUB2 (gridDefPosition, GRIDDEFPOSITION, griddefposition, INT, INT)
 FCALLSCFUN2 (INT, gridInqReference, GRIDINQREFERENCE, gridinqreference, INT, PSTRING)
 FCALLSCSUB2 (gridDefReference, GRIDDEFREFERENCE, griddefreference, INT, STRING)
-FCALLSCFUN2 (STRING, gridInqUUID, GRIDINQUUID, gridinquuid, INT, PSTRING)
-FCALLSCSUB2 (gridDefUUID, GRIDDEFUUID, griddefuuid, INT, STRING)
+FCALLSCFUN2 (STRING, gridInqUUID, GRIDINQUUID, gridinquuid, INT, CBUF)
+FCALLSCSUB2 (gridDefUUID, GRIDDEFUUID, griddefuuid, INT, CBUF)
 
 /*  Lambert Conformal Conic grid (GRIB version)  */
 
@@ -404,8 +395,8 @@ FCALLSCSUB2 (zaxisInqLevels, ZAXISINQLEVELS, zaxisinqlevels, INT, PDOUBLE)
 FCALLSCSUB3 (zaxisDefLevel, ZAXISDEFLEVEL, zaxisdeflevel, INT, INT, DOUBLE)
 FCALLSCFUN2 (DOUBLE, zaxisInqLevel, ZAXISINQLEVEL, zaxisinqlevel, INT, INT)
 FCALLSCSUB2 (zaxisDefReference, ZAXISDEFREFERENCE, zaxisdefreference, INT, INT)
-FCALLSCSUB2 (zaxisDefUUID, ZAXISDEFUUID, zaxisdefuuid, INT, STRING)
-FCALLSCFUN2 (STRING, zaxisInqUUID, ZAXISINQUUID, zaxisinquuid, INT, PSTRING)
+FCALLSCSUB2 (zaxisDefUUID, ZAXISDEFUUID, zaxisdefuuid, INT, CBUF)
+FCALLSCFUN2 (STRING, zaxisInqUUID, ZAXISINQUUID, zaxisinquuid, INT, CBUF)
 FCALLSCFUN1 (INT, zaxisInqReference, ZAXISINQREFERENCE, zaxisinqreference, INT)
 FCALLSCSUB2 (zaxisDefName, ZAXISDEFNAME, zaxisdefname, INT, STRING)
 FCALLSCSUB2 (zaxisDefLongname, ZAXISDEFLONGNAME, zaxisdeflongname, INT, STRING)
diff --git a/libcdi/src/cdiFortran.h b/libcdi/src/cdiFortran.h
new file mode 100644
index 0000000..500a2bc
--- /dev/null
+++ b/libcdi/src/cdiFortran.h
@@ -0,0 +1,20 @@
+#ifndef  _CDIFORTRAN_H
+#define  _CDIFORTRAN_H
+
+/*******************************************************************************
+ * Character buffer:
+ */
+
+#define CBUF_cfINT(N,A,B,X,Y,Z)		STRING_cfINT(N,A,B,X,Y,Z)
+#define CBUF_cfSEP(T,  B)		STRING_cfSEP(T,B)
+#define CBUF_cfN(  T,A)			STRING_cfN(T,A)
+#define CBUF_cfSTR(N,T,A,B,C,D,E)	STRING_cfSTR(N,T,A,B,C,D,E)
+#if defined(vmsFortran)
+#   define CBUF_cfT(M,I,A,B,D)		A->dsc$a_pointer
+#elif defined(CRAYFortran)
+#   define CBUF_cfT(M,I,A,B,D)		_fcdtocp(A)
+#else
+#   define CBUF_cfT(M,I,A,B,D)		A
+#endif
+
+#endif
diff --git a/libcdi/src/stream_int.c b/libcdi/src/cdi_int.c
similarity index 99%
rename from libcdi/src/stream_int.c
rename to libcdi/src/cdi_int.c
index cf69623..4aebb8c 100644
--- a/libcdi/src/stream_int.c
+++ b/libcdi/src/cdi_int.c
@@ -12,7 +12,7 @@
 #include "dmemory.h"
 
 #include "cdi.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "pio_util.h"
 #include "namespace.h"
 #include "resource_handle.h"
@@ -27,7 +27,7 @@ int cdiDefaultCalendar = CALENDAR_PROLEPTIC;
 int cdiDefaultInstID   = CDI_UNDEFID;
 int cdiDefaultModelID  = CDI_UNDEFID;
 int cdiDefaultTableID  = CDI_UNDEFID;
-int cdiNcMissingValue  = CDI_UNDEFID;
+//int cdiNcMissingValue  = CDI_UNDEFID;
 int cdiNcChunksizehint = CDI_UNDEFID;
 int cdiChunkType       = CHUNK_GRID;
 int cdiSplitLtype105   = CDI_UNDEFID;
@@ -194,10 +194,10 @@ void cdiInitialize(void)
 
       envString = getenv("CDI_MISSVAL");
       if ( envString ) cdiDefaultMissval = atof(envString);
-
+      /*
       envString = getenv("NC_MISSING_VALUE");
       if ( envString ) cdiNcMissingValue = atoi(envString);
-
+      */
       envString = getenv("NC_CHUNKSIZEHINT");
       if ( envString ) cdiNcChunksizehint = atoi(envString);
 
diff --git a/libcdi/src/stream_int.h b/libcdi/src/cdi_int.h
similarity index 96%
rename from libcdi/src/stream_int.h
rename to libcdi/src/cdi_int.h
index f6c3bc9..69978eb 100644
--- a/libcdi/src/stream_int.h
+++ b/libcdi/src/cdi_int.h
@@ -1,5 +1,5 @@
-#ifndef _STREAM_INT_H
-#define _STREAM_INT_H
+#ifndef _CDI_INT_H
+#define _CDI_INT_H
 
 #if defined (HAVE_CONFIG_H)
 #  include "config.h"
@@ -267,7 +267,7 @@ extern int cdiDefaultInstID;
 extern int cdiDefaultModelID;
 extern int cdiDefaultTableID;
 extern int cdiDefaultLeveltype;
-extern int cdiNcMissingValue;
+//extern int cdiNcMissingValue;
 extern int cdiNcChunksizehint;
 extern int cdiChunkType;
 extern int cdiSplitLtype105;
@@ -333,8 +333,18 @@ 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);
 
+#define CDI_UNIT_PA   1
+#define CDI_UNIT_HPA  2
+#define CDI_UNIT_MM   3
+#define CDI_UNIT_CM   4
+#define CDI_UNIT_DM   5
+#define CDI_UNIT_M    6
 
-#endif  /* _STREAM_INT_H */
+char *cdiUnitNamePtr(int cdi_unit);
+
+
+
+#endif  /* _CDI_INT_H */
 /*
  * Local Variables:
  * c-file-style: "Java"
diff --git a/libcdi/src/cdi_util.c b/libcdi/src/cdi_util.c
index b5fc74f..18c00b6 100644
--- a/libcdi/src/cdi_util.c
+++ b/libcdi/src/cdi_util.c
@@ -93,6 +93,30 @@ void cdiParamToString(int param, char *paramstr, int maxlen)
   if ( len > ( maxlen-1) )
     fprintf(stderr, "Internal problem (%s): size of input string is too small!\n", __func__);
 }
+
+
+char *cdiUnitNamePtr(int cdi_unit)
+{
+  char *cdiUnits[] = {
+    /*  0 */  "undefined",
+    /*  1 */  "Pa",
+    /*  2 */  "hPa",
+    /*  3 */  "mm",
+    /*  4 */  "cm",
+    /*  5 */  "dm",
+    /*  6 */  "m",
+  };
+  char *name;
+  int size = (int) (sizeof(cdiUnits)/sizeof(char *));
+
+  if ( cdi_unit > 0 && cdi_unit < size )
+    name = cdiUnits[cdi_unit];
+  else
+    name = NULL;
+
+  return (name);
+}
+
 /*
  * Local Variables:
  * c-file-style: "Java"
diff --git a/libcdi/src/cdilib.c b/libcdi/src/cdilib.c
index ba98417..b4aa0ba 100644
--- a/libcdi/src/cdilib.c
+++ b/libcdi/src/cdilib.c
@@ -1,7 +1,7 @@
 
-/* Automatically generated by m214003 at 2013-03-14, do not edit */
+/* Automatically generated by m214003 at 2013-06-28, do not edit */
 
-/* CDILIB_VERSION="1.6.0" */
+/* CDILIB_VERSION="1.6.1" */
 
 #if  defined  (HAVE_CONFIG_H)
 #  include "config.h"
@@ -596,7 +596,8 @@ extern "C" {
 #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                  */
+#define  ZAXIS_SNOW              19  /* Snow level                              */
+#define  ZAXIS_REFERENCE         20  /* zaxis reference number                  */
 
 /* TIME types */
 
@@ -681,6 +682,8 @@ void    cdiDebug(int debug);
 char   *cdiLibraryVersion(void);
 void    cdiPrintVersion(void);
 
+int     cdiHaveFiletype(int filetype);
+
 void    cdiDefMissval(double missval);
 double  cdiInqMissval(void);
 void    cdiDefGlobal(const char *string, int val);
@@ -941,6 +944,12 @@ void    vlistDefVarMissval(int vlistID, int varID, double missval);
 /*      vlistInqVarMissval: Get the missing value of a Variable */
 double  vlistInqVarMissval(int vlistID, int varID);
 
+/*      vlistDefVarExtra: Define extra information of a Variable */
+void    vlistDefVarExtra(int vlistID, int varID, const char *extra);
+
+/*      vlistInqVarExtra: Get extra information of a Variable */
+void    vlistInqVarExtra(int vlistID, int varID, char *extra);
+
 void    vlistDefVarScalefactor(int vlistID, int varID, double scalefactor);
 double  vlistInqVarScalefactor(int vlistID, int varID);
 void    vlistDefVarAddoffset(int vlistID, int varID, double addoffset);
@@ -966,27 +975,22 @@ 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) */
-/* ---------------------------------- */
+/* cdiClearAdditionalKeys: Clear the list of additional GRIB keys. */
+void    cdiClearAdditionalKeys();
+/* cdiDefAdditionalKey: Register an additional GRIB key which is read when file is opened. */
+void    cdiDefAdditionalKey(const char *string);
 
 /* 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);
+/* vlistHasVarKey: returns 1 if meta-data key was read, 0 otherwise. */
+int     vlistHasVarKey(int vlistID, int varID, const char *name);
 /* vlistInqVarDblKey: raw access to GRIB meta-data */
-double  vlistInqVarDblKey(int streamID, const char* name);
+double  vlistInqVarDblKey(int vlistID, int varID, 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);
+int     vlistInqVarIntKey(int vlistID, int varID, const char *name);
 
 
 /* VLIST attributes */
@@ -1002,14 +1006,14 @@ int     vlistDefAttInt(int vlistID, int varID, const char *name, int type, int l
 /*      vlistDefAttFlt: Define a floating point attribute */
 int     vlistDefAttFlt(int vlistID, int varID, const char *name, int type, int len, const double *dp_vec);
 /*      vlistDefAttTxt: Define a text attribute */
-int     vlistDefAttTxt(int vlistID, int varID, const char *name, int len, const char *tp);
+int     vlistDefAttTxt(int vlistID, int varID, const char *name, int len, const char *tp_cbuf);
 
 /*      vlistInqAttInt: Get the value(s) of an integer attribute */
 int     vlistInqAttInt(int vlistID, int varID, const char *name, int mlen, int *ip_vec);
 /*      vlistInqAttFlt: Get the value(s) of a floating point attribute */
 int     vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double *dp_vec);
 /*      vlistInqAttTxt: Get the value(s) of a text attribute */
-int     vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp);
+int     vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp_cbuf);
 
 
 /* GRID routines */
@@ -1156,8 +1160,8 @@ int     gridInqPosition(int gridID);
 void    gridDefPosition(int gridID, int position);
 int     gridInqReference(int gridID, char *reference);
 void    gridDefReference(int gridID, const char *reference);
-char   *gridInqUUID(int gridID, char *uuid);
-void    gridDefUUID(int gridID, const char *uuid);
+char   *gridInqUUID(int gridID, char *uuid_cbuf);
+void    gridDefUUID(int gridID, const char *uuid_cbuf);
 
 
 /* Lambert Conformal Conic grid (GRIB version) */
@@ -1241,10 +1245,10 @@ double  zaxisInqLevel(int zaxisID, int levelID);
 void    zaxisDefReference(int zaxisID, int refID);
 
 /*      zaxisDefUUID: Define the uuid of a generalized Z-axis */
-void    zaxisDefUUID(int zaxisID, const char *uuid);
+void    zaxisDefUUID(int zaxisID, const char *uuid_cbuf);
 
 /*      zaxisInqUUID: Get the reference of a generalized Z-axis */
-char   *zaxisInqUUID(int zaxisID, char *uuid);
+char   *zaxisInqUUID(int zaxisID, char *uuid_cbuf);
 
 /*      zaxisInqReference: Get the reference of a generalized Z-axis */
 int     zaxisInqReference(int zaxisID);
@@ -1430,6 +1434,8 @@ void    streamInqHistoryString(int streamID, char *history);
 #ifndef  _TIMEBASE_H
 #define  _TIMEBASE_H
 
+#include <inttypes.h>
+
 /* date format:  YYYYMMDD */
 /* time format:  hhmmss   */
 
@@ -1507,8 +1513,144 @@ DateTime;
  * require-trailing-newline: t
  * End:
  */
-#ifndef _STREAM_INT_H
-#define _STREAM_INT_H
+#if defined (HAVE_CONFIG_H)
+#  include "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 _CDI_INT_H
+#define _CDI_INT_H
 
 #if defined (HAVE_CONFIG_H)
 #  include "config.h"
@@ -1776,7 +1918,7 @@ extern int cdiDefaultInstID;
 extern int cdiDefaultModelID;
 extern int cdiDefaultTableID;
 extern int cdiDefaultLeveltype;
-extern int cdiNcMissingValue;
+//extern int cdiNcMissingValue;
 extern int cdiNcChunksizehint;
 extern int cdiChunkType;
 extern int cdiSplitLtype105;
@@ -1842,8 +1984,18 @@ 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);
 
+#define CDI_UNIT_PA   1
+#define CDI_UNIT_HPA  2
+#define CDI_UNIT_MM   3
+#define CDI_UNIT_CM   4
+#define CDI_UNIT_DM   5
+#define CDI_UNIT_M    6
 
-#endif  /* _STREAM_INT_H */
+char *cdiUnitNamePtr(int cdi_unit);
+
+
+
+#endif  /* _CDI_INT_H */
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -2123,6 +2275,7 @@ double calculate_pfactor(const double* spectralField, long fieldTruncation, long
 #define  GRIB2_LTYPE_HYBRID              105
 #define  GRIB2_LTYPE_LANDDEPTH           106
 #define  GRIB2_LTYPE_ISENTROPIC          107
+#define  GRIB2_LTYPE_SNOW                114
 #define  GRIB2_LTYPE_REFERENCE           150
 #define  GRIB2_LTYPE_SEADEPTH            160
 
@@ -2194,7 +2347,7 @@ 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);
+		  int unreduced, int *nmiss, int *zip, double missval, int vlistID, int varID);
 
 size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisID,
 		     int vdate, int vtime, int tsteptype, int numavg, 
@@ -3860,7 +4013,7 @@ int zaxisSize(void);
 
 
 void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
-		  int level1, int level2, int level_sf, int prec,
+		  int level1, int level2, int level_sf, int level_unit, int prec,
 		  int *pvarID, int *plevelID, int tsteptype, int numavg, int ltype,
 		  const char *name, const char *longname, const char *units);
 
@@ -3882,6 +4035,10 @@ void varDefTable(int varID, int tableID);
 int  varInqTable(int varID);
 void varDefEnsembleInfo(int varID, int ens_idx, int ens_count, int forecast_type);
 
+void varDefOptGribInt(int varID, long lval, const char *keyword);
+void varDefOptGribDbl(int varID, double dval, const char *keyword);
+int varOptGribNentries(int varID);
+
 int  zaxisCompare(int zaxisID, int zaxistype, int nlevels, int lbounds, double *levels, char *longname, char *units, int ltype);
 
 #endif
@@ -4322,6 +4479,7 @@ typedef struct
   char       *longname;
   char       *stdname;
   char       *units;
+  char       *extra;
   double      missval;
   double      scalefactor;
   double      addoffset;
@@ -4335,6 +4493,7 @@ typedef struct
   int         decoSize;
   deco_t     *deco;
 
+#if  defined  (HAVE_LIBGRIB_API)
   /* ---------------------------------- */
   /* Local change: 2013-01-28, FP (DWD) */
   /* ---------------------------------- */
@@ -4347,6 +4506,7 @@ typedef struct
   int    opt_grib_int_nentries;
   char*  opt_grib_int_keyword[MAX_OPT_GRIB_ENTRIES];
   int    opt_grib_int_val[MAX_OPT_GRIB_ENTRIES];
+#endif
 }
 var_t;
 
@@ -4398,6 +4558,11 @@ void    vlistDefVarValidrange(int vlistID, int varID, const double *validrange);
 /*      vlistInqVarValidrange: Get the valid range of a Variable */
 int     vlistInqVarValidrange(int vlistID, int varID, double *validrange);
 
+#if  defined  (HAVE_LIBGRIB_API)
+extern int   cdiNAdditionalGRIBKeys;
+extern char* cdiAdditionalGRIBKeys[];
+#endif
+
 #endif  /* _VLIST_H */
 /*
  * Local Variables:
@@ -5604,141 +5769,6 @@ extern void    Free   (const char *caller, const char *file, int line, void *ptr
 #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:
- */
-#if defined (HAVE_CONFIG_H)
-#endif
-
 #include <string.h>
 #ifdef USE_MPI
 #include <mpi.h>
@@ -7132,7 +7162,6 @@ void taxisPack ( void * voidP, void * packBuffer, int packBufferSize,
 #include <math.h>		/* for floor() */
 
 
-
 /* convert Julian date into year, months, day */
 void decode_julday(int calendar,
 		   int julday,	/* Julian day number to convert */
@@ -7773,7 +7802,7 @@ int main(void)
   int year, month, day, hour, minute, second;
   int value = 30;
   int factor = 86400;
-  
+
   calendar = CALENDAR_360DAYS;
 
   year=1979; month=1; day=15; hour=12; minute=30; second = 0;
@@ -7972,7 +8001,7 @@ int modelInq(int instID, int modelgribID, char *name)
 
       if ( modelptr->used )
         {
-          if ( name )
+          if ( name && *name )
             {
               found = 1;
               if ( instID      != -1 && modelptr->instID      != instID )      found = 0;
@@ -8015,7 +8044,7 @@ int modelDef(int instID, int modelgribID, const char *name)
 
   modelptr->instID      = instID;
   modelptr->modelgribID = modelgribID;
-  if ( name ) modelptr->name = strdupx(name);
+  if ( name && *name ) modelptr->name = strdupx(name);
 
   return modelptr->self;
 }
@@ -8344,8 +8373,12 @@ int institutInq(int center, int subcenter, const char *name, const char *longnam
   ip1->used       = 0;
   ip1->center     = center;
   ip1->subcenter  = subcenter;
-  ip1->name       = ( char * ) name;
-  ip1->longname   = ( char * ) longname;
+  ip1->name       = NULL;
+  ip1->longname   = NULL;
+  if ( name && *name )
+    ip1->name     = ( char * ) name;
+  if ( longname && *longname )
+    ip1->longname = ( char * ) longname;
 
   instCount = instituteCount ();
   instResHs = xmalloc ( instCount * sizeof ( int ));
@@ -8380,8 +8413,8 @@ int institutDef(int center, int subcenter, const char *name, const char *longnam
 
   instituteptr->center    = center;
   instituteptr->subcenter = subcenter;
-  if ( name )     instituteptr->name     = strdupx(name);
-  if ( longname ) instituteptr->longname = strdupx(longname);
+  if ( name && *name )         instituteptr->name     = strdupx(name);
+  if ( longname && *longname ) instituteptr->longname = strdupx(longname);
 
   return instituteptr->self;
 }
@@ -10038,6 +10071,7 @@ typedef struct
   int         ltype;     /* GRIB level type */
   int         lbounds;
   int         level_sf;
+  int         level_unit;
   int         zaxisID;
   int         nlevels;
   int         levelTableSize;
@@ -10053,6 +10087,16 @@ typedef struct
   char       *longname;
   char       *units;
   ensinfo_t  *ensdata;
+#if  defined  (HAVE_LIBGRIB_API)
+  /* (Optional) list of keyword/double value pairs */
+  int    opt_grib_dbl_nentries;
+  char*  opt_grib_dbl_keyword[MAX_OPT_GRIB_ENTRIES];
+  double opt_grib_dbl_val[MAX_OPT_GRIB_ENTRIES];
+  /* (Optional) list of keyword/integer value pairs */
+  int    opt_grib_int_nentries;
+  char*  opt_grib_int_keyword[MAX_OPT_GRIB_ENTRIES];
+  int    opt_grib_int_val[MAX_OPT_GRIB_ENTRIES];
+#endif
 }
 vartable_t;
 
@@ -10076,6 +10120,7 @@ void paramInitEntry(int varID, int param)
   vartable[varID].ltype          = 0;
   vartable[varID].lbounds        = 0;
   vartable[varID].level_sf       = 0;
+  vartable[varID].level_unit     = 0;
   vartable[varID].levelTable     = NULL;
   vartable[varID].levelTableSize = 0;
   vartable[varID].nlevels        = 0;
@@ -10239,7 +10284,13 @@ int paramNewEntry(int param)
 	}
 
       for( i = 0; i < varTablesize; i++ )
-	vartable[i].param = UNDEF_PARAM;
+	{
+	  vartable[i].param = UNDEF_PARAM;
+#if  defined  (HAVE_LIBGRIB_API)
+	  vartable[i].opt_grib_int_nentries = 0;
+	  vartable[i].opt_grib_dbl_nentries = 0;
+#endif
+	}
     }
   else
     {
@@ -10266,7 +10317,13 @@ int paramNewEntry(int param)
       varID = varTablesize/2;
 
       for( i = varID; i < varTablesize; i++ )
-	vartable[i].param = UNDEF_PARAM;
+	{
+	  vartable[i].param = UNDEF_PARAM;
+#if  defined  (HAVE_LIBGRIB_API)
+	  vartable[i].opt_grib_int_nentries = 0;
+	  vartable[i].opt_grib_dbl_nentries = 0;
+#endif
+	}
     }
 
   paramInitEntry(varID, param);
@@ -10276,7 +10333,7 @@ int paramNewEntry(int param)
 
 
 void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
-		  int level1, int level2, int level_sf, int prec,
+		  int level1, int level2, int level_sf, int level_unit, int prec,
 		  int *pvarID, int *plevelID, int tsteptype, int numavg, int ltype,
 		  const char *name, const char *longname, const char *units)
 {
@@ -10295,6 +10352,7 @@ void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
       vartable[varID].ltype     = ltype;
       vartable[varID].lbounds   = lbounds;
       vartable[varID].level_sf  = level_sf;
+      vartable[varID].level_unit = level_unit;
       if ( tsteptype != UNDEFID ) vartable[varID].tsteptype = tsteptype;
       if ( numavg ) vartable[varID].timave = 1;
 
@@ -10466,7 +10524,7 @@ void cdi_generate_vars(stream_t *streamptr)
       comptype  = vartable[varid].comptype;
 
       level_sf  = 1;
-      if ( vartable[varid].level_sf == 77 ) level_sf = 0.001;
+      if ( vartable[varid].level_sf != 0 ) level_sf = 1./vartable[varid].level_sf;
 
       zaxisID = UNDEFID;
 
@@ -10531,12 +10589,9 @@ void cdi_generate_vars(stream_t *streamptr)
 	    dlevels2[levelID] = level_sf*vartable[varid].levelTable[levelID].level2;
 	}
 
-      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);
+      char *unitptr = cdiUnitNamePtr(vartable[varid].level_unit);
+      zaxisID = varDefZaxis(vlistID, zaxistype, nlevels, dlevels, lbounds, dlevels1, dlevels2,
+                            Vctsize, Vct, NULL, NULL, unitptr, 0, 0, ltype);
 
       if ( lbounds ) free(dlevels1);
       if ( lbounds ) free(dlevels2);
@@ -10561,6 +10616,33 @@ void cdi_generate_vars(stream_t *streamptr)
 	                                                  vartable[varid].ensdata->ens_count,
 							  vartable[varid].ensdata->forecast_init_type);
 
+#if  defined  (HAVE_LIBGRIB_API)
+      /* ---------------------------------- */
+      /* Local change: 2013-04-23, FP (DWD) */
+      /* ---------------------------------- */
+
+      int    i;
+      vlist_t *vlistptr;
+      vlistptr = vlist_to_pointer(vlistID);
+      for (i=0; i<vartable[varid].opt_grib_int_nentries; i++)
+        {
+          int idx = vlistptr->vars[varID].opt_grib_int_nentries;
+          vlistptr->vars[varID].opt_grib_int_nentries++;
+          if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/integer value pairs!");
+          vlistptr->vars[varID].opt_grib_int_val[idx] = vartable[varid].opt_grib_int_val[idx];
+          vlistptr->vars[varID].opt_grib_int_keyword[idx] = strdupx(vartable[varid].opt_grib_int_keyword[idx]);
+        }
+      for (i=0; i<vartable[varid].opt_grib_dbl_nentries; i++)
+        {
+          int idx = vlistptr->vars[varID].opt_grib_dbl_nentries;
+          vlistptr->vars[varID].opt_grib_dbl_nentries++;
+          if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/double value pairs!");
+          vlistptr->vars[varID].opt_grib_dbl_val[idx] = vartable[varid].opt_grib_dbl_val[idx];
+          vlistptr->vars[varID].opt_grib_dbl_keyword[idx] = strdupx(vartable[varid].opt_grib_dbl_keyword[idx]);
+        }
+      /* note: if the key is not defined, we do not throw an error! */
+#endif
+
       if ( cdiDefaultTableID != UNDEFID )
 	{
 	  int pdis, pcat, pnum;
@@ -10604,7 +10686,7 @@ void cdi_generate_vars(stream_t *streamptr)
       for ( levelID = 0; levelID < nlevels; levelID++ )
 	{
 	  lindex = vartable[varid].levelTable[levelID].lindex;
-	  printf("%d %d %d %d %d\n", varID, levelID, 
+	  printf("%d %d %d %d %d\n", varID, levelID,
 		 vartable[varid].levelTable[levelID].lindex,
 		 vartable[varid].levelTable[levelID].recID,
 		 vartable[varid].levelTable[levelID].level1);
@@ -10644,7 +10726,7 @@ void varDefZAxisReference(int nlev, int nvgrid, char *uuid)
 {
   numberOfVerticalLevels = nlev;
   numberOfVerticalGrid = nvgrid;
-  strncpy(uuidVGrid, uuid, 16);
+  memcpy(uuidVGrid, uuid, 16);
 }
 
 
@@ -10936,6 +11018,40 @@ void varDefEnsembleInfo(int varID, int ens_idx, int ens_count, int forecast_type
   vartable[varID].ensdata->forecast_init_type = forecast_type;
 }
 
+
+void varDefOptGribInt(int varID, long lval, const char *keyword)
+{
+#if  defined  (HAVE_LIBGRIB_API)
+  int idx = vartable[varID].opt_grib_int_nentries;
+  vartable[varID].opt_grib_int_nentries++;
+  if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/integer value pairs!");
+  vartable[varID].opt_grib_int_val[idx] = (int) lval;
+  vartable[varID].opt_grib_int_keyword[idx] = strdupx(keyword);
+#endif
+}
+
+
+void varDefOptGribDbl(int varID, double dval, const char *keyword)
+{
+#if  defined  (HAVE_LIBGRIB_API)
+  int idx = vartable[varID].opt_grib_dbl_nentries;
+  vartable[varID].opt_grib_dbl_nentries++;
+  if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/double value pairs!");
+  vartable[varID].opt_grib_dbl_val[idx] = dval;
+  vartable[varID].opt_grib_dbl_keyword[idx] = strdupx(keyword);
+#endif
+}
+
+
+int varOptGribNentries(int varID)
+{
+  int nentries = 0;
+#if  defined  (HAVE_LIBGRIB_API)
+  nentries = vartable[varID].opt_grib_int_nentries + vartable[varID].opt_grib_dbl_nentries;
+#endif
+  return (nentries);
+}
+
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -10949,6 +11065,12 @@ void varDefEnsembleInfo(int varID, int ens_idx, int ens_count, int forecast_type
 #endif
 
 
+#if  defined  (HAVE_LIBGRIB_API)
+/* list of additional GRIB2 keywords which are read by the open process */
+int    cdiNAdditionalGRIBKeys = 0;
+char*  cdiAdditionalGRIBKeys[MAX_OPT_GRIB_ENTRIES];
+#endif
+
 extern void zaxisGetIndexList ( int, int * );
 
 static int VLIST_Debug = 0;
@@ -11159,6 +11281,7 @@ void vlistDestroy(int vlistID)
 
       if ( vlistptr->vars[varID].ensdata )  free(vlistptr->vars[varID].ensdata);
 
+#if  defined  (HAVE_LIBGRIB_API)
       int i;
       for (i=0; i<vlistptr->vars[varID].opt_grib_int_nentries; i++) {
 	if ( vlistptr->vars[varID].opt_grib_int_keyword[i] )
@@ -11168,6 +11291,7 @@ void vlistDestroy(int vlistID)
 	if ( vlistptr->vars[varID].opt_grib_dbl_keyword[i] )
 	  free(vlistptr->vars[varID].opt_grib_dbl_keyword[i]);
       }
+#endif
 
       vlistDelAtts(vlistID, varID);
     }
@@ -11235,6 +11359,7 @@ void vlistCopy(int vlistID2, int vlistID1)
                      vlistptr1->vars[varID].ensdata, sizeof(ensinfo_t));
             }
 
+#if  defined  (HAVE_LIBGRIB_API)
           /* ---------------------------------- */
           /* Local change: 2013-01-28, FP (DWD) */
           /* ---------------------------------- */
@@ -11254,6 +11379,7 @@ void vlistCopy(int vlistID2, int vlistID1)
 	      vlistptr2->vars[varID].opt_grib_dbl_val[i]     = vlistptr1->vars[varID].opt_grib_dbl_val[i];
 	    }
 	  }
+#endif
 
 	  vlistptr2->vars[varID].atts.nelems = 0;
 	  vlistCopyVarAtts(vlistID1, varID, vlistID2, varID);
@@ -11484,6 +11610,7 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
                        vlistptr1->vars[varID].ensdata, sizeof(ensinfo_t));
               }
 
+#if  defined  (HAVE_LIBGRIB_API)
 	    /* ---------------------------------- */
 	    /* Local change: 2013-01-28, FP (DWD) */
 	    /* ---------------------------------- */
@@ -11503,6 +11630,7 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
 		vlistptr2->vars[varID2].opt_grib_dbl_val[i]     = vlistptr1->vars[varID].opt_grib_dbl_val[i];
 	      }
 	    }
+#endif
 
 	    vlistptr2->vars[varID2].atts.nelems = 0;
 	    vlistCopyVarAtts(vlistID1, varID, vlistID2, varID2);
@@ -11703,6 +11831,7 @@ void vlistCat(int vlistID2, int vlistID1)
           memcpy(vlistptr2->vars[varID2].ensdata, vlistptr1->vars[varID].ensdata, sizeof(ensinfo_t));
         }
 
+#if  defined  (HAVE_LIBGRIB_API)
       /* ---------------------------------- */
       /* Local change: 2013-01-28, FP (DWD) */
       /* ---------------------------------- */
@@ -11722,6 +11851,7 @@ void vlistCat(int vlistID2, int vlistID1)
 	  vlistptr2->vars[varID2].opt_grib_dbl_val[i]     = vlistptr1->vars[varID].opt_grib_dbl_val[i];
 	}
       }
+#endif
 
       vlistptr2->vars[varID2].atts.nelems = 0;
       vlistCopyVarAtts(vlistID1, varID, vlistID2, varID2);
@@ -12926,7 +13056,7 @@ int vlist_def_att(int indtype, int exdtype, int vlistID, int varID, const char *
 
   if ( attp != NULL )
     fill_att(attp, indtype, exdtype, len, xsz, xp);
-  
+
   return (status);
 }
 
@@ -13016,11 +13146,7 @@ The function @func{vlistDefAttInt} defines an integer attribute.
 */
 int vlistDefAttInt(int vlistID, int varID, const char *name, int type, int len, const int *ip)
 {
-  int status;
-
-  status = vlist_def_att(DATATYPE_INT, type, vlistID, varID, name, (size_t) len, len*sizeof(int), (const void *) ip);
-
-  return (status);
+  return vlist_def_att(DATATYPE_INT, type, vlistID, varID, name, (size_t) len, len*sizeof(int), (const void *) ip);
 }
 
 /*
@@ -13044,11 +13170,7 @@ The function @func{vlistDefAttFlt} defines a floating point attribute.
 */
 int vlistDefAttFlt(int vlistID, int varID, const char *name, int type, int len, const double *dp)
 {
-  int status;
-
-  status = vlist_def_att(DATATYPE_FLT, type, vlistID, varID, name, (size_t) len, len*sizeof(double), (const void *) dp);
-
-  return (status);
+  return vlist_def_att(DATATYPE_FLT, type, vlistID, varID, name, (size_t) len, len*sizeof(double), (const void *) dp);
 }
 
 /*
@@ -13071,11 +13193,7 @@ The function @func{vlistDefAttTxt} defines a text attribute.
 */
 int vlistDefAttTxt(int vlistID, int varID, const char *name, int len, const char *tp)
 {
-  int status;
-
-  status = vlist_def_att(DATATYPE_TXT, DATATYPE_TXT, vlistID, varID, name, (size_t) len, len*sizeof(char), (const void *) tp);
-
-  return (status);
+  return vlist_def_att(DATATYPE_TXT, DATATYPE_TXT, vlistID, varID, name, (size_t) len, len*sizeof(char), (const void *) tp);
 }
 
 /*
@@ -13097,17 +13215,14 @@ The function @func{vlistInqAttInt} gets the values(s) of an integer attribute.
 */
 int vlistInqAttInt(int vlistID, int varID, const char *name, int mlen, int *ip)
 {
-  int status
-    = vlist_inq_att(DATATYPE_INT, vlistID, varID, name,
-                    mlen*sizeof(int), (void *) ip);
-  return status;
+  return vlist_inq_att(DATATYPE_INT, vlistID, varID, name, mlen*sizeof(int), (void *) ip);
 }
 
 /*
 @Function  vlistInqAttFlt
 @Title     Get the value(s) of a floating point attribute
 
- at Prototype int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, int *dp)
+ at Prototype int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double *dp)
 @Parameter
     @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
     @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
@@ -13122,18 +13237,14 @@ The function @func{vlistInqAttFlt} gets the values(s) of a floating point attrib
 */
 int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double *dp)
 {
-  int status = CDI_NOERR;
-
-  status = vlist_inq_att(DATATYPE_FLT, vlistID, varID, name, mlen*sizeof(double), (void *) dp);
-
-  return (status);
+  return vlist_inq_att(DATATYPE_FLT, vlistID, varID, name, mlen*sizeof(double), (void *) dp);
 }
 
 /*
 @Function  vlistInqAttTxt
 @Title     Get the value(s) of a text attribute
 
- at Prototype int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, int *tp)
+ at Prototype int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp)
 @Parameter
     @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
     @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
@@ -13148,11 +13259,7 @@ The function @func{vlistInqAttTxt} gets the values(s) of a text attribute.
 */
 int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp)
 {
-  int status = CDI_NOERR;
-
-  status = vlist_inq_att(DATATYPE_TXT, vlistID, varID, name, mlen*sizeof(char), (void *) tp);
-
-  return (status);
+  return vlist_inq_att(DATATYPE_TXT, vlistID, varID, name, mlen*sizeof(char), (void *) tp);
 }
 
 #ifdef USE_MPI
@@ -13365,6 +13472,7 @@ void vlistvarInitEntry(int vlistID, int varID)
   vlistptr->vars[varID].longname      = NULL;
   vlistptr->vars[varID].stdname       = NULL;
   vlistptr->vars[varID].units         = NULL;
+  vlistptr->vars[varID].extra         = NULL;
   vlistptr->vars[varID].nlevs         = 0;
   vlistptr->vars[varID].levinfo       = NULL;
   vlistptr->vars[varID].comptype      = COMPRESS_NONE;
@@ -13379,6 +13487,7 @@ void vlistvarInitEntry(int vlistID, int varID)
   vlistptr->vars[varID].decoSize      = 0;
   vlistptr->vars[varID].deco          = NULL;
 
+#if  defined  (HAVE_LIBGRIB_API)
   /* ---------------------------------- */
   /* Local change: 2013-01-28, FP (DWD) */
   /* ---------------------------------- */
@@ -13392,6 +13501,7 @@ void vlistvarInitEntry(int vlistID, int varID)
     vlistptr->vars[varID].opt_grib_int_keyword[i] = NULL;
     vlistptr->vars[varID].opt_grib_dbl_keyword[i] = NULL;
   } // for
+#endif
 }
 
 static
@@ -14168,16 +14278,16 @@ void vlistDefVarDatatype(int vlistID, int varID, int datatype)
     }
 
   vlistptr->vars[varID].datatype = datatype;
-  
+
   if ( vlistptr->vars[varID].missvalused == FALSE )
     switch (datatype)
       {
-      case DATATYPE_INT8:   vlistptr->vars[varID].missval = SCHAR_MIN; break;
-      case DATATYPE_UINT8:  vlistptr->vars[varID].missval = UCHAR_MAX; break;
-      case DATATYPE_INT16:  vlistptr->vars[varID].missval = SHRT_MIN;  break;
-      case DATATYPE_UINT16: vlistptr->vars[varID].missval = USHRT_MAX; break;
-      case DATATYPE_INT32:  vlistptr->vars[varID].missval = INT_MIN;   break;
-      case DATATYPE_UINT32: vlistptr->vars[varID].missval = UINT_MAX;  break;
+      case DATATYPE_INT8:   vlistptr->vars[varID].missval = -SCHAR_MAX; break;
+      case DATATYPE_UINT8:  vlistptr->vars[varID].missval =  UCHAR_MAX; break;
+      case DATATYPE_INT16:  vlistptr->vars[varID].missval = -SHRT_MAX;  break;
+      case DATATYPE_UINT16: vlistptr->vars[varID].missval =  USHRT_MAX; break;
+      case DATATYPE_INT32:  vlistptr->vars[varID].missval = -INT_MAX;   break;
+      case DATATYPE_UINT32: vlistptr->vars[varID].missval =  UINT_MAX;  break;
       }
 }
 
@@ -14493,6 +14603,87 @@ void vlistDefVarMissval(int vlistID, int varID, double missval)
   vlistptr->vars[varID].missvalused = TRUE;
 }
 
+/*
+ at Function  vlistDefVarExtra
+ at Title     Define extra information of a Variable
+
+ at Prototype void vlistDefVarExtra(int vlistID, int varID, const char *extra)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  varID    Variable identifier.
+    @Item  extra    Extra information.
+
+ at Description
+The function @func{vlistDefVarExtra} defines the extra information of a variable.
+
+ at EndFunction
+*/
+void vlistDefVarExtra(int vlistID, int varID, const char *extra)
+{
+  vlist_t *vlistptr;
+
+  if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
+    {
+      xwarning("%s", "Operation not executed." );
+      return;
+    }
+
+  vlistptr = vlist_to_pointer(vlistID);
+
+  vlistCheckVarID(__func__, vlistID, varID);
+
+  if ( extra )
+    {
+      if ( vlistptr->vars[varID].extra )
+	{
+	  free(vlistptr->vars[varID].extra);
+	  vlistptr->vars[varID].extra = NULL;
+	}
+
+      vlistptr->vars[varID].extra = strdupx(extra);
+    }
+}
+
+/*
+ at Function  vlistInqVarExtra
+ at Title     Get extra information of a Variable
+
+ at Prototype void vlistInqVarExtra(int vlistID, int varID, char *extra)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  varID    Variable identifier.
+    @Item  extra    Returned variable extra information. The caller must allocate space for the
+                    returned string. The maximum possible length, in characters, of
+                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
+
+ at Description
+The function @func{vlistInqVarExtra} returns the extra information of a variable.
+
+ at Result
+ at func{vlistInqVarExtra} returns the extra information of the variable to the parameter extra if available,
+otherwise the result is an empty string.
+
+ at EndFunction
+*/
+void vlistInqVarExtra(int vlistID, int varID, char *extra)
+{
+  int tableID;
+  int param;
+  int pdis, pcat, pnum;
+  vlist_t *vlistptr;
+
+  vlistptr = vlist_to_pointer(vlistID);
+
+  vlistCheckVarID(__func__, vlistID, varID);
+
+  if ( vlistptr->vars[varID].extra == NULL )
+      sprintf(extra, "-");
+  else
+    strcpy(extra, vlistptr->vars[varID].extra);
+
+  return;
+}
+
 
 int vlistInqVarValidrange(int vlistID, int varID, double *validrange)
 {
@@ -15133,6 +15324,7 @@ int vlistInqVarEnsemble( int vlistID, int varID, int *ensID, int *ensCount, int
 /* vlistDefVarIntKey: Set an arbitrary keyword/integer value pair for GRIB API */
 void vlistDefVarIntKey(int vlistID, int varID, const char *name, int value)
 {
+#if  defined  (HAVE_LIBGRIB_API)
   vlist_t *vlistptr;
   vlistptr = vlist_to_pointer(vlistID);
 
@@ -15144,11 +15336,13 @@ void vlistDefVarIntKey(int vlistID, int varID, const char *name, int value)
     vlistptr->vars[varID].opt_grib_int_keyword[idx] = strdupx(name);
   else
     Error("Internal error!");
+#endif
 }
 
 /* vlistDefVarDblKey: Set an arbitrary keyword/double value pair for GRIB API */
 void vlistDefVarDblKey(int vlistID, int varID, const char *name, double value)
 {
+#if  defined  (HAVE_LIBGRIB_API)
   vlist_t *vlistptr;
   vlistptr = vlist_to_pointer(vlistID);
 
@@ -15160,72 +15354,96 @@ void vlistDefVarDblKey(int vlistID, int varID, const char *name, double value)
     vlistptr->vars[varID].opt_grib_dbl_keyword[idx] = strdupx(name);
   else
     Error("Internal error!");
+#endif
 }
 
 #if  defined  (HAVE_LIBGRIB_API)
 #endif
 
-/* vlistInqVarRawBegin: Open GRIB record to retrieve raw meta-data in subsequent calls */
-void vlistInqVarRawBegin(int streamID, int varID)
+
+/* cdiClearAdditionalKeys: Clears the list of additional GRIB keys. */
+void cdiClearAdditionalKeys()
 {
 #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);
+  int i;
+  for (i=0; i<cdiNAdditionalGRIBKeys; i++)  free(cdiAdditionalGRIBKeys[i]);
+  cdiNAdditionalGRIBKeys = 0;
+#endif
+}
 
-  fileID  = streamInqFileID(streamID);
-  tsID    = streamptr->curTsID;
+/* cdiDefAdditionalKey: Register an additional GRIB key which is read when file is opened. */
+void cdiDefAdditionalKey(const char *name)
+{
+#if  defined  (HAVE_LIBGRIB_API)
+  int idx = cdiNAdditionalGRIBKeys;
+  cdiNAdditionalGRIBKeys++;
+  if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many additional keywords!");
+  if ( name )
+    cdiAdditionalGRIBKeys[idx] = strdupx(name);
+  else
+    Error("Internal error!");
+#endif
+}
 
-  // 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;
+/* vlistHasVarKey: returns 1 if meta-data key was read, 0 otherwise. */
+int vlistHasVarKey(int vlistID, int varID, const char* name)
+{
+#if  defined  (HAVE_LIBGRIB_API)
+  /* check if the GRIB key was previously read and is stored */
+  vlist_t *vlistptr;
+  int      i;
+  vlistptr = vlist_to_pointer(vlistID);
 
-  fileSetPos(fileID, recpos, SEEK_SET);
-  fileRead(fileID, streamptr->record->buffer, (size_t) recsize);
+  for (i=0; i<vlistptr->vars[varID].opt_grib_dbl_nentries; i++)
+    {
+      if ( strcmp(name, vlistptr->vars[varID].opt_grib_dbl_keyword[i]) == 0 )
+	return 1;
+    }
 
-  streamptr->gh = (void *) grib_handle_new_from_message(NULL, (void *) streamptr->record->buffer, recsize);
+  for (i=0; i<vlistptr->vars[varID].opt_grib_int_nentries; i++)
+    {
+      if ( strcmp(name, vlistptr->vars[varID].opt_grib_int_keyword[i]) == 0 )
+	return 1;
+    }
 #endif
+  return 0;
 }
 
-
 /* vlistInqVarDblKey: raw access to GRIB meta-data */
-double vlistInqVarDblKey(int streamID, const char* name)
+double vlistInqVarDblKey(int vlistID, int varID, 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);
+  /* check if the GRIB key was previously read and is stored in
+     "opt_grib_dbl_val" */
+  vlist_t *vlistptr;
+  vlistptr = vlist_to_pointer(vlistID);
+
+  int i;
+  for (i=0; i<vlistptr->vars[varID].opt_grib_dbl_nentries; i++)
+    if ( strcmp(name, vlistptr->vars[varID].opt_grib_dbl_keyword[i]) == 0 )
+      return vlistptr->vars[varID].opt_grib_dbl_val[i];
 #endif
   return value;
 }
 
 
 /* vlistInqVarIntKey: raw access to GRIB meta-data */
-int vlistInqVarIntKey(int streamID, const char* name)
+int vlistInqVarIntKey(int vlistID, int varID, 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;
-}
-
+  /* check if the GRIB key was previously read and is stored in
+     "opt_grib_int_val" */
+  vlist_t *vlistptr;
+  vlistptr = vlist_to_pointer(vlistID);
 
-/* 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);
+  int i;
+  for (i=0; i<vlistptr->vars[varID].opt_grib_int_nentries; i++)
+    if ( strcmp(name, vlistptr->vars[varID].opt_grib_int_keyword[i]) == 0 )
+      return vlistptr->vars[varID].opt_grib_int_val[i];
 #endif
+  return (int) value;
 }
 
 
@@ -19607,9 +19825,8 @@ void gridChangeType(int gridID, int gridtype)
 
   grid_check_ptr(gridID, gridptr);
 
-  Message("Changed grid type from %s to %s",
-          gridNamePtr(gridptr->type),
-          gridNamePtr(gridtype));
+  if ( CDI_Debug ) 
+    Message("Changed grid type from %s to %s", gridNamePtr(gridptr->type), gridNamePtr(gridtype));
 
   gridptr->type = gridtype;
 }
@@ -21648,7 +21865,7 @@ char *gridInqUUID(int gridID, char *uuid)
 
   grid_check_ptr(gridID, gridptr);
 
-  strncpy(uuid, gridptr->uuid, 16);
+  memcpy(uuid, gridptr->uuid, 16);
 
   return (uuid);
 }
@@ -21668,7 +21885,7 @@ void gridDefUUID(int gridID, const char *uuid)
 
   grid_check_ptr(gridID, gridptr);
 
-  strncpy(gridptr->uuid, uuid, 16);
+  memcpy(gridptr->uuid, uuid, 16);
 
   return;
 }
@@ -22296,11 +22513,11 @@ void gridPack ( void * voidP, void * packBuffer, int packBufferSize,
 
 
 static struct {
-  unsigned char positive;
+  unsigned char positive;   // 1: up;  2: down
   char *name;
   char *longname;
   char *stdname;
-  char *units;    // 1: up;  2: down
+  char *units;
 }
 ZaxistypeEntry[] = {
   { /*  0 */ 0, "sfc",        "surface",           "",               ""},
@@ -22322,7 +22539,8 @@ ZaxistypeEntry[] = {
   { /* 16 */ 0, "cloudbase",  "cloud_base",        "",               ""},
   { /* 17 */ 0, "cloudtop",   "cloud_top",         "",               ""},
   { /* 18 */ 0, "isotherm0",  "isotherm_zero",     "",               ""},
-  { /* 19 */ 0, "height",     "generalized height","height",         "m"},
+  { /* 19 */ 0, "snow",       "snow",              "",               ""},
+  { /* 20 */ 0, "height",     "generalized height","height",         "m"},
 };
 
 static int CDI_MaxZaxistype = sizeof(ZaxistypeEntry) / sizeof(ZaxistypeEntry[0]);
@@ -22458,7 +22676,7 @@ int zaxisSize(void)
                       @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_CLOUD_TOP}, @func{ZAXIS_ISOTHERM_ZERO}, @func{ZAXIS_SNOW},
                       @func{ZAXIS_DEPTH_BELOW_SEA} and @func{ZAXIS_DEPTH_BELOW_LAND}.
     @Item  size       Number of levels.
 
@@ -22991,7 +23209,7 @@ void zaxisDefUUID(int zaxisID, const char *uuid)
 
   zaxis_check_ptr(zaxisID, zaxisptr);
 
-  strncpy(zaxisptr->uuid, uuid, 16);
+  memcpy(zaxisptr->uuid, uuid, 16);
 
   return;
 }
@@ -23019,7 +23237,7 @@ char *zaxisInqUUID(int zaxisID, char *uuid)
 
   zaxis_check_ptr(zaxisID, zaxisptr);
 
-  strncpy(uuid, zaxisptr->uuid, 16);
+  memcpy(uuid, zaxisptr->uuid, 16);
 
   return (uuid);
 }
@@ -23269,7 +23487,7 @@ 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},
- at func{ZAXIS_CLOUD_TOP}, @func{ZAXIS_ISOTHERM_ZERO}, 
+ at func{ZAXIS_CLOUD_TOP}, @func{ZAXIS_ISOTHERM_ZERO}, @func{ZAXIS_SNOW},
 @func{ZAXIS_DEPTH_BELOW_SEA} and @func{ZAXIS_DEPTH_BELOW_LAND}.
 
 @EndFunction
@@ -24212,11 +24430,11 @@ void cdf_create(const char *path, int cmode, int *ncidp)
   if ( CDF_Debug || status != NC_NOERR )
     Message("chunksizehint %d", chunksizehint);
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  if ( status != NC_NOERR ) Error("%s: %s", path, nc_strerror(status));
 
   status = nc_set_fill(*ncidp, NC_NOFILL, &oldfill);
 
-  if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
+  if ( status != NC_NOERR ) Error("%s: %s", path, nc_strerror(status));
 }
 
 
@@ -25095,6 +25313,30 @@ void cdiParamToString(int param, char *paramstr, int maxlen)
   if ( len > ( maxlen-1) )
     fprintf(stderr, "Internal problem (%s): size of input string is too small!\n", __func__);
 }
+
+
+char *cdiUnitNamePtr(int cdi_unit)
+{
+  char *cdiUnits[] = {
+    /*  0 */  "undefined",
+    /*  1 */  "Pa",
+    /*  2 */  "hPa",
+    /*  3 */  "mm",
+    /*  4 */  "cm",
+    /*  5 */  "dm",
+    /*  6 */  "m",
+  };
+  char *name;
+  int size = (int) (sizeof(cdiUnits)/sizeof(char *));
+
+  if ( cdi_unit > 0 && cdi_unit < size )
+    name = cdiUnits[cdi_unit];
+  else
+    name = NULL;
+
+  return (name);
+}
+
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -25124,7 +25366,7 @@ int cdiDefaultCalendar = CALENDAR_PROLEPTIC;
 int cdiDefaultInstID   = CDI_UNDEFID;
 int cdiDefaultModelID  = CDI_UNDEFID;
 int cdiDefaultTableID  = CDI_UNDEFID;
-int cdiNcMissingValue  = CDI_UNDEFID;
+//int cdiNcMissingValue  = CDI_UNDEFID;
 int cdiNcChunksizehint = CDI_UNDEFID;
 int cdiChunkType       = CHUNK_GRID;
 int cdiSplitLtype105   = CDI_UNDEFID;
@@ -25291,10 +25533,10 @@ void cdiInitialize(void)
 
       envString = getenv("CDI_MISSVAL");
       if ( envString ) cdiDefaultMissval = atof(envString);
-
+      /*
       envString = getenv("NC_MISSING_VALUE");
       if ( envString ) cdiNcMissingValue = atoi(envString);
-
+      */
       envString = getenv("NC_CHUNKSIZEHINT");
       if ( envString ) cdiNcChunksizehint = atoi(envString);
 
@@ -25899,6 +26141,46 @@ void cdiDebug(int level)
 }
 
 
+int cdiHaveFiletype(int filetype)
+{
+  int status = 0;
+
+  switch (filetype)
+    {
+#if  defined  (HAVE_LIBSERVICE)
+    case FILETYPE_SRV:  { status = 1; break; }
+#endif
+#if  defined  (HAVE_LIBEXTRA)
+    case FILETYPE_EXT:  { status = 1; break; }
+#endif
+#if  defined  (HAVE_LIBIEG)
+    case FILETYPE_IEG:  { status = 1; break; }
+#endif
+#if  defined  (HAVE_LIBGRIB)
+#if  defined  (HAVE_LIBGRIB_API) || defined  (HAVE_LIBCGRIBEX)
+    case FILETYPE_GRB:  { status = 1; break; }
+#endif
+#if  defined  (HAVE_LIBGRIB_API)
+    case FILETYPE_GRB2: { status = 1; break; }
+#endif
+#endif
+#if  defined  (HAVE_LIBNETCDF)
+    case FILETYPE_NC:   { status = 1; break; }
+#if  defined  (HAVE_NETCDF2)
+    case FILETYPE_NC2:  { status = 1; break; }
+#endif
+#if  defined  (HAVE_NETCDF4)
+    case FILETYPE_NC4:  { status = 1; break; }
+    case FILETYPE_NC4C: { status = 1; break; }
+#endif
+#endif
+    default: { status = 0; break; }
+    }
+
+  return (status);
+}
+
+
 #undef  IsBigendian
 #define IsBigendian()  ( u_byteorder.c[sizeof(long) - 1] )
 
@@ -28623,7 +28905,7 @@ void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, d
   if ( datatype > 32 ) datatype = DATATYPE_PACK32;
   if ( datatype <  0 ) datatype = DATATYPE_PACK;
 
-  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, 0,
+  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, 0, 0,
 	       datatype, &varID, &levelID, tsteptype, numavg, ISEC1_LevelType, NULL, NULL, NULL);
 
   (*record).varID   = varID;
@@ -30672,15 +30954,14 @@ static
 int gribapiGetEndStep(grib_handle *gh, int startStep, int timeunits)
 {
   int endStep = startStep;
-  int timeunits2;
+  int timeunits2 = timeunits;
   int status;
   long unitsOfTime;
   long lpar;
 
-  // status = grib_get_long(gh, "stepUnits", &unitsOfTime);
-
-  // timeunits2 = getTimeunits(unitsOfTime);
-  timeunits2 = gribapiGetTimeUnits(gh);
+  status = grib_get_long(gh, "stepUnits", &unitsOfTime);
+  if ( status == 0 ) timeunits2 = getTimeunits(unitsOfTime);
+  //timeunits2 = gribapiGetTimeUnits(gh);
 
   status = grib_get_long(gh, "endStep", &lpar);
 
@@ -30811,8 +31092,9 @@ int gribapiGetValidityDateTime(grib_handle *gh, int *vdate, int *vtime)
 	static int lprint = TRUE;
 	extern int grib_calendar;
 	int ryear, rmonth, rday, rhour, rminute, rsecond;
-	int time_period = endStep;
-	int julday, secofday, addsec;
+	int julday, secofday;
+	int64_t time_period = endStep;
+        int64_t addsec;
 
 	cdiDecodeDate(rdate, &ryear, &rmonth, &rday);
 	cdiDecodeTime(rtime, &rhour, &rminute, &rsecond);
@@ -31088,7 +31370,7 @@ void gribapiGetGrid(grib_handle *gh, grid_t *grid)
             len = (size_t) 16;
             if ( grib_get_bytes(gh, "uuidOfHGrid", (unsigned char *) uuid, &len) == 0)
               {
-                strncpy(grid->uuid, uuid, 16);
+                memcpy(grid->uuid, uuid, 16);
               }
           }
 	break;
@@ -31169,7 +31451,7 @@ void grib1GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, i
 	  GRIB_CHECK(grib_get_double(gh, "level", &dlevel), 0);
 	  if ( *leveltype == 100 ) dlevel *= 100;
 	  if ( dlevel < -2.e9 || dlevel > 2.e9 ) dlevel = 0;
-	  if ( *leveltype == 99 ) *leveltype = 100;
+	  if ( *leveltype == GRIB1_LTYPE_99 ) *leveltype = 100;
 
 	  *level1 = (int) dlevel;
 	  *level2 = 0;
@@ -31185,81 +31467,77 @@ 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, int *level_sf)
+double grib2ScaleFactor(long factor)
+{
+  double scaleFactor = 0;
+
+  if      ( factor == 0 ) scaleFactor =    1;
+  else if ( factor == 1 ) scaleFactor =    0.1;
+  else if ( factor == 2 ) scaleFactor =    0.01;
+  else if ( factor == 3 ) scaleFactor =    0.001;
+  else if ( factor == 4 ) scaleFactor =    0.0001;
+
+  return (scaleFactor);
+}
+
+static
+void grib2GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, int *level2, int *level_sf, int *level_unit)
 {
   int status;
   int leveltype2 = -1;
   long lpar;
   long factor;
-  double dlevel;
 
-  *leveltype = 0;
-  *lbounds = 0;
-  *level1  = 0;
-  *level2  = 0;
-  *level_sf = 0;
+  *leveltype  = 0;
+  *lbounds    = 0;
+  *level1     = 0;
+  *level2     = 0;
+  *level_sf   = 0;
+  *level_unit = 0;
 
   status = grib_get_long(gh, "typeOfFirstFixedSurface", &lpar);
   if ( status == 0 )
     {
+      long llevel;
+      double dlevel1 = 0, dlevel2 = 0;
+
       *leveltype = (int) lpar;
 
       status = grib_get_long(gh, "typeOfSecondFixedSurface", &lpar);
       if ( status == 0 ) leveltype2 = lpar;
 
-      if ( *leveltype == leveltype2 && *leveltype != 255 ) *lbounds = 1;
+      if ( *leveltype != 255 && leveltype2 != 255 && leveltype2 > 0 ) *lbounds = 1;
 
-      if ( *lbounds == 0 )
-	{
-	  if ( *leveltype == GRIB2_LTYPE_LANDDEPTH )
-	    {
-	      GRIB_CHECK(grib_get_long(gh, "scaleFactorOfFirstFixedSurface", &factor), 0);
-	      GRIB_CHECK(grib_get_double(gh, "scaledValueOfFirstFixedSurface", &dlevel), 0);
-	      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
-	    {
-	      GRIB_CHECK(grib_get_double(gh, "level", &dlevel), 0);
-	      if ( *leveltype == GRIB2_LTYPE_ISOBARIC ) dlevel *= 100;
-	      if ( dlevel < -2.e9 || dlevel > 2.e9 ) dlevel = 0;
-	      if ( *leveltype == 99 ) *leveltype = 100;
-	    }
+      if ( *leveltype == GRIB2_LTYPE_LANDDEPTH )
+        {
+          *level_sf = 1000;
+          *level_unit = CDI_UNIT_M;
+        }
+      else if ( *leveltype == GRIB2_LTYPE_ISOBARIC )
+        {
+          *level_sf = 1000;
+          *level_unit = CDI_UNIT_PA;
+        }
 
-	  *level1 = (int) dlevel;
-	  *level2 = 0;
-	}
-      else
+      GRIB_CHECK(grib_get_long(gh, "scaleFactorOfFirstFixedSurface", &factor), 0);
+      GRIB_CHECK(grib_get_long(gh, "scaledValueOfFirstFixedSurface", &llevel), 0);
+      if ( llevel != GRIB_MISSING_LONG && factor != GRIB_MISSING_LONG )
+        dlevel1 = llevel*grib2ScaleFactor(factor);
+
+      if ( *level_sf != 0 ) dlevel1 *= (*level_sf);
+
+      if ( *lbounds == 1 )
 	{
-	  if ( *leveltype == GRIB2_LTYPE_LANDDEPTH )
-	    {
-	      GRIB_CHECK(grib_get_long(gh, "scaleFactorOfFirstFixedSurface", &factor), 0);
-	      GRIB_CHECK(grib_get_double(gh, "scaledValueOfFirstFixedSurface", &dlevel), 0);
-	      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 *= 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
-	    {
-	      GRIB_CHECK(grib_get_long(gh, "topLevel", &lpar), 0);
-	      *level1 = lpar;
-	      GRIB_CHECK(grib_get_long(gh, "bottomLevel", &lpar), 0);
-	      *level2 = lpar;
-	    }
-	}
+          GRIB_CHECK(grib_get_long(gh, "scaleFactorOfSecondFixedSurface", &factor), 0);
+          GRIB_CHECK(grib_get_long(gh, "scaledValueOfSecondFixedSurface", &llevel), 0);
+          if ( llevel != GRIB_MISSING_LONG && factor != GRIB_MISSING_LONG )
+            dlevel2 = llevel*grib2ScaleFactor(factor);
+
+          if ( *level_sf != 0 ) dlevel2 *= (*level_sf);
+        }
+
+      *level1 = (int) dlevel1;
+      *level2 = (int) dlevel2;
     }
 }
 
@@ -31273,10 +31551,11 @@ void gribapiGetString(grib_handle *gh, const char *key, char *string, size_t len
   else if ( length == 2 && memcmp(string, "~", length)       == 0 ) string[0] = 0;
 }
 
+#if  defined  (HAVE_LIBGRIB_API)
 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)
+                      int leveltype, int lbounds, int level1, int level2, int level_sf, int level_unit)
 {
   long editionNumber;
   int zaxistype;
@@ -31381,7 +31660,7 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
     }
   // fprintf(stderr, "param %d name %s %s %s\n", param, name, longname, units);
 
-  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, level_sf,
+  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, level_sf, level_unit,
 	       datatype, &varID, &levelID, tsteptype, numavg, leveltype,
 	       varname, longname, units);
 
@@ -31406,6 +31685,27 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
   if ( ens_index > 0 )
     varDefEnsembleInfo(varID, (int)ens_index, (int)ens_count, (int)ens_forecast_type);
 
+  int    i;
+  long   lval;
+  double dval;
+
+  /* we read the additional keys for the first variable record only. */
+  int linitial_field = (varOptGribNentries(varID) == 0);
+
+  for ( i = 0; i < cdiNAdditionalGRIBKeys; i++ )
+    {
+      if ( linitial_field )
+	{
+	  if ( grib_get_long(gh, cdiAdditionalGRIBKeys[i], &lval) == 0 )
+            varDefOptGribInt(varID, lval, cdiAdditionalGRIBKeys[i]);
+	}
+      if ( linitial_field )
+	{
+	  if ( grib_get_double(gh, cdiAdditionalGRIBKeys[i], &dval) == 0 )
+            varDefOptGribInt(varID, dval, cdiAdditionalGRIBKeys[i]);
+	}
+      /* note: if the key is not defined, we do not throw an error! */
+    }
 
   if ( varInqInst(varID) == CDI_UNDEFID )
     {
@@ -31459,6 +31759,7 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
     Message("varID = %d  param = %d  zaxistype = %d  gridID = %d  levelID = %d",
 	    varID, param, zaxistype, gridID, levelID);
 }
+#endif
 
 static
 int gribapiGetParam(grib_handle *gh)
@@ -31557,7 +31858,7 @@ int gribapiScanTimestep1(stream_t * streamptr)
   int bitsPerValue;
   int lieee = FALSE;
   int lbounds;
-  int level_sf;
+  int level_sf, level_unit;
   char paramstr[32];
   char varname[256];
 
@@ -31626,6 +31927,7 @@ int gribapiScanTimestep1(stream_t * streamptr)
 
 	  grib1GetLevel(gh, &leveltype, &lbounds, &level1, &level2);
           level_sf = 0;
+          level_unit = 0;
 	}
       else
 	{
@@ -31642,7 +31944,7 @@ int gribapiScanTimestep1(stream_t * streamptr)
 
 	  param = gribapiGetParam(gh);
 
-	  grib2GetLevel(gh, &leveltype, &lbounds, &level1, &level2, &level_sf);
+	  grib2GetLevel(gh, &leveltype, &lbounds, &level1, &level2, &level_sf, &level_unit);
 	}
 
       cdiParamToString(param, paramstr, sizeof(paramstr));
@@ -31737,7 +32039,7 @@ int gribapiScanTimestep1(stream_t * streamptr)
 	Message("%4d %8d %4d  %8d %8d %6d", nrecs, (int)recpos, param, level1, vdate, vtime);
 
       gribapiAddRecord(streamptr, param, gh, recsize, recpos, datatype, comptype, len, varname,
-                       leveltype, lbounds, level1, level2, level_sf);
+                       leveltype, lbounds, level1, level2, level_sf, level_unit);
 
       grib_handle_delete(gh);
       gh = NULL;
@@ -31846,7 +32148,7 @@ int gribapiScanTimestep2(stream_t * streamptr)
   long editionNumber;
   long lpar;
   int lbounds;
-  int level_sf;
+  int level_sf, level_unit;
   char paramstr[32];
   char varname[256];
 
@@ -31930,12 +32232,13 @@ int gribapiScanTimestep2(stream_t * streamptr)
 
 	  grib1GetLevel(gh, &leveltype, &lbounds, &level1, &level2);
           level_sf = 0;
+          level_unit = 0;
 	}
       else
 	{
 	  param = gribapiGetParam(gh);
 
-	  grib2GetLevel(gh, &leveltype, &lbounds, &level1, &level2, &level_sf);
+	  grib2GetLevel(gh, &leveltype, &lbounds, &level1, &level2, &level_sf, &level_unit);
 	}
 
       cdiParamToString(param, paramstr, sizeof(paramstr));
@@ -32109,7 +32412,7 @@ int gribapiScanTimestep(stream_t * streamptr)
   long editionNumber;
   long lpar;
   int lbounds;
-  int level_sf;
+  int level_sf, level_unit;
   char paramstr[32];
   char varname[256];
 
@@ -32200,12 +32503,13 @@ int gribapiScanTimestep(stream_t * streamptr)
 
 	      grib1GetLevel(gh, &leveltype, &lbounds, &level1, &level2);
               level_sf = 0;
+              level_unit = 0;
 	    }
 	  else
 	    {
 	      param = gribapiGetParam(gh);
 
-	      grib2GetLevel(gh, &leveltype, &lbounds, &level1, &level2, &level_sf);
+	      grib2GetLevel(gh, &leveltype, &lbounds, &level1, &level2, &level_sf, &level_unit);
 	    }
 
           cdiParamToString(param, paramstr, sizeof(paramstr));
@@ -32364,7 +32668,7 @@ int gribapiScanTimestep(stream_t * streamptr)
 
 
 int gribapiDecode(unsigned char *gribbuffer, int gribsize, double *data, int gridsize,
-		  int unreduced, int *nmiss, int *zip, double missval)
+		  int unreduced, int *nmiss, int *zip, double missval, int vlistID, int varID)
 {
   int status = 0;
 #if  defined  (HAVE_LIBGRIB_API)
@@ -33017,7 +33321,8 @@ 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_bytes(gh, "uuidOfHGrid", (unsigned char *) gridInqUUID(gridID, uuid), &len), 0);
+	    if (grib_set_bytes(gh, "uuidOfHGrid", (unsigned char *) gridInqUUID(gridID, uuid), &len) != 0)
+	      Warning("Can't write UUID!");
 	  }
 
 	break;
@@ -33031,35 +33336,85 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int ljpeg, i
 }
 
 static
-void getLevelFactor(double level, long *factor, double *scale)
+void getLevelFactor(double level, long *factor, long *out_scaled_value)
+{
+  double scaled_value  = level;
+  long   iscaled_value = (long) round(scaled_value);
+  long   i;
+
+  const double eps = 1.e-8;
+  for ( i=0; (fabs(scaled_value - (double) iscaled_value) >= eps) && i < 7; i++ )
+    {
+      scaled_value *= 10.;
+      iscaled_value = round(scaled_value);
+    }
+
+  (*factor)           = i;
+  (*out_scaled_value) = iscaled_value;
+}
+
+static
+void gribapiDefLevelType(grib_handle *gh, int gcinit, const char *keyname, long leveltype)
 {
-  double dum;
+  if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, keyname, leveltype), 0);
+}
+
+static
+void grib2DefLevel(grib_handle *gh, int gcinit, long leveltype, int lbounds, double level, double dlevel1, double dlevel2)
+{
+  long scaled_level;
+  long factor;
+
+  gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", leveltype);
+  if ( lbounds ) gribapiDefLevelType(gh, gcinit, "typeOfSecondFixedSurface", leveltype);
 
-  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; }
+  if ( !lbounds ) dlevel1 = level;
+
+  getLevelFactor(dlevel1, &factor, &scaled_level);
+  GRIB_CHECK(grib_set_long(gh, "scaleFactorOfFirstFixedSurface", factor), 0);
+  GRIB_CHECK(grib_set_long(gh, "scaledValueOfFirstFixedSurface", scaled_level), 0);
+
+  if ( lbounds )
+    {
+      getLevelFactor(dlevel2, &factor, &scaled_level);
+      GRIB_CHECK(grib_set_long(gh, "scaleFactorOfSecondFixedSurface", factor), 0);
+      GRIB_CHECK(grib_set_long(gh, "scaledValueOfSecondFixedSurface", scaled_level), 0);
+    }
 }
 
 static
 void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID, int levelID, int gcinit)
 {
   double level;
+  int lbounds = 0;
   int zaxistype, ltype;
   static int warning = 1;
   int reference;
   char uuid[17];
   size_t len;
+  double scalefactor;
+  double dlevel1 = 0, dlevel2 = 0;
+
 
   zaxistype = zaxisInqType(zaxisID);
   ltype = zaxisInqLtype(zaxisID);
   level = zaxisInqLevel(zaxisID, levelID);
 
+  if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
+    {
+      lbounds = 1;
+      dlevel1 = zaxisInqLbound(zaxisID, levelID);
+      dlevel2 = zaxisInqUbound(zaxisID, levelID);
+    }
+  else
+    {
+      dlevel1 = level;
+      dlevel2 = 0;
+    }
+
   if ( zaxistype == ZAXIS_GENERIC && ltype == 0 )
     {
-      Message("Changed zaxis type from %s to %s",
-	      zaxisNamePtr(zaxistype), zaxisNamePtr(ZAXIS_PRESSURE));
+      Message("Changed zaxis type from %s to %s", zaxisNamePtr(zaxistype), zaxisNamePtr(ZAXIS_PRESSURE));
       zaxistype = ZAXIS_PRESSURE;
       zaxisChangeType(zaxisID, zaxistype);
       zaxisDefUnits(zaxisID, "Pa");
@@ -33070,13 +33425,9 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
     case ZAXIS_SURFACE:
       {
 	if ( editionNumber <= 1 )
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_SURFACE), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_SURFACE);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_SURFACE), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_SURFACE);
 
         GRIB_CHECK(grib_set_long(gh, "level", level), 0);
 
@@ -33085,91 +33436,63 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
     case ZAXIS_CLOUD_BASE:
       {
 	if ( editionNumber <= 1 )
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_CLOUDBASE), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_CLOUDBASE);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_CLOUDBASE), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_CLOUDBASE);
 
         break;
       }
     case ZAXIS_CLOUD_TOP:
       {
 	if ( editionNumber <= 1 )
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_CLOUDTOP), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_CLOUDTOP);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_CLOUDTOP), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_CLOUDTOP);
 
         break;
       }
     case ZAXIS_ISOTHERM_ZERO:
       {
 	if ( editionNumber <= 1 )
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_ISOTHERM0), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_ISOTHERM0);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_ISOTHERM0), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_ISOTHERM0);
 
         break;
       }
     case ZAXIS_TOA:
       {
 	if ( editionNumber <= 1 )
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_TOA), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_TOA);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_TOA), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_TOA);
 
         break;
       }
     case ZAXIS_SEA_BOTTOM:
       {
 	if ( editionNumber <= 1 )
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_SEA_BOTTOM), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_SEA_BOTTOM);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_SEA_BOTTOM), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_SEA_BOTTOM);
 
         break;
       }
     case ZAXIS_ATMOSPHERE:
       {
 	if ( editionNumber <= 1 )
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_ATMOSPHERE), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_ATMOSPHERE);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_ATMOSPHERE), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_ATMOSPHERE);
 
         break;
       }
     case ZAXIS_MEANSEA:
       {
 	if ( editionNumber <= 1 )
-	  {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_MEANSEA), 0);
-          }
+	  gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_MEANSEA);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_MEANSEA), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_MEANSEA);
 
 	GRIB_CHECK(grib_set_double(gh, "level", level), 0);
 
@@ -33178,38 +33501,27 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
     case ZAXIS_HYBRID:
     case ZAXIS_HYBRID_HALF:
       {
-	if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
+	if ( lbounds )
 	  {
-	    long level1, level2;
-
 	    if ( editionNumber <= 1 )
-	      {
-                if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_HYBRID_LAYER), 0);
-              }
+	      gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_HYBRID_LAYER);
             else
 	      {
-		if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_HYBRID), 0);
-		if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfSecondFixedSurface", GRIB2_LTYPE_HYBRID), 0);
+		gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_HYBRID);
+		gribapiDefLevelType(gh, gcinit, "typeOfSecondFixedSurface", GRIB2_LTYPE_HYBRID);
 	      }
 
-	    level1 = zaxisInqLbound(zaxisID, levelID);
-	    level2 = zaxisInqUbound(zaxisID, levelID);
-
-	    GRIB_CHECK(grib_set_long(gh, "topLevel", level1), 0);
-	    GRIB_CHECK(grib_set_long(gh, "bottomLevel", level2), 0);
+	    GRIB_CHECK(grib_set_long(gh, "topLevel", (long) dlevel1), 0);
+	    GRIB_CHECK(grib_set_long(gh, "bottomLevel", (long) dlevel2), 0);
 	  }
 	else
 	  {
 	    if ( editionNumber <= 1 )
-              {
-                if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_HYBRID), 0);
-              }
+              gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_HYBRID);
             else
-              {
-                if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_HYBRID), 0);
-              }
+              gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_HYBRID);
 
-	    GRIB_CHECK(grib_set_long(gh, "level", level), 0);
+	    GRIB_CHECK(grib_set_long(gh, "level", (long) level), 0);
 	  }
 
         if ( !gcinit )
@@ -33236,47 +33548,49 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
 	if ( level < 0 ) Warning("Pressure level of %f Pa is below zero!", level);
 
 	zaxisInqUnits(zaxisID, units);
-	if ( memcmp(units, "Pa", 2) != 0 ) level *= 100;
+	if ( memcmp(units, "Pa", 2) != 0 )
+          {
+            level   *= 100;
+            dlevel1 *= 100;
+            dlevel2 *= 100;
+          }
 
-	if ( level < 32768 && (level < 100 || modf(level/100, &dum) > 0) )
-	  {
-	    if ( editionNumber <= 1 )
-              {
-                if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_99), 0);
-              }
+        if ( editionNumber <= 1 )
+          {
+            long leveltype = GRIB1_LTYPE_ISOBARIC;
+
+            if ( level < 32768 && (level < 100 || modf(level/100, &dum) > 0) )
+              leveltype = GRIB1_LTYPE_99;
             else
-              {
-                if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB1_LTYPE_99), 0);
-              }
+              level /= 100;
 
-	    GRIB_CHECK(grib_set_double(gh, "level", level), 0);
+            gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", leveltype);
+            GRIB_CHECK(grib_set_double(gh, "level", level), 0);
 	  }
 	else
 	  {
-	    if ( editionNumber <= 1 )
-              {
-                if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_ISOBARIC), 0);
-              }
-            else
-              {
-                if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_ISOBARIC), 0);
-              }
-            //GRIB_CHECK(grib_set_double(gh, "scaledValueOfFirstFixedSurface", level), 0);
-	    GRIB_CHECK(grib_set_double(gh, "level", level/100), 0);
+            grib2DefLevel(gh, gcinit, GRIB2_LTYPE_ISOBARIC, lbounds, level, dlevel1, dlevel2);
 	  }
 
 	break;
       }
-    case ZAXIS_HEIGHT:
+    case ZAXIS_SNOW:
       {
         if ( editionNumber <= 1 )
+          ; // not available
+	else
           {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_HEIGHT), 0);
+            grib2DefLevel(gh, gcinit, GRIB2_LTYPE_SNOW, lbounds, level, dlevel1, dlevel2);
           }
+
+	break;
+      }
+    case ZAXIS_HEIGHT:
+      {
+        if ( editionNumber <= 1 )
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_HEIGHT);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_HEIGHT), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_HEIGHT);
 
 	GRIB_CHECK(grib_set_double(gh, "level", level), 0);
 
@@ -33285,13 +33599,9 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
     case ZAXIS_ALTITUDE:
       {
         if ( editionNumber <= 1 )
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_ALTITUDE), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_ALTITUDE);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_ALTITUDE), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_ALTITUDE);
 
 	GRIB_CHECK(grib_set_double(gh, "level", level), 0);
 
@@ -33300,13 +33610,9 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
     case ZAXIS_SIGMA:
       {
 	if ( editionNumber <= 1 )
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_SIGMA), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_SIGMA);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_SIGMA), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_SIGMA);
 
 	GRIB_CHECK(grib_set_double(gh, "level", level), 0);
 
@@ -33320,50 +33626,26 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
 
 	if ( editionNumber <= 1 )
 	  {
-	    double factor;
-	    if      ( memcmp(units, "mm", 2) == 0 ) factor =   0.1;
-	    else if ( memcmp(units, "cm", 2) == 0 ) factor =   1;
-	    else if ( memcmp(units, "dm", 2) == 0 ) factor =  10;
-	    else                                    factor = 100; // meter
-
-	    if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_LANDDEPTH), 0);
-	    GRIB_CHECK(grib_set_double(gh, "level", level*factor), 0);
+	    if      ( memcmp(units, "mm", 2) == 0 ) scalefactor =   0.1;
+	    else if ( memcmp(units, "cm", 2) == 0 ) scalefactor =   1; // cm
+	    else if ( memcmp(units, "dm", 2) == 0 ) scalefactor =  10;
+	    else                                    scalefactor = 100;
+
+	    gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_LANDDEPTH);
+	    GRIB_CHECK(grib_set_double(gh, "level", level*scalefactor), 0);
 	  }
 	else
 	  {
-	    long factor;
-            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 = 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*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*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*scale), 0);
-	      }
+            level   *= scalefactor;
+            dlevel1 *= scalefactor;
+            dlevel1 *= scalefactor;
+
+            grib2DefLevel(gh, gcinit, GRIB2_LTYPE_LANDDEPTH, lbounds, level, dlevel1, dlevel2);
 	  }
 
 	break;
@@ -33371,13 +33653,9 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
     case ZAXIS_DEPTH_BELOW_SEA:
       {
 	if ( editionNumber <= 1 )
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_SEADEPTH), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_SEADEPTH);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_SEADEPTH), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_SEADEPTH);
 
 	GRIB_CHECK(grib_set_double(gh, "level", level), 0);
 
@@ -33386,13 +33664,9 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
     case ZAXIS_ISENTROPIC:
       {
 	if ( editionNumber <= 1 )
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_ISENTROPIC), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_ISENTROPIC);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_ISENTROPIC), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_ISENTROPIC);
 
 	GRIB_CHECK(grib_set_double(gh, "level", level), 0);
 
@@ -33405,12 +33679,13 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
         else
           {
             reference = zaxisInqReference(zaxisID);
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_REFERENCE), 0);
+            gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_REFERENCE);
             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_bytes(gh, "uuidOfVGrid", (unsigned char *) zaxisInqUUID(zaxisID, uuid), &len), 0);
+	    if (grib_set_bytes(gh, "uuidOfVGrid", (unsigned char *) zaxisInqUUID(zaxisID, uuid), &len) != 0)
+	      Warning("Can't write UUID!");
             GRIB_CHECK(grib_set_double(gh, "level", level), 0);
           }
 
@@ -33419,13 +33694,9 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
     case ZAXIS_GENERIC:
       {
 	if ( editionNumber <= 1 )
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", ltype), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", ltype);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", ltype), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", ltype);
 
 	GRIB_CHECK(grib_set_double(gh, "level", level), 0);
 
@@ -33614,14 +33885,14 @@ int grib1ltypeToZaxisType(int grib_ltype)
     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_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_ISENTROPIC:         { zaxistype = ZAXIS_ISENTROPIC;	break; }
     case GRIB1_LTYPE_SEADEPTH:           { zaxistype = ZAXIS_DEPTH_BELOW_SEA;   break; }
     }
 
@@ -33652,6 +33923,7 @@ int grib2ltypeToZaxisType(int grib_ltype)
     case GRIB2_LTYPE_LANDDEPTH:
  /* case GRIB2_LTYPE_LANDDEPTH_LAYER: */ { zaxistype = ZAXIS_DEPTH_BELOW_LAND;  break; }
     case GRIB2_LTYPE_ISENTROPIC:         { zaxistype = ZAXIS_ISENTROPIC;        break; }
+    case GRIB2_LTYPE_SNOW:               { zaxistype = ZAXIS_SNOW;              break; }
     case GRIB2_LTYPE_SEADEPTH:           { zaxistype = ZAXIS_DEPTH_BELOW_SEA;   break; }
     }
 
@@ -33700,16 +33972,25 @@ int grbDefRecord(stream_t * streamptr)
 
 static
 int grbDecode(int filetype, unsigned char *gribbuffer, int gribsize, double *data, int gridsize,
-	      int unreduced, int *nmiss, int *zip, double missval)
+	      int unreduced, int *nmiss, int *zip, double missval, int vlistID, int varID)
 {
   int status = 0;
 
 #if  defined  (HAVE_LIBCGRIBEX)
   if ( filetype == FILETYPE_GRB )
-    status = cgribexDecode(gribbuffer, gribsize, data, gridsize, unreduced, nmiss, zip, missval);
+    {
+#if  defined  (HAVE_LIBGRIB_API)
+      extern int cdiNAdditionalGRIBKeys;
+      if ( cdiNAdditionalGRIBKeys > 0 )
+	Error("CGRIBEX decode does not support reading of additional GRIB keys!");
+#endif
+      status = cgribexDecode(gribbuffer, gribsize, data, gridsize, unreduced, nmiss, zip, missval);
+    }
   else
 #endif
-    status = gribapiDecode(gribbuffer, gribsize, data, gridsize, unreduced, nmiss, zip, missval);
+    {
+      status = gribapiDecode(gribbuffer, gribsize, data, gridsize, unreduced, nmiss, zip, missval, vlistID, varID);
+    }
 
   return (status);
 }
@@ -33753,7 +34034,7 @@ int grbReadRecord(stream_t * streamptr, double *data, int *nmiss)
 
   missval = vlistInqVarMissval(vlistID, varID);
 
-  grbDecode(filetype, gribbuffer, recsize, data, gridsize, streamptr->unreduced, nmiss, &zip, missval);
+  grbDecode(filetype, gribbuffer, recsize, data, gridsize, streamptr->unreduced, nmiss, &zip, missval, vlistID, varID);
 
   streamptr->tsteps[tsID].records[recID].zip = zip;
 
@@ -33926,7 +34207,7 @@ void grbReadVarDP(stream_t * streamptr, int varID, double *data, int *nmiss)
       missval = vlistInqVarMissval(vlistID, varID);
 
       grbDecode(filetype, gribbuffer, recsize, &data[levelID*gridsize], gridsize,
-		streamptr->unreduced, &imiss, &zip, missval);
+		streamptr->unreduced, &imiss, &zip, missval, vlistID, varID);
 
       *nmiss += imiss;
 
@@ -33980,7 +34261,7 @@ void grbReadVarSliceDP(stream_t * streamptr, int varID, int levelID, double *dat
 
   missval = vlistInqVarMissval(vlistID, varID);
 
-  grbDecode(filetype, gribbuffer, recsize, data, gridsize, streamptr->unreduced, nmiss, &zip, missval);
+  grbDecode(filetype, gribbuffer, recsize, data, gridsize, streamptr->unreduced, nmiss, &zip, missval, vlistID, varID);
 
   fileSetPos(fileID, currentfilepos, SEEK_SET);
 
@@ -34067,7 +34348,7 @@ int grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype
   int ljpeg_warn = 1;
   void *gc = NULL;
 
-  if ( memtype == MEMTYPE_FLOAT ) Error("cdf_write_var_slice not implemented for memtype float!");
+  if ( memtype == MEMTYPE_FLOAT ) Error("grb_write_var_slice not implemented for memtype float!");
 
   filetype  = streamptr->filetype;
   fileID    = streamptr->fileID;
@@ -34539,7 +34820,7 @@ void srv_add_record(stream_t *streamptr, int param, int level, int xsize, int ys
 
   datatype = srvInqDatatype(prec);
 
-  varAddRecord(recID, param, gridID, leveltype, 0, level, 0, 0,
+  varAddRecord(recID, param, gridID, leveltype, 0, level, 0, 0, 0,
 	       datatype, &varID, &levelID, UNDEFID, 0, 0, NULL, NULL, NULL);
 
   (*record).varID   = varID;
@@ -35546,7 +35827,7 @@ void extAddRecord(stream_t *streamptr, int param, int level, int xysize,
   */
   leveltype = ZAXIS_GENERIC;
 
-  varAddRecord(recID, param, gridID, leveltype, 0, level, 0, 0,
+  varAddRecord(recID, param, gridID, leveltype, 0, level, 0, 0, 0,
 	       extInqDatatype(prec, number), &varID, &levelID, UNDEFID, 0, 0, NULL, NULL, NULL);
 
   (*record).varID   = varID;
@@ -37028,7 +37309,7 @@ void iegAddRecord(stream_t *streamptr, int param, int *pdb, int *gdb, double *vc
 
   datatype = iegInqDatatype(prec);
 
-  varAddRecord(recID, param, gridID, leveltype, lbounds, level1, level2, 0,
+  varAddRecord(recID, param, gridID, leveltype, lbounds, level1, level2, 0, 0,
 	       datatype, &varID, &levelID, UNDEFID, 0, 0, NULL, NULL, NULL);
 
   (*record).varID   = varID;
@@ -37836,7 +38117,8 @@ typedef struct {
   int      calendar;
   int      tableID;
   int      truncation;
-  int      defmiss;
+  int      defmissval;
+  int      deffillval;
   int      xtype;
   int      ndims;
   int      gmapid;
@@ -37854,6 +38136,7 @@ typedef struct {
   size_t   vlen;
   double  *vdata;
   double   missval;
+  double   fillval;
   double   addoffset;
   double   scalefactor;
   double   validrange[2];
@@ -37861,6 +38144,7 @@ typedef struct {
   char     longname[CDI_MAX_NAME];
   char     stdname[CDI_MAX_NAME];
   char     units[CDI_MAX_NAME];
+  char     extra[CDI_MAX_NAME];
   ensinfo_t   *ensdata;    /* Ensemble information */
 }
 ncvar_t;
@@ -38443,10 +38727,10 @@ void cdfDefVarMissval(stream_t *streamptr, int varID, int dtype, int lcheck)
 
       xtype = cdfDefDatatype(dtype, streamptr->filetype);
 
-      cdf_put_att_double(fileID, ncvarid, "_FillValue", (nc_type) xtype, 1, &missval);
+      if ( xtype == NC_BYTE && missval > 127 && missval < 256 ) xtype = NC_INT;
 
-      if ( cdiNcMissingValue == 1 )
-        cdf_put_att_double(fileID, ncvarid, "missing_value", (nc_type) xtype, 1, &missval);
+      cdf_put_att_double(fileID, ncvarid, "_FillValue", (nc_type) xtype, 1, &missval);
+      cdf_put_att_double(fileID, ncvarid, "missing_value", (nc_type) xtype, 1, &missval);
 
       if ( lcheck && streamptr->ncmode == 2 ) cdf_enddef(fileID);
 
@@ -41848,14 +42132,17 @@ void init_ncvars(long nvars, ncvar_t *ncvars)
       ncvars[ncvarid].positive        = 0;
       ncvars[ncvarid].chunked         = 0;
       ncvars[ncvarid].chunktype       = UNDEFID;
-      ncvars[ncvarid].defmiss         = 0;
+      ncvars[ncvarid].defmissval      = 0;
+      ncvars[ncvarid].deffillval      = 0;
       ncvars[ncvarid].missval         = 0;
+      ncvars[ncvarid].fillval         = 0;
       ncvars[ncvarid].addoffset       = 0;
       ncvars[ncvarid].scalefactor     = 1;
       ncvars[ncvarid].name[0]         = 0;
       ncvars[ncvarid].longname[0]     = 0;
       ncvars[ncvarid].stdname[0]      = 0;
       ncvars[ncvarid].units[0]        = 0;
+      ncvars[ncvarid].extra[0]        = 0;
       ncvars[ncvarid].natts           = 0;
       ncvars[ncvarid].atts            = NULL;
       ncvars[ncvarid].deflate         = 0;
@@ -42158,6 +42445,7 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
 #if  defined  (HAVE_NETCDF4)
       if ( format == NC_FORMAT_NETCDF4_CLASSIC || format == NC_FORMAT_NETCDF4 )
         {
+          char buf[CDI_MAX_NAME];
           int shuffle, deflate, deflate_level;
           size_t chunks[nvdims];
           int storage_in;
@@ -42170,10 +42458,20 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
                 {
                   ncvars[ncvarid].chunked = 1;
                   for ( int i = 0; i < nvdims; ++i ) ncvars[ncvarid].chunks[i] = chunks[i];
-                  /*
-                  printf("storage %d %d %d\n", storage_in, NC_CONTIGUOUS, NC_CHUNKED);
-                  for ( int i = 0; i < nvdims; ++i ) printf("chunk %d %d\n", i, chunks[i]);
-                  */
+                  if ( CDI_Debug )
+                    {
+                      fprintf(stderr, "\nchunking %d %d %d\nchunks ", storage_in, NC_CONTIGUOUS, NC_CHUNKED);
+                      for ( int i = 0; i < nvdims; ++i ) fprintf(stderr, "%ld ", chunks[i]);
+                      fprintf(stderr, "\n");
+                    }
+                  strcat(ncvars[ncvarid].extra, "chunks=");
+                  for ( int i = nvdims-1; i >= 0; --i )
+                    {
+                      sprintf(buf, "%ld", (long) chunks[i]);
+                      strcat(ncvars[ncvarid].extra, buf);
+                      if ( i > 0 ) strcat(ncvars[ncvarid].extra, "x");
+                    }
+                  strcat(ncvars[ncvarid].extra, " ");
                 }
             }
         }
@@ -42507,11 +42805,16 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
                   ncdims[ncvars[ncvarid].dimids[0]].dimtype = Z_AXIS;
                 }
             }
-          else if ( (strcmp(attname, "_FillValue") == 0 || strcmp(attname, "missing_value") == 0) &&
-		    atttype != NC_CHAR )
+          else if ( strcmp(attname, "_FillValue") == 0 && atttype != NC_CHAR )
+            {
+	      cdfGetAttDouble(ncid, ncvarid, attname, 1, &ncvars[ncvarid].fillval);
+	      ncvars[ncvarid].deffillval = TRUE;
+	      /* cdfSetVar(ncvars, ncvarid, TRUE); */
+            }
+          else if ( strcmp(attname, "missing_value") == 0 && atttype != NC_CHAR )
             {
 	      cdfGetAttDouble(ncid, ncvarid, attname, 1, &ncvars[ncvarid].missval);
-	      ncvars[ncvarid].defmiss = TRUE;
+	      ncvars[ncvarid].defmissval = TRUE;
 	      /* cdfSetVar(ncvars, ncvarid, TRUE); */
             }
           else if ( strcmp(attname, "valid_range") == 0 && attlen == 2 )
@@ -42979,7 +43282,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, char *uuidOfHGrid)
+void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nvars, ncvar_t *ncvars, int timedimid, char *uuidOfHGrid, int number_of_grid_used)
 {
   int ncvarid, ncvarid2;
   int ndims;
@@ -43410,6 +43713,13 @@ void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
 		}
 	    }
 
+	  if ( number_of_grid_used != UNDEFID &&
+               (grid.type == UNDEFID || grid.type == GRID_GENERIC) )
+	    {
+	      grid.type   = GRID_REFERENCE;
+	      grid.number = number_of_grid_used;
+	    }
+
 	  if ( ncvars[ncvarid].gmapid >= 0 && ncvars[ncvarid].gridtype != GRID_CURVILINEAR )
 	    {
 	      cdf_inq_varnatts(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, &nvatts);
@@ -43526,7 +43836,8 @@ 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 )
+          if ( uuidOfHGrid[0] != 0 && 
+	       (grid.type == GRID_UNSTRUCTURED || grid.type == GRID_REFERENCE) )
             gridDefUUID(ncvars[ncvarid].gridID, uuidOfHGrid);
 
           if ( ncvars[ncvarid].chunked )
@@ -43756,7 +44067,7 @@ void define_all_zaxes(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
 
 /* define all input data variables */
 static
-void define_all_vars(stream_t *streamptr, 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, int num_ncvars, ncvar_t *ncvars)
 {
   int ncid;
   int varID1, varID, ncvarid;
@@ -43807,9 +44118,7 @@ void define_all_vars(stream_t *streamptr, int vlistID, int instID, int modelID,
         vlistDefVarChunkType(vlistID, varID, ncvars[ncvarid].chunktype);
 #endif
 
-      streamptr->vars[varID1].level   = NULL;
       streamptr->vars[varID1].defmiss = 0;
-      streamptr->vars[varID1].nlevs   = zaxisInqSize(ncvars[ncvarid].zaxisID);
       streamptr->vars[varID1].ncvarid = ncvarid;
 
       vlistDefVarName(vlistID, varID, ncvars[ncvarid].name);
@@ -43840,7 +44149,14 @@ void define_all_vars(stream_t *streamptr, int vlistID, int instID, int modelID,
       if ( ncvars[ncvarid].tableID != UNDEFID )
 	vlistDefVarTable(vlistID, varID, ncvars[ncvarid].tableID);
 
-      if ( ncvars[ncvarid].defmiss == TRUE ) vlistDefVarMissval(vlistID, varID, ncvars[ncvarid].missval);
+      if ( ncvars[ncvarid].deffillval == FALSE && ncvars[ncvarid].defmissval == TRUE )
+        {
+          ncvars[ncvarid].deffillval = TRUE;
+          ncvars[ncvarid].fillval    = ncvars[ncvarid].missval;
+        }
+
+      if ( ncvars[ncvarid].deffillval == TRUE )
+        vlistDefVarMissval(vlistID, varID, ncvars[ncvarid].fillval);
 
       if ( CDI_Debug )
 	Message("varID = %d  gridID = %d  zaxisID = %d", varID,
@@ -43900,6 +44216,11 @@ void define_all_vars(stream_t *streamptr, int vlistID, int instID, int modelID,
           free(ncvars[ncvarid].ensdata);
           ncvars[ncvarid].ensdata = NULL;
         }
+
+      if ( ncvars[ncvarid].extra != NULL && ncvars[ncvarid].extra[0] != 0 )
+        {
+          vlistDefVarExtra(vlistID, varID, ncvars[ncvarid].extra);
+        }
     }
 
   for ( varID = 0; varID < nvars; varID++ )
@@ -43965,9 +44286,14 @@ void define_all_vars(stream_t *streamptr, int vlistID, int instID, int modelID,
 	    }
 
 	  free(ncvars[ncvarid].atts);
+          ncvars[ncvarid].atts = NULL;
 	}
     }
 
+  /* release mem of not freed attributes */
+  for ( ncvarid = 0; ncvarid < num_ncvars; ncvarid++ )
+    if ( ncvars[ncvarid].atts ) free(ncvars[ncvarid].atts);
+
   if ( varids ) free(varids);
 
   for ( varID = 0; varID < nvars; varID++ )
@@ -44044,7 +44370,7 @@ void define_all_vars(stream_t *streamptr, int vlistID, int instID, int modelID,
 
 static
 void scan_global_attributtes(int fileID, int vlistID, stream_t *streamptr, int ngatts,
-                             int *instID, int *modelID, int *ucla_les, char *uuidOfHGrid)
+                             int *instID, int *modelID, int *ucla_les, char *uuidOfHGrid, int *number_of_grid_used)
 {
   nc_type xtype;
   size_t attlen;
@@ -44110,15 +44436,23 @@ void scan_global_attributtes(int fileID, int vlistID, stream_t *streamptr, int n
 	}
       else if ( xtype == NC_SHORT || xtype == NC_INT )
 	{
-	  int *attint;
-	  attint = (int *) malloc(attlen*sizeof(int));
-	  cdfGetAttInt(fileID, NC_GLOBAL, attname, attlen, attint);
-	  if ( xtype == NC_SHORT )
-	    vlistDefAttInt(vlistID, CDI_GLOBAL, attname, DATATYPE_INT16, (int)attlen, attint);
-	  else
-	    vlistDefAttInt(vlistID, CDI_GLOBAL, attname, DATATYPE_INT32, (int)attlen, attint);
-	  free(attint);
-	}
+	  if ( strcmp(attname, "number_of_grid_used") == 0 )
+	    {
+	      (*number_of_grid_used) = UNDEFID;
+	      cdfGetAttInt(fileID, NC_GLOBAL, attname, 1, number_of_grid_used);
+	    }
+ 	  else
+            {
+              int *attint;
+              attint = (int *) malloc(attlen*sizeof(int));
+              cdfGetAttInt(fileID, NC_GLOBAL, attname, attlen, attint);
+              if ( xtype == NC_SHORT )
+                vlistDefAttInt(vlistID, CDI_GLOBAL, attname, DATATYPE_INT16, (int)attlen, attint);
+              else
+                vlistDefAttInt(vlistID, CDI_GLOBAL, attname, DATATYPE_INT32, (int)attlen, attint);
+              free(attint);
+            }
+        }
       else if ( xtype == NC_FLOAT || xtype == NC_DOUBLE )
 	{
 	  double *attflt;
@@ -44165,6 +44499,7 @@ int cdfInqContents(stream_t *streamptr)
   int format = 0;
   int ucla_les = FALSE;
   char uuidOfHGrid[17];
+  int number_of_grid_used = UNDEFID;
 
   uuidOfHGrid[0] = 0;
 
@@ -44236,7 +44571,7 @@ int cdfInqContents(stream_t *streamptr)
     }
 
   /* scan global attributtes */
-  scan_global_attributtes(fileID, vlistID, streamptr, ngatts, &instID, &modelID, &ucla_les, uuidOfHGrid);
+  scan_global_attributtes(fileID, vlistID, streamptr, ngatts, &instID, &modelID, &ucla_les, uuidOfHGrid, &number_of_grid_used);
 
   /* find time dim */
   if ( unlimdimid >= 0 )
@@ -44399,7 +44734,15 @@ int cdfInqContents(stream_t *streamptr)
       if ( ncvars[ncvarid].ndims > 4 )
 	{
 	  ncvars[ncvarid].isvar = 0;
-	  Warning("%d dimensional variables unsupported, skipped variable %s!",
+	  Warning("%d dimensional variables are not supported, skipped variable %s!",
+		ncvars[ncvarid].ndims, ncvars[ncvarid].name);
+	  continue;
+	}
+
+      if ( ncvars[ncvarid].ndims == 4 && timedimid == UNDEFID )
+	{
+	  ncvars[ncvarid].isvar = 0;
+	  Warning("%d dimensional variables without time dimension are not supported, skipped variable %s!",
 		ncvars[ncvarid].ndims, ncvars[ncvarid].name);
 	  continue;
 	}
@@ -44529,7 +44872,7 @@ int cdfInqContents(stream_t *streamptr)
 
 
   /* define all grids */
-  define_all_grids(streamptr, vlistID, ncdims, nvars, ncvars, timedimid, uuidOfHGrid);
+  define_all_grids(streamptr, vlistID, ncdims, nvars, ncvars, timedimid, uuidOfHGrid, number_of_grid_used);
 
 
   /* read VCT */
@@ -44571,7 +44914,7 @@ int cdfInqContents(stream_t *streamptr)
   streamptr->ntsteps = ntsteps;
 
   /* define all data variables */
-  define_all_vars(streamptr, vlistID, instID, modelID, varids, nvars_data, ncvars);
+  define_all_vars(streamptr, vlistID, instID, modelID, varids, nvars_data, nvars, ncvars);
 
 
   cdiCreateTimesteps(streamptr);
@@ -44669,10 +45012,10 @@ int cdfInqContents(stream_t *streamptr)
   cdfCreateRecords(streamptr, 0);
 
   /* free ncdims */
-  free (ncdims);
+  free(ncdims);
 
   /* free ncvars */
-  free (ncvars);
+  free(ncvars);
 
 #endif
 
@@ -45023,8 +45366,6 @@ void streamvar_init_entry(stream_t *streamptr, int varID)
   streamptr->vars[varID].gridID       = CDI_UNDEFID;
   streamptr->vars[varID].zaxisID      = CDI_UNDEFID;
   streamptr->vars[varID].tsteptype    = CDI_UNDEFID;
-  streamptr->vars[varID].level        = NULL;
-  streamptr->vars[varID].nlevs        = 0;
 }
 
 static
@@ -45826,7 +46167,7 @@ size_t getpagesize(void);
 #ifdef USE_MPI
 #endif
 
-#if ! defined(O_BINARY)
+#if ! defined (O_BINARY)
 #define O_BINARY 0
 #endif
 
@@ -45941,7 +46282,9 @@ static size_t FileBufferSizeMin = MIN_BUF_SIZE;
 static long   FileBufferSizeEnv = -1;
 static int    FileBufferTypeEnv =  0;
 
-static int    FileTypeEnv =  0;
+static int    FileTypeRead  = FILE_TYPE_OPEN;
+static int    FileTypeWrite = FILE_TYPE_FOPEN;
+static int    FileFlagWrite = 0;
 
 static int    FILE_Debug = 0;   /* If set to 1, debugging */
 
@@ -45952,7 +46295,7 @@ static void file_table_print(void);
  * A version string.
  */
 #undef   LIBVERSION
-#define  LIBVERSION      1.8.1
+#define  LIBVERSION      1.8.2
 #define  XSTRING(x)	 #x
 #define  STRING(x) 	 XSTRING(x)
 const char file_libvers[] = STRING(LIBVERSION) " of "__DATE__" "__TIME__;
@@ -45973,6 +46316,7 @@ const char file_libvers[] = STRING(LIBVERSION) " of "__DATE__" "__TIME__;
   11/11/2010  1.7.1 update for changed interface of error.h
   02/02/2012  1.8.0 cleanup
   16/11/2012  1.8.1 added support for unbuffered write
+  27/06/2013  1.8.2 added env. var. FILE_TYPE_WRITE (1:open; 2:fopen)
  */
 
 
@@ -46539,6 +46883,7 @@ static
 void file_initialize(void)
 {
   long value;
+  char *envString;
 
 #if  defined  (HAVE_LIBPTHREAD)
   /* initialize global API mutex lock */
@@ -46564,20 +46909,42 @@ void file_initialize(void)
       if ( value >= 0 ) FileBufferSizeEnv = value;
     }
 
-  value = file_getenv("FILE_TYPE");
+  value = file_getenv("FILE_TYPE_READ");
+  if ( value > 0 )
+    {
+      switch (value)
+	{
+	case FILE_TYPE_OPEN:
+	case FILE_TYPE_FOPEN:
+	  FileTypeRead = value;
+	  break;
+	default:
+	  Warning("File type %d not implemented!", value);
+	}
+    }
+
+  value = file_getenv("FILE_TYPE_WRITE");
   if ( value > 0 )
     {
       switch (value)
 	{
 	case FILE_TYPE_OPEN:
 	case FILE_TYPE_FOPEN:
-	  FileTypeEnv = value;
+	  FileTypeWrite = value;
 	  break;
 	default:
 	  Warning("File type %d not implemented!", value);
 	}
     }
 
+  envString = getenv("FILE_FLAG_WRITE");
+  if ( envString )
+    {
+#if defined (O_NONBLOCK)
+      if ( strcmp(envString, "NONBLOCK") == 0 ) FileFlagWrite = O_NONBLOCK;
+#endif
+    }
+
   value = file_getenv("FILE_BUFTYPE");
 #if ! defined (HAVE_MMAP)
   if ( value == FILE_BUFTYPE_MMAP )
@@ -46887,13 +47254,18 @@ int fileOpen(const char *filename, const char *mode)
   switch ( fmode )
     {
     case 'r':
-      if ( FileTypeEnv == FILE_TYPE_FOPEN )
+      if ( FileTypeRead == FILE_TYPE_FOPEN )
 	fp = fopen(filename, "rb");
       else
 	fd =  open(filename, O_RDONLY | O_BINARY);
       break;
     case 'x':  fp = fopen(filename, "rb");      break;
-    case 'w':  fp = fopen(filename, "wb");      break;
+    case 'w':
+      if ( FileTypeWrite == FILE_TYPE_FOPEN )
+        fp = fopen(filename, "wb");
+      else
+	fd =  open(filename, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY | FileFlagWrite, 0666);
+      break;
     case 'a':  fp = fopen(filename, "ab");      break;
     default:   Error("Mode %c unexpected!", fmode);
     }
@@ -46937,12 +47309,9 @@ int fileOpen(const char *filename, const char *mode)
 #endif
 
       if ( fmode == 'r' )
-	{
-	  if ( FileTypeEnv == FILE_TYPE_FOPEN )
-	    fileptr->type = FILE_TYPE_FOPEN;
-	  else
-	    fileptr->type = FILE_TYPE_OPEN;
-	}
+        fileptr->type = FileTypeRead;
+      else if ( fmode == 'w' )
+        fileptr->type = FileTypeWrite;
       else
 	fileptr->type = FILE_TYPE_FOPEN;
 
@@ -46994,10 +47363,10 @@ int fileClose(int fileID)
       fprintf(stderr, " file name        : %s\n",  fileptr->name);
       fprintf(stderr, " file type        : %d (%s)\n", fileptr->type, ftname[fileptr->type]);
 
-      if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
-	fprintf(stderr, " file descriptor  : %d\n",  fileptr->fd);
-      else
+      if ( fileptr->type == FILE_TYPE_FOPEN )
 	fprintf(stderr, " file pointer     : %p\n",  (void *) fileptr->fp);
+      else
+        fprintf(stderr, " file descriptor  : %d\n",  fileptr->fd);
 
       fprintf(stderr, " file mode        : %c\n",  fileptr->mode);
 
@@ -47037,7 +47406,13 @@ int fileClose(int fileID)
       fprintf(stderr, "--------------------------------------------\n");
     }
 
-  if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
+  if ( fileptr->type == FILE_TYPE_FOPEN )
+    {
+      ret = fclose(fileptr->fp);
+      if ( ret == EOF )
+	SysError("EOF returned for close of %s!", name);
+    }
+  else
     {
 #if defined (HAVE_MMAP)
       if ( fileptr->buffer && fileptr->mappedSize )
@@ -47052,12 +47427,6 @@ int fileClose(int fileID)
       if ( ret == -1 )
 	SysError("EOF returned for close of %s!", name);
     }
-  else
-    {
-      ret = fclose(fileptr->fp);
-      if ( ret == EOF )
-	SysError("EOF returned for close of %s!", name);
-    }
 
   if ( fileptr->name )    free((void*) fileptr->name);
   if ( fileptr->buffer )  free((void*) fileptr->buffer);
@@ -47161,7 +47530,7 @@ size_t fileRead(int fileID, void *restrict ptr, size_t size)
 
   if ( fileptr )
     {
-      if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
+      if ( fileptr->type == FILE_TYPE_OPEN )
 	nread = file_read_from_buffer(fileptr, ptr, size);
       else
 	{
@@ -47189,7 +47558,6 @@ size_t fileRead(int fileID, void *restrict ptr, size_t size)
 size_t fileWrite(int fileID, const void *restrict ptr, size_t size)
 {
   size_t nwrite = 0;
-  FILE *fp;
   bfile_t *fileptr;
 
   fileptr = file_to_pointer(fileID);
@@ -47198,9 +47566,10 @@ size_t fileWrite(int fileID, const void *restrict ptr, size_t size)
     {
       /* if ( fileptr->buffer == NULL ) file_set_buffer(fileptr); */
 
-      fp = fileptr->fp;
-
-      nwrite = fwrite(ptr, 1, size, fp);
+      if ( fileptr->type == FILE_TYPE_FOPEN )
+        nwrite = fwrite(ptr, 1, size, fileptr->fp);
+      else
+        nwrite =  write(fileptr->fd, ptr, size);
 
       fileptr->position  += nwrite;
       fileptr->byteTrans += nwrite;
@@ -47219,9 +47588,9 @@ size_t fileWrite(int fileID, const void *restrict ptr, size_t size)
  * End:
  */
 
-/* Automatically generated by m214003 at 2013-03-05, do not edit */
+/* Automatically generated by m214003 at 2013-06-27, do not edit */
 
-/* CGRIBEXLIB_VERSION="1.6.0" */
+/* CGRIBEXLIB_VERSION="1.6.1" */
 
 #ifdef _ARCH_PWR6
 #pragma options nostrict
@@ -47234,6 +47603,7 @@ size_t fileWrite(int fileID, const void *restrict ptr, size_t size)
 #include <ctype.h>
 #include <stdarg.h>
 #include <sys/types.h>
+#include <inttypes.h>
 
 
 
@@ -48237,7 +48607,7 @@ void avx_encode_double_array_2byte(size_t datasize,
 				   const double * restrict data, 
 				   double zref, double factor, size_t *gz) 
 {
-  size_t i, j;
+  size_t i, j, residual;
   const double *dval = data;
   __m128i *sgrib = (__m128i *) (lGrib+(*gz));
 
@@ -48251,7 +48621,9 @@ void avx_encode_double_array_2byte(size_t datasize,
   __m128i i0, i1, i2, i3;
   __m128i s0, s1;  
 
-  for (i = 0; i < datasize; i += 16)
+  residual = datasize % 16;
+
+  for (i = 0; i < (datasize-residual); i += 16)
     {
       (void) _mm_prefetch(dval+8, _MM_HINT_NTA);
       //_____________________________________________________________________________
@@ -48315,7 +48687,6 @@ void avx_encode_double_array_2byte(size_t datasize,
   if (i != datasize)
     {
       uint16_t ui16;
-      i -= 16;
       for ( j = i; j < datasize; j++ )
 	{
 	  ui16 = (uint16_t) ((data[j] - zref) * factor + 0.5);
@@ -48337,7 +48708,7 @@ void sse41_encode_double_array_2byte(size_t datasize,
 				     const double * restrict data, 
 				     double zref, double factor, size_t *gz) 
 {
-  size_t i, j;
+  size_t i, j, residual;
   const double *dval = data;
   __m128i *sgrib = (__m128i *) (lGrib+(*gz));
 
@@ -48351,7 +48722,9 @@ void sse41_encode_double_array_2byte(size_t datasize,
   __m128i i0, i1, i2, i3, i4;
   __m128i s0, s1;  
 
-  for (i = 0; i < datasize; i += 16)
+  residual = datasize % 16;
+
+  for (i = 0; i < (datasize-residual); i += 16)
     {
       (void) _mm_prefetch(dval+8, _MM_HINT_NTA);
       //_____________________________________________________________________________
@@ -48443,7 +48816,6 @@ void sse41_encode_double_array_2byte(size_t datasize,
   if (i != datasize) 
     {
       uint16_t ui16;
-      i -= 16;  
       for ( j = i; j < datasize; j++ )
 	{
 	  ui16 = (uint16_t) ((data[j] - zref) * factor + 0.5);
@@ -57727,7 +58099,7 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
 
   return (gribLen);
 }
-static const char grb_libvers[] = "1.6.0" " of ""Mar  5 2013"" ""11:10:25";
+static const char grb_libvers[] = "1.6.1" " of ""Jun 27 2013"" ""15:38:33";
 const char *
 cgribexLibraryVersion(void)
 {
@@ -62682,7 +63054,7 @@ listSetForeach(listSet *q, void (*func)(void *elem, void *data), void *data)
  * require-trailing-newline: t
  * End:
  */
-   static char cdi_libvers[] = "1.6.0" " of ""Mar 14 2013"" ""11:28:22";
+   static char cdi_libvers[] = "1.6.1" " of ""Jun 28 2013"" ""13:11:17";
 char *cdiLibraryVersion(void);
 char *cdiLibraryVersion(void)
 {
@@ -63157,6 +63529,10 @@ for (i=0; i<sizeofcstr/elem_len; i++) {
 } return cstr; }
 
 /* kill the trailing char t's in string s. */
+#if defined (__GNUC__)
+#pragma GCC push_options
+#pragma GCC optimize ("O2")
+#endif
 #ifndef __CF__KnR
 static char *kill_trailing(char *s, char t)
 #else
@@ -63168,6 +63544,9 @@ if (e>s) {                           /* Need this to handle NULL string.*/
   while (e>s && *--e==t);            /* Don't follow t's past beginning. */
   e[*e==t?0:1] = '\0';               /* Handle s[0]=t correctly.       */
 } return s; }
+#if defined (__GNUC__)
+#pragma GCC pop_options
+#endif
 
 /* kill_trailingn(s,t,e) will kill the trailing t's in string s. e normally 
 points to the terminating '\0' of s, but may actually point to anywhere in s.
@@ -65082,6 +65461,26 @@ string. */
  * require-trailing-newline: t
  * End:
  */
+#ifndef  _CDIFORTRAN_H
+#define  _CDIFORTRAN_H
+
+/*******************************************************************************
+ * Character buffer:
+ */
+
+#define CBUF_cfINT(N,A,B,X,Y,Z)		STRING_cfINT(N,A,B,X,Y,Z)
+#define CBUF_cfSEP(T,  B)		STRING_cfSEP(T,B)
+#define CBUF_cfN(  T,A)			STRING_cfN(T,A)
+#define CBUF_cfSTR(N,T,A,B,C,D,E)	STRING_cfSTR(N,T,A,B,C,D,E)
+#if defined(vmsFortran)
+#   define CBUF_cfT(M,I,A,B,D)		A->dsc$a_pointer
+#elif defined(CRAYFortran)
+#   define CBUF_cfT(M,I,A,B,D)		_fcdtocp(A)
+#else
+#   define CBUF_cfT(M,I,A,B,D)		A
+#endif
+
+#endif
 #endif
 /* Automatically generated by make_fint.c, don't edit! */
 
@@ -65099,6 +65498,10 @@ string. */
 #  include "cfortran.h"
 #endif
 
+#if ! defined (_CDIFORTRAN_H)
+#  include "cdiFortran.h"
+#endif
+
 
 /*  Byte order  */
 
@@ -65163,6 +65566,7 @@ FCALLSCFUN1 (STRING, cdiStringError, CDISTRINGERROR, cdistringerror, INT)
 FCALLSCSUB1 (cdiDebug, CDIDEBUG, cdidebug, INT)
 FCALLSCFUN0 (STRING, cdiLibraryVersion, CDILIBRARYVERSION, cdilibraryversion)
 FCALLSCSUB0 (cdiPrintVersion, CDIPRINTVERSION, cdiprintversion)
+FCALLSCFUN1 (INT, cdiHaveFiletype, CDIHAVEFILETYPE, cdihavefiletype, INT)
 FCALLSCSUB1 (cdiDefMissval, CDIDEFMISSVAL, cdidefmissval, DOUBLE)
 FCALLSCFUN0 (DOUBLE, cdiInqMissval, CDIINQMISSVAL, cdiinqmissval)
 FCALLSCSUB2 (cdiDefGlobal, CDIDEFGLOBAL, cdidefglobal, STRING, INT)
@@ -65310,6 +65714,8 @@ FCALLSCSUB3 (vlistDefVarUnits, VLISTDEFVARUNITS, vlistdefvarunits, INT, INT, STR
 FCALLSCSUB3 (vlistInqVarUnits, VLISTINQVARUNITS, vlistinqvarunits, INT, INT, PSTRING)
 FCALLSCSUB3 (vlistDefVarMissval, VLISTDEFVARMISSVAL, vlistdefvarmissval, INT, INT, DOUBLE)
 FCALLSCFUN2 (DOUBLE, vlistInqVarMissval, VLISTINQVARMISSVAL, vlistinqvarmissval, INT, INT)
+FCALLSCSUB3 (vlistDefVarExtra, VLISTDEFVAREXTRA, vlistdefvarextra, INT, INT, STRING)
+FCALLSCSUB3 (vlistInqVarExtra, VLISTINQVAREXTRA, vlistinqvarextra, INT, INT, PSTRING)
 FCALLSCSUB3 (vlistDefVarScalefactor, VLISTDEFVARSCALEFACTOR, vlistdefvarscalefactor, INT, INT, DOUBLE)
 FCALLSCFUN2 (DOUBLE, vlistInqVarScalefactor, VLISTINQVARSCALEFACTOR, vlistinqvarscalefactor, INT, INT)
 FCALLSCSUB3 (vlistDefVarAddoffset, VLISTDEFVARADDOFFSET, vlistdefvaraddoffset, INT, INT, DOUBLE)
@@ -65332,28 +65738,12 @@ 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)  */
-
-
-/*  ----------------------------------  */
-
+FCALLSCSUB1 (cdiDefAdditionalKey, CDIDEFADDITIONALKEY, cdidefadditionalkey, STRING)
 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)
+FCALLSCFUN3 (INT, vlistHasVarKey, VLISTHASVARKEY, vlisthasvarkey, INT, INT, STRING)
+FCALLSCFUN3 (DOUBLE, vlistInqVarDblKey, VLISTINQVARDBLKEY, vlistinqvardblkey, INT, INT, STRING)
+FCALLSCFUN3 (INT, vlistInqVarIntKey, VLISTINQVARINTKEY, vlistinqvarintkey, INT, INT, STRING)
 
 /*  VLIST attributes  */
 
@@ -65362,10 +65752,10 @@ FCALLSCFUN6 (INT, vlistInqAtt, VLISTINQATT, vlistinqatt, INT, INT, INT, PSTRING,
 FCALLSCFUN3 (INT, vlistDelAtt, VLISTDELATT, vlistdelatt, INT, INT, STRING)
 FCALLSCFUN6 (INT, vlistDefAttInt, VLISTDEFATTINT, vlistdefattint, INT, INT, STRING, INT, INT, PINT)
 FCALLSCFUN6 (INT, vlistDefAttFlt, VLISTDEFATTFLT, vlistdefattflt, INT, INT, STRING, INT, INT, PDOUBLE)
-FCALLSCFUN5 (INT, vlistDefAttTxt, VLISTDEFATTTXT, vlistdefatttxt, INT, INT, STRING, INT, STRING)
+FCALLSCFUN5 (INT, vlistDefAttTxt, VLISTDEFATTTXT, vlistdefatttxt, INT, INT, STRING, INT, CBUF)
 FCALLSCFUN5 (INT, vlistInqAttInt, VLISTINQATTINT, vlistinqattint, INT, INT, STRING, INT, PINT)
 FCALLSCFUN5 (INT, vlistInqAttFlt, VLISTINQATTFLT, vlistinqattflt, INT, INT, STRING, INT, PDOUBLE)
-FCALLSCFUN5 (INT, vlistInqAttTxt, VLISTINQATTTXT, vlistinqatttxt, INT, INT, STRING, INT, PSTRING)
+FCALLSCFUN5 (INT, vlistInqAttTxt, VLISTINQATTTXT, vlistinqatttxt, INT, INT, STRING, INT, CBUF)
 
 /*  GRID routines  */
 
@@ -65442,8 +65832,8 @@ FCALLSCFUN1 (INT, gridInqPosition, GRIDINQPOSITION, gridinqposition, INT)
 FCALLSCSUB2 (gridDefPosition, GRIDDEFPOSITION, griddefposition, INT, INT)
 FCALLSCFUN2 (INT, gridInqReference, GRIDINQREFERENCE, gridinqreference, INT, PSTRING)
 FCALLSCSUB2 (gridDefReference, GRIDDEFREFERENCE, griddefreference, INT, STRING)
-FCALLSCFUN2 (STRING, gridInqUUID, GRIDINQUUID, gridinquuid, INT, PSTRING)
-FCALLSCSUB2 (gridDefUUID, GRIDDEFUUID, griddefuuid, INT, STRING)
+FCALLSCFUN2 (STRING, gridInqUUID, GRIDINQUUID, gridinquuid, INT, CBUF)
+FCALLSCSUB2 (gridDefUUID, GRIDDEFUUID, griddefuuid, INT, CBUF)
 
 /*  Lambert Conformal Conic grid (GRIB version)  */
 
@@ -65489,8 +65879,8 @@ FCALLSCSUB2 (zaxisInqLevels, ZAXISINQLEVELS, zaxisinqlevels, INT, PDOUBLE)
 FCALLSCSUB3 (zaxisDefLevel, ZAXISDEFLEVEL, zaxisdeflevel, INT, INT, DOUBLE)
 FCALLSCFUN2 (DOUBLE, zaxisInqLevel, ZAXISINQLEVEL, zaxisinqlevel, INT, INT)
 FCALLSCSUB2 (zaxisDefReference, ZAXISDEFREFERENCE, zaxisdefreference, INT, INT)
-FCALLSCSUB2 (zaxisDefUUID, ZAXISDEFUUID, zaxisdefuuid, INT, STRING)
-FCALLSCFUN2 (STRING, zaxisInqUUID, ZAXISINQUUID, zaxisinquuid, INT, PSTRING)
+FCALLSCSUB2 (zaxisDefUUID, ZAXISDEFUUID, zaxisdefuuid, INT, CBUF)
+FCALLSCFUN2 (STRING, zaxisInqUUID, ZAXISINQUUID, zaxisinquuid, INT, CBUF)
 FCALLSCFUN1 (INT, zaxisInqReference, ZAXISINQREFERENCE, zaxisinqreference, INT)
 FCALLSCSUB2 (zaxisDefName, ZAXISDEFNAME, zaxisdefname, INT, STRING)
 FCALLSCSUB2 (zaxisDefLongname, ZAXISDEFLONGNAME, zaxisdeflongname, INT, STRING)
diff --git a/libcdi/src/cfortran.h b/libcdi/src/cfortran.h
index ea0b0e9..867dfc2 100644
--- a/libcdi/src/cfortran.h
+++ b/libcdi/src/cfortran.h
@@ -461,6 +461,10 @@ for (i=0; i<sizeofcstr/elem_len; i++) {
 } return cstr; }
 
 /* kill the trailing char t's in string s. */
+#if defined (__GNUC__)
+#pragma GCC push_options
+#pragma GCC optimize ("O2")
+#endif
 #ifndef __CF__KnR
 static char *kill_trailing(char *s, char t)
 #else
@@ -472,6 +476,9 @@ if (e>s) {                           /* Need this to handle NULL string.*/
   while (e>s && *--e==t);            /* Don't follow t's past beginning. */
   e[*e==t?0:1] = '\0';               /* Handle s[0]=t correctly.       */
 } return s; }
+#if defined (__GNUC__)
+#pragma GCC pop_options
+#endif
 
 /* kill_trailingn(s,t,e) will kill the trailing t's in string s. e normally 
 points to the terminating '\0' of s, but may actually point to anywhere in s.
diff --git a/libcdi/src/cgribexlib.c b/libcdi/src/cgribexlib.c
index 063e78f..d0df1a6 100644
--- a/libcdi/src/cgribexlib.c
+++ b/libcdi/src/cgribexlib.c
@@ -1,7 +1,7 @@
 
-/* Automatically generated by m214003 at 2013-03-05, do not edit */
+/* Automatically generated by m214003 at 2013-06-27, do not edit */
 
-/* CGRIBEXLIB_VERSION="1.6.0" */
+/* CGRIBEXLIB_VERSION="1.6.1" */
 
 #ifdef _ARCH_PWR6
 #pragma options nostrict
@@ -15,6 +15,7 @@
 #include <ctype.h>
 #include <stdarg.h>
 #include <sys/types.h>
+#include <inttypes.h>
 
 
 #include "file.h"
@@ -1027,7 +1028,7 @@ void avx_encode_double_array_2byte(size_t datasize,
 				   const double * restrict data, 
 				   double zref, double factor, size_t *gz) 
 {
-  size_t i, j;
+  size_t i, j, residual;
   const double *dval = data;
   __m128i *sgrib = (__m128i *) (lGrib+(*gz));
 
@@ -1041,7 +1042,9 @@ void avx_encode_double_array_2byte(size_t datasize,
   __m128i i0, i1, i2, i3;
   __m128i s0, s1;  
 
-  for (i = 0; i < datasize; i += 16)
+  residual = datasize % 16;
+
+  for (i = 0; i < (datasize-residual); i += 16)
     {
       (void) _mm_prefetch(dval+8, _MM_HINT_NTA);
       //_____________________________________________________________________________
@@ -1105,7 +1108,6 @@ void avx_encode_double_array_2byte(size_t datasize,
   if (i != datasize)
     {
       uint16_t ui16;
-      i -= 16;
       for ( j = i; j < datasize; j++ )
 	{
 	  ui16 = (uint16_t) ((data[j] - zref) * factor + 0.5);
@@ -1127,7 +1129,7 @@ void sse41_encode_double_array_2byte(size_t datasize,
 				     const double * restrict data, 
 				     double zref, double factor, size_t *gz) 
 {
-  size_t i, j;
+  size_t i, j, residual;
   const double *dval = data;
   __m128i *sgrib = (__m128i *) (lGrib+(*gz));
 
@@ -1141,7 +1143,9 @@ void sse41_encode_double_array_2byte(size_t datasize,
   __m128i i0, i1, i2, i3, i4;
   __m128i s0, s1;  
 
-  for (i = 0; i < datasize; i += 16)
+  residual = datasize % 16;
+
+  for (i = 0; i < (datasize-residual); i += 16)
     {
       (void) _mm_prefetch(dval+8, _MM_HINT_NTA);
       //_____________________________________________________________________________
@@ -1233,7 +1237,6 @@ void sse41_encode_double_array_2byte(size_t datasize,
   if (i != datasize) 
     {
       uint16_t ui16;
-      i -= 16;  
       for ( j = i; j < datasize; j++ )
 	{
 	  ui16 = (uint16_t) ((data[j] - zref) * factor + 0.5);
@@ -10519,7 +10522,7 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
 
   return (gribLen);
 }
-static const char grb_libvers[] = "1.6.0" " of ""Mar  5 2013"" ""11:10:25";
+static const char grb_libvers[] = "1.6.1" " of ""Jun 27 2013"" ""15:38:33";
 const char *
 cgribexLibraryVersion(void)
 {
diff --git a/libcdi/src/config.h.in b/libcdi/src/config.h.in
index c2bd546..f8cb3f2 100644
--- a/libcdi/src/config.h.in
+++ b/libcdi/src/config.h.in
@@ -1,5 +1,11 @@
 /* src/config.h.in.  Generated from configure.ac by autoheader.  */
 
+/* Compiler */
+#undef COMPILER
+
+/* Compiler version */
+#undef COMP_VERSION
+
 /* Define if C / Fortran interface cfortran.h works */
 #undef HAVE_CF_INTERFACE
 
diff --git a/libcdi/src/file.c b/libcdi/src/file.c
index 3822729..c164f97 100644
--- a/libcdi/src/file.c
+++ b/libcdi/src/file.c
@@ -27,7 +27,7 @@ size_t getpagesize(void);
 #include "pio_util.h"
 #endif
 
-#if ! defined(O_BINARY)
+#if ! defined (O_BINARY)
 #define O_BINARY 0
 #endif
 
@@ -142,7 +142,9 @@ static size_t FileBufferSizeMin = MIN_BUF_SIZE;
 static long   FileBufferSizeEnv = -1;
 static int    FileBufferTypeEnv =  0;
 
-static int    FileTypeEnv =  0;
+static int    FileTypeRead  = FILE_TYPE_OPEN;
+static int    FileTypeWrite = FILE_TYPE_FOPEN;
+static int    FileFlagWrite = 0;
 
 static int    FILE_Debug = 0;   /* If set to 1, debugging */
 
@@ -153,7 +155,7 @@ static void file_table_print(void);
  * A version string.
  */
 #undef   LIBVERSION
-#define  LIBVERSION      1.8.1
+#define  LIBVERSION      1.8.2
 #define  XSTRING(x)	 #x
 #define  STRING(x) 	 XSTRING(x)
 const char file_libvers[] = STRING(LIBVERSION) " of "__DATE__" "__TIME__;
@@ -174,6 +176,7 @@ const char file_libvers[] = STRING(LIBVERSION) " of "__DATE__" "__TIME__;
   11/11/2010  1.7.1 update for changed interface of error.h
   02/02/2012  1.8.0 cleanup
   16/11/2012  1.8.1 added support for unbuffered write
+  27/06/2013  1.8.2 added env. var. FILE_TYPE_WRITE (1:open; 2:fopen)
  */
 
 
@@ -740,6 +743,7 @@ static
 void file_initialize(void)
 {
   long value;
+  char *envString;
 
 #if  defined  (HAVE_LIBPTHREAD)
   /* initialize global API mutex lock */
@@ -765,20 +769,42 @@ void file_initialize(void)
       if ( value >= 0 ) FileBufferSizeEnv = value;
     }
 
-  value = file_getenv("FILE_TYPE");
+  value = file_getenv("FILE_TYPE_READ");
   if ( value > 0 )
     {
       switch (value)
 	{
 	case FILE_TYPE_OPEN:
 	case FILE_TYPE_FOPEN:
-	  FileTypeEnv = value;
+	  FileTypeRead = value;
 	  break;
 	default:
 	  Warning("File type %d not implemented!", value);
 	}
     }
 
+  value = file_getenv("FILE_TYPE_WRITE");
+  if ( value > 0 )
+    {
+      switch (value)
+	{
+	case FILE_TYPE_OPEN:
+	case FILE_TYPE_FOPEN:
+	  FileTypeWrite = value;
+	  break;
+	default:
+	  Warning("File type %d not implemented!", value);
+	}
+    }
+
+  envString = getenv("FILE_FLAG_WRITE");
+  if ( envString )
+    {
+#if defined (O_NONBLOCK)
+      if ( strcmp(envString, "NONBLOCK") == 0 ) FileFlagWrite = O_NONBLOCK;
+#endif
+    }
+
   value = file_getenv("FILE_BUFTYPE");
 #if ! defined (HAVE_MMAP)
   if ( value == FILE_BUFTYPE_MMAP )
@@ -1088,13 +1114,18 @@ int fileOpen(const char *filename, const char *mode)
   switch ( fmode )
     {
     case 'r':
-      if ( FileTypeEnv == FILE_TYPE_FOPEN )
+      if ( FileTypeRead == FILE_TYPE_FOPEN )
 	fp = fopen(filename, "rb");
       else
 	fd =  open(filename, O_RDONLY | O_BINARY);
       break;
     case 'x':  fp = fopen(filename, "rb");      break;
-    case 'w':  fp = fopen(filename, "wb");      break;
+    case 'w':
+      if ( FileTypeWrite == FILE_TYPE_FOPEN )
+        fp = fopen(filename, "wb");
+      else
+	fd =  open(filename, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY | FileFlagWrite, 0666);
+      break;
     case 'a':  fp = fopen(filename, "ab");      break;
     default:   Error("Mode %c unexpected!", fmode);
     }
@@ -1138,12 +1169,9 @@ int fileOpen(const char *filename, const char *mode)
 #endif
 
       if ( fmode == 'r' )
-	{
-	  if ( FileTypeEnv == FILE_TYPE_FOPEN )
-	    fileptr->type = FILE_TYPE_FOPEN;
-	  else
-	    fileptr->type = FILE_TYPE_OPEN;
-	}
+        fileptr->type = FileTypeRead;
+      else if ( fmode == 'w' )
+        fileptr->type = FileTypeWrite;
       else
 	fileptr->type = FILE_TYPE_FOPEN;
 
@@ -1195,10 +1223,10 @@ int fileClose(int fileID)
       fprintf(stderr, " file name        : %s\n",  fileptr->name);
       fprintf(stderr, " file type        : %d (%s)\n", fileptr->type, ftname[fileptr->type]);
 
-      if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
-	fprintf(stderr, " file descriptor  : %d\n",  fileptr->fd);
-      else
+      if ( fileptr->type == FILE_TYPE_FOPEN )
 	fprintf(stderr, " file pointer     : %p\n",  (void *) fileptr->fp);
+      else
+        fprintf(stderr, " file descriptor  : %d\n",  fileptr->fd);
 
       fprintf(stderr, " file mode        : %c\n",  fileptr->mode);
 
@@ -1238,7 +1266,13 @@ int fileClose(int fileID)
       fprintf(stderr, "--------------------------------------------\n");
     }
 
-  if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
+  if ( fileptr->type == FILE_TYPE_FOPEN )
+    {
+      ret = fclose(fileptr->fp);
+      if ( ret == EOF )
+	SysError("EOF returned for close of %s!", name);
+    }
+  else
     {
 #if defined (HAVE_MMAP)
       if ( fileptr->buffer && fileptr->mappedSize )
@@ -1253,12 +1287,6 @@ int fileClose(int fileID)
       if ( ret == -1 )
 	SysError("EOF returned for close of %s!", name);
     }
-  else
-    {
-      ret = fclose(fileptr->fp);
-      if ( ret == EOF )
-	SysError("EOF returned for close of %s!", name);
-    }
 
   if ( fileptr->name )    free((void*) fileptr->name);
   if ( fileptr->buffer )  free((void*) fileptr->buffer);
@@ -1362,7 +1390,7 @@ size_t fileRead(int fileID, void *restrict ptr, size_t size)
 
   if ( fileptr )
     {
-      if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
+      if ( fileptr->type == FILE_TYPE_OPEN )
 	nread = file_read_from_buffer(fileptr, ptr, size);
       else
 	{
@@ -1390,7 +1418,6 @@ size_t fileRead(int fileID, void *restrict ptr, size_t size)
 size_t fileWrite(int fileID, const void *restrict ptr, size_t size)
 {
   size_t nwrite = 0;
-  FILE *fp;
   bfile_t *fileptr;
 
   fileptr = file_to_pointer(fileID);
@@ -1399,9 +1426,10 @@ size_t fileWrite(int fileID, const void *restrict ptr, size_t size)
     {
       /* if ( fileptr->buffer == NULL ) file_set_buffer(fileptr); */
 
-      fp = fileptr->fp;
-
-      nwrite = fwrite(ptr, 1, size, fp);
+      if ( fileptr->type == FILE_TYPE_FOPEN )
+        nwrite = fwrite(ptr, 1, size, fileptr->fp);
+      else
+        nwrite =  write(fileptr->fd, ptr, size);
 
       fileptr->position  += nwrite;
       fileptr->byteTrans += nwrite;
diff --git a/libcdi/src/gribapi.c b/libcdi/src/gribapi.c
index 4692671..79337c7 100644
--- a/libcdi/src/gribapi.c
+++ b/libcdi/src/gribapi.c
@@ -9,7 +9,7 @@
 #include <stdio.h>
 
 #include "cdi.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "gribapi.h"
 #include "dmemory.h"
 
diff --git a/libcdi/src/gribapi.h b/libcdi/src/gribapi.h
index 080e39d..741ebaf 100644
--- a/libcdi/src/gribapi.h
+++ b/libcdi/src/gribapi.h
@@ -19,6 +19,7 @@
 #define  GRIB2_LTYPE_HYBRID              105
 #define  GRIB2_LTYPE_LANDDEPTH           106
 #define  GRIB2_LTYPE_ISENTROPIC          107
+#define  GRIB2_LTYPE_SNOW                114
 #define  GRIB2_LTYPE_REFERENCE           150
 #define  GRIB2_LTYPE_SEADEPTH            160
 
diff --git a/libcdi/src/grid.c b/libcdi/src/grid.c
index 6b6c014..b521f46 100644
--- a/libcdi/src/grid.c
+++ b/libcdi/src/grid.c
@@ -11,7 +11,7 @@
 
 #include "dmemory.h"
 #include "cdi.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "grid.h"
 #include "gaussgrid.h"
 #include "pio_util.h"
@@ -2171,9 +2171,8 @@ void gridChangeType(int gridID, int gridtype)
 
   grid_check_ptr(gridID, gridptr);
 
-  Message("Changed grid type from %s to %s",
-          gridNamePtr(gridptr->type),
-          gridNamePtr(gridtype));
+  if ( CDI_Debug ) 
+    Message("Changed grid type from %s to %s", gridNamePtr(gridptr->type), gridNamePtr(gridtype));
 
   gridptr->type = gridtype;
 }
@@ -4212,7 +4211,7 @@ char *gridInqUUID(int gridID, char *uuid)
 
   grid_check_ptr(gridID, gridptr);
 
-  strncpy(uuid, gridptr->uuid, 16);
+  memcpy(uuid, gridptr->uuid, 16);
 
   return (uuid);
 }
@@ -4232,7 +4231,7 @@ void gridDefUUID(int gridID, const char *uuid)
 
   grid_check_ptr(gridID, gridptr);
 
-  strncpy(gridptr->uuid, uuid, 16);
+  memcpy(gridptr->uuid, uuid, 16);
 
   return;
 }
diff --git a/libcdi/src/institution.c b/libcdi/src/institution.c
index 0b41a39..a7887e7 100644
--- a/libcdi/src/institution.c
+++ b/libcdi/src/institution.c
@@ -4,7 +4,7 @@
 
 #include "dmemory.h"
 #include "cdi.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "resource_handle.h"
 #include "pio_util.h"
 #include "resource_handle.h"
@@ -198,8 +198,12 @@ int institutInq(int center, int subcenter, const char *name, const char *longnam
   ip1->used       = 0;
   ip1->center     = center;
   ip1->subcenter  = subcenter;
-  ip1->name       = ( char * ) name;
-  ip1->longname   = ( char * ) longname;
+  ip1->name       = NULL;
+  ip1->longname   = NULL;
+  if ( name && *name )
+    ip1->name     = ( char * ) name;
+  if ( longname && *longname )
+    ip1->longname = ( char * ) longname;
 
   instCount = instituteCount ();
   instResHs = xmalloc ( instCount * sizeof ( int ));
@@ -234,8 +238,8 @@ int institutDef(int center, int subcenter, const char *name, const char *longnam
 
   instituteptr->center    = center;
   instituteptr->subcenter = subcenter;
-  if ( name )     instituteptr->name     = strdupx(name);
-  if ( longname ) instituteptr->longname = strdupx(longname);
+  if ( name && *name )         instituteptr->name     = strdupx(name);
+  if ( longname && *longname ) instituteptr->longname = strdupx(longname);
 
   return instituteptr->self;
 }
diff --git a/libcdi/src/model.c b/libcdi/src/model.c
index c0f3241..2546219 100644
--- a/libcdi/src/model.c
+++ b/libcdi/src/model.c
@@ -4,7 +4,7 @@
 
 #include "dmemory.h"
 #include "cdi.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "pio_util.h"
 #include "resource_handle.h"
 #include "pio_rpc.h"
@@ -172,7 +172,7 @@ int modelInq(int instID, int modelgribID, char *name)
 
       if ( modelptr->used )
         {
-          if ( name )
+          if ( name && *name )
             {
               found = 1;
               if ( instID      != -1 && modelptr->instID      != instID )      found = 0;
@@ -215,7 +215,7 @@ int modelDef(int instID, int modelgribID, const char *name)
 
   modelptr->instID      = instID;
   modelptr->modelgribID = modelgribID;
-  if ( name ) modelptr->name = strdupx(name);
+  if ( name && *name ) modelptr->name = strdupx(name);
 
   return modelptr->self;
 }
diff --git a/libcdi/src/pio_interface.c b/libcdi/src/pio_interface.c
index a976dbf..b8098cf 100644
--- a/libcdi/src/pio_interface.c
+++ b/libcdi/src/pio_interface.c
@@ -17,7 +17,7 @@
 #include "pio_rpc.h"
 #include "pio_server.h"
 #include "resource_handle.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "vlist.h"
 extern resOps streamOps;
 
diff --git a/libcdi/src/pio_server.c b/libcdi/src/pio_server.c
index c0a7888..fa151c3 100644
--- a/libcdi/src/pio_server.c
+++ b/libcdi/src/pio_server.c
@@ -17,7 +17,7 @@
 #include "pio_comm.h"
 #include "pio_rpc.h"
 #include "pio_util.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "resource_handle.h"
 #include "vlist_var.h"
 
diff --git a/libcdi/src/stream.c b/libcdi/src/stream.c
index 43d9b99..c75ad98 100644
--- a/libcdi/src/stream.c
+++ b/libcdi/src/stream.c
@@ -6,7 +6,7 @@
 
 #include "dmemory.h"
 #include "cdi.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "cdf.h"
 #include "stream_grb.h"
 #include "stream_cdf.h"
@@ -85,6 +85,46 @@ void cdiDebug(int level)
 }
 
 
+int cdiHaveFiletype(int filetype)
+{
+  int status = 0;
+
+  switch (filetype)
+    {
+#if  defined  (HAVE_LIBSERVICE)
+    case FILETYPE_SRV:  { status = 1; break; }
+#endif
+#if  defined  (HAVE_LIBEXTRA)
+    case FILETYPE_EXT:  { status = 1; break; }
+#endif
+#if  defined  (HAVE_LIBIEG)
+    case FILETYPE_IEG:  { status = 1; break; }
+#endif
+#if  defined  (HAVE_LIBGRIB)
+#if  defined  (HAVE_LIBGRIB_API) || defined  (HAVE_LIBCGRIBEX)
+    case FILETYPE_GRB:  { status = 1; break; }
+#endif
+#if  defined  (HAVE_LIBGRIB_API)
+    case FILETYPE_GRB2: { status = 1; break; }
+#endif
+#endif
+#if  defined  (HAVE_LIBNETCDF)
+    case FILETYPE_NC:   { status = 1; break; }
+#if  defined  (HAVE_NETCDF2)
+    case FILETYPE_NC2:  { status = 1; break; }
+#endif
+#if  defined  (HAVE_NETCDF4)
+    case FILETYPE_NC4:  { status = 1; break; }
+    case FILETYPE_NC4C: { status = 1; break; }
+#endif
+#endif
+    default: { status = 0; break; }
+    }
+
+  return (status);
+}
+
+
 #undef  IsBigendian
 #define IsBigendian()  ( u_byteorder.c[sizeof(long) - 1] )
 
diff --git a/libcdi/src/stream_cdf.c b/libcdi/src/stream_cdf.c
index 9b7f651..c49fe97 100644
--- a/libcdi/src/stream_cdf.c
+++ b/libcdi/src/stream_cdf.c
@@ -15,7 +15,7 @@
 #include "cdi.h"
 #include "basetime.h"
 #include "gaussgrid.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "stream_cdf.h"
 #include "cdf_int.h"
 #include "varscan.h"
@@ -80,7 +80,8 @@ typedef struct {
   int      calendar;
   int      tableID;
   int      truncation;
-  int      defmiss;
+  int      defmissval;
+  int      deffillval;
   int      xtype;
   int      ndims;
   int      gmapid;
@@ -98,6 +99,7 @@ typedef struct {
   size_t   vlen;
   double  *vdata;
   double   missval;
+  double   fillval;
   double   addoffset;
   double   scalefactor;
   double   validrange[2];
@@ -105,6 +107,7 @@ typedef struct {
   char     longname[CDI_MAX_NAME];
   char     stdname[CDI_MAX_NAME];
   char     units[CDI_MAX_NAME];
+  char     extra[CDI_MAX_NAME];
   ensinfo_t   *ensdata;    /* Ensemble information */
 }
 ncvar_t;
@@ -687,10 +690,10 @@ void cdfDefVarMissval(stream_t *streamptr, int varID, int dtype, int lcheck)
 
       xtype = cdfDefDatatype(dtype, streamptr->filetype);
 
-      cdf_put_att_double(fileID, ncvarid, "_FillValue", (nc_type) xtype, 1, &missval);
+      if ( xtype == NC_BYTE && missval > 127 && missval < 256 ) xtype = NC_INT;
 
-      if ( cdiNcMissingValue == 1 )
-        cdf_put_att_double(fileID, ncvarid, "missing_value", (nc_type) xtype, 1, &missval);
+      cdf_put_att_double(fileID, ncvarid, "_FillValue", (nc_type) xtype, 1, &missval);
+      cdf_put_att_double(fileID, ncvarid, "missing_value", (nc_type) xtype, 1, &missval);
 
       if ( lcheck && streamptr->ncmode == 2 ) cdf_enddef(fileID);
 
@@ -4092,14 +4095,17 @@ void init_ncvars(long nvars, ncvar_t *ncvars)
       ncvars[ncvarid].positive        = 0;
       ncvars[ncvarid].chunked         = 0;
       ncvars[ncvarid].chunktype       = UNDEFID;
-      ncvars[ncvarid].defmiss         = 0;
+      ncvars[ncvarid].defmissval      = 0;
+      ncvars[ncvarid].deffillval      = 0;
       ncvars[ncvarid].missval         = 0;
+      ncvars[ncvarid].fillval         = 0;
       ncvars[ncvarid].addoffset       = 0;
       ncvars[ncvarid].scalefactor     = 1;
       ncvars[ncvarid].name[0]         = 0;
       ncvars[ncvarid].longname[0]     = 0;
       ncvars[ncvarid].stdname[0]      = 0;
       ncvars[ncvarid].units[0]        = 0;
+      ncvars[ncvarid].extra[0]        = 0;
       ncvars[ncvarid].natts           = 0;
       ncvars[ncvarid].atts            = NULL;
       ncvars[ncvarid].deflate         = 0;
@@ -4402,6 +4408,7 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
 #if  defined  (HAVE_NETCDF4)
       if ( format == NC_FORMAT_NETCDF4_CLASSIC || format == NC_FORMAT_NETCDF4 )
         {
+          char buf[CDI_MAX_NAME];
           int shuffle, deflate, deflate_level;
           size_t chunks[nvdims];
           int storage_in;
@@ -4414,10 +4421,20 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
                 {
                   ncvars[ncvarid].chunked = 1;
                   for ( int i = 0; i < nvdims; ++i ) ncvars[ncvarid].chunks[i] = chunks[i];
-                  /*
-                  printf("storage %d %d %d\n", storage_in, NC_CONTIGUOUS, NC_CHUNKED);
-                  for ( int i = 0; i < nvdims; ++i ) printf("chunk %d %d\n", i, chunks[i]);
-                  */
+                  if ( CDI_Debug )
+                    {
+                      fprintf(stderr, "\nchunking %d %d %d\nchunks ", storage_in, NC_CONTIGUOUS, NC_CHUNKED);
+                      for ( int i = 0; i < nvdims; ++i ) fprintf(stderr, "%ld ", chunks[i]);
+                      fprintf(stderr, "\n");
+                    }
+                  strcat(ncvars[ncvarid].extra, "chunks=");
+                  for ( int i = nvdims-1; i >= 0; --i )
+                    {
+                      sprintf(buf, "%ld", (long) chunks[i]);
+                      strcat(ncvars[ncvarid].extra, buf);
+                      if ( i > 0 ) strcat(ncvars[ncvarid].extra, "x");
+                    }
+                  strcat(ncvars[ncvarid].extra, " ");
                 }
             }
         }
@@ -4751,11 +4768,16 @@ void cdfScanVarAttributes(int nvars, ncvar_t *ncvars, ncdim_t *ncdims,
                   ncdims[ncvars[ncvarid].dimids[0]].dimtype = Z_AXIS;
                 }
             }
-          else if ( (strcmp(attname, "_FillValue") == 0 || strcmp(attname, "missing_value") == 0) &&
-		    atttype != NC_CHAR )
+          else if ( strcmp(attname, "_FillValue") == 0 && atttype != NC_CHAR )
+            {
+	      cdfGetAttDouble(ncid, ncvarid, attname, 1, &ncvars[ncvarid].fillval);
+	      ncvars[ncvarid].deffillval = TRUE;
+	      /* cdfSetVar(ncvars, ncvarid, TRUE); */
+            }
+          else if ( strcmp(attname, "missing_value") == 0 && atttype != NC_CHAR )
             {
 	      cdfGetAttDouble(ncid, ncvarid, attname, 1, &ncvars[ncvarid].missval);
-	      ncvars[ncvarid].defmiss = TRUE;
+	      ncvars[ncvarid].defmissval = TRUE;
 	      /* cdfSetVar(ncvars, ncvarid, TRUE); */
             }
           else if ( strcmp(attname, "valid_range") == 0 && attlen == 2 )
@@ -5223,7 +5245,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, char *uuidOfHGrid)
+void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nvars, ncvar_t *ncvars, int timedimid, char *uuidOfHGrid, int number_of_grid_used)
 {
   int ncvarid, ncvarid2;
   int ndims;
@@ -5654,6 +5676,13 @@ void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
 		}
 	    }
 
+	  if ( number_of_grid_used != UNDEFID &&
+               (grid.type == UNDEFID || grid.type == GRID_GENERIC) )
+	    {
+	      grid.type   = GRID_REFERENCE;
+	      grid.number = number_of_grid_used;
+	    }
+
 	  if ( ncvars[ncvarid].gmapid >= 0 && ncvars[ncvarid].gridtype != GRID_CURVILINEAR )
 	    {
 	      cdf_inq_varnatts(ncvars[ncvarid].ncid, ncvars[ncvarid].gmapid, &nvatts);
@@ -5770,7 +5799,8 @@ 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 )
+          if ( uuidOfHGrid[0] != 0 && 
+	       (grid.type == GRID_UNSTRUCTURED || grid.type == GRID_REFERENCE) )
             gridDefUUID(ncvars[ncvarid].gridID, uuidOfHGrid);
 
           if ( ncvars[ncvarid].chunked )
@@ -6000,7 +6030,7 @@ void define_all_zaxes(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
 
 /* define all input data variables */
 static
-void define_all_vars(stream_t *streamptr, 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, int num_ncvars, ncvar_t *ncvars)
 {
   int ncid;
   int varID1, varID, ncvarid;
@@ -6051,9 +6081,7 @@ void define_all_vars(stream_t *streamptr, int vlistID, int instID, int modelID,
         vlistDefVarChunkType(vlistID, varID, ncvars[ncvarid].chunktype);
 #endif
 
-      streamptr->vars[varID1].level   = NULL;
       streamptr->vars[varID1].defmiss = 0;
-      streamptr->vars[varID1].nlevs   = zaxisInqSize(ncvars[ncvarid].zaxisID);
       streamptr->vars[varID1].ncvarid = ncvarid;
 
       vlistDefVarName(vlistID, varID, ncvars[ncvarid].name);
@@ -6084,7 +6112,14 @@ void define_all_vars(stream_t *streamptr, int vlistID, int instID, int modelID,
       if ( ncvars[ncvarid].tableID != UNDEFID )
 	vlistDefVarTable(vlistID, varID, ncvars[ncvarid].tableID);
 
-      if ( ncvars[ncvarid].defmiss == TRUE ) vlistDefVarMissval(vlistID, varID, ncvars[ncvarid].missval);
+      if ( ncvars[ncvarid].deffillval == FALSE && ncvars[ncvarid].defmissval == TRUE )
+        {
+          ncvars[ncvarid].deffillval = TRUE;
+          ncvars[ncvarid].fillval    = ncvars[ncvarid].missval;
+        }
+
+      if ( ncvars[ncvarid].deffillval == TRUE )
+        vlistDefVarMissval(vlistID, varID, ncvars[ncvarid].fillval);
 
       if ( CDI_Debug )
 	Message("varID = %d  gridID = %d  zaxisID = %d", varID,
@@ -6144,6 +6179,11 @@ void define_all_vars(stream_t *streamptr, int vlistID, int instID, int modelID,
           free(ncvars[ncvarid].ensdata);
           ncvars[ncvarid].ensdata = NULL;
         }
+
+      if ( ncvars[ncvarid].extra != NULL && ncvars[ncvarid].extra[0] != 0 )
+        {
+          vlistDefVarExtra(vlistID, varID, ncvars[ncvarid].extra);
+        }
     }
 
   for ( varID = 0; varID < nvars; varID++ )
@@ -6209,9 +6249,14 @@ void define_all_vars(stream_t *streamptr, int vlistID, int instID, int modelID,
 	    }
 
 	  free(ncvars[ncvarid].atts);
+          ncvars[ncvarid].atts = NULL;
 	}
     }
 
+  /* release mem of not freed attributes */
+  for ( ncvarid = 0; ncvarid < num_ncvars; ncvarid++ )
+    if ( ncvars[ncvarid].atts ) free(ncvars[ncvarid].atts);
+
   if ( varids ) free(varids);
 
   for ( varID = 0; varID < nvars; varID++ )
@@ -6288,7 +6333,7 @@ void define_all_vars(stream_t *streamptr, int vlistID, int instID, int modelID,
 
 static
 void scan_global_attributtes(int fileID, int vlistID, stream_t *streamptr, int ngatts,
-                             int *instID, int *modelID, int *ucla_les, char *uuidOfHGrid)
+                             int *instID, int *modelID, int *ucla_les, char *uuidOfHGrid, int *number_of_grid_used)
 {
   nc_type xtype;
   size_t attlen;
@@ -6354,15 +6399,23 @@ void scan_global_attributtes(int fileID, int vlistID, stream_t *streamptr, int n
 	}
       else if ( xtype == NC_SHORT || xtype == NC_INT )
 	{
-	  int *attint;
-	  attint = (int *) malloc(attlen*sizeof(int));
-	  cdfGetAttInt(fileID, NC_GLOBAL, attname, attlen, attint);
-	  if ( xtype == NC_SHORT )
-	    vlistDefAttInt(vlistID, CDI_GLOBAL, attname, DATATYPE_INT16, (int)attlen, attint);
-	  else
-	    vlistDefAttInt(vlistID, CDI_GLOBAL, attname, DATATYPE_INT32, (int)attlen, attint);
-	  free(attint);
-	}
+	  if ( strcmp(attname, "number_of_grid_used") == 0 )
+	    {
+	      (*number_of_grid_used) = UNDEFID;
+	      cdfGetAttInt(fileID, NC_GLOBAL, attname, 1, number_of_grid_used);
+	    }
+ 	  else
+            {
+              int *attint;
+              attint = (int *) malloc(attlen*sizeof(int));
+              cdfGetAttInt(fileID, NC_GLOBAL, attname, attlen, attint);
+              if ( xtype == NC_SHORT )
+                vlistDefAttInt(vlistID, CDI_GLOBAL, attname, DATATYPE_INT16, (int)attlen, attint);
+              else
+                vlistDefAttInt(vlistID, CDI_GLOBAL, attname, DATATYPE_INT32, (int)attlen, attint);
+              free(attint);
+            }
+        }
       else if ( xtype == NC_FLOAT || xtype == NC_DOUBLE )
 	{
 	  double *attflt;
@@ -6409,6 +6462,7 @@ int cdfInqContents(stream_t *streamptr)
   int format = 0;
   int ucla_les = FALSE;
   char uuidOfHGrid[17];
+  int number_of_grid_used = UNDEFID;
 
   uuidOfHGrid[0] = 0;
 
@@ -6480,7 +6534,7 @@ int cdfInqContents(stream_t *streamptr)
     }
 
   /* scan global attributtes */
-  scan_global_attributtes(fileID, vlistID, streamptr, ngatts, &instID, &modelID, &ucla_les, uuidOfHGrid);
+  scan_global_attributtes(fileID, vlistID, streamptr, ngatts, &instID, &modelID, &ucla_les, uuidOfHGrid, &number_of_grid_used);
 
   /* find time dim */
   if ( unlimdimid >= 0 )
@@ -6643,7 +6697,15 @@ int cdfInqContents(stream_t *streamptr)
       if ( ncvars[ncvarid].ndims > 4 )
 	{
 	  ncvars[ncvarid].isvar = 0;
-	  Warning("%d dimensional variables unsupported, skipped variable %s!",
+	  Warning("%d dimensional variables are not supported, skipped variable %s!",
+		ncvars[ncvarid].ndims, ncvars[ncvarid].name);
+	  continue;
+	}
+
+      if ( ncvars[ncvarid].ndims == 4 && timedimid == UNDEFID )
+	{
+	  ncvars[ncvarid].isvar = 0;
+	  Warning("%d dimensional variables without time dimension are not supported, skipped variable %s!",
 		ncvars[ncvarid].ndims, ncvars[ncvarid].name);
 	  continue;
 	}
@@ -6773,7 +6835,7 @@ int cdfInqContents(stream_t *streamptr)
 
 
   /* define all grids */
-  define_all_grids(streamptr, vlistID, ncdims, nvars, ncvars, timedimid, uuidOfHGrid);
+  define_all_grids(streamptr, vlistID, ncdims, nvars, ncvars, timedimid, uuidOfHGrid, number_of_grid_used);
 
 
   /* read VCT */
@@ -6815,7 +6877,7 @@ int cdfInqContents(stream_t *streamptr)
   streamptr->ntsteps = ntsteps;
 
   /* define all data variables */
-  define_all_vars(streamptr, vlistID, instID, modelID, varids, nvars_data, ncvars);
+  define_all_vars(streamptr, vlistID, instID, modelID, varids, nvars_data, nvars, ncvars);
 
 
   cdiCreateTimesteps(streamptr);
@@ -6913,10 +6975,10 @@ int cdfInqContents(stream_t *streamptr)
   cdfCreateRecords(streamptr, 0);
 
   /* free ncdims */
-  free (ncdims);
+  free(ncdims);
 
   /* free ncvars */
-  free (ncvars);
+  free(ncvars);
 
 #endif
 
diff --git a/libcdi/src/stream_cgribex.c b/libcdi/src/stream_cgribex.c
index 1626d06..c96e9b5 100644
--- a/libcdi/src/stream_cgribex.c
+++ b/libcdi/src/stream_cgribex.c
@@ -7,7 +7,7 @@
 
 #include "dmemory.h"
 #include "cdi.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "file.h"
 #include "varscan.h"
 #include "datetime.h"
@@ -408,7 +408,7 @@ void cgribexAddRecord(stream_t * streamptr, int param, int *isec1, int *isec2, d
   if ( datatype > 32 ) datatype = DATATYPE_PACK32;
   if ( datatype <  0 ) datatype = DATATYPE_PACK;
 
-  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, 0,
+  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, 0, 0,
 	       datatype, &varID, &levelID, tsteptype, numavg, ISEC1_LevelType, NULL, NULL, NULL);
 
   (*record).varID   = varID;
diff --git a/libcdi/src/stream_ext.c b/libcdi/src/stream_ext.c
index ceafb4b..d6a57e6 100644
--- a/libcdi/src/stream_ext.c
+++ b/libcdi/src/stream_ext.c
@@ -10,7 +10,7 @@
 #include "error.h"
 #include "file.h"
 #include "cdi.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "varscan.h"
 #include "datetime.h"
 #include "extra.h"
@@ -275,7 +275,7 @@ void extAddRecord(stream_t *streamptr, int param, int level, int xysize,
   */
   leveltype = ZAXIS_GENERIC;
 
-  varAddRecord(recID, param, gridID, leveltype, 0, level, 0, 0,
+  varAddRecord(recID, param, gridID, leveltype, 0, level, 0, 0, 0,
 	       extInqDatatype(prec, number), &varID, &levelID, UNDEFID, 0, 0, NULL, NULL, NULL);
 
   (*record).varID   = varID;
diff --git a/libcdi/src/stream_grb.c b/libcdi/src/stream_grb.c
index 0323a49..8b7b899 100644
--- a/libcdi/src/stream_grb.c
+++ b/libcdi/src/stream_grb.c
@@ -7,7 +7,7 @@
 
 #include "dmemory.h"
 #include "cdi.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "stream_cgribex.h"
 #include "stream_gribapi.h"
 #include "file.h"
@@ -37,14 +37,14 @@ int grib1ltypeToZaxisType(int grib_ltype)
     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_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_ISENTROPIC:         { zaxistype = ZAXIS_ISENTROPIC;	break; }
     case GRIB1_LTYPE_SEADEPTH:           { zaxistype = ZAXIS_DEPTH_BELOW_SEA;   break; }
     }
 
@@ -75,6 +75,7 @@ int grib2ltypeToZaxisType(int grib_ltype)
     case GRIB2_LTYPE_LANDDEPTH:
  /* case GRIB2_LTYPE_LANDDEPTH_LAYER: */ { zaxistype = ZAXIS_DEPTH_BELOW_LAND;  break; }
     case GRIB2_LTYPE_ISENTROPIC:         { zaxistype = ZAXIS_ISENTROPIC;        break; }
+    case GRIB2_LTYPE_SNOW:               { zaxistype = ZAXIS_SNOW;              break; }
     case GRIB2_LTYPE_SEADEPTH:           { zaxistype = ZAXIS_DEPTH_BELOW_SEA;   break; }
     }
 
@@ -123,16 +124,25 @@ int grbDefRecord(stream_t * streamptr)
 
 static
 int grbDecode(int filetype, unsigned char *gribbuffer, int gribsize, double *data, int gridsize,
-	      int unreduced, int *nmiss, int *zip, double missval)
+	      int unreduced, int *nmiss, int *zip, double missval, int vlistID, int varID)
 {
   int status = 0;
 
 #if  defined  (HAVE_LIBCGRIBEX)
   if ( filetype == FILETYPE_GRB )
-    status = cgribexDecode(gribbuffer, gribsize, data, gridsize, unreduced, nmiss, zip, missval);
+    {
+#if  defined  (HAVE_LIBGRIB_API)
+      extern int cdiNAdditionalGRIBKeys;
+      if ( cdiNAdditionalGRIBKeys > 0 )
+	Error("CGRIBEX decode does not support reading of additional GRIB keys!");
+#endif
+      status = cgribexDecode(gribbuffer, gribsize, data, gridsize, unreduced, nmiss, zip, missval);
+    }
   else
 #endif
-    status = gribapiDecode(gribbuffer, gribsize, data, gridsize, unreduced, nmiss, zip, missval);
+    {
+      status = gribapiDecode(gribbuffer, gribsize, data, gridsize, unreduced, nmiss, zip, missval, vlistID, varID);
+    }
 
   return (status);
 }
@@ -176,7 +186,7 @@ int grbReadRecord(stream_t * streamptr, double *data, int *nmiss)
 
   missval = vlistInqVarMissval(vlistID, varID);
 
-  grbDecode(filetype, gribbuffer, recsize, data, gridsize, streamptr->unreduced, nmiss, &zip, missval);
+  grbDecode(filetype, gribbuffer, recsize, data, gridsize, streamptr->unreduced, nmiss, &zip, missval, vlistID, varID);
 
   streamptr->tsteps[tsID].records[recID].zip = zip;
 
@@ -349,7 +359,7 @@ void grbReadVarDP(stream_t * streamptr, int varID, double *data, int *nmiss)
       missval = vlistInqVarMissval(vlistID, varID);
 
       grbDecode(filetype, gribbuffer, recsize, &data[levelID*gridsize], gridsize,
-		streamptr->unreduced, &imiss, &zip, missval);
+		streamptr->unreduced, &imiss, &zip, missval, vlistID, varID);
 
       *nmiss += imiss;
 
@@ -403,7 +413,7 @@ void grbReadVarSliceDP(stream_t * streamptr, int varID, int levelID, double *dat
 
   missval = vlistInqVarMissval(vlistID, varID);
 
-  grbDecode(filetype, gribbuffer, recsize, data, gridsize, streamptr->unreduced, nmiss, &zip, missval);
+  grbDecode(filetype, gribbuffer, recsize, data, gridsize, streamptr->unreduced, nmiss, &zip, missval, vlistID, varID);
 
   fileSetPos(fileID, currentfilepos, SEEK_SET);
 
@@ -490,7 +500,7 @@ int grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype
   int ljpeg_warn = 1;
   void *gc = NULL;
 
-  if ( memtype == MEMTYPE_FLOAT ) Error("cdf_write_var_slice not implemented for memtype float!");
+  if ( memtype == MEMTYPE_FLOAT ) Error("grb_write_var_slice not implemented for memtype float!");
 
   filetype  = streamptr->filetype;
   fileID    = streamptr->fileID;
diff --git a/libcdi/src/stream_gribapi.c b/libcdi/src/stream_gribapi.c
index 2cf4ef0..47439b0 100644
--- a/libcdi/src/stream_gribapi.c
+++ b/libcdi/src/stream_gribapi.c
@@ -6,7 +6,7 @@
 
 #include "dmemory.h"
 #include "cdi.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "file.h"
 #include "varscan.h"
 #include "datetime.h"
@@ -16,7 +16,7 @@
 
 
 #if  defined  (HAVE_LIBGRIB_API)
-#  include "cgribex.h"      /* gribGetSize, gribRead, gribGetZip */
+#  include "cgribex.h"      /* gribGetSize, gribRead, gribGetZip, GRIB1_LTYPE_99 */
 #  include "gribapi.h"
 #  include "grib_api.h"
 #endif
@@ -189,15 +189,14 @@ static
 int gribapiGetEndStep(grib_handle *gh, int startStep, int timeunits)
 {
   int endStep = startStep;
-  int timeunits2;
+  int timeunits2 = timeunits;
   int status;
   long unitsOfTime;
   long lpar;
 
-  // status = grib_get_long(gh, "stepUnits", &unitsOfTime);
-
-  // timeunits2 = getTimeunits(unitsOfTime);
-  timeunits2 = gribapiGetTimeUnits(gh);
+  status = grib_get_long(gh, "stepUnits", &unitsOfTime);
+  if ( status == 0 ) timeunits2 = getTimeunits(unitsOfTime);
+  //timeunits2 = gribapiGetTimeUnits(gh);
 
   status = grib_get_long(gh, "endStep", &lpar);
 
@@ -328,8 +327,9 @@ int gribapiGetValidityDateTime(grib_handle *gh, int *vdate, int *vtime)
 	static int lprint = TRUE;
 	extern int grib_calendar;
 	int ryear, rmonth, rday, rhour, rminute, rsecond;
-	int time_period = endStep;
-	int julday, secofday, addsec;
+	int julday, secofday;
+	int64_t time_period = endStep;
+        int64_t addsec;
 
 	cdiDecodeDate(rdate, &ryear, &rmonth, &rday);
 	cdiDecodeTime(rtime, &rhour, &rminute, &rsecond);
@@ -605,7 +605,7 @@ void gribapiGetGrid(grib_handle *gh, grid_t *grid)
             len = (size_t) 16;
             if ( grib_get_bytes(gh, "uuidOfHGrid", (unsigned char *) uuid, &len) == 0)
               {
-                strncpy(grid->uuid, uuid, 16);
+                memcpy(grid->uuid, uuid, 16);
               }
           }
 	break;
@@ -686,7 +686,7 @@ void grib1GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, i
 	  GRIB_CHECK(grib_get_double(gh, "level", &dlevel), 0);
 	  if ( *leveltype == 100 ) dlevel *= 100;
 	  if ( dlevel < -2.e9 || dlevel > 2.e9 ) dlevel = 0;
-	  if ( *leveltype == 99 ) *leveltype = 100;
+	  if ( *leveltype == GRIB1_LTYPE_99 ) *leveltype = 100;
 
 	  *level1 = (int) dlevel;
 	  *level2 = 0;
@@ -702,81 +702,77 @@ 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, int *level_sf)
+double grib2ScaleFactor(long factor)
+{
+  double scaleFactor = 0;
+
+  if      ( factor == 0 ) scaleFactor =    1;
+  else if ( factor == 1 ) scaleFactor =    0.1;
+  else if ( factor == 2 ) scaleFactor =    0.01;
+  else if ( factor == 3 ) scaleFactor =    0.001;
+  else if ( factor == 4 ) scaleFactor =    0.0001;
+
+  return (scaleFactor);
+}
+
+static
+void grib2GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, int *level2, int *level_sf, int *level_unit)
 {
   int status;
   int leveltype2 = -1;
   long lpar;
   long factor;
-  double dlevel;
 
-  *leveltype = 0;
-  *lbounds = 0;
-  *level1  = 0;
-  *level2  = 0;
-  *level_sf = 0;
+  *leveltype  = 0;
+  *lbounds    = 0;
+  *level1     = 0;
+  *level2     = 0;
+  *level_sf   = 0;
+  *level_unit = 0;
 
   status = grib_get_long(gh, "typeOfFirstFixedSurface", &lpar);
   if ( status == 0 )
     {
+      long llevel;
+      double dlevel1 = 0, dlevel2 = 0;
+
       *leveltype = (int) lpar;
 
       status = grib_get_long(gh, "typeOfSecondFixedSurface", &lpar);
       if ( status == 0 ) leveltype2 = lpar;
 
-      if ( *leveltype == leveltype2 && *leveltype != 255 ) *lbounds = 1;
+      if ( *leveltype != 255 && leveltype2 != 255 && leveltype2 > 0 ) *lbounds = 1;
 
-      if ( *lbounds == 0 )
-	{
-	  if ( *leveltype == GRIB2_LTYPE_LANDDEPTH )
-	    {
-	      GRIB_CHECK(grib_get_long(gh, "scaleFactorOfFirstFixedSurface", &factor), 0);
-	      GRIB_CHECK(grib_get_double(gh, "scaledValueOfFirstFixedSurface", &dlevel), 0);
-	      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
-	    {
-	      GRIB_CHECK(grib_get_double(gh, "level", &dlevel), 0);
-	      if ( *leveltype == GRIB2_LTYPE_ISOBARIC ) dlevel *= 100;
-	      if ( dlevel < -2.e9 || dlevel > 2.e9 ) dlevel = 0;
-	      if ( *leveltype == 99 ) *leveltype = 100;
-	    }
+      if ( *leveltype == GRIB2_LTYPE_LANDDEPTH )
+        {
+          *level_sf = 1000;
+          *level_unit = CDI_UNIT_M;
+        }
+      else if ( *leveltype == GRIB2_LTYPE_ISOBARIC )
+        {
+          *level_sf = 1000;
+          *level_unit = CDI_UNIT_PA;
+        }
 
-	  *level1 = (int) dlevel;
-	  *level2 = 0;
-	}
-      else
+      GRIB_CHECK(grib_get_long(gh, "scaleFactorOfFirstFixedSurface", &factor), 0);
+      GRIB_CHECK(grib_get_long(gh, "scaledValueOfFirstFixedSurface", &llevel), 0);
+      if ( llevel != GRIB_MISSING_LONG && factor != GRIB_MISSING_LONG )
+        dlevel1 = llevel*grib2ScaleFactor(factor);
+
+      if ( *level_sf != 0 ) dlevel1 *= (*level_sf);
+
+      if ( *lbounds == 1 )
 	{
-	  if ( *leveltype == GRIB2_LTYPE_LANDDEPTH )
-	    {
-	      GRIB_CHECK(grib_get_long(gh, "scaleFactorOfFirstFixedSurface", &factor), 0);
-	      GRIB_CHECK(grib_get_double(gh, "scaledValueOfFirstFixedSurface", &dlevel), 0);
-	      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 *= 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
-	    {
-	      GRIB_CHECK(grib_get_long(gh, "topLevel", &lpar), 0);
-	      *level1 = lpar;
-	      GRIB_CHECK(grib_get_long(gh, "bottomLevel", &lpar), 0);
-	      *level2 = lpar;
-	    }
-	}
+          GRIB_CHECK(grib_get_long(gh, "scaleFactorOfSecondFixedSurface", &factor), 0);
+          GRIB_CHECK(grib_get_long(gh, "scaledValueOfSecondFixedSurface", &llevel), 0);
+          if ( llevel != GRIB_MISSING_LONG && factor != GRIB_MISSING_LONG )
+            dlevel2 = llevel*grib2ScaleFactor(factor);
+
+          if ( *level_sf != 0 ) dlevel2 *= (*level_sf);
+        }
+
+      *level1 = (int) dlevel1;
+      *level2 = (int) dlevel2;
     }
 }
 
@@ -790,10 +786,11 @@ void gribapiGetString(grib_handle *gh, const char *key, char *string, size_t len
   else if ( length == 2 && memcmp(string, "~", length)       == 0 ) string[0] = 0;
 }
 
+#if  defined  (HAVE_LIBGRIB_API)
 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)
+                      int leveltype, int lbounds, int level1, int level2, int level_sf, int level_unit)
 {
   long editionNumber;
   int zaxistype;
@@ -898,7 +895,7 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
     }
   // fprintf(stderr, "param %d name %s %s %s\n", param, name, longname, units);
 
-  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, level_sf,
+  varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, level_sf, level_unit,
 	       datatype, &varID, &levelID, tsteptype, numavg, leveltype,
 	       varname, longname, units);
 
@@ -923,6 +920,27 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
   if ( ens_index > 0 )
     varDefEnsembleInfo(varID, (int)ens_index, (int)ens_count, (int)ens_forecast_type);
 
+  int    i;
+  long   lval;
+  double dval;
+
+  /* we read the additional keys for the first variable record only. */
+  int linitial_field = (varOptGribNentries(varID) == 0);
+
+  for ( i = 0; i < cdiNAdditionalGRIBKeys; i++ )
+    {
+      if ( linitial_field )
+	{
+	  if ( grib_get_long(gh, cdiAdditionalGRIBKeys[i], &lval) == 0 )
+            varDefOptGribInt(varID, lval, cdiAdditionalGRIBKeys[i]);
+	}
+      if ( linitial_field )
+	{
+	  if ( grib_get_double(gh, cdiAdditionalGRIBKeys[i], &dval) == 0 )
+            varDefOptGribInt(varID, dval, cdiAdditionalGRIBKeys[i]);
+	}
+      /* note: if the key is not defined, we do not throw an error! */
+    }
 
   if ( varInqInst(varID) == CDI_UNDEFID )
     {
@@ -976,6 +994,7 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
     Message("varID = %d  param = %d  zaxistype = %d  gridID = %d  levelID = %d",
 	    varID, param, zaxistype, gridID, levelID);
 }
+#endif
 
 static
 int gribapiGetParam(grib_handle *gh)
@@ -1074,7 +1093,7 @@ int gribapiScanTimestep1(stream_t * streamptr)
   int bitsPerValue;
   int lieee = FALSE;
   int lbounds;
-  int level_sf;
+  int level_sf, level_unit;
   char paramstr[32];
   char varname[256];
 
@@ -1143,6 +1162,7 @@ int gribapiScanTimestep1(stream_t * streamptr)
 
 	  grib1GetLevel(gh, &leveltype, &lbounds, &level1, &level2);
           level_sf = 0;
+          level_unit = 0;
 	}
       else
 	{
@@ -1159,7 +1179,7 @@ int gribapiScanTimestep1(stream_t * streamptr)
 
 	  param = gribapiGetParam(gh);
 
-	  grib2GetLevel(gh, &leveltype, &lbounds, &level1, &level2, &level_sf);
+	  grib2GetLevel(gh, &leveltype, &lbounds, &level1, &level2, &level_sf, &level_unit);
 	}
 
       cdiParamToString(param, paramstr, sizeof(paramstr));
@@ -1254,7 +1274,7 @@ int gribapiScanTimestep1(stream_t * streamptr)
 	Message("%4d %8d %4d  %8d %8d %6d", nrecs, (int)recpos, param, level1, vdate, vtime);
 
       gribapiAddRecord(streamptr, param, gh, recsize, recpos, datatype, comptype, len, varname,
-                       leveltype, lbounds, level1, level2, level_sf);
+                       leveltype, lbounds, level1, level2, level_sf, level_unit);
 
       grib_handle_delete(gh);
       gh = NULL;
@@ -1363,7 +1383,7 @@ int gribapiScanTimestep2(stream_t * streamptr)
   long editionNumber;
   long lpar;
   int lbounds;
-  int level_sf;
+  int level_sf, level_unit;
   char paramstr[32];
   char varname[256];
 
@@ -1447,12 +1467,13 @@ int gribapiScanTimestep2(stream_t * streamptr)
 
 	  grib1GetLevel(gh, &leveltype, &lbounds, &level1, &level2);
           level_sf = 0;
+          level_unit = 0;
 	}
       else
 	{
 	  param = gribapiGetParam(gh);
 
-	  grib2GetLevel(gh, &leveltype, &lbounds, &level1, &level2, &level_sf);
+	  grib2GetLevel(gh, &leveltype, &lbounds, &level1, &level2, &level_sf, &level_unit);
 	}
 
       cdiParamToString(param, paramstr, sizeof(paramstr));
@@ -1626,7 +1647,7 @@ int gribapiScanTimestep(stream_t * streamptr)
   long editionNumber;
   long lpar;
   int lbounds;
-  int level_sf;
+  int level_sf, level_unit;
   char paramstr[32];
   char varname[256];
 
@@ -1717,12 +1738,13 @@ int gribapiScanTimestep(stream_t * streamptr)
 
 	      grib1GetLevel(gh, &leveltype, &lbounds, &level1, &level2);
               level_sf = 0;
+              level_unit = 0;
 	    }
 	  else
 	    {
 	      param = gribapiGetParam(gh);
 
-	      grib2GetLevel(gh, &leveltype, &lbounds, &level1, &level2, &level_sf);
+	      grib2GetLevel(gh, &leveltype, &lbounds, &level1, &level2, &level_sf, &level_unit);
 	    }
 
           cdiParamToString(param, paramstr, sizeof(paramstr));
@@ -1881,7 +1903,7 @@ int gribapiScanTimestep(stream_t * streamptr)
 
 
 int gribapiDecode(unsigned char *gribbuffer, int gribsize, double *data, int gridsize,
-		  int unreduced, int *nmiss, int *zip, double missval)
+		  int unreduced, int *nmiss, int *zip, double missval, int vlistID, int varID)
 {
   int status = 0;
 #if  defined  (HAVE_LIBGRIB_API)
@@ -2534,7 +2556,8 @@ 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_bytes(gh, "uuidOfHGrid", (unsigned char *) gridInqUUID(gridID, uuid), &len), 0);
+	    if (grib_set_bytes(gh, "uuidOfHGrid", (unsigned char *) gridInqUUID(gridID, uuid), &len) != 0)
+	      Warning("Can't write UUID!");
 	  }
 
 	break;
@@ -2548,35 +2571,85 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int ljpeg, i
 }
 
 static
-void getLevelFactor(double level, long *factor, double *scale)
+void getLevelFactor(double level, long *factor, long *out_scaled_value)
 {
-  double dum;
+  double scaled_value  = level;
+  long   iscaled_value = (long) round(scaled_value);
+  long   i;
+
+  const double eps = 1.e-8;
+  for ( i=0; (fabs(scaled_value - (double) iscaled_value) >= eps) && i < 7; i++ )
+    {
+      scaled_value *= 10.;
+      iscaled_value = round(scaled_value);
+    }
+
+  (*factor)           = i;
+  (*out_scaled_value) = iscaled_value;
+}
 
-  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 gribapiDefLevelType(grib_handle *gh, int gcinit, const char *keyname, long leveltype)
+{
+  if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, keyname, leveltype), 0);
+}
+
+static
+void grib2DefLevel(grib_handle *gh, int gcinit, long leveltype, int lbounds, double level, double dlevel1, double dlevel2)
+{
+  long scaled_level;
+  long factor;
+
+  gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", leveltype);
+  if ( lbounds ) gribapiDefLevelType(gh, gcinit, "typeOfSecondFixedSurface", leveltype);
+
+  if ( !lbounds ) dlevel1 = level;
+
+  getLevelFactor(dlevel1, &factor, &scaled_level);
+  GRIB_CHECK(grib_set_long(gh, "scaleFactorOfFirstFixedSurface", factor), 0);
+  GRIB_CHECK(grib_set_long(gh, "scaledValueOfFirstFixedSurface", scaled_level), 0);
+
+  if ( lbounds )
+    {
+      getLevelFactor(dlevel2, &factor, &scaled_level);
+      GRIB_CHECK(grib_set_long(gh, "scaleFactorOfSecondFixedSurface", factor), 0);
+      GRIB_CHECK(grib_set_long(gh, "scaledValueOfSecondFixedSurface", scaled_level), 0);
+    }
 }
 
 static
 void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID, int levelID, int gcinit)
 {
   double level;
+  int lbounds = 0;
   int zaxistype, ltype;
   static int warning = 1;
   int reference;
   char uuid[17];
   size_t len;
+  double scalefactor;
+  double dlevel1 = 0, dlevel2 = 0;
+
 
   zaxistype = zaxisInqType(zaxisID);
   ltype = zaxisInqLtype(zaxisID);
   level = zaxisInqLevel(zaxisID, levelID);
 
+  if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
+    {
+      lbounds = 1;
+      dlevel1 = zaxisInqLbound(zaxisID, levelID);
+      dlevel2 = zaxisInqUbound(zaxisID, levelID);
+    }
+  else
+    {
+      dlevel1 = level;
+      dlevel2 = 0;
+    }
+
   if ( zaxistype == ZAXIS_GENERIC && ltype == 0 )
     {
-      Message("Changed zaxis type from %s to %s",
-	      zaxisNamePtr(zaxistype), zaxisNamePtr(ZAXIS_PRESSURE));
+      Message("Changed zaxis type from %s to %s", zaxisNamePtr(zaxistype), zaxisNamePtr(ZAXIS_PRESSURE));
       zaxistype = ZAXIS_PRESSURE;
       zaxisChangeType(zaxisID, zaxistype);
       zaxisDefUnits(zaxisID, "Pa");
@@ -2587,13 +2660,9 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
     case ZAXIS_SURFACE:
       {
 	if ( editionNumber <= 1 )
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_SURFACE), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_SURFACE);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_SURFACE), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_SURFACE);
 
         GRIB_CHECK(grib_set_long(gh, "level", level), 0);
 
@@ -2602,91 +2671,63 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
     case ZAXIS_CLOUD_BASE:
       {
 	if ( editionNumber <= 1 )
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_CLOUDBASE), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_CLOUDBASE);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_CLOUDBASE), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_CLOUDBASE);
 
         break;
       }
     case ZAXIS_CLOUD_TOP:
       {
 	if ( editionNumber <= 1 )
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_CLOUDTOP), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_CLOUDTOP);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_CLOUDTOP), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_CLOUDTOP);
 
         break;
       }
     case ZAXIS_ISOTHERM_ZERO:
       {
 	if ( editionNumber <= 1 )
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_ISOTHERM0), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_ISOTHERM0);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_ISOTHERM0), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_ISOTHERM0);
 
         break;
       }
     case ZAXIS_TOA:
       {
 	if ( editionNumber <= 1 )
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_TOA), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_TOA);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_TOA), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_TOA);
 
         break;
       }
     case ZAXIS_SEA_BOTTOM:
       {
 	if ( editionNumber <= 1 )
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_SEA_BOTTOM), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_SEA_BOTTOM);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_SEA_BOTTOM), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_SEA_BOTTOM);
 
         break;
       }
     case ZAXIS_ATMOSPHERE:
       {
 	if ( editionNumber <= 1 )
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_ATMOSPHERE), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_ATMOSPHERE);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_ATMOSPHERE), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_ATMOSPHERE);
 
         break;
       }
     case ZAXIS_MEANSEA:
       {
 	if ( editionNumber <= 1 )
-	  {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_MEANSEA), 0);
-          }
+	  gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_MEANSEA);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_MEANSEA), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_MEANSEA);
 
 	GRIB_CHECK(grib_set_double(gh, "level", level), 0);
 
@@ -2695,38 +2736,27 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
     case ZAXIS_HYBRID:
     case ZAXIS_HYBRID_HALF:
       {
-	if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
+	if ( lbounds )
 	  {
-	    long level1, level2;
-
 	    if ( editionNumber <= 1 )
-	      {
-                if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_HYBRID_LAYER), 0);
-              }
+	      gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_HYBRID_LAYER);
             else
 	      {
-		if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_HYBRID), 0);
-		if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfSecondFixedSurface", GRIB2_LTYPE_HYBRID), 0);
+		gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_HYBRID);
+		gribapiDefLevelType(gh, gcinit, "typeOfSecondFixedSurface", GRIB2_LTYPE_HYBRID);
 	      }
 
-	    level1 = zaxisInqLbound(zaxisID, levelID);
-	    level2 = zaxisInqUbound(zaxisID, levelID);
-
-	    GRIB_CHECK(grib_set_long(gh, "topLevel", level1), 0);
-	    GRIB_CHECK(grib_set_long(gh, "bottomLevel", level2), 0);
+	    GRIB_CHECK(grib_set_long(gh, "topLevel", (long) dlevel1), 0);
+	    GRIB_CHECK(grib_set_long(gh, "bottomLevel", (long) dlevel2), 0);
 	  }
 	else
 	  {
 	    if ( editionNumber <= 1 )
-              {
-                if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_HYBRID), 0);
-              }
+              gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_HYBRID);
             else
-              {
-                if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_HYBRID), 0);
-              }
+              gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_HYBRID);
 
-	    GRIB_CHECK(grib_set_long(gh, "level", level), 0);
+	    GRIB_CHECK(grib_set_long(gh, "level", (long) level), 0);
 	  }
 
         if ( !gcinit )
@@ -2753,47 +2783,49 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
 	if ( level < 0 ) Warning("Pressure level of %f Pa is below zero!", level);
 
 	zaxisInqUnits(zaxisID, units);
-	if ( memcmp(units, "Pa", 2) != 0 ) level *= 100;
+	if ( memcmp(units, "Pa", 2) != 0 )
+          {
+            level   *= 100;
+            dlevel1 *= 100;
+            dlevel2 *= 100;
+          }
 
-	if ( level < 32768 && (level < 100 || modf(level/100, &dum) > 0) )
-	  {
-	    if ( editionNumber <= 1 )
-              {
-                if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_99), 0);
-              }
+        if ( editionNumber <= 1 )
+          {
+            long leveltype = GRIB1_LTYPE_ISOBARIC;
+
+            if ( level < 32768 && (level < 100 || modf(level/100, &dum) > 0) )
+              leveltype = GRIB1_LTYPE_99;
             else
-              {
-                if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB1_LTYPE_99), 0);
-              }
+              level /= 100;
 
-	    GRIB_CHECK(grib_set_double(gh, "level", level), 0);
+            gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", leveltype);
+            GRIB_CHECK(grib_set_double(gh, "level", level), 0);
 	  }
 	else
 	  {
-	    if ( editionNumber <= 1 )
-              {
-                if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_ISOBARIC), 0);
-              }
-            else
-              {
-                if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_ISOBARIC), 0);
-              }
-            //GRIB_CHECK(grib_set_double(gh, "scaledValueOfFirstFixedSurface", level), 0);
-	    GRIB_CHECK(grib_set_double(gh, "level", level/100), 0);
+            grib2DefLevel(gh, gcinit, GRIB2_LTYPE_ISOBARIC, lbounds, level, dlevel1, dlevel2);
 	  }
 
 	break;
       }
-    case ZAXIS_HEIGHT:
+    case ZAXIS_SNOW:
       {
         if ( editionNumber <= 1 )
+          ; // not available
+	else
           {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_HEIGHT), 0);
+            grib2DefLevel(gh, gcinit, GRIB2_LTYPE_SNOW, lbounds, level, dlevel1, dlevel2);
           }
+
+	break;
+      }
+    case ZAXIS_HEIGHT:
+      {
+        if ( editionNumber <= 1 )
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_HEIGHT);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_HEIGHT), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_HEIGHT);
 
 	GRIB_CHECK(grib_set_double(gh, "level", level), 0);
 
@@ -2802,13 +2834,9 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
     case ZAXIS_ALTITUDE:
       {
         if ( editionNumber <= 1 )
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_ALTITUDE), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_ALTITUDE);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_ALTITUDE), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_ALTITUDE);
 
 	GRIB_CHECK(grib_set_double(gh, "level", level), 0);
 
@@ -2817,13 +2845,9 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
     case ZAXIS_SIGMA:
       {
 	if ( editionNumber <= 1 )
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_SIGMA), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_SIGMA);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_SIGMA), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_SIGMA);
 
 	GRIB_CHECK(grib_set_double(gh, "level", level), 0);
 
@@ -2837,50 +2861,26 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
 
 	if ( editionNumber <= 1 )
 	  {
-	    double factor;
-	    if      ( memcmp(units, "mm", 2) == 0 ) factor =   0.1;
-	    else if ( memcmp(units, "cm", 2) == 0 ) factor =   1;
-	    else if ( memcmp(units, "dm", 2) == 0 ) factor =  10;
-	    else                                    factor = 100; // meter
-
-	    if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_LANDDEPTH), 0);
-	    GRIB_CHECK(grib_set_double(gh, "level", level*factor), 0);
+	    if      ( memcmp(units, "mm", 2) == 0 ) scalefactor =   0.1;
+	    else if ( memcmp(units, "cm", 2) == 0 ) scalefactor =   1; // cm
+	    else if ( memcmp(units, "dm", 2) == 0 ) scalefactor =  10;
+	    else                                    scalefactor = 100;
+
+	    gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_LANDDEPTH);
+	    GRIB_CHECK(grib_set_double(gh, "level", level*scalefactor), 0);
 	  }
 	else
 	  {
-	    long factor;
-            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 = 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*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*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*scale), 0);
-	      }
+            level   *= scalefactor;
+            dlevel1 *= scalefactor;
+            dlevel1 *= scalefactor;
+
+            grib2DefLevel(gh, gcinit, GRIB2_LTYPE_LANDDEPTH, lbounds, level, dlevel1, dlevel2);
 	  }
 
 	break;
@@ -2888,13 +2888,9 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
     case ZAXIS_DEPTH_BELOW_SEA:
       {
 	if ( editionNumber <= 1 )
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_SEADEPTH), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_SEADEPTH);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_SEADEPTH), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_SEADEPTH);
 
 	GRIB_CHECK(grib_set_double(gh, "level", level), 0);
 
@@ -2903,13 +2899,9 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
     case ZAXIS_ISENTROPIC:
       {
 	if ( editionNumber <= 1 )
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", GRIB1_LTYPE_ISENTROPIC), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", GRIB1_LTYPE_ISENTROPIC);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_ISENTROPIC), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_ISENTROPIC);
 
 	GRIB_CHECK(grib_set_double(gh, "level", level), 0);
 
@@ -2922,12 +2914,13 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
         else
           {
             reference = zaxisInqReference(zaxisID);
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", GRIB2_LTYPE_REFERENCE), 0);
+            gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", GRIB2_LTYPE_REFERENCE);
             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_bytes(gh, "uuidOfVGrid", (unsigned char *) zaxisInqUUID(zaxisID, uuid), &len), 0);
+	    if (grib_set_bytes(gh, "uuidOfVGrid", (unsigned char *) zaxisInqUUID(zaxisID, uuid), &len) != 0)
+	      Warning("Can't write UUID!");
             GRIB_CHECK(grib_set_double(gh, "level", level), 0);
           }
 
@@ -2936,13 +2929,9 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
     case ZAXIS_GENERIC:
       {
 	if ( editionNumber <= 1 )
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "indicatorOfTypeOfLevel", ltype), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "indicatorOfTypeOfLevel", ltype);
         else
-          {
-            if ( !gcinit ) GRIB_CHECK(grib_set_long(gh, "typeOfFirstFixedSurface", ltype), 0);
-          }
+          gribapiDefLevelType(gh, gcinit, "typeOfFirstFixedSurface", ltype);
 
 	GRIB_CHECK(grib_set_double(gh, "level", level), 0);
 
diff --git a/libcdi/src/stream_gribapi.h b/libcdi/src/stream_gribapi.h
index 380d0d6..11bb7aa 100644
--- a/libcdi/src/stream_gribapi.h
+++ b/libcdi/src/stream_gribapi.h
@@ -6,7 +6,7 @@ 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);
+		  int unreduced, int *nmiss, int *zip, double missval, int vlistID, int varID);
 
 size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisID,
 		     int vdate, int vtime, int tsteptype, int numavg, 
diff --git a/libcdi/src/stream_history.c b/libcdi/src/stream_history.c
index 558482c..adf6492 100644
--- a/libcdi/src/stream_history.c
+++ b/libcdi/src/stream_history.c
@@ -4,7 +4,7 @@
 
 #include "dmemory.h"
 #include "cdi.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "stream_cdf.h"
 
 
diff --git a/libcdi/src/stream_ieg.c b/libcdi/src/stream_ieg.c
index 1c48d27..33c2484 100644
--- a/libcdi/src/stream_ieg.c
+++ b/libcdi/src/stream_ieg.c
@@ -12,7 +12,7 @@
 #include "error.h"
 #include "file.h"
 #include "cdi.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "varscan.h"
 #include "datetime.h"
 #include "ieg.h"
@@ -769,7 +769,7 @@ void iegAddRecord(stream_t *streamptr, int param, int *pdb, int *gdb, double *vc
 
   datatype = iegInqDatatype(prec);
 
-  varAddRecord(recID, param, gridID, leveltype, lbounds, level1, level2, 0,
+  varAddRecord(recID, param, gridID, leveltype, lbounds, level1, level2, 0, 0,
 	       datatype, &varID, &levelID, UNDEFID, 0, 0, NULL, NULL, NULL);
 
   (*record).varID   = varID;
diff --git a/libcdi/src/stream_record.c b/libcdi/src/stream_record.c
index 28a55f6..71dc7a6 100644
--- a/libcdi/src/stream_record.c
+++ b/libcdi/src/stream_record.c
@@ -9,7 +9,7 @@
 
 #include "cdi.h"
 #include "cdf_int.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "stream_grb.h"
 #include "stream_cdf.h"
 #include "stream_srv.h"
diff --git a/libcdi/src/stream_srv.c b/libcdi/src/stream_srv.c
index 51131b3..03458de 100644
--- a/libcdi/src/stream_srv.c
+++ b/libcdi/src/stream_srv.c
@@ -10,7 +10,7 @@
 #include "error.h"
 #include "file.h"
 #include "cdi.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "varscan.h"
 #include "datetime.h"
 #include "service.h"
@@ -276,7 +276,7 @@ void srv_add_record(stream_t *streamptr, int param, int level, int xsize, int ys
 
   datatype = srvInqDatatype(prec);
 
-  varAddRecord(recID, param, gridID, leveltype, 0, level, 0, 0,
+  varAddRecord(recID, param, gridID, leveltype, 0, level, 0, 0, 0,
 	       datatype, &varID, &levelID, UNDEFID, 0, 0, NULL, NULL, NULL);
 
   (*record).varID   = varID;
diff --git a/libcdi/src/stream_var.c b/libcdi/src/stream_var.c
index a069e5e..8f9fd9a 100644
--- a/libcdi/src/stream_var.c
+++ b/libcdi/src/stream_var.c
@@ -8,7 +8,7 @@
 #include "error.h"
 
 #include "cdi.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 
 
 static
@@ -23,8 +23,6 @@ void streamvar_init_entry(stream_t *streamptr, int varID)
   streamptr->vars[varID].gridID       = CDI_UNDEFID;
   streamptr->vars[varID].zaxisID      = CDI_UNDEFID;
   streamptr->vars[varID].tsteptype    = CDI_UNDEFID;
-  streamptr->vars[varID].level        = NULL;
-  streamptr->vars[varID].nlevs        = 0;
 }
 
 static
diff --git a/libcdi/src/table.c b/libcdi/src/table.c
index 90c9e54..7649e91 100644
--- a/libcdi/src/table.c
+++ b/libcdi/src/table.c
@@ -6,7 +6,7 @@
 
 #include "dmemory.h"
 #include "cdi.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 
 #undef  UNDEFID
 #define UNDEFID -1
diff --git a/libcdi/src/taxis.c b/libcdi/src/taxis.c
index eb6640b..ee33c31 100644
--- a/libcdi/src/taxis.c
+++ b/libcdi/src/taxis.c
@@ -11,7 +11,7 @@
 
 #include "cdi.h"
 #include "taxis.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "calendar.h"
 #include "pio_util.h"
 #include "namespace.h"
diff --git a/libcdi/src/timebase.c b/libcdi/src/timebase.c
index 01e3549..3c1800c 100644
--- a/libcdi/src/timebase.c
+++ b/libcdi/src/timebase.c
@@ -3,7 +3,7 @@
 #include <math.h>		/* for floor() */
 
 #include "cdi.h"
-
+#include "timebase.h"
 
 /* convert Julian date into year, months, day */
 void decode_julday(int calendar,
diff --git a/libcdi/src/timebase.h b/libcdi/src/timebase.h
index d298f17..716bb60 100644
--- a/libcdi/src/timebase.h
+++ b/libcdi/src/timebase.h
@@ -1,6 +1,8 @@
 #ifndef  _TIMEBASE_H
 #define  _TIMEBASE_H
 
+#include <inttypes.h>
+
 /* date format:  YYYYMMDD */
 /* time format:  hhmmss   */
 
diff --git a/libcdi/src/tsteps.c b/libcdi/src/tsteps.c
index 1cc139a..7eac592 100644
--- a/libcdi/src/tsteps.c
+++ b/libcdi/src/tsteps.c
@@ -5,7 +5,7 @@
 #include "dmemory.h"
 
 #include "cdi.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 
 
 static
diff --git a/libcdi/src/util.c b/libcdi/src/util.c
index 6a0f540..3fa2ad0 100644
--- a/libcdi/src/util.c
+++ b/libcdi/src/util.c
@@ -7,7 +7,7 @@
 #include <float.h>
 #include <sys/types.h>
 
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "dmemory.h"
 #include "binary.h"
 
diff --git a/libcdi/src/varscan.c b/libcdi/src/varscan.c
index f4a3a3f..15597a9 100644
--- a/libcdi/src/varscan.c
+++ b/libcdi/src/varscan.c
@@ -6,7 +6,7 @@
 #include <math.h>
 
 #include "cdi.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "dmemory.h"
 #include "varscan.h"
 #include "vlist.h"
@@ -48,6 +48,7 @@ typedef struct
   int         ltype;     /* GRIB level type */
   int         lbounds;
   int         level_sf;
+  int         level_unit;
   int         zaxisID;
   int         nlevels;
   int         levelTableSize;
@@ -63,6 +64,16 @@ typedef struct
   char       *longname;
   char       *units;
   ensinfo_t  *ensdata;
+#if  defined  (HAVE_LIBGRIB_API)
+  /* (Optional) list of keyword/double value pairs */
+  int    opt_grib_dbl_nentries;
+  char*  opt_grib_dbl_keyword[MAX_OPT_GRIB_ENTRIES];
+  double opt_grib_dbl_val[MAX_OPT_GRIB_ENTRIES];
+  /* (Optional) list of keyword/integer value pairs */
+  int    opt_grib_int_nentries;
+  char*  opt_grib_int_keyword[MAX_OPT_GRIB_ENTRIES];
+  int    opt_grib_int_val[MAX_OPT_GRIB_ENTRIES];
+#endif
 }
 vartable_t;
 
@@ -86,6 +97,7 @@ void paramInitEntry(int varID, int param)
   vartable[varID].ltype          = 0;
   vartable[varID].lbounds        = 0;
   vartable[varID].level_sf       = 0;
+  vartable[varID].level_unit     = 0;
   vartable[varID].levelTable     = NULL;
   vartable[varID].levelTableSize = 0;
   vartable[varID].nlevels        = 0;
@@ -249,7 +261,13 @@ int paramNewEntry(int param)
 	}
 
       for( i = 0; i < varTablesize; i++ )
-	vartable[i].param = UNDEF_PARAM;
+	{
+	  vartable[i].param = UNDEF_PARAM;
+#if  defined  (HAVE_LIBGRIB_API)
+	  vartable[i].opt_grib_int_nentries = 0;
+	  vartable[i].opt_grib_dbl_nentries = 0;
+#endif
+	}
     }
   else
     {
@@ -276,7 +294,13 @@ int paramNewEntry(int param)
       varID = varTablesize/2;
 
       for( i = varID; i < varTablesize; i++ )
-	vartable[i].param = UNDEF_PARAM;
+	{
+	  vartable[i].param = UNDEF_PARAM;
+#if  defined  (HAVE_LIBGRIB_API)
+	  vartable[i].opt_grib_int_nentries = 0;
+	  vartable[i].opt_grib_dbl_nentries = 0;
+#endif
+	}
     }
 
   paramInitEntry(varID, param);
@@ -286,7 +310,7 @@ int paramNewEntry(int param)
 
 
 void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
-		  int level1, int level2, int level_sf, int prec,
+		  int level1, int level2, int level_sf, int level_unit, int prec,
 		  int *pvarID, int *plevelID, int tsteptype, int numavg, int ltype,
 		  const char *name, const char *longname, const char *units)
 {
@@ -305,6 +329,7 @@ void varAddRecord(int recID, int param, int gridID, int zaxistype, int lbounds,
       vartable[varID].ltype     = ltype;
       vartable[varID].lbounds   = lbounds;
       vartable[varID].level_sf  = level_sf;
+      vartable[varID].level_unit = level_unit;
       if ( tsteptype != UNDEFID ) vartable[varID].tsteptype = tsteptype;
       if ( numavg ) vartable[varID].timave = 1;
 
@@ -476,7 +501,7 @@ void cdi_generate_vars(stream_t *streamptr)
       comptype  = vartable[varid].comptype;
 
       level_sf  = 1;
-      if ( vartable[varid].level_sf == 77 ) level_sf = 0.001;
+      if ( vartable[varid].level_sf != 0 ) level_sf = 1./vartable[varid].level_sf;
 
       zaxisID = UNDEFID;
 
@@ -541,12 +566,9 @@ void cdi_generate_vars(stream_t *streamptr)
 	    dlevels2[levelID] = level_sf*vartable[varid].levelTable[levelID].level2;
 	}
 
-      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);
+      char *unitptr = cdiUnitNamePtr(vartable[varid].level_unit);
+      zaxisID = varDefZaxis(vlistID, zaxistype, nlevels, dlevels, lbounds, dlevels1, dlevels2,
+                            Vctsize, Vct, NULL, NULL, unitptr, 0, 0, ltype);
 
       if ( lbounds ) free(dlevels1);
       if ( lbounds ) free(dlevels2);
@@ -571,6 +593,33 @@ void cdi_generate_vars(stream_t *streamptr)
 	                                                  vartable[varid].ensdata->ens_count,
 							  vartable[varid].ensdata->forecast_init_type);
 
+#if  defined  (HAVE_LIBGRIB_API)
+      /* ---------------------------------- */
+      /* Local change: 2013-04-23, FP (DWD) */
+      /* ---------------------------------- */
+
+      int    i;
+      vlist_t *vlistptr;
+      vlistptr = vlist_to_pointer(vlistID);
+      for (i=0; i<vartable[varid].opt_grib_int_nentries; i++)
+        {
+          int idx = vlistptr->vars[varID].opt_grib_int_nentries;
+          vlistptr->vars[varID].opt_grib_int_nentries++;
+          if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/integer value pairs!");
+          vlistptr->vars[varID].opt_grib_int_val[idx] = vartable[varid].opt_grib_int_val[idx];
+          vlistptr->vars[varID].opt_grib_int_keyword[idx] = strdupx(vartable[varid].opt_grib_int_keyword[idx]);
+        }
+      for (i=0; i<vartable[varid].opt_grib_dbl_nentries; i++)
+        {
+          int idx = vlistptr->vars[varID].opt_grib_dbl_nentries;
+          vlistptr->vars[varID].opt_grib_dbl_nentries++;
+          if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/double value pairs!");
+          vlistptr->vars[varID].opt_grib_dbl_val[idx] = vartable[varid].opt_grib_dbl_val[idx];
+          vlistptr->vars[varID].opt_grib_dbl_keyword[idx] = strdupx(vartable[varid].opt_grib_dbl_keyword[idx]);
+        }
+      /* note: if the key is not defined, we do not throw an error! */
+#endif
+
       if ( cdiDefaultTableID != UNDEFID )
 	{
 	  int pdis, pcat, pnum;
@@ -614,7 +663,7 @@ void cdi_generate_vars(stream_t *streamptr)
       for ( levelID = 0; levelID < nlevels; levelID++ )
 	{
 	  lindex = vartable[varid].levelTable[levelID].lindex;
-	  printf("%d %d %d %d %d\n", varID, levelID, 
+	  printf("%d %d %d %d %d\n", varID, levelID,
 		 vartable[varid].levelTable[levelID].lindex,
 		 vartable[varid].levelTable[levelID].recID,
 		 vartable[varid].levelTable[levelID].level1);
@@ -654,7 +703,7 @@ void varDefZAxisReference(int nlev, int nvgrid, char *uuid)
 {
   numberOfVerticalLevels = nlev;
   numberOfVerticalGrid = nvgrid;
-  strncpy(uuidVGrid, uuid, 16);
+  memcpy(uuidVGrid, uuid, 16);
 }
 
 
@@ -946,6 +995,40 @@ void varDefEnsembleInfo(int varID, int ens_idx, int ens_count, int forecast_type
   vartable[varID].ensdata->forecast_init_type = forecast_type;
 }
 
+
+void varDefOptGribInt(int varID, long lval, const char *keyword)
+{
+#if  defined  (HAVE_LIBGRIB_API)
+  int idx = vartable[varID].opt_grib_int_nentries;
+  vartable[varID].opt_grib_int_nentries++;
+  if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/integer value pairs!");
+  vartable[varID].opt_grib_int_val[idx] = (int) lval;
+  vartable[varID].opt_grib_int_keyword[idx] = strdupx(keyword);
+#endif
+}
+
+
+void varDefOptGribDbl(int varID, double dval, const char *keyword)
+{
+#if  defined  (HAVE_LIBGRIB_API)
+  int idx = vartable[varID].opt_grib_dbl_nentries;
+  vartable[varID].opt_grib_dbl_nentries++;
+  if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many optional keyword/double value pairs!");
+  vartable[varID].opt_grib_dbl_val[idx] = dval;
+  vartable[varID].opt_grib_dbl_keyword[idx] = strdupx(keyword);
+#endif
+}
+
+
+int varOptGribNentries(int varID)
+{
+  int nentries = 0;
+#if  defined  (HAVE_LIBGRIB_API)
+  nentries = vartable[varID].opt_grib_int_nentries + vartable[varID].opt_grib_dbl_nentries;
+#endif
+  return (nentries);
+}
+
 /*
  * Local Variables:
  * c-file-style: "Java"
diff --git a/libcdi/src/varscan.h b/libcdi/src/varscan.h
index f24f162..084d1f6 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 level_sf, int prec,
+		  int level1, int level2, int level_sf, int level_unit, int prec,
 		  int *pvarID, int *plevelID, int tsteptype, int numavg, int ltype,
 		  const char *name, const char *longname, const char *units);
 
@@ -29,6 +29,10 @@ void varDefTable(int varID, int tableID);
 int  varInqTable(int varID);
 void varDefEnsembleInfo(int varID, int ens_idx, int ens_count, int forecast_type);
 
+void varDefOptGribInt(int varID, long lval, const char *keyword);
+void varDefOptGribDbl(int varID, double dval, const char *keyword);
+int varOptGribNentries(int varID);
+
 int  zaxisCompare(int zaxisID, int zaxistype, int nlevels, int lbounds, double *levels, char *longname, char *units, int ltype);
 
 #endif
diff --git a/libcdi/src/vlist.c b/libcdi/src/vlist.c
index adfabf6..44c57a3 100644
--- a/libcdi/src/vlist.c
+++ b/libcdi/src/vlist.c
@@ -4,7 +4,7 @@
 
 #include "dmemory.h"
 #include "cdi.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "vlist.h"
 #include "zaxis.h"
 #include "varscan.h"
@@ -15,6 +15,12 @@
 #include "vlist_att.h"
 #include "pio_rpc.h"
 
+#if  defined  (HAVE_LIBGRIB_API)
+/* list of additional GRIB2 keywords which are read by the open process */
+int    cdiNAdditionalGRIBKeys = 0;
+char*  cdiAdditionalGRIBKeys[MAX_OPT_GRIB_ENTRIES];
+#endif
+
 extern void zaxisGetIndexList ( int, int * );
 
 static int VLIST_Debug = 0;
@@ -226,6 +232,7 @@ void vlistDestroy(int vlistID)
 
       if ( vlistptr->vars[varID].ensdata )  free(vlistptr->vars[varID].ensdata);
 
+#if  defined  (HAVE_LIBGRIB_API)
       int i;
       for (i=0; i<vlistptr->vars[varID].opt_grib_int_nentries; i++) {
 	if ( vlistptr->vars[varID].opt_grib_int_keyword[i] )
@@ -235,6 +242,7 @@ void vlistDestroy(int vlistID)
 	if ( vlistptr->vars[varID].opt_grib_dbl_keyword[i] )
 	  free(vlistptr->vars[varID].opt_grib_dbl_keyword[i]);
       }
+#endif
 
       vlistDelAtts(vlistID, varID);
     }
@@ -302,6 +310,7 @@ void vlistCopy(int vlistID2, int vlistID1)
                      vlistptr1->vars[varID].ensdata, sizeof(ensinfo_t));
             }
 
+#if  defined  (HAVE_LIBGRIB_API)
           /* ---------------------------------- */
           /* Local change: 2013-01-28, FP (DWD) */
           /* ---------------------------------- */
@@ -321,6 +330,7 @@ void vlistCopy(int vlistID2, int vlistID1)
 	      vlistptr2->vars[varID].opt_grib_dbl_val[i]     = vlistptr1->vars[varID].opt_grib_dbl_val[i];
 	    }
 	  }
+#endif
 
 	  vlistptr2->vars[varID].atts.nelems = 0;
 	  vlistCopyVarAtts(vlistID1, varID, vlistID2, varID);
@@ -551,6 +561,7 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
                        vlistptr1->vars[varID].ensdata, sizeof(ensinfo_t));
               }
 
+#if  defined  (HAVE_LIBGRIB_API)
 	    /* ---------------------------------- */
 	    /* Local change: 2013-01-28, FP (DWD) */
 	    /* ---------------------------------- */
@@ -570,6 +581,7 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
 		vlistptr2->vars[varID2].opt_grib_dbl_val[i]     = vlistptr1->vars[varID].opt_grib_dbl_val[i];
 	      }
 	    }
+#endif
 
 	    vlistptr2->vars[varID2].atts.nelems = 0;
 	    vlistCopyVarAtts(vlistID1, varID, vlistID2, varID2);
@@ -770,6 +782,7 @@ void vlistCat(int vlistID2, int vlistID1)
           memcpy(vlistptr2->vars[varID2].ensdata, vlistptr1->vars[varID].ensdata, sizeof(ensinfo_t));
         }
 
+#if  defined  (HAVE_LIBGRIB_API)
       /* ---------------------------------- */
       /* Local change: 2013-01-28, FP (DWD) */
       /* ---------------------------------- */
@@ -789,6 +802,7 @@ void vlistCat(int vlistID2, int vlistID1)
 	  vlistptr2->vars[varID2].opt_grib_dbl_val[i]     = vlistptr1->vars[varID].opt_grib_dbl_val[i];
 	}
       }
+#endif
 
       vlistptr2->vars[varID2].atts.nelems = 0;
       vlistCopyVarAtts(vlistID1, varID, vlistID2, varID2);
diff --git a/libcdi/src/vlist.h b/libcdi/src/vlist.h
index a49f394..2e6970f 100644
--- a/libcdi/src/vlist.h
+++ b/libcdi/src/vlist.h
@@ -101,6 +101,7 @@ typedef struct
   char       *longname;
   char       *stdname;
   char       *units;
+  char       *extra;
   double      missval;
   double      scalefactor;
   double      addoffset;
@@ -114,6 +115,7 @@ typedef struct
   int         decoSize;
   deco_t     *deco;
 
+#if  defined  (HAVE_LIBGRIB_API)
   /* ---------------------------------- */
   /* Local change: 2013-01-28, FP (DWD) */
   /* ---------------------------------- */
@@ -126,6 +128,7 @@ typedef struct
   int    opt_grib_int_nentries;
   char*  opt_grib_int_keyword[MAX_OPT_GRIB_ENTRIES];
   int    opt_grib_int_val[MAX_OPT_GRIB_ENTRIES];
+#endif
 }
 var_t;
 
@@ -177,6 +180,11 @@ void    vlistDefVarValidrange(int vlistID, int varID, const double *validrange);
 /*      vlistInqVarValidrange: Get the valid range of a Variable */
 int     vlistInqVarValidrange(int vlistID, int varID, double *validrange);
 
+#if  defined  (HAVE_LIBGRIB_API)
+extern int   cdiNAdditionalGRIBKeys;
+extern char* cdiAdditionalGRIBKeys[];
+#endif
+
 #endif  /* _VLIST_H */
 /*
  * Local Variables:
diff --git a/libcdi/src/vlist_att.c b/libcdi/src/vlist_att.c
index 39076cb..db29cf2 100644
--- a/libcdi/src/vlist_att.c
+++ b/libcdi/src/vlist_att.c
@@ -13,7 +13,7 @@
 #include "dmemory.h"
 
 #include "cdi.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "vlist.h"
 #include "pio_util.h"
 
@@ -247,7 +247,7 @@ int vlist_def_att(int indtype, int exdtype, int vlistID, int varID, const char *
 
   if ( attp != NULL )
     fill_att(attp, indtype, exdtype, len, xsz, xp);
-  
+
   return (status);
 }
 
@@ -337,11 +337,7 @@ The function @func{vlistDefAttInt} defines an integer attribute.
 */
 int vlistDefAttInt(int vlistID, int varID, const char *name, int type, int len, const int *ip)
 {
-  int status;
-
-  status = vlist_def_att(DATATYPE_INT, type, vlistID, varID, name, (size_t) len, len*sizeof(int), (const void *) ip);
-
-  return (status);
+  return vlist_def_att(DATATYPE_INT, type, vlistID, varID, name, (size_t) len, len*sizeof(int), (const void *) ip);
 }
 
 /*
@@ -365,11 +361,7 @@ The function @func{vlistDefAttFlt} defines a floating point attribute.
 */
 int vlistDefAttFlt(int vlistID, int varID, const char *name, int type, int len, const double *dp)
 {
-  int status;
-
-  status = vlist_def_att(DATATYPE_FLT, type, vlistID, varID, name, (size_t) len, len*sizeof(double), (const void *) dp);
-
-  return (status);
+  return vlist_def_att(DATATYPE_FLT, type, vlistID, varID, name, (size_t) len, len*sizeof(double), (const void *) dp);
 }
 
 /*
@@ -392,11 +384,7 @@ The function @func{vlistDefAttTxt} defines a text attribute.
 */
 int vlistDefAttTxt(int vlistID, int varID, const char *name, int len, const char *tp)
 {
-  int status;
-
-  status = vlist_def_att(DATATYPE_TXT, DATATYPE_TXT, vlistID, varID, name, (size_t) len, len*sizeof(char), (const void *) tp);
-
-  return (status);
+  return vlist_def_att(DATATYPE_TXT, DATATYPE_TXT, vlistID, varID, name, (size_t) len, len*sizeof(char), (const void *) tp);
 }
 
 /*
@@ -418,17 +406,14 @@ The function @func{vlistInqAttInt} gets the values(s) of an integer attribute.
 */
 int vlistInqAttInt(int vlistID, int varID, const char *name, int mlen, int *ip)
 {
-  int status
-    = vlist_inq_att(DATATYPE_INT, vlistID, varID, name,
-                    mlen*sizeof(int), (void *) ip);
-  return status;
+  return vlist_inq_att(DATATYPE_INT, vlistID, varID, name, mlen*sizeof(int), (void *) ip);
 }
 
 /*
 @Function  vlistInqAttFlt
 @Title     Get the value(s) of a floating point attribute
 
- at Prototype int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, int *dp)
+ at Prototype int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double *dp)
 @Parameter
     @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
     @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
@@ -443,18 +428,14 @@ The function @func{vlistInqAttFlt} gets the values(s) of a floating point attrib
 */
 int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double *dp)
 {
-  int status = CDI_NOERR;
-
-  status = vlist_inq_att(DATATYPE_FLT, vlistID, varID, name, mlen*sizeof(double), (void *) dp);
-
-  return (status);
+  return vlist_inq_att(DATATYPE_FLT, vlistID, varID, name, mlen*sizeof(double), (void *) dp);
 }
 
 /*
 @Function  vlistInqAttTxt
 @Title     Get the value(s) of a text attribute
 
- at Prototype int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, int *tp)
+ at Prototype int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp)
 @Parameter
     @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
     @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
@@ -469,11 +450,7 @@ The function @func{vlistInqAttTxt} gets the values(s) of a text attribute.
 */
 int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp)
 {
-  int status = CDI_NOERR;
-
-  status = vlist_inq_att(DATATYPE_TXT, vlistID, varID, name, mlen*sizeof(char), (void *) tp);
-
-  return (status);
+  return vlist_inq_att(DATATYPE_TXT, vlistID, varID, name, mlen*sizeof(char), (void *) tp);
 }
 
 #ifdef USE_MPI
diff --git a/libcdi/src/vlist_var.c b/libcdi/src/vlist_var.c
index 20bbbe6..9c8e919 100644
--- a/libcdi/src/vlist_var.c
+++ b/libcdi/src/vlist_var.c
@@ -10,7 +10,7 @@
 
 #include "dmemory.h"
 #include "cdi.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "vlist.h"
 #include "vlist_var.h"
 #include "resource_handle.h"
@@ -50,6 +50,7 @@ void vlistvarInitEntry(int vlistID, int varID)
   vlistptr->vars[varID].longname      = NULL;
   vlistptr->vars[varID].stdname       = NULL;
   vlistptr->vars[varID].units         = NULL;
+  vlistptr->vars[varID].extra         = NULL;
   vlistptr->vars[varID].nlevs         = 0;
   vlistptr->vars[varID].levinfo       = NULL;
   vlistptr->vars[varID].comptype      = COMPRESS_NONE;
@@ -64,6 +65,7 @@ void vlistvarInitEntry(int vlistID, int varID)
   vlistptr->vars[varID].decoSize      = 0;
   vlistptr->vars[varID].deco          = NULL;
 
+#if  defined  (HAVE_LIBGRIB_API)
   /* ---------------------------------- */
   /* Local change: 2013-01-28, FP (DWD) */
   /* ---------------------------------- */
@@ -77,6 +79,7 @@ void vlistvarInitEntry(int vlistID, int varID)
     vlistptr->vars[varID].opt_grib_int_keyword[i] = NULL;
     vlistptr->vars[varID].opt_grib_dbl_keyword[i] = NULL;
   } // for
+#endif
 }
 
 static
@@ -854,16 +857,16 @@ void vlistDefVarDatatype(int vlistID, int varID, int datatype)
     }
 
   vlistptr->vars[varID].datatype = datatype;
-  
+
   if ( vlistptr->vars[varID].missvalused == FALSE )
     switch (datatype)
       {
-      case DATATYPE_INT8:   vlistptr->vars[varID].missval = SCHAR_MIN; break;
-      case DATATYPE_UINT8:  vlistptr->vars[varID].missval = UCHAR_MAX; break;
-      case DATATYPE_INT16:  vlistptr->vars[varID].missval = SHRT_MIN;  break;
-      case DATATYPE_UINT16: vlistptr->vars[varID].missval = USHRT_MAX; break;
-      case DATATYPE_INT32:  vlistptr->vars[varID].missval = INT_MIN;   break;
-      case DATATYPE_UINT32: vlistptr->vars[varID].missval = UINT_MAX;  break;
+      case DATATYPE_INT8:   vlistptr->vars[varID].missval = -SCHAR_MAX; break;
+      case DATATYPE_UINT8:  vlistptr->vars[varID].missval =  UCHAR_MAX; break;
+      case DATATYPE_INT16:  vlistptr->vars[varID].missval = -SHRT_MAX;  break;
+      case DATATYPE_UINT16: vlistptr->vars[varID].missval =  USHRT_MAX; break;
+      case DATATYPE_INT32:  vlistptr->vars[varID].missval = -INT_MAX;   break;
+      case DATATYPE_UINT32: vlistptr->vars[varID].missval =  UINT_MAX;  break;
       }
 }
 
@@ -1179,6 +1182,87 @@ void vlistDefVarMissval(int vlistID, int varID, double missval)
   vlistptr->vars[varID].missvalused = TRUE;
 }
 
+/*
+ at Function  vlistDefVarExtra
+ at Title     Define extra information of a Variable
+
+ at Prototype void vlistDefVarExtra(int vlistID, int varID, const char *extra)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  varID    Variable identifier.
+    @Item  extra    Extra information.
+
+ at Description
+The function @func{vlistDefVarExtra} defines the extra information of a variable.
+
+ at EndFunction
+*/
+void vlistDefVarExtra(int vlistID, int varID, const char *extra)
+{
+  vlist_t *vlistptr;
+
+  if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
+    {
+      xwarning("%s", "Operation not executed." );
+      return;
+    }
+
+  vlistptr = vlist_to_pointer(vlistID);
+
+  vlistCheckVarID(__func__, vlistID, varID);
+
+  if ( extra )
+    {
+      if ( vlistptr->vars[varID].extra )
+	{
+	  free(vlistptr->vars[varID].extra);
+	  vlistptr->vars[varID].extra = NULL;
+	}
+
+      vlistptr->vars[varID].extra = strdupx(extra);
+    }
+}
+
+/*
+ at Function  vlistInqVarExtra
+ at Title     Get extra information of a Variable
+
+ at Prototype void vlistInqVarExtra(int vlistID, int varID, char *extra)
+ at Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  varID    Variable identifier.
+    @Item  extra    Returned variable extra information. The caller must allocate space for the
+                    returned string. The maximum possible length, in characters, of
+                    the string is given by the predefined constant @func{CDI_MAX_NAME}.
+
+ at Description
+The function @func{vlistInqVarExtra} returns the extra information of a variable.
+
+ at Result
+ at func{vlistInqVarExtra} returns the extra information of the variable to the parameter extra if available,
+otherwise the result is an empty string.
+
+ at EndFunction
+*/
+void vlistInqVarExtra(int vlistID, int varID, char *extra)
+{
+  int tableID;
+  int param;
+  int pdis, pcat, pnum;
+  vlist_t *vlistptr;
+
+  vlistptr = vlist_to_pointer(vlistID);
+
+  vlistCheckVarID(__func__, vlistID, varID);
+
+  if ( vlistptr->vars[varID].extra == NULL )
+      sprintf(extra, "-");
+  else
+    strcpy(extra, vlistptr->vars[varID].extra);
+
+  return;
+}
+
 
 int vlistInqVarValidrange(int vlistID, int varID, double *validrange)
 {
@@ -1819,6 +1903,7 @@ int vlistInqVarEnsemble( int vlistID, int varID, int *ensID, int *ensCount, int
 /* vlistDefVarIntKey: Set an arbitrary keyword/integer value pair for GRIB API */
 void vlistDefVarIntKey(int vlistID, int varID, const char *name, int value)
 {
+#if  defined  (HAVE_LIBGRIB_API)
   vlist_t *vlistptr;
   vlistptr = vlist_to_pointer(vlistID);
 
@@ -1830,11 +1915,13 @@ void vlistDefVarIntKey(int vlistID, int varID, const char *name, int value)
     vlistptr->vars[varID].opt_grib_int_keyword[idx] = strdupx(name);
   else
     Error("Internal error!");
+#endif
 }
 
 /* vlistDefVarDblKey: Set an arbitrary keyword/double value pair for GRIB API */
 void vlistDefVarDblKey(int vlistID, int varID, const char *name, double value)
 {
+#if  defined  (HAVE_LIBGRIB_API)
   vlist_t *vlistptr;
   vlistptr = vlist_to_pointer(vlistID);
 
@@ -1846,6 +1933,7 @@ void vlistDefVarDblKey(int vlistID, int varID, const char *name, double value)
     vlistptr->vars[varID].opt_grib_dbl_keyword[idx] = strdupx(name);
   else
     Error("Internal error!");
+#endif
 }
 
 #if  defined  (HAVE_LIBGRIB_API)
@@ -1853,67 +1941,90 @@ void vlistDefVarDblKey(int vlistID, int varID, const char *name, double value)
 #  include "grib_api.h"
 #endif
 
-/* vlistInqVarRawBegin: Open GRIB record to retrieve raw meta-data in subsequent calls */
-void vlistInqVarRawBegin(int streamID, int varID)
+
+/* cdiClearAdditionalKeys: Clears the list of additional GRIB keys. */
+void cdiClearAdditionalKeys()
 {
 #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);
+  int i;
+  for (i=0; i<cdiNAdditionalGRIBKeys; i++)  free(cdiAdditionalGRIBKeys[i]);
+  cdiNAdditionalGRIBKeys = 0;
+#endif
+}
 
-  fileID  = streamInqFileID(streamID);
-  tsID    = streamptr->curTsID;
+/* cdiDefAdditionalKey: Register an additional GRIB key which is read when file is opened. */
+void cdiDefAdditionalKey(const char *name)
+{
+#if  defined  (HAVE_LIBGRIB_API)
+  int idx = cdiNAdditionalGRIBKeys;
+  cdiNAdditionalGRIBKeys++;
+  if ( idx >= MAX_OPT_GRIB_ENTRIES ) Error("Too many additional keywords!");
+  if ( name )
+    cdiAdditionalGRIBKeys[idx] = strdupx(name);
+  else
+    Error("Internal error!");
+#endif
+}
 
-  // 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;
+/* vlistHasVarKey: returns 1 if meta-data key was read, 0 otherwise. */
+int vlistHasVarKey(int vlistID, int varID, const char* name)
+{
+#if  defined  (HAVE_LIBGRIB_API)
+  /* check if the GRIB key was previously read and is stored */
+  vlist_t *vlistptr;
+  int      i;
+  vlistptr = vlist_to_pointer(vlistID);
 
-  fileSetPos(fileID, recpos, SEEK_SET);
-  fileRead(fileID, streamptr->record->buffer, (size_t) recsize);
+  for (i=0; i<vlistptr->vars[varID].opt_grib_dbl_nentries; i++)
+    {
+      if ( strcmp(name, vlistptr->vars[varID].opt_grib_dbl_keyword[i]) == 0 )
+	return 1;
+    }
 
-  streamptr->gh = (void *) grib_handle_new_from_message(NULL, (void *) streamptr->record->buffer, recsize);
+  for (i=0; i<vlistptr->vars[varID].opt_grib_int_nentries; i++)
+    {
+      if ( strcmp(name, vlistptr->vars[varID].opt_grib_int_keyword[i]) == 0 )
+	return 1;
+    }
 #endif
+  return 0;
 }
 
-
 /* vlistInqVarDblKey: raw access to GRIB meta-data */
-double vlistInqVarDblKey(int streamID, const char* name)
+double vlistInqVarDblKey(int vlistID, int varID, 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);
+  /* check if the GRIB key was previously read and is stored in
+     "opt_grib_dbl_val" */
+  vlist_t *vlistptr;
+  vlistptr = vlist_to_pointer(vlistID);
+
+  int i;
+  for (i=0; i<vlistptr->vars[varID].opt_grib_dbl_nentries; i++)
+    if ( strcmp(name, vlistptr->vars[varID].opt_grib_dbl_keyword[i]) == 0 )
+      return vlistptr->vars[varID].opt_grib_dbl_val[i];
 #endif
   return value;
 }
 
 
 /* vlistInqVarIntKey: raw access to GRIB meta-data */
-int vlistInqVarIntKey(int streamID, const char* name)
+int vlistInqVarIntKey(int vlistID, int varID, 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;
-}
-
+  /* check if the GRIB key was previously read and is stored in
+     "opt_grib_int_val" */
+  vlist_t *vlistptr;
+  vlistptr = vlist_to_pointer(vlistID);
 
-/* 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);
+  int i;
+  for (i=0; i<vlistptr->vars[varID].opt_grib_int_nentries; i++)
+    if ( strcmp(name, vlistptr->vars[varID].opt_grib_int_keyword[i]) == 0 )
+      return vlistptr->vars[varID].opt_grib_int_val[i];
 #endif
+  return (int) value;
 }
 
 
diff --git a/libcdi/src/zaxis.c b/libcdi/src/zaxis.c
index cc9ac86..2d38392 100644
--- a/libcdi/src/zaxis.c
+++ b/libcdi/src/zaxis.c
@@ -9,7 +9,7 @@
 #include "dmemory.h"
 
 #include "cdi.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "pio_util.h"
 #include "resource_handle.h"
 #include "pio_rpc.h"
@@ -21,11 +21,11 @@
 
 
 static struct {
-  unsigned char positive;
+  unsigned char positive;   // 1: up;  2: down
   char *name;
   char *longname;
   char *stdname;
-  char *units;    // 1: up;  2: down
+  char *units;
 }
 ZaxistypeEntry[] = {
   { /*  0 */ 0, "sfc",        "surface",           "",               ""},
@@ -47,7 +47,8 @@ ZaxistypeEntry[] = {
   { /* 16 */ 0, "cloudbase",  "cloud_base",        "",               ""},
   { /* 17 */ 0, "cloudtop",   "cloud_top",         "",               ""},
   { /* 18 */ 0, "isotherm0",  "isotherm_zero",     "",               ""},
-  { /* 19 */ 0, "height",     "generalized height","height",         "m"},
+  { /* 19 */ 0, "snow",       "snow",              "",               ""},
+  { /* 20 */ 0, "height",     "generalized height","height",         "m"},
 };
 
 static int CDI_MaxZaxistype = sizeof(ZaxistypeEntry) / sizeof(ZaxistypeEntry[0]);
@@ -183,7 +184,7 @@ int zaxisSize(void)
                       @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_CLOUD_TOP}, @func{ZAXIS_ISOTHERM_ZERO}, @func{ZAXIS_SNOW},
                       @func{ZAXIS_DEPTH_BELOW_SEA} and @func{ZAXIS_DEPTH_BELOW_LAND}.
     @Item  size       Number of levels.
 
@@ -717,7 +718,7 @@ void zaxisDefUUID(int zaxisID, const char *uuid)
 
   zaxis_check_ptr(zaxisID, zaxisptr);
 
-  strncpy(zaxisptr->uuid, uuid, 16);
+  memcpy(zaxisptr->uuid, uuid, 16);
 
   return;
 }
@@ -745,7 +746,7 @@ char *zaxisInqUUID(int zaxisID, char *uuid)
 
   zaxis_check_ptr(zaxisID, zaxisptr);
 
-  strncpy(uuid, zaxisptr->uuid, 16);
+  memcpy(uuid, zaxisptr->uuid, 16);
 
   return (uuid);
 }
@@ -995,7 +996,7 @@ 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},
- at func{ZAXIS_CLOUD_TOP}, @func{ZAXIS_ISOTHERM_ZERO}, 
+ at func{ZAXIS_CLOUD_TOP}, @func{ZAXIS_ISOTHERM_ZERO}, @func{ZAXIS_SNOW},
 @func{ZAXIS_DEPTH_BELOW_SEA} and @func{ZAXIS_DEPTH_BELOW_LAND}.
 
 @EndFunction
diff --git a/libcdi/tests/cksum_write.c b/libcdi/tests/cksum_write.c
index 99cb824..7b25d6d 100644
--- a/libcdi/tests/cksum_write.c
+++ b/libcdi/tests/cksum_write.c
@@ -127,8 +127,7 @@ main(int argc, char *argv[])
         nts = parse_intarg("error parsing number of timesteps");
         break;
       default: /* '?' */
-        fprintf(stderr, "Usage: %s [-m nlon] [-n nlat] [-o nlev] [-t nts]\n",
-                argv[0]);
+        fprintf(stderr, "Usage: %s [-m nlon] [-n nlat] [-o nlev] [-t nts]\n", argv[0]);
         exit(EXIT_FAILURE);
       }
   }
@@ -141,7 +140,7 @@ main(int argc, char *argv[])
     lats[i] = ((double)(i * 180))/nlat - 90.0;
   levs = malloc(nlev * sizeof (levs[0]));
   for (i = 0; i < nlev; ++i)
-    levs[i] = 101300 - 3940.3 * (exp(1.3579 * (double)(i)/(nlev - 1)) - 1.0);
+    levs[i] = 101300 - floor(3940.3 * (exp(2.3579 * (double)(i)/(nlev - 1)) - 1.0));
 
   varSize[0] = nlon * nlat;
   varSize[1] = nlon * nlat * nlev;
@@ -263,10 +262,8 @@ main(int argc, char *argv[])
                             / (lons[nlat-1] - lats[0]))
                       ) * mscale)) * mrscale;
 
-        memcrc_r(&checksum_state[0], (const unsigned char *)var[0],
-                 varSize[0] * sizeof (var[0][0]));
-        memcrc_r(&checksum_state[1], (const unsigned char *)var[1],
-                 varSize[1] * sizeof (var[1][0]));
+        memcrc_r(&checksum_state[0], (const unsigned char *)var[0], varSize[0] * sizeof (var[0][0]));
+        memcrc_r(&checksum_state[1], (const unsigned char *)var[1], varSize[1] * sizeof (var[1][0]));
 
         // Write var1 and var2
         streamWriteVar(streamID, varID[0], var[0], nmiss);
@@ -288,8 +285,7 @@ main(int argc, char *argv[])
         {
           uint32_t cksum;
           int code;
-          cksum = memcrc_finish(&checksum_state[i],
-                                (off_t)varSize[i] * sizeof (var[i][0]) * nts);
+          cksum = memcrc_finish(&checksum_state[i], (off_t)varSize[i] * sizeof (var[i][0]) * nts);
           code = vlistInqVarCode(vlistID, varID[i]);
           if (fprintf(tablefp, "%08lx %d\n", (unsigned long)cksum, code) < 0)
             {
diff --git a/m4/acx_options.m4 b/m4/acx_options.m4
index 7f339f4..8016b81 100644
--- a/m4/acx_options.m4
+++ b/m4/acx_options.m4
@@ -312,6 +312,21 @@ AC_ARG_ENABLE([ieg],
 AC_MSG_RESULT([$enable_ieg])
 AC_SUBST([ENABLE_IEG],[$enable_ieg])
 #  ----------------------------------------------------------------------
+#  Compile with fftw support
+AC_MSG_CHECKING([for FFTW3 support])
+AC_ARG_WITH([fftw3],
+    [AS_HELP_STRING([--without-fftw3],
+      [disable support for fftw3])],
+    [],
+    [with_fftw3=yes])
+
+  AS_IF([test "x$with_fftw3" != xno],
+      [AC_CHECK_HEADERS([fftw3.h])
+    AC_SEARCH_LIBS([fftw_cleanup],[fftw3],
+      [AC_DEFINE([HAVE_LIBFFTW3],[1],[FFTW3 library is present if defined to 1])],
+      [AC_MSG_RESULT([Could not link to fftw3 library])])])
+
+#  ----------------------------------------------------------------------
 #  Checks for PROJ.4 library
 AC_ARG_WITH([proj],
             [AS_HELP_STRING([--with-proj=<directory>],
diff --git a/src/._CdoMagicsMapper.h b/src/._CdoMagicsMapper.h
index 41970ee..0bf182a 100644
Binary files a/src/._CdoMagicsMapper.h and b/src/._CdoMagicsMapper.h differ
diff --git a/src/._Maggraph.c b/src/._Maggraph.c
deleted file mode 100644
index ac9f42c..0000000
Binary files a/src/._Maggraph.c and /dev/null differ
diff --git a/src/._Magplot.c b/src/._Magplot.c
deleted file mode 100644
index 39512cd..0000000
Binary files a/src/._Magplot.c and /dev/null differ
diff --git a/src/._Magvector.c b/src/._Magvector.c
deleted file mode 100644
index db92965..0000000
Binary files a/src/._Magvector.c and /dev/null differ
diff --git a/src/._Rhopot.c b/src/._Rhopot.c
deleted file mode 100644
index 70fd267..0000000
Binary files a/src/._Rhopot.c and /dev/null differ
diff --git a/src/._StringUtilities.c b/src/._StringUtilities.c
index fa730a7..3bf3f4b 100644
Binary files a/src/._StringUtilities.c and b/src/._StringUtilities.c differ
diff --git a/src/._StringUtilities.h b/src/._StringUtilities.h
index 6c0ff55..dab9ce1 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 11d1ace..09c0584 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 d92da7d..9690fc5 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 14c70a0..afe55fa 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 64de6c5..f1a77a9 100644
Binary files a/src/._template_parser.h and b/src/._template_parser.h differ
diff --git a/src/Arith.c b/src/Arith.c
index b43503f..529f87f 100644
--- a/src/Arith.c
+++ b/src/Arith.c
@@ -113,12 +113,12 @@ void *Arith(void *argument)
       if ( ntsteps1 != 1 && ntsteps2 == 1 )
 	{
 	  filltype = FILL_VAR;
-	  cdoPrint("Filling up stream2 >%s< by copying the first variable.", cdoStreamName(1));
+	  cdoPrint("Filling up stream2 >%s< by copying the first variable.", cdoStreamName(1)->args);
 	}
       else
 	{
 	  filltype = FILL_VARTS;
-	  cdoPrint("Filling up stream2 >%s< by copying the first variable of each timestep.", cdoStreamName(1));
+	  cdoPrint("Filling up stream2 >%s< by copying the first variable of each timestep.", cdoStreamName(1)->args);
 	}
     }
   else if ( lfill1 )
@@ -128,12 +128,12 @@ void *Arith(void *argument)
       if ( ntsteps1 == 1 && ntsteps2 != 1 )
 	{
 	  filltype = FILL_VAR;
-	  cdoPrint("Filling up stream1 >%s< by copying the first variable.", cdoStreamName(0));
+	  cdoPrint("Filling up stream1 >%s< by copying the first variable.", cdoStreamName(0)->args);
 	}
       else
 	{
 	  filltype = FILL_VARTS;
-	  cdoPrint("Filling up stream1 >%s< by copying the first variable of each timestep.", cdoStreamName(0));
+	  cdoPrint("Filling up stream1 >%s< by copying the first variable of each timestep.", cdoStreamName(0)->args);
 	}
       streamIDx1 = streamID2;
       streamIDx2 = streamID1;
@@ -163,12 +163,12 @@ void *Arith(void *argument)
       if ( ntsteps1 != 1 && ntsteps2 == 1 )
 	{
 	  filltype = FILL_TS;
-	  cdoPrint("Filling up stream2 >%s< by copying the first timestep.", cdoStreamName(1));
+	  cdoPrint("Filling up stream2 >%s< by copying the first timestep.", cdoStreamName(1)->args);
 	}
       else if ( ntsteps1 == 1 && ntsteps2 != 1 )
 	{
 	  filltype = FILL_TS;
-	  cdoPrint("Filling up stream1 >%s< by copying the first timestep.", cdoStreamName(0));
+	  cdoPrint("Filling up stream1 >%s< by copying the first timestep.", cdoStreamName(0)->args);
 	  streamIDx1 = streamID2;
           streamIDx2 = streamID1;
 	  vlistIDx1 = vlistID2;
@@ -220,7 +220,7 @@ void *Arith(void *argument)
 	      if ( filltype == FILL_NONE && streamIDx2 == streamID2 )
 		{
 		  filltype = FILL_FILE;
-		  cdoPrint("Filling up stream2 >%s< by copying all timesteps.", cdoStreamName(1));
+		  cdoPrint("Filling up stream2 >%s< by copying all timesteps.", cdoStreamName(1)->args);
 		}
 
 	      if ( filltype == FILL_FILE )
@@ -237,7 +237,7 @@ void *Arith(void *argument)
 
 		  nrecs2 = streamInqTimestep(streamIDx2, tsID2);
 		  if ( nrecs2 == 0 )
-		    cdoAbort("Empty input stream %s!", cdoStreamName(1));
+		    cdoAbort("Empty input stream %s!", cdoStreamName(1)->args);
 		}
 	      else
 		cdoAbort("Input streams have different number of timesteps!");
diff --git a/src/Arithc.c b/src/Arithc.c
index fea20bb..322e017 100644
--- a/src/Arithc.c
+++ b/src/Arithc.c
@@ -157,6 +157,8 @@ void *Arithc(void *argument)
   if ( field.ptr ) free(field.ptr);
   if ( vars ) free(vars);
 
+  vlistDestroy(vlistID2);
+
   cdoFinish();
 
   return (0);
diff --git a/src/CDIread.c b/src/CDIread.c
index 904b755..fbfd3ce 100644
--- a/src/CDIread.c
+++ b/src/CDIread.c
@@ -205,7 +205,7 @@ void *CDIread(void *argument)
       tw = timer_val(timer_read) - tw0;
       twsum += tw;
 
-      file_size = (double) filesize(cdoStreamName(0));
+      file_size = (double) filesize(cdoStreamName(0)->args);
 
       if ( nruns > 1 ) sprintf(sinfo, "(run %d)", irun+1);
 
diff --git a/src/CDIwrite.c b/src/CDIwrite.c
index 590afed..cd8dffd 100644
--- a/src/CDIwrite.c
+++ b/src/CDIwrite.c
@@ -279,7 +279,7 @@ void *CDIwrite(void *argument)
       tw = timer_val(timer_write) - tw0;
       twsum += tw;
 
-      file_size = (double ) filesize(cdoStreamName(0));
+      file_size = (double ) filesize(cdoStreamName(0)->args);
 
       if ( nruns > 1 ) sprintf(sinfo, "(run %d)", irun+1);
 
diff --git a/src/Cat.c b/src/Cat.c
index e0424e0..5440bad 100644
--- a/src/Cat.c
+++ b/src/Cat.c
@@ -51,7 +51,7 @@ void *Cat(void *argument)
 
   for ( indf = 0; indf < nfiles; indf++ )
     {
-      if ( cdoVerbose ) cdoPrint("Process file: %s", cdoStreamName(indf));
+      if ( cdoVerbose ) cdoPrint("Process file: %s", cdoStreamName(indf)->args);
 
       streamID1 = streamOpenRead(cdoStreamName(indf));
 
@@ -60,7 +60,7 @@ void *Cat(void *argument)
 
       if ( indf == 0 )
 	{
-	  if ( fileExists(cdoStreamName(nfiles)) )
+	  if ( fileExists(cdoStreamName(nfiles)->args) )
 	    {
 	      streamID2 = streamOpenAppend(cdoStreamName(nfiles));
 
@@ -75,7 +75,7 @@ void *Cat(void *argument)
 	  else
 	    {
 	      if ( cdoVerbose )
-		cdoPrint("Output file doesn't exist, creating: %s", cdoStreamName(nfiles));
+		cdoPrint("Output file doesn't exist, creating: %s", cdoStreamName(nfiles)->args);
 
 	      streamID2 = streamOpenWrite(cdoStreamName(nfiles), cdoFiletype());
 
diff --git a/src/CdoMagicsMapper.c b/src/CdoMagicsMapper.c
index 8802e5e..4c995ed 100644
--- a/src/CdoMagicsMapper.c
+++ b/src/CdoMagicsMapper.c
@@ -3,6 +3,7 @@
 #endif
 
 #include "CdoMagicsMapper.h"
+#include "magics_template_parser.h"
 
 #define PARAM_COUNT  sizeof( mapper ) / sizeof ( CdoMagicsMapper )
 
diff --git a/src/Change_e5slm.c b/src/Change_e5slm.c
index d0965bc..c313d1c 100644
--- a/src/Change_e5slm.c
+++ b/src/Change_e5slm.c
@@ -67,7 +67,9 @@ void *Change_e5slm(void *argument)
   fn_slm = operatorArgv()[0];
 
   /* read SLM */
-  streamIDslm = streamOpenRead(fn_slm);
+  argument_t *fileargument = file_argument_new(fn_slm);
+  streamIDslm = streamOpenRead(fileargument);
+  file_argument_free(fileargument);
 
   vlistIDslm = streamInqVlist(streamIDslm);
 
diff --git a/src/Command.c b/src/Command.c
index 0f3f01f..4dd81c7 100644
--- a/src/Command.c
+++ b/src/Command.c
@@ -332,7 +332,7 @@ void *Command(void *argument)
 
   processStartTime(&s_utime, &s_stime);
 
-  gl_streamID = streamOpenRead(cdoStreamName(0));
+  gl_streamID = streamOpenRead(cdoStreamName(0)->args);
 
   command_init();
   
diff --git a/src/Comp.c b/src/Comp.c
index 8d4e199..23078a8 100644
--- a/src/Comp.c
+++ b/src/Comp.c
@@ -91,12 +91,12 @@ void *Comp(void *argument)
   if ( vlistNrecs(vlistID1) != 1 && vlistNrecs(vlistID2) == 1 )
     {
       filltype = FILL_REC;
-      cdoPrint("Filling up stream2 >%s< by copying the first record.", cdoStreamName(1));
+      cdoPrint("Filling up stream2 >%s< by copying the first record.", cdoStreamName(1)->args);
     }
   else if ( vlistNrecs(vlistID1) == 1 && vlistNrecs(vlistID2) != 1 )
     {
       filltype = FILL_REC;
-      cdoPrint("Filling up stream1 >%s< by copying the first record.", cdoStreamName(0));
+      cdoPrint("Filling up stream1 >%s< by copying the first record.", cdoStreamName(0)->args);
       streamIDx1 = streamID2;
       streamIDx2 = streamID1;
       vlistIDx1 = vlistID2;
@@ -127,12 +127,12 @@ void *Comp(void *argument)
       if ( ntsteps1 != 1 && ntsteps2 == 1 )
 	{
 	  filltype = FILL_TS;
-	  cdoPrint("Filling up stream2 >%s< by copying the first timestep.", cdoStreamName(1));
+	  cdoPrint("Filling up stream2 >%s< by copying the first timestep.", cdoStreamName(1)->args);
 	}
       else if ( ntsteps1 == 1 && ntsteps2 != 1 )
 	{
 	  filltype = FILL_TS;
-	  cdoPrint("Filling up stream1 >%s< by copying the first timestep.", cdoStreamName(0));
+	  cdoPrint("Filling up stream1 >%s< by copying the first timestep.", cdoStreamName(0)->args);
 	  streamIDx1 = streamID2;
           streamIDx2 = streamID1;
 	  vlistIDx1 = vlistID2;
diff --git a/src/Cond.c b/src/Cond.c
index e2576d5..0484f4e 100644
--- a/src/Cond.c
+++ b/src/Cond.c
@@ -77,7 +77,7 @@ void *Cond(void *argument)
   if ( vlistNrecs(vlistID1) == 1 && vlistNrecs(vlistID2) != 1 )
     {
       filltype = FILL_REC;
-      cdoPrint("Filling up stream1 >%s< by copying the first record.", cdoStreamName(0));
+      cdoPrint("Filling up stream1 >%s< by copying the first record.", cdoStreamName(0)->args);
     }
 
   if ( filltype == FILL_NONE )
@@ -93,7 +93,7 @@ void *Cond(void *argument)
   gridsize = vlistGridsizeMax(vlistID2);
 
   if ( filltype == FILL_REC && gridsize != gridInqSize(vlistGrid(vlistID1, 0)) )
-    cdoAbort("Stream1 >%s< has wrong gridsize!", cdoStreamName(0));
+    cdoAbort("Stream1 >%s< has wrong gridsize!", cdoStreamName(0)->args);
 
   array1 = (double *) malloc(gridsize*sizeof(double));
   array2 = (double *) malloc(gridsize*sizeof(double));
@@ -107,7 +107,7 @@ void *Cond(void *argument)
       if ( ntsteps1 == 1 && ntsteps2 != 1 )
 	{
 	  filltype = FILL_TS;
-	  cdoPrint("Filling up stream1 >%s< by copying the first timestep.", cdoStreamName(0));
+	  cdoPrint("Filling up stream1 >%s< by copying the first timestep.", cdoStreamName(0)->args);
 
 	  nvars  = vlistNvars(vlistID1);
 	  vardata1  = (double **) malloc(nvars*sizeof(double *));
diff --git a/src/Cond2.c b/src/Cond2.c
index b1ab0d0..4b8c744 100644
--- a/src/Cond2.c
+++ b/src/Cond2.c
@@ -77,7 +77,7 @@ void *Cond2(void *argument)
   if ( vlistNrecs(vlistID1) == 1 && vlistNrecs(vlistID2) != 1 )
     {
       filltype = FILL_REC;
-      cdoPrint("Filling up stream1 >%s< by copying the first record.", cdoStreamName(0));
+      cdoPrint("Filling up stream1 >%s< by copying the first record.", cdoStreamName(0)->args);
     }
 
   if ( filltype == FILL_NONE )
@@ -96,7 +96,7 @@ void *Cond2(void *argument)
   gridsize = vlistGridsizeMax(vlistID1);
 
   if ( filltype == FILL_REC && gridsize != gridInqSize(vlistGrid(vlistID1, 0)) )
-    cdoAbort("Stream1 >%s< has wrong gridsize!", cdoStreamName(0));
+    cdoAbort("Stream1 >%s< has wrong gridsize!", cdoStreamName(0)->args);
 
   array1 = (double *) malloc(gridsize*sizeof(double));
   array2 = (double *) malloc(gridsize*sizeof(double));
@@ -112,7 +112,7 @@ void *Cond2(void *argument)
       if ( ntsteps1 == 1 && ntsteps2 != 1 )
 	{
 	  filltype = FILL_TS;
-	  cdoPrint("Filling up stream1 >%s< by copying the first timestep.", cdoStreamName(0));
+	  cdoPrint("Filling up stream1 >%s< by copying the first timestep.", cdoStreamName(0)->args);
 
 	  nvars  = vlistNvars(vlistID1);
 	  vardata1  = (double **) malloc(nvars*sizeof(double *));
diff --git a/src/Copy.c b/src/Copy.c
index a28d0be..ba81f82 100644
--- a/src/Copy.c
+++ b/src/Copy.c
@@ -37,7 +37,7 @@ void *Copy(void *argument)
   int tsID1, tsID2, recID, varID, levelID;
   int lcopy = FALSE;
   int gridsize;
-  int vlistID1, vlistID2 = -1;
+  int vlistID1, vlistID2 = CDI_UNDEFID;
   int nmiss;
   int streamCnt, nfiles, indf;
   int taxisID1, taxisID2 = CDI_UNDEFID;
@@ -67,7 +67,7 @@ void *Copy(void *argument)
   tsID2 = 0;
   for ( indf = 0; indf < nfiles; indf++ )
     {
-      if ( cdoVerbose ) cdoPrint("Process file: %s", cdoStreamName(indf));
+      if ( cdoVerbose ) cdoPrint("Process file: %s", cdoStreamName(indf)->args);
 
       streamID1 = streamOpenRead(cdoStreamName(indf));
 
@@ -166,6 +166,7 @@ void *Copy(void *argument)
   streamClose(streamID2);
 
   if ( array ) free(array);
+  if ( vlistID2 != CDI_UNDEFID ) vlistDestroy(vlistID2);
 
   cdoFinish();
 
diff --git a/src/Echam5ini.c b/src/Echam5ini.c
index be47bfe..dfecd60 100644
--- a/src/Echam5ini.c
+++ b/src/Echam5ini.c
@@ -1456,9 +1456,9 @@ void *Echam5ini(void *argument)
       iniatts(&atts);
 
       if ( operatorID == IMPORT_E5ML )
-	nvars = import_e5ml(cdoStreamName(0), &vars);
+	nvars = import_e5ml(cdoStreamName(0)->args, &vars);
       else if ( operatorID == IMPORT_E5RES )
-	nvars = import_e5res(cdoStreamName(0), &vars, &atts);
+	nvars = import_e5res(cdoStreamName(0)->args, &vars, &atts);
       else
 	cdoAbort("Operator not implemented!");
 
@@ -1607,9 +1607,9 @@ void *Echam5ini(void *argument)
       streamClose(streamID1);
 
       if ( operatorID == EXPORT_E5ML )
-	export_e5ml(cdoStreamName(1), vars, nvars, vdate, vtime, ntr);
+	export_e5ml(cdoStreamName(1)->args, vars, nvars, vdate, vtime, ntr);
       else if ( operatorID == EXPORT_E5RES )
-	export_e5res(cdoStreamName(1), vars, nvars);
+	export_e5res(cdoStreamName(1)->args, vars, nvars);
       else
 	cdoAbort("Operator not implemented!");
     }
diff --git a/src/Enlargegrid.c b/src/Enlargegrid.c
index 64db2cc..b8645d2 100644
--- a/src/Enlargegrid.c
+++ b/src/Enlargegrid.c
@@ -84,9 +84,9 @@ void gen_index(int gridID1, int gridID2, int *index)
       {
 	char units[CDI_MAX_NAME];
 	gridInqXunits(gridID1, units);
-	gridToDegree(units, "grid1 center lon", nlon1, xvals1);
+	grid_to_degree(units, nlon1, xvals1, "grid1 center lon");
 	gridInqYunits(gridID1, units);
-	gridToDegree(units, "grid1 center lat", nlat1, yvals1);
+	grid_to_degree(units, nlat1, yvals1, "grid1 center lat");
       }
 
       gridInqXvals(gridID2, xvals2);
@@ -96,9 +96,9 @@ void gen_index(int gridID1, int gridID2, int *index)
       {
 	char units[CDI_MAX_NAME];
 	gridInqXunits(gridID2, units);
-	gridToDegree(units, "grid2 center lon", nlon2, xvals2);
+	grid_to_degree(units, nlon2, xvals2, "grid2 center lon");
 	gridInqYunits(gridID2, units);
-	gridToDegree(units, "grid2 center lat", nlat2, yvals2);
+	grid_to_degree(units, nlat2, yvals2, "grid2 center lat");
       }
 
       for ( i2 = 0; i2 < nlat2; i2++ )
@@ -202,7 +202,7 @@ void *Enlargegrid(void *argument)
     if ( vlistGrid(vlistID1, 0) != vlistGrid(vlistID1, index) )
       ndiffgrids++;
 
-  if ( ndiffgrids > 0 ) cdoAbort("Too many different grids in %s!", cdoStreamName(0));
+  if ( ndiffgrids > 0 ) cdoAbort("Too many different grids in %s!", cdoStreamName(0)->args);
 
   gridID1 = vlistGrid(vlistID1, 0);
 
diff --git a/src/Ensstat.c b/src/Ensstat.c
index 8bac853..db3be43 100644
--- a/src/Ensstat.c
+++ b/src/Ensstat.c
@@ -28,9 +28,6 @@
       Ensstat    ensvar          Ensemble variance
       Ensstat    ensvar1         Ensemble variance
       Ensstat    enspctl         Ensemble percentiles
-
-      Ensstat    enscrps         Ensemble cumulative ranked probability score
-      Ensstat    ensbrs          Ensemble brier score
 */
 
 #if defined (_OPENMP)
@@ -86,8 +83,6 @@ void *Ensstat(void *argument)
   cdoOperatorAdd("ensvar",  func_var,  0, NULL);
   cdoOperatorAdd("ensvar1", func_var1, 0, NULL);
   cdoOperatorAdd("enspctl", func_pctl, 0, NULL);
-  cdoOperatorAdd("enscrps", func_crps, 0, NULL);
-  cdoOperatorAdd("ensbrs",  func_brs,  0, NULL);
 
   operatorID = cdoOperatorID();
   operfunc = cdoOperatorF1(operatorID);
@@ -106,7 +101,7 @@ void *Ensstat(void *argument)
   if ( cdoVerbose )
     cdoPrint("Ensemble over %d files.", nfiles);
 
-  ofilename = cdoStreamName(nfiles);
+  ofilename = cdoStreamName(nfiles)->args;
 
   if ( !cdoSilentMode && !cdoOverwriteMode )
     if ( fileExists(ofilename) )
@@ -145,7 +140,7 @@ void *Ensstat(void *argument)
   taxisID2 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
-  streamID2 = streamOpenWrite(ofilename, cdoFiletype());
+  streamID2 = streamOpenWrite(cdoStreamName(nfiles), cdoFiletype());
 
   streamDefVlist(streamID2, vlistID2);
 	  
@@ -167,10 +162,10 @@ void *Ensstat(void *argument)
 	  if ( nrecs != nrecs0 )
 	    {
 	      if ( nrecs == 0 )
-		cdoAbort("Inconsistent ensemble file, too few time steps in %s!", cdoStreamName(fileID));
+		cdoAbort("Inconsistent ensemble file, too few time steps in %s!", cdoStreamName(fileID)->args);
 	      else
 		cdoAbort("Inconsistent ensemble file, number of records at time step %d of %s and %s differ!",
-			 tsID+1, cdoStreamName(0), cdoStreamName(fileID));
+			 tsID+1, cdoStreamName(0)->args, cdoStreamName(fileID)->args);
 	    }
 	}
 
diff --git a/src/Ensstat3.c b/src/Ensstat3.c
index 33b1052..7480e54 100644
--- a/src/Ensstat3.c
+++ b/src/Ensstat3.c
@@ -114,7 +114,7 @@ void *Ensstat3(void *argument)
   if ( cdoVerbose )
     cdoPrint("Ensemble over %d files.", nfiles);
 
-  ofilename = cdoStreamName(nfiles);
+  ofilename = cdoStreamName(nfiles)->args;
 
   if ( !cdoSilentMode && !cdoOverwriteMode )
     if ( fileExists(ofilename) )
@@ -206,11 +206,12 @@ void *Ensstat3(void *argument)
     }
   } 
 
-  if ( operfunc != func_roc ) {
-    streamID2 = streamOpenWrite(ofilename, cdoFiletype());
+  if ( operfunc != func_roc )
+    {
+      streamID2 = streamOpenWrite(cdoStreamName(nfiles), cdoFiletype());
 
-    streamDefVlist(streamID2, vlistID2);
-  }
+      streamDefVlist(streamID2, vlistID2);
+    }
 
   gridsize = vlistGridsizeMax(vlistID1);
 
@@ -260,10 +261,10 @@ void *Ensstat3(void *argument)
 	  if ( nrecs != nrecs0 )
 	    {
 	      if ( nrecs == 0 )
-		cdoAbort("Inconsistent ensemble file, too few time steps in %s!", cdoStreamName(fileID));
+		cdoAbort("Inconsistent ensemble file, too few time steps in %s!", cdoStreamName(fileID)->args);
 	      else
 		cdoAbort("Inconsistent ensemble file, number of records at time step %d of %s and %s differ!",
-			   tsID+1, cdoStreamName(0), cdoStreamName(fileID));
+			   tsID+1, cdoStreamName(0)->args, cdoStreamName(fileID)->args);
 	    }
 	}
 
diff --git a/src/Ensval.c b/src/Ensval.c
index 0f0a87f..758e0e0 100644
--- a/src/Ensval.c
+++ b/src/Ensval.c
@@ -43,9 +43,9 @@ enum RESTYPE_CRPS { CRPS_RES,CRPS_RELI,CRPS_POT };
 void *Ensval(void *argument)
 {
   int operatorID;
-  int operfunc, datafunc;
+  int operfunc;
   int i,k;
-  int nvars,nrecs = 0, nrecs0, nmiss, nens, nfiles,nlevs,valcount, nostreams = 0, ngrids;
+  int nvars,nrecs = 0, nrecs0, nmiss, nens, nfiles, nostreams = 0, ngrids;
   int levelID, varID, recID, tsID;
   int gridsize = 0;
   int gridID = -1, gridID2;
@@ -54,9 +54,8 @@ void *Ensval(void *argument)
   int vlistID, vlistID1, *vlistID2;
   int taxisID1, *taxisID2;
   int zaxisID1, *zaxisID2;
-  int *varID2;
-  int xsize,ysize;
-  double missval;
+  //int xsize,ysize;
+  double missval = 0;
   double *alpha, *beta, *alpha_weights, *beta_weights;
   double *brs_g, *brs_o, *brs_g_weights, *brs_o_weights;
   double *r;                      // Pointer to hold results for single time step
@@ -86,7 +85,6 @@ void *Ensval(void *argument)
 
   // INITIALIZE POINTERS
   streamID2 = NULL;
-  varID2 = NULL;
   alpha = NULL; beta = NULL; alpha_weights = NULL; beta_weights = NULL; 
   brs_g = NULL; brs_o = NULL; brs_g_weights = NULL; brs_o_weights = NULL;
   r = NULL;
@@ -102,7 +100,6 @@ void *Ensval(void *argument)
   
   operatorID = cdoOperatorID();
   operfunc = cdoOperatorF1(operatorID);
-  datafunc = cdoOperatorF2(operatorID);
 
   nfiles = cdoStreamCnt() - 1;
   nens = nfiles-1;
@@ -171,7 +168,6 @@ void *Ensval(void *argument)
   vlistID1 = ef[0].vlistID;
   taxisID1 = vlistInqTaxis(vlistID1);
   zaxisID1 = vlistInqVarZaxis(vlistID1,0);
-  nlevs    = zaxisInqSize(zaxisID1);
 
   gridID2 = gridCreate(GRID_LONLAT, 1);
   gridDefXsize(gridID2, 1);
@@ -179,7 +175,7 @@ void *Ensval(void *argument)
   gridDefXvals(gridID2, &xval);
   gridDefYvals(gridID2, &yval);
 
-  ofilebase = cdoStreamName(nfiles);
+  ofilebase = cdoStreamName(nfiles)->args;
 
   memset(file_suffix, 0, sizeof(file_suffix) );
   cdoGenFileSuffix(&file_suffix[0], sizeof(file_suffix), 
@@ -190,33 +186,34 @@ void *Ensval(void *argument)
       + 9  /*type_suffix*/ 
       + 32 /*file_suffix*/
       + 3  /*separating dots and EOS*/;
-    int ntype = 0;
 
     switch ( operfunc ) {
     case CRPS: switch ( stream ) {
-      case 0: ntype=4; sprintf(type_suffix,"crps");      break;
-      case 1: ntype=9; sprintf(type_suffix,"crps_reli"); break;
-      case 2: ntype=8; sprintf(type_suffix,"crps_pot");  break; } 
+      case 0: sprintf(type_suffix,"crps");      break;
+      case 1: sprintf(type_suffix,"crps_reli"); break;
+      case 2: sprintf(type_suffix,"crps_pot");  break; } 
       break;
     case BRS: switch ( stream ) {
-      case 0: ntype=3; sprintf(type_suffix,"brs");       break;
-      case 1: ntype=8; sprintf(type_suffix,"brs_reli");  break;
-      case 2: ntype=8; sprintf(type_suffix,"brs_reso");  break;
-      case 3: ntype=8; sprintf(type_suffix,"brs_unct");  break; }
+      case 0: sprintf(type_suffix,"brs");       break;
+      case 1: sprintf(type_suffix,"brs_reli");  break;
+      case 2: sprintf(type_suffix,"brs_reso");  break;
+      case 3: sprintf(type_suffix,"brs_unct");  break; }
       break;
     }
 
-    ofilename = (char *) calloc ( namelen, sizeof(char) );
+    ofilename = (char *) calloc(namelen, sizeof(char));
 
-    sprintf(ofilename,"%s.%s%s",ofilebase,type_suffix,file_suffix);
-    fprintf(stderr,"StreamID %i: %s\n",stream,ofilename);
+    sprintf(ofilename, "%s.%s%s", ofilebase, type_suffix, file_suffix);
+    // fprintf(stderr, "StreamID %i: %s\n", stream, ofilename);
 
     if ( !cdoSilentMode && !cdoOverwriteMode )
       if ( fileExists(ofilename) )
 	if ( !userFileOverwrite(ofilename) )
 	    cdoAbort("Outputfile %s already exists!", ofilename);
 
-    streamID2[stream] = streamOpenWrite(ofilename, cdoFiletype());    
+    argument_t *fileargument = file_argument_new(ofilename);
+    streamID2[stream] = streamOpenWrite(fileargument, cdoFiletype());    
+    file_argument_free(fileargument);
 
     free(ofilename);
 
@@ -225,17 +222,17 @@ void *Ensval(void *argument)
     vlistID2[stream] = vlistDuplicate(vlistID1);
 
     ngrids = vlistNgrids(vlistID2[stream]);
-    fprintf(stderr,"ngrids %i\n",ngrids);
+    //fprintf(stderr,"ngrids %i\n",ngrids);
     for ( i=0; i<ngrids; i++ )
       vlistChangeGridIndex(vlistID2[stream], i, gridID2);
 
     vlistDefTaxis(vlistID2[stream], taxisID2[stream]);
     streamDefVlist(streamID2[stream], vlistID2[stream]);
 
-    vlistCheck = streamInqVlist(streamID2[stream]);
-    gridsizeCheck = vlistGridsizeMax(vlistCheck);
+    // vlistCheck = streamInqVlist(streamID2[stream]);
+    // gridsizeCheck = vlistGridsizeMax(vlistCheck);
 
-    fprintf(stderr,"stream %i vlist %3i gridsize %4i\n",stream,vlistCheck,gridsizeCheck);
+    //fprintf(stderr,"stream %i vlist %3i gridsize %4i\n",stream,vlistCheck,gridsizeCheck);
   }
 
   if ( cdoVerbose ) 
@@ -250,7 +247,7 @@ void *Ensval(void *argument)
 	  streamID = ef[fileID].streamID;
 	  nrecs = streamInqTimestep(streamID, tsID);
 	  if ( nrecs != nrecs0 )
-	    cdoAbort("Number of records at time step %d of %s and %s differ!", tsID+1, cdoStreamName(0), cdoStreamName(fileID));
+	    cdoAbort("Number of records at time step %d of %s and %s differ!", tsID+1, cdoStreamName(0)->args, cdoStreamName(fileID)->args);
 	}
       
       for ( stream = 0; stream < nostreams; stream++ ) {
@@ -281,8 +278,8 @@ void *Ensval(void *argument)
 	      streamReadRecord(streamID, ef[fileID].array, &nmiss);
 	    }
 
-	  xsize = gridInqXsize(gridID);
-	  ysize = gridInqYsize(gridID);
+	  // xsize = gridInqXsize(gridID);
+	  // ysize = gridInqYsize(gridID);
 	  
 	  /*	  if ( xsize > 1 && ysize > 1 )  {
 	    gridWeights(gridID, weights);
@@ -297,7 +294,6 @@ void *Ensval(void *argument)
 	  }
 	  
 	  nmiss = 0;
-	  valcount = 0;
 	  heavyside0 = 0;
 	  heavysideN = 0;
 	  
@@ -344,7 +340,7 @@ void *Ensval(void *argument)
 		}
 	      else if ( operfunc == BRS ) 
 		{
-		  int occ = xa > brs_thresh? 1 : 0;
+		  //  int occ = xa > brs_thresh? 1 : 0;
 
 		  // brs_g[i] - number of enemble members with rank i that forecast event
 		  //          - event: value > brs_thresh
@@ -412,7 +408,7 @@ void *Ensval(void *argument)
 	    // Last Bin
 	    p=1.; g=0.;
 	    o = 1. - heavysideN/gridsize; 
-	    if ( IS_EQUAL(o,1.) ) {
+	    if ( IS_NOT_EQUAL(o,1.) ) {
 	      g = alpha[nens] / (1-o);
 	      
 	      crps_reli    += g * (o-p) * (o-p);
diff --git a/src/Eofcoeff.c b/src/Eofcoeff.c
index 5044909..0b64846 100644
--- a/src/Eofcoeff.c
+++ b/src/Eofcoeff.c
@@ -90,10 +90,10 @@ void *Eofcoeff(void * argument)
   
   if (vlistGridsizeMax(vlistID2)   != gridsize ||
       vlistInqVarGrid(vlistID2, 0) != gridID1 )
-    cdoAbort("EOFs (%s) and data (%s) defined on different grids", cdoStreamName(0), cdoStreamName(1));    
+    cdoAbort("EOFs (%s) and data (%s) defined on different grids", cdoStreamName(0)->args, cdoStreamName(1)->args);    
  
   
-  strcpy(oname, cdoStreamName(2));
+  strcpy(oname, cdoStreamName(2)->args);
   nchars = strlen(oname);
   
   filesuffix[0] = 0;
@@ -137,7 +137,7 @@ void *Eofcoeff(void * argument)
    }
   neof = eofID;  
   
-  if ( cdoVerbose ) cdoPrint("%s contains %i eof's", cdoStreamName(0), neof);
+  if ( cdoVerbose ) cdoPrint("%s contains %i eof's", cdoStreamName(0)->args, neof);
   // Create 1x1 Grid for output
   gridID3 = gridCreate(GRID_LONLAT, 1);
   gridDefXsize(gridID3, 1);
@@ -172,7 +172,10 @@ void *Eofcoeff(void * argument)
       if ( filesuffix[0] )
         strcat(oname, filesuffix);
       
-      streamIDs[eofID] = streamOpenWrite(oname, cdoFiletype());
+      argument_t *fileargument = file_argument_new(oname);
+      streamIDs[eofID] = streamOpenWrite(fileargument, cdoFiletype());
+      file_argument_free(fileargument);
+
       if (cdoVerbose) 
         cdoPrint("opened %s ('w')  as stream%i for %i. eof", oname, streamIDs[eofID], eofID+1);
       
diff --git a/src/Eofcoeff3d.c b/src/Eofcoeff3d.c
index 6944c33..54f970c 100644
--- a/src/Eofcoeff3d.c
+++ b/src/Eofcoeff3d.c
@@ -89,9 +89,9 @@ void *Eofcoeff3d(void * argument)
   
   if (vlistGridsizeMax(vlistID2)   != gridsize ||
       vlistInqVarGrid(vlistID2, 0) != gridID1 )
-    cdoAbort("EOFs (%s) and data (%s) defined on different grids", cdoStreamName(0), cdoStreamName(1));    
+    cdoAbort("EOFs (%s) and data (%s) defined on different grids", cdoStreamName(0)->args, cdoStreamName(1)->args);    
  
-  strcpy(oname, cdoStreamName(2));
+  strcpy(oname, cdoStreamName(2)->args);
   nchars = strlen(oname);
   
   filesuffix[0] = 0;
@@ -136,7 +136,7 @@ void *Eofcoeff3d(void * argument)
    }
   neof = eofID;  
   
-  if ( cdoVerbose ) cdoPrint("%s contains %i eof's", cdoStreamName(0), neof);
+  if ( cdoVerbose ) cdoPrint("%s contains %i eof's", cdoStreamName(0)->args, neof);
   // Create 1x1 Grid for output
   gridID3 = gridCreate(GRID_LONLAT, 1);
   gridDefXsize(gridID3, 1);
@@ -173,7 +173,10 @@ void *Eofcoeff3d(void * argument)
       if ( filesuffix[0] )
         strcat(oname, filesuffix);
       
-      streamIDs[eofID] = streamOpenWrite(oname, cdoFiletype());
+      argument_t *fileargument = file_argument_new(oname);
+      streamIDs[eofID] = streamOpenWrite(fileargument, cdoFiletype());
+      file_argument_free(fileargument);
+
       if (cdoVerbose) 
         cdoPrint("opened %s ('w')  as stream%i for %i. eof", oname, streamIDs[eofID], eofID+1);
       
diff --git a/src/Exprf.c b/src/Exprf.c
index 36105b5..32c228e 100644
--- a/src/Exprf.c
+++ b/src/Exprf.c
@@ -152,9 +152,10 @@ void *Expr(void *argument)
 
   if ( cdoVerbose ) vlistPrint(vlistID2);
 
-  for ( varID = 0; varID < nvars; varID++ )
-    if ( parse_arg.var_needed[varID] && cdoVerbose )
-      printf("var_needed: %d %s\n", varID, parse_arg.var[varID]);
+  if ( cdoVerbose )
+    for ( varID = 0; varID < nvars; varID++ )
+      if ( parse_arg.var_needed[varID] )
+	printf("Needed var: %d %s\n", varID, parse_arg.var[varID]);
 
   taxisID1 = vlistInqTaxis(vlistID1);
   taxisID2 = taxisDuplicate(taxisID1);
diff --git a/src/Fillmiss.c b/src/Fillmiss.c
index 2f9ba5a..2e032b2 100644
--- a/src/Fillmiss.c
+++ b/src/Fillmiss.c
@@ -24,7 +24,6 @@
 #include "cdo.h"
 #include "cdo_int.h"
 #include "pstream.h"
-#include "interpol.h"
 
 
 void fillmiss(field_t *field1, field_t *field2, int nfill)
diff --git a/src/Filter.c b/src/Filter.c
index 4ac3c87..5e43839 100644
--- a/src/Filter.c
+++ b/src/Filter.c
@@ -23,7 +23,11 @@
       Filter    bandpass
 */
 
-#if defined ( _USE_FFTW3 ) 
+#if  defined  (HAVE_CONFIG_H)
+#  include "config.h"
+#endif
+
+#if defined ( HAVE_LIBFFTW3 ) 
 #include <fftw3.h>
 #endif
 
@@ -133,10 +137,10 @@ void create_fmasc(int nts, double fdata, double fmin, double fmax, int *fmasc)
 }
 
 
-#if defined ( _USE_FFTW3 ) 
+#if defined ( HAVE_LIBFFTW3 ) 
 static
 void filter_fftw(int nts, const int *fmasc, 
-	    fftw_complex *fft_in, fftw_complex *fft_out, fftw_plan *p_T2S, fftw_plan *p_S2T)
+                 fftw_complex *fft_in, fftw_complex *fft_out, fftw_plan *p_T2S, fftw_plan *p_S2T)
 {  
   //  fprintf(stderr,"using fftw filter\n");
 
@@ -195,12 +199,12 @@ void *Filter(void *argument)
   int incperiod0, incunit0, incunit, dpy, calendar;
   int year0, month0, day0;
   double missval;
-  double *array1, *array2;
+  double *array1 = NULL, *array2 = NULL;
   double fdata = 0;
   field_t ***vars = NULL;
   double fmin = 0, fmax = 0;
   int *fmasc;
-#if defined ( _USE_FFTW3 ) 
+#if defined ( HAVE_LIBFFTW3 ) 
   fftw_plan p_T2S, p_S2T;
   fftw_complex *out_fft;
   fftw_complex *in_fft;
@@ -322,7 +326,7 @@ void *Filter(void *argument)
   nts = tsID;
   /*  round up nts to next power of two for (better) performance 
    ** of fast fourier transformation */
-#if defined ( _USE_FFTW3 ) 
+#if defined ( HAVE_LIBFFTW3 ) 
   nts2 = nts;
 
   out_fft = (fftw_complex *) malloc ( nts * sizeof(fftw_complex) );
@@ -383,13 +387,13 @@ void *Filter(void *argument)
       gridsize = gridInqSize(gridID);
       nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
 
-#if defined ( _USE_FFTW3 ) 
+#if defined ( HAVE_LIBFFTW3 ) 
       fprintf(stderr," using fftw lib\n");
 #endif
       
       for ( levelID = 0; levelID < nlevel; levelID++ )
         { 
-#if defined ( _USE_FFTW3 ) 
+#if defined ( HAVE_LIBFFTW3 ) 
           for ( i = 0; i < gridsize-1; i++ )
             {
               for ( tsID = 0; tsID < nts; tsID++ )                              
diff --git a/src/Fldstat2.c b/src/Fldstat2.c
index 9af8566..b0a3bcf 100644
--- a/src/Fldstat2.c
+++ b/src/Fldstat2.c
@@ -32,19 +32,18 @@
 /* correclation in space */
 static
 double correlation_s(const double * restrict in0, const double * restrict in1,
-		     const double * restrict weight, double missval, long gridsize)
+		     const double * restrict weight, double missval1, double missval2, long gridsize)
 {
   long i;
   double sum0, sum1, sum00, sum01, sum11, wsum0;
   double out;
-  double missval1 = missval, missval2 = missval;
 
   sum0 = sum1 = sum00 = sum01 = sum11 = 0;
   wsum0 = 0;
 	
   for ( i = 0; i < gridsize; ++i )
     {
-      if ( weight[i] != missval && in0[i] != missval && in1[i] != missval)
+      if ( IS_NOT_EQUAL(weight[i], missval1) && IS_NOT_EQUAL(in0[i], missval1) && IS_NOT_EQUAL(in1[i], missval2) )
 	    {
 	      sum0  += weight[i] * in0[i];
 	      sum1  += weight[i] * in1[i];
@@ -55,10 +54,10 @@ double correlation_s(const double * restrict in0, const double * restrict in1,
 	    }
     }
 
-  out = wsum0 ?
+  out = IS_NOT_EQUAL(wsum0, 0) ?
         DIV((sum01 * wsum0 - sum0 * sum1),
 	     SQRT((sum00 * wsum0 - sum0 * sum0) *
-	          (sum11 * wsum0 - sum1 * sum1))) : missval;
+	          (sum11 * wsum0 - sum1 * sum1))) : missval1;
 
   return (out);
 }
@@ -66,7 +65,7 @@ double correlation_s(const double * restrict in0, const double * restrict in1,
 /* covariance in space */
 static
 double covariance_s(const double * restrict in0, const double * restrict in1,
-		    const double * restrict weight, double missval, long gridsize)
+		    const double * restrict weight, double missval1, double missval2, long gridsize)
 {
   long i;
   double sum0, sum1, sum01, wsum0, wsum00;
@@ -77,7 +76,7 @@ double covariance_s(const double * restrict in0, const double * restrict in1,
 
   for ( i = 0; i < gridsize; ++i )
     {
-      if ( weight[i] != missval && in0[i] != missval && in1[i] != missval )
+      if ( IS_NOT_EQUAL(weight[i], missval1) && IS_NOT_EQUAL(in0[i], missval1) && IS_NOT_EQUAL(in1[i], missval2) )
 	{
 	  sum0   += weight[i] * in0[i];
 	  sum1   += weight[i] * in1[i];
@@ -87,8 +86,8 @@ double covariance_s(const double * restrict in0, const double * restrict in1,
 	}
     }
 
-  out = wsum0 ?
-        (sum01 * wsum0 - sum0 * sum1) / (wsum0 * wsum0) : missval;
+  out = IS_NOT_EQUAL(wsum0, 0) ?
+        (sum01 * wsum0 - sum0 * sum1) / (wsum0 * wsum0) : missval1;
 
   return (out);
 }
@@ -110,11 +109,11 @@ void *Fldstat2(void *argument)
   long gridsize;
   int needWeights = TRUE;
   int nmiss1, nmiss2, nmiss3;
-  double missval;
+  double missval1, missval2;
   double slon, slat;
   double sglval;
   double *array1, *array2, *weight;
-  int taxisID1, taxisID2, taxisID3;
+  int taxisID1, taxisID3;
 
   cdoInitialize(argument);
 
@@ -134,7 +133,6 @@ void *Fldstat2(void *argument)
   vlistCompare(vlistID1, vlistID2, CMP_ALL);
 
   taxisID1 = vlistInqTaxis(vlistID1);
-  taxisID2 = vlistInqTaxis(vlistID2);
   taxisID3 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID3, taxisID3);
 
@@ -168,6 +166,12 @@ void *Fldstat2(void *argument)
     {
       nrecs2 = streamInqTimestep(streamID2, tsID);
 
+      if ( nrecs2 == 0 )
+	{
+	  cdoWarning("Input streams have different number of time steps!");
+	  break;
+	}
+
       taxisCopyTimestep(taxisID3, taxisID1);
 
       streamDefTimestep(streamID3, tsID);
@@ -190,18 +194,19 @@ void *Fldstat2(void *argument)
 	  if ( wstatus != 0 && tsID == 0 && code != oldcode )
 	    cdoWarning("Using constant grid cell area weights for code %d!", oldcode=code);
 
-	  missval = vlistInqVarMissval(vlistID1, varID);
+	  missval1 = vlistInqVarMissval(vlistID1, varID);
+	  missval2 = vlistInqVarMissval(vlistID2, varID);
 
 	  if ( operfunc == func_cor )
 	    {
-	      sglval = correlation_s(array1, array2, weight, missval, gridsize);
+	      sglval = correlation_s(array1, array2, weight, missval1, missval2, gridsize);
 	    }
 	  else if ( operfunc == func_covar )
 	    {
-	      sglval = covariance_s(array1, array2, weight, missval, gridsize);
+	      sglval = covariance_s(array1, array2, weight, missval1, missval2, gridsize);
 	    }
 
-	  if ( DBL_IS_EQUAL(sglval, missval) )
+	  if ( DBL_IS_EQUAL(sglval, missval1) )
 	    nmiss3 = 1;
 	  else
 	    nmiss3 = 0;
diff --git a/src/Gather.c b/src/Gather.c
index b372ad0..2b68618 100644
--- a/src/Gather.c
+++ b/src/Gather.c
@@ -132,7 +132,7 @@ int genGrid(int nfiles, ens_file_t *ef, int **gridindex, int igrid)
       xyinfo[fileID].y  = yvals[fileID][0];
       xyinfo[fileID].id = fileID;
 
-      if ( fileID == 0 && ysize[fileID] > 1 )
+      if ( ysize[fileID] > 1 )
 	{
 	  if ( yvals[fileID][0] > yvals[fileID][ysize[fileID]-1] ) lsouthnorth = FALSE;
 	}
@@ -290,7 +290,7 @@ void *Gather(void *argument)
     
   nfiles = cdoStreamCnt() - 1;
 
-  ofilename = cdoStreamName(nfiles);
+  ofilename = cdoStreamName(nfiles)->args;
 
   if ( !cdoSilentMode && !cdoOverwriteMode )
     if ( fileExists(ofilename) )
@@ -383,8 +383,8 @@ void *Gather(void *argument)
 	}
     }
 
-  streamID2 = streamOpenWrite(ofilename, cdoFiletype());
-
+  streamID2 = streamOpenWrite(cdoStreamName(nfiles), cdoFiletype());
+      
   streamDefVlist(streamID2, vlistID2);
 	  
   array2 = (double *) malloc(gridsize2*sizeof(double));
@@ -398,7 +398,7 @@ void *Gather(void *argument)
 	  streamID = ef[fileID].streamID;
 	  nrecs = streamInqTimestep(streamID, tsID);
 	  if ( nrecs != nrecs0 )
-	    cdoAbort("Number of records at time step %d of %s and %s differ!", tsID+1, cdoStreamName(0), cdoStreamName(fileID));
+	    cdoAbort("Number of records at time step %d of %s and %s differ!", tsID+1, cdoStreamName(0)->args, cdoStreamName(fileID)->args);
 	}
 
       taxisCopyTimestep(taxisID2, taxisID1);
diff --git a/src/Gradsdes.c b/src/Gradsdes.c
index 3a43eba..cf63889 100644
--- a/src/Gradsdes.c
+++ b/src/Gradsdes.c
@@ -235,8 +235,8 @@ void dumpmap()
   indx.intpnt = NULL;
   indx.fltpnt = NULL;
 
-  mapfp = fopen(cdoStreamName(0), "r");
-  if ( mapfp == NULL ) cdoAbort("Open failed on %s", cdoStreamName(0));
+  mapfp = fopen(cdoStreamName(0)->args, "r");
+  if ( mapfp == NULL ) cdoAbort("Open failed on %s", cdoStreamName(0)->args);
 
   /* check the version number */
 
@@ -694,6 +694,41 @@ void ctl_vars(FILE *gdp, int filetype, int vlistID, int nvarsout, int *vars)
 	      */
 	      fprintf(gdp, "  %d,%d", code, ltype);
 	    }
+	  else if ( filetype == FILETYPE_NC )
+	    {
+	      int xyz = vlistInqVarXYZ(vlistID, varID);
+
+	      fprintf(gdp, "  ");
+	      if ( vlistInqVarTsteptype(vlistID, varID) != TSTEP_CONSTANT )
+		fprintf(gdp, "t,");
+	      if ( xyz == 321 )
+		{
+		  if ( nlev > 0 ) fprintf(gdp, "z,");
+		  fprintf(gdp, "y,x");
+		}
+	      else if ( xyz == 312 )
+		{
+		  if ( nlev > 0 ) fprintf(gdp, "z,");
+		  fprintf(gdp, "x,y");
+		}
+	      else if ( xyz == 231 )
+		{
+		  fprintf(gdp, "y,");
+		  if ( nlev > 0 ) fprintf(gdp, "z,");
+		  fprintf(gdp, "x");
+		}
+	      else if ( xyz == 132 )
+		{
+		  fprintf(gdp, "x,");
+		  if ( nlev > 0 ) fprintf(gdp, "z,");
+		  fprintf(gdp, "y");
+		}
+	      else
+		{
+		  if ( nlev > 0 ) fprintf(gdp, "z,");
+		  fprintf(gdp, "y,x");
+		}
+	    }
 	  else
 	    fprintf(gdp, "  99");
 
@@ -823,7 +858,7 @@ void write_map_grib1(const char *ctlfile, int map_version, int nrecords, int *in
 
 void *Gradsdes(void *argument)
 {
-  int GRADSDES1, GRADSDES2, DUMPMAP;
+  int GRADSDES2, DUMPMAP;
   int operatorID;
   int streamID = 0;
   int gridID = -1;
@@ -874,7 +909,7 @@ void *Gradsdes(void *argument)
       
   cdoInitialize(argument);
 
-  GRADSDES1 = cdoOperatorAdd("gradsdes1", 0, 0, NULL);
+              cdoOperatorAdd("gradsdes1", 0, 0, NULL);
   GRADSDES2 = cdoOperatorAdd("gradsdes2", 0, 0, NULL);
   DUMPMAP   = cdoOperatorAdd("dumpmap",   0, 0, NULL);
 
@@ -882,7 +917,7 @@ void *Gradsdes(void *argument)
 
   if ( operatorID == GRADSDES2 ) map_version = 2;
 
-  if ( cdoStreamName(0)[0] == '-' )
+  if ( cdoStreamName(0)->args[0] == '-' )
     cdoAbort("This operator does not work with pipes!");
 
   if ( operatorID == DUMPMAP )
@@ -903,13 +938,16 @@ void *Gradsdes(void *argument)
   filetype  = streamInqFiletype(streamID);
   byteorder = streamInqByteorder(streamID);
 
+  if ( filetype == FILETYPE_NC2 || filetype == FILETYPE_NC4 ) filetype = FILETYPE_NC;
+
   if ( filetype != FILETYPE_SRV &&
        filetype != FILETYPE_EXT &&
        filetype != FILETYPE_IEG &&
        filetype != FILETYPE_GRB )
     {
-      if ( filetype == FILETYPE_NC || filetype == FILETYPE_NC2 || filetype == FILETYPE_NC4 )
-	cdoAbort("Unsupported file format: netCDF");
+      if ( filetype == FILETYPE_NC )
+	//	cdoAbort("Unsupported file format: netCDF");
+	;
       else if ( filetype == FILETYPE_GRB2 )
 	cdoAbort("Unsupported file format: GRIB2");
       else
@@ -993,7 +1031,7 @@ void *Gradsdes(void *argument)
       if ( byteorder == CDI_LITTLEENDIAN ) littleendian = TRUE;
     }
 
-  strcpy(ctlfile, cdoStreamName(0));
+  strcpy(ctlfile, cdoStreamName(0)->args);
   len = (int) strlen(ctlfile);
   if ( len > 4 )
     {
@@ -1005,6 +1043,8 @@ void *Gradsdes(void *argument)
 	if ( strcmp(&ctlfile[len-4], ".ieg") == 0 ) ctlfile[len-4] = 0;
       if ( filetype == FILETYPE_GRB )
 	if ( strcmp(&ctlfile[len-4], ".grb") == 0 ) ctlfile[len-4] = 0;
+      if ( filetype == FILETYPE_NC )
+	if ( strcmp(&ctlfile[len-3], ".nc") == 0 ) ctlfile[len-3] = 0;
     }
 
   strcat(ctlfile, ".ctl");
@@ -1018,13 +1058,13 @@ void *Gradsdes(void *argument)
 
   /* DSET */
 
-  datfile = cdoStreamName(0);
+  datfile = cdoStreamName(0)->args;
   if ( datfile[0] == '/' )
     fprintf(gdp, "DSET  %s\n", datfile);
   else
     {
       datfile = strrchr(datfile, '/');
-      if ( datfile == 0 ) datfile = cdoStreamName(0);
+      if ( datfile == 0 ) datfile = cdoStreamName(0)->args;
       else                datfile++;	  
       fprintf(gdp, "DSET  ^%s\n", datfile);
     }
@@ -1051,6 +1091,10 @@ void *Gradsdes(void *argument)
       gridsize = vlistGridsizeMax(vlistID);
       array = (double *) malloc(gridsize*sizeof(double));
     }
+  else if ( filetype == FILETYPE_NC )
+    {
+      fprintf(gdp, "DTYPE  netCDF\n");
+    }
 
   /* XYHEADER */
   if ( xyheader ) fprintf(gdp, "XYHEADER  %d\n", xyheader);
diff --git a/src/Gridboxstat.c b/src/Gridboxstat.c
index 3c8e55c..9777fdb 100644
--- a/src/Gridboxstat.c
+++ b/src/Gridboxstat.c
@@ -188,9 +188,9 @@ int genBoxGrid(int gridID1, int xinc, int yinc)
       {
 	char units[CDI_MAX_NAME];
 	gridInqXunits(gridID1, units);
-	gridToDegree(units, "grid center lon", nlon1*nlat1, xvals1);
+	grid_to_degree(units, nlon1*nlat1, xvals1, "grid center lon");
 	gridInqYunits(gridID1, units);
-	gridToDegree(units, "grid center lat", nlon1*nlat1, yvals1);
+	grid_to_degree(units, nlon1*nlat1, yvals1, "grid center lat");
       }
       
       if ( gridHasBounds )
@@ -206,9 +206,9 @@ int genBoxGrid(int gridID1, int xinc, int yinc)
 	  {
 	    char units[CDI_MAX_NAME];
 	    gridInqXunits(gridID1, units);
-	    gridToDegree(units, "grid corner lon", 4*nlon1*nlat1, grid1_corner_lon);
+	    grid_to_degree(units, 4*nlon1*nlat1, grid1_corner_lon, "grid corner lon");
 	    gridInqYunits(gridID1, units);
-	    gridToDegree(units, "grid corner lat", 4*nlon1*nlat1, grid1_corner_lat);
+	    grid_to_degree(units, 4*nlon1*nlat1, grid1_corner_lat, "grid corner lat");
 	  }
         }
       
diff --git a/src/Harmonic.c b/src/Harmonic.c
index f879490..c0b3d66 100644
--- a/src/Harmonic.c
+++ b/src/Harmonic.c
@@ -80,7 +80,7 @@ void *Harmonic(void *argument)
 
   streamIDs = (int*) malloc(n_out*sizeof(int));
 
-  strcpy(filename, cdoStreamName(1));
+  strcpy(filename, cdoStreamName(1)->args);
   nchars = strlen(filename);
 
   for ( j = 0; j < n_out; ++j )
@@ -89,7 +89,9 @@ void *Harmonic(void *argument)
       if ( filesuffix[0] )
 	sprintf(filename+nchars+1, "%s", filesuffix);
 
-      streamID2 = streamOpenWrite(filename, cdoFiletype());
+      argument_t *fileargument = file_argument_new(filename);
+      streamID2 = streamOpenWrite(fileargument, cdoFiletype());
+      file_argument_free(fileargument);
 
       streamIDs[j] = streamID2;
 
diff --git a/src/Importamsr.c b/src/Importamsr.c
index 89c8f40..e428a39 100644
--- a/src/Importamsr.c
+++ b/src/Importamsr.c
@@ -193,14 +193,14 @@ void *Importamsr(void *argument)
 
   cdoInitialize(argument);
 
-  fp = fopen(cdoStreamName(0), "r");
-  if ( fp == NULL ) { perror(cdoStreamName(0)); exit(EXIT_FAILURE); }
+  fp = fopen(cdoStreamName(0)->args, "r");
+  if ( fp == NULL ) { perror(cdoStreamName(0)->args); exit(EXIT_FAILURE); }
 
   fseek(fp, 0L, SEEK_END);
   fsize = (size_t) ftell(fp);
   fseek(fp, 0L, SEEK_SET);
 
-  vdate = getDate(cdoStreamName(0));
+  vdate = getDate(cdoStreamName(0)->args);
   if ( vdate <= 999999 ) vdate = vdate*100 + 1;
 
   streamID = streamOpenWrite(cdoStreamName(1), cdoFiletype());
diff --git a/src/Importbinary.c b/src/Importbinary.c
index f6bf1c8..98636b0 100644
--- a/src/Importbinary.c
+++ b/src/Importbinary.c
@@ -229,7 +229,7 @@ void *Importbinary(void *argument)
 
   dsets_init(&pfi);
 
-  status = read_gradsdes((char *)cdoStreamName(0), &pfi);
+  status = read_gradsdes(cdoStreamName(0)->args, &pfi);
   if ( cdoVerbose ) fprintf(stderr, "status %d\n", status);
   //if ( status ) cdoAbort("Open failed on %s!", pfi.name);
   if ( status ) cdoAbort("Open failed!");
diff --git a/src/Importcmsaf.c b/src/Importcmsaf.c
index ab2b734..79c086d 100644
--- a/src/Importcmsaf.c
+++ b/src/Importcmsaf.c
@@ -1433,8 +1433,8 @@ void *Importcmsaf(void *argument)
   dsets_init(&dsets);
 
   /* Open an existing file. */
-  file_id = H5Fopen(cdoStreamName(0), H5F_ACC_RDONLY, H5P_DEFAULT);
-  if ( file_id < 0 ) cdoAbort("H5Fopen failed on %s", cdoStreamName(0));
+  file_id = H5Fopen(cdoStreamName(0)->args, H5F_ACC_RDONLY, H5P_DEFAULT);
+  if ( file_id < 0 ) cdoAbort("H5Fopen failed on %s", cdoStreamName(0)->args);
 
   /* cmsaf_type = get_cmsaf_type(file_id); */
 
diff --git a/src/Importobs.c b/src/Importobs.c
index 13a3012..8eca2f9 100644
--- a/src/Importobs.c
+++ b/src/Importobs.c
@@ -157,15 +157,15 @@ void *Importobs(void *argument)
   {
     char units[CDI_MAX_NAME];
     gridInqXunits(gridID, units);
-    gridToDegree(units, "grid center lon", gridsize, xvals);
+    grid_to_degree(units, gridsize, xvals, "grid center lon");
     gridInqYunits(gridID, units);
-    gridToDegree(units, "grid center lat", gridsize, yvals);
+    grid_to_degree(units, gridsize, yvals, "grid center lat");
   }
 
-  fp = fopen(cdoStreamName(0), "r");
-  if ( fp == NULL ) { perror(cdoStreamName(0)); exit(EXIT_FAILURE); }
+  fp = fopen(cdoStreamName(0)->args, "r");
+  if ( fp == NULL ) { perror(cdoStreamName(0)->args); exit(EXIT_FAILURE); }
 
-  vdate = getDate(cdoStreamName(0));
+  vdate = getDate(cdoStreamName(0)->args);
   if ( vdate <= 999999 ) vdate = vdate*100 + 1;
 
   streamID = streamOpenWrite(cdoStreamName(1), cdoFiletype());
diff --git a/src/Info.c b/src/Info.c
index 3bb7a45..e93f865 100644
--- a/src/Info.c
+++ b/src/Info.c
@@ -283,15 +283,15 @@ void *Info(void *argument)
 	    {
 	      if ( (tsID == 0 && recID == 0) || operatorID == MAP )
 		{
-		  if ( operatorID == INFON )
-		    fprintf(stdout, "%6d :       Date     Time   Level Gridsize    Miss :"
-			    "     Minimum        Mean     Maximum : Parameter name\n",  -(indf+1));
-		  else if ( operatorID == INFOC )
-		    fprintf(stdout, "%6d :       Date     Time   Level Gridsize    Miss :"
-			    "     Minimum        Mean     Maximum : Code number\n",  -(indf+1));
-		  else
-		    fprintf(stdout, "%6d :       Date     Time   Level Gridsize    Miss :"
-			    "     Minimum        Mean     Maximum : Parameter ID\n",  -(indf+1));
+		  fprintf(stdout, "%6d :       Date     Time   Level Gridsize    Miss :"
+			  "     Minimum        Mean     Maximum : ",  -(indf+1));
+
+		  if      ( operatorID == INFON ) fprintf(stdout, "Parameter name");
+		  else if ( operatorID == INFOC ) fprintf(stdout, "Code number");
+		  else                            fprintf(stdout, "Parameter ID");
+
+		  if ( cdoVerbose ) fprintf(stdout, " : Extra" );              
+		  fprintf(stdout, "\n" );              
 		}
 
 	      streamInqRecord(streamID, &varID, &levelID);
@@ -408,11 +408,18 @@ void *Info(void *argument)
 		}
 
 	      if ( operatorID == INFON )
-		fprintf(stdout, " : %-11s", varname);
+		fprintf(stdout, " : %-14s", varname);
 	      else if ( operatorID == INFOC )
-		fprintf(stdout, " : %4d", code);
+		fprintf(stdout, " : %4d   ", code);
 	      else
-		fprintf(stdout, " : %-11s", paramstr);
+		fprintf(stdout, " : %-14s", paramstr);
+
+	      if ( cdoVerbose )
+		{
+		  char varextra[CDI_MAX_NAME];
+		  vlistInqVarExtra(vlistID, varID, varextra);
+		  fprintf(stdout, " : %s", varextra );              
+		}
 
 	      fprintf(stdout, "\n");
 
diff --git a/src/Intgrid.c b/src/Intgrid.c
index d9d4e16..5b94d98 100644
--- a/src/Intgrid.c
+++ b/src/Intgrid.c
@@ -310,7 +310,7 @@ void thinout(field_t *field1, field_t *field2, int xinc, int yinc)
 
 void *Intgrid(void *argument)
 {
-  int INTGRID, INTPOINT, INTERPOLATE, BOXAVG, THINOUT;
+  int INTGRIDBIL, INTGRIDCON, INTPOINT, INTERPOLATE, BOXAVG, THINOUT;
   int operatorID;
   int streamID1, streamID2;
   int nrecs, ngrids;
@@ -329,7 +329,8 @@ void *Intgrid(void *argument)
 
   cdoInitialize(argument);
 
-  INTGRID     = cdoOperatorAdd("intgridbil",  0, 0, NULL);
+  INTGRIDBIL  = cdoOperatorAdd("intgridbil",  0, 0, NULL);
+  INTGRIDCON  = cdoOperatorAdd("intgridcon",  0, 0, NULL);
   INTPOINT    = cdoOperatorAdd("intpoint",    0, 0, NULL);
   INTERPOLATE = cdoOperatorAdd("interpolate", 0, 0, NULL);
   BOXAVG      = cdoOperatorAdd("boxavg",      0, 0, NULL);
@@ -337,7 +338,7 @@ void *Intgrid(void *argument)
 
   operatorID = cdoOperatorID();
 
-  if ( operatorID == INTGRID || operatorID == INTERPOLATE )
+  if ( operatorID == INTGRIDBIL || operatorID == INTGRIDCON || operatorID == INTERPOLATE )
     {
       operatorInputArg("grid description file or name");
       gridID2 = cdoDefineGrid(operatorArgv()[0]);
@@ -437,8 +438,10 @@ void *Intgrid(void *argument)
 	  field2.ptr     = array2;
 	  field2.nmiss   = 0;
 
-	  if ( operatorID == INTGRID || operatorID == INTPOINT )
-	    intgrid(&field1, &field2);
+	  if ( operatorID == INTGRIDBIL || operatorID == INTPOINT )
+	    intgridbil(&field1, &field2);
+	  if ( operatorID == INTGRIDCON )
+	    intgridcon(&field1, &field2);
 	  else if ( operatorID == INTERPOLATE )
 	    interpolate(&field1, &field2);
 	  else if ( operatorID == BOXAVG )
diff --git a/src/Intgridtraj.c b/src/Intgridtraj.c
index ea84450..002e0d5 100644
--- a/src/Intgridtraj.c
+++ b/src/Intgridtraj.c
@@ -217,7 +217,7 @@ void *Intgridtraj(void *argument)
 		  field2.ptr     = &point;
 		  field2.nmiss   = 0;
 
-		  intgrid(&field1, &field2);
+		  intgridbil(&field1, &field2);
 
 		  streamDefRecord(streamID2, varID, levelID);
 		  streamWriteRecord(streamID2, &point, nmiss);
diff --git a/src/Intlevel3d.c b/src/Intlevel3d.c
index 96b4658..36f34fc 100644
--- a/src/Intlevel3d.c
+++ b/src/Intlevel3d.c
@@ -238,7 +238,9 @@ void *Intlevel3d(void *argument)
   /*  Read filename from Parameter */
   operatorInputArg("grid description file or name, remap file (SCRIP netCDF)");
   operatorCheckArgc(1);
-  streamID0 = streamOpenRead(operatorArgv()[0]);                /*  3d vertical input coordinate */
+  argument_t *fileargument = file_argument_new(operatorArgv()[0]);
+  streamID0 = streamOpenRead(fileargument);                /*  3d vertical input coordinate */
+  file_argument_free(fileargument);
   streamID1 = streamOpenRead(cdoStreamName(0));                 /*  input data */
   streamID2 = streamOpenRead(cdoStreamName(1));                 /*  3d target vertical coordinate */
   streamID3 = streamOpenWrite(cdoStreamName(2),cdoFiletype());  /*  output stream */
diff --git a/src/Inttime.c b/src/Inttime.c
index a5462f7..5d3b978 100644
--- a/src/Inttime.c
+++ b/src/Inttime.c
@@ -194,10 +194,10 @@ void *Inttime(void *argument)
 	  streamReadRecord(streamID1, single2, &nmiss2[varID][levelID]);
 	}
 
-      while ( juldate_to_seconds(juldate) < juldate_to_seconds(juldate2) )
+      while ( juldate_to_seconds(juldate) <= juldate_to_seconds(juldate2) )
 	{
 	  if ( juldate_to_seconds(juldate) >= juldate_to_seconds(juldate1) &&
-	       juldate_to_seconds(juldate) <  juldate_to_seconds(juldate2) )
+	       juldate_to_seconds(juldate) <= juldate_to_seconds(juldate2) )
 	    {
 	      juldate_decode(calendar, juldate, &vdate, &vtime);
 
@@ -217,7 +217,6 @@ void *Inttime(void *argument)
 	      if ( streamID2 == -1 )
 		{
 		  streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
-
 		  streamDefVlist(streamID2, vlistID2);
 		}
 
diff --git a/src/Intyear.c b/src/Intyear.c
index 37f6f27..e5e1285 100644
--- a/src/Intyear.c
+++ b/src/Intyear.c
@@ -81,7 +81,7 @@ void *Intyear(void *argument)
   if ( taxisHasBounds(taxisID3) ) taxisDeleteBounds(taxisID3);
   vlistDefTaxis(vlistID3, taxisID3);
 
-  strcpy(filename, cdoStreamName(2));
+  strcpy(filename, cdoStreamName(2)->args);
   nchars = strlen(filename);
 
   filesuffix[0] = 0;
@@ -92,8 +92,10 @@ void *Intyear(void *argument)
       sprintf(filename+nchars, "%04d", iyears[iy]);
       if ( filesuffix[0] )
 	sprintf(filename+nchars+4, "%s", filesuffix);
-      /*	  printf("filename %s\n", filename); */
-      streamIDs[iy] = streamOpenWrite(filename, cdoFiletype());
+
+      argument_t *fileargument = file_argument_new(filename);
+      streamIDs[iy] = streamOpenWrite(fileargument, cdoFiletype());
+      file_argument_free(fileargument);
 
       streamDefVlist(streamIDs[iy], vlistID3);
     }
diff --git a/src/Log.c b/src/Log.c
index 4f299a9..6ba50ed 100644
--- a/src/Log.c
+++ b/src/Log.c
@@ -47,24 +47,24 @@ void *Log(void *argument)
   operfunc   = cdoOperatorF1(operatorID);
   dumptype   = cdoOperatorF2(operatorID);
 
-  if ( cdoStreamName(0)[0] == '-' )
+  if ( cdoStreamName(0)->args[0] == '-' )
     cdoAbort("This operator does not work with pipes!");
 
   if ( operatorID == DUMPLOGS )
     {
-      dumplogs(cdoStreamName(0));
+      dumplogs(cdoStreamName(0)->args);
     }
   else if ( operatorID == DAYLOGS )
     {
-      daylogs(cdoStreamName(0));
+      daylogs(cdoStreamName(0)->args);
     }
   else if ( operatorID == MONLOGS )
     {
-      monlogs(cdoStreamName(0));
+      monlogs(cdoStreamName(0)->args);
     }
   else if ( operfunc == 1 )
     {
-      dumplogo(cdoStreamName(0), dumptype);
+      dumplogo(cdoStreamName(0)->args, dumptype);
     }
 
   cdoFinish();
diff --git a/src/Maggraph.c b/src/Maggraph.c
index a788e18..08ec5d0 100644
--- a/src/Maggraph.c
+++ b/src/Maggraph.c
@@ -533,6 +533,10 @@ void maggraph(const char *plotfile, const char *varname,const char *varunits, lo
   mag_setc("axis_date_max_value", max_date_time_str);
   mag_setc("axis_title_text","Time");
   mag_setc("axis_title_orientation","horizontal");
+
+  mag_seti("axis_tick_label_frequency", 2);
+  mag_setr("axis_years_label_height", 0.4);
+
   mag_axis();
 
   /* Vertical Axis attributes */
@@ -559,6 +563,10 @@ void maggraph(const char *plotfile, const char *varname,const char *varunits, lo
   mag_setc("axis_title_text",varname);
   
   mag_setc("axis_title_orientation","vertical");
+
+  mag_seti("axis_tick_label_frequency", 2);
+  mag_setr("axis_tick_label_height", 0.5);
+
   mag_axis();
  
 
@@ -808,7 +816,7 @@ void *Maggraph(void *argument)
     VerifyGraphParameters(nparam,pnames);
   
   nfiles = cdoStreamCnt() - 1;
-  ofilename = cdoStreamName(nfiles);
+  ofilename = cdoStreamName(nfiles)->args;
   
   if( DBG )
     {
@@ -834,7 +842,7 @@ void *Maggraph(void *argument)
       
      
       if( DBG )
-        fprintf( stderr," file %d is %s\n", fileID, cdoStreamName(fileID) );
+        fprintf( stderr," file %d is %s\n", fileID, cdoStreamName(fileID)->args );
       streamID = streamOpenRead(cdoStreamName(fileID));
 
       vlistID = streamInqVlist(streamID);
diff --git a/src/Magplot.c b/src/Magplot.c
index d38d50e..3459523 100644
--- a/src/Magplot.c
+++ b/src/Magplot.c
@@ -87,7 +87,7 @@ char *COLOUR = NULL, *COLOUR_MIN = NULL, *COLOUR_MAX = NULL, *STYLE = NULL, *DEV
 
 
 static
-void magplot( const char *plotfile, int operatorID, const char *varname, long nlon, long nlat, double *grid_center_lon, double *grid_center_lat, double *array,  int nparam, char **params, char *datetime )
+void magplot( const char *plotfile, int operatorID, const char *varname, const char *units, long nlon, long nlat, double *grid_center_lon, double *grid_center_lat, double *array,  int nparam, char **params, char *datetime )
 
 {
   long i;
@@ -173,7 +173,7 @@ void magplot( const char *plotfile, int operatorID, const char *varname, long nl
       dlat /= (nlat-1);
     }
 
-  sprintf( plotfilename, "%s %s", varname, datetime );
+  sprintf( plotfilename, "%s [%s] %s", varname, units, datetime );
   titlename = strdup( plotfilename );
   sprintf( plotfilename, "%s_%s", plotfile, varname );
 
@@ -211,6 +211,10 @@ void magplot( const char *plotfile, int operatorID, const char *varname, long nl
       mag_setc ("output_format", DEVICE );
     }
 
+  mag_seti ("map_label_latitude_frequency",2);
+  mag_seti ("map_label_longitude_frequency",2);
+  /*mag_setr ("map_label_height",0.5);*/
+  mag_setr ("map_label_height",0.4);
 
 
   /* define the contouring parameters */
@@ -554,9 +558,9 @@ void *Magplot(void *argument)
 
   /* Convert lat/lon units if required */
   gridInqXunits(gridID, units);
-  gridToDegree(units, "grid center lon", gridsize, grid_center_lon);
+  grid_to_degree(units, gridsize, grid_center_lon, "grid center lon");
   gridInqYunits(gridID, units);
-  gridToDegree(units, "grid center lat", gridsize, grid_center_lat);
+  grid_to_degree(units, gridsize, grid_center_lat, "grid center lat");
 					
   tsID = 0;
 
@@ -595,6 +599,16 @@ void *Magplot(void *argument)
 	             continue;
 	    	  }
             }
+         else 
+            {
+		if( tsID )
+		  {
+	   		cdoWarning("File variables have values at more than one time step! Images created for first time step!!!");
+           		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;
+		  }
+	    }
         }
       
       vdate = taxisInqVdate(taxisID);
@@ -611,6 +625,7 @@ void *Magplot(void *argument)
 	  streamInqRecord(streamID, &varID, &levelID);
 	  streamReadRecord(streamID, array, &nmiss);
 	  vlistInqVarName(vlistID, varID, varname);
+	  vlistInqVarUnits(vlistID, varID, units);
 
 	  if ( operatorID == SHADED || operatorID == CONTOUR || operatorID == GRFILL )
           {
@@ -626,7 +641,7 @@ void *Magplot(void *argument)
 
                 if( DBG )
                   fprintf( stderr,"Plot %d\n",varID );
-	  	magplot(cdoStreamName(1), operatorID, varname, nlon, nlat, grid_center_lon, grid_center_lat, array, nparam, pnames, datetimestr );
+	  	magplot(cdoStreamName(1)->args, operatorID, varname, units, nlon, nlat, grid_center_lon, grid_center_lat, array, nparam, pnames, datetimestr );
           }
 	  else
 	  	fprintf(stderr,"operator not implemented\n");
@@ -636,7 +651,9 @@ void *Magplot(void *argument)
         fprintf( stderr,"TimeStep %d\n",tsID );
 
        
-      if( !STEP_FREQ )
+      tsID++;
+      /*
+      if( !STEP_FREQ  && tsID )
         {
 	   cdoWarning("File variables have values at more than one time step! Images created for first time step!!!");
            cdoWarning("To plot steps at a particular interval, set 'step_freq' to the frequency of the steps to be plotted!!!");
@@ -649,6 +666,7 @@ void *Magplot(void *argument)
            if( DBG )
              fprintf( stderr,"TimeStep %d\n",tsID );
 	}
+      */
     }
 
   if( ANIM_FLAG )
diff --git a/src/Magvector.c b/src/Magvector.c
index 6bedde0..e927cda 100644
--- a/src/Magvector.c
+++ b/src/Magvector.c
@@ -154,6 +154,15 @@ void magvector( const char *plotfile, int operatorID, const char *varname, long
 	mag_set2r("input_wind_u_component", uarray, nlon, nlat);
 	mag_set2r("input_wind_v_component", varray, nlon, nlat);
 
+
+	mag_seti ("map_label_latitude_frequency",2);
+	mag_seti ("map_label_longitude_frequency",2);
+	/*mag_setr ("map_label_height",0.5);*/
+	mag_setr ("map_label_height",0.4);
+	
+
+
+
         if( operatorID == VECTOR ) 
 	  {
 		/* Magics functions for performing vector operation */
@@ -282,8 +291,8 @@ void *Magvector(void *argument)
   nlat     = gridInqYsize(gridID);
   nlev     = zaxisInqSize(zaxisID);
 
-  uarray           = (double *) malloc(gridsize*sizeof(double));
-  varray           = (double *) malloc(gridsize*sizeof(double));
+  uarray          = (double *) malloc(gridsize*sizeof(double));
+  varray          = (double *) malloc(gridsize*sizeof(double));
   grid_center_lat = (double *) malloc(gridsize*sizeof(double));
   grid_center_lon = (double *) malloc(gridsize*sizeof(double));
 
@@ -292,9 +301,9 @@ void *Magvector(void *argument)
 
   /* Convert lat/lon units if required */
   gridInqXunits(gridID, units);
-  gridToDegree(units, "grid center lon", gridsize, grid_center_lon);
+  grid_to_degree(units, gridsize, grid_center_lon, "grid center lon");
   gridInqYunits(gridID, units);
-  gridToDegree(units, "grid center lat", gridsize, grid_center_lat);
+  grid_to_degree(units, gridsize, grid_center_lat, "grid center lat");
 					
   tsID = 0;
 
@@ -317,6 +326,14 @@ void *Magvector(void *argument)
                 continue;
             }
         }
+      else
+        {
+          if( !STEP_FREQ  && tsID )
+            {
+          	 cdoWarning("File has values at more than one time step! Image created for first time step!!!");
+           	 break;
+            }
+        }
 
       vdate = taxisInqVdate(taxisID);
       vtime = taxisInqVtime(taxisID);
@@ -362,7 +379,7 @@ void *Magvector(void *argument)
 	     {
                 if( DBG )
           	  fprintf( stderr,"Found Both U & V VEL, Creating vector fields! \n" );
-		magvector( cdoStreamName(1), operatorID, varname, nlon, nlat, grid_center_lon, grid_center_lat, uarray, varray, nparam, pnames, datetimestr );
+		magvector( cdoStreamName(1)->args, operatorID, varname, nlon, nlat, grid_center_lon, grid_center_lat, uarray, varray, nparam, pnames, datetimestr );
 	     }
 	   else if( found == 1 )
              {
@@ -376,6 +393,9 @@ void *Magvector(void *argument)
              }
 	}
     
+      tsID++;
+
+      /*
       if( ANIM_FLAG )
         tsID++;
       else
@@ -385,6 +405,7 @@ void *Magvector(void *argument)
              cdoWarning("Step frequency parameter ignored!!!");
            break;
         }
+      */
     }
 
   streamClose(streamID);
diff --git a/src/Makefile.am b/src/Makefile.am
index 040686c..8271018 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -89,6 +89,7 @@ cdo_SOURCES += Adisit.c        \
                Nmltest.c       \
                Output.c        \
                Outputgmt.c     \
+               Pack.c          \
                Pinfo.c         \
                Pressure.c      \
                Regres.c        \
diff --git a/src/Makefile.in b/src/Makefile.in
index 994687c..5de8c69 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -101,8 +101,8 @@ am__cdo_SOURCES_DIST = cdo.c Adisit.c Arith.c Arithc.c Arithdays.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 \
+	Mrotuvb.c Ninfo.c Nmltest.c Output.c Outputgmt.c Pack.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 \
@@ -187,7 +187,7 @@ am_cdo_OBJECTS = cdo-cdo.$(OBJEXT) cdo-Adisit.$(OBJEXT) \
 	cdo-Merstat.$(OBJEXT) cdo-Monarith.$(OBJEXT) \
 	cdo-Mrotuv.$(OBJEXT) cdo-Mrotuvb.$(OBJEXT) cdo-Ninfo.$(OBJEXT) \
 	cdo-Nmltest.$(OBJEXT) cdo-Output.$(OBJEXT) \
-	cdo-Outputgmt.$(OBJEXT) cdo-Pinfo.$(OBJEXT) \
+	cdo-Outputgmt.$(OBJEXT) cdo-Pack.$(OBJEXT) cdo-Pinfo.$(OBJEXT) \
 	cdo-Pressure.$(OBJEXT) cdo-Regres.$(OBJEXT) \
 	cdo-Remap.$(OBJEXT) cdo-Remapeta.$(OBJEXT) \
 	cdo-Replace.$(OBJEXT) cdo-Replacevalues.$(OBJEXT) \
@@ -468,8 +468,8 @@ cdo_SOURCES = cdo.c Adisit.c Arith.c Arithc.c Arithdays.c Arithlat.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 \
+	Output.c Outputgmt.c Pack.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 \
@@ -722,6 +722,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Nmltest.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Output.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Outputgmt.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Pack.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Pinfo.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Pressure.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Regres.Po at am__quote@
@@ -2114,6 +2115,20 @@ cdo-Outputgmt.obj: Outputgmt.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-Outputgmt.obj `if test -f 'Outputgmt.c'; then $(CYGPATH_W) 'Outputgmt.c'; else $(CYGPATH_W) '$(srcdir)/Outputgmt.c'; fi`
 
+cdo-Pack.o: Pack.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-Pack.o -MD -MP -MF $(DEPDIR)/cdo-Pack.Tpo -c -o cdo-Pack.o `test -f 'Pack.c' || echo '$(srcdir)/'`Pack.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-Pack.Tpo $(DEPDIR)/cdo-Pack.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='Pack.c' object='cdo-Pack.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-Pack.o `test -f 'Pack.c' || echo '$(srcdir)/'`Pack.c
+
+cdo-Pack.obj: Pack.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-Pack.obj -MD -MP -MF $(DEPDIR)/cdo-Pack.Tpo -c -o cdo-Pack.obj `if test -f 'Pack.c'; then $(CYGPATH_W) 'Pack.c'; else $(CYGPATH_W) '$(srcdir)/Pack.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-Pack.Tpo $(DEPDIR)/cdo-Pack.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='Pack.c' object='cdo-Pack.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-Pack.obj `if test -f 'Pack.c'; then $(CYGPATH_W) 'Pack.c'; else $(CYGPATH_W) '$(srcdir)/Pack.c'; fi`
+
 cdo-Pinfo.o: Pinfo.c
 @am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-Pinfo.o -MD -MP -MF $(DEPDIR)/cdo-Pinfo.Tpo -c -o cdo-Pinfo.o `test -f 'Pinfo.c' || echo '$(srcdir)/'`Pinfo.c
 @am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-Pinfo.Tpo $(DEPDIR)/cdo-Pinfo.Po
diff --git a/src/Maskbox.c b/src/Maskbox.c
index 5742708..963e3fa 100644
--- a/src/Maskbox.c
+++ b/src/Maskbox.c
@@ -155,9 +155,9 @@ void maskregion(int *mask, int gridID, double *xcoords, double *ycoords, int nof
   {
     char units[CDI_MAX_NAME];
     gridInqXunits(gridID, units);
-    gridToDegree(units, "grid center lon", nlon, xvals);
+    grid_to_degree(units, nlon, xvals, "grid center lon");
     gridInqYunits(gridID, units);
-    gridToDegree(units, "grid center lat", nlat, yvals);
+    grid_to_degree(units, nlat, yvals, "grid center lat");
   }
 
   xmin = xvals[0];
diff --git a/src/Mastrfu.c b/src/Mastrfu.c
index 26aa05d..801ab2d 100644
--- a/src/Mastrfu.c
+++ b/src/Mastrfu.c
@@ -25,6 +25,7 @@
 #include <cdi.h>
 #include "cdo.h"
 #include "cdo_int.h"
+#include "grid.h"
 #include "pstream.h"
 
 
diff --git a/src/Merge.c b/src/Merge.c
index 6bd32a9..c26f4d5 100644
--- a/src/Merge.c
+++ b/src/Merge.c
@@ -144,7 +144,7 @@ void *Merge(void *argument)
   streamCnt = cdoStreamCnt();
   nmerge    = streamCnt - 1;
 
-  ofilename = cdoStreamName(streamCnt-1);
+  ofilename = cdoStreamName(streamCnt-1)->args;
 
   if ( !cdoSilentMode && !cdoOverwriteMode )
     if ( fileExists(ofilename) )
@@ -172,7 +172,7 @@ void *Merge(void *argument)
   vlistCopy(vlistID2, vlistIDs[0]);
   for ( index = 1; index < nmerge; index++ )
     {
-      checkDupEntry(vlistID2, vlistIDs[index], cdoStreamName(index));
+      checkDupEntry(vlistID2, vlistIDs[index], cdoStreamName(index)->args);
       /* vlistCat(vlistID2, vlistIDs[index]); */
       vlistMerge(vlistID2, vlistIDs[index]);
     }
@@ -183,7 +183,7 @@ void *Merge(void *argument)
       vlistPrint(vlistID2);
     }
        
-  streamID2 = streamOpenWrite(ofilename, cdoFiletype());
+  streamID2 = streamOpenWrite(cdoStreamName(streamCnt-1), cdoFiletype());
 
   vlistDefTaxis(vlistID2, taxisID2);
   streamDefVlist(streamID2, vlistID2);
diff --git a/src/Mergegrid.c b/src/Mergegrid.c
index 96f854f..7716bb8 100644
--- a/src/Mergegrid.c
+++ b/src/Mergegrid.c
@@ -86,9 +86,9 @@ void gen_index(int gridID1, int gridID2, int *index)
       {
 	char units[CDI_MAX_NAME];
 	gridInqXunits(gridID1, units);
-	gridToDegree(units, "grid1 center lon", nlon1, xvals1);
+	grid_to_degree(units, nlon1, xvals1, "grid1 center lon");
 	gridInqYunits(gridID1, units);
-	gridToDegree(units, "grid1 center lat", nlat1, yvals1);
+	grid_to_degree(units, nlat1, yvals1, "grid1 center lat");
       }
 
       gridInqXvals(gridID2, xvals2);
@@ -98,9 +98,9 @@ void gen_index(int gridID1, int gridID2, int *index)
       {
 	char units[CDI_MAX_NAME];
 	gridInqXunits(gridID2, units);
-	gridToDegree(units, "grid2 center lon", nlon2, xvals2);
+	grid_to_degree(units, nlon2, xvals2, "grid2 center lon");
 	gridInqYunits(gridID2, units);
-	gridToDegree(units, "grid2 center lat", nlat2, yvals2);
+	grid_to_degree(units, nlat2, yvals2, "grid2 center lat");
       }
 
       for ( i2 = 0; i2 < nlat2; i2++ )
@@ -205,14 +205,14 @@ void *Mergegrid(void *argument)
     if ( vlistGrid(vlistID1, 0) != vlistGrid(vlistID1, index) )
       ndiffgrids++;
 
-  if ( ndiffgrids > 0 ) cdoAbort("Too many different grids in %s!", cdoStreamName(0));
+  if ( ndiffgrids > 0 ) cdoAbort("Too many different grids in %s!", cdoStreamName(0)->args);
 
   ndiffgrids = 0;
   for ( index = 1; index < vlistNgrids(vlistID2); index++ )
     if ( vlistGrid(vlistID2, 0) != vlistGrid(vlistID2, index))
       ndiffgrids++;
 
-  if ( ndiffgrids > 0 ) cdoAbort("Too many different grids in %s!", cdoStreamName(1));
+  if ( ndiffgrids > 0 ) cdoAbort("Too many different grids in %s!", cdoStreamName(1)->args);
 
   gridID1 = vlistGrid(vlistID1, 0);
   gridID2 = vlistGrid(vlistID2, 0);
diff --git a/src/Mergetime.c b/src/Mergetime.c
index 126d71c..3b6dc55 100644
--- a/src/Mergetime.c
+++ b/src/Mergetime.c
@@ -81,7 +81,7 @@ void *Mergetime(void *argument)
 
   for ( fileID = 0; fileID < nfiles; fileID++ )
     {
-      if ( cdoVerbose ) cdoPrint("process: %s", cdoStreamName(fileID));
+      if ( cdoVerbose ) cdoPrint("process: %s", cdoStreamName(fileID)->args);
 
       streamID1 = streamOpenRead(cdoStreamName(fileID));
 
@@ -115,14 +115,14 @@ void *Mergetime(void *argument)
 	}
     }
 
-  ofilename = cdoStreamName(nfiles);
+  ofilename = cdoStreamName(nfiles)->args;
 
   if ( !cdoSilentMode && !cdoOverwriteMode )
     if ( fileExists(ofilename) )
       if ( !userFileOverwrite(ofilename) )
 	cdoAbort("Outputfile %s already exists!", ofilename);
 
-  streamID2 = streamOpenWrite(ofilename, cdoFiletype());
+  streamID2 = streamOpenWrite(cdoStreamName(nfiles), cdoFiletype());
 
   if ( ! lcopy )
     {
diff --git a/src/Monarith.c b/src/Monarith.c
index 53caa43..2a45f7a 100644
--- a/src/Monarith.c
+++ b/src/Monarith.c
@@ -113,7 +113,7 @@ void *Monarith(void *argument)
 
 	  nrecs2 = streamInqTimestep(streamID2, tsID2);
 	  if ( nrecs2 == 0 )
-	    cdoAbort("Missing year=%4d mon=%2d in %s!", year1, mon1, cdoStreamName(1));
+	    cdoAbort("Missing year=%4d mon=%2d in %s!", year1, mon1, cdoStreamName(1)->args);
 
 	  vdate = taxisInqVdate(taxisID2);
 
@@ -127,7 +127,7 @@ void *Monarith(void *argument)
 	      mon2  = yearmon2 - (yearmon2/100)*100;
 
 	      cdoAbort("Timestep %d in %s has wrong date!\nCurrent year=%4d mon=%2d, expected year=%4d mon=%2d",
-		       tsID2+1, cdoStreamName(1), year2, mon2, year1, mon1);
+		       tsID2+1, cdoStreamName(1)->args, year2, mon2, year1, mon1);
 	    }
 
 	  for ( recID = 0; recID < nrecs2; recID++ )
diff --git a/src/Mrotuv.c b/src/Mrotuv.c
index c602f41..a526473 100644
--- a/src/Mrotuv.c
+++ b/src/Mrotuv.c
@@ -236,7 +236,7 @@ void *Mrotuv(void *argument)
 	  vid = 1;
 	}
       else
-	cdoAbort("U and V not found in %s",  cdoStreamName(0));
+	cdoAbort("U and V not found in %s",  cdoStreamName(0)->args);
     }
 
   nlevs = zaxisInqSize(vlistInqVarZaxis(vlistID1, uid));
@@ -277,9 +277,9 @@ void *Mrotuv(void *argument)
   {
     char units[CDI_MAX_NAME];
     gridInqXunits(gridID1, units);
-    gridToDegree(units, "grid center lon", gridsize, grid1x);
+    grid_to_degree(units, gridsize, grid1x, "grid center lon");
     gridInqYunits(gridID1, units);
-    gridToDegree(units, "grid center lat", gridsize, grid1y);
+    grid_to_degree(units, gridsize, grid1y, "grid center lat");
   }
 
   p_to_uv_grid(nlon, nlat, grid1x, grid1y, gridux, griduy, gridvx, gridvy);
diff --git a/src/Mrotuvb.c b/src/Mrotuvb.c
index 66c7227..fde6cd2 100644
--- a/src/Mrotuvb.c
+++ b/src/Mrotuvb.c
@@ -266,13 +266,14 @@ void *Mrotuvb(void *argument)
   int varID1, varID2;
   int nvars;
   int gridID1, gridID2, gridID3;
-  int gridsize, gridsizex;
+  int gridsize;
   int nlon, nlat;
   int vlistID1, vlistID2, vlistID3;
   int i, j;
   int taxisID1, taxisID3;
   int nmiss1, nmiss2;
   int code1, code2;
+  int gpint = TRUE;
   double missval1, missval2;
   double *ufield = NULL, *vfield = NULL;
   double *urfield = NULL, *vrfield = NULL;
@@ -282,6 +283,10 @@ void *Mrotuvb(void *argument)
 
   cdoInitialize(argument);
 
+  if ( operatorArgc() == 1 )
+    if ( strcmp(operatorArgv()[0], "noint") == 0 )
+      gpint = FALSE;
+
   streamID1 = streamOpenRead(cdoStreamName(0));
   streamID2 = streamOpenRead(cdoStreamName(1));
 
@@ -289,14 +294,15 @@ void *Mrotuvb(void *argument)
   vlistID2 = streamInqVlist(streamID2);
 
   nvars = vlistNvars(vlistID1);
-  if ( nvars > 1 ) cdoAbort("More than one variable found in %s",  cdoStreamName(0));
+  if ( nvars > 1 ) cdoAbort("More than one variable found in %s",  cdoStreamName(0)->args);
   nvars = vlistNvars(vlistID2);
-  if ( nvars > 1 ) cdoAbort("More than one variable found in %s",  cdoStreamName(1));
+  if ( nvars > 1 ) cdoAbort("More than one variable found in %s",  cdoStreamName(1)->args);
 
   gridID1 = vlistGrid(vlistID1, 0);
   gridID2 = vlistGrid(vlistID2, 0);
   gridsize = gridInqSize(gridID1);
-  if ( gridID1 == gridID2 ) cdoAbort("Input grids are the same!");
+  if ( gpint == TRUE  && gridID1 == gridID2 ) cdoAbort("Input grids are the same!");
+  if ( gpint == FALSE && gridID1 != gridID2 ) cdoAbort("Input grids are not the same!");
   if ( gridsize != gridInqSize(gridID2) ) cdoAbort("Grids have different size!");
 
   if ( gridInqType(gridID1) != GRID_LONLAT      &&
@@ -331,9 +337,9 @@ void *Mrotuvb(void *argument)
   {
     char units[CDI_MAX_NAME];
     gridInqXunits(gridID1, units);
-    gridToDegree(units, "grid1 center lon", gridsize, grid1x);
+    grid_to_degree(units, gridsize, grid1x, "grid1 center lon");
     gridInqYunits(gridID1, units);
-    gridToDegree(units, "grid1 center lat", gridsize, grid1y);
+    grid_to_degree(units, gridsize, grid1y, "grid1 center lat");
   }
 
   gridInqXvals(gridID2, grid2x);
@@ -343,12 +349,20 @@ void *Mrotuvb(void *argument)
   {
     char units[CDI_MAX_NAME];
     gridInqXunits(gridID2, units);
-    gridToDegree(units, "grid2 center lon", gridsize, grid2x);
+    grid_to_degree(units, gridsize, grid2x, "grid2 center lon");
     gridInqYunits(gridID2, units);
-    gridToDegree(units, "grid2 center lat", gridsize, grid2y);
+    grid_to_degree(units, gridsize, grid2y, "grid2 center lat");
   }
 
-  uv_to_p_grid(nlon, nlat, grid1x, grid1y, grid2x, grid2y, grid3x, grid3y);
+  if ( gpint )
+    {
+      uv_to_p_grid(nlon, nlat, grid1x, grid1y, grid2x, grid2y, grid3x, grid3y);
+    }
+  else
+    {
+      memcpy(grid3x, grid1x, gridsize*sizeof(double));
+      memcpy(grid3y, grid1y, gridsize*sizeof(double));
+    }
 
   if ( grid1x ) free(grid1x);
   if ( grid1y ) free(grid1y);
@@ -398,10 +412,12 @@ void *Mrotuvb(void *argument)
   urfield = (double *) malloc(gridsize*sizeof(double));
   vrfield = (double *) malloc(gridsize*sizeof(double));
 
-  gridsizex = (nlon+2)*nlat;
-
-  uhelp   = (double *) malloc(gridsizex*sizeof(double));
-  vhelp   = (double *) malloc(gridsizex*sizeof(double));
+  if ( gpint )
+    {
+      int gridsizex = (nlon+2)*nlat;
+      uhelp   = (double *) malloc(gridsizex*sizeof(double));
+      vhelp   = (double *) malloc(gridsizex*sizeof(double));
+    }
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
@@ -432,30 +448,33 @@ void *Mrotuvb(void *argument)
 		}
 	    }
 
-	  /* load to a help field */
-	  for ( j = 0; j < nlat; j++ )
-	    for ( i = 0; i < nlon; i++ )
-	      {
-		uhelp[IX2D(j,i+1,nlon+2)] = ufield[IX2D(j,i,nlon)];
-		vhelp[IX2D(j,i+1,nlon+2)] = vfield[IX2D(j,i,nlon)];
-	      }
-
-	  /* make help field cyclic */
-	  for ( j = 0; j < nlat; j++ )
+	  if ( gpint )
 	    {
-	      uhelp[IX2D(j,0,nlon+2)]      = uhelp[IX2D(j,nlon,nlon+2)];
-	      uhelp[IX2D(j,nlon+1,nlon+2)] = uhelp[IX2D(j,1,nlon+2)];
-	      vhelp[IX2D(j,0,nlon+2)]      = vhelp[IX2D(j,nlon,nlon+2)];
-	      vhelp[IX2D(j,nlon+1,nlon+2)] = vhelp[IX2D(j,1,nlon+2)];
-	    }
+	      /* load to a help field */
+	      for ( j = 0; j < nlat; j++ )
+		for ( i = 0; i < nlon; i++ )
+		  {
+		    uhelp[IX2D(j,i+1,nlon+2)] = ufield[IX2D(j,i,nlon)];
+		    vhelp[IX2D(j,i+1,nlon+2)] = vfield[IX2D(j,i,nlon)];
+		  }
+
+	      /* make help field cyclic */
+	      for ( j = 0; j < nlat; j++ )
+		{
+		  uhelp[IX2D(j,0,nlon+2)]      = uhelp[IX2D(j,nlon,nlon+2)];
+		  uhelp[IX2D(j,nlon+1,nlon+2)] = uhelp[IX2D(j,1,nlon+2)];
+		  vhelp[IX2D(j,0,nlon+2)]      = vhelp[IX2D(j,nlon,nlon+2)];
+		  vhelp[IX2D(j,nlon+1,nlon+2)] = vhelp[IX2D(j,1,nlon+2)];
+		}
 
-	  /* interpolate on pressure points */
-	  for ( j = 1; j < nlat; j++ )
-	    for ( i = 0; i < nlon; i++ )
-	      {
-		ufield[IX2D(j,i,nlon)] = (uhelp[IX2D(j,i,nlon+2)]+uhelp[IX2D(j,i+1,nlon+2)])*0.5;
-		vfield[IX2D(j,i,nlon)] = (vhelp[IX2D(j-1,i+1,nlon+2)]+vhelp[IX2D(j,i+1,nlon+2)])*0.5;
-	      }
+	      /* interpolate on pressure points */
+	      for ( j = 1; j < nlat; j++ )
+		for ( i = 0; i < nlon; i++ )
+		  {
+		    ufield[IX2D(j,i,nlon)] = (uhelp[IX2D(j,i,nlon+2)]+uhelp[IX2D(j,i+1,nlon+2)])*0.5;
+		    vfield[IX2D(j,i,nlon)] = (vhelp[IX2D(j-1,i+1,nlon+2)]+vhelp[IX2D(j,i+1,nlon+2)])*0.5;
+		  }
+	    }
 
 	  for ( i = 0; i < nlon; i++ )
 	    {
@@ -507,8 +526,11 @@ void *Mrotuvb(void *argument)
   if ( vfield  ) free(vfield);
   if ( urfield ) free(urfield);
   if ( vrfield ) free(vrfield);
-  if ( uhelp   ) free(uhelp);
-  if ( vhelp   ) free(vhelp);
+  if ( gpint )
+    {
+      if ( uhelp   ) free(uhelp);
+      if ( vhelp   ) free(vhelp);
+    }
   if ( grid3x  ) free(grid3x);
   if ( grid3y  ) free(grid3y);
 
diff --git a/src/Output.c b/src/Output.c
index 4b97cba..335457c 100644
--- a/src/Output.c
+++ b/src/Output.c
@@ -174,9 +174,9 @@ void *Output(void *argument)
 	  {
 	    char units[CDI_MAX_NAME];
 	    gridInqXunits(gridID, units);
-	    gridToDegree(units, "grid center lon", gridsize, grid_center_lon);
+	    grid_to_degree(units, gridsize, grid_center_lon, "grid center lon");
 	    gridInqYunits(gridID, units);
-	    gridToDegree(units, "grid center lat", gridsize, grid_center_lat);
+	    grid_to_degree(units, gridsize, grid_center_lat, "grid center lat");
 	  }
 	}
 
diff --git a/src/Outputgmt.c b/src/Outputgmt.c
index e7bd776..15e4911 100644
--- a/src/Outputgmt.c
+++ b/src/Outputgmt.c
@@ -717,9 +717,9 @@ void *Outputgmt(void *argument)
 
   /* Convert lat/lon units if required */
   gridInqXunits(gridID, units);
-  gridToDegree(units, "grid center lon", gridsize, grid_center_lon);
+  grid_to_degree(units, gridsize, grid_center_lon, "grid center lon");
   gridInqYunits(gridID, units);
-  gridToDegree(units, "grid center lat", gridsize, grid_center_lat);
+  grid_to_degree(units, gridsize, grid_center_lat, "grid center lat");
 
   nvals = gridsize;
   plon = grid_center_lon;
@@ -779,8 +779,8 @@ void *Outputgmt(void *argument)
 
 
       /* Note: using units from latitude instead from bounds */
-      gridToDegree(units, "grid corner lon", gridcorners*gridsize, grid_corner_lon);
-      gridToDegree(units, "grid corner lat", gridcorners*gridsize, grid_corner_lat);
+      grid_to_degree(units, gridcorners*gridsize, grid_corner_lon, "grid corner lon");
+      grid_to_degree(units, gridcorners*gridsize, grid_corner_lat, "grid corner lat");
 
       if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
 	{
@@ -853,7 +853,7 @@ void *Outputgmt(void *argument)
 	  if ( operatorID == OUTPUTVECTOR )
 	    fprintf(stdout, "# Increment = %d\n", ninc);
 	  fprintf(stdout, "#\n");
-	  fprintf(stdout, "# File  = %s\n", cdoStreamName(0));
+	  fprintf(stdout, "# File  = %s\n", cdoStreamName(0)->args);
 	  fprintf(stdout, "# Date  = %s\n", vdatestr);
 	  fprintf(stdout, "# Time  = %s\n", vtimestr);
 	  fprintf(stdout, "# Name  = %s\n", varname);
diff --git a/src/Pack.c b/src/Pack.c
new file mode 100644
index 0000000..94caef3
--- /dev/null
+++ b/src/Pack.c
@@ -0,0 +1,290 @@
+/*
+  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:
+
+      Pack    pack         Pack
+*/
+
+#if defined (_OPENMP)
+#  include <omp.h>
+#endif
+
+#include <limits.h>
+
+#include <cdi.h>
+#include "cdo.h"
+#include "cdo_int.h"
+#include "pstream.h"
+
+
+#define  NALLOC_INC  1024
+
+
+static
+int get_type_values(int datatype, double *tmin, double *tmax)
+{
+  int status = 0;
+
+  switch (datatype)
+    {
+    case DATATYPE_INT8:    *tmin = -SCHAR_MAX+1; *tmax = SCHAR_MAX;   break;
+    case DATATYPE_UINT8:   *tmin = 0;            *tmax = UCHAR_MAX-1; break;
+    case DATATYPE_INT16:   *tmin = -SHRT_MAX+1;  *tmax = SHRT_MAX;    break;
+    case DATATYPE_UINT16:  *tmin = 0;            *tmax = USHRT_MAX-1; break;
+    case DATATYPE_INT32:   *tmin = -INT_MAX+1;   *tmax = INT_MAX;     break;
+    case DATATYPE_UINT32:  *tmin = 0;            *tmax = UINT_MAX-1;  break;
+    default: status = 1; break;
+    }
+
+  return status;
+}
+
+static
+int compute_scale(int datatype, double fmin, double fmax, double *scale_factor, double *add_offset)
+{
+  double tmin, tmax;
+  double ao = 0.0, sf = 1.0;
+
+  *scale_factor = sf;
+  *add_offset = ao;
+
+  if ( get_type_values(datatype, &tmin, &tmax) ) return (1);
+
+  if ( IS_NOT_EQUAL(fmin, fmax) )
+    {
+      sf = (fmax - fmin) / (tmax - tmin);
+      ao = ((fmax + fmin) - sf * (tmin + tmax)) / 2;
+    }
+
+  *scale_factor = sf;
+  *add_offset   = ao;
+
+  return 0;
+}
+
+
+void *Pack(void *argument)
+{
+  int gridsize;
+  int nrecs;
+  int gridID, varID, levelID, recID;
+  int tsID;
+  int i;
+  int nts;
+  int nalloc = 0;
+  int streamID1, streamID2;
+  int vlistID1, vlistID2, taxisID1, taxisID2;
+  int nmiss;
+  int nvars, nlevel;
+  int datatype = DATATYPE_INT16;
+  double missval1, missval2;
+  field_t ***vars = NULL;
+  dtinfo_t *dtinfo = NULL;
+
+  cdoInitialize(argument);
+
+  streamID1 = streamOpenRead(cdoStreamName(0));
+
+  vlistID1 = streamInqVlist(streamID1);
+  vlistID2 = vlistDuplicate(vlistID1);
+
+  taxisID1 = vlistInqTaxis(vlistID1);
+  taxisID2 = taxisDuplicate(taxisID1);
+  vlistDefTaxis(vlistID2, taxisID2);
+
+  nvars = vlistNvars(vlistID1);
+
+  tsID = 0;
+  while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
+    {
+      if ( tsID >= nalloc )
+	{
+	  nalloc += NALLOC_INC;
+	  dtinfo = (dtinfo_t *) realloc(dtinfo, nalloc*sizeof(dtinfo_t));
+	  vars   = (field_t ***) realloc(vars, nalloc*sizeof(field_t **));
+	}
+
+      taxisInqDTinfo(taxisID1, &dtinfo[tsID]);
+
+      vars[tsID] = (field_t **) malloc(nvars*sizeof(field_t *));
+
+      for ( varID = 0; varID < nvars; varID++ )
+	{
+	  gridID   = vlistInqVarGrid(vlistID1, varID);
+	  missval1 = vlistInqVarMissval(vlistID1, varID);
+	  nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
+
+	  vars[tsID][varID] = (field_t *) malloc(nlevel*sizeof(field_t));
+
+	  for ( levelID = 0; levelID < nlevel; levelID++ )
+	    {
+	      vars[tsID][varID][levelID].grid    = gridID;
+	      vars[tsID][varID][levelID].missval = missval1;
+	      vars[tsID][varID][levelID].ptr     = NULL;
+	    }
+	}
+
+      for ( recID = 0; recID < nrecs; recID++ )
+	{
+	  streamInqRecord(streamID1, &varID, &levelID);
+	  gridID   = vlistInqVarGrid(vlistID1, varID);
+	  gridsize = gridInqSize(gridID);
+	  vars[tsID][varID][levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+	  streamReadRecord(streamID1, vars[tsID][varID][levelID].ptr, &nmiss);
+	  vars[tsID][varID][levelID].nmiss = nmiss;
+	}
+
+      tsID++;
+    }
+
+  nts = tsID;
+
+  if ( cdoDefaultDataType != CDI_UNDEFID )
+    {
+      if ( cdoDefaultDataType == DATATYPE_FLT64 || cdoDefaultDataType == DATATYPE_FLT32 )
+	{
+	  cdoWarning("Changed default output datatype to int16");
+	  cdoDefaultDataType = datatype;
+	}
+      else
+	{
+	  datatype = cdoDefaultDataType;
+	}
+    }
+
+  cdoDefaultDataType = datatype;
+
+
+  for ( varID = 0; varID < nvars; varID++ )
+    {
+      double fmin =  1.e300;
+      double fmax = -1.e300;
+      double sf, ao;
+      long ivals = 0;
+      long nmisspv = 0;
+
+      gridID   = vlistInqVarGrid(vlistID1, varID);
+      missval1 = vlistInqVarMissval(vlistID1, varID);
+      gridsize = gridInqSize(gridID);
+      nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
+
+      for ( levelID = 0; levelID < nlevel; levelID++ )
+	{
+	  for ( tsID = 0; tsID < nts; tsID++ )
+	    {
+	      double *array =  vars[tsID][varID][levelID].ptr;
+	      nmiss = vars[tsID][varID][levelID].nmiss;
+	      if ( nmiss > 0 )
+		{
+		  nmisspv += nmiss;
+		  for ( i = 0; i < gridsize; ++i )
+		    {
+		      if ( !DBL_IS_EQUAL(array[i], missval1) )
+			{
+			  if ( array[i] < fmin ) fmin = array[i];
+			  if ( array[i] > fmax ) fmax = array[i];
+			  ivals++;
+			}
+		    }
+		}
+	      else
+		{
+		  for ( i = 0; i < gridsize; ++i )
+		    {
+		      if ( array[i] < fmin ) fmin = array[i];
+		      if ( array[i] > fmax ) fmax = array[i];
+		    }
+		  ivals = gridsize;
+		}
+	    }
+	}
+
+      vlistDefVarDatatype(vlistID2, varID, datatype);
+      missval2 = vlistInqVarMissval(vlistID2, varID);
+
+      if ( nmisspv > 0 )
+	{
+	  double tmin, tmax;
+	  if ( !get_type_values(datatype, &tmin, &tmax) )
+	    {
+	      if ( !(missval2 < tmin || missval2 > tmax) )
+		cdoWarning("new missing value %g is inside data range (%g - %g)!", missval2, tmin, tmax); 
+
+	      for ( levelID = 0; levelID < nlevel; levelID++ )
+		{
+		  for ( tsID = 0; tsID < nts; tsID++ )
+		    {
+		      double *array =  vars[tsID][varID][levelID].ptr;
+		      nmiss = vars[tsID][varID][levelID].nmiss;
+		      if ( nmiss > 0 )
+			for ( i = 0; i < gridsize; ++i )
+			  if ( DBL_IS_EQUAL(array[i], missval1) ) array[i] = missval2;
+		    }
+		}	  
+	    }
+	}
+
+      // printf("fmin %g fmax %g missval %g\n", fmin, fmax, vlistInqVarMissval(vlistID2, varID));
+      if ( !compute_scale(datatype, fmin, fmax, &sf, &ao) )
+	{
+	  // printf("sf = %g ao = %g \n", sf, ao);
+	  // printf("smin %g smax %g\n", (fmin - ao)/sf, (fmax -ao)/sf);
+
+	  vlistDefVarScalefactor(vlistID2, varID, sf);
+	  vlistDefVarAddoffset(vlistID2, varID, ao);
+	}
+    }
+
+  streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
+
+  streamDefVlist(streamID2, vlistID2);
+
+  for ( tsID = 0; tsID < nts; tsID++ )
+    {
+      taxisDefDTinfo(taxisID2, dtinfo[tsID]);
+      streamDefTimestep(streamID2, tsID);
+
+      for ( varID = 0; varID < nvars; varID++ )
+	{
+	  nlevel = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
+	  for ( levelID = 0; levelID < nlevel; levelID++ )
+	    {
+	      if ( vars[tsID][varID][levelID].ptr )
+		{
+		  nmiss = vars[tsID][varID][levelID].nmiss;
+		  streamDefRecord(streamID2, varID, levelID);
+		  streamWriteRecord(streamID2, vars[tsID][varID][levelID].ptr, nmiss);
+		  free(vars[tsID][varID][levelID].ptr);
+		}
+	    }
+	  free(vars[tsID][varID]);
+	}
+      free(vars[tsID]);
+    }
+
+  if ( vars  ) free(vars);
+  if ( dtinfo ) free(dtinfo);
+
+  streamClose(streamID2);
+  streamClose(streamID1);
+
+  cdoFinish();
+
+  return (0);
+}
diff --git a/src/Remap.c b/src/Remap.c
index 7c945ad..d9fcd79 100644
--- a/src/Remap.c
+++ b/src/Remap.c
@@ -1037,7 +1037,7 @@ void *Remap(void *argument)
   WRITE_REMAP:
  
   if ( lwrite_remap ) 
-    write_remap_scrip(cdoStreamName(1), map_type, submap_type, remap_order, remaps[r].grid, remaps[r].vars);
+    write_remap_scrip(cdoStreamName(1)->args, map_type, submap_type, remap_order, remaps[r].grid, remaps[r].vars);
 
   streamClose(streamID1);
 
diff --git a/src/Remapeta.c b/src/Remapeta.c
index 40ad8e8..880f1c5 100644
--- a/src/Remapeta.c
+++ b/src/Remapeta.c
@@ -264,7 +264,9 @@ void *Remapeta(void *argument)
       lfis2 = TRUE;
       fname = operatorArgv()[1];
       
-      streamID1 = streamOpenRead(fname);
+      argument_t *fileargument = file_argument_new(fname);
+      streamID1 = streamOpenRead(fileargument);
+      file_argument_free(fileargument);
 
       vlistID1 = streamInqVlist(streamID1);
 
diff --git a/src/Rhopot.c b/src/Rhopot.c
index ab25a9d..7291f4b 100644
--- a/src/Rhopot.c
+++ b/src/Rhopot.c
@@ -222,7 +222,7 @@ void *Rhopot(void *argument)
     {   
       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));
+      cdoPrint("   cdo rhopot -adisit %s %s", cdoStreamName(0)->args, cdoStreamName(1)->args);
     }
   if ( toID  == -1 ) cdoAbort("In-situ temperature not found!");
 
diff --git a/src/Rotuv.c b/src/Rotuv.c
index ddcc24f..3d0eb0c 100644
--- a/src/Rotuv.c
+++ b/src/Rotuv.c
@@ -56,11 +56,11 @@ void rot_uv_back(int gridID, double *us, double *vs)
   {
     char units[CDI_MAX_NAME];
     gridInqXunits(gridID, units);
-    gridToDegree(units, "xpole", 1, &xpole);
-    gridToDegree(units, "grid center lon", nlon, xvals);
+    grid_to_degree(units, 1, &xpole, "xpole");
+    grid_to_degree(units, nlon, xvals, "grid center lon");
     gridInqYunits(gridID, units);
-    gridToDegree(units, "ypole", 1, &ypole);
-    gridToDegree(units, "grid center lat", nlat, yvals);
+    grid_to_degree(units, 1, &ypole, "ypole");
+    grid_to_degree(units, nlat, yvals, "grid center lat");
   }
 
   for ( ilat = 0; ilat < nlat; ilat++ )
diff --git a/src/SSOpar.c b/src/SSOpar.c
index 6512428..edc8cdc 100644
--- a/src/SSOpar.c
+++ b/src/SSOpar.c
@@ -692,7 +692,7 @@ void *SSOpar(void *argument)
   int tsID, varID, levelID;
   int nvars;
   int zaxisID2, zaxisIDh = -1, nzaxis, surfaceID;
-  int ngrids, gridID, zaxisID;
+  int ngrids, gridID = -1, zaxisID;
   int nlevel;
   int nvct;
   int geopID = -1, tempID = -1, humID = -1, psID = -1, lnpsID = -1, presID = -1, clwcID = -1, ciwcID = -1;
diff --git a/src/Scatter.c b/src/Scatter.c
index 3658b7b..1ca7f3f 100644
--- a/src/Scatter.c
+++ b/src/Scatter.c
@@ -28,7 +28,7 @@ void genGrids(int gridID1, int *gridIDs, int nxvals, int nyvals, int nxblocks, i
 {
   int gridID2;
   int gridtype;
-  int gridsize, nx, ny;
+  int nx, ny;
   int gridsize2;
   int index, i, j, ix, iy, offset;
   int *xlsize = NULL, *ylsize = NULL;
@@ -38,7 +38,6 @@ void genGrids(int gridID1, int *gridIDs, int nxvals, int nyvals, int nxblocks, i
   if ( !(gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN || gridtype == GRID_GENERIC) )
     cdoAbort("Unsupported grid type: %s!", gridNamePtr(gridtype));
 
-  gridsize = gridInqSize(gridID1);
   nx = gridInqXsize(gridID1);
   ny = gridInqYsize(gridID1);
 
@@ -64,16 +63,21 @@ void genGrids(int gridID1, int *gridIDs, int nxvals, int nyvals, int nxblocks, i
     for ( ix = 0; ix < nxblocks; ++ix )
       {
 	offset = iy*nyvals*nx + ix*nxvals;
+
+	gridsize2 = xlsize[ix]*ylsize[iy];
+	gridindex[index] = (int *) malloc(gridsize2*sizeof(int));
+
 	gridsize2 = 0;
-	// printf("iy %d, ix %d offset %d\n", iy, ix,  offset);
+        // printf("iy %d, ix %d offset %d\n", iy, ix,  offset);
 	for ( j = 0; j < ylsize[iy]; ++j )
 	  {
 	    for ( i = 0; i < xlsize[ix]; ++i )
 	      {
-		//	printf(">> %d %d %d\n", j, i, offset + j*nx + i);
+	       	// printf(">> %d %d %d\n", j, i, offset + j*nx + i);
 		gridindex[index][gridsize2++] = offset + j*nx + i;
 	      }
 	  }
+	// printf("gridsize2 %d\n", gridsize2);
 
 	gridID2 = gridCreate(gridtype, gridsize2);
 	gridDefXsize(gridID2, xlsize[ix]);
@@ -96,7 +100,7 @@ void genGrids(int gridID1, int *gridIDs, int nxvals, int nyvals, int nxblocks, i
 }
 
 static
-void window_cell(double *array1, int gridID1, double *array2, long gridsize2, int *cellidx)
+void window_cell(double *array1, double *array2, long gridsize2, int *cellidx)
 {
   long i;
 
@@ -164,7 +168,7 @@ void *Scatter(void *argument)
       gridID1 = vlistGrid(vlistID1, index);
       gridtype = gridInqType(gridID1);
       if ( gridtype == GRID_LONLAT   || gridtype == GRID_GAUSSIAN ||
-	   (gridtype == GRID_GENERIC && gridInqXsize(gridID1) > 0 && gridInqYsize(gridID1) > 0) )
+	  (gridtype == GRID_GENERIC && gridInqXsize(gridID1) > 0 && gridInqYsize(gridID1) > 0) )
 	   break;
     }
 
@@ -182,8 +186,16 @@ void *Scatter(void *argument)
 	cdoAbort("Gridsize must not change!");
     }
 
-  if ( nxblocks > nx ) cdoAbort("nxblocks greater than nx!");
-  if ( nyblocks > ny ) cdoAbort("nyblocks greater than ny!");
+  if ( nxblocks > nx )
+    {
+      cdoPrint("nxblocks (%d) greater than nx (%d), set to %d!", nxblocks, nx, nx);
+      nxblocks = nx;
+    }
+  if ( nyblocks > ny )
+    {
+      cdoPrint("nyblocks (%d) greater than ny (%d), set to %d!", nyblocks, ny, ny);
+      nyblocks = ny;
+    }
 
   xinc = nx/nxblocks;
   yinc = ny/nyblocks;
@@ -194,10 +206,7 @@ void *Scatter(void *argument)
   nsplit = nxblocks*nyblocks;
   if ( nsplit > MAX_BLOCKS ) cdoAbort("Too many blocks (max = %d)!", MAX_BLOCKS);
 
-  gridsize2max = xinc*yinc;
-
   array1 = (double *) malloc(gridsize*sizeof(double));
-  array2 = (double *) malloc(gridsize2max*sizeof(double));
 
   vlistIDs  = (int *) malloc(nsplit*sizeof(int));
   streamIDs = (int *) malloc(nsplit*sizeof(int));
@@ -206,27 +215,39 @@ void *Scatter(void *argument)
   for ( i = 0; i < ngrids; i++ )
     {  
       gridID1 = vlistGrid(vlistID1, i);
-      grids[i].gridID = vlistGrid(vlistID1, i);
-      grids[i].gridIDs = (int *) malloc(nsplit*sizeof(int));
-      grids[i].gridsize = (int *) malloc(nsplit*sizeof(int));
+      grids[i].gridID    = vlistGrid(vlistID1, i);
+      grids[i].gridIDs   = (int *) malloc(nsplit*sizeof(int));
+      grids[i].gridsize  = (int *) malloc(nsplit*sizeof(int));
       grids[i].gridindex = (int **) malloc(nsplit*sizeof(int*));
-      for ( index = 0; index < nsplit; index++ )
-	grids[i].gridindex[index] = (int *) malloc(gridsize2max*sizeof(int));
+
+      for ( index = 0; index < nsplit; index++ ) grids[i].gridindex[index] = NULL;
     }
 
   for ( index = 0; index < nsplit; index++ )
     vlistIDs[index] = vlistDuplicate(vlistID1);
 
+  if ( cdoVerbose ) cdoPrint("ngrids=%d  nsplit=%d", ngrids, nsplit);
+
   for ( i = 0; i < ngrids; i++ )
     {
       gridID1 = vlistGrid(vlistID1, i);
       genGrids(gridID1, grids[i].gridIDs, xinc, yinc, nxblocks, nyblocks, grids[i].gridindex, grids[i].gridsize, nsplit);
-
+      /*
+      if ( cdoVerbose )
+	for ( index = 0; index < nsplit; index++ )
+	  cdoPrint("Block %d,  gridID %d,  gridsize %d", index+1, grids[i].gridIDs[index], gridInqSize(grids[i].gridIDs[index]));
+      */
       for ( index = 0; index < nsplit; index++ )
 	vlistChangeGridIndex(vlistIDs[index], i, grids[i].gridIDs[index]);
     }
 
-  strcpy(filename, cdoStreamName(1));
+  gridsize2max = 0;
+  for ( index = 0; index < nsplit; index++ )
+    if ( grids[0].gridsize[index] > gridsize2max ) gridsize2max = grids[0].gridsize[index];
+
+  array2 = (double *) malloc(gridsize2max*sizeof(double));
+
+  strcpy(filename, cdoStreamName(1)->args);
   nchars = strlen(filename);
 
   filesuffix[0] = 0;
@@ -237,12 +258,15 @@ void *Scatter(void *argument)
       sprintf(filename+nchars, "%05d", index);
       if ( filesuffix[0] )
 	sprintf(filename+nchars+5, "%s", filesuffix);
-      streamIDs[index] = streamOpenWrite(filename, cdoFiletype());
+
+      argument_t *fileargument = file_argument_new(filename);
+      streamIDs[index] = streamOpenWrite(fileargument, cdoFiletype());
+      file_argument_free(fileargument);
 
       streamDefVlist(streamIDs[index], vlistIDs[index]);
     }
 
-  printf("Bausstelle: i=0!\n");
+  if ( ngrids > 1 ) cdoPrint("Bausstelle: number of different grids > 1!");
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
     {
@@ -259,13 +283,13 @@ void *Scatter(void *argument)
 	  for ( index = 0; index < nsplit; index++ )
 	    {
 	      i = 0;
-	      window_cell(array1, gridID1, array2, grids[i].gridsize[index], grids[i].gridindex[index]);
+	      window_cell(array1, array2, grids[i].gridsize[index], grids[i].gridindex[index]);
 	      streamDefRecord(streamIDs[index], varID, levelID);
 	      if ( nmiss > 0 )
 		{
 		  nmiss = 0;
-		  for ( i = 0; i < grids[i].gridsize[index]; ++i )
-		    if ( DBL_IS_EQUAL(array2[i], missval) ) nmiss++;
+		  for ( int k = 0; k < grids[i].gridsize[index]; ++k )
+		    if ( DBL_IS_EQUAL(array2[k], missval) ) nmiss++;
 		}
 	      streamWriteRecord(streamIDs[index], array2, nmiss);
 	    }
diff --git a/src/Seaspctl.c b/src/Seaspctl.c
index 019402c..4c139bc 100644
--- a/src/Seaspctl.c
+++ b/src/Seaspctl.c
@@ -133,14 +133,14 @@ void *Seaspctl(void *argument)
 
       nrecs = streamInqTimestep(streamID2, otsID);
       if ( nrecs != streamInqTimestep(streamID3, otsID) )
-        cdoAbort("Number of records at time step %d of %s and %s differ!", otsID+1, cdoStreamName(1), cdoStreamName(2));
+        cdoAbort("Number of records at time step %d of %s and %s differ!", otsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args);
       
       vdate2 = taxisInqVdate(taxisID2);
       vtime2 = taxisInqVtime(taxisID2);
       vdate3 = taxisInqVdate(taxisID3);
       vtime3 = taxisInqVtime(taxisID3);
       if ( vdate2 != vdate3 || vtime2 != vtime3 )
-        cdoAbort("Verification dates at time step %d of %s and %s differ!", otsID+1, cdoStreamName(1), cdoStreamName(2));
+        cdoAbort("Verification dates at time step %d of %s and %s differ!", otsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args);
 
       for ( recID = 0; recID < nrecs; recID++ )
         {
@@ -224,9 +224,9 @@ void *Seaspctl(void *argument)
       if ( nrecs == 0 && nsets == 0 ) break;
 
       if ( vdate2 != vdate4 )
-        cdoAbort("Verification dates at time step %d of %s, %s and %s differ!", otsID+1, cdoStreamName(1), cdoStreamName(2), cdoStreamName(3));
+        cdoAbort("Verification dates at time step %d of %s, %s and %s differ!", otsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args, cdoStreamName(3)->args);
       if ( vtime2 != vtime4 )
-        cdoAbort("Verification times at time step %d of %s, %s and %s differ!", otsID+1, cdoStreamName(1), cdoStreamName(2), cdoStreamName(3));
+        cdoAbort("Verification times at time step %d of %s, %s and %s differ!", otsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args, cdoStreamName(3)->args);
 
       for ( varID = 0; varID < nvars; varID++ )
 	{
diff --git a/src/Selbox.c b/src/Selbox.c
index a91ac2e..08320bd 100644
--- a/src/Selbox.c
+++ b/src/Selbox.c
@@ -25,6 +25,7 @@
 #include <cdi.h>
 #include "cdo.h"
 #include "cdo_int.h"
+#include "grid.h"
 #include "pstream.h"
 
 
diff --git a/src/Select.c b/src/Select.c
index 3d1fa83..4f8cef0 100644
--- a/src/Select.c
+++ b/src/Select.c
@@ -27,8 +27,7 @@
 #include "pstream.h"
 #include "error.h"
 #include "util.h"
-#include "list.h"
-#include "namelist.h"
+//#include "list.h"
 
 
 #define  PML_INT         1
@@ -139,6 +138,19 @@ pml_t *pmlNew(const char *name)
 }
 
 
+void pmlDestroy(pml_t *pml)
+{
+  if ( pml == NULL ) return;
+
+  for ( int i = 0; i < pml->size; ++i )
+    {
+      if ( pml->entry[i] ) free(pml->entry[i]);
+    }
+
+  free(pml);
+}
+
+
 void pmlPrint(pml_t *pml)
 {
   pml_entry_t *entry;
@@ -224,6 +236,7 @@ int pmlNum(pml_t *pml, const char *name)
   return (nocc);
 }
 
+void split_intstring(const char *intstr, int *first, int *last, int *inc);
 
 int pml_add_entry(pml_entry_t *entry, char *arg)
 {
@@ -231,8 +244,22 @@ int pml_add_entry(pml_entry_t *entry, char *arg)
 
   if ( entry->type == PML_INT )
     {
-      if ( entry->occ < (int) entry->size )
-	((int *) entry->ptr)[entry->occ++] = atoi(arg);
+      int ival, first, last, inc;
+
+      split_intstring(arg, &first, &last, &inc);
+
+      if ( inc >= 0 )
+	{
+	  for ( ival = first; ival <= last; ival += inc )
+	    if ( entry->occ < (int) entry->size )
+	      ((int *) entry->ptr)[entry->occ++] = ival;
+	}
+      else
+	{
+	  for ( ival = first; ival >= last; ival += inc )
+	    if ( entry->occ < (int) entry->size )
+	      ((int *) entry->ptr)[entry->occ++] = ival;
+	}
     }
   else if ( entry->type == PML_FLT )
     {
@@ -466,6 +493,8 @@ void *Select(void *argument)
   PML_DEF_INT(year,     1024, "Year");
   PML_DEF_INT(month,      32, "Month");
   PML_DEF_INT(day,        32, "Day");
+  PML_DEF_INT(hour,       24, "Hour");
+  PML_DEF_INT(minute,     60, "Minute");
   PML_DEF_INT(code,     1024, "Code number");
   PML_DEF_INT(ltype,    1024, "Level type");
   PML_DEF_INT(levidx,   1024, "Level index");
@@ -477,6 +506,8 @@ void *Select(void *argument)
   PML_INIT_INT(year);
   PML_INIT_INT(month);
   PML_INIT_INT(day);
+  PML_INIT_INT(hour);
+  PML_INIT_INT(minute);
   PML_INIT_INT(code);
   PML_INIT_INT(ltype);
   PML_INIT_INT(levidx);
@@ -508,6 +539,8 @@ void *Select(void *argument)
   PML_ADD_INT(pml, year);
   PML_ADD_INT(pml, month);
   PML_ADD_INT(pml, day);
+  PML_ADD_INT(pml, hour);
+  PML_ADD_INT(pml, minute);
   PML_ADD_INT(pml, code);
   PML_ADD_INT(pml, ltype);
   PML_ADD_INT(pml, levidx);
@@ -523,6 +556,8 @@ void *Select(void *argument)
   PML_NUM(pml, year);
   PML_NUM(pml, month);
   PML_NUM(pml, day);
+  PML_NUM(pml, hour);
+  PML_NUM(pml, minute);
   PML_NUM(pml, code);
   PML_NUM(pml, ltype);
   PML_NUM(pml, levidx);
@@ -539,7 +574,7 @@ void *Select(void *argument)
   tsID2 = 0;
   for ( indf = 0; indf < nfiles; indf++ )
     {
-      if ( cdoVerbose ) cdoPrint("Process file: %s", cdoStreamName(indf));
+      if ( cdoVerbose ) cdoPrint("Process file: %s", cdoStreamName(indf)->args);
 
       streamID1 = streamOpenRead(cdoStreamName(indf));
 
@@ -669,7 +704,7 @@ void *Select(void *argument)
 	  PAR_CHECK_WORD_FLAG(name);
 	  PAR_CHECK_WORD_FLAG(param);
 
-	  if ( npar_timestep || npar_year || npar_month || npar_day ) ltimsel = TRUE;
+	  if ( npar_timestep || npar_year || npar_month || npar_day || npar_hour || npar_minute ) ltimsel = TRUE;
 
 	  npar = 0;
 	  for ( varID = 0; varID < nvars; varID++ )
@@ -773,15 +808,21 @@ void *Select(void *argument)
 
 	      if ( !copytimestep && npar_timestep == 0 )
 		{
-		  int lyear = 0, lmonth = 0, lday = 0;
+		  int lyear = 0, lmonth = 0, lday = 0, lhour = 0, lminute = 0;
+		  int second;
+
 		  vdate = taxisInqVdate(taxisID1);
 		  vtime = taxisInqVtime(taxisID1);
 		  cdiDecodeDate(vdate, &year, &month, &day);
-		  if ( npar_year  == 0 || (npar_year   && PAR_CHECK_INT(year))  ) lyear  = TRUE;
-		  if ( npar_month == 0 || (npar_month  && PAR_CHECK_INT(month)) ) lmonth = TRUE;
-		  if ( npar_day   == 0 || (npar_day    && PAR_CHECK_INT(day))   ) lday   = TRUE;
+		  cdiDecodeTime(vtime, &hour, &minute, &second);
 
-		  if ( lyear && lmonth && lday ) copytimestep = TRUE;
+		  if ( npar_year   == 0 || (npar_year   && PAR_CHECK_INT(year))   ) lyear   = TRUE;
+		  if ( npar_month  == 0 || (npar_month  && PAR_CHECK_INT(month))  ) lmonth  = TRUE;
+		  if ( npar_day    == 0 || (npar_day    && PAR_CHECK_INT(day))    ) lday    = TRUE;
+		  if ( npar_hour   == 0 || (npar_hour   && PAR_CHECK_INT(hour))   ) lhour   = TRUE;
+		  if ( npar_minute == 0 || (npar_minute && PAR_CHECK_INT(minute)) ) lminute = TRUE;
+
+		  if ( lyear && lmonth && lday && lhour && lminute ) copytimestep = TRUE;
 		}
 
 	      if ( operatorID == DELETE ) copytimestep = !copytimestep;
@@ -830,12 +871,16 @@ void *Select(void *argument)
   PAR_CHECK_INT_FLAG(year);
   PAR_CHECK_INT_FLAG(month);
   PAR_CHECK_INT_FLAG(day);
+  PAR_CHECK_INT_FLAG(hour);
+  PAR_CHECK_INT_FLAG(minute);
 
   streamClose(streamID2);
 
   vlistDestroy(vlistID0);
   vlistDestroy(vlistID2);
 
+  pmlDestroy(pml);
+
   if ( array ) free(array);
   if ( vars ) free(vars);
 
diff --git a/src/Seltime.c b/src/Seltime.c
index 1b496f0..96fcf1b 100644
--- a/src/Seltime.c
+++ b/src/Seltime.c
@@ -399,6 +399,7 @@ void *Seltime(void *argument)
       else if ( operfunc == func_date )
 	{
 	  selival = (vdate/intval)%moddat[operatorID];
+	  if ( selival < 0 ) selival = -selival;
 	}
       else if ( operfunc == func_time )
 	{
diff --git a/src/Setgrid.c b/src/Setgrid.c
index 78e802f..41a3114 100644
--- a/src/Setgrid.c
+++ b/src/Setgrid.c
@@ -99,7 +99,9 @@ void *Setgrid(void *argument)
       operatorCheckArgc(1);
       areafile = operatorArgv()[0];
 
-      streamID = streamOpenRead(areafile);
+      argument_t *fileargument = file_argument_new(areafile);
+      streamID = streamOpenRead(fileargument);
+      file_argument_free(fileargument);
 
       vlistID = streamInqVlist(streamID);
 
@@ -140,7 +142,9 @@ void *Setgrid(void *argument)
 
       operatorCheckArgc(1);
       maskfile = operatorArgv()[0];
-      streamID = streamOpenRead(maskfile);
+      argument_t *fileargument = file_argument_new(maskfile);
+      streamID = streamOpenRead(fileargument);
+      file_argument_free(fileargument);
 
       vlistID = streamInqVlist(streamID);
 
diff --git a/src/Sethalo.c b/src/Sethalo.c
index 580bb0b..33401fc 100644
--- a/src/Sethalo.c
+++ b/src/Sethalo.c
@@ -232,7 +232,7 @@ int gengrid(int gridID1, int lhalo, int rhalo)
   gridDefYlongname(gridID2, ylongname);
   gridDefYunits(gridID2, yunits);
 
-  if ( memcmp(xunits, "degree", 6) == 0 ) cpi2 *= rad2deg;
+  if ( memcmp(xunits, "degree", 6) == 0 ) cpi2 *= RAD2DEG;
 
   if ( gridInqXvals(gridID1, NULL) && gridInqYvals(gridID1, NULL) )
     {
diff --git a/src/Sinfo.c b/src/Sinfo.c
index 9dfd6fa..24cee62 100644
--- a/src/Sinfo.c
+++ b/src/Sinfo.c
@@ -108,33 +108,20 @@ void *Sinfo(void *argument)
 
       vlistID = streamInqVlist(streamID);
 
-      printf("   File format: ");
+      fprintf(stdout, "   File format: ");
       printFiletype(streamID, vlistID);
 
       if ( lensemble )
-	{
-	  if ( operfunc == func_name )
-	    fprintf(stdout,
-		    "%6d : Institut Source   Ttype    Einfo Levels Num  Gridsize Num Dtype : Parameter name\n",  -(indf+1));
-	  else if ( operfunc == func_code )
-	    fprintf(stdout,
-		    "%6d : Institut Source   Ttype    Einfo Levels Num  Gridsize Num Dtype : Table Code\n",  -(indf+1));
-	  else
-	    fprintf(stdout,
-		    "%6d : Institut Source   Ttype    Einfo Levels Num  Gridsize Num Dtype : Parameter ID\n",  -(indf+1));
-	}
+	fprintf(stdout, "%6d : Institut Source   Ttype    Einfo Levels Num  Gridsize Num Dtype : ",  -(indf+1));
       else
-	{
-	  if ( operfunc == func_name )
-	    fprintf(stdout,
-		    "%6d : Institut Source   Ttype    Levels Num  Gridsize Num Dtype : Parameter name\n",  -(indf+1));
-	  else if ( operfunc == func_code )
-	    fprintf(stdout,
-		    "%6d : Institut Source   Ttype    Levels Num  Gridsize Num Dtype : Table Code\n",  -(indf+1));
-	  else
-	    fprintf(stdout,
-		    "%6d : Institut Source   Ttype    Levels Num  Gridsize Num Dtype : Parameter ID\n",  -(indf+1));
-	}
+	fprintf(stdout, "%6d : Institut Source   Ttype    Levels Num  Gridsize Num Dtype : ",  -(indf+1));
+
+      if      ( operfunc == func_name ) fprintf(stdout, "Parameter name");
+      else if ( operfunc == func_code ) fprintf(stdout, "Table Code");
+      else                              fprintf(stdout, "Parameter ID");
+
+      if ( cdoVerbose ) fprintf(stdout, " : Extra" );              
+      fprintf(stdout, "\n" );              
 
       nvars = vlistNvars(vlistID);
 
@@ -222,11 +209,18 @@ void *Sinfo(void *argument)
 	  if ( operfunc == func_name ) vlistInqVarName(vlistID, varID, varname);
 
 	  if ( operfunc == func_name )
-	    fprintf(stdout, "%-11s", varname);
+	    fprintf(stdout, "%-14s", varname);
 	  else if ( operfunc == func_code )
-	    fprintf(stdout, "%4d %4d", tabnum, code);
+	    fprintf(stdout, "%4d %4d   ", tabnum, code);
 	  else
-	    fprintf(stdout, "%-11s", paramstr);
+	    fprintf(stdout, "%-14s", paramstr);
+
+	  if ( cdoVerbose )
+	    {
+	      char varextra[CDI_MAX_NAME];
+	      vlistInqVarExtra(vlistID, varID, varextra);
+	      fprintf(stdout, " : %s", varextra );              
+	    }
 
 	  fprintf(stdout, "\n");
 	}
diff --git a/src/Split.c b/src/Split.c
index 2637436..5acb176 100644
--- a/src/Split.c
+++ b/src/Split.c
@@ -97,7 +97,7 @@ void *Split(void *argument)
 
   if ( swap_obase == 0 )
     {
-      strcpy(filename, cdoStreamName(1));
+      strcpy(filename, cdoStreamName(1)->args);
       nchars = strlen(filename);
     }
 
@@ -151,20 +151,22 @@ void *Split(void *argument)
 	  if ( codes[index] > 9999 )
 	    {
 	      sprintf(filename+nchars, "%05d", codes[index]);
-	      gen_filename(filename, swap_obase, cdoStreamName(1), filesuffix);
+	      gen_filename(filename, swap_obase, cdoStreamName(1)->args, filesuffix);
 	    }
 	  else if ( codes[index] > 999 )
 	    {
 	      sprintf(filename+nchars, "%04d", codes[index]);
-	      gen_filename(filename, swap_obase, cdoStreamName(1), filesuffix);
+	      gen_filename(filename, swap_obase, cdoStreamName(1)->args, filesuffix);
 	    }
 	  else
 	    {
 	      sprintf(filename+nchars, "%03d", codes[index]);
-	      gen_filename(filename, swap_obase, cdoStreamName(1), filesuffix);
+	      gen_filename(filename, swap_obase, cdoStreamName(1)->args, filesuffix);
 	    }
 
-	  streamIDs[index] = streamOpenWrite(filename, cdoFiletype());
+	  argument_t *fileargument = file_argument_new(filename);
+	  streamIDs[index] = streamOpenWrite(fileargument, cdoFiletype());
+	  file_argument_free(fileargument);
 
 	  streamDefVlist(streamIDs[index], vlistIDs[index]);
 	}
@@ -219,9 +221,11 @@ void *Split(void *argument)
 
 	  filename[nchars] = '\0';
 	  strcat(filename, paramstr);
-	  gen_filename(filename, swap_obase, cdoStreamName(1), filesuffix);
+	  gen_filename(filename, swap_obase, cdoStreamName(1)->args, filesuffix);
 
-	  streamIDs[index] = streamOpenWrite(filename, cdoFiletype());
+	  argument_t *fileargument = file_argument_new(filename);
+	  streamIDs[index] = streamOpenWrite(fileargument, cdoFiletype());
+	  file_argument_free(fileargument);
 
 	  streamDefVlist(streamIDs[index], vlistIDs[index]);
 	}
@@ -271,9 +275,11 @@ void *Split(void *argument)
 	  vlistIDs[index] = vlistID2;
 
 	  sprintf(filename+nchars, "%03d", tabnums[index]);
-	  gen_filename(filename, swap_obase, cdoStreamName(1), filesuffix);
+	  gen_filename(filename, swap_obase, cdoStreamName(1)->args, filesuffix);
 
-	  streamIDs[index] = streamOpenWrite(filename, cdoFiletype());
+	  argument_t *fileargument = file_argument_new(filename);
+	  streamIDs[index] = streamOpenWrite(fileargument, cdoFiletype());
+	  file_argument_free(fileargument);
 
 	  streamDefVlist(streamIDs[index], vlistIDs[index]);
 	}
@@ -306,9 +312,11 @@ void *Split(void *argument)
 	  filename[nchars] = '\0';
 	  vlistInqVarName(vlistID1, varID, varname);
 	  strcat(filename, varname);
-	  gen_filename(filename, swap_obase, cdoStreamName(1), filesuffix);
+	  gen_filename(filename, swap_obase, cdoStreamName(1)->args, filesuffix);
 
-	  streamIDs[index] = streamOpenWrite(filename, cdoFiletype());
+	  argument_t *fileargument = file_argument_new(filename);
+	  streamIDs[index] = streamOpenWrite(fileargument, cdoFiletype());
+	  file_argument_free(fileargument);
 
 	  streamDefVlist(streamIDs[index], vlistID2);
 	}
@@ -359,9 +367,11 @@ void *Split(void *argument)
 	  vlistIDs[index] = vlistID2;
 
 	  sprintf(filename+nchars, "%06g", levels[index]);
-	  gen_filename(filename, swap_obase, cdoStreamName(1), filesuffix);
+	  gen_filename(filename, swap_obase, cdoStreamName(1)->args, filesuffix);
    
-	  streamIDs[index] = streamOpenWrite(filename, cdoFiletype());
+	  argument_t *fileargument = file_argument_new(filename);
+	  streamIDs[index] = streamOpenWrite(fileargument, cdoFiletype());
+	  file_argument_free(fileargument);
 
 	  streamDefVlist(streamIDs[index], vlistID2);
 	}
@@ -402,9 +412,11 @@ void *Split(void *argument)
 	  vlistIDs[index] = vlistID2;
 
 	  sprintf(filename+nchars, "%02d", vlistGridIndex(vlistID1, gridIDs[index])+1);
-	  gen_filename(filename, swap_obase, cdoStreamName(1), filesuffix);
+	  gen_filename(filename, swap_obase, cdoStreamName(1)->args, filesuffix);
 
-	  streamIDs[index] = streamOpenWrite(filename, cdoFiletype());
+	  argument_t *fileargument = file_argument_new(filename);
+	  streamIDs[index] = streamOpenWrite(fileargument, cdoFiletype());
+	  file_argument_free(fileargument);
 
 	  streamDefVlist(streamIDs[index], vlistID2);
 	}
@@ -444,9 +456,11 @@ void *Split(void *argument)
 	  vlistIDs[index] = vlistID2;
 
 	  sprintf(filename+nchars, "%02d", vlistZaxisIndex(vlistID1, zaxisIDs[index])+1);
-	  gen_filename(filename, swap_obase, cdoStreamName(1), filesuffix);
+	  gen_filename(filename, swap_obase, cdoStreamName(1)->args, filesuffix);
 
-	  streamIDs[index] = streamOpenWrite(filename, cdoFiletype());
+	  argument_t *fileargument = file_argument_new(filename);
+	  streamIDs[index] = streamOpenWrite(fileargument, cdoFiletype());
+	  file_argument_free(fileargument);
 
 	  streamDefVlist(streamIDs[index], vlistID2);
 	}
diff --git a/src/Splitrec.c b/src/Splitrec.c
index 6a9bb42..cf2b1e7 100644
--- a/src/Splitrec.c
+++ b/src/Splitrec.c
@@ -54,7 +54,7 @@ void *Splitrec(void *argument)
 
   nrecs  = vlistNrecs(vlistID1);
 
-  strcpy(filename, cdoStreamName(1));
+  strcpy(filename, cdoStreamName(1)->args);
   nchars = strlen(filename);
 
   filesuffix[0] = 0;
@@ -88,7 +88,9 @@ void *Splitrec(void *argument)
 
 	  if ( cdoVerbose ) cdoPrint("create file %s", filename);
 
-	  streamID2 = streamOpenWrite(filename, cdoFiletype());
+	  argument_t *fileargument = file_argument_new(filename);
+	  streamID2 = streamOpenWrite(fileargument, cdoFiletype());
+	  file_argument_free(fileargument);
 
 	  streamDefVlist(streamID2, vlistID2);
 
diff --git a/src/Splitsel.c b/src/Splitsel.c
index 6ffb8fc..4da1476 100644
--- a/src/Splitsel.c
+++ b/src/Splitsel.c
@@ -94,7 +94,7 @@ void *Splitsel(void *argument)
   taxisID2 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
-  strcpy(filename, cdoStreamName(1));
+  strcpy(filename, cdoStreamName(1)->args);
   nchars = strlen(filename);
 
   filesuffix[0] = 0;
@@ -163,7 +163,9 @@ void *Splitsel(void *argument)
       sprintf(filename+nchars+6, "%s", filesuffix);
 	  
       if ( cdoVerbose ) cdoPrint("create file %s", filename);
-      streamID2 = streamOpenWrite(filename, cdoFiletype());
+      argument_t *fileargument = file_argument_new(filename);
+      streamID2 = streamOpenWrite(fileargument, cdoFiletype());
+      file_argument_free(fileargument);
 
       streamDefVlist(streamID2, vlistID2);
 
diff --git a/src/Splittime.c b/src/Splittime.c
index 0054469..4d9bdfc 100644
--- a/src/Splittime.c
+++ b/src/Splittime.c
@@ -90,7 +90,7 @@ void *Splittime(void *argument)
   taxisID2 = taxisDuplicate(taxisID1);
   vlistDefTaxis(vlistID2, taxisID2);
 
-  strcpy(filename, cdoStreamName(1));
+  strcpy(filename, cdoStreamName(1)->args);
   nchars = strlen(filename);
 
   filesuffix[0] = 0;
@@ -140,6 +140,7 @@ void *Splittime(void *argument)
       if ( operfunc == func_date )
 	{
 	  index = (vdate/operintval)%100;
+	  if ( index < 0 ) index = -index;
 
 	  if ( operatorID == SPLITSEAS )
 	    {
@@ -191,7 +192,9 @@ void *Splittime(void *argument)
 
 	  if ( cdoVerbose ) cdoPrint("create file %s", filename);
 
-	  streamID2 = streamOpenWrite(filename, cdoFiletype());
+	  argument_t *fileargument = file_argument_new(filename);
+	  streamID2 = streamOpenWrite(fileargument, cdoFiletype());
+	  file_argument_free(fileargument);
 
 	  streamDefVlist(streamID2, vlistID2);
 
diff --git a/src/Splityear.c b/src/Splityear.c
index 885405b..a5c8eb3 100644
--- a/src/Splityear.c
+++ b/src/Splityear.c
@@ -62,7 +62,7 @@ void *Splityear(void *argument)
   vlistID1 = streamInqVlist(streamID1);
   vlistID2 = vlistDuplicate(vlistID1);
 
-  strcpy(filename, cdoStreamName(1));
+  strcpy(filename, cdoStreamName(1)->args);
   nchars = strlen(filename);
 
   filesuffix[0] = 0;
@@ -112,7 +112,9 @@ void *Splityear(void *argument)
 	  
 	  if ( cdoVerbose ) cdoPrint("create file %s", filename);
 
-	  streamID2 = streamOpenWrite(filename, cdoFiletype());
+	  argument_t *fileargument = file_argument_new(filename);
+	  streamID2 = streamOpenWrite(fileargument, cdoFiletype());
+	  file_argument_free(fileargument);
 
 	  streamDefVlist(streamID2, vlistID2);
 	}
diff --git a/src/Timpctl.c b/src/Timpctl.c
index 2035fea..b96c228 100644
--- a/src/Timpctl.c
+++ b/src/Timpctl.c
@@ -133,14 +133,14 @@ void timpctl(int operatorID)
       
       nrecs = streamInqTimestep(streamID2, otsID);
       if ( nrecs != streamInqTimestep(streamID3, otsID) )
-        cdoAbort("Number of records at time step %d of %s and %s differ!", otsID+1, cdoStreamName(1), cdoStreamName(2));
+        cdoAbort("Number of records at time step %d of %s and %s differ!", otsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args);
 
       vdate2 = taxisInqVdate(taxisID2);
       vtime2 = taxisInqVtime(taxisID2);
       vdate3 = taxisInqVdate(taxisID3);
       vtime3 = taxisInqVtime(taxisID3);
       if ( vdate2 != vdate3 || vtime2 != vtime3 )
-        cdoAbort("Verification dates at time step %d of %s and %s differ!", otsID+1, cdoStreamName(1), cdoStreamName(2));
+        cdoAbort("Verification dates at time step %d of %s and %s differ!", otsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args);
       
       for ( recID = 0; recID < nrecs; recID++ )
         {
@@ -193,9 +193,11 @@ void timpctl(int operatorID)
       if ( nrecs == 0 && nsets == 0 ) break;
 
       if ( vdate2 != vdate4 )
-        cdoAbort("Verification dates at time step %d of %s, %s and %s differ!", otsID+1, cdoStreamName(1), cdoStreamName(2), cdoStreamName(3));
+        cdoAbort("Verification dates at time step %d of %s, %s and %s differ!",
+		 otsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args, cdoStreamName(3)->args);
       if ( vtime2 != vtime4 )
-        cdoAbort("Verification times at time step %d of %s, %s and %s differ!", otsID+1, cdoStreamName(1), cdoStreamName(2), cdoStreamName(3));
+        cdoAbort("Verification times at time step %d of %s, %s and %s differ!",
+		 otsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args, cdoStreamName(3)->args);
       
       for ( varID = 0; varID < nvars; varID++ )
 	{
diff --git a/src/Timselpctl.c b/src/Timselpctl.c
index 3b99988..8ffd9ea 100644
--- a/src/Timselpctl.c
+++ b/src/Timselpctl.c
@@ -158,14 +158,14 @@ void *Timselpctl(void *argument)
     {
       nrecs = streamInqTimestep(streamID2, otsID);
       if ( nrecs != streamInqTimestep(streamID3, otsID) )
-        cdoAbort("Number of records at time step %d of %s and %s differ!", otsID+1, cdoStreamName(1), cdoStreamName(2));
+        cdoAbort("Number of records at time step %d of %s and %s differ!", otsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args);
 
       vdate2 = taxisInqVdate(taxisID2);
       vtime2 = taxisInqVtime(taxisID2);
       vdate3 = taxisInqVdate(taxisID3);
       vtime3 = taxisInqVtime(taxisID3);
       if ( vdate2 != vdate3 || vtime2 != vtime3 )
-        cdoAbort("Verification dates at time step %d of %s and %s differ!", otsID+1, cdoStreamName(1), cdoStreamName(2));
+        cdoAbort("Verification dates at time step %d of %s and %s differ!", otsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args);
       
       for ( recID = 0; recID < nrecs; recID++ )
         {
@@ -218,10 +218,10 @@ void *Timselpctl(void *argument)
 
       if ( vdate2 != vdate4 )
         cdoAbort("Verification dates at time step %d of %s, %s and %s differ!",
-		 otsID+1, cdoStreamName(1), cdoStreamName(2), cdoStreamName(3));
+		 otsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args, cdoStreamName(3)->args);
       if ( vtime2 != vtime4 )
         cdoAbort("Verification times at time step %d of %s, %s and %s differ!",
-		 otsID+1, cdoStreamName(1), cdoStreamName(2), cdoStreamName(3));
+		 otsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args, cdoStreamName(3)->args);
 
       for ( varID = 0; varID < nvars; varID++ )
         {
diff --git a/src/Timstat.c b/src/Timstat.c
index 3cffe70..a015944 100644
--- a/src/Timstat.c
+++ b/src/Timstat.c
@@ -203,8 +203,10 @@ void *Timstat(void *argument)
 
       strcpy(filename, cdoOperatorName(operatorID));
       strcat(filename, "_");
-      strcat(filename, cdoStreamName(1));
-      streamID3 = streamOpenWrite(filename, cdoFiletype());
+      strcat(filename, cdoStreamName(1)->args);
+      argument_t *fileargument = file_argument_new(filename);
+      streamID3 = streamOpenWrite(fileargument, cdoFiletype());
+      file_argument_free(fileargument);
 
       vlistID3 = vlistDuplicate(vlistID1);
 
diff --git a/src/Vargen.c b/src/Vargen.c
index 2b63235..4bfe782 100644
--- a/src/Vargen.c
+++ b/src/Vargen.c
@@ -100,7 +100,6 @@ void *Vargen(void *argument)
   double rval, rstart = 0, rstop = 0, rinc = 0;
   double rconst = 0;
   double *array, *levels = NULL;
-  LIST *flist = listNew(FLT_LIST);
 
   cdoInitialize(argument);
 
@@ -188,10 +187,12 @@ void *Vargen(void *argument)
   else if ( operatorID == STDATM )
     {
       double lon = 0, lat = 0;
+      LIST *flist = listNew(FLT_LIST);
 
       operatorInputArg("levels");
       nlevels = args2fltlist(operatorArgc(), operatorArgv(), flist);
       levels  = (double *) listArrayPtr(flist);
+      //listDelete(flist);
 
       if ( cdoVerbose ) for ( i = 0; i < nlevels; ++i ) printf("levels %d: %g\n", i, levels[i]);
 
diff --git a/src/Writegrid.c b/src/Writegrid.c
index 26b7718..92010fb 100644
--- a/src/Writegrid.c
+++ b/src/Writegrid.c
@@ -66,7 +66,7 @@ void *Writegrid(void *argument)
       for ( i = 0; i < gridsize; i++ ) mask[i] = 1;
     }
       
-  writeNCgrid(cdoStreamName(1), gridID, mask);
+  writeNCgrid(cdoStreamName(1)->args, gridID, mask);
 
   streamClose(streamID);
 
diff --git a/src/YAR.c b/src/YAR.c
index 78e60a5..51c073c 100644
--- a/src/YAR.c
+++ b/src/YAR.c
@@ -20,16 +20,75 @@
 #include "cdo_int.h"
 #include "pstream.h"
 #include "interpol.h"
+#include "grid.h"
+#include "remap.h"
 
 #if defined (HAVE_LIBYAC)
 #include "points.h"
 #include "grid_reg2d.h"
+#include "grid_search.h"
+#include "bucket_search.h"
 #include "event.h"
 #include "search.h"
 #include "clipping.h"
 #endif
 
-int lout = 1;
+int timer_yar_remap, timer_yar_remap_init, timer_yar_remap_sort, timer_yar_remap_con, timer_yar_remap_bil;
+
+
+void yar_remap(double *restrict dst_array, double missval, long dst_size, long num_links, double *restrict map_wts, 
+	       long num_wts, const int *restrict dst_add, const int *restrict src_add, const double *restrict src_array)
+{
+  long n;
+
+  for ( n = 0; n < dst_size; ++n ) dst_array[n] = missval;
+
+  for ( n = 0; n < num_links; ++n ) dst_array[dst_add[n]] = 0;
+
+  for ( n = 0; n < num_links; ++n )
+    {
+      
+      //printf("%5d %5d %5d %g # dst_add src_add n\n", dst_add[n], src_add[n], n, map_wts[n]);
+      
+      //dst_array[dst_add[n]] += src_array[src_add[n]]*map_wts[num_wts*n];
+      dst_array[dst_add[n]] += src_array[src_add[n]]*map_wts[n];
+    }
+  //for ( n = 0; n < 10; ++n ) printf("array1 %d %g\n", n, src_array[n]);
+  //for ( n = 0; n < 10; ++n ) printf("array2 %d %g\n", n, dst_array[n]);
+}
+
+
+void yar_store_link_cnsrv(remapvars_t *rv, long add1, long add2, double weight)
+{
+  /*
+    Input variables:
+    int  add1         ! address on grid1
+    int  add2         ! address on grid2
+    double weight     ! remapping weight for this link
+  */
+  /* Local variables */
+  long nlink; /* link index */
+
+  /*  If the weight is ZERO, do not bother storing the link */
+
+  if ( IS_EQUAL(weight, 0) ) return;
+
+  /*
+     If the link does not yet exist, increment number of links and 
+     check to see if remap arrays need to be increased to accomodate 
+     the new link. Then store the link.
+  */
+  nlink = rv->num_links;
+
+  rv->num_links++;
+  if ( rv->num_links >= rv->max_links )
+    resize_remap_vars(rv, rv->resize_increment);
+
+  rv->grid1_add[nlink] = add1;
+  rv->grid2_add[nlink] = add2;
+
+  rv->wts[nlink] = weight;
+}
 
 static
 void gen_xbounds(int nx, double *xvals, double *xbounds)
@@ -80,13 +139,83 @@ void set_source_data(double * source_data, double init_value,
 }
 
 
-int grid_search( int *restrict src_add, double *restrict src_lats, 
-		double *restrict src_lons, double plat, double plon, const int *restrict src_grid_dims)
+static
+long find_ij_weights(double plon, double plat, double *restrict src_lats, double *restrict src_lons,
+		     double *ig, double *jg)
 {
-  return 0;
+#define  TWO      2.0
+#define  THREE    3.0
+#define  HALF     0.5
+#define  PI       M_PI
+#define  PI2      TWO*PI
+#define  PIH      HALF*PI
+  long    Max_Iter = 100;
+  double  converge = 1.e-10;            /* Convergence criterion */
+  long iter;                     /*  iteration counters   */
+  double iguess, jguess;         /*  current guess for bilinear coordinate  */
+  double deli, delj;             /*  corrections to i,j                     */
+  double dth1, dth2, dth3;       /*  some latitude  differences             */
+  double dph1, dph2, dph3;       /*  some longitude differences             */
+  double dthp, dphp;             /*  difference between point and sw corner */
+  double mat1, mat2, mat3, mat4; /*  matrix elements                        */
+  double determinant;            /*  matrix determinant                     */
+
+  /* Iterate to find i,j for bilinear approximation  */
+
+  dth1 = src_lats[1] - src_lats[0];
+  dth2 = src_lats[3] - src_lats[0];
+  dth3 = src_lats[2] - src_lats[1] - dth2;
+
+  dph1 = src_lons[1] - src_lons[0];
+  dph2 = src_lons[3] - src_lons[0];
+  dph3 = src_lons[2] - src_lons[1];
+
+  if ( dph1 >  THREE*PIH ) dph1 -= PI2;
+  if ( dph2 >  THREE*PIH ) dph2 -= PI2;
+  if ( dph3 >  THREE*PIH ) dph3 -= PI2;
+  if ( dph1 < -THREE*PIH ) dph1 += PI2;
+  if ( dph2 < -THREE*PIH ) dph2 += PI2;
+  if ( dph3 < -THREE*PIH ) dph3 += PI2;
+
+  dph3 = dph3 - dph2;
+
+  iguess = HALF;
+  jguess = HALF;
+
+  for ( iter = 0; iter < Max_Iter; ++iter )
+    {
+      dthp = plat - src_lats[0] - dth1*iguess - dth2*jguess - dth3*iguess*jguess;
+      dphp = plon - src_lons[0];
+      
+      if ( dphp >  THREE*PIH ) dphp -= PI2;
+      if ( dphp < -THREE*PIH ) dphp += PI2;
+
+      dphp = dphp - dph1*iguess - dph2*jguess - dph3*iguess*jguess;
+
+      mat1 = dth1 + dth3*jguess;
+      mat2 = dth2 + dth3*iguess;
+      mat3 = dph1 + dph3*jguess;
+      mat4 = dph2 + dph3*iguess;
+
+      determinant = mat1*mat4 - mat2*mat3;
+
+      deli = (dthp*mat4 - dphp*mat2)/determinant;
+      delj = (dphp*mat1 - dthp*mat3)/determinant;
+
+      if ( fabs(deli) < converge && fabs(delj) < converge ) break;
+
+      iguess += deli;
+      jguess += delj;
+    }
+
+  *ig = iguess;
+  *jg = jguess;
+
+  return (iter);
 }
 
-void testint_p(field_t *field1, field_t *field2)
+
+void yar_remap_bil(field_t *field1, field_t *field2)
 {
   int nlonIn, nlatIn;
   int nlonOut, nlatOut;
@@ -96,23 +225,39 @@ void testint_p(field_t *field1, field_t *field2)
   int gridsize1, gridsize2;
   double *lonIn, *latIn;
   double *lonOut, *latOut;
+  double *xlonIn, *xlatIn;
+  double *xlonOut, *xlatOut;
   double **fieldIn;
   double **field;
   double *array = NULL;
-  double *arrayIn, *arrayOut;
+  double *array1, *array2;
   double missval;
   int testit = 1;
+  double dxIn, dxOut;
+  remap_t remap;
   /* static int index = 0; */
 
   gridIDin  = field1->grid;
   gridIDout = field2->grid;
-  arrayIn   = field1->ptr;
-  arrayOut  = field2->ptr;
+  array1    = field1->ptr;
+  array2    = field2->ptr;
   missval   = field1->missval;
 
   if ( ! (gridInqXvals(gridIDin, NULL) && gridInqYvals(gridIDin, NULL)) )
     cdoAbort("Source grid has no values");
 
+  remap.grid.restrict_type = 0;
+  remap.grid.num_srch_bins = 0;
+  remap.grid.pinit = FALSE;
+  remap.vars.pinit = FALSE;
+
+  if ( cdoTimer ) timer_start(timer_yar_remap_init);
+  remapGridInit(MAP_TYPE_BILINEAR, 0, gridIDin, gridIDout, &remap.grid);
+  remapVarsInit(MAP_TYPE_BILINEAR, &remap.grid, &remap.vars);
+  if ( cdoTimer ) timer_stop(timer_yar_remap_init);
+
+
+  if ( cdoTimer ) timer_start(timer_yar_remap_init);
   nlonIn = gridInqXsize(gridIDin);
   nlatIn = gridInqYsize(gridIDin);
   gridsize1 = gridInqSize(gridIDin);
@@ -120,7 +265,21 @@ void testint_p(field_t *field1, field_t *field2)
   latIn = (double *) malloc(nlatIn*sizeof(double));
   gridInqXvals(gridIDin, lonIn);
   gridInqYvals(gridIDin, latIn);
+  for ( int i = 0; i < nlonIn; ++i ) lonIn[i] *= DEG2RAD;
+  for ( int i = 0; i < nlatIn; ++i ) latIn[i] *= DEG2RAD;
 
+  xlonIn = (double *) malloc((nlonIn+1)*sizeof(double));
+  xlatIn = (double *) malloc((nlatIn+1)*sizeof(double));
+  gridInqXvals(gridIDin, xlonIn);
+  gridInqYvals(gridIDin, xlatIn);
+  dxIn = xlonIn[1] - xlonIn[0];
+  for ( int i = 0; i < nlonIn; ++i ) xlonIn[i] -= dxIn/2;
+  for ( int i = 0; i < nlatIn; ++i ) xlatIn[i] -= dxIn/2;
+  for ( int i = 0; i < nlonIn; ++i ) xlonIn[i] *= DEG2RAD;
+  for ( int i = 0; i < nlatIn; ++i ) xlatIn[i] *= DEG2RAD;
+  xlonIn[nlonIn] = xlonIn[nlonIn-1]+dxIn*DEG2RAD;
+  xlatIn[nlatIn] = -xlatIn[0];
+ 
   if ( ! (gridInqXvals(gridIDout, NULL) && gridInqYvals(gridIDout, NULL)) )
     cdoAbort("Target grid has no values");
 
@@ -131,6 +290,29 @@ void testint_p(field_t *field1, field_t *field2)
   latOut = (double *) malloc(nlatOut*sizeof(double));
   gridInqXvals(gridIDout, lonOut);
   gridInqYvals(gridIDout, latOut);
+  for ( int i = 0; i < nlonOut; ++i ) lonOut[i] *= DEG2RAD;
+  for ( int i = 0; i < nlatOut; ++i ) latOut[i] *= DEG2RAD;
+
+  xlonOut = (double *) malloc((nlonOut+1)*sizeof(double));
+  xlatOut = (double *) malloc((nlatOut+1)*sizeof(double));
+  gridInqXvals(gridIDout, xlonOut);
+  gridInqYvals(gridIDout, xlatOut);
+  dxOut = xlonOut[1] - xlonOut[0];
+  for ( int i = 0; i < nlonOut; ++i ) xlonOut[i] -= dxOut/2;
+  for ( int i = 0; i < nlatOut; ++i ) xlatOut[i] -= dxOut/2;
+  for ( int i = 0; i < nlonOut; ++i ) xlonOut[i] *= DEG2RAD;
+  for ( int i = 0; i < nlatOut; ++i ) xlatOut[i] *= DEG2RAD;
+  xlonOut[nlonOut] = xlonOut[nlonOut-1]+dxOut*DEG2RAD;
+  xlatOut[nlatOut] = xlatOut[0];
+
+  printf("source grid: inc = %g  nlon = %d  nlat = %d\n", dxIn, nlonIn, nlatIn);
+  printf("target grid: inc = %g  nlon = %d  nlat = %d\n", dxOut, nlonOut, nlatOut);
+
+  printf("lonIn: %g %g %g ... %g %g\n", lonIn[0]/DEG2RAD, lonIn[1]/DEG2RAD, lonIn[2]/DEG2RAD, lonIn[nlonIn-2]/DEG2RAD, lonIn[nlonIn-1]/DEG2RAD);
+  printf("latIn: %g %g %g ... %g %g\n", latIn[0]/DEG2RAD, latIn[1]/DEG2RAD, latIn[2]/DEG2RAD, latIn[nlatIn-2]/DEG2RAD, latIn[nlatIn-1]/DEG2RAD);
+
+  printf("lonOut: %g %g %g ... %g %g\n", lonOut[0]/DEG2RAD, lonOut[1]/DEG2RAD, lonOut[2]/DEG2RAD, lonOut[nlonOut-2]/DEG2RAD, lonOut[nlonOut-1]/DEG2RAD);
+  printf("latOut: %g %g %g ... %g %g\n", latOut[0]/DEG2RAD, latOut[1]/DEG2RAD, latOut[2]/DEG2RAD, latOut[nlatOut-2]/DEG2RAD, latOut[nlatOut-1]/DEG2RAD);
 
 #if defined (HAVE_LIBYAC)
 
@@ -145,44 +327,45 @@ void testint_p(field_t *field1, field_t *field2)
   num_target_cells[1] = nlatOut;
 
   unsigned cyclic[2] = {0,0};
-  struct grid source_grid, target_grid;
+  struct grid *source_grid;
 
-  init_reg2d_grid(&source_grid, NULL, NULL, num_source_cells, cyclic);
-  init_reg2d_grid(&target_grid, NULL, NULL, num_target_cells, cyclic);
+  source_grid = reg2d_grid_new(xlonIn, xlatIn, num_source_cells, cyclic);
 
-  struct points source_points, target_points;
+  if ( cdoTimer ) timer_stop(timer_yar_remap_init);
+
+  struct points source_points;
 
   //--------------------------------------------
   // define points
   //--------------------------------------------
-  init_points(&source_points, &source_grid, CELL, lonIn, latIn);
-  init_points(&target_points, &target_grid, CELL, lonOut, latOut);
+  init_points(&source_points, source_grid, CELL, lonIn, latIn);
 
   //--------------------------------------------
   // initialise interpolation
   //--------------------------------------------
 
-  struct dep_list tgt_to_src_cell;
+  struct dep_list deps;
   unsigned search_id;
   //struct interpolation interpolation;
 
-  // seg fault:  printf("src num_grid_corners %d\n", get_num_grid_corners(*get_point_grid(&source_grid)));
-  // seg fault:  printf("tgt num_grid_corners %d\n", get_num_grid_corners(*get_point_grid(&target_grid)));
-  printf("src num_grid_corners %d\n", get_num_grid_corners(*get_point_grid(&source_points)));
-  printf("tgt num_grid_corners %d\n", get_num_grid_corners(*get_point_grid(&target_points)));
+  printf("src num_grid_corners %d\n", get_num_grid_corners(get_point_grid(&source_points)));
 
-  search_id = search_init(get_point_grid(&source_points));
- 
-  do_point_search_p(*get_point_grid(&target_points), search_id, &tgt_to_src_cell);
+  // search_id = search_init(get_point_grid(&source_points));
+  struct grid_search *search;
+  unsigned const * curr_src_corners;
 
-  printf("total_num_dependencies: %d\n", get_total_num_dependencies(tgt_to_src_cell));
+  if ( cdoTimer ) timer_start(timer_yar_remap_bil);
+
+  search = bucket_search_new(source_grid);
+  /*
+
+  printf("total_num_dependencies: %d\n", get_total_num_dependencies(deps));
 
-  unsigned const * curr_src_corners;
   for ( int i = 0; i < 10; ++i )
     {
-      printf("num_deps_per_element %d %d\n", i, tgt_to_src_cell.num_deps_per_element[i]);
-      curr_src_corners = get_dependencies_of_element(tgt_to_src_cell,i);
-      for ( int k = 0; k < tgt_to_src_cell.num_deps_per_element[i]; ++k )
+      printf("num_deps_per_element %d %d\n", i, deps.num_deps_per_element[i]);
+      curr_src_corners = get_dependencies_of_element(deps,i);
+      for ( int k = 0; k < deps.num_deps_per_element[i]; ++k )
 	printf("  curr_src_corners: %d %d\n", k, curr_src_corners[k]);
     }
 
@@ -190,31 +373,84 @@ void testint_p(field_t *field1, field_t *field2)
     {
       double lon = lonOut[i];
       double lat = latOut[i];
-      printf("num_deps_per_element %d %d\n", i, tgt_to_src_cell.num_deps_per_element[i]);
-      curr_src_corners = get_dependencies_of_element(tgt_to_src_cell,i);
-      for ( int k = 0; k < tgt_to_src_cell.num_deps_per_element[i]; ++k )
+      printf("num_deps_per_element %d %d\n", i, deps.num_deps_per_element[i]);
+      curr_src_corners = get_dependencies_of_element(deps,i);
+      for ( int k = 0; k < deps.num_deps_per_element[i]; ++k )
 	printf("  curr_src_corners: %d %d\n", k, curr_src_corners[k]);
     }
-
+  */
   for ( int i = 0; i < gridsize2; ++i )
     {
-      double lon = lonOut[i];
-      double lat = latOut[i];
-      curr_src_corners = get_dependencies_of_element(tgt_to_src_cell,i);
-      for ( int k = 0; k < tgt_to_src_cell.num_deps_per_element[i]; ++k )
+      double wgts[4];
+      double plon;
+      double plat;
+      double iguess = 0.5, jguess = 0.5;         /*  current guess for bilinear coordinate  */
+      int ix, iy;
+      int dst_add = i;
+
+      iy = dst_add/nlonOut;
+      ix = dst_add - iy*nlonOut;
+
+      plon = lonOut[ix];
+      plat = latOut[iy];
+
+      // do search
+      do_point_search_p3(search, &plon, &plat, 1, &deps, &source_points);
+
+      if ( i < 10 ) printf("total_num_dependencies: %d\n", get_total_num_dependencies(deps));
+      //printf("i, ix, iy %d %d %d\n", i, ix, iy);
+      curr_src_corners = get_dependencies_of_element(deps,0);
+      for ( int k = 0; k < deps.num_deps_per_element[i]; ++k )
 	{
 	}
-    }
 
-  /*
-  for ( int j = 0; j < 10; ++j )
-    {
-      for ( int i = 0; i < 10; ++i )
-	printf("%g ", arrayOut[j*10+i]);
-      printf("\n");
+      if ( deps.num_deps_per_element[0] == 4 )
+	{
+	  int sa, src_add[4];                /*  address for the four source points     */
+	  double src_lats[4];            /* latitudes  of the four corner points   */
+	  double src_lons[4];            /* longitudes of the four corner points   */
+
+	  for ( int k = 0; k < deps.num_deps_per_element[0]; ++k )
+	    {
+	      sa = curr_src_corners[k];
+	      src_add[k] = sa;
+	      iy = sa/nlonIn;
+	      ix = sa - iy*nlonIn;
+	      src_lats[k] = latIn[iy];
+	      src_lons[k] = lonIn[ix];
+	      if ( i < 3 ) printf("i, k, iy, ix %d %d %d %d\n", i, k, iy, ix);
+	    }
+
+	  // try it with do_point_search_p3
+	  if ( find_ij_weights(plon, plat, src_lats, src_lons, &iguess, &jguess) < 100 )
+	    {
+
+	      wgts[0] = (1.-iguess)*(1.-jguess);
+	      wgts[1] = iguess*(1.-jguess);
+	      wgts[2] = iguess*jguess;
+	      wgts[3] = (1.-iguess)*jguess;
+
+#if defined (_OPENMP)
+#pragma omp critical
+#endif
+	      store_link_bilin(&remap.vars, dst_add, src_add, wgts);
+	    }
+	}
     }
-  */
-  // free (search_result);
+
+  if ( cdoTimer ) timer_stop(timer_yar_remap_bil);
+
+  if ( cdoTimer ) timer_start(timer_yar_remap);
+  yar_remap(array2, missval, gridInqSize(gridIDout), remap.vars.num_links, remap.vars.wts,
+	    remap.vars.num_wts, remap.vars.grid2_add, remap.vars.grid1_add, array1);
+  if ( cdoTimer ) timer_stop(timer_yar_remap);
+
+  nmiss = 0;
+  for ( int i = 0; i < gridInqSize(gridIDout); ++i )
+    if ( DBL_IS_EQUAL(array2[i], missval) ) nmiss++;
+
+  field2->nmiss = nmiss;
+
   // if (array) free(array);
   //free(lonIn);
   //free(latIn);
@@ -225,7 +461,7 @@ void testint_p(field_t *field1, field_t *field2)
 }
 
 
-void testint_c(field_t *field1, field_t *field2)
+void yar_remap_con(field_t *field1, field_t *field2)
 {
   int nlonIn, nlatIn;
   int nlonOut, nlatOut;
@@ -239,21 +475,33 @@ void testint_c(field_t *field1, field_t *field2)
   double *xlonOut, *xlatOut;
   double **fieldIn;
   double **field;
-  double *array = NULL;
-  double *arrayIn, *arrayOut;
+  double *array1, *array2;
   double missval;
   double dxIn, dxOut;
+  remap_t remap;
   /* static int index = 0; */
 
   gridIDin  = field1->grid;
   gridIDout = field2->grid;
-  arrayIn   = field1->ptr;
-  arrayOut  = field2->ptr;
+  array1    = field1->ptr;
+  array2    = field2->ptr;
   missval   = field1->missval;
 
   if ( ! (gridInqXvals(gridIDin, NULL) && gridInqYvals(gridIDin, NULL)) )
     cdoAbort("Source grid has no values");
 
+  remap.grid.restrict_type = 0;
+  remap.grid.num_srch_bins = 0;
+  remap.grid.pinit = FALSE;
+  remap.vars.pinit = FALSE;
+
+  if ( cdoTimer ) timer_start(timer_yar_remap_init);
+  remapGridInit(MAP_TYPE_CONSERV, 0, gridIDin, gridIDout, &remap.grid);
+  remapVarsInit(MAP_TYPE_CONSERV, &remap.grid, &remap.vars);
+  if ( cdoTimer ) timer_stop(timer_yar_remap_init);
+
+
+  if ( cdoTimer ) timer_start(timer_yar_remap_init);
   nlonIn = gridInqXsize(gridIDin);
   nlatIn = gridInqYsize(gridIDin);
   gridsize1 = gridInqSize(gridIDin);
@@ -268,8 +516,10 @@ void testint_c(field_t *field1, field_t *field2)
   dxIn = lonIn[1] - lonIn[0];
   for ( int i = 0; i < nlonIn; ++i ) lonIn[i] -= dxIn/2;
   for ( int i = 0; i < nlatIn; ++i ) latIn[i] -= dxIn/2;
-  //  latIn[nlatIn] = latIn[nlatIn-1] + dxIn;
-  latIn[nlatIn] = 90;
+  for ( int i = 0; i < nlonIn; ++i ) lonIn[i] *= DEG2RAD;
+  for ( int i = 0; i < nlatIn; ++i ) latIn[i] *= DEG2RAD;
+  lonIn[nlonIn] = lonIn[nlonIn-1]+dxIn*DEG2RAD;
+  latIn[nlatIn] = -latIn[0];
 
   if ( ! (gridInqXvals(gridIDout, NULL) && gridInqYvals(gridIDout, NULL)) )
     cdoAbort("Target grid has no values");
@@ -288,9 +538,20 @@ void testint_c(field_t *field1, field_t *field2)
   dxOut = lonOut[1] - lonOut[0];
   for ( int i = 0; i < nlonOut; ++i ) lonOut[i] -= dxOut/2;
   for ( int i = 0; i < nlatOut; ++i ) latOut[i] -= dxOut/2;
-  //latOut[nlatOut] = latIn[nlatOut-1] + dxIn;
-  latOut[nlatOut] = 90;
-  printf("dxIn: %g   dxOut: %g\n", dxIn, dxOut);
+  for ( int i = 0; i < nlonOut; ++i ) lonOut[i] *= DEG2RAD;
+  for ( int i = 0; i < nlatOut; ++i ) latOut[i] *= DEG2RAD;
+  lonOut[nlonOut] = lonOut[nlonOut-1]+dxOut*DEG2RAD;
+  latOut[nlatOut] = latOut[0];
+
+  printf("source grid: inc = %g  nlon = %d  nlat = %d\n", dxIn, nlonIn, nlatIn);
+  printf("target grid: inc = %g  nlon = %d  nlat = %d\n", dxOut, nlonOut, nlatOut);
+
+  printf("lonIn: %g %g %g ... %g %g\n", lonIn[0]/DEG2RAD, lonIn[1]/DEG2RAD, lonIn[2]/DEG2RAD, lonIn[nlonIn-2]/DEG2RAD, lonIn[nlonIn-1]/DEG2RAD);
+  printf("latIn: %g %g %g ... %g %g\n", latIn[0]/DEG2RAD, latIn[1]/DEG2RAD, latIn[2]/DEG2RAD, latIn[nlatIn-2]/DEG2RAD, latIn[nlatIn-1]/DEG2RAD);
+
+  printf("lonOut: %g %g %g ... %g %g\n", lonOut[0]/DEG2RAD, lonOut[1]/DEG2RAD, lonOut[2]/DEG2RAD, lonOut[nlonOut-2]/DEG2RAD, lonOut[nlonOut-1]/DEG2RAD);
+  printf("latOut: %g %g %g ... %g %g\n", latOut[0]/DEG2RAD, latOut[1]/DEG2RAD, latOut[2]/DEG2RAD, latOut[nlatOut-2]/DEG2RAD, latOut[nlatOut-1]/DEG2RAD);
+
 #if defined (HAVE_LIBYAC)
 
   //--------------------------------------------
@@ -304,10 +565,12 @@ void testint_c(field_t *field1, field_t *field2)
   num_target_cells[1] = nlatOut;
 
   unsigned cyclic[2] = {1,0};
-  struct grid source_grid, target_grid;
+  struct grid *source_grid, *target_grid;
+
+  source_grid = reg2d_grid_new(lonIn, latIn, num_source_cells, cyclic);
+  target_grid = reg2d_grid_new(lonOut, latOut, num_target_cells, cyclic);
 
-  init_reg2d_grid(&source_grid, lonIn, latIn, num_source_cells, cyclic);
-  init_reg2d_grid(&target_grid, lonOut, latOut, num_target_cells, cyclic);
+  if ( cdoTimer ) timer_stop(timer_yar_remap_init);
 
   struct points source_points, target_points;
 
@@ -321,24 +584,33 @@ void testint_c(field_t *field1, field_t *field2)
   // initialise interpolation
   //--------------------------------------------
 
-  struct dep_list tgt_to_src_cell;
+  struct dep_list deps;
   unsigned search_id;
   //struct interpolation interpolation;
 
   // printf("src num_grid_corners %d\n", get_num_grid_corners(*get_point_grid(&source_points)));
   //printf("tgt num_grid_corners %d\n", get_num_grid_corners(*get_point_grid(&target_points)));
 
-  search_id = search_init(&source_grid);
+  struct grid_search *search;
+
+  if ( cdoTimer ) timer_start(timer_yar_remap_con);
+
+  search = bucket_search_new(source_grid);
+  // search_id = search_init(&source_grid);
  
-  do_cell_search(target_grid, search_id, &tgt_to_src_cell);
+  do_cell_search(search, target_grid, &deps);
 
 
-  printf("total_num_dependencies: %d\n", get_total_num_dependencies(tgt_to_src_cell));
-  int num_elements = tgt_to_src_cell.num_elements;
-  printf("dep num elements: %d\n", tgt_to_src_cell.num_elements);
+  printf("total_num_dependencies: %d\n", get_total_num_dependencies(deps));
+  int num_elements = deps.num_elements;
+  printf("dep num elements: %d\n", deps.num_elements);
 
   enum edge_type quad_type[] = {GREAT_CIRCLE, GREAT_CIRCLE, GREAT_CIRCLE, GREAT_CIRCLE};
 
+  int n;
+  double weight_sum;
+  double const epsilon = 1.0e-10; // relative precision 
+
   double *weight;
   weight = (double *) malloc(gridsize1*sizeof(double));
 
@@ -371,76 +643,98 @@ void testint_c(field_t *field1, field_t *field2)
       int ilat2 = index2/nlonOut;
       int ilon2 = index2 - ilat2*nlonOut;
 
-      TargetCell.coordinates_x[0] =  xlonOut[ilon2]-dxOut/2;
-      TargetCell.coordinates_y[0] =  xlatOut[ilat2]-dxOut/2;
-      TargetCell.coordinates_x[1] =  xlonOut[ilon2]+dxOut/2;
-      TargetCell.coordinates_y[1] =  xlatOut[ilat2]-dxOut/2;
-      TargetCell.coordinates_x[2] =  xlonOut[ilon2]+dxOut/2;
-      TargetCell.coordinates_y[2] =  xlatOut[ilat2]+dxOut/2;
-      TargetCell.coordinates_x[3] =  xlonOut[ilon2]-dxOut/2;
-      TargetCell.coordinates_y[3] =  xlatOut[ilat2]+dxOut/2;
+      TargetCell.coordinates_x[0] =  lonOut[ilon2];
+      TargetCell.coordinates_y[0] =  latOut[ilat2];
+      TargetCell.coordinates_x[1] =  lonOut[ilon2+1];
+      TargetCell.coordinates_y[1] =  latOut[ilat2];
+      TargetCell.coordinates_x[2] =  lonOut[ilon2+1];
+      TargetCell.coordinates_y[2] =  latOut[ilat2+1];
+      TargetCell.coordinates_x[3] =  lonOut[ilon2];
+      TargetCell.coordinates_y[3] =  latOut[ilat2+1];
 
-      if ( lout )
+      if ( cdoVerbose )
 	{
 	  printf("target:\n");
 	  for ( int n = 0; n < 4; ++n )
-	    printf(" %g %g", TargetCell.coordinates_x[n], TargetCell.coordinates_y[n]);
+	    printf(" %g %g", TargetCell.coordinates_x[n]/DEG2RAD, TargetCell.coordinates_y[n]/DEG2RAD);
 	  printf("\n");
 	}
 
-      if ( lout )
-	printf("num_deps_per_element %d %d\n", i, tgt_to_src_cell.num_deps_per_element[i]);
-      int num_deps = tgt_to_src_cell.num_deps_per_element[i];
-      if ( num_deps > 0 ) curr_deps = get_dependencies_of_element(tgt_to_src_cell, i);
+      if ( cdoVerbose )
+	printf("num_deps_per_element %d %d\n", i, deps.num_deps_per_element[i]);
+      int num_deps = deps.num_deps_per_element[i];
+      int nSourceCells = num_deps;
+
+      if ( num_deps > 0 ) curr_deps = get_dependencies_of_element(deps, i);
       for ( int k = 0; k < num_deps; ++k )
 	{
 	  int index1 = curr_deps[k];
 	  int ilat1 = index1/nlonIn;
 	  int ilon1 = index1 - ilat1*nlonIn;
-	  if ( lout )
+	  if ( cdoVerbose )
 	    printf("  dep: %d %d %d %d %d %d\n", k, nlonOut, nlatOut, index1, ilon1, ilat1);
 	
-	  SourceCell[k].coordinates_x[0] =  xlonIn[ilon1]-dxIn/2;
-	  SourceCell[k].coordinates_y[0] =  xlatIn[ilat1]-dxIn/2;
-	  SourceCell[k].coordinates_x[1] =  xlonIn[ilon1]+dxIn/2;
-	  SourceCell[k].coordinates_y[1] =  xlatIn[ilat1]-dxIn/2;
-	  SourceCell[k].coordinates_x[2] =  xlonIn[ilon1]+dxIn/2;
-	  SourceCell[k].coordinates_y[2] =  xlatIn[ilat1]+dxIn/2;
-	  SourceCell[k].coordinates_x[3] =  xlonIn[ilon1]-dxIn/2;
-	  SourceCell[k].coordinates_y[3] =  xlatIn[ilat1]+dxIn/2;
-	  if ( lout )
+	  SourceCell[k].coordinates_x[0] =  lonIn[ilon1];
+	  SourceCell[k].coordinates_y[0] =  latIn[ilat1];
+	  SourceCell[k].coordinates_x[1] =  lonIn[ilon1+1];
+	  SourceCell[k].coordinates_y[1] =  latIn[ilat1];
+	  SourceCell[k].coordinates_x[2] =  lonIn[ilon1+1];
+	  SourceCell[k].coordinates_y[2] =  latIn[ilat1+1];
+	  SourceCell[k].coordinates_x[3] =  lonIn[ilon1];
+	  SourceCell[k].coordinates_y[3] =  latIn[ilat1+1];
+	  if ( cdoVerbose )
 	    {
 	      printf("source: %d\n", k);
 	      for ( int n = 0; n < 4; ++n )
-		printf(" %g %g", SourceCell[k].coordinates_x[n], SourceCell[k].coordinates_y[n]);
+		printf(" %g %g", SourceCell[k].coordinates_x[n]/DEG2RAD, SourceCell[k].coordinates_y[n]/DEG2RAD);
 	      printf("\n");
 	    }
 	}
       
       polygon_partial_weights(num_deps, SourceCell, TargetCell, weight, &polygons);
 
+      correct_weights ( nSourceCells, weight );
+
       for ( int k = 0; k < num_deps; ++k )
 	{
 	  int index1 = curr_deps[k];
 	  int ilat1 = index1/nlonIn;
 	  int ilon1 = index1 - ilat1*nlonIn;
-	  if ( lout )
+	  long add1, add2;
+
+	  add1 = index1;
+	  add2 = index2;
+
+	  yar_store_link_cnsrv(&remap.vars, add1, add2, weight[k]);
+
+	  if ( cdoVerbose )
 	    printf("  result dep: %d %d %d %d %d %d  %g\n", k, nlonOut, nlatOut, index1, ilon1, ilat1, weight[k]);
 	}
       // correct_weights ( nSourceCells, weight );
     }
 
   polygon_destroy ( &polygons );
-  /*
-  for ( int j = 0; j < 10; ++j )
-    {
-      for ( int i = 0; i < 10; ++i )
-	printf("%g ", arrayOut[j*10+i]);
-      printf("\n");
-    }
-  */
-  // free (search_result);
-  // if (array) free(array);
+  if ( cdoTimer ) timer_stop(timer_yar_remap_con);
+
+  if ( cdoTimer ) timer_start(timer_yar_remap);
+  yar_remap(array2, missval, gridInqSize(gridIDout), remap.vars.num_links, remap.vars.wts,
+	    remap.vars.num_wts, remap.vars.grid2_add, remap.vars.grid1_add, array1);
+  if ( cdoTimer ) timer_stop(timer_yar_remap);
+
+  nmiss = 0;
+  for ( int i = 0; i < gridInqSize(gridIDout); ++i )
+    if ( DBL_IS_EQUAL(array2[i], missval) ) nmiss++;
+
+  field2->nmiss = nmiss;
+
+  //---------------
+  // cleanup
+  //---------------
+  delete_grid_search(search);
+  free_dep_list(&deps);
+  delete_grid(source_grid);
+  delete_grid(target_grid);
+
   //free(lonIn);
   //free(latIn);
   //free(lonOut);
@@ -469,6 +763,15 @@ void *YAR(void *argument)
   field_t field1, field2;
   int taxisID1, taxisID2;
 
+  if ( cdoTimer )
+    {
+      timer_yar_remap        = timer_new("yar remap");
+      timer_yar_remap_init   = timer_new("yar remap init");
+      timer_yar_remap_sort   = timer_new("yar remap sort");
+      timer_yar_remap_con    = timer_new("yar remap con");
+      timer_yar_remap_bil    = timer_new("yar remap bil");
+    }
+
   cdoInitialize(argument);
 
   YARBIL = cdoOperatorAdd("yarbil",  0, 0, NULL);
@@ -536,9 +839,9 @@ void *YAR(void *argument)
 	  field2.nmiss   = 0;
 
 	  if ( operatorID == YARBIL )
-	    testint_p(&field1, &field2);
+	    yar_remap_bil(&field1, &field2);
 	  else if ( operatorID == YARCON )
-	    testint_c(&field1, &field2);
+	    yar_remap_con(&field1, &field2);
 	  else
 	    cdoAbort("Not implemented!");
 
diff --git a/src/Ydaypctl.c b/src/Ydaypctl.c
index bea10dc..8f54bdd 100644
--- a/src/Ydaypctl.c
+++ b/src/Ydaypctl.c
@@ -111,13 +111,13 @@ void *Ydaypctl(void *argument)
   while ( (nrecs = streamInqTimestep(streamID2, tsID)) )
     {
       if ( nrecs != streamInqTimestep(streamID3, tsID) )
-        cdoAbort("Number of records at time step %d of %s and %s differ!", tsID+1, cdoStreamName(1), cdoStreamName(2));
+        cdoAbort("Number of records at time step %d of %s and %s differ!", tsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args);
       
       vdate = taxisInqVdate(taxisID2);
       vtime = taxisInqVtime(taxisID2);
       
       if ( vdate != taxisInqVdate(taxisID3) || vtime != taxisInqVtime(taxisID3) )
-        cdoAbort("Verification dates at time step %d of %s and %s differ!", tsID+1, cdoStreamName(1), cdoStreamName(2));
+        cdoAbort("Verification dates at time step %d of %s and %s differ!", tsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args);
         
       if ( cdoVerbose ) cdoPrint("process timestep: %d %d %d", tsID+1, vdate, vtime);
 
@@ -201,7 +201,7 @@ void *Ydaypctl(void *argument)
       vtimes1[dayoy] = vtime;
       
       if ( vars1[dayoy] == NULL )
-        cdoAbort("No data for day %d in %s and %s", dayoy, cdoStreamName(1), cdoStreamName(2));
+        cdoAbort("No data for day %d in %s and %s", dayoy, cdoStreamName(1)->args, cdoStreamName(2)->args);
         
       for ( recID = 0; recID < nrecs; recID++ )
 	{
@@ -228,9 +228,9 @@ void *Ydaypctl(void *argument)
     if ( nsets[dayoy] )
       {
         if ( vdates1[dayoy] != vdates2[dayoy] )
-          cdoAbort("Verification dates for day %d of %s, %s and %s are different!", dayoy, cdoStreamName(1), cdoStreamName(2), cdoStreamName(3));
+          cdoAbort("Verification dates for day %d of %s, %s and %s are different!", dayoy, cdoStreamName(1)->args, cdoStreamName(2)->args, cdoStreamName(3)->args);
         if ( vtimes1[dayoy] != vtimes2[dayoy] )
-          cdoAbort("Verification times for day %d of %s, %s and %s are different!", dayoy, cdoStreamName(1), cdoStreamName(2), cdoStreamName(3));
+          cdoAbort("Verification times for day %d of %s, %s and %s are different!", dayoy, cdoStreamName(1)->args, cdoStreamName(2)->args, cdoStreamName(3)->args);
         
 	for ( varID = 0; varID < nvars; varID++ )
 	  {
diff --git a/src/Ydrunpctl.c b/src/Ydrunpctl.c
index f642136..362db4d 100644
--- a/src/Ydrunpctl.c
+++ b/src/Ydrunpctl.c
@@ -147,13 +147,13 @@ void *Ydrunpctl(void *argument)
   while ( (nrecs = streamInqTimestep(streamID2, tsID)) )
     {
       if ( nrecs != streamInqTimestep(streamID3, tsID) )
-        cdoAbort("Number of records at time step %d of %s and %s differ!", tsID+1, cdoStreamName(1), cdoStreamName(2));
+        cdoAbort("Number of records at time step %d of %s and %s differ!", tsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args);
       
       vdate = taxisInqVdate(taxisID2);
       vtime = taxisInqVtime(taxisID2);
       
       if ( vdate != taxisInqVdate(taxisID3) || vtime != taxisInqVtime(taxisID3) )
-        cdoAbort("Verification dates at time step %d of %s and %s differ!", tsID+1, cdoStreamName(1), cdoStreamName(2));
+        cdoAbort("Verification dates at time step %d of %s and %s differ!", tsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args);
         
       if ( cdoVerbose ) cdoPrint("process timestep: %d %d %d", tsID+1, vdate, vtime);
 
@@ -260,7 +260,7 @@ void *Ydrunpctl(void *argument)
       vtimes1[dayoy] = vtime;
       
       if ( vars2[dayoy] == NULL )
-        cdoAbort("No data for day %d in %s and %s", dayoy, cdoStreamName(1), cdoStreamName(2));
+        cdoAbort("No data for day %d in %s and %s", dayoy, cdoStreamName(1)->args, cdoStreamName(2)->args);
 
       for ( varID = 0; varID < nvars; varID++ )
 	{
@@ -304,9 +304,9 @@ void *Ydrunpctl(void *argument)
     if ( nsets[dayoy] )
       {
         if ( vdates1[dayoy] != vdates2[dayoy] )
-          cdoAbort("Verification dates for day %d of %s, %s and %s are different!", dayoy, cdoStreamName(1), cdoStreamName(2), cdoStreamName(3));
+          cdoAbort("Verification dates for day %d of %s, %s and %s are different!", dayoy, cdoStreamName(1)->args, cdoStreamName(2)->args, cdoStreamName(3)->args);
         if ( vtimes1[dayoy] != vtimes2[dayoy] )
-          cdoAbort("Verification times for day %d of %s, %s and %s are different!", dayoy, cdoStreamName(1), cdoStreamName(2), cdoStreamName(3));
+          cdoAbort("Verification times for day %d of %s, %s and %s are different!", dayoy, cdoStreamName(1)->args, cdoStreamName(2)->args, cdoStreamName(3)->args);
 
 	for ( varID = 0; varID < nvars; varID++ )
 	  {
diff --git a/src/Ymonpctl.c b/src/Ymonpctl.c
index a8ace66..3504226 100644
--- a/src/Ymonpctl.c
+++ b/src/Ymonpctl.c
@@ -109,13 +109,13 @@ void *Ymonpctl(void *argument)
   while ( (nrecs = streamInqTimestep(streamID2, tsID)) )
     {
       if ( nrecs != streamInqTimestep(streamID3, tsID) )
-        cdoAbort("Number of records at time step %d of %s and %s differ!", tsID+1, cdoStreamName(1), cdoStreamName(2));
+        cdoAbort("Number of records at time step %d of %s and %s differ!", tsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args);
       
       vdate = taxisInqVdate(taxisID2);
       vtime = taxisInqVtime(taxisID2);
       
       if ( vdate != taxisInqVdate(taxisID3) || vtime != taxisInqVtime(taxisID3) )
-        cdoAbort("Verification dates at time step %d of %s and %s differ!", tsID+1, cdoStreamName(1), cdoStreamName(2));
+        cdoAbort("Verification dates at time step %d of %s and %s differ!", tsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args);
         
       if ( cdoVerbose ) cdoPrint("process timestep: %d %d %d", tsID+1, vdate, vtime);
 
@@ -187,7 +187,7 @@ void *Ymonpctl(void *argument)
       vtimes1[month] = vtime;
 
       if ( vars1[month] == NULL )
-        cdoAbort("No data for month %d in %s and %s", month, cdoStreamName(1), cdoStreamName(2));
+        cdoAbort("No data for month %d in %s and %s", month, cdoStreamName(1)->args, cdoStreamName(2)->args);
 
       for ( recID = 0; recID < nrecs; recID++ )
 	{
@@ -214,9 +214,9 @@ void *Ymonpctl(void *argument)
     if ( nsets[month] )
       {
         if ( vdates1[month] != vdates2[month] )
-          cdoAbort("Verification dates for month %d of %s, %s and %s are different!", month, cdoStreamName(1), cdoStreamName(2), cdoStreamName(3));
+          cdoAbort("Verification dates for month %d of %s, %s and %s are different!", month, cdoStreamName(1)->args, cdoStreamName(2)->args, cdoStreamName(3)->args);
         if ( vtimes1[month] != vtimes2[month] )
-          cdoAbort("Verification times for month %d of %s, %s and %s are different!", month, cdoStreamName(1), cdoStreamName(2), cdoStreamName(3));
+          cdoAbort("Verification times for month %d of %s, %s and %s are different!", month, cdoStreamName(1)->args, cdoStreamName(2)->args, cdoStreamName(3)->args);
 
 	for ( varID = 0; varID < nvars; varID++ )
 	  {
diff --git a/src/Yseaspctl.c b/src/Yseaspctl.c
index 8c04289..b032b31 100644
--- a/src/Yseaspctl.c
+++ b/src/Yseaspctl.c
@@ -112,13 +112,13 @@ void *Yseaspctl(void *argument)
   while ( (nrecs = streamInqTimestep(streamID2, tsID)) )
     {
       if ( nrecs != streamInqTimestep(streamID3, tsID) )
-        cdoAbort("Number of records at time step %d of %s and %s differ!", tsID+1, cdoStreamName(1), cdoStreamName(2));
+        cdoAbort("Number of records at time step %d of %s and %s differ!", tsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args);
       
       vdate = taxisInqVdate(taxisID2);
       vtime = taxisInqVtime(taxisID2);
       
       if ( vdate != taxisInqVdate(taxisID3) || vtime != taxisInqVtime(taxisID3) )
-        cdoAbort("Verification dates at time step %d of %s and %s differ!", tsID+1, cdoStreamName(1), cdoStreamName(2));
+        cdoAbort("Verification dates at time step %d of %s and %s differ!", tsID+1, cdoStreamName(1)->args, cdoStreamName(2)->args);
         
       if ( cdoVerbose ) cdoPrint("process timestep: %d %d %d", tsID+1, vdate, vtime);
 
@@ -213,7 +213,7 @@ void *Yseaspctl(void *argument)
       vtimes1[seas] = vtime;
 
       if ( vars1[seas] == NULL )
-        cdoAbort("No data for season %d in %s and %s", seas, cdoStreamName(1), cdoStreamName(2));
+        cdoAbort("No data for season %d in %s and %s", seas, cdoStreamName(1)->args, cdoStreamName(2)->args);
 
       for ( recID = 0; recID < nrecs; recID++ )
 	{
@@ -240,9 +240,9 @@ void *Yseaspctl(void *argument)
     if ( nsets[seas] )
       {
         if ( vdates1[seas] != vdates2[seas] )
-          cdoAbort("Verification dates for season %d of %s, %s and %s are different!", seas, cdoStreamName(1), cdoStreamName(2), cdoStreamName(3));
+          cdoAbort("Verification dates for season %d of %s, %s and %s are different!", seas, cdoStreamName(1)->args, cdoStreamName(2)->args, cdoStreamName(3)->args);
         if ( vtimes1[seas] != vtimes2[seas] )
-          cdoAbort("Verification times for season %d of %s, %s and %s are different!", seas, cdoStreamName(1), cdoStreamName(2), cdoStreamName(3));
+          cdoAbort("Verification times for season %d of %s, %s and %s are different!", seas, cdoStreamName(1)->args, cdoStreamName(2)->args, cdoStreamName(3)->args);
 
 	for ( varID = 0; varID < nvars; varID++ )
 	  {
diff --git a/src/cdo.c b/src/cdo.c
index ef8ef0f..01fa775 100644
--- a/src/cdo.c
+++ b/src/cdo.c
@@ -141,6 +141,9 @@ int timer_total, timer_read, timer_write;
 static
 void cdo_version(void)
 {
+  int   filetypes[] = {FILETYPE_SRV, FILETYPE_EXT, FILETYPE_IEG, FILETYPE_GRB, FILETYPE_GRB2, FILETYPE_NC, FILETYPE_NC2, FILETYPE_NC4, FILETYPE_NC4C};
+  char *typenames[] = {        "srv",        "ext",        "ieg",        "grb",        "grb2",        "nc",        "nc2",        "nc4",        "nc4c"};
+
   fprintf(stderr, "%s\n", CDO_Version);
 #if defined (COMPILER)
   fprintf(stderr, "Compiler: %s\n", COMPILER);
@@ -148,6 +151,11 @@ void cdo_version(void)
 #if defined (COMP_VERSION)
   fprintf(stderr, " version: %s\n", COMP_VERSION);
 #endif
+#if defined (USER_NAME) && defined(HOST_NAME) && defined(SYSTEM_TYPE)
+  fprintf(stderr, "Compiled: by %s on %s (%s) %s %s\n",
+	  USER_NAME, HOST_NAME, SYSTEM_TYPE, __DATE__, __TIME__);
+#endif
+
   fprintf(stderr, "    with:");
 #if defined (HAVE_LIBPTHREAD)
   fprintf(stderr, " PTHREADS");
@@ -189,10 +197,12 @@ void cdo_version(void)
   fprintf(stderr, " CURL");
 #endif
   fprintf(stderr, "\n");
-#if defined (USER_NAME) && defined(HOST_NAME) && defined(SYSTEM_TYPE)
-  fprintf(stderr, "Compiled: by %s on %s (%s) %s %s\n",
-	  USER_NAME, HOST_NAME, SYSTEM_TYPE, __DATE__, __TIME__);
-#endif
+
+  fprintf(stderr, "filetype: ");
+  for ( size_t i = 0; i < sizeof(filetypes)/sizeof(int); ++i )
+    if ( cdiHaveFiletype(filetypes[i]) ) fprintf(stderr, "%s ", typenames[i]);
+  fprintf(stderr, "\n");
+
   cdiPrintVersion();
   fprintf(stderr, "\n");
 }
@@ -452,17 +462,17 @@ void setDefaultDataType(char *datatypestr)
 		  exit(EXIT_FAILURE);
 		}
 	    }
-	  /*
 	  else if ( dtype == D_UINT )
 	    {
 	      if      ( nbits ==  8 ) cdoDefaultDataType = DATATYPE_UINT8;
+	      else if ( nbits == 16 ) cdoDefaultDataType = DATATYPE_UINT16;
+	      else if ( nbits == 32 ) cdoDefaultDataType = DATATYPE_UINT32;
 	      else
 		{
 		  fprintf(stderr, "Unsupported number of bits = %d for datatype UINT!\n", nbits);
 		  exit(EXIT_FAILURE);
 		}
 	    }
-	  */
 	  else if ( dtype == D_FLT )
 	    {
 	      if      ( nbits == 32 ) cdoDefaultDataType = DATATYPE_FLT32;
@@ -607,6 +617,7 @@ void setDefaultFileType(char *filetypestr, int labort)
 #endif
 
 #define NTESTS 11
+#include <inttypes.h>
 static
 int getMemAlignment(void)
 {
@@ -1107,8 +1118,8 @@ int main(int argc, char *argv[])
   int status = 0;
   char *operatorName = NULL;
   char *operatorArg = NULL;
-  char *argument = NULL;
   extern int dmemory_ExitOnError;
+  argument_t *argument = NULL;
 
   init_is_tty();
 
@@ -1160,13 +1171,14 @@ int main(int argc, char *argv[])
   if ( cdoOptind < argc )
     {
       operatorArg = argv[cdoOptind];
-      argument = makeArgument(argc-cdoOptind, &argv[cdoOptind]);
+      argument = argument_new(argc-cdoOptind, 0);
+      argument_fill(argument, argc-cdoOptind, &argv[cdoOptind]);
     }
   else
     {
       if ( ! Version && ! Help )
 	{
-	  fprintf(stderr, "\nno operator given\n\n");
+	  fprintf(stderr, "\nNo operator given!\n\n");
 	  usage();
 	  status = 1;
 	}
@@ -1204,13 +1216,14 @@ int main(int argc, char *argv[])
       if ( cdoTimer ) timer_report();
     }
 
-  if ( argument ) free(argument);
+  if ( argument ) argument_free(argument);
 
   if ( cdoVarnames )
     {
       if ( cdoNumVarnames ) free(cdoVarnames[0]);
       free(cdoVarnames);
     }
+
   /* problems with alias!!! if ( operatorName ) free(operatorName); */ 
 
   /* malloc_stats(); */
diff --git a/src/cdo.h b/src/cdo.h
index 85e0b3d..665e56e 100644
--- a/src/cdo.h
+++ b/src/cdo.h
@@ -20,6 +20,7 @@
 
 #include <stdio.h>
 #include "dmemory.h"
+#include "util.h"
 
 #undef   TRUE
 #define  TRUE   1
@@ -35,14 +36,7 @@
 #undef   NINTD
 #define  NINTD(x)   ((x) < 0 ? ((x)-0.5) : ((x)+0.5))
 
-#define  UNCHANGED_RECORD  (processSelf() == 0 && *cdoStreamName(0) != '-' && cdoRegulargrid == FALSE && cdoDefaultFileType == -1 && cdoDefaultDataType == -1 && cdoDefaultByteorder == -1 )
-
-
-typedef struct {
-  int      argc;
-  char   **argv;
-}
-ARGUMENT;
+#define  UNCHANGED_RECORD  (processSelf() == 0 && cdoStreamName(0)->argv[0][0] != '-' && cdoRegulargrid == FALSE && cdoDefaultFileType == -1 && cdoDefaultDataType == -1 && cdoDefaultByteorder == -1 )
 
 
 extern int ompNumThreads;
@@ -95,7 +89,7 @@ int     operatorArgc(void);
 char  **operatorArgv(void);
 void    operatorCheckArgc(int numargs);
 
-const char *cdoStreamName(int cnt);
+const argument_t *cdoStreamName(int cnt);
 
 void    cdoInitialize(void *argument);
 void    cdoFinish(void);
diff --git a/src/cdo_int.h b/src/cdo_int.h
index 9f9dcf2..2ad504f 100644
--- a/src/cdo_int.h
+++ b/src/cdo_int.h
@@ -85,22 +85,14 @@ char *strdup(const char *s);
 #endif
 
 
-#ifndef  M_PI
-#define  M_PI        3.14159265358979323846  /* pi */
-#endif
-
 #ifndef  M_LN10
 #define  M_LN10      2.30258509299404568402  /* log_e 10 */
 #endif
 
-
-#ifndef  RAD2DEG
-#define  RAD2DEG  (180./M_PI)   /* conversion for rad to deg */
+#ifndef  M_PI
+#define  M_PI        3.14159265358979323846  /* pi */
 #endif
 
-#ifndef  DEG2RAD
-#define  DEG2RAD  (M_PI/180.)   /* conversion for deg to rad */
-#endif
 
 #define  IX2D(y,x,nx)  ((y)*(nx)+(x))
 
diff --git a/src/commandline.c b/src/commandline.c
index 88c8919..7a8a26e 100644
--- a/src/commandline.c
+++ b/src/commandline.c
@@ -17,7 +17,7 @@
 
 #include <string.h>
 
-static int gargc = 0;
+static int    gargc = 0;
 static char **gargv;
 
 static char CommandLine[1024];
diff --git a/src/config.h.in b/src/config.h.in
index d07b305..1d8a446 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -16,6 +16,9 @@
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #undef HAVE_DLFCN_H
 
+/* Define to 1 if you have the <fftw3.h> header file. */
+#undef HAVE_FFTW3_H
+
 /* Define to 1 if you have the `gethostname' function. */
 #undef HAVE_GETHOSTNAME
 
@@ -46,6 +49,9 @@
 /* Define to 1 for EXTRA interface */
 #undef HAVE_LIBEXTRA
 
+/* FFTW3 library is present if defined to 1 */
+#undef HAVE_LIBFFTW3
+
 /* Define to 1 for GRIB support */
 #undef HAVE_LIBGRIB
 
diff --git a/src/ecacore.c b/src/ecacore.c
index 3222a60..69bd0fd 100755
--- a/src/ecacore.c
+++ b/src/ecacore.c
@@ -59,7 +59,6 @@ void eca1(const ECA_REQUEST_1 *request)
   cmplen = DATE_LEN - cdoOperatorF2(operatorID);
 
   istreamID = streamOpenRead(cdoStreamName(0));
-  if ( istreamID < 0 ) cdiError(istreamID, "Open failed on %s", cdoStreamName(0));
 
   ivlistID = streamInqVlist(istreamID);
   ovlistID = vlistCreate();
@@ -105,7 +104,6 @@ void eca1(const ECA_REQUEST_1 *request)
   vlistDefTaxis(ovlistID, otaxisID);
 
   ostreamID = streamOpenWrite(cdoStreamName(1), cdoFiletype());
-  if ( ostreamID < 0 ) cdiError(ostreamID, "Open failed on %s", cdoStreamName(1));
 
   streamDefVlist(ostreamID, ovlistID);
 
@@ -417,9 +415,7 @@ void eca2(const ECA_REQUEST_2 *request)
   cmplen = DATE_LEN - cdoOperatorF2(operatorID);
 
   istreamID1 = streamOpenRead(cdoStreamName(0));
-  if ( istreamID1 < 0 ) cdiError(istreamID1, "Open failed on %s", cdoStreamName(0));
   istreamID2 = streamOpenRead(cdoStreamName(1));
-  if ( istreamID2 < 0 ) cdiError(istreamID2, "Open failed on %s", cdoStreamName(1));
 
   ivlistID1 = streamInqVlist(istreamID1);
   ivlistID2 = streamInqVlist(istreamID2);
@@ -470,7 +466,6 @@ void eca2(const ECA_REQUEST_2 *request)
   vlistDefTaxis(ovlistID, otaxisID);
 
   ostreamID = streamOpenWrite(cdoStreamName(2), cdoFiletype());
-  if ( ostreamID < 0 ) cdiError(ostreamID, "Open failed on %s", cdoStreamName(2));
 
   streamDefVlist(ostreamID, ovlistID);
 
@@ -800,9 +795,7 @@ void eca3(const ECA_REQUEST_3 *request)
   cmplen = DATE_LEN - cdoOperatorF2(operatorID);
 
   istreamID1 = streamOpenRead(cdoStreamName(0));
-  if ( istreamID1 < 0 ) cdiError(istreamID1, "Open failed on %s", cdoStreamName(0));
   istreamID2 = streamOpenRead(cdoStreamName(1));
-  if ( istreamID2 < 0 ) cdiError(istreamID2, "Open failed on %s", cdoStreamName(1));
 
   ivlistID1 = streamInqVlist(istreamID1);
   ivlistID2 = streamInqVlist(istreamID2);
@@ -838,7 +831,6 @@ void eca3(const ECA_REQUEST_3 *request)
   vlistDefTaxis(ovlistID, otaxisID);
 
   ostreamID = streamOpenWrite(cdoStreamName(2), cdoFiletype());
-  if ( ostreamID < 0 ) cdiError(ostreamID, "Open failed on %s", cdoStreamName(2));
 
   streamDefVlist(ostreamID, ovlistID);
 
@@ -1009,9 +1001,7 @@ void eca4(const ECA_REQUEST_4 *request)
   cmplen = DATE_LEN - cdoOperatorF2(operatorID);
 
   istreamID1 = streamOpenRead(cdoStreamName(0));
-  if ( istreamID1 < 0 ) cdiError(istreamID1, "Open failed on %s", cdoStreamName(0));
   istreamID2 = streamOpenRead(cdoStreamName(1));
-  if ( istreamID2 < 0 ) cdiError(istreamID1, "Open failed on %s", cdoStreamName(1));
 
   ivlistID1 = streamInqVlist(istreamID1);
   ivlistID2 = streamInqVlist(istreamID2);
@@ -1057,7 +1047,6 @@ void eca4(const ECA_REQUEST_4 *request)
   vlistDefTaxis(ovlistID, otaxisID);
 
   ostreamID = streamOpenWrite(cdoStreamName(2), cdoFiletype());
-  if ( ostreamID < 0 ) cdiError(ostreamID, "Open failed on %s", cdoStreamName(2));
 
   streamDefVlist(ostreamID, ovlistID);
 
diff --git a/src/expr.c b/src/expr.c
index b3cbf03..2751fea 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -293,7 +293,7 @@ nodeType *expr_var_var(int oper, nodeType *p1, nodeType *p2)
   nodeType *p;
   long ngp, ngp1, ngp2, i;
   long nlev, nlev1, nlev2, k;
-  long loff1, loff2;
+  long loff, loff1, loff2;
   int nmiss, nmiss1, nmiss2;
   double missval1, missval2;
 
@@ -306,7 +306,7 @@ nodeType *expr_var_var(int oper, nodeType *p1, nodeType *p2)
   ngp2 = gridInqSize(p2->gridID);
 
   if ( ngp1 != ngp2 )
-    cdoAbort("number of grid points differ. ngp1 = %d, ngp2 = %d", ngp1, ngp2);
+    cdoAbort("Number of grid points differ. ngp1 = %d, ngp2 = %d", ngp1, ngp2);
 
   ngp = ngp1;
 
@@ -347,6 +347,8 @@ nodeType *expr_var_var(int oper, nodeType *p1, nodeType *p2)
 
   for ( k = 0; k < nlev; k++ )
     {
+      loff = k*ngp;
+
       if ( nlev1 == 1 ) loff1 = 0;
       else              loff1 = k*ngp;
 
@@ -359,52 +361,52 @@ nodeType *expr_var_var(int oper, nodeType *p1, nodeType *p2)
 	  if ( nmiss1 > 0 || nmiss2 > 0 )
 	    {
 	      for ( i = 0; i < ngp; i++ )
-		p->data[i+k*ngp] = ADD(p1->data[i+loff1], p2->data[i+loff2]);
+		p->data[i+loff] = ADD(p1->data[i+loff1], p2->data[i+loff2]);
 	    }
 	  else
 	    {
 	      for ( i = 0; i < ngp; i++ )
-		p->data[i+k*ngp] = p1->data[i+loff1] + p2->data[i+loff2];
+		p->data[i+loff] = p1->data[i+loff1] + p2->data[i+loff2];
 	    }
 	  break;
 	case '-':
 	  if ( nmiss1 > 0 || nmiss2 > 0 )
 	    {
 	      for ( i = 0; i < ngp; i++ )
-		p->data[i+k*ngp] = SUB(p1->data[i+loff1], p2->data[i+loff2]);
+		p->data[i+loff] = SUB(p1->data[i+loff1], p2->data[i+loff2]);
 	    }
 	  else
 	    {
 	      for ( i = 0; i < ngp; i++ )
-		p->data[i+k*ngp] = p1->data[i+loff1] - p2->data[i+loff2];
+		p->data[i+loff] = p1->data[i+loff1] - p2->data[i+loff2];
 	    }
 	  break;
 	case '*':
 	  if ( nmiss1 > 0 || nmiss2 > 0 )
 	    {
 	      for ( i = 0; i < ngp; i++ )
-		p->data[i+k*ngp] = MUL(p1->data[i+loff1], p2->data[i+loff2]);
+		p->data[i+loff] = MUL(p1->data[i+loff1], p2->data[i+loff2]);
 	    }
 	  else
 	    {
 	      for ( i = 0; i < ngp; i++ )
-		p->data[i+k*ngp] = p1->data[i+loff1] * p2->data[i+loff2];
+		p->data[i+loff] = p1->data[i+loff1] * p2->data[i+loff2];
 	    }
 	  break;
 	case '/':
 	  if ( nmiss1 > 0 || nmiss2 > 0 )
 	    {
 	      for ( i = 0; i < ngp; i++ )
-		p->data[i+k*ngp] = DIV(p1->data[i+loff1], p2->data[i+loff2]);
+		p->data[i+loff] = DIV(p1->data[i+loff1], p2->data[i+loff2]);
 	    }
 	  else
 	    {
 	      for ( i = 0; i < ngp; i++ )
 		{
 		  if ( IS_EQUAL(p2->data[i+loff2], 0.) )
-		    p->data[i+k*ngp] = missval1;
+		    p->data[i+loff] = missval1;
 		  else
-		    p->data[i+k*ngp] = p1->data[i+loff1] / p2->data[i+loff2];
+		    p->data[i+loff] = p1->data[i+loff1] / p2->data[i+loff2];
 		}
 	    }
 	  break;
@@ -412,12 +414,12 @@ nodeType *expr_var_var(int oper, nodeType *p1, nodeType *p2)
 	  if ( nmiss1 > 0 || nmiss2 > 0 )
 	    {
 	      for ( i = 0; i < ngp; i++ )
-		p->data[i+k*ngp] = POW(p1->data[i+loff1], p2->data[i+loff2]);
+		p->data[i+loff] = POW(p1->data[i+loff1], p2->data[i+loff2]);
 	    }
 	  else
 	    {
 	      for ( i = 0; i < ngp; i++ )
-		p->data[i+k*ngp] = pow(p1->data[i+loff1], p2->data[i+loff2]);
+		p->data[i+loff] = pow(p1->data[i+loff1], p2->data[i+loff2]);
 	    }
 	  break;
 	default:
@@ -451,7 +453,7 @@ void ex_copy(nodeType *p2, nodeType *p1)
   ngp2 = gridInqSize(p2->gridID);
 
   if ( ngp1 != ngp2 )
-    cdoAbort("number of grid points differ. ngp1 = %d, ngp2 = %d", ngp1, ngp2);
+    cdoAbort("Number of grid points differ. ngp1 = %d, ngp2 = %d", ngp1, ngp2);
 
   ngp = ngp2;
   nlev = zaxisInqSize(p2->zaxisID);
@@ -518,7 +520,7 @@ nodeType *ex_fun_con(char *fun, nodeType *p1)
 	}
 
   if ( funcID == -1 )
-    cdoAbort("function %s not available!", fun);
+    cdoAbort("Function %s not available!", fun);
 
   p->u.con.value = fun_sym_tbl[funcID].func(p1->u.con.value);
 
@@ -563,7 +565,7 @@ nodeType *ex_fun_var(char *fun, nodeType *p1)
       }
 
   if ( funcID == -1 )
-    cdoAbort("function %s not available!", fun);
+    cdoAbort("Function %s not available!", fun);
 
   if ( nmiss > 0 )
     {
@@ -739,7 +741,7 @@ nodeType *expr_run(nodeType *p, parse_parm_t *parse_arg)
       if ( parse_arg->init )
 	{
 	  if ( parse_arg->debug )
-	    printf("\tpush\t%g\n", p->u.con.value);
+	    printf("\tpush const \t%g\n", p->u.con.value);
 	}
       else
 	{
@@ -751,7 +753,7 @@ nodeType *expr_run(nodeType *p, parse_parm_t *parse_arg)
       /*    if ( parse_arg->init ) */
 	{
 	  if ( parse_arg->debug )
-	    printf("\tpush\t%s\n", p->u.var.nm);
+	    printf("\tpush var \t%s\n", p->u.var.nm);
 
 	  nvars = vlistNvars(parse_arg->vlistID1);
 	  for ( varID = 0; varID < nvars; varID++ )
@@ -766,6 +768,7 @@ nodeType *expr_run(nodeType *p, parse_parm_t *parse_arg)
 	    }
 	  else
 	    {
+	      int nlev1, nlev2 = 0;
 	      if ( varID >= MAX_VARS ) cdoAbort("Too many parameter (limit=%d)!", MAX_VARS);
 
 	      if ( parse_arg->var_needed[varID] == 0 )
@@ -776,17 +779,20 @@ nodeType *expr_run(nodeType *p, parse_parm_t *parse_arg)
 		  parse_arg->var_needed[varID] = 1;
 		}
 
-	      gridID1  = vlistInqVarGrid(parse_arg->vlistID1, varID);
-	      zaxisID1 = vlistInqVarZaxis(parse_arg->vlistID1, varID);
-	      tsteptype1  = vlistInqVarTsteptype(parse_arg->vlistID1, varID);
-	      missval  = vlistInqVarMissval(parse_arg->vlistID1, varID);
+	      gridID1    = vlistInqVarGrid(parse_arg->vlistID1, varID);
+	      zaxisID1   = vlistInqVarZaxis(parse_arg->vlistID1, varID);
+	      tsteptype1 = vlistInqVarTsteptype(parse_arg->vlistID1, varID);
+	      missval    = vlistInqVarMissval(parse_arg->vlistID1, varID);
+	      nlev1 = zaxisInqSize(zaxisID1);
 
 	      parse_arg->missval2 = missval;
 
 	      if ( parse_arg->gridID2 == -1 )
 		parse_arg->gridID2 = gridID1;
 
-	      if ( parse_arg->zaxisID2 == -1 )
+	      if ( parse_arg->zaxisID2 != -1 ) nlev2 = zaxisInqSize(parse_arg->zaxisID2);
+
+	      if ( parse_arg->zaxisID2 == -1 || (nlev1 > 1 && nlev2 == 1) )
 		parse_arg->zaxisID2 = zaxisID1;
 
 	      if ( parse_arg->tsteptype2 == -1 || parse_arg->tsteptype2 == TSTEP_CONSTANT )
@@ -796,7 +802,7 @@ nodeType *expr_run(nodeType *p, parse_parm_t *parse_arg)
 	/* else */
 	{ 
 	  if ( parse_arg->debug )
-	    printf("%s %d %d %d\n", p->u.var.nm, varID, gridID1, zaxisID1);
+	    printf("var: %s %d %d %d\n", p->u.var.nm, varID, gridID1, zaxisID1);
 	  p->gridID  = gridID1;
 	  p->zaxisID = zaxisID1;
 	  p->missval = missval;
@@ -837,7 +843,7 @@ nodeType *expr_run(nodeType *p, parse_parm_t *parse_arg)
 	  if ( parse_arg->init )
 	    {
 	      if ( parse_arg->debug )
-		printf("\tpop\t%s\n", p->u.opr.op[0]->u.var.nm);
+		printf("\tpop var\t%s\n", p->u.opr.op[0]->u.var.nm);
 	      /*
 	      if ( p->u.opr.op[1]->type != typeVar )
 		cdoAbort("Operand not variable!");
@@ -852,7 +858,7 @@ nodeType *expr_run(nodeType *p, parse_parm_t *parse_arg)
 	  else
 	    {
 	      if ( parse_arg->debug )
-		printf("\tpop\t%s\t%s\n", p->u.opr.op[0]->u.var.nm, rnode->u.var.nm);
+		printf("\tpop var\t%s\t%s\n", p->u.opr.op[0]->u.var.nm, rnode->u.var.nm);
 
 	      nvars = vlistNvars(parse_arg->vlistID2);
 	      for ( varID = 0; varID < nvars; varID++ )
@@ -863,7 +869,7 @@ nodeType *expr_run(nodeType *p, parse_parm_t *parse_arg)
 
 	      if ( varID == nvars )
 		{
-		  cdoAbort("variable >%s< not found!", p->u.opr.op[0]->u.var.nm);
+		  cdoAbort("Variable >%s< not found!", p->u.opr.op[0]->u.var.nm);
 		}
 	      else
 		{
diff --git a/src/grid.c b/src/grid.c
index 40cd811..ec8a722 100644
--- a/src/grid.c
+++ b/src/grid.c
@@ -32,13 +32,43 @@
 #include "grid.h"
 
 
-void gridToDegree(const char *units, const char *string, int gridsize, double *array)
+static
+void scale_vec(double scalefactor, long nvals, double *restrict values)
 {
-  long i;
+  long n;
+
+#if defined (_OPENMP)
+#pragma omp parallel for default(none) shared(nvals, scalefactor, values)
+#endif
+  for ( n = 0; n < nvals; ++n )
+    {
+      values[n] *= scalefactor;
+    }
+}
+
+
+void grid_to_radian(const char *units, long nvals, double *restrict values, const char *description)
+{
+  if ( memcmp(units, "degree", 6) == 0 )
+    {
+      scale_vec(DEG2RAD, nvals, values);
+    }
+  else if ( memcmp(units, "radian", 6) == 0 )
+    {
+      /* No conversion necessary */
+    }
+  else
+    {
+      cdoWarning("Unknown units [%s] supplied for %s; proceeding assuming radians!", units, description);
+    }
+}
 
+
+void grid_to_degree(const char *units, long nvals, double *restrict values, const char *description)
+{
   if ( memcmp(units, "radian", 6) == 0 )
     {
-      for ( i = 0; i < gridsize; i++ ) array[i] *= rad2deg;
+      for ( long n = 0; n < nvals; ++n ) values[n] *= RAD2DEG;
     }
   else if ( memcmp(units, "degree", 6) == 0 )
     {
@@ -46,7 +76,7 @@ void gridToDegree(const char *units, const char *string, int gridsize, double *a
     }
   else
     {
-      cdoWarning("Unknown units supplied for %s: %s", string, "proceeding assuming degrees!");
+      cdoWarning("Unknown units [%s] supplied for %s; proceeding assuming degress!", units, description);
     }
 }
 
@@ -379,8 +409,8 @@ void sinusoidal_to_geo(int gridsize, double *xvals, double *yvals)
       data.u = xvals[i];
       data.v = yvals[i];
       res = pj_inv(data, libProj);
-      xvals[i] = res.u*rad2deg;
-      yvals[i] = res.v*rad2deg;
+      xvals[i] = res.u*RAD2DEG;
+      yvals[i] = res.v*RAD2DEG;
     }
 #else
   cdoAbort("proj4 support not compiled in!");
@@ -423,8 +453,8 @@ void laea_to_geo(int gridID, int gridsize, double *xvals, double *yvals)
       data.u = xvals[i];
       data.v = yvals[i];
       res = pj_inv(data, libProj);
-      xvals[i] = res.u*rad2deg;
-      yvals[i] = res.v*rad2deg;
+      xvals[i] = res.u*RAD2DEG;
+      yvals[i] = res.v*RAD2DEG;
     }
 #else
   cdoAbort("proj4 support not compiled in!");
@@ -469,8 +499,8 @@ void lcc2_to_geo(int gridID, int gridsize, double *xvals, double *yvals)
       data.u = xvals[i];
       data.v = yvals[i];
       res = pj_inv(data, libProj);
-      xvals[i] = res.u*rad2deg;
-      yvals[i] = res.v*rad2deg;
+      xvals[i] = res.u*RAD2DEG;
+      yvals[i] = res.v*RAD2DEG;
     }
 #else
   cdoAbort("proj4 support not compiled in!");
@@ -1166,8 +1196,8 @@ int gridCurvilinearToRegular(int gridID1)
       gridInqXunits(gridID1, xunits);
       gridInqYunits(gridID1, yunits);
 
-      gridToDegree(xunits, "grid1 center lon", nx, xvals);
-      gridToDegree(yunits, "grid1 center lat", ny, yvals);
+      grid_to_degree(xunits, nx, xvals, "grid1 center lon");
+      grid_to_degree(yunits, ny, yvals, "grid1 center lat");
 
       gridDefXvals(gridID2, xvals);
       gridDefYvals(gridID2, yvals);
@@ -1471,13 +1501,13 @@ int gridGenArea(int gridID, double *area)
       {
 	for ( i = 0; i < gridsize; ++i )
 	  {
-	    grid_center_lon[i] *= deg2rad;
-	    grid_center_lat[i] *= deg2rad;
+	    grid_center_lon[i] *= DEG2RAD;
+	    grid_center_lat[i] *= DEG2RAD;
 	  }
 	for ( i = 0; i < gridsize*nv; ++i )
 	  {
-	    grid_corner_lon[i] *= deg2rad;
-	    grid_corner_lat[i] *= deg2rad;
+	    grid_corner_lon[i] *= DEG2RAD;
+	    grid_corner_lat[i] *= DEG2RAD;
 	  }
       }
     else
@@ -1507,7 +1537,7 @@ int gridGenArea(int gridID, double *area)
       //     total_area += area[i];
     }
 
-  //  if ( cdoVerbose ) cdoPrint("Total area = %g", total_area);
+  //  if ( cdoVerbose ) cdoPrint("Total area = %g steradians", total_area);
 
   free(grid_center_lon);
   free(grid_center_lat);
@@ -1546,7 +1576,7 @@ int gridGenWeights(int gridID, double *grid_area, double *grid_wgts)
       nvals++;
     }
 
-  if ( cdoVerbose ) cdoPrint("Total area = %g", total_area);
+  if ( cdoVerbose ) cdoPrint("Total area = %g steradians", total_area);
 
   for ( i = 0; i < gridsize; i++ )
     {
@@ -1613,8 +1643,8 @@ int gridWeightsOld(int gridID, double *weights)
 	  sumw = 0;
 	  for ( j = 0; j < nlat; j++ )
 	    {
-	      phi1 = (lats[j-1]+lats[j])/2*deg2rad;
-	      phi2 = (lats[j+1]+lats[j])/2*deg2rad;
+	      phi1 = (lats[j-1]+lats[j])/2*DEG2RAD;
+	      phi2 = (lats[j+1]+lats[j])/2*DEG2RAD;
 	      if ( phi1 < (-1*M_PI/2) ) phi1 = -1*M_PI/2;
 	      if ( phi1 > (   M_PI/2) ) phi1 =    M_PI/2;
 	      if ( phi2 > (   M_PI/2) ) phi2 =    M_PI/2;
@@ -1626,8 +1656,8 @@ int gridWeightsOld(int gridID, double *weights)
 		    weights[datapoint] = 0;
 		  else
 		    {
-		      theta1 = (lons[i-1]+lons[i])/2*deg2rad;
-		      theta2 = (lons[i+1]+lons[i])/2*deg2rad;
+		      theta1 = (lons[i-1]+lons[i])/2*DEG2RAD;
+		      theta2 = (lons[i+1]+lons[i])/2*DEG2RAD;
 		      weights[datapoint] = fabs((theta2-theta1)*sindphi);
 		      sumw += weights[datapoint];
 		    }
diff --git a/src/grid.h b/src/grid.h
index bd6fc80..b8e79b0 100644
--- a/src/grid.h
+++ b/src/grid.h
@@ -1,12 +1,24 @@
 #ifndef _GRID_H
 #define _GRID_H
 
-#define  deg2rad  (M_PI/180.)   /* conversion for deg to rad */
-#define  rad2deg  (180./M_PI)   /* conversion for rad to deg */
+#ifndef  M_PI
+#define  M_PI        3.14159265358979323846  /* pi */
+#endif
 
 
+#ifndef  RAD2DEG
+#define  RAD2DEG  (180./M_PI)   /* conversion for rad to deg */
+#endif
+
+#ifndef  DEG2RAD
+#define  DEG2RAD  (M_PI/180.)   /* conversion for deg to rad */
+#endif
+
+
+void grid_to_radian(const char *units, long nvals, double *restrict values, const char *description);
+void grid_to_degree(const char *units, long nvals, double *restrict values, const char *description);
+
 int referenceToGrid(int gridID);
-void gridToDegree(const char *units, const char *string, int gridsize, double *array);
 int gridToZonal(int gridID);
 int gridToMeridional(int gridID);
 int gridToUnstructured(int gridID, int lbounds);
@@ -37,8 +49,6 @@ void gme_grid(int lbounds, int gridsize, double *rlon, double *rlat,
 /* Rotated grid */
 double lamrot_to_lam(double phis, double rlas, double polphi, double pollam, double polgam);
 double phirot_to_phi(double phis, double rlas, double polphi, double polgam);
-double rl_to_rls(double phi, double rla, double polphi, double pollam);
-double ph_to_phs(double phi, double rla, double polphi, double pollam);
 void usvs_to_uv(double us, double vs, double phi, double rla,
 		double polphi, double pollam, double *u, double *v);
 
diff --git a/src/grid_rot.c b/src/grid_rot.c
index b88f877..2d1a110 100644
--- a/src/grid_rot.c
+++ b/src/grid_rot.c
@@ -1,17 +1,7 @@
 #include <stdio.h>
 #include <math.h>
 
-#ifndef M_PI
-#define M_PI		3.14159265358979323846	/* pi */
-#endif
-
-#ifndef  rad2deg
-#define  rad2deg  (180./M_PI)   /* conversion for rad to deg */
-#endif
-
-#ifndef  deg2rad
-#define  deg2rad  (M_PI/180.)   /* conversion for deg to rad */
-#endif
+#include "grid.h"
 
 
 double lamrot_to_lam(double phirot, double lamrot, double polphi, double pollam, double polgam)
@@ -35,17 +25,17 @@ double lamrot_to_lam(double phirot, double lamrot, double polphi, double pollam,
   double zphirot, zlamrot, zarg1, zarg2;
   double zgam;
 
-  zsinpol = sin(deg2rad*polphi);
-  zcospol = cos(deg2rad*polphi);
+  zsinpol = sin(DEG2RAD*polphi);
+  zcospol = cos(DEG2RAD*polphi);
 
-  zlampol = deg2rad*pollam;
-  zphirot = deg2rad*phirot;
+  zlampol = DEG2RAD*pollam;
+  zphirot = DEG2RAD*phirot;
   if ( lamrot > 180.0 ) lamrot -= 360.0;
-  zlamrot = deg2rad*lamrot;
+  zlamrot = DEG2RAD*lamrot;
 
   if ( polgam > 0 )
     {
-      zgam  = deg2rad*polgam;
+      zgam  = DEG2RAD*polgam;
       zarg1 = sin(zlampol) *                                               
  	    (- zsinpol*cos(zphirot) * (cos(zlamrot)*cos(zgam) - sin(zlamrot)*sin(zgam)) 
  	     + zcospol*sin(zphirot))                                              
@@ -68,7 +58,7 @@ double lamrot_to_lam(double phirot, double lamrot, double polphi, double pollam,
 
   if ( fabs(zarg2) < 1.0e-20 ) zarg2 = 1.0e-20;
 
-  return (rad2deg*atan2(zarg1, zarg2));
+  return (RAD2DEG*atan2(zarg1, zarg2));
 }
 
 
@@ -93,23 +83,23 @@ double phirot_to_phi(double phirot, double lamrot, double polphi, double polgam)
   double zphirot, zlamrot, zarg;
   double zgam;
 
-  zsinpol = sin(deg2rad*polphi);
-  zcospol = cos(deg2rad*polphi);
+  zsinpol = sin(DEG2RAD*polphi);
+  zcospol = cos(DEG2RAD*polphi);
 
-  zphirot   = deg2rad*phirot;
+  zphirot   = DEG2RAD*phirot;
   if ( lamrot > 180.0 ) lamrot -= 360.0;
-  zlamrot   = deg2rad*lamrot;
+  zlamrot   = DEG2RAD*lamrot;
 
   if ( polgam > 0 )
     {
-      zgam = deg2rad*polgam;
+      zgam = DEG2RAD*polgam;
       zarg = zsinpol*sin(zphirot) +
              zcospol*cos(zphirot)*(cos(zlamrot)*cos(zgam) - sin(zgam)*sin(zlamrot));
     }
   else
     zarg   = zcospol*cos(zphirot)*cos(zlamrot) + zsinpol*sin(zphirot);
 
-  return (rad2deg*asin(zarg));
+  return (RAD2DEG*asin(zarg));
 }
 
 static
@@ -128,21 +118,21 @@ double rl_to_rls(double phi, double rla, double polphi, double pollam)
   double zsinpol, zcospol, zlampol;
   double zphi, zrla, zarg1, zarg2;
 
-  zsinpol = sin(deg2rad*polphi);
-  zcospol = cos(deg2rad*polphi);
-  zlampol =     deg2rad*pollam;
+  zsinpol = sin(DEG2RAD*polphi);
+  zcospol = cos(DEG2RAD*polphi);
+  zlampol =     DEG2RAD*pollam;
 
   if ( rla > 180.0 ) rla -= 360.0;
 
-  zrla = deg2rad*rla;
-  zphi = deg2rad*phi;
+  zrla = DEG2RAD*rla;
+  zphi = DEG2RAD*phi;
 
   zarg1  = - sin(zrla-zlampol)*cos(zphi);
   zarg2  = - zsinpol*cos(zphi)*cos(zrla-zlampol)+zcospol*sin(zphi);
 
   if ( fabs(zarg2) < 1.0e-20 ) zarg2 = 1.0e-20;
 
-  return (rad2deg*atan2(zarg1,zarg2));
+  return (RAD2DEG*atan2(zarg1,zarg2));
 }
 
 static
@@ -161,17 +151,17 @@ double ph_to_phs(double phi, double rla, double polphi, double pollam)
   double zsinpol, zcospol, zlampol;
   double zphi, zrla, zarg;
 
-  zsinpol = sin(deg2rad*polphi);
-  zcospol = cos(deg2rad*polphi);
-  zlampol =     deg2rad*pollam;
+  zsinpol = sin(DEG2RAD*polphi);
+  zcospol = cos(DEG2RAD*polphi);
+  zlampol =     DEG2RAD*pollam;
 
-  zphi = deg2rad*phi;
+  zphi = DEG2RAD*phi;
   if ( rla > 180.0 ) rla -= 360.0;
-  zrla = deg2rad*rla;
+  zrla = DEG2RAD*rla;
 
   zarg = zcospol*cos(zphi)*cos(zrla-zlampol) + zsinpol*sin(zphi);
 
-  return (rad2deg*asin(zarg));
+  return (RAD2DEG*asin(zarg));
 }
 
 
@@ -195,15 +185,15 @@ void usvs_to_uv(double us, double vs, double phi, double rla,
   double zpolphi, zpollam, zrla, zphi, pollamd, zrlas, zarg, zbeta;
 
   /* umrechnung von grad in bogenmass */
-  zpolphi = polphi*deg2rad;
-  zpollam = pollam*deg2rad;
-  zrla    = rla   *deg2rad;
-  zphi    = phi   *deg2rad;
+  zpolphi = polphi*DEG2RAD;
+  zpollam = pollam*DEG2RAD;
+  zrla    = rla   *DEG2RAD;
+  zphi    = phi   *DEG2RAD;
   pollamd = pollam;
   if ( pollamd < 0.0 ) pollamd += 360.0;
 
   /* laenge im rotierten system berechnen */
-  zrlas = rl_to_rls(phi, rla, polphi, pollam)*deg2rad;
+  zrlas = rl_to_rls(phi, rla, polphi, pollam)*DEG2RAD;
 
   /* winkel zbeta berechen (schnittwinkel der breitenkreise) */
   zarg = - sin(zpolphi)*sin(zrla-zpollam)*sin(zrlas) - cos(zrla-zpollam)*cos(zrlas);
diff --git a/src/griddes.c b/src/griddes.c
index 76b3a9a..f4f080c 100644
--- a/src/griddes.c
+++ b/src/griddes.c
@@ -38,9 +38,6 @@
 #include "griddes.h"
 #include "error.h"
 
-#define  deg2rad  (M_PI/180.)   /* conversion for deg to rad */
-#define  rad2deg  (180./M_PI)   /* conversion for rad to deg */
-
 #define  cmpstr(s1, s2, len)  (memcmp(s1, s2, len = strlen(s2)))
 
 /*
@@ -667,6 +664,7 @@ double readflt(const char *filename, const char *name, const char *pline)
   return (val);
 }
 
+void str2uuid(const char *uuidstr, char *uuid);
 
 int gridFromFile(FILE *gfp, const char *dname)
 {
@@ -1357,7 +1355,7 @@ int gridFromPingo(FILE *gfp, const char *dname)
 	  gaussaw(yvals, yw, grid.ysize);
 	  free(yw);
 	  for ( i = 0; i < (int) grid.ysize; i++ )
-	    yvals[i] = asin(yvals[i])*rad2deg;
+	    yvals[i] = asin(yvals[i])*RAD2DEG;
 
 	  for ( i = 0; i < (int) grid.ysize; i++ )
 	    if ( fabs(yvals[i] - grid.yvals[i]) > ((yvals[0] - yvals[1])/500) ) break;
diff --git a/src/interpol.c b/src/interpol.c
index dbed041..06cef09 100644
--- a/src/interpol.c
+++ b/src/interpol.c
@@ -4,22 +4,22 @@
 #include "grid.h"
 #include "util.h"  /* progressStatus */
 
+#if defined (_OPENMP)
+#include <omp.h>  // omp_get_thread_num()
+#endif
 
 /**
-* Find the interval i-1 .. i in which an element x fits
-* and return i, the bigger one of the interval borders
-* or x itself if it is an interval border.
-* If the index of x is 0, return 1, thus the bigger border. (strange?)
+* Find the interval i-1 .. i in which an element x fits and return i, the 
+* bigger one of the interval borders or x itself if it is an interval border.
 *
 * If no interval can be found return the length of the array.
-* TODO: Check whether the as strange marked behavior is intended.
 
-* @param *array ascending sorted list        TODO: check whether descending also needed
+* @param *array ascending or descending sorted list
 * @param nelem  length of the sorted list
 * @param x      the element to find a position for 
 */
 static
-long find_element(double x, long nelem, const double *array)
+long find_element(double x, long nelem, const double *restrict array)
 {
   long ii;
   long mid = 0;
@@ -33,13 +33,17 @@ long find_element(double x, long nelem, const double *array)
 
       /* search for the interval in which x fits */
       // implementation: binary search algorithm
-      for ( ii = 1; ii < nelem; ii++ )
+      for ( ii = 1; ii < nelem; ++ii )
 	{
 	  // binary search: divide search room in the middle
-	  mid = first + ((last - first) / 2);
+	  // mid = first + ((last - first) >> 1);
+	  // faster!
+	  mid = (first + last) >> 1;
       
 	  /* return the bigger interval border of the interval in which x fits */
-	  if ( x >= array[mid-1] && x <= array[mid] ) break;
+	  // if ( x >= array[mid-1] && x <= array[mid] ) break;
+	  // faster!
+	  if ( !(x < array[mid-1] || x > array[mid]) ) break;
 
 	  // binary search: ignore half of the search room
 	  if ( x > array[mid] )
@@ -55,13 +59,17 @@ long find_element(double x, long nelem, const double *array)
 
       /* search for the interval in which x fits */
       // implementation: binary search algorithm
-      for ( ii = 1; ii < nelem; ii++ )
+      for ( ii = 1; ii < nelem; ++ii )
 	{
 	  // binary search: divide search room in the middle
-	  mid = first + ((last - first) / 2);
+	  // mid = first + ((last - first) >> 1);
+	  // faster!
+	  mid = (first + last) >> 1;
       
 	  /* return the bigger interval border of the interval in which x fits */
-	  if ( x >= array[mid] && x <= array[mid-1] ) break;
+	  // if ( x >= array[mid] && x <= array[mid-1] ) break;
+	  // faster!
+	  if ( !(x < array[mid] || x > array[mid-1]) ) break;
 
 	  // binary search: ignore half of the search room
 	  if ( x < array[mid] )
@@ -94,6 +102,74 @@ long find_element_old(double x, long nelem, const double *array)
 }
 */
 
+static
+int rect_grid_search(long *ii, long *jj, double x, double y, long nxm, long nym, const double *restrict xm, const double *restrict ym)
+{
+  int lfound = 0;
+
+  *jj = find_element(y, nym, ym);
+	  
+  if ( *jj < nym )
+    {
+      *ii = find_element(x, nxm, xm);
+	  
+      if ( *ii < nxm ) lfound = 1;
+    }
+
+  return (lfound);
+}
+
+static
+int rect_grid_search2(long *imin, long *imax, double xmin, double xmax, long nxm, const double *restrict xm)
+{
+  int lfound = 0;
+  int lascend = 0;
+  long i;
+  *imin = nxm;
+  *imax = -1;
+  
+  if ( xm[0] < xm[nxm-1] ) lascend = 1;
+
+  i = find_element(xmin, nxm, xm);
+
+  if ( i > 0 && i < nxm )
+    {
+      lfound = 1;
+
+      if ( lascend )
+	{
+	  if ( i > 1 && xmin <= xm[i-1] ) i--;
+	  *imin = i-1;
+	  *imax = i-1;
+	}
+      else
+	{
+	  if ( i > 1 && i < nxm-2 && xmin <= xm[i+1] ) i++;   
+	  *imin = i-1;
+	  *imax = i-1;
+	}
+
+      i = find_element(xmax, nxm, xm);
+
+      if ( i > 0 && i < nxm )
+	{
+	  if ( lascend )
+	    {
+	      if ( i > 1 && i < nxm-2 && xmax >= xm[i+1] ) i++;   
+	      *imax = i-1;
+	    }
+	  else
+	    {
+	      if ( i > 1 && xmax >= xm[i-1] ) i--;
+	      *imin = i-1;
+	    }
+	}
+    }
+  
+  return (lfound);
+}
+
+
 double intlinarr2p(long nxm, long nym, double **fieldm, const double *xm, const double *ym,
 		   double x, double y)
 {
@@ -122,51 +198,408 @@ double intlinarr2p(long nxm, long nym, double **fieldm, const double *xm, const
 }
 
 static
-void intlinarr2(double missval,
-		long nxm, long nym,  double **fieldm, const double *xm, const double *ym,
-		long gridsize2, double *field, const double *x, const double *y)
+void intlinarr2(double missval, int lon_is_circular,
+		long nxm, long nym,  const double *restrict fieldm, const double *restrict xm, const double *restrict ym,
+		long gridsize2, double *field, const double *restrict x, const double *restrict y)
 {
   long i, ii, jj;
+  long gridsize1;
+  long nlon1 = nxm;
   double findex = 0;
+  int *grid1_mask = NULL;
+
+  if ( lon_is_circular ) nlon1--;
+  gridsize1 = nlon1*nym;
+
+  grid1_mask = (int *) calloc(1, gridsize1*sizeof(int));
+  for ( jj = 0; jj < nym; ++jj )
+    for ( ii = 0; ii < nlon1; ++ii )
+      {
+	if ( !DBL_IS_EQUAL(fieldm[jj*nlon1+ii], missval) ) grid1_mask[jj*nlon1+ii] = 1;
+      }
 
   progressInit();
 
 #if defined (_OPENMP)
 #pragma omp parallel for default(none) \
-  shared(ompNumThreads, field, fieldm, x, y, xm, ym, nxm, nym, findex, gridsize2, missval) \
+  shared(ompNumThreads, field, fieldm, x, y, xm, ym, nxm, nym, gridsize2, missval, findex, nlon1, lon_is_circular, grid1_mask) \
   private(i, jj, ii)
 #endif
   for ( i = 0; i < gridsize2; ++i )
     {
+      int src_add[4];                /*  address for the four source points    */
+      long n;
+      long iix;
+      int lfound;
+      int lprogress = 1;
+#if defined (_OPENMP)
+      if ( omp_get_thread_num() != 0 ) lprogress = 0;
+#endif
+
       field[i] = missval;
 
 #if defined (_OPENMP)
 #pragma omp atomic
 #endif
       findex++;
-      if ( ompNumThreads == 1 ) progressStatus(0, 1, findex/gridsize2);
+      if ( lprogress ) progressStatus(0, 1, findex/gridsize2);
 
-      jj = find_element(y[i], nym, ym);
-	  
-      if ( jj < nym )
+      lfound = rect_grid_search(&ii, &jj, x[i], y[i], nxm, nym, xm, ym); 
+
+      if ( lfound )
 	{
-	  ii = find_element(x[i], nxm, xm);
+	  iix = ii;
+	  if ( lon_is_circular && iix == (nxm-1) ) iix = 0;
+	  src_add[0] = (jj-1)*nlon1+(ii-1);
+	  src_add[1] = (jj-1)*nlon1+(iix);
+	  src_add[2] = (jj)*nlon1+(ii-1);
+	  src_add[3] = (jj)*nlon1+(iix);
+
+	  /* Check to see if points are missing values */
+	  for ( n = 0; n < 4; ++n )
+	    if ( ! grid1_mask[src_add[n]] ) lfound = 0;
+	}
+
+      if ( lfound )
+	{
+	  double wgts[4];
+
+	  wgts[0] = (x[i]-xm[ii])   * (y[i]-ym[jj])   / ((xm[ii-1]-xm[ii]) * (ym[jj-1]-ym[jj]));
+	  wgts[1] = (x[i]-xm[ii-1]) * (y[i]-ym[jj])   / ((xm[ii]-xm[ii-1]) * (ym[jj-1]-ym[jj]));
+	  wgts[2] = (x[i]-xm[ii])   * (y[i]-ym[jj-1]) / ((xm[ii-1]-xm[ii]) * (ym[jj]-ym[jj-1]));
+	  wgts[3] = (x[i]-xm[ii-1]) * (y[i]-ym[jj-1]) / ((xm[ii]-xm[ii-1]) * (ym[jj]-ym[jj-1]));
 	  
-	  if ( ii < nxm )
+	  field[i] = 0;
+	  for ( n = 0; n < 4; ++n )
+	    field[i] += fieldm[src_add[n]] * wgts[n];
+	}
+    }
+ 
+  if ( findex < gridsize2 ) progressStatus(0, 1, 1);
+
+  if ( grid1_mask ) free(grid1_mask);
+}
+
+static
+void restrict_boundbox(const double *restrict grid_bound_box, double *restrict bound_box)
+{
+  if ( bound_box[0] < grid_bound_box[0] && bound_box[1] > grid_bound_box[0] ) bound_box[0] = grid_bound_box[0];
+  if ( bound_box[1] > grid_bound_box[1] && bound_box[0] < grid_bound_box[1] ) bound_box[1] = grid_bound_box[1];
+  //  if ( bound_box[2] < grid_bound_box[2] && bound_box[3] > grid_bound_box[2] ) bound_box[2] = grid_bound_box[2];
+  //  if ( bound_box[3] > grid_bound_box[3] && bound_box[2] < grid_bound_box[3] ) bound_box[3] = grid_bound_box[3];
+}
+
+static
+void boundbox_from_corners(long ic, long nc, const double *restrict corner_lon,
+			   const double *restrict corner_lat, double *restrict bound_box)
+{
+  long inc, j;
+  double clon, clat;
+
+    {
+      inc = ic*nc;
+      clat = corner_lat[inc];
+      clon = corner_lon[inc];
+      bound_box[0] = clat;
+      bound_box[1] = clat;
+      bound_box[2] = clon;
+      bound_box[3] = clon;
+      for ( j = 1; j < nc; ++j )
+	{
+	  clat = corner_lat[inc+j];
+	  clon = corner_lon[inc+j];
+	  if ( clat < bound_box[0] ) bound_box[0] = clat;
+	  if ( clat > bound_box[1] ) bound_box[1] = clat;
+	  if ( clon < bound_box[2] ) bound_box[2] = clon;
+	  if ( clon > bound_box[3] ) bound_box[3] = clon;
+	}
+    }
+}
+
+#if defined (HAVE_LIBYAC)
+#include "points.h"
+#include "grid_reg2d.h"
+#include "grid_search.h"
+#include "bucket_search.h"
+#include "event.h"
+#include "search.h"
+#include "clipping.h"
+#endif
+
+static
+void intconarr2(double missval, int lon_is_circular,
+		long nxm, long nym,  const double *restrict fieldm, const double *restrict xm, const double *restrict ym,
+		long nc2, long gridsize2, double *field, const double *restrict x, const double *restrict y)
+{
+  long ndeps;
+  int *deps;
+  long i, ii = -1, jj = -1;
+  long gridsize1;
+  long nlon1 = nxm;
+  double findex = 0;
+  int *grid1_mask = NULL;
+
+  printf(" nxm, nym %ld %ld\n", nxm, nym);
+  //if ( lon_is_circular ) nlon1--;
+  gridsize1 = (nxm-1)*(nym-1);
+
+  deps = (int *) malloc(gridsize1*sizeof(int));
+
+  grid1_mask = (int *) calloc(1, gridsize1*sizeof(int));
+  for ( jj = 0; jj < nym-1; ++jj )
+    for ( ii = 0; ii < nxm-1; ++ii )
+      {
+	if ( !DBL_IS_EQUAL(fieldm[jj*(nxm-1)+ii], missval) ) grid1_mask[jj*(nxm-1)+ii] = 1;
+      }
+
+  double grid1_bound_box[4];
+  grid1_bound_box[0] = ym[0];
+  grid1_bound_box[1] = ym[nym-1];
+  if ( ym[0] > ym[nym-1] )
+    {
+      grid1_bound_box[0] = ym[nym-1];
+      grid1_bound_box[1] = ym[0];
+    }
+  grid1_bound_box[2] = xm[0];
+  grid1_bound_box[3] = xm[nxm-1];
+ 
+  progressInit();
+
+#if defined (HAVE_LIBYAC)
+  enum edge_type quad_type[] = {GREAT_CIRCLE, GREAT_CIRCLE, GREAT_CIRCLE, GREAT_CIRCLE}; // not used !
+  // enum edge_type quad_type[] = {LON_CIRCLE, LON_CIRCLE, LON_CIRCLE, LON_CIRCLE};
+
+  int n;
+  double weight_sum;
+
+  double *weight;
+  weight = (double *) malloc(gridsize1*sizeof(double));
+
+  struct grid_cell *SourceCell;
+  SourceCell = malloc (gridsize1  * sizeof(*SourceCell) );
+
+  for ( int n = 0; n <  gridsize1; n++ ) {
+    SourceCell[n].num_corners   = 4;
+    SourceCell[n].edge_type     = quad_type;
+    SourceCell[n].coordinates_x = malloc (4 * sizeof(SourceCell[n].coordinates_x[0]) );
+    SourceCell[n].coordinates_y = malloc (4 * sizeof(SourceCell[n].coordinates_y[0]) );
+  }
+
+  struct grid_cell  TargetCell;
+
+  TargetCell.num_corners   = nc2;
+  TargetCell.edge_type     = quad_type;
+  TargetCell.coordinates_x = malloc (nc2 * sizeof(*TargetCell.coordinates_x) );
+  TargetCell.coordinates_y = malloc (nc2 * sizeof(*TargetCell.coordinates_y) );
+
+  unsigned const * curr_deps;
+  struct polygons polygons;
+
+  polygon_create ( &polygons );
+#endif
+
+  /*
+#if defined (_OPENMP)
+#pragma omp parallel for default(none) \
+  shared(ompNumThreads, field, fieldm, x, y, xm, ym, nxm, nym, gridsize2, missval, findex, nlon1, lon_is_circular, grid1_mask, nc2) \
+  private(i, jj, ii)
+#endif
+  */
+  for ( i = 0; i < gridsize2; ++i )
+    {
+      int src_add[4];                /*  address for the four source points    */
+      long n;
+      long iix;
+      int lfound;
+      int lprogress = 1;
+      ndeps = 0;
+      /*
+#if defined (_OPENMP)
+      if ( omp_get_thread_num() != 0 ) lprogress = 0;
+#endif
+      */
+      field[i] = missval;
+      
+      // printf("%ld lonb: %g %g %g %g latb: %g %g %g %g\n", i+1, x[i*nc2]*RAD2DEG, x[i*nc2+1]*RAD2DEG, x[i*nc2+2]*RAD2DEG, x[i*nc2+3]*RAD2DEG, y[i*nc2]*RAD2DEG, y[i*nc2+1]*RAD2DEG, y[i*nc2+2]*RAD2DEG, y[i*nc2+3]*RAD2DEG);
+
+
+      double bound_lon1, bound_lon2;
+      double bound_box[4];
+      boundbox_from_corners(i, nc2, x, y, bound_box);
+      restrict_boundbox(grid1_bound_box, bound_box);
+      bound_lon1 = bound_box[2];
+      bound_lon2 = bound_box[3];
+      //  printf("bound_box %ld  lon: %g %g lat: %g %g\n", i+1, bound_box[2]*RAD2DEG, bound_box[3]*RAD2DEG, bound_box[0]*RAD2DEG, bound_box[1]*RAD2DEG);
+      /*
+#if defined (_OPENMP)
+#pragma omp atomic
+#endif
+      */
+      findex++;
+      if ( lprogress ) progressStatus(0, 1, findex/gridsize2);
+
+      //      lfound = rect_grid_search(&ii, &jj, x[i], y[i], nxm, nym, xm, ym);
+      //     for ( int k = 0; k < nxm; ++k ) printf("x: %d %g\n", k+1, xm[k]);
+      //    for ( int k = 0; k < nym; ++k ) printf("y: %d %g\n", k+1, ym[k]*RAD2DEG);
+      long imin = nxm, imax = -1, jmin = nym, jmax = -1;
+
+      lfound = rect_grid_search2(&jmin, &jmax, bound_box[0], bound_box[1], nym, ym);
+      bound_lon1 = bound_box[2];
+      bound_lon2 = bound_box[3];
+      if ( bound_lon1 <= grid1_bound_box[3] && bound_lon2 >= grid1_bound_box[2] )
+	{
+	  //printf("b1 %g %g\n", bound_lon1*RAD2DEG, bound_lon2*RAD2DEG);
+	  if ( bound_lon1 < grid1_bound_box[2] && bound_lon2 > grid1_bound_box[2] ) bound_lon1 = grid1_bound_box[2];
+	  if ( bound_lon2 > grid1_bound_box[3] && bound_lon1 < grid1_bound_box[3] ) bound_lon2 = grid1_bound_box[3];
+	  lfound = rect_grid_search2(&imin, &imax, bound_lon1, bound_lon2, nxm, xm);
+	  //printf("imin %ld  imax %ld  jmin %ld jmax %ld\n", imin, imax, jmin, jmax);
+	  for ( long jm = jmin; jm <= jmax; ++jm )
+	    for ( long im = imin; im <= imax; ++im )
+	      deps[ndeps++] = jm*(nxm-1) + im;
+	}
+
+
+      bound_lon1 = bound_box[2];
+      bound_lon2 = bound_box[3];
+      if ( bound_lon1 <= grid1_bound_box[2] && bound_lon2 > grid1_bound_box[2] )
+	{
+	  bound_lon1 += 2*M_PI;
+	  bound_lon2 += 2*M_PI;
+	  //printf("b2 %g %g\n", bound_lon1*RAD2DEG, bound_lon2*RAD2DEG);
+	  if ( bound_lon1 < grid1_bound_box[2] && bound_lon2 > grid1_bound_box[2] ) bound_lon1 = grid1_bound_box[2];
+	  if ( bound_lon2 > grid1_bound_box[3] && bound_lon1 < grid1_bound_box[3] ) bound_lon2 = grid1_bound_box[3];
+	  lfound = rect_grid_search2(&imin, &imax, bound_lon1, bound_lon2, nxm, xm);
+	  //printf("imin %ld  imax %ld  jmin %ld jmax %ld\n", imin, imax, jmin, jmax);
+	  for ( long jm = jmin; jm <= jmax; ++jm )
+	    for ( long im = imin; im <= imax; ++im )
+	      deps[ndeps++] = jm*(nxm-1) + im;
+	}
+
+      bound_lon1 = bound_box[2];
+      bound_lon2 = bound_box[3];
+      if ( bound_lon1 < grid1_bound_box[3] && bound_lon2 >= grid1_bound_box[3] )
+	{
+	  bound_lon1 -= 2*M_PI;
+	  bound_lon2 -= 2*M_PI;
+	  //printf("b3 %g %g\n", bound_lon1*RAD2DEG, bound_lon2*RAD2DEG);
+	  if ( bound_lon1 < grid1_bound_box[2] && bound_lon2 > grid1_bound_box[2] ) bound_lon1 = grid1_bound_box[2];
+	  if ( bound_lon2 > grid1_bound_box[3] && bound_lon1 < grid1_bound_box[3] ) bound_lon2 = grid1_bound_box[3];
+	  lfound = rect_grid_search2(&imin, &imax, bound_lon1, bound_lon2, nxm, xm);
+	  //printf("imin %ld  imax %ld  jmin %ld jmax %ld\n", imin, imax, jmin, jmax);
+	  for ( long jm = jmin; jm <= jmax; ++jm )
+	    for ( long im = imin; im <= imax; ++im )
+	      deps[ndeps++] = jm*(nxm-1) + im;
+	}
+
+      //for ( long id = 0; id < ndeps; ++id )
+	//	printf("dep %ld %d\n", id+1, deps[id]);
+      /*
+      if ( bound_lon1 < grid1_bound_box[2] && bound_box[3] >= grid1_bound_box[2] )
+	lfound = rect_grid_search2(&imin, &imax, bound_box[2], bound_box[3], nxm, xm);
+      */
+
+#if defined (HAVE_LIBYAC)
+      int index2 = i;
+      /*
+      int ilat2 = index2/nlonOut;
+      int ilon2 = index2 - ilat2*nlonOut;
+      */
+      for ( int ic = 0; ic < nc2; ++ic )
+	{
+	  TargetCell.coordinates_x[ic] =  x[index2*nc2+ic];
+	  TargetCell.coordinates_y[ic] =  y[index2*nc2+ic];
+	}
+
+      if ( cdoVerbose )
+	{
+	  printf("target:\n");
+	  for ( int n = 0; n < nc2; ++n )
+	    printf(" %g %g", TargetCell.coordinates_x[n]/DEG2RAD, TargetCell.coordinates_y[n]/DEG2RAD);
+	  printf("\n");
+	}
+      /*
+      if ( cdoVerbose )
+	printf("num_deps_per_element %d %d\n", i, ndeps);
+      */
+      int num_deps = ndeps;
+      int nSourceCells = num_deps;
+
+      for ( int k = 0; k < num_deps; ++k )
+	{
+	  int index1 = deps[k];
+	  int ilat1 = index1/(nxm-1);
+	  int ilon1 = index1 - ilat1*(nxm-1);
+	  /*
+	  if ( cdoVerbose )
+	    printf("  dep: %d %d %d %d %d %d\n", k, nlonOut, nlatOut, index1, ilon1, ilat1);
+	  */
+	  if ( ym[ilat1] < ym[ilat1+1] )
+	    {
+	      SourceCell[k].coordinates_x[0] =  xm[ilon1];
+	      SourceCell[k].coordinates_y[0] =  ym[ilat1];
+	      SourceCell[k].coordinates_x[1] =  xm[ilon1+1];
+	      SourceCell[k].coordinates_y[1] =  ym[ilat1];
+	      SourceCell[k].coordinates_x[2] =  xm[ilon1+1];
+	      SourceCell[k].coordinates_y[2] =  ym[ilat1+1];
+	      SourceCell[k].coordinates_x[3] =  xm[ilon1];
+	      SourceCell[k].coordinates_y[3] =  ym[ilat1+1];
+	    }
+	  else
 	    {
-	      field[i] = fieldm[jj-1][ii-1] * (x[i]-xm[ii]) * (y[i]-ym[jj])
-		                   / ((xm[ii-1]-xm[ii]) * (ym[jj-1]-ym[jj]))
-		       + fieldm[jj-1][ii] * (x[i]-xm[ii-1]) * (y[i]-ym[jj])
-		                   / ((xm[ii]-xm[ii-1]) * (ym[jj-1]-ym[jj]))
-		       + fieldm[jj][ii-1] * (x[i]-xm[ii]) * (y[i]-ym[jj-1])
-		                  / ((xm[ii-1]-xm[ii]) * (ym[jj]-ym[jj-1]))
-		       + fieldm[jj][ii] * (x[i]-xm[ii-1]) * (y[i]-ym[jj-1])
-		                   / ((xm[ii]-xm[ii-1]) * (ym[jj]-ym[jj-1]));
+	      SourceCell[k].coordinates_x[0] =  xm[ilon1];
+	      SourceCell[k].coordinates_y[0] =  ym[ilat1+1];
+	      SourceCell[k].coordinates_x[1] =  xm[ilon1+1];
+	      SourceCell[k].coordinates_y[1] =  ym[ilat1+1];
+	      SourceCell[k].coordinates_x[2] =  xm[ilon1+1];
+	      SourceCell[k].coordinates_y[2] =  ym[ilat1];
+	      SourceCell[k].coordinates_x[3] =  xm[ilon1];
+	      SourceCell[k].coordinates_y[3] =  ym[ilat1];
+	    }
+	  if ( cdoVerbose )
+	    {
+	      printf("source: %d\n", k);
+	      for ( int n = 0; n < 4; ++n )
+		printf(" %g %g", SourceCell[k].coordinates_x[n]/DEG2RAD, SourceCell[k].coordinates_y[n]/DEG2RAD);
+	      printf("\n");
 	    }
 	}
+      
+      polygon_partial_weights(num_deps, SourceCell, TargetCell, weight, &polygons);
+
+      correct_weights ( nSourceCells, weight );
+
+      field[i] = missval;
+      if ( num_deps ) field[i] = 0;
+      for ( int k = 0; k < num_deps; ++k )
+	{
+	  int index1 = deps[k];
+	  /*
+	  int ilat1 = index1/(nxm-1);
+	  int ilon1 = index1 - ilat1*(nxm-1);
+	  long add1, add2;
+
+	  add1 = index1;
+	  add2 = index2;
+
+	  yar_store_link_cnsrv(&remap.vars, add1, add2, weight[k]);
+	  */
+	  field[i] += fieldm[index1] * weight[k];
+	  /*
+	  if ( cdoVerbose )
+	    printf("  result dep: %ld %d %d  %g\n", i, k, index1, weight[k]);
+	  */
+	}
+#endif
     }
  
+#if defined (HAVE_LIBYAC)
+  polygon_destroy ( &polygons );
+#endif
+
   if ( findex < gridsize2 ) progressStatus(0, 1, 1);
+
+  if ( deps ) free(deps);
+  if ( grid1_mask ) free(grid1_mask);
 }
 
 
@@ -201,19 +634,21 @@ void intlinarr(long nxm, double *ym, double *xm, int nx, double *y, double *x)
 }
 
 
-void intgrid(field_t *field1, field_t *field2)
+void intgridbil(field_t *field1, field_t *field2)
 {
   int nlon1, nlat1;
   int nlon2, nlat2;
   int ilat;
   int gridID1, gridID2;
   int i, nmiss;
+  int lon_is_circular;
   double *lon1, *lat1;
   double **array1_2D = NULL;
   double **field;
   double *array = NULL;
   double *array1, *array2;
   double missval;
+  char units[CDI_MAX_NAME];
   /* static int index = 0; */
 
   gridID1 = field1->grid;
@@ -225,20 +660,32 @@ void intgrid(field_t *field1, field_t *field2)
   if ( ! (gridInqXvals(gridID1, NULL) && gridInqYvals(gridID1, NULL)) )
     cdoAbort("Source grid has no values");
 
+  lon_is_circular = gridIsCircular(gridID1);
+
   nlon1 = gridInqXsize(gridID1);
   nlat1 = gridInqYsize(gridID1);
+
+  array1_2D = (double **) malloc(nlat1*sizeof(double *));
+  for ( ilat = 0; ilat < nlat1; ilat++ )
+    array1_2D[ilat] = array1 + ilat*nlon1;
+
+  if ( lon_is_circular ) nlon1 += 1;
   lon1 = (double *) malloc(nlon1*sizeof(double));
   lat1 = (double *) malloc(nlat1*sizeof(double));
   gridInqXvals(gridID1, lon1);
   gridInqYvals(gridID1, lat1);
+  if ( lon_is_circular ) lon1[nlon1-1] = 0;
+
+  gridInqXunits(gridID1, units);
+
+  grid_to_radian(units, nlon1, lon1, "grid1 center lon"); 
+  grid_to_radian(units, nlat1, lat1, "grid1 center lat"); 
+
+  if ( lon_is_circular ) lon1[nlon1-1] = lon1[0] + 2*M_PI;
 
   nlon2 = gridInqXsize(gridID2);
   nlat2 = gridInqYsize(gridID2);
 
-  array1_2D = (double **) malloc(nlat1*sizeof(double *));
-  for ( ilat = 0; ilat < nlat1; ilat++ )
-    array1_2D[ilat] = array1 + ilat*nlon1;
-
   if ( nlon2 == 1 && nlat2 == 1 )
     {
       double lon2, lat2;
@@ -246,7 +693,12 @@ void intgrid(field_t *field1, field_t *field2)
       gridInqXvals(gridID2, &lon2);
       gridInqYvals(gridID2, &lat2);
 
-      if ( lon2 < lon1[0] ) lon2 += 360;
+      gridInqXunits(gridID2, units);
+
+      grid_to_radian(units, nlon2, &lon2, "grid2 center lon"); 
+      grid_to_radian(units, nlat2, &lat2, "grid2 center lat"); 
+
+      if ( lon2 < lon1[0] ) lon2 += 2*M_PI;
 
       if ( lon2 > lon1[nlon1-1] )
 	{
@@ -260,7 +712,7 @@ void intgrid(field_t *field1, field_t *field2)
 	      array1_2D[ilat] = array + ilat*(nlon1+1);  
 	      memcpy(array1_2D[ilat], field[ilat], nlon1*sizeof(double));
 	      array1_2D[ilat][nlon1] = array1_2D[ilat][0];
-	      lon1[nlon1] = lon1[0] + 360;
+	      lon1[nlon1] = lon1[0] + 2*M_PI;
 	    }
 	  nlon1++;
 	  free(field);
@@ -298,8 +750,19 @@ void intgrid(field_t *field1, field_t *field2)
       gridInqXvals(gridID2, lon2);
       gridInqYvals(gridID2, lat2);
 
-      intlinarr2(missval,
-		 nlon1, nlat1, array1_2D, lon1, lat1,
+      gridInqXunits(gridID2, units);
+
+      grid_to_radian(units, gridsize2, lon2, "grid2 center lon"); 
+      grid_to_radian(units, gridsize2, lat2, "grid2 center lat"); 
+
+      for ( int i = 0; i < gridsize2; ++i )
+	{
+	  if ( lon2[i] < lon1[0]       ) lon2[i] += 2*M_PI;
+	  if ( lon2[i] > lon1[nlon1-1] ) lon2[i] -= 2*M_PI;
+	}
+
+      intlinarr2(missval, lon_is_circular, 
+		 nlon1, nlat1, array1, lon1, lat1,
 		 gridsize2, array2, lon2, lat2);
 
       nmiss = 0;
@@ -319,6 +782,145 @@ void intgrid(field_t *field1, field_t *field2)
 }
 
 
+void gridGenBounds1(int ny, double *yvals, double *ybounds)
+{
+  int i;
+
+  for ( i = 0; i < ny-1; i++ )
+    {
+      ybounds[i+1] = 0.5*(yvals[i] + yvals[i+1]);
+    }
+
+  ybounds[0]  = 2*yvals[0] - ybounds[1];
+  ybounds[ny] = 2*yvals[ny-1] - ybounds[ny-1];
+}
+
+
+void intgridcon(field_t *field1, field_t *field2)
+{
+  int nlon1, nlat1;
+  int nlon1b, nlat1b;
+  int nlon2, nlat2;
+  int ilat;
+  int gridID1, gridID2;
+  int i, nmiss;
+  int lon_is_circular;
+  double *lon1, *lat1;
+  double *lon1bounds, *lat1bounds;
+  double **field;
+  double *array = NULL;
+  double *array1, *array2;
+  double missval;
+  char units[CDI_MAX_NAME];
+  /* static int index = 0; */
+
+  gridID1 = field1->grid;
+  gridID2 = field2->grid;
+  array1  = field1->ptr;
+  array2  = field2->ptr;
+  missval = field1->missval;
+
+  if ( ! (gridInqXvals(gridID1, NULL) && gridInqYvals(gridID1, NULL)) )
+    cdoAbort("Source grid has no values");
+
+  lon_is_circular = gridIsCircular(gridID1);
+
+  nlon1 = gridInqXsize(gridID1);
+  nlat1 = gridInqYsize(gridID1);
+
+  lon1 = (double *) malloc(nlon1*sizeof(double));
+  lat1 = (double *) malloc(nlat1*sizeof(double));
+  gridInqXvals(gridID1, lon1);
+  gridInqYvals(gridID1, lat1);
+
+  gridInqXunits(gridID1, units);
+
+  grid_to_radian(units, nlon1, lon1, "grid1 center lon"); 
+  grid_to_radian(units, nlat1, lat1, "grid1 center lat"); 
+
+  nlon1b = nlon1 + 1;
+  nlat1b = nlat1 + 1;
+  lon1bounds = (double *) malloc(nlon1b*sizeof(double));
+  lat1bounds = (double *) malloc(nlat1b*sizeof(double));
+
+  gridGenBounds1(nlon1, lon1, lon1bounds);
+  gridGenBounds1(nlat1, lat1, lat1bounds);
+
+  for ( int i = 0; i < nlat1; ++i )
+    printf("lat1 %d %g\n", i+1, lat1[i]*RAD2DEG);
+  printf("lat1bounds: %g %g %g ... %g %g %g\n", lat1bounds[0]*RAD2DEG, lat1bounds[1]*RAD2DEG, lat1bounds[2]*RAD2DEG, lat1bounds[nlat1b-3]*RAD2DEG, lat1bounds[nlat1b-2]*RAD2DEG, lat1bounds[nlat1b-1]*RAD2DEG);
+  printf("lon1bounds: %g %g %g ... %g %g %g\n", lon1bounds[0]*RAD2DEG, lon1bounds[1]*RAD2DEG, lon1bounds[2]*RAD2DEG, lon1bounds[nlon1b-3]*RAD2DEG, lon1bounds[nlon1b-2]*RAD2DEG, lon1bounds[nlon1b-1]*RAD2DEG);
+
+  nlon2 = gridInqXsize(gridID2);
+  nlat2 = gridInqYsize(gridID2);
+
+  int gridsize2;
+
+  if ( gridInqType(gridID2) == GRID_GME ) gridID2 = gridToUnstructured(gridID2, 0);
+
+  if ( gridInqType(gridID2) != GRID_UNSTRUCTURED && gridInqType(gridID2) != GRID_CURVILINEAR )
+    gridID2 = gridToCurvilinear(gridID2, 0);
+
+  if ( ! (gridInqXvals(gridID2, NULL) && gridInqYvals(gridID2, NULL)) )
+    cdoAbort("Target grid has no values");
+
+  gridsize2 = gridInqSize(gridID2);
+
+  int nc2;
+
+  if ( gridInqType(gridID2) == GRID_UNSTRUCTURED )
+    nc2 = gridInqNvertex(gridID2);
+  else
+    nc2 = 4;
+
+  printf("nc2: %d\n", nc2);
+
+  double *grid2_corner_lon = NULL, *grid2_corner_lat = NULL;
+
+  if ( gridInqYbounds(gridID2, NULL) && gridInqXbounds(gridID2, NULL) )
+    {
+      grid2_corner_lon = (double *) malloc(nc2*gridsize2*sizeof(double));
+      grid2_corner_lat = (double *) malloc(nc2*gridsize2*sizeof(double));
+      gridInqXbounds(gridID2, grid2_corner_lon);
+      gridInqYbounds(gridID2, grid2_corner_lat);
+    }
+  else
+    {
+      cdoAbort("grid2 corner missing!");
+    }
+ 
+  gridInqXunits(gridID2, units);
+
+  grid_to_radian(units, nc2*gridsize2, grid2_corner_lon, "grid2 corner lon"); 
+  grid_to_radian(units, nc2*gridsize2, grid2_corner_lat, "grid2 corner lat"); 
+  /*
+  for ( int i = 0; i < gridsize2; ++i )
+    {
+      if ( lon2[i] < lon1[0]       ) lon2[i] += 2*M_PI;
+      if ( lon2[i] > lon1[nlon1-1] ) lon2[i] -= 2*M_PI;
+    }
+  */
+  for ( i = 0; i < gridsize2; ++i ) array2[i] = missval;
+
+  intconarr2(missval, lon_is_circular, 
+	     nlon1b, nlat1b, array1, lon1bounds, lat1bounds,
+	     nc2, gridsize2, array2, grid2_corner_lon, grid2_corner_lat);
+
+  nmiss = 0;
+  for ( i = 0; i < gridsize2; ++i )
+    if ( DBL_IS_EQUAL(array2[i], missval) ) nmiss++;
+
+  field2->nmiss = nmiss;
+
+  if (grid2_corner_lon) free(grid2_corner_lon);
+  if (grid2_corner_lat) free(grid2_corner_lat);
+
+  if (array) free(array);
+  free(lon1);
+  free(lat1);
+}
+
+
 /* source code from pingo */
 void interpolate(field_t *field1, field_t *field2)
 {
@@ -385,9 +987,9 @@ void interpolate(field_t *field1, field_t *field2)
   {
     char units[CDI_MAX_NAME];
     gridInqXunits(gridIDi, units);
-    gridToDegree(units, "grid1 center lon", nlon, lon);
+    grid_to_degree(units, nlon, lon, "grid1 center lon");
     gridInqYunits(gridIDi, units);
-    gridToDegree(units, "grid1 center lat", nlat, lat);
+    grid_to_degree(units, nlat, lat, "grid1 center lat");
   }
 
   if ( nlon > 1 )
@@ -431,9 +1033,9 @@ void interpolate(field_t *field1, field_t *field2)
   {
     char units[CDI_MAX_NAME];
     gridInqXunits(gridIDo, units);
-    gridToDegree(units, "grid2 center lon", out_nlon, lono);
+    grid_to_degree(units, out_nlon, lono, "grid2 center lon");
     gridInqYunits(gridIDo, units);
-    gridToDegree(units, "grid2 center lat", out_nlat, lato);
+    grid_to_degree(units, out_nlat, lato, "grid2 center lat");
   }
 
   for ( i = 0; i < out_nlon - 1; i++ )
diff --git a/src/interpol.h b/src/interpol.h
index d73a138..9328198 100644
--- a/src/interpol.h
+++ b/src/interpol.h
@@ -1,3 +1,4 @@
 
-void intgrid(field_t *field1, field_t *field2);
+void intgridbil(field_t *field1, field_t *field2);
+void intgridcon(field_t *field1, field_t *field2);
 void interpolate(field_t *field1, field_t *field2);
diff --git a/src/list.c b/src/list.c
index 4a79b50..1cca323 100644
--- a/src/list.c
+++ b/src/list.c
@@ -117,8 +117,31 @@ double listGetFlt(LIST *list, int num)
   return (fval);
 }
 
-
 static
+int get_ival(const char *intstr, int idefault, int istart, int iend, int *ilast)
+{
+  int ival = idefault;
+  int i;
+
+  for ( i = istart; i < iend; i++ )
+    {
+      if ( ! (isdigit(intstr[i]) || intstr[i] == '-') )
+	{
+	  if ( intstr[i] == '/' )
+	    ival = atoi(intstr+i+1);
+	  else
+	    fprintf(stderr, "Syntax error in >%.*s<! Character %c not allowed.\n",
+		    iend, intstr, intstr[i]);
+	  break;
+	}
+    }
+
+  *ilast = i;
+
+  return (ival);
+}
+
+
 void split_intstring(const char *intstr, int *first, int *last, int *inc)
 {
   int i, start;
@@ -130,34 +153,12 @@ void split_intstring(const char *intstr, int *first, int *last, int *inc)
   *inc   = 1;
 
   start = 1;
-  for ( i = start; i < istrlen; i++ )
-    {
-      if ( ! isdigit(intstr[i]) )
-	{
-	  if ( intstr[i] == '/' )
-	    *last = atoi(intstr+i+1);
-	  else
-	    fprintf(stderr, "Syntax error in >%.*s<! Character %c not allowed.\n",
-		    istrlen, intstr, intstr[i]);
-	  break;
-	}
-    }
+  *last = get_ival(intstr, *first, start, istrlen, &i);
 
   if ( i < istrlen )
     {
       start = i+1;
-      for ( i = start; i < istrlen; i++ )
-	{
-	  if ( ! isdigit(intstr[i]) )
-	    {
-	      if ( intstr[i] == '/' )
-		*inc = atoi(intstr+i+1);
-	      else
-		fprintf(stderr, "Syntax error in >%.*s<! Character %c not allowed.\n",
-			istrlen, intstr, intstr[i]);
-	      break;
-	    }
-	}
+      *inc = get_ival(intstr, 1, start, istrlen, &i);
     }
 }
 
diff --git a/src/modules.c b/src/modules.c
index 0a5c72b..02f5d96 100644
--- a/src/modules.c
+++ b/src/modules.c
@@ -126,8 +126,9 @@ void *Ninfo(void *argument);
 void *Nmltest(void *argument);
 void *Output(void *argument);
 void *Outputgmt(void *argument);
-void *Pressure(void *argument);
+void *Pack(void *argument);
 void *Pinfo(void *argument);
+void *Pressure(void *argument);
 void *Regres(void *argument);
 void *Remap(void *argument);
 void *Remapeta(void *argument);
@@ -331,7 +332,7 @@ void *Maggraph(void *argument);
 #define  ImportobsOperators     {"import_obs"}
 #define  InfoOperators          {"info", "infop", "infon", "infoc", "map"}
 #define  InputOperators         {"input", "inputsrv", "inputext"}
-#define  IntgridOperators       {"intgridbil", "intpoint", "interpolate", "boxavg", "thinout"}
+#define  IntgridOperators       {"intgridbil", "intgridcon", "intpoint", "interpolate", "boxavg", "thinout"}
 #define  IntgridtrajOperators   {"intgridtraj"}
 #define  IntlevelOperators      {"intlevel", "intlevelx"}
 #define  Intlevel3dOperators    {"intlevel3d", "intlevelx3d"}
@@ -363,8 +364,9 @@ void *Maggraph(void *argument);
                                  "outputfld", "outputarr", "outputxyz", "outputtab"}
 #define  OutputgmtOperators     {"gridverify", "outputcenter", "outputcenter2", "outputcentercpt", "outputbounds", \
                                  "outputboundscpt", "outputvector", "outputtri", "outputvrml"}
-#define  PressureOperators      {"pressure_fl", "pressure_hl", "deltap"}
+#define  PackOperators          {"pack"}
 #define  PinfoOperators         {"pinfo", "pinfov"}
+#define  PressureOperators      {"pressure_fl", "pressure_hl", "deltap"}
 #define  RegresOperators        {"regres"}
 #define  RemapOperators         {"remap"}
 #define    RemapgridOperators   {"remapcon", "remapbil", "remapbic", "remapdis", "remapnn", "remaplaf", "remapcon2", "remapsum"}
@@ -624,8 +626,9 @@ static modules_t Modules[] =
   { Nmltest,        NULL,              NmltestOperators,       CDI_REAL,  0,  0 },
   { Output,         OutputHelp,        OutputOperators,        CDI_REAL, -1,  0 },
   { Outputgmt,      NULL,              OutputgmtOperators,     CDI_REAL,  1,  0 },
-  { Pressure,       NULL,              PressureOperators,      CDI_REAL,  1,  1 },
+  { Pack,           NULL,              PackOperators,          CDI_REAL,  1,  1 },
   { Pinfo,          NULL,              PinfoOperators,         CDI_REAL,  1,  1 },
+  { Pressure,       NULL,              PressureOperators,      CDI_REAL,  1,  1 },
   { Regres,         RegresHelp,        RegresOperators,        CDI_REAL,  1,  1 },
   { Remap,          RemapHelp,         RemapOperators,         CDI_REAL,  1,  1 },
   { Remap,          RemapgridHelp,     RemapgridOperators,     CDI_REAL,  1,  1 },
diff --git a/src/operator_help.h b/src/operator_help.h
index b50b524..5568b0e 100644
--- a/src/operator_help.h
+++ b/src/operator_help.h
@@ -244,7 +244,7 @@ static char *MergegridHelp[] = {
     "    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 ",
+    "    Only rectilinear grids are supported. Both input files need to have the same variables ",
     "    and the same number of timesteps.",
     NULL
 };
@@ -421,6 +421,8 @@ static char *SelectHelp[] = {
     "    ltype     INTEGER Comma separated list of GRIB level types",
     "    levidx    INTEGER Comma separated list of index of levels",
     "    level     FLOAT   Comma separated list of vertical levels",
+    "    minute    INTEGER Comma separated list of minutes",
+    "    hour      INTEGER Comma separated list of hours",
     "    day       INTEGER Comma separated list of days",
     "    month     INTEGER Comma separated list of months",
     "    year      INTEGER Comma separated list of years",
@@ -557,18 +559,15 @@ static char *SelboxHelp[] = {
     "    selindexbox,idx1,idx2,idy1,idy2  ifile ofile",
     "",
     "DESCRIPTION",
-    "    Selects a box of the rectangular understood field.",
-    "    All input fields need to have the same horizontal grid.",
+    "    Selects a box of the rectangularly understood field. All input fields need to have the same horizontal grid.",
     "",
     "OPERATORS",
     "    sellonlatbox  Select a longitude/latitude box",
-    "                  Selects a longitude/latitude box. The user has to give the ",
-    "                  longitudes and latitudes of the edges of the box. ",
-    "                  Considered are only those grid cells with the grid center inside the lon/lat box.",
+    "                  Selects a regular longitude/latitude box. The user has to give the longitudes and latitudes of the ",
+    "                  edges of the box. Considered are only those grid cells with the grid center inside the lon/lat box.",
     "    selindexbox   Select an index box",
-    "                  Selects an index box. The user has to give the indexes of the ",
-    "                  edges of the box. The index of the left edge may be greater ",
-    "                  then that of the right edge.",
+    "                  Selects an index box. The user has to give the indexes of the edges of the box. The index of the ",
+    "                  left edge may be greater then that of the right edge.",
     "",
     "PARAMETER",
     "    lon1  FLOAT    Western longitude",
@@ -967,6 +966,9 @@ static char *SetgattHelp[] = {
     "PARAMETER",
     "    attname,attstring  STRING  Name and text of the global attribute (without spaces!)",
     "    attfile            STRING  File name which contains global text attributes",
+    "",
+    "NOTE",
+    "    Besides netCDF none of the supported data formats supports global attributes.",
     NULL
 };
 
@@ -978,7 +980,7 @@ static char *InvertHelp[] = {
     "    invertlat  ifile ofile",
     "",
     "DESCRIPTION",
-    "    This operator inverts the latitudes of all fields with a regular lon/lat grid. ",
+    "    This operator inverts the latitudes of all fields on a rectilinear grid. ",
     NULL
 };
 
@@ -1026,20 +1028,17 @@ static char *MaskboxHelp[] = {
     "    maskindexbox,idx1,idx2,idy1,idy2  ifile ofile",
     "",
     "DESCRIPTION",
-    "    Masks a box of the rectangular understood field. The elements inside ",
-    "    the box are untouched, the elements outside are set to missing value.",
-    "    All input fields need to have the same horizontal grid.",
+    "    Masked a box of the rectangularly understood field. The elements inside the box are untouched, the ",
+    "    elements outside are set to missing value. All input fields need to have the same horizontal grid.",
     "    Use sellonlatbox or selindexbox if only the data inside the box are needed.",
     "",
     "OPERATORS",
     "    masklonlatbox  Mask a longitude/latitude box",
-    "                   Masks a longitude/latitude box. The user has to give the ",
-    "                   longitudes and latitudes of the edges of the box.",
-    "                   Considered are only those grid cells with the grid center inside the lon/lat box.",
+    "                   Masked a regular longitude/latitude box. The user has to give the longitudes and latitudes of the ",
+    "                   edges of the box. Considered are only those grid cells with the grid center inside the lon/lat box.",
     "    maskindexbox   Mask an index box",
-    "                   Masks an index box. The user has to give the indexes of the ",
-    "                   edges of the box. The index of the left edge can be greater ",
-    "                   then the one of the right edge.",
+    "                   Masked an index box. The user has to give the indexes of the edges of the box. ",
+    "                   The index of the left edge can be greater then the one of the right edge.",
     "",
     "PARAMETER",
     "    lon1  FLOAT    Western longitude",
@@ -1062,10 +1061,9 @@ static char *SetboxHelp[] = {
     "    setcindexbox,c,idx1,idx2,idy1,idy2  ifile ofile",
     "",
     "DESCRIPTION",
-    "    Sets a box of the rectangular understood field to a constant value. ",
-    "    The elements outside the box are untouched, the elements inside are ",
-    "    set to the given constant. All input fields need to have the same ",
-    "    horizontal grid.",
+    "    Sets a box of the rectangularly understood field to a constant value. The elements outside ",
+    "    the box are untouched, the elements inside are set to the given constant. All input fields ",
+    "    need to have the same horizontal grid.",
     "",
     "OPERATORS",
     "    setclonlatbox  Set a longitude/latitude box to constant",
@@ -1811,9 +1809,9 @@ static char *VertstatHelp[] = {
     "    vertsum   Vertical sum",
     "              For every gridpoint the sum over all levels is computed.",
     "    vertmean  Vertical mean",
-    "              For every gridpoint the mean over all levels is computed.",
+    "              For every gridpoint the arithmetical mean over all levels is computed.",
     "    vertavg   Vertical average",
-    "              For every gridpoint the average over all levels is computed.",
+    "              For every gridpoint the arithmetical average over all levels is computed.",
     "    vertvar   Vertical variance",
     "              For every gridpoint the variance over all levels is computed.",
     "    vertstd   Vertical standard deviation",
@@ -2392,6 +2390,9 @@ static char *YearstatHelp[] = {
     "              Divisor is (n-1). For every adjacent sequence t_1, ...,t_n of timesteps of the same year it is",
     "              ",
     "              o(t,x) = var1{i(t',x), t_1 < t' <= t_n}",
+    "",
+    "NOTE",
+    "    The operators yearmean and yearavg compute only arithmetical means!",
     NULL
 };
 
@@ -3066,6 +3067,10 @@ static char *DetrendHelp[] = {
     "DESCRIPTION",
     "    Every time series in ifile is linearly detrended. For every field element x ",
     "    only those timesteps t belong to the sample S(x), which have i(t,x) NE miss.",
+    "",
+    "NOTE",
+    "    This operator has to keep the fields of all timesteps concurrently in the memory.",
+    "    If not enough memory is available use the operators trend and subtrend.",
     NULL
 };
 
@@ -3232,6 +3237,11 @@ static char *RemapgridHelp[] = {
     "    REMAP_AREA_MIN   ",
     "        This variable is used to set the minimum destination area fraction. The default",
     "        of this variable is 0.0.",
+    "",
+    "NOTE",
+    "    For this module the author has converted the original Fortran 90 SCRIP ",
+    "    software to ANSI C99. If there are any problems send a bug report to CDO and",
+    "    not to SCRIP!",
     NULL
 };
 
@@ -3288,6 +3298,11 @@ static char *GenweightsHelp[] = {
     "    REMAP_AREA_MIN   ",
     "        This variable is used to set the minimum destination area fraction. The default",
     "        of this variable is 0.0.",
+    "",
+    "NOTE",
+    "    For this module the author has converted the original Fortran 90 SCRIP ",
+    "    software to ANSI C99. If there are any problems send a bug report to CDO and",
+    "    not to SCRIP!",
     NULL
 };
 
@@ -3317,6 +3332,11 @@ static char *RemapHelp[] = {
     "    REMAP_AREA_MIN   ",
     "        This variable is used to set the minimum destination area fraction. The default",
     "        of this variable is 0.0.",
+    "",
+    "NOTE",
+    "    For this module the author has converted the original Fortran 90 SCRIP ",
+    "    software to ANSI C99. If there are any problems send a bug report to CDO and",
+    "    not to SCRIP!",
     NULL
 };
 
@@ -3328,12 +3348,11 @@ static char *RemapetaHelp[] = {
     "    remapeta,vct[,oro]  ifile ofile",
     "",
     "DESCRIPTION",
-    "    This operator interpolates between different vertical hybrid levels. ",
-    "    This include the preparation of consistent data for the free atmosphere.",
-    "    The procedure for the vertical interpolation is based on the HIRLAM scheme",
-    "    and was adapted from INTERA.",
-    "    The vertical interpolation is based on the vertical integration of the",
-    "    hydrostatic equation with few adjustments. The basic tasks are the following one:",
+    "    This operator interpolates between different vertical hybrid levels. This include the preparation ",
+    "    of consistent data for the free atmosphere. The procedure for the vertical interpolation is based ",
+    "    on the HIRLAM scheme and was adapted from INTERA.",
+    "    The vertical interpolation is based on the vertical integration of the hydrostatic equation with ",
+    "    few adjustments. The basic tasks are the following one:",
     "    - at first integration of hydrostatic equation",
     "    - extrapolation of surface pressure",
     "    - Planetary Boundary-Layer (PBL) profile interpolation",
@@ -3341,20 +3360,16 @@ static char *RemapetaHelp[] = {
     "    - merging of both profiles",
     "    - final surface pressure correction",
     "    ",
-    "    The vertical interpolation corrects the surface pressure. This is simply",
-    "    a cut-off or an addition of air mass. This mass correction should not",
-    "    influence the geostrophic velocity field in the middle troposhere. Therefore",
-    "    the total mass above a given reference level is conserved. As reference level",
-    "    the geopotential height of the 400 hPa level is used. Near the surface the",
-    "    correction can affect the vertical structure of the PBL. Therefore the",
-    "    interpolation is done using the potential temperature. But in the free",
-    "    atmosphere above a certain n (n=0.8 defining the top of the PBL) the",
-    "    interpolation is done linearly. After the interpolation both profiles",
-    "    are merged. With the resulting temperature/pressure correction the hydrostatic",
-    "    equation is integrated again and adjusted to the reference level finding",
-    "    the final surface pressure correction. A more detailed description of",
-    "    the interpolation can be found in INTERA.",
-    "    All input fields have to be on the same horizontal grid.",
+    "    The vertical interpolation corrects the surface pressure. This is simply a cut-off or an addition ",
+    "    of air mass. This mass correction should not influence the geostrophic velocity field in the middle ",
+    "    troposhere. Therefore the total mass above a given reference level is conserved. As reference level",
+    "    the geopotential height of the 400 hPa level is used. Near the surface the correction can affect ",
+    "    the vertical structure of the PBL. Therefore the interpolation is done using the potential temperature. ",
+    "    But in the free atmosphere above a certain n (n=0.8 defining the top of the PBL) the interpolation ",
+    "    is done linearly. After the interpolation both profiles are merged. With the resulting ",
+    "    temperature/pressure correction the hydrostatic equation is integrated again and adjusted to the ",
+    "    reference level finding the final surface pressure correction. A more detailed description of",
+    "    the interpolation can be found in INTERA. All input fields have to be on the same horizontal grid.",
     "",
     "PARAMETER",
     "    vct  STRING  File name of an ASCII dataset with the vertical coordinate table",
@@ -3365,6 +3380,22 @@ static char *RemapetaHelp[] = {
     "        Sets the minimum pressure level for condensation.",
     "        Above this level the humidity is set to the constant 1.E-6.",
     "        The default value is 0 Pa.",
+    "",
+    "NOTE",
+    "    The code numbers or the variable names of the required parameter have to follow the ECHAM convention.",
+    "    Presently, the vertical coordinate definition of a netCDF file has also to follow the ECHAM convention.",
+    "    This means:",
+    "    - the dimension of the full level coordinate and the corresponding variable is called mlev,",
+    "    - the dimension of the half level coordinate and the corresponding variable is called ilev (ilev must have one element more than mlev)",
+    "    - the hybrid vertical coefficient a is given in units of Pa and called hyai (hyam for level midpoints)",
+    "    - the hybrid vertical coefficient b is given in units of 1 and called hybi (hybm for level midpoints)",
+    "    - the mlev variable has a borders attribute containing the character string 'ilev'",
+    "    ",
+    "    Use the sinfo command to test if your vertical coordinate system is recognized as hybrid system.",
+    "    ",
+    "    In case remapeta complains about not finding any data on hybrid model levels you may wish",
+    "    to use the setzaxis command to generate a zaxis description which conforms to the ECHAM convention.",
+    "    See section \"1.4 Z-axis description\" for an example how to define a hybrid Z-axis.",
     NULL
 };
 
@@ -3401,6 +3432,10 @@ static char *IntvertHelp[] = {
     "ENVIRONMENT",
     "    EXTRAPOLATE",
     "        If set to 1 extrapolate missing values.",
+    "",
+    "NOTE",
+    "    The netCDF CF convention for vertical hybrid coordinates is ",
+    "    not supported, yet!",
     NULL
 };
 
@@ -3631,6 +3666,9 @@ static char *ImportbinaryHelp[] = {
     "    Here is a list of the supported components:",
     "    BYTESWAPPED, CHSUB, DSET, ENDVARS, FILEHEADER, HEADERBYTES, OPTIONS, TDEF, TITLE, ",
     "    TRAILERBYTES, UNDEF, VARS, XDEF, XYHEADER, YDEF, ZDEF",
+    "",
+    "NOTE",
+    "    Only 32-bit IEEE floats are supported for standard binary files!",
     NULL
 };
 
@@ -3675,6 +3713,11 @@ static char *ImportcmsafHelp[] = {
     "    satellite projection, additional files with arrays of latitudes and longitudes are needed.",
     "    These can be obtained from CM-SAF together with the data.",
     "    ",
+    "",
+    "NOTE",
+    "    To use this operator, it is necessary to build CDO with HDF5 support (version 1.6 or higher).",
+    "    The PROJ.4 library (version 4.6 or higher) is needed for full support of the remapping",
+    "    functionality. ",
     NULL
 };
 
@@ -3779,11 +3822,10 @@ static char *GradsdesHelp[] = {
     "    <operator>  ifile",
     "",
     "DESCRIPTION",
-    "    Creates a GrADS data descriptor file. Supported file formats are GRIB1,",
-    "    SERVICE, EXTRA and IEG. For GRIB1 files the GrADS map file is also ",
-    "    generated. For SERVICE and EXTRA files the grid have to be specified with",
-    "    the CDO option '-g <grid>'. This module takes ifile in order to create ",
-    "    filenames for the descriptor (ifile.ctl) and the map (ifile.gmp) file.",
+    "    Creates a GrADS data descriptor file. Supported file formats are GRIB1, netCDF, SERVICE, ",
+    "    EXTRA and IEG. For GRIB1 files the GrADS map file is also generated. For SERVICE and EXTRA",
+    "    files the grid have to be specified with the CDO option '-g <grid>'. This module takes ifile",
+    "    in order to create filenames for the descriptor (ifile.ctl) and the map (ifile.gmp) file.",
     "    \"gradsdes\" is an alias for gradsdes2.",
     "",
     "OPERATORS",
@@ -4102,12 +4144,11 @@ static char *SethaloHelp[] = {
     "    sethalo,lhalo,rhalo  ifile ofile",
     "",
     "DESCRIPTION",
-    "    This operator sets the left and right bounds of the rectangularly",
-    "    understood fields. Positive numbers of the parameter lhalo enlarges ",
-    "    the left bound by the given number of columns from the right bound. The",
-    "    parameter rhalo does the similar for the right bound.",
-    "    Negative numbers of the parameter lhalo/rhalo can be used to remove",
-    "    the given number of columns of the left and right bounds.",
+    "    This operator sets the left and right bounds of the rectangularly understood fields.",
+    "    Positive numbers of the parameter lhalo enlarges the left bound by the given ",
+    "    number of columns from the right bound. The parameter rhalo does the similar ",
+    "    for the right bound. Negative numbers of the parameter lhalo/rhalo can ",
+    "    be used to remove the given number of columns of the left and right bounds.",
     "",
     "PARAMETER",
     "    lhalo  INTEGER  Left halo",
@@ -4736,6 +4777,10 @@ static char *EcaPdHelp[] = {
     "",
     "PARAMETER",
     "    x  FLOAT   Daily precipitation amount threshold in [mm]",
+    "",
+    "NOTE",
+    "    Precipitation rates in [mm/s] have to be converted to precipitation amounts (multiply with 86400 s).",
+    "    Apart from metadata information the result of eca_pd,1 and eca_rr1 is the same.",
     NULL
 };
 
diff --git a/src/pipe.h b/src/pipe.h
index 324a5c4..c373d99 100644
--- a/src/pipe.h
+++ b/src/pipe.h
@@ -58,6 +58,7 @@ typedef struct {
   char         **mfnames;
   varlist_t     *varlist;
 #if  defined  (HAVE_LIBPTHREAD)
+  void          *argument;
   struct pipe_s *pipe;
   pthread_t     rthreadID; /* read  thread ID */
   pthread_t     wthreadID; /* write thread ID */
diff --git a/src/process.c b/src/process.c
index 90a685e..358b418 100644
--- a/src/process.c
+++ b/src/process.c
@@ -56,31 +56,31 @@ operator_t;
 
 typedef struct {
 #if  defined  (HAVE_LIBPTHREAD)
-  pthread_t threadID;
-  int       l_threadID;
+  pthread_t   threadID;
+  int         l_threadID;
 #endif
-  short      nchild;
-  short      nstream;
-  short      streams[MAX_STREAM];
-  double     s_utime;
-  double     s_stime;
-  double     a_utime;
-  double     a_stime;
-  double     cputime;
-
-  off_t      nvals;
-  short      nvars;
-  int        ntimesteps;
-  short      streamCnt;
-  char     **streamNames;
-  char      *xoperator;
-  char      *operatorName;
-  char      *operatorArg;
-  int        oargc;
-  char      *oargv[MAX_OARGC];
-  char       prompt[64];
-  short      noper;
-  operator_t operator[MAX_OPERATOR];
+  short       nchild;
+  short       nstream;
+  short       streams[MAX_STREAM];
+  double      s_utime;
+  double      s_stime;
+  double      a_utime;
+  double      a_stime;
+  double      cputime;
+
+  off_t       nvals;
+  short       nvars;
+  int         ntimesteps;
+  short       streamCnt;
+  argument_t *streamNames;
+  char       *xoperator;
+  char       *operatorName;
+  char       *operatorArg;
+  int         oargc;
+  char       *oargv[MAX_OARGC];
+  char        prompt[64];
+  short       noper;
+  operator_t  operator[MAX_OPERATOR];
 }
 process_t;
 
@@ -330,14 +330,14 @@ const char *processInqPrompt(void)
   return (Process[processID].prompt);
 }
 
-/* Convert a wildcard pattern into a list of blank-separated
-   filenames which match the wildcard.  */
-char *glob_pattern(const char *restrict wildcard)
+#if  defined  (HAVE_GLOB_H)
+/* Convert a wildcard pattern into a list of blank-separated filenames which match the wildcard. */
+argument_t *glob_pattern(const char *restrict wildcard)
 {
-  char *gfilename;
   size_t cnt, length = 0;
   glob_t glob_results;
   char **p;
+  argument_t *argument = NULL;
 
   glob(wildcard, GLOB_NOCHECK, 0, &glob_results);
 
@@ -346,18 +346,20 @@ char *glob_pattern(const char *restrict wildcard)
     length += strlen(*p) + 1;
 
   /* Allocate the space and generate the list.  */
-  gfilename = (char *) calloc(length, sizeof(char));
-  for ( p = glob_results.gl_pathv, cnt = glob_results.gl_pathc; cnt; p++, cnt-- )
+  argument = argument_new(glob_results.gl_pathc, length);
+
+  for ( cnt = 0; cnt < glob_results.gl_pathc; cnt++ )
     {
-      strcat(gfilename, *p);
-      if ( cnt > 1 ) strcat(gfilename, " ");
+      argument->argv[cnt] = strdupx(glob_results.gl_pathv[cnt]);
+      strcat(argument->args, glob_results.gl_pathv[cnt]);
+      if ( cnt < glob_results.gl_pathc-1 ) strcat(argument->args, " ");
     }
 
   globfree(&glob_results);
 
-  return gfilename;
+  return argument;
 }
-
+#endif
 
 int cdoStreamCnt(void)
 {
@@ -370,14 +372,14 @@ int cdoStreamCnt(void)
 }
 
 
-const char *cdoStreamName(int cnt)
+const argument_t *cdoStreamName(int cnt)
 {
   int processID = processSelf();
 
   if ( cnt > Process[processID].streamCnt || cnt < 0 )
     Error("count %d out of range!", cnt);
 
-  return (Process[processID].streamNames[cnt]);
+  return (&(Process[processID].streamNames[cnt]));
 }
 
 
@@ -423,12 +425,7 @@ int getGlobArgc(int argc, char *argv[], int globArgc)
   char *opername;
   char *comma_position;
   const char *caller = processInqPrompt();
-  /*
-  { int i;
-  for ( i = 0; i < argc; i++ )
-    printf("%d %d %s\n", globArgc, i, argv[i]);
-  }
-  */
+
   opername = &argv[globArgc][1];
   comma_position = strchr(opername, ',');
   if ( comma_position ) *comma_position = 0;
@@ -436,22 +433,7 @@ int getGlobArgc(int argc, char *argv[], int globArgc)
   streamInCnt  = operatorStreamInCnt(opername);
   streamOutCnt = operatorStreamOutCnt(opername);
 
-  if ( streamInCnt == -1 )
-    {
-      /*
-      int i;
-
-      for ( i = globArgc+1; i < argc; i++ )
-	if ( argv[i][0] == '-' ) break;
-
-      printf("%d %d %d\n", i, argc, globArgc);
-      if ( i < argc )
-      */
-      streamInCnt = 1;
-      /*
-      Errorc("Unlimited input streams not allowed in CDO pipes (Operator %s)!", opername);
-      */
-    }
+  if ( streamInCnt == -1 ) streamInCnt = 1;
 
   if ( streamOutCnt > 1 )
     Errorc("More than one output stream not allowed in CDO pipes (Operator %s)!", opername);
@@ -515,7 +497,7 @@ static
 void setStreamNames(int argc, char *argv[])
 {
   int processID = processSelf();
-  int i;
+  int i, ac;
   int globArgc = 1;
   int globArgcStart;
   char *streamname;
@@ -523,28 +505,43 @@ void setStreamNames(int argc, char *argv[])
 
   while ( globArgc < argc )
     {
-      //     printf("arg %d %d %s\n", argc, globArgc, argv[globArgc]);
       if ( argv[globArgc][0] == '-' )
 	{
 	  globArgcStart = globArgc;
 
 	  globArgc = getGlobArgc(argc, argv, globArgc);
-	  //	  printf("globArgc %d\n", globArgc);
 	  len = 0;
 	  for ( i = globArgcStart; i < globArgc; i++ ) len += strlen(argv[i]) + 1;
-	  streamname = (char *) malloc(len);
-	  memcpy(streamname, argv[globArgcStart], len);
+	  streamname = (char *) calloc(1, len);
+	  for ( i = globArgcStart; i < globArgc; i++ )
+	    {
+	      strcat(streamname, argv[i]);
+	      if ( i < globArgc-1 ) strcat(streamname, " ");
+	    }
 	  for ( i = 1; i < len-1; i++ ) if ( streamname[i] == '\0' ) streamname[i] = ' ';
-	  Process[processID].streamNames[Process[processID].streamCnt++] = streamname;
-	  // printf("streamname1: %s\n", streamname);
+	  Process[processID].streamNames[Process[processID].streamCnt].args = streamname;
+	  ac = globArgc - globArgcStart;
+	  //printf("setStreamNames:  ac %d  streamname1: %s\n", ac, streamname);
+	  Process[processID].streamNames[Process[processID].streamCnt].argv = (char **) malloc(ac*sizeof(char *));
+	  for ( i = 0; i < ac; ++i )
+	    Process[processID].streamNames[Process[processID].streamCnt].argv[i] = argv[i+globArgcStart];
+	  Process[processID].streamNames[Process[processID].streamCnt].argc = ac;
+	  Process[processID].streamCnt++;
+	  //printf("setStreamNames:  streamname1: %s\n", streamname);
 	}
       else
 	{
 	  len = strlen(argv[globArgc]) + 1;
 	  streamname = (char *) malloc(len);
 	  strcpy(streamname, argv[globArgc]);
-	  Process[processID].streamNames[Process[processID].streamCnt++] = streamname;
-	  // printf("streamname2: %s\n", streamname);
+	  Process[processID].streamNames[Process[processID].streamCnt].args = streamname;
+	  ac = 1;
+	  Process[processID].streamNames[Process[processID].streamCnt].argv = (char **) malloc(ac*sizeof(char *));
+	  Process[processID].streamNames[Process[processID].streamCnt].argv[0] = argv[globArgc];
+	  Process[processID].streamNames[Process[processID].streamCnt].argc = ac;
+	  Process[processID].streamNames[Process[processID].streamCnt].args = streamname;
+	  Process[processID].streamCnt++;
+	  //printf("setStreamNames:  streamname2: %s\n", streamname);
 	  globArgc++;
 	}
     }
@@ -554,64 +551,45 @@ static
 int expand_wildcards(int processID, int streamCnt)
 {
   int i;
-  const char *streamname0 = Process[processID].streamNames[0];
+  const char *streamname0 = Process[processID].streamNames[0].args;
   int len = strlen(streamname0);
 
-  for ( i = 0; i < len; ++i ) if ( streamname0[i] == '?' || streamname0[i] == '*' ) break;
+  for ( i = 0; i < len; ++i ) if ( streamname0[i] == '?' || streamname0[i] == '*' || streamname0[i] == '[' ) break;
   if ( i < len )
     {
 #if  defined  (HAVE_GLOB_H)
-      char *pattern = glob_pattern(streamname0);
-      if ( strcmp(streamname0, pattern) != 0 )
+      argument_t *glob_arg = glob_pattern(streamname0);
+
+      if ( strcmp(streamname0, glob_arg->args) != 0 )
 	{
-	  int gargc = 0;
-	  char *gargv[MAX_FILES];
-	  int len;
-	  gargv[gargc++] = pattern;
-	  len = strlen(pattern);
-	  for ( i = 1; i < len; ++i )
-	    if ( pattern[i] == ' ' )
-	      {
-		pattern[i] = 0;
-		i++;
-		gargv[gargc++] = &pattern[i];
-		if ( gargc >= MAX_FILES )
-		  Error("Internal problem! More than %d arguments.", MAX_FILES);
-	      }
-
-	  // for ( i = 0; i < gargc; ++i ) printf("pattern %d >%s<\n", i+1, gargv[i]);
-
-	  streamCnt = streamCnt - 1 + gargc;
-	  
-	  /*
-	  for ( i = 0; i < Process[processID].streamCnt; ++i )
-	    printf("stream %d <%s>\n", i+1, Process[processID].streamNames[i]);
-	  */
-	  Process[processID].streamNames = (char **) realloc(Process[processID].streamNames, streamCnt*sizeof(char *));
+	  streamCnt = streamCnt - 1 + glob_arg->argc;
+
+	  free(Process[processID].streamNames[0].argv);
+	  free(Process[processID].streamNames[0].args);
+
+	  Process[processID].streamNames = (argument_t *) realloc(Process[processID].streamNames, streamCnt*sizeof(argument_t));
 	      
 	  // move output streams to the end
 	  for ( i = 1; i < Process[processID].streamCnt; ++i )
-	    Process[processID].streamNames[i+gargc-1] = Process[processID].streamNames[i];
+	    Process[processID].streamNames[i+glob_arg->argc-1] = Process[processID].streamNames[i];
 
-	  free(Process[processID].streamNames[0]);
-
-	  for ( i = 0; i < gargc; ++i )
+	  for ( i = 0; i < glob_arg->argc; ++i )
 	    {
-	      char *streamname;
-	      len = strlen(gargv[i]) + 1;
-	      streamname = (char *) malloc(len);
-	      strcpy(streamname, gargv[i]);
-	      Process[processID].streamNames[i] = streamname;
+	      // printf("add %d %s\n", i, glob_arg->argv[i]);
+	      Process[processID].streamNames[i].argv    = (char **) malloc(sizeof(char *));
+	      Process[processID].streamNames[i].argc    = 1;
+	      Process[processID].streamNames[i].argv[0] = strdupx(glob_arg->argv[i]);
+	      Process[processID].streamNames[i].args    = strdupx(glob_arg->argv[i]);
 	    }
 	  
 	  Process[processID].streamCnt = streamCnt;
 	  /*
 	  for ( i = 0; i < Process[processID].streamCnt; ++i )
-	    printf("stream %d <%s>\n", i+1, Process[processID].streamNames[i]);
+	    printf("expand_wildcards: ostream %d <%s>\n", i+1, Process[processID].streamNames[i].args);
 	  */
 	}
-      
-      free(pattern);
+
+      free(glob_arg);
 #else
       cdoAbort("Wildcards support not compiled in!");
 #endif
@@ -674,17 +652,17 @@ int checkStreamCnt(void)
 
   for ( i = streamInCnt; i < streamCnt; i++ )
     {
-      if ( Process[processID].streamNames[i][0] == '-' )
+      if ( Process[processID].streamNames[i].args[0] == '-' )
 	{
 	  Errorc("Output file name %s must not begin with \"-\"!\n",
-		 Process[processID].streamNames[i]);
+		 Process[processID].streamNames[i].args);
 	}
       else if ( !obase )
 	{
 	  for ( j = 0; j < streamInCnt; j++ ) /* does not work with files in pipes */
-	    if ( strcmp(Process[processID].streamNames[i], Process[processID].streamNames[j]) == 0 )
+	    if ( strcmp(Process[processID].streamNames[i].args, Process[processID].streamNames[j].args) == 0 )
 	      Errorc("Output file name %s is equal to input file name"
-		     " on position %d!\n", Process[processID].streamNames[i], j+1);
+		     " on position %d!\n", Process[processID].streamNames[i].args, j+1);
 	}
     }
 
@@ -695,32 +673,12 @@ int checkStreamCnt(void)
 }
 
 static
-void setStreams(const char *argument)
+void setStreams(int argc, char *argv[])
 {
   int processID = processSelf();
   int streamCnt;
-  int i;
   int status;
-  int argc = 0;
-  char *argv[MAX_FILES];
-  char *string;
-  size_t arglen;
-
-  arglen = 1 + strlen(argument);
-  string = (char *) malloc(arglen);
-  strcpy(string, argument);
-
-  argv[argc++] = string;
-  for ( i = 1; i < (int) arglen-1; i++ )
-    {
-      if ( string[i] == ' ' )
-	{
-	  string[i] = '\0';
-	  argv[argc++] = &string[i+1];
-	  if ( argc >= MAX_FILES )
-	    Error("Internal problem! More than %d arguments.", MAX_FILES);
-	}
-    }
+  int i;
 
   streamCnt = getStreamCnt(argc, argv);
 
@@ -730,8 +688,13 @@ void setStreams(const char *argument)
 
   Process[processID].streamCnt  = 0; /* filled in setStreamNames */
   if ( streamCnt )
-    Process[processID].streamNames = (char **) malloc(streamCnt*sizeof(char *));
-  for ( i = 0; i < streamCnt; i++ ) Process[processID].streamNames[i] = NULL;
+    Process[processID].streamNames = (argument_t *) malloc(streamCnt*sizeof(argument_t));
+  for ( i = 0; i < streamCnt; i++ )
+    {
+      Process[processID].streamNames[i].argc = 0;
+      Process[processID].streamNames[i].argv = NULL;
+      Process[processID].streamNames[i].args = NULL;
+    }
 
   setStreamNames(argc, argv);
 
@@ -739,26 +702,24 @@ void setStreams(const char *argument)
 
   if ( status == 0 && Process[processID].streamCnt != streamCnt )
     Error("Internal problem with stream count %d %d", Process[processID].streamCnt, streamCnt);
-
   /*
   for ( i = 0; i < streamCnt; i++ )
-    fprintf(stderr, "stream %d %s\n", i+1, Process[processID].streamNames[i]);
+    fprintf(stderr, "setStreams: stream %d %s\n", i+1, Process[processID].streamNames[i].args);
   */
-
-  free(argv[0]);
 }
 
 
-void processDefArgument(const char *argument)
+void processDefArgument(void *vargument)
 {
   int processID = processSelf();
   char *operatorArg;
   char *commapos;
   int oargc = 0;
   char **oargv = Process[processID].oargv;
+  int argc = ((argument_t *) vargument)->argc;
+  char **argv = ((argument_t *) vargument)->argv;
 
-  /* printf("argument: %s\n", argument); */
-  Process[processID].xoperator    = getOperator(argument);
+  Process[processID].xoperator    = argv[0];
   Process[processID].operatorName = getOperatorName(Process[processID].xoperator);
   Process[processID].operatorArg  = getOperatorArg(Process[processID].xoperator);
   operatorArg = Process[processID].operatorArg;
@@ -766,7 +727,7 @@ void processDefArgument(const char *argument)
   if ( operatorArg )
     {
       oargv[oargc++] = operatorArg;
-      /*printf("%d %s\n", oargc, operatorArg);*/
+      //fprintf(stderr, "processDefArgument: %d %s\n", oargc, operatorArg);
 
       commapos = operatorArg;
       while ( (commapos = strchr(commapos, ',')) != NULL )
@@ -785,7 +746,7 @@ void processDefArgument(const char *argument)
 
   processDefPrompt(Process[processID].operatorName);
 
-  setStreams(argument);
+  setStreams(argc, argv);
 }
 
 
diff --git a/src/process.h b/src/process.h
index bb8a7ef..4ad92ec 100644
--- a/src/process.h
+++ b/src/process.h
@@ -31,7 +31,7 @@ int  processInqStreamID(int streamindex);
 void processAddStream(int streamID);
 void processDelStream(int streamID);
 void processDefVarNum(int nvars, int streamID);
-void processDefArgument(const char *argument);
+void processDefArgument(void *vargument);
 
 void processStartTime(double *utime, double *stime);
 void processEndTime(double *utime, double *stime);
diff --git a/src/pstream.c b/src/pstream.c
index 8bae20f..5a3310e 100644
--- a/src/pstream.c
+++ b/src/pstream.c
@@ -201,6 +201,7 @@ void pstream_init_entry(pstream_t *pstreamptr)
   pstreamptr->mfnames    = NULL;
   pstreamptr->varlist    = NULL;
 #if  defined  (HAVE_LIBPTHREAD)
+  pstreamptr->argument   = NULL;
   pstreamptr->pipe       = NULL;
   //  pstreamptr->rthreadID  = 0;
   //  pstreamptr->wthreadID  = 0;
@@ -298,10 +299,8 @@ int pstreamIsPipe(int pstreamID)
 }
 
 
-int pstreamOpenRead(const char *argument)
+int pstreamOpenRead(const argument_t *argument)
 {
-  char *operatorArg = NULL;
-  char *operatorName = NULL;
   int ispipe = FALSE;
   int fileID;
   int pstreamID;
@@ -314,11 +313,17 @@ int pstreamOpenRead(const char *argument)
 
   pstreamID = pstreamptr->self;
 
-  ispipe = argument[0] == '-';
-
+  ispipe = argument->args[0] == '-';
+  /*
+  printf("pstreamOpenRead: args >%s<\n", argument->args);
+  for ( int i = 0; i < argument->argc; ++i )
+    printf("pstreamOpenRead: arg %d >%s<\n", i, argument->argv[i]);
+  */
   if ( ispipe )
     {
 #if  defined  (HAVE_LIBPTHREAD)
+      char *operatorArg;
+      char *operatorName;
       char *newarg;
       char *pipename = (char *) malloc(16);
       int rval;
@@ -328,22 +333,34 @@ int pstreamOpenRead(const char *argument)
       size_t len;
       size_t stacksize;
       int status;
+      argument_t *newargument = (argument_t *) malloc(sizeof(argument_t));
 
-      operatorArg = getOperator(argument);
+      newargument->argc = argument->argc + 1;
+      newargument->argv = (char **) malloc(newargument->argc*sizeof(char *));
+      memcpy(newargument->argv, argument->argv, argument->argc*sizeof(char *));
+
+      operatorArg  = argument->argv[0];
       operatorName = getOperatorName(operatorArg);
-      free(operatorArg);
 
-      len = strlen(argument);
+      len = strlen(argument->args);
       newarg = (char *) malloc(len+16);
-      strcpy(newarg, argument);
+      strcpy(newarg, argument->args);
       sprintf(pipename, "(pipe%d.%d)", processSelf() + 1, processInqChildNum() + 1);
       newarg[len] = ' ';
       strcpy(&newarg[len+1], pipename);
 
-      pstreamptr->ispipe = TRUE;
-      pstreamptr->name   = pipename;
+      newargument->argv[argument->argc] = pipename;
+      newargument->args = newarg;
+      /*
+      printf("pstreamOpenRead: new args >%s<\n", newargument->args);
+      for ( int i = 0; i < newargument->argc; ++i )
+	printf("pstreamOpenRead: new arg %d >%s<\n", i, newargument->argv[i]);
+      */
+      pstreamptr->ispipe    = TRUE;
+      pstreamptr->name      = pipename;
       pstreamptr->rthreadID = pthread_self();
-      pstreamptr->pipe   = pipeNew();
+      pstreamptr->pipe      = pipeNew();
+      pstreamptr->argument  = (void *) newargument;
  
       if ( ! cdoSilentMode )
 	fprintf(stderr, "%s: Started child process \"%s\".\n", processInqPrompt(), newarg+1);
@@ -373,7 +390,8 @@ int pstreamOpenRead(const char *argument)
 	  stacksize = 2097152;
 	  pthread_attr_setstacksize(&attr, stacksize);
 	}
-      rval = pthread_create(&thrID, &attr, operatorModule(operatorName), newarg);
+
+      rval = pthread_create(&thrID, &attr, operatorModule(operatorName), newargument);
       if ( rval != 0 )
 	{
 	  errno = rval;
@@ -396,17 +414,17 @@ int pstreamOpenRead(const char *argument)
       char *filename = NULL;
       const char *pch;
 
-      len = strlen(argument);
+      len = strlen(argument->args);
 
       for ( i = 0; i < len; i++ )
-	if ( argument[i] == ':' ) break;
+	if ( argument->args[i] == ':' ) break;
 
       if ( i < len )
 	{
-	  pch = &argument[i+1];
+	  pch = &argument->args[i+1];
 	  len -= (i+1);
-	  if ( len && ( memcmp(argument, "filelist:", 9) == 0 || 
-			memcmp(argument, "flist:", 6) == 0 ) )
+	  if ( len && ( memcmp(argument->args, "filelist:", 9) == 0 || 
+			memcmp(argument->args, "flist:", 6) == 0 ) )
 	    {
 	      for ( i = 0; i < len; i++ ) if ( pch[i] == ',' ) nfiles++;
 
@@ -424,8 +442,7 @@ int pstreamOpenRead(const char *argument)
 		  nfiles = 0;
 		  while ( readline(fp, line, 4096) )
 		    {
-		      if ( line[0] == '#' || line[0] == '\0' ||
-			   line[0] == ' ' ) continue;
+		      if ( line[0] == '#' || line[0] == '\0' || line[0] == ' ' ) continue;
 
 		      fp2 = fopen(line, "r" );
 		      if ( fp2 == NULL ) cdoAbort("Open failed on %s", line);
@@ -472,7 +489,7 @@ int pstreamOpenRead(const char *argument)
 		    }
 		}
 	    }
-	  else if ( len && memcmp(argument, "ls:", 3) == 0 )
+	  else if ( len && memcmp(argument->args, "ls:", 3) == 0 )
 	    {
 	      char line[4096];
 	      char command[4096];
@@ -512,25 +529,9 @@ int pstreamOpenRead(const char *argument)
 	}
       else
 	{
-	  len = strlen(argument);
-	  /*
-	  if ( cdoExpMode == CDO_EXP_REMOTE )
-	    {
-	      char datapath[] = "/scratch/localA/m214003/data/";
-	      len += strlen(datapath);
-
-	      filename = (char *) malloc(len+1);
-
-	      strcpy(filename, datapath);
-	      strcat(filename, argument);
-	    }
-	  else
-	  */
-	    {
-	      filename = (char *) malloc(len+1);
-
-	      strcpy(filename, argument);
-	    }
+	  len = strlen(argument->args);
+	  filename = (char *) malloc(len+1);
+	  strcpy(filename, argument->args);
 	}
 
       if ( PSTREAM_Debug ) Message("file %s", filename);
@@ -563,7 +564,7 @@ int pstreamOpenRead(const char *argument)
       pstreamptr->fileID = fileID;
     }
 
-  if ( pstreamID < 0 ) cdiError(pstreamID, "Open failed on %s", argument);
+  if ( pstreamID < 0 ) cdiError(pstreamID, "Open failed on %s", argument->args);
   
   return (pstreamID);
 }
@@ -627,7 +628,7 @@ void query_user_exit(const char *argument)
 }
 
 
-int pstreamOpenWrite(const char *argument, int filetype)
+int pstreamOpenWrite(const argument_t *argument, int filetype)
 {
   int fileID;
   int pstreamID = -1;
@@ -636,14 +637,14 @@ int pstreamOpenWrite(const char *argument, int filetype)
 
   PSTREAM_INIT();
 
-  ispipe = memcmp(argument, "(pipe", 5) == 0;
+  ispipe = memcmp(argument->args, "(pipe", 5) == 0;
 
   if ( ispipe )
     {
 #if  defined  (HAVE_LIBPTHREAD)
-      if ( PSTREAM_Debug ) Message("pipe %s", argument);
-      pstreamID = pstreamFindID(argument);
-      if ( pstreamID == -1 ) Error("%s is not open!", argument);
+      if ( PSTREAM_Debug ) Message("pipe %s", argument->args);
+      pstreamID = pstreamFindID(argument->args);
+      if ( pstreamID == -1 ) Error("%s is not open!", argument->args);
 
       pstreamptr = pstream_to_pointer(pstreamID);
 
@@ -655,14 +656,14 @@ int pstreamOpenWrite(const char *argument, int filetype)
   else
     {
       /* extern int cdoDefaultInstID; */
-      char *filename = (char *) malloc(strlen(argument)+1);
+      char *filename = (char *) malloc(strlen(argument->args)+1);
 
       pstreamptr = pstream_new_entry();
       if ( ! pstreamptr ) Error("No memory");
 
       pstreamID = pstreamptr->self;
   
-      if ( PSTREAM_Debug ) Message("file %s", argument);
+      if ( PSTREAM_Debug ) Message("file %s", argument->args);
 
       if ( filetype == CDI_UNDEFID ) filetype = FILETYPE_GRB;
 
@@ -671,9 +672,9 @@ int pstreamOpenWrite(const char *argument, int filetype)
 	  int rstatus;
 	  struct stat stbuf;
 
-	  rstatus = stat(argument, &stbuf);
+	  rstatus = stat(argument->args, &stbuf);
 	  /* If permanent file already exists, query user whether to overwrite or exit */
-	  if ( rstatus != -1 ) query_user_exit(argument);
+	  if ( rstatus != -1 ) query_user_exit(argument->args);
 	}
 
       if ( processNums() == 1 && ompNumThreads == 1 ) timer_start(timer_write);
@@ -683,7 +684,7 @@ int pstreamOpenWrite(const char *argument, int filetype)
       else
 	pthread_mutex_lock(&streamOpenWriteMutex);
 #endif
-      fileID = streamOpenWrite(argument, filetype);
+      fileID = streamOpenWrite(argument->args, filetype);
 #if  defined  (HAVE_LIBPTHREAD)
       if ( cdoLockIO )
 	pthread_mutex_unlock(&streamMutex);
@@ -691,7 +692,7 @@ int pstreamOpenWrite(const char *argument, int filetype)
 	pthread_mutex_unlock(&streamOpenWriteMutex);
 #endif
       if ( processNums() == 1 && ompNumThreads == 1 ) timer_stop(timer_write);
-      if ( fileID < 0 ) cdiError(fileID, "Open failed on %s", argument);
+      if ( fileID < 0 ) cdiError(fileID, "Open failed on %s", argument->args);
 
       cdoDefHistory(fileID, commandLine());
 
@@ -730,7 +731,7 @@ int pstreamOpenWrite(const char *argument, int filetype)
       if ( cdoDefaultInstID != CDI_UNDEFID )
 	streamDefInstID(fileID, cdoDefaultInstID);
       */
-      strcpy(filename, argument);
+      strcpy(filename, argument->args);
 
       pstreamptr->mode     = 'w';
       pstreamptr->name     = filename;
@@ -742,30 +743,30 @@ int pstreamOpenWrite(const char *argument, int filetype)
 }
 
 
-int pstreamOpenAppend(const char *argument)
+int pstreamOpenAppend(const argument_t *argument)
 {
   int fileID;
   int pstreamID = -1;
   int ispipe;
   pstream_t *pstreamptr;
 
-  ispipe = memcmp(argument, "(pipe", 5) == 0;
+  ispipe = memcmp(argument->args, "(pipe", 5) == 0;
 
   if ( ispipe )
     {
-      if ( PSTREAM_Debug ) Message("pipe %s", argument);
+      if ( PSTREAM_Debug ) Message("pipe %s", argument->args);
       cdoAbort("this operator doesn't work with pipes!");
     }
   else
     {
-      char *filename = (char *) malloc(strlen(argument)+1);
+      char *filename = (char *) malloc(strlen(argument->args)+1);
 
       pstreamptr = pstream_new_entry();
       if ( ! pstreamptr ) Error("No memory");
 
       pstreamID = pstreamptr->self;
   
-      if ( PSTREAM_Debug ) Message("file %s", argument);
+      if ( PSTREAM_Debug ) Message("file %s", argument->args);
 
       if ( processNums() == 1 && ompNumThreads == 1 ) timer_start(timer_write);
 #if  defined  (HAVE_LIBPTHREAD)
@@ -774,7 +775,7 @@ int pstreamOpenAppend(const char *argument)
       else
 	pthread_mutex_lock(&streamOpenReadMutex);
 #endif
-      fileID = streamOpenAppend(argument);
+      fileID = streamOpenAppend(argument->args);
 #if  defined  (HAVE_LIBPTHREAD)
       if ( cdoLockIO )
 	pthread_mutex_unlock(&streamMutex);
@@ -782,12 +783,12 @@ int pstreamOpenAppend(const char *argument)
 	pthread_mutex_unlock(&streamOpenReadMutex);
 #endif
       if ( processNums() == 1 && ompNumThreads == 1 ) timer_stop(timer_write);
-      if ( fileID < 0 ) cdiError(fileID, "Open failed on %s", argument);
+      if ( fileID < 0 ) cdiError(fileID, "Open failed on %s", argument->args);
       /*
       cdoInqHistory(fileID);
       cdoDefHistory(fileID, commandLine());
       */
-      strcpy(filename, argument);
+      strcpy(filename, argument->args);
 
       pstreamptr->mode   = 'a';
       pstreamptr->name   = filename;
@@ -837,8 +838,21 @@ void pstreamClose(int pstreamID)
 
 	  pthread_join(pstreamptr->wthreadID, NULL);
 
+	  pthread_mutex_lock(pipe->mutex);
+	  if ( pstreamptr->name ) free(pstreamptr->name);
+	  if ( pstreamptr->argument )
+	    {
+	      argument_t *argument = (argument_t *) (pstreamptr->argument);
+	      if ( argument->argv ) free(argument->argv);
+	      if ( argument->args ) free(argument->args);
+	      free(argument);
+	    }
+	  vlistDestroy(pstreamptr->vlistID);
+	  pthread_mutex_unlock(pipe->mutex);
+
 	  processAddNvals(pipe->nvals);
 	  pipeDelete(pipe);
+
 	  pstream_delete_entry(pstreamptr);
 	}
       else
@@ -1233,8 +1247,8 @@ void pstreamCheckDatarange(pstream_t *pstreamptr, int varID, double *array, int
       if ( datatype == DATATYPE_INT8  || datatype == DATATYPE_UINT8 ||
 	   datatype == DATATYPE_INT16 || datatype == DATATYPE_UINT16 )
 	{
-	  smin = NINTD(smin);
-	  smax = NINTD(smax);
+	  smin = (int) NINTD(smin);
+	  smax = (int) NINTD(smax);
 	}
 
       if      ( datatype == DATATYPE_INT8   ) { vmin =        -128.; vmax =        127.; }
@@ -1511,7 +1525,7 @@ void cdoInitialize(void *argument)
      Message("process %d  thread %ld", processSelf(), pthread_self());
 #endif
 
-  processDefArgument((const char*) argument);
+  processDefArgument(argument);
 }
 
 
diff --git a/src/pstream.h b/src/pstream.h
index 4d98d21..e9eead6 100644
--- a/src/pstream.h
+++ b/src/pstream.h
@@ -42,9 +42,9 @@
 #define  streamCopyRecord         pstreamCopyRecord
 
 
-int     pstreamOpenWrite(const char *streamname, int filetype);
-int     pstreamOpenRead(const char *streamname);
-int     pstreamOpenAppend(const char *streamname);
+int     pstreamOpenWrite(const argument_t *argument, int filetype);
+int     pstreamOpenRead(const argument_t *argument);
+int     pstreamOpenAppend(const argument_t *argument);
 void    pstreamClose(int pstreamID);
 
 int     pstreamInqFiletype(int pstreamID);
diff --git a/src/realtime.c b/src/realtime.c
index eb4bb23..24166d6 100644
--- a/src/realtime.c
+++ b/src/realtime.c
@@ -52,13 +52,13 @@ double util_walltime(void)
   static double time_init = 0.;
 
   struct timeval tbuf;
-  if (gettimeofday(&tbuf,NULL) == -1) perror("UTIL_WALLTIME");
+  if ( gettimeofday(&tbuf,NULL) == -1 ) perror("UTIL_WALLTIME");
 
-  if (time_init == 0.) time_init =
-    (double) tbuf.tv_sec + (tbuf.tv_usec / 1000000.0);
+  // if ( time_init == 0. )
+  if ( !(time_init < 0. || 0. < time_init) )
+    time_init = (double) tbuf.tv_sec + (tbuf.tv_usec * 1.0e-6);
 
-  time_in_secs =
-  (double) tbuf.tv_sec + (tbuf.tv_usec / 1000000.0) - time_init;
+  time_in_secs = (double) tbuf.tv_sec + (tbuf.tv_usec * 1.0e-6) - time_init;
 #endif
 
   return (time_in_secs);
@@ -227,16 +227,14 @@ void util_get_real_time_size(int *rt_size)
 
 void util_read_real_time(void *it)
 { 
-  double *t;
-  t = (double *) it;
+  double *t = (double *) it;
   *t=util_walltime();
 }
 
 void util_diff_real_time(void *it1, void *it2, double *t)
 {
-  double *t1, *t2;
-  t1 = (double*) it1;
-  t2 = (double*) it2;
+  double *t1 = (double*) it1;
+  double *t2 = (double*) it2;
   *t = *t2 - *t1;
 } 
 
diff --git a/src/remap.h b/src/remap.h
index 22637aa..279efaa 100644
--- a/src/remap.h
+++ b/src/remap.h
@@ -184,3 +184,5 @@ void write_remap_scrip(const char *interp_file, int map_type, int submap_type,
 		       int remap_order, remapgrid_t rg, remapvars_t rv);
 void read_remap_scrip(const char *interp_file, int gridID1, int gridID2, int *map_type, int *submap_type,
 		      int *remap_order, remapgrid_t *rg, remapvars_t *rv);
+
+void store_link_bilin(remapvars_t *rv, int dst_add, const int *restrict src_add, const double *restrict weights);
diff --git a/src/remaplib.c b/src/remaplib.c
index b9934de..21c0fd5 100644
--- a/src/remaplib.c
+++ b/src/remaplib.c
@@ -529,20 +529,6 @@ void boundbox_from_center(int lonIsCyclic, long size, long nx, long ny, const do
     }
 }
 
-static
-void scale2(long nvals, double scalefactor, double *restrict vec1, double *restrict vec2)
-{
-  long n;
-
-#if defined (_OPENMP)
-#pragma omp parallel for default(none) shared(nvals, scalefactor, vec1, vec2)
-#endif
-  for ( n = 0; n < nvals; ++n )
-    {
-      vec1[n] *= scalefactor;
-      vec2[n] *= scalefactor;
-    }
-}
 
 static
 void check_lon_range(long nlons, double *lons)
@@ -764,8 +750,12 @@ void calc_lat_bins(remapgrid_t *rg, int map_type)
   if ( cdoVerbose )
     cdoPrint("Using %d latitude bins to restrict search.", nbins);
 
-  rg->bin_lats  = (restr_t *) realloc(rg->bin_lats, 2*nbins*sizeof(restr_t));
-  rg->bin_lons  = (restr_t *) realloc(rg->bin_lons, 2*nbins*sizeof(restr_t));
+  if ( nbins > 0 )
+    {
+      rg->bin_lats  = (restr_t *) realloc(rg->bin_lats, 2*nbins*sizeof(restr_t));
+      rg->bin_lons  = (restr_t *) realloc(rg->bin_lons, 2*nbins*sizeof(restr_t));
+    }
+
   for ( n = 0; n < nbins; ++n )
     {
       n2 = n<<1;
@@ -775,7 +765,7 @@ void calc_lat_bins(remapgrid_t *rg, int map_type)
       rg->bin_lons[n2+1] = RESTR_SCALE(PI2);
     }
 
-  rg->bin_addr1 = (int *) realloc(rg->bin_addr1, 2*nbins*sizeof(int));
+  if ( nbins > 0 ) rg->bin_addr1 = (int *) realloc(rg->bin_addr1, 2*nbins*sizeof(int));
   for ( n = 0; n < nbins; ++n )
     {
       n2 = n<<1;
@@ -810,7 +800,7 @@ void calc_lat_bins(remapgrid_t *rg, int map_type)
 
   if ( map_type == MAP_TYPE_CONSERV )
     {
-      rg->bin_addr2 = (int *) realloc(rg->bin_addr2, 2*nbins*sizeof(int));
+      if ( nbins > 0 ) rg->bin_addr2 = (int *) realloc(rg->bin_addr2, 2*nbins*sizeof(int));
       for ( n = 0; n < nbins; ++n )
 	{
 	  n2 = n<<1;
@@ -1139,21 +1129,13 @@ void remapGridInit(int map_type, int lextrapolate, int gridID1, int gridID2, rem
 
   gridInqYunits(gridID1, units);
 
-  if ( memcmp(units, "degree", 6) == 0 )
-    {
-      scale2(rg->grid1_size, DEG2RAD, rg->grid1_center_lat, rg->grid1_center_lon);
-
-      /* Note: using units from latitude instead from bounds */
-      if ( rg->grid1_corners && rg->lneed_grid1_corners )
-	scale2(rg->grid1_corners*rg->grid1_size, DEG2RAD, rg->grid1_corner_lat, rg->grid1_corner_lon);
-    }
-  else if ( memcmp(units, "radian", 6) == 0 )
-    {
-      /* No conversion necessary */
-    }
-  else
+  grid_to_radian(units, rg->grid1_size, rg->grid1_center_lon, "grid1 center lon"); 
+  grid_to_radian(units, rg->grid1_size, rg->grid1_center_lat, "grid1 center lat"); 
+  /* Note: using units from latitude instead from bounds */
+  if ( rg->grid1_corners && rg->lneed_grid1_corners )
     {
-      cdoWarning("Unknown units supplied for grid1 center lat/lon: proceeding assuming radians");
+      grid_to_radian(units, rg->grid1_corners*rg->grid1_size, rg->grid1_corner_lon, "grid1 corner lon"); 
+      grid_to_radian(units, rg->grid1_corners*rg->grid1_size, rg->grid1_corner_lat, "grid1 corner lat"); 
     }
 
   if ( lgrid1_destroy ) gridDestroy(gridID1);
@@ -1211,21 +1193,13 @@ void remapGridInit(int map_type, int lextrapolate, int gridID1, int gridID2, rem
 
   gridInqYunits(gridID2, units);
 
-  if ( memcmp(units, "degree", 6) == 0 )
-    {
-      scale2(rg->grid2_size, DEG2RAD, rg->grid2_center_lat, rg->grid2_center_lon);
-
-      /* Note: using units from latitude instead from bounds */
-      if ( rg->grid2_corners && rg->lneed_grid2_corners )
-	scale2( rg->grid2_corners*rg->grid2_size, DEG2RAD, rg->grid2_corner_lat, rg->grid2_corner_lon);
-    }
-  else if ( memcmp(units, "radian", 6) == 0 )
-    {
-      /* No conversion necessary */
-    }
-  else
+  grid_to_radian(units, rg->grid2_size, rg->grid2_center_lon, "grid2 center lon"); 
+  grid_to_radian(units, rg->grid2_size, rg->grid2_center_lat, "grid2 center lat"); 
+  /* Note: using units from latitude instead from bounds */
+  if ( rg->grid2_corners && rg->lneed_grid2_corners )
     {
-      cdoWarning("Unknown units supplied for grid2 center lat/lon: proceeding assuming radians");
+      grid_to_radian(units, rg->grid2_corners*rg->grid2_size, rg->grid2_corner_lon, "grid2 corner lon"); 
+      grid_to_radian(units, rg->grid2_corners*rg->grid2_size, rg->grid2_corner_lat, "grid2 corner lat"); 
     }
 
   if ( lgrid2_destroy ) gridDestroy(gridID2);
@@ -1333,7 +1307,7 @@ void remapGridInit(int map_type, int lextrapolate, int gridID1, int gridID2, rem
     Set up and assign address ranges to search bins in order to 
     further restrict later searches
   */
-  if ( rg->restrict_type == RESTRICT_LATITUDE )
+  if ( rg->restrict_type == RESTRICT_LATITUDE || rg->restrict_type == 0 )
     {
       calc_lat_bins(rg, map_type);
     }
@@ -2065,7 +2039,6 @@ int grid_search(remapgrid_t *rg, int *restrict src_add, double *restrict src_lat
   This routine stores the address and weight for four links associated with one destination
   point in the appropriate address and weight arrays and resizes those arrays if necessary.
 */
-static
 void store_link_bilin(remapvars_t *rv, int dst_add, const int *restrict src_add, const double *restrict weights)
 {
   /*
@@ -2189,10 +2162,11 @@ void remap_bilin(remapgrid_t *rg, remapvars_t *rv)
   double plat, plon;             /*  lat/lon coords of destination point    */
   double iguess, jguess;         /*  current guess for bilinear coordinate  */
   double sum_wgts;               /*  sum of weights for normalization       */
+  double findex = 0;
 
   if ( cdoTimer ) timer_start(timer_remap_bil);
 
-  if ( ompNumThreads == 1 ) progressInit();
+  progressInit();
 
   grid2_size = rg->grid2_size;
 
@@ -2205,7 +2179,7 @@ void remap_bilin(remapgrid_t *rg, remapvars_t *rv)
 
 #if defined (_OPENMP)
 #pragma omp parallel for default(none) \
-  shared(ompNumThreads, cdoTimer, cdoVerbose, grid2_size, rg, rv, Max_Iter, converge, lwarn) \
+  shared(ompNumThreads, cdoTimer, cdoVerbose, grid2_size, rg, rv, Max_Iter, converge, lwarn, findex) \
   private(dst_add, n, icount, iter, src_add, src_lats, src_lons, \
 	  wgts, plat, plon, iguess, jguess, sum_wgts, search_result)					\
   schedule(dynamic,1)
@@ -2213,7 +2187,15 @@ void remap_bilin(remapgrid_t *rg, remapvars_t *rv)
   /* grid_loop1 */
   for ( dst_add = 0; dst_add < grid2_size; ++dst_add )
     {
-      if ( ompNumThreads == 1 ) progressStatus(0, 1, (dst_add+1.)/grid2_size);
+      int lprogress = 1;
+#if defined (_OPENMP)
+      if ( omp_get_thread_num() != 0 ) lprogress = 0;
+#endif
+#if defined (_OPENMP)
+#pragma omp atomic
+#endif
+      findex++;
+      if ( lprogress ) progressStatus(0, 1, findex/grid2_size);
 
       if ( ! rg->grid2_mask[dst_add] ) continue;
 
@@ -2389,8 +2371,9 @@ void remap_bicub(remapgrid_t *rg, remapvars_t *rv)
   double plat, plon;             /*  lat/lon coords of destination point    */
   double iguess, jguess;         /*  current guess for bilinear coordinate  */
   double sum_wgts;               /*  sum of weights for normalization       */
+  double findex = 0;
 
-  if ( ompNumThreads == 1 ) progressInit();
+  progressInit();
 
   /* Compute mappings from grid1 to grid2 */
 
@@ -2401,15 +2384,22 @@ void remap_bicub(remapgrid_t *rg, remapvars_t *rv)
 
 #if defined (_OPENMP)
 #pragma omp parallel for default(none) \
-  shared(ompNumThreads, cdoTimer, cdoVerbose, rg, rv, Max_Iter, converge, lwarn)	\
-  private(dst_add, n, icount, iter, src_add, src_lats, src_lons, wgts, plat, plon, iguess, jguess, \
-	  sum_wgts, search_result)					\
+  shared(ompNumThreads, cdoTimer, cdoVerbose, rg, rv, Max_Iter, converge, lwarn, findex) \
+  private(dst_add, n, icount, iter, src_add, src_lats, src_lons, wgts, plat, plon, iguess, jguess, sum_wgts, search_result)					\
   schedule(dynamic,1)
 #endif
   /* grid_loop1 */
   for ( dst_add = 0; dst_add < rg->grid2_size; ++dst_add )
     {
-      if ( ompNumThreads == 1 ) progressStatus(0, 1, (dst_add+1.)/rg->grid2_size);
+      int lprogress = 1;
+#if defined (_OPENMP)
+      if ( omp_get_thread_num() != 0 ) lprogress = 0;
+#endif
+#if defined (_OPENMP)
+#pragma omp atomic
+#endif
+      findex++;
+      if ( lprogress ) progressStatus(0, 1, findex/rg->grid2_size);
 
       if ( ! rg->grid2_mask[dst_add] ) continue;
 
@@ -2754,8 +2744,9 @@ void remap_distwgt(remapgrid_t *rg, remapvars_t *rv)
   double *coslat, *sinlat; /* cosine, sine of grid lats (for distance)    */
   double *coslon, *sinlon; /* cosine, sine of grid lons (for distance)    */
   double wgtstmp;          /* hold the link weight                        */
+  double findex = 0;
 
-  if ( ompNumThreads == 1 ) progressInit();
+  progressInit();
 
   /* Compute mappings from grid1 to grid2 */
 
@@ -2785,14 +2776,22 @@ void remap_distwgt(remapgrid_t *rg, remapvars_t *rv)
   /* grid_loop1 */
 #if defined (_OPENMP)
 #pragma omp parallel for default(none) \
-  shared(ompNumThreads, cdoTimer, rg, rv, grid2_size, coslat, coslon, sinlat, sinlon)	\
+  shared(ompNumThreads, cdoTimer, rg, rv, grid2_size, coslat, coslon, sinlat, sinlon, findex) \
   private(dst_add, n, coslat_dst, coslon_dst, sinlat_dst, sinlon_dst, dist_tot, \
 	  nbr_add, nbr_dist, nbr_mask, wgtstmp)	\
   schedule(dynamic,1)
 #endif
   for ( dst_add = 0; dst_add < grid2_size; ++dst_add )
     {
-      if ( ompNumThreads == 1 ) progressStatus(0, 1, (dst_add+1.)/grid2_size);
+      int lprogress = 1;
+#if defined (_OPENMP)
+      if ( omp_get_thread_num() != 0 ) lprogress = 0;
+#endif
+#if defined (_OPENMP)
+#pragma omp atomic
+#endif
+      findex++;
+      if ( lprogress ) progressStatus(0, 1, findex/grid2_size);
 
       if ( ! rg->grid2_mask[dst_add] ) continue;
 
@@ -2985,10 +2984,11 @@ void remap_distwgt1(remapgrid_t *rg, remapvars_t *rv)
   double *coslat, *sinlat; /* cosine, sine of grid lats (for distance)    */
   double *coslon, *sinlon; /* cosine, sine of grid lons (for distance)    */
   double wgtstmp;          /* hold the link weight                        */
+  double findex = 0;
 
   if ( cdoTimer ) timer_start(timer_remap_nn);
 
-  if ( ompNumThreads == 1 ) progressInit();
+  progressInit();
 
   /* Compute mappings from grid1 to grid2 */
 
@@ -3018,14 +3018,21 @@ void remap_distwgt1(remapgrid_t *rg, remapvars_t *rv)
   /* grid_loop1 */
 #if defined (_OPENMP)
 #pragma omp parallel for default(none) \
-  shared(ompNumThreads, cdoTimer, rg, rv, grid2_size, coslat, coslon, sinlat, sinlon)	\
-  private(dst_add, n, coslat_dst, coslon_dst, sinlat_dst, sinlon_dst,   \
-	  nbr_add, nbr_dist, nbr_mask, wgtstmp)	\
+  shared(ompNumThreads, cdoTimer, rg, rv, grid2_size, coslat, coslon, sinlat, sinlon, findex) \
+  private(dst_add, n, coslat_dst, coslon_dst, sinlat_dst, sinlon_dst, nbr_add, nbr_dist, nbr_mask, wgtstmp)	\
   schedule(dynamic,1)
 #endif
   for ( dst_add = 0; dst_add < grid2_size; ++dst_add )
     {
-      if ( ompNumThreads == 1 ) progressStatus(0, 1, (dst_add+1.)/grid2_size);
+      int lprogress = 1;
+#if defined (_OPENMP)
+      if ( omp_get_thread_num() != 0 ) lprogress = 0;
+#endif
+#if defined (_OPENMP)
+#pragma omp atomic
+#endif
+      findex++;
+      if ( lprogress ) progressStatus(0, 1, findex/grid2_size);
 
       if ( ! rg->grid2_mask[dst_add] ) continue;
 
@@ -4478,8 +4485,9 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
   int avoid_pole_count = 0;         /* count attempts to avoid pole  */
   double avoid_pole_offset = TINY;  /* endpoint offset to avoid pole */
   grid_store_t *grid_store = NULL;
+  double findex = 0;
 
-  if ( ompNumThreads == 1 ) progressInit();
+  progressInit();
 
   nbins = rg->num_srch_bins;
 
@@ -4568,9 +4576,8 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
 #if defined (_OPENMP)
 #pragma omp parallel for default(none) \
   shared(ompNumThreads, cdoTimer, nbins, grid1_centroid_lon, grid1_centroid_lat, \
-         grid_store, link_add1, link_add2,	 \
-         rv, cdoVerbose, max_subseg, \
-	 grid1_corners,	srch_corners, rg, grid2_size, grid1_size, srch_add2) \
+         grid_store, link_add1, link_add2, rv, cdoVerbose, max_subseg, \
+	 grid1_corners,	srch_corners, rg, grid2_size, grid1_size, srch_add2, findex) \
   private(ompthID, srch_add, n, k, num_srch_cells, max_srch_cells, \
 	  grid1_add, grid2_add, ioffset, nsrch_corners, corner, next_corn, beglat, beglon, \
 	  endlat, endlon, lrevers, begseg, lbegin, num_subseg, srch_corner_lat, srch_corner_lon, \
@@ -4579,12 +4586,17 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
 #endif
   for ( grid1_add = 0; grid1_add < grid1_size; ++grid1_add )
     {
+      int lprogress = 1;
 #if defined (_OPENMP)
       ompthID = omp_get_thread_num();
       srch_add = srch_add2[ompthID];
+      if ( ompthID != 0 ) lprogress = 0;
 #endif
-
-      if ( ompNumThreads == 1 ) progressStatus(0, 0.5, (grid1_add+1.)/grid1_size);
+#if defined (_OPENMP)
+#pragma omp atomic
+#endif
+      findex++;
+      if ( lprogress ) progressStatus(0, 0.5, findex/grid1_size);
 
       lthresh   = FALSE;
       luse_last = FALSE;
@@ -4785,12 +4797,13 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
 
   if ( cdoTimer ) timer_start(timer_remap_con_l2);
 
+  findex = 0;
+
 #if defined (_OPENMP)
 #pragma omp parallel for default(none) \
   shared(ompNumThreads, cdoTimer, nbins, grid2_centroid_lon, grid2_centroid_lat, \
-         grid_store, link_add1, link_add2, \
-         rv, cdoVerbose, max_subseg, \
-	 grid2_corners, srch_corners, rg, grid2_size, grid1_size, srch_add2) \
+         grid_store, link_add1, link_add2, rv, cdoVerbose, max_subseg, \
+	 grid2_corners, srch_corners, rg, grid2_size, grid1_size, srch_add2, findex) \
   private(ompthID, srch_add, n, k, num_srch_cells, max_srch_cells, \
 	  grid1_add, grid2_add, ioffset, nsrch_corners, corner, next_corn, beglat, beglon, \
 	  endlat, endlon, lrevers, begseg, lbegin, num_subseg, srch_corner_lat, srch_corner_lon, \
@@ -4799,12 +4812,17 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
 #endif
   for ( grid2_add = 0; grid2_add < grid2_size; ++grid2_add )
     {
+      int lprogress = 1;
 #if defined (_OPENMP)
       ompthID = omp_get_thread_num();
       srch_add = srch_add2[ompthID];
+      if ( ompthID != 0 ) lprogress = 0;
 #endif
-
-      if ( ompNumThreads == 1 ) progressStatus(0.5, 0.5, (grid2_add+1.)/grid2_size);
+#if defined (_OPENMP)
+#pragma omp atomic
+#endif
+      findex++;
+      if ( lprogress ) progressStatus(0.5, 0.5, findex/grid2_size);
 
       lthresh   = FALSE;
       luse_last = FALSE;
@@ -6399,10 +6417,8 @@ void read_remap_scrip(const char *interp_file, int gridID1, int gridID2, int *ma
   nce(nc_inq_attlen(nc_file_id, nc_srcgrdcntrlat_id, "units", &attlen));
   grid1_units[attlen] = 0;
 
-  if ( memcmp(grid1_units, "degree", 6) == 0 )
-    scale2(rg->grid1_size, DEG2RAD, rg->grid1_center_lat, rg->grid1_center_lon);
-  else if ( memcmp(grid1_units, "radian", 6) != 0 )
-    cdoPrint("Unknown units supplied for grid1 center lat/lon: proceeding assuming radians");
+  grid_to_radian(grid1_units, rg->grid1_size, rg->grid1_center_lon, "grid1 center lon"); 
+  grid_to_radian(grid1_units, rg->grid1_size, rg->grid1_center_lat, "grid1 center lat"); 
 
   if ( rg->grid1_corners )
     {
@@ -6413,10 +6429,8 @@ void read_remap_scrip(const char *interp_file, int gridID1, int gridID2, int *ma
       nce(nc_inq_attlen(nc_file_id, nc_srcgrdcrnrlat_id, "units", &attlen));
       grid1_units[attlen] = 0;
 
-      if ( memcmp(grid1_units, "degree", 6) == 0 )
-	scale2( rg->grid1_corners*rg->grid1_size, DEG2RAD, rg->grid1_corner_lat, rg->grid1_corner_lon);
-      else if ( memcmp(grid1_units, "radian", 6) != 0 )
-	cdoPrint("Unknown units supplied for grid1 corner lat/lon: proceeding assuming radians");
+      grid_to_radian(grid1_units, rg->grid1_corners*rg->grid1_size, rg->grid1_corner_lon, "grid1 corner lon"); 
+      grid_to_radian(grid1_units, rg->grid1_corners*rg->grid1_size, rg->grid1_corner_lat, "grid1 corner lat"); 
     }
 
   if ( rv->map_type == MAP_TYPE_CONSERV )
@@ -6435,10 +6449,8 @@ void read_remap_scrip(const char *interp_file, int gridID1, int gridID2, int *ma
   nce(nc_inq_attlen(nc_file_id, nc_dstgrdcntrlat_id, "units", &attlen));
   grid2_units[attlen] = 0;
 
-  if ( memcmp(grid2_units, "degree", 6) == 0 )
-    scale2(rg->grid2_size, DEG2RAD, rg->grid2_center_lat, rg->grid2_center_lon);
-  else if ( memcmp(grid2_units, "radian", 6) != 0 )
-    cdoPrint("Unknown units supplied for grid2 center lat/lon: proceeding assuming radians");
+  grid_to_radian(grid2_units, rg->grid2_size, rg->grid2_center_lon, "grid2 center lon"); 
+  grid_to_radian(grid2_units, rg->grid2_size, rg->grid2_center_lat, "grid2 center lat"); 
 
   if ( rg->grid2_corners )
     {
@@ -6449,10 +6461,8 @@ void read_remap_scrip(const char *interp_file, int gridID1, int gridID2, int *ma
       nce(nc_inq_attlen(nc_file_id, nc_dstgrdcrnrlat_id, "units", &attlen));
       grid2_units[attlen] = 0;
       
-      if ( memcmp(grid2_units, "degree", 6) == 0 )
-	scale2( rg->grid2_corners*rg->grid2_size, DEG2RAD, rg->grid2_corner_lat, rg->grid2_corner_lon);
-      else if ( memcmp(grid2_units, "radian", 6) != 0 )
-	cdoPrint("Unknown units supplied for grid2 corner lat/lon: proceeding assuming radians");
+      grid_to_radian(grid2_units, rg->grid2_corners*rg->grid2_size, rg->grid2_corner_lon, "grid2 corner lon"); 
+      grid_to_radian(grid2_units, rg->grid2_corners*rg->grid2_size, rg->grid2_corner_lat, "grid2 corner lat"); 
     }
 
   if ( rv->map_type == MAP_TYPE_CONSERV )
diff --git a/src/timebase.h b/src/timebase.h
index 57111ab..716bb60 100644
--- a/src/timebase.h
+++ b/src/timebase.h
@@ -1,6 +1,8 @@
 #ifndef  _TIMEBASE_H
 #define  _TIMEBASE_H
 
+#include <inttypes.h>
+
 /* date format:  YYYYMMDD */
 /* time format:  hhmmss   */
 
@@ -13,11 +15,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 */
diff --git a/src/userlog.c b/src/userlog.c
index 6661447..ca098f8 100644
--- a/src/userlog.c
+++ b/src/userlog.c
@@ -94,7 +94,7 @@ void cdolog(const char *prompt, double cputime)
 
   for ( streamID = 0; streamID < cdoStreamCnt(); streamID++ )
     {
-      streamName = cdoStreamName(streamID);
+      streamName = cdoStreamName(streamID)->args;
       pos = 0;
       while ( pos < (int) strlen(streamName) )
 	{
diff --git a/src/util.c b/src/util.c
index 8a8cc64..764ba05 100644
--- a/src/util.c
+++ b/src/util.c
@@ -46,22 +46,15 @@ char *getProgname(char *string)
 char *getOperator(const char *argument)
 {
   char *operatorArg = NULL;
-  char *blankpos;
   size_t len;
 
   if ( argument )
     {
-      blankpos = strchr(argument, ' ');
-
-      if ( blankpos )
-	len = blankpos - argument;
-      else
-	len = strlen(argument);
+      len = 1 + strlen(argument);
 
-      operatorArg = (char *) malloc(len+1);
+      operatorArg = (char *) malloc(len);
 
       memcpy(operatorArg, argument, len);
-      operatorArg[len] = '\0';
     }
 
   return (operatorArg);
@@ -97,30 +90,96 @@ char *getOperatorName(const char *operatorArg)
 }
 
 
-char *makeArgument(int argc, char *argv[])
+argument_t *file_argument_new(const char *filename)
 {
-  char *argument = NULL;
-  int iarg;
-  size_t len, pos = 0, off = 0;
+  argument_t *argument;
+
+  argument = (argument_t *) calloc(1, sizeof(argument_t));
+
+  argument->argc = 1;
+  argument->argv = (char **) calloc(1, sizeof(char *));
+  argument->argv[0] = (char *) filename;
+  argument->args = (char *) filename;
+
+  return (argument);
+}
+
+
+void file_argument_free(argument_t *argument)
+{
+  if ( argument )
+    {
+      if ( argument->argc )
+	{
+	  assert(argument->argc == 1);
+	  free(argument->argv);
+	}
+      free(argument);
+    }
+}
+
+
+argument_t *argument_new(size_t argc, size_t len)
+{
+  argument_t *argument;
+
+  argument = (argument_t *) calloc(1, sizeof(argument_t));
 
-  if ( argv[0][0] == '-' ) off = 1;
-  for ( iarg = 0; iarg < argc; iarg++ )
+  if ( argc > 0 )
     {
-      len = strlen(argv[iarg]) + 1 - off;
-      argument = (char *) realloc(argument, pos+len);
-      strcpy(&argument[pos], argv[iarg]+off);
-      pos += len;
-      argument[pos-1] = ' ';
-      off = 0;
+      argument->argc = argc;
+      argument->argv = (char **) calloc(argc, sizeof(char *));
     }
 
-  if ( argc )
-    argument[pos-1] = '\0';
+  if ( len > 0 )
+    argument->args = (char *) calloc(len, sizeof(char));
 
   return (argument);
 }
 
 
+void argument_free(argument_t *argument)
+{
+  if ( argument )
+    {
+      if ( argument->argc )
+	{
+	  for ( int i = 0; i < argument->argc; ++i )
+	    {
+	      if ( argument->argv[i] )
+		{
+		  free(argument->argv[i]);
+		  argument->argv[i] = NULL;
+		}
+	    }
+
+	  free(argument->argv);
+	  argument->argv = NULL;
+	  argument->argc = 0;
+	}
+
+      if ( argument->args )
+	{
+	  free(argument->args);
+	  argument->args = NULL;
+	}
+
+      free(argument);
+    }
+}
+
+
+void argument_fill(argument_t *argument, int argc, char *argv[])
+{
+  int iarg;
+
+  assert(argument->argc == argc);
+
+  for ( iarg = 0; iarg < argc; ++iarg )
+    argument->argv[iarg] = strdup(argv[iarg]);
+}
+
+
 char *getFileArg(char *argument)
 {
   char *fileArg = NULL;
diff --git a/src/util.h b/src/util.h
index b588903..9200f65 100644
--- a/src/util.h
+++ b/src/util.h
@@ -18,11 +18,24 @@
 #ifndef _UTIL_H
 #define _UTIL_H
 
+typedef struct {
+  int    argc;
+  int    argl;
+  char **argv;
+  char  *args;
+} argument_t;
+
+argument_t *file_argument_new(const char *filename);
+void        file_argument_free(argument_t *argument);
+argument_t *argument_new(size_t argc, size_t len);
+void        argument_free(argument_t *argument);
+void        argument_fill(argument_t *argument, int argc, char *argv[]);
+
 char *getProgname(char *string);
 char *getOperator(const char *argument);
 char *getOperatorName(const char *xoperator);
 
-char *makeArgument(int argc, char *argv[]);
+argument_t makeArgument(int argc, char *argv[]);
 char *getFileArg(char *argument);
 
 enum {START_DEC, START_JAN};
diff --git a/src/zaxis.c b/src/zaxis.c
index 1d135f3..6adc691 100644
--- a/src/zaxis.c
+++ b/src/zaxis.c
@@ -463,7 +463,6 @@ int ztype2ltype(int zaxistype)
   else if ( zaxistype == ZAXIS_DEPTH_BELOW_LAND  )  ltype = 111;
   else if ( zaxistype == ZAXIS_ISENTROPIC        )  ltype = 113;
   else if ( zaxistype == ZAXIS_DEPTH_BELOW_SEA   )  ltype = 160;
-  else cdoWarning("zaxis type %d not supported", zaxistype);
 
   return (ltype);
 }

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