diff --git a/.gitattributes b/.gitattributes
index dd921096564a9ab6bbf18e2ed999f10436504394..87d02e6846c31998c3a354618d883f650b00c980 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -107,14 +107,18 @@ examples/cdi_copy_f.f -text
 examples/cdi_copy_file.c -text
 examples/cdi_open.c -text
 examples/cdi_read.c -text
+examples/cdi_read_atts.f -text
 examples/cdi_read_example.f90 -text
 examples/cdi_read_f.f -text
 examples/cdi_read_f2003.f90 -text
 examples/cdi_read_records.c -text
+examples/cdi_read_simple.f -text
+examples/cdi_read_sst.f -text
 examples/cdi_write.c -text
 examples/cdi_write_ens.c -text
 examples/cdi_write_f.f -text
 examples/cdi_write_f2003.f90 -text
+examples/cdi_write_hybrid.c -text
 examples/cdi_write_reset.c -text
 examples/compf -text
 examples/pio/Makefile.am -text
@@ -180,7 +184,10 @@ src/cdf_int.h -text
 src/cdi.h -text
 src/cdi.inc -text
 src/cdiFortran.c -text
+src/cdiFortran.h -text
 src/cdi_error.c -text
+src/cdi_int.c -text
+src/cdi_int.h -text
 src/cdi_limits.h -text
 src/cdi_util.c -text
 src/cdilib.c -text
@@ -259,8 +266,6 @@ src/stream_gribapi.h -text
 src/stream_history.c -text
 src/stream_ieg.c -text
 src/stream_ieg.h -text
-src/stream_int.c -text
-src/stream_int.h -text
 src/stream_record.c -text
 src/stream_srv.c -text
 src/stream_srv.h -text
diff --git a/ChangeLog b/ChangeLog
index 5cb5508a9ba44ef4f7b579d5c0ecf16a07709217..e6f1a9c9c4dd8ac5fc636408d3d9170052c51017 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,73 @@
+2013-06-18  Uwe Schulzweida  <Uwe.Schulzweida@zmaw.de>
+
+	* Version 1.6.1 released
+
+2013-06-11  Uwe Schulzweida  <Uwe.Schulzweida@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@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@zmaw.de>
+
+	* added patch from Florian Prill: Lesen von 'number_of_grid_used', GRID_REFERENCE (bug fix)
+
+2013-05-29  Uwe Schulzweida  <Uwe.Schulzweida@zmaw.de>
+
+	* netCDF: skip 4D variables without time dimension (bug fix)
+
+2013-05-28  Uwe Schulzweida  <Uwe.Schulzweida@zmaw.de>
+
+	* GRIB2: added support for pressure levels with 3 fractional digits
+
+2013-05-27  Uwe Schulzweida  <Uwe.Schulzweida@zmaw.de>
+
+	* gribapiGetEndStep: use stepUnits for timeunits2
+	* grib2GetLevel: set level bounds if  0 < leveltype2 < 255
+
+2013-05-23  Uwe Schulzweida  <Uwe.Schulzweida@zmaw.de>
+
+	* netCDF: missing_value attribute removed [Bug #3592]
+
+2013-05-17  Uwe Schulzweida  <Uwe.Schulzweida@zmaw.de>
+
+	* added CDI function cdiHaveFiletype() to check whether a filetype is available
+
+2013-05-13  Uwe Schulzweida  <Uwe.Schulzweida@zmaw.de>
+
+	* added patch from Florian Prill: Lesen von "Nicht-Standard" GRIB-Keys (bug fix)
+
+2013-04-26  Uwe Schulzweida  <Uwe.Schulzweida@zmaw.de>
+
+	* added patch from Florian Prill: Lesen von "Nicht-Standard" GRIB-Keys
+
+2013-04-25  Uwe Schulzweida  <Uwe.Schulzweida@zmaw.de>
+
+	* institutInq: check contents of name and longname (bug fix) [Bug #3419]
+
+2013-04-23  Uwe Schulzweida  <Uwe.Schulzweida@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@zmaw.de>
+
+	* stream_gribapi: replaced function getLevelFactor() [Bug #3446]
+
+2013-04-18  Uwe Schulzweida  <Uwe.Schulzweida@zmaw.de>
+
+	* added function vlistDefVarExtra() and vlistInqVarExtra()
+
+2013-04-04  Uwe Schulzweida  <Uwe.Schulzweida@zmaw.de>
+
+	* vlistDefVarDatatype: changed default missing values of signed integers to -TYPE_MAX
+
 2013-04-02  Uwe Schulzweida  <Uwe.Schulzweida@zmaw.de>
 
 	* cdi.h: changed >char*< to >char *< (bug fix for fortran interface)
diff --git a/NEWS b/NEWS
index ae614eb7b1424217468513f5b850e9de478edd69..c6825e7d70017f2e89946e4dd9ab978c02f7a5dc 100644
--- a/NEWS
+++ b/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/app/cdi.c b/app/cdi.c
index 92138b02e7e7df12c1ab063c45af8ad955f33b12..76c4a187536391214b93956c2c1f55ac6df5512f 100644
--- a/app/cdi.c
+++ b/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/config/default b/config/default
index 0599021e178150085dc45de97ff5a1b3f57b6cd9..d477177596ac8c5555303545f50b4b1409ce48d2 100755
--- a/config/default
+++ b/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/configure b/configure
index 020d7627a2800b94d0b802ac17dfba1a1c7c2483..78fcb00ac928f54800eacee855e5a58be6c2b895 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 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=''
 
@@ -685,6 +685,9 @@ PTHREAD_CFLAGS
 PTHREAD_LIBS
 PTHREAD_CC
 ax_pthread_config
+SYSTEM_TYPE
+HOST_NAME
+USER_NAME
 AS
 CXXCPP
 am__fastdepCXX_FALSE
@@ -769,9 +772,6 @@ am__isrc
 INSTALL_DATA
 INSTALL_SCRIPT
 INSTALL_PROGRAM
-SYSTEM_TYPE
-HOST_NAME
-USER_NAME
 host_os
 host_vendor
 host_cpu
@@ -1421,7 +1421,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]...
 
@@ -1491,7 +1491,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
 
@@ -1659,7 +1659,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.
@@ -2420,7 +2420,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 $@
@@ -2878,41 +2878,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'
 
@@ -3352,7 +3317,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='cdi'
- VERSION='1.6.0'
+ VERSION='1.6.1'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -23916,6 +23881,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
@@ -27270,6 +27291,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 tests/pio_cksum_cdf util/serialrun"
 
 
@@ -27853,7 +27882,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
@@ -27919,7 +27948,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/configure.ac b/configure.ac
index 784a86952c4e59527e9241d05e217b1c97b0466f..72312ca68d06ed7e97c36715e6e67f8a57aba134 100644
--- a/configure.ac
+++ b/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)
@@ -262,6 +279,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/doc/tex/c_quick_ref.tex b/doc/tex/c_quick_ref.tex
index 7a2fde779ef25290d635799c2a81b2745778df9d..0891059751fbcafe01a616b3d2b2a96e1939e7e1 100644
--- a/doc/tex/c_quick_ref.tex
+++ b/doc/tex/c_quick_ref.tex
@@ -4,6 +4,15 @@
 This appendix provide a brief listing of the C language bindings of the
 CDI library routines:
 
+\section*{\tt \htmlref{cdiDefAdditionalKey}{cdiDefAdditionalKey}}
+
+\begin{verbatim}
+    void cdiDefAdditionalKey (const char *string);
+\end{verbatim}
+
+Register an additional GRIB key which is read when file is opened..
+
+
 \section*{\tt \htmlref{gridCreate}{gridCreate}}
 
 \begin{verbatim}
@@ -706,7 +715,7 @@ Define an integer attribute.
 
 \begin{verbatim}
     int vlistDefAttTxt (int vlistID, int varID, const char *name, int len,
-                        const char *tp);
+                        const char *tp_cbuf);
 \end{verbatim}
 
 Define a text attribute.
@@ -757,6 +766,15 @@ Define the data type of a Variable.
 Set an arbitrary keyword/double value pair for GRIB API.
 
 
+\section*{\tt \htmlref{vlistDefVarExtra}{vlistDefVarExtra}}
+
+\begin{verbatim}
+    void vlistDefVarExtra (int vlistID, int varID, const char *extra);
+\end{verbatim}
+
+Define extra information of a Variable.
+
+
 \section*{\tt \htmlref{vlistDefVarIntKey}{vlistDefVarIntKey}}
 
 \begin{verbatim}
@@ -871,7 +889,8 @@ Get the value(s) of an integer attribute.
 \section*{\tt \htmlref{vlistInqAttTxt}{vlistInqAttTxt}}
 
 \begin{verbatim}
-    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);
 \end{verbatim}
 
 Get the value(s) of a text attribute.
@@ -916,16 +935,25 @@ Get the data type of a Variable.
 \section*{\tt \htmlref{vlistInqVarDblKey}{vlistInqVarDblKey}}
 
 \begin{verbatim}
-    double vlistInqVarDblKey (int streamID, const char *name);
+    double vlistInqVarDblKey (int vlistID, int varID, const char *name);
 \end{verbatim}
 
 raw access to GRIB meta-data.
 
 
+\section*{\tt \htmlref{vlistInqVarExtra}{vlistInqVarExtra}}
+
+\begin{verbatim}
+    void vlistInqVarExtra (int vlistID, int varID, char *extra);
+\end{verbatim}
+
+Get extra information of a Variable.
+
+
 \section*{\tt \htmlref{vlistInqVarIntKey}{vlistInqVarIntKey}}
 
 \begin{verbatim}
-    int vlistInqVarIntKey (int streamID, const char *name);
+    int vlistInqVarIntKey (int vlistID, int varID, const char *name);
 \end{verbatim}
 
 raw access to GRIB meta-data.
@@ -967,24 +995,6 @@ Get the name of a Variable.
 Get the parameter number of a Variable.
 
 
-\section*{\tt \htmlref{vlistInqVarRawBegin}{vlistInqVarRawBegin}}
-
-\begin{verbatim}
-    void vlistInqVarRawBegin (int streamID, int varID);
-\end{verbatim}
-
-Open GRIB record to retrieve raw meta-data in subsequent calls.
-
-
-\section*{\tt \htmlref{vlistInqVarRawEnd}{vlistInqVarRawEnd}}
-
-\begin{verbatim}
-    void vlistInqVarRawEnd (int streamID);
-\end{verbatim}
-
-Free previously opened GRIB record.
-
-
 \section*{\tt \htmlref{vlistInqVarStdname}{vlistInqVarStdname}}
 
 \begin{verbatim}
@@ -1105,7 +1115,7 @@ Define the reference of a generalized Z-axis.
 \section*{\tt \htmlref{zaxisDefUUID}{zaxisDefUUID}}
 
 \begin{verbatim}
-    void zaxisDefUUID (int zaxisID, const char *uuid);
+    void zaxisDefUUID (int zaxisID, const char *uuid_cbuf);
 \end{verbatim}
 
 Define the uuid of a generalized Z-axis.
@@ -1213,7 +1223,7 @@ Get the type of a Z-axis.
 \section*{\tt \htmlref{zaxisInqUUID}{zaxisInqUUID}}
 
 \begin{verbatim}
-    char * zaxisInqUUID (int zaxisID, char *uuid);
+    char * zaxisInqUUID (int zaxisID, char *uuid_cbuf);
 \end{verbatim}
 
 Get the reference of a generalized Z-axis.
diff --git a/doc/tex/c_ref.tex b/doc/tex/c_ref.tex
index 792ecebdb3d83b6fce26898df6ac44362427e359..bc2a48b737e60c3db5b49eaa4eb50d9dec16fd43 100644
--- a/doc/tex/c_ref.tex
+++ b/doc/tex/c_ref.tex
@@ -1183,7 +1183,7 @@ vlistInqAttFlt
 \fi
 }
 \begin{verbatim}
-    int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, int *dp);
+    int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double *dp);
 \end{verbatim}
 
 Get the value(s) of a floating point attribute
@@ -1213,7 +1213,7 @@ vlistInqAttTxt
 \fi
 }
 \begin{verbatim}
-    int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, int *tp);
+    int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp);
 \end{verbatim}
 
 Get the value(s) of a text attribute
diff --git a/doc/tex/c_vlist_att.tex b/doc/tex/c_vlist_att.tex
index 6da7198082d63273521e283e32ffd959fa16adc7..f1344ab139bd39d7f8fde129b4e4fd735aa0bb70 100644
--- a/doc/tex/c_vlist_att.tex
+++ b/doc/tex/c_vlist_att.tex
@@ -160,7 +160,7 @@ The function {\tt vlistInqAttFlt} gets the values(s) of a floating point attribu
 \subsubsection*{Usage}
 
 \begin{verbatim}
-    int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, int *dp);
+    int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double *dp);
 \end{verbatim}
 
 \hspace*{4mm}\begin{minipage}[]{15cm}
@@ -218,7 +218,7 @@ The function {\tt vlistInqAttTxt} gets the values(s) of a text attribute.
 \subsubsection*{Usage}
 
 \begin{verbatim}
-    int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, int *tp);
+    int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp);
 \end{verbatim}
 
 \hspace*{4mm}\begin{minipage}[]{15cm}
diff --git a/doc/tex/c_vlist_var.tex b/doc/tex/c_vlist_var.tex
index 22ad2880e730192b17f8f83d9cc5dfb132e87760..409549762c64c03324ed409d8642faad9d53f0b8 100644
--- a/doc/tex/c_vlist_var.tex
+++ b/doc/tex/c_vlist_var.tex
@@ -381,7 +381,7 @@ Variable list ID, from a previous call to {\htmlref{\tt vlistCreate}{vlistCreate
 \item[{\tt varID}]
 Variable identifier.
 \item[{\tt units}]
-Units of the variable. The caller must allocate space for the 
+Units of the variable. The caller must allocate space for the
                     returned string. The maximum possible length, in characters, of
                     the string is given by the predefined constant {\tt CDI\_MAX\_NAME}.
 
diff --git a/doc/tex/c_zaxis.tex b/doc/tex/c_zaxis.tex
index b143fca047162732bd034890ff0d49434910cc66..05affaee1eade4993c4512622f88ffe21ed7f265 100644
--- a/doc/tex/c_zaxis.tex
+++ b/doc/tex/c_zaxis.tex
@@ -20,7 +20,7 @@ The type of the Z-axis, one of the set of predefined {\CDI} Z-axis types.
                       {\tt ZAXIS\_HYBRID}, {\tt ZAXIS\_SIGMA}, {\tt ZAXIS\_PRESSURE}, {\tt ZAXIS\_HEIGHT},
                       {\tt ZAXIS\_ISENTROPIC}, {\tt ZAXIS\_ALTITUDE}, {\tt ZAXIS\_MEANSEA}, {\tt ZAXIS\_TOA},
                       {\tt ZAXIS\_SEA\_BOTTOM}, {\tt ZAXIS\_ATMOSPHERE}, {\tt ZAXIS\_CLOUD\_BASE},
-                      {\tt ZAXIS\_CLOUD\_TOP}, {\tt ZAXIS\_ISOTHERM\_ZERO}, 
+                      {\tt ZAXIS\_CLOUD\_TOP}, {\tt ZAXIS\_ISOTHERM\_ZERO}, {\tt ZAXIS\_SNOW},
                       {\tt ZAXIS\_DEPTH\_BELOW\_SEA} and {\tt ZAXIS\_DEPTH\_BELOW\_LAND}.
 \item[{\tt size}]
 Number of levels.
@@ -98,7 +98,7 @@ The valid {\CDI} Z-axis types are {\tt ZAXIS\_GENERIC}, {\tt ZAXIS\_SURFACE},
 {\tt ZAXIS\_HYBRID}, {\tt ZAXIS\_SIGMA}, {\tt ZAXIS\_PRESSURE}, {\tt ZAXIS\_HEIGHT},
 {\tt ZAXIS\_ISENTROPIC}, {\tt ZAXIS\_ALTITUDE}, {\tt ZAXIS\_MEANSEA}, {\tt ZAXIS\_TOA},
 {\tt ZAXIS\_SEA\_BOTTOM}, {\tt ZAXIS\_ATMOSPHERE}, {\tt ZAXIS\_CLOUD\_BASE},
-{\tt ZAXIS\_CLOUD\_TOP}, {\tt ZAXIS\_ISOTHERM\_ZERO}, 
+{\tt ZAXIS\_CLOUD\_TOP}, {\tt ZAXIS\_ISOTHERM\_ZERO}, {\tt ZAXIS\_SNOW},
 {\tt ZAXIS\_DEPTH\_BELOW\_SEA} and {\tt ZAXIS\_DEPTH\_BELOW\_LAND}.
 
 
diff --git a/doc/tex/cdi_cman.tex b/doc/tex/cdi_cman.tex
index c3f8e7a549a69123fc817d76cab2b5927930ba17..c2bf536be77084ff85d673671a8429da9e59dbe7 100644
--- a/doc/tex/cdi_cman.tex
+++ b/doc/tex/cdi_cman.tex
@@ -8,15 +8,15 @@
 \gdef\pdfoutput{0}
 \fi
 
-\newif\ifpdf
+\newif\ifpdfx
 \ifnum\pdfoutput=0
 % latex is called for dvi output
-   \pdffalse
+   \pdfxfalse
    \usepackage{graphics}
    \usepackage{hyperref}
 \else
 % pdflatex is called for pdf output
-   \pdftrue
+   \pdfxtrue
    \usepackage[pdftex]{graphicx}
    \usepackage[pdftex]{hyperref}
 \fi
@@ -236,7 +236,7 @@ CDI library routines:
 
 
 \clearpage
-\ifpdf
+\ifpdfx
 \phantomsection
 \fi
 \addcontentsline{toc}{chapter}{\indexname}
diff --git a/doc/tex/cdi_fman.tex b/doc/tex/cdi_fman.tex
index 2cc452df64b1830a9bfb53d78a89f35527733a0f..d6706294fcc986202c8ca88e22ade2952bc12912 100644
--- a/doc/tex/cdi_fman.tex
+++ b/doc/tex/cdi_fman.tex
@@ -8,15 +8,15 @@
 \gdef\pdfoutput{0}
 \fi
 
-\newif\ifpdf
+\newif\ifpdfx
 \ifnum\pdfoutput=0
 % latex is called for dvi output
-   \pdffalse
+   \pdfxfalse
    \usepackage{graphics}
    \usepackage{hyperref}
 \else
 % pdflatex is called for pdf output
-   \pdftrue
+   \pdfxtrue
    \usepackage[pdftex]{graphicx}
    \usepackage[pdftex]{hyperref}
 \fi
@@ -233,7 +233,7 @@ CDI library routines:
 
 
 \clearpage
-\ifpdf
+\ifpdfx
 \phantomsection
 \printindex
 \fi
diff --git a/doc/tex/f_quick_ref.tex b/doc/tex/f_quick_ref.tex
index 65e9b8a600cfa06c7f7a2d7f32b5977baa516c45..152b24b0511d6af58a9f123f1f51ee16aaf06ac1 100644
--- a/doc/tex/f_quick_ref.tex
+++ b/doc/tex/f_quick_ref.tex
@@ -4,6 +4,15 @@
 This appendix provide a brief listing of the Fortran language bindings of the
 CDI library routines:
 
+\section*{\tt \htmlref{cdiDefAdditionalKey}{cdiDefAdditionalKey}}
+
+\begin{verbatim}
+    SUBROUTINE cdiDefAdditionalKey (CHARACTER*(*) string)
+\end{verbatim}
+
+Register an additional GRIB key which is read when file is opened..
+
+
 \section*{\tt \htmlref{gridCreate}{gridCreate}}
 
 \begin{verbatim}
@@ -712,7 +721,7 @@ Define an integer attribute.
 \begin{verbatim}
     INTEGER FUNCTION vlistDefAttTxt (INTEGER vlistID, INTEGER varID, 
                                      CHARACTER*(*) name, INTEGER len, 
-                                     CHARACTER*(*) tp)
+                                     CHARACTER*(*) tp_cbuf)
 \end{verbatim}
 
 Define a text attribute.
@@ -765,6 +774,15 @@ Define the data type of a Variable.
 Set an arbitrary keyword/double value pair for GRIB API.
 
 
+\section*{\tt \htmlref{vlistDefVarExtra}{vlistDefVarExtra}}
+
+\begin{verbatim}
+    SUBROUTINE vlistDefVarExtra (INTEGER vlistID, INTEGER varID, CHARACTER*(*) extra)
+\end{verbatim}
+
+Define extra information of a Variable.
+
+
 \section*{\tt \htmlref{vlistDefVarIntKey}{vlistDefVarIntKey}}
 
 \begin{verbatim}
@@ -887,7 +905,7 @@ Get the value(s) of an integer attribute.
 \begin{verbatim}
     INTEGER FUNCTION vlistInqAttTxt (INTEGER vlistID, INTEGER varID, 
                                      CHARACTER*(*) name, INTEGER mlen, 
-                                     CHARACTER*(*) tp)
+                                     CHARACTER*(*) tp_cbuf)
 \end{verbatim}
 
 Get the value(s) of a text attribute.
@@ -932,16 +950,27 @@ Get the data type of a Variable.
 \section*{\tt \htmlref{vlistInqVarDblKey}{vlistInqVarDblKey}}
 
 \begin{verbatim}
-    DOUBLEPRECISION FUNCTION vlistInqVarDblKey (INTEGER streamID, CHARACTER*(*) name)
+    DOUBLEPRECISION FUNCTION vlistInqVarDblKey (INTEGER vlistID, INTEGER varID, 
+                                                CHARACTER*(*) name)
 \end{verbatim}
 
 raw access to GRIB meta-data.
 
 
+\section*{\tt \htmlref{vlistInqVarExtra}{vlistInqVarExtra}}
+
+\begin{verbatim}
+    SUBROUTINE vlistInqVarExtra (INTEGER vlistID, INTEGER varID, CHARACTER*(*) extra)
+\end{verbatim}
+
+Get extra information of a Variable.
+
+
 \section*{\tt \htmlref{vlistInqVarIntKey}{vlistInqVarIntKey}}
 
 \begin{verbatim}
-    INTEGER FUNCTION vlistInqVarIntKey (INTEGER streamID, CHARACTER*(*) name)
+    INTEGER FUNCTION vlistInqVarIntKey (INTEGER vlistID, INTEGER varID, 
+                                        CHARACTER*(*) name)
 \end{verbatim}
 
 raw access to GRIB meta-data.
@@ -984,24 +1013,6 @@ Get the name of a Variable.
 Get the parameter number of a Variable.
 
 
-\section*{\tt \htmlref{vlistInqVarRawBegin}{vlistInqVarRawBegin}}
-
-\begin{verbatim}
-    SUBROUTINE vlistInqVarRawBegin (INTEGER streamID, INTEGER varID)
-\end{verbatim}
-
-Open GRIB record to retrieve raw meta-data in subsequent calls.
-
-
-\section*{\tt \htmlref{vlistInqVarRawEnd}{vlistInqVarRawEnd}}
-
-\begin{verbatim}
-    SUBROUTINE vlistInqVarRawEnd (INTEGER streamID)
-\end{verbatim}
-
-Free previously opened GRIB record.
-
-
 \section*{\tt \htmlref{vlistInqVarStdname}{vlistInqVarStdname}}
 
 \begin{verbatim}
@@ -1124,7 +1135,7 @@ Define the reference of a generalized Z-axis.
 \section*{\tt \htmlref{zaxisDefUUID}{zaxisDefUUID}}
 
 \begin{verbatim}
-    SUBROUTINE zaxisDefUUID (INTEGER zaxisID, CHARACTER*(*) uuid)
+    SUBROUTINE zaxisDefUUID (INTEGER zaxisID, CHARACTER*(*) uuid_cbuf)
 \end{verbatim}
 
 Define the uuid of a generalized Z-axis.
@@ -1232,7 +1243,7 @@ Get the type of a Z-axis.
 \section*{\tt \htmlref{zaxisInqUUID}{zaxisInqUUID}}
 
 \begin{verbatim}
-    CHARACTER(80) FUNCTION zaxisInqUUID (INTEGER zaxisID, CHARACTER*(*) uuid)
+    CHARACTER(80) FUNCTION zaxisInqUUID (INTEGER zaxisID, CHARACTER*(*) uuid_cbuf)
 \end{verbatim}
 
 Get the reference of a generalized Z-axis.
diff --git a/doc/tex/f_ref.tex b/doc/tex/f_ref.tex
index 3977e36f0ce90d411aa8491bd94ef7886304d74f..759dea1067b964c9e798ce50ad3c98898966e4a6 100644
--- a/doc/tex/f_ref.tex
+++ b/doc/tex/f_ref.tex
@@ -1195,7 +1195,7 @@ vlistInqAttFlt
 }
 \begin{verbatim}
     INTEGER FUNCTION vlistInqAttFlt(INTEGER vlistID, INTEGER varID, 
-                                    CHARACTER*(*) name, INTEGER mlen, INTEGER dp)
+                                    CHARACTER*(*) name, INTEGER mlen, REAL*8 dp)
 \end{verbatim}
 
 Get the value(s) of a floating point attribute
@@ -1227,7 +1227,8 @@ vlistInqAttTxt
 }
 \begin{verbatim}
     INTEGER FUNCTION vlistInqAttTxt(INTEGER vlistID, INTEGER varID, 
-                                    CHARACTER*(*) name, INTEGER mlen, INTEGER tp)
+                                    CHARACTER*(*) name, INTEGER mlen, 
+                                    CHARACTER*(*) tp)
 \end{verbatim}
 
 Get the value(s) of a text attribute
diff --git a/doc/tex/f_vlist_att.tex b/doc/tex/f_vlist_att.tex
index 39a65cd57fbc4c2dac1cf73774b0335cc429eee2..835e1d2065e35b6de5059fc9ecb3baee47c264cc 100644
--- a/doc/tex/f_vlist_att.tex
+++ b/doc/tex/f_vlist_att.tex
@@ -165,7 +165,7 @@ The function {\tt vlistInqAttFlt} gets the values(s) of a floating point attribu
 
 \begin{verbatim}
     INTEGER FUNCTION vlistInqAttFlt(INTEGER vlistID, INTEGER varID, 
-                                    CHARACTER*(*) name, INTEGER mlen, INTEGER dp)
+                                    CHARACTER*(*) name, INTEGER mlen, REAL*8 dp)
 \end{verbatim}
 
 \hspace*{4mm}\begin{minipage}[]{15cm}
@@ -226,7 +226,8 @@ The function {\tt vlistInqAttTxt} gets the values(s) of a text attribute.
 
 \begin{verbatim}
     INTEGER FUNCTION vlistInqAttTxt(INTEGER vlistID, INTEGER varID, 
-                                    CHARACTER*(*) name, INTEGER mlen, INTEGER tp)
+                                    CHARACTER*(*) name, INTEGER mlen, 
+                                    CHARACTER*(*) tp)
 \end{verbatim}
 
 \hspace*{4mm}\begin{minipage}[]{15cm}
diff --git a/doc/tex/f_vlist_var.tex b/doc/tex/f_vlist_var.tex
index fcf9ac74e18e2f54702bb649e7ecb6b6f2edf061..81adbfb3d8b91115a2b7e5c64f5640dcc96950c8 100644
--- a/doc/tex/f_vlist_var.tex
+++ b/doc/tex/f_vlist_var.tex
@@ -386,7 +386,7 @@ Variable list ID, from a previous call to {\htmlref{\tt vlistCreate}{vlistCreate
 \item[{\tt varID}]
 Variable identifier.
 \item[{\tt units}]
-Units of the variable. The caller must allocate space for the 
+Units of the variable. The caller must allocate space for the
                     returned string. The maximum possible length, in characters, of
                     the string is given by the predefined constant {\tt CDI\_MAX\_NAME}.
 
diff --git a/doc/tex/f_zaxis.tex b/doc/tex/f_zaxis.tex
index 26dfacac637e156f5bc9340abec240fcfc5d50ba..7a4a4863e2a4b78e6abf2944820a486dad2aa392 100644
--- a/doc/tex/f_zaxis.tex
+++ b/doc/tex/f_zaxis.tex
@@ -20,7 +20,7 @@ The type of the Z-axis, one of the set of predefined {\CDI} Z-axis types.
                       {\tt ZAXIS\_HYBRID}, {\tt ZAXIS\_SIGMA}, {\tt ZAXIS\_PRESSURE}, {\tt ZAXIS\_HEIGHT},
                       {\tt ZAXIS\_ISENTROPIC}, {\tt ZAXIS\_ALTITUDE}, {\tt ZAXIS\_MEANSEA}, {\tt ZAXIS\_TOA},
                       {\tt ZAXIS\_SEA\_BOTTOM}, {\tt ZAXIS\_ATMOSPHERE}, {\tt ZAXIS\_CLOUD\_BASE},
-                      {\tt ZAXIS\_CLOUD\_TOP}, {\tt ZAXIS\_ISOTHERM\_ZERO}, 
+                      {\tt ZAXIS\_CLOUD\_TOP}, {\tt ZAXIS\_ISOTHERM\_ZERO}, {\tt ZAXIS\_SNOW},
                       {\tt ZAXIS\_DEPTH\_BELOW\_SEA} and {\tt ZAXIS\_DEPTH\_BELOW\_LAND}.
 \item[{\tt size}]
 Number of levels.
@@ -98,7 +98,7 @@ The valid {\CDI} Z-axis types are {\tt ZAXIS\_GENERIC}, {\tt ZAXIS\_SURFACE},
 {\tt ZAXIS\_HYBRID}, {\tt ZAXIS\_SIGMA}, {\tt ZAXIS\_PRESSURE}, {\tt ZAXIS\_HEIGHT},
 {\tt ZAXIS\_ISENTROPIC}, {\tt ZAXIS\_ALTITUDE}, {\tt ZAXIS\_MEANSEA}, {\tt ZAXIS\_TOA},
 {\tt ZAXIS\_SEA\_BOTTOM}, {\tt ZAXIS\_ATMOSPHERE}, {\tt ZAXIS\_CLOUD\_BASE},
-{\tt ZAXIS\_CLOUD\_TOP}, {\tt ZAXIS\_ISOTHERM\_ZERO}, 
+{\tt ZAXIS\_CLOUD\_TOP}, {\tt ZAXIS\_ISOTHERM\_ZERO}, {\tt ZAXIS\_SNOW},
 {\tt ZAXIS\_DEPTH\_BELOW\_SEA} and {\tt ZAXIS\_DEPTH\_BELOW\_LAND}.
 
 
diff --git a/doc/tex/formats.tex b/doc/tex/formats.tex
index 5c6588b524f9e87de6ae58f4df85f1e529032b70..7371875fdf63ea77c0171335787e74046052fc6e 100644
--- a/doc/tex/formats.tex
+++ b/doc/tex/formats.tex
@@ -68,6 +68,7 @@ GRIB1  & GRIB2 & & \\
  111  & 106 & depthBelowLand          & Depth below land surface    \\
  112  & 106 & depthBelowLandLayer & Layer between two depths below land surface   \\   
  113  & 107 & theta                           & Isentropic (theta) level \\
+   --  & 114 & --                               & Snow level \\
  160  & 160 & depthBelowSea            & Depth below sea level    \\
 \hline
 \end{tabular}
diff --git a/doc/tex/zaxis.tex b/doc/tex/zaxis.tex
index bbcbcb164e64a5f149d5fa341ef785545ee34520..997aa9345df523174cfbb1932184f3986c51bec3 100644
--- a/doc/tex/zaxis.tex
+++ b/doc/tex/zaxis.tex
@@ -21,6 +21,7 @@ The following different Z-axis types are available:
 \item[{\large\tt ZAXIS\_CLOUD\_BASE        }]  Cloud base level
 \item[{\large\tt ZAXIS\_CLOUD\_TOP         }]  Level of cloud tops
 \item[{\large\tt ZAXIS\_ISOTHERM\_ZERO    }]  Level of 0$^{\circ}$ C isotherm
+\item[{\large\tt ZAXIS\_SNOW                   }]  Snow level
 \item[{\large\tt ZAXIS\_DEPTH\_BELOW\_SEA }]  Depth below sea level in meters
 \item[{\large\tt ZAXIS\_DEPTH\_BELOW\_LAND}]  Depth below land surface in centimeters
 \end{deflist}
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 850875f3bc881a4f5f38f33634d56fbdfee0ec03..4baab3a5a15cc53fb4761b26361c3b89ae2693e7 100644
--- a/examples/Makefile.am
+++ b/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/examples/Makefile.in b/examples/Makefile.in
index d294de1298ef738fdbe014e16e580cdf5d9db1b3..a39b3f40ea3ae90aa65e2299b3a149da77676444 100644
--- a/examples/Makefile.in
+++ b/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@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.@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;; \
@@ -345,6 +351,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
 #
@@ -421,6 +430,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)
@@ -432,6 +444,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdi_read.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdi_write.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdi_write_ens.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdi_write_hybrid.Po@am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
diff --git a/examples/cdi_read_atts.f b/examples/cdi_read_atts.f
new file mode 100644
index 0000000000000000000000000000000000000000..259075467538288fca1d7a477d23a878e72229b9
--- /dev/null
+++ b/examples/cdi_read_atts.f
@@ -0,0 +1,79 @@
+      PROGRAM CDIREAD
+
+      IMPLICIT NONE
+
+      INCLUDE 'cdi.inc'
+
+      INTEGER nlon, nlat, nlev, nts
+      PARAMETER (nlon = 12)   ! Number of longitudes
+      PARAMETER (nlat =  6)   ! Number of latitudes
+      PARAMETER (nlev =  5)   ! Number of levels
+      PARAMETER (nts  =  3)   ! Number of time steps
+
+      CHARACTER(80) varname
+      CHARACTER(80) attname
+      CHARACTER(80) atttxt
+      INTEGER ia, natts, atttype, attlen
+      INTEGER inst
+      INTEGER gridID, zaxisID1, zaxisID2, taxisID
+      INTEGER vlistID, varID1, varID2, streamID, tsID
+      INTEGER nmiss, status, vdate, vtime
+      REAL*8 var1(nlon*nlat), var2(nlon*nlat*nlev)
+
+!     Open the dataset
+      streamID = streamOpenRead("example2.nc")
+      IF ( streamID < 0 ) THEN
+         WRITE(0,*) cdiStringError(streamID)
+         STOP
+      END IF
+
+!     Get the variable list of the dataset
+      vlistID = streamInqVlist(streamID)
+      varname(1:80) = "       "
+      CALL vlistInqVarName(vlistID, 0, varname)
+      WRITE(*,*) 'varname : ', varname
+
+!     Set the variable IDs
+      varID1 = 0
+      varID2 = 1
+
+!     Get the Time axis from the variable list
+      taxisID = vlistInqTaxis(vlistID)
+
+      status = vlistInqNatts(vlistID, -1, natts);
+      WRITE(0,*) 'natts: ', natts
+      attname(1:80) = " "
+
+      DO ia = 1, natts
+
+        status = vlistInqAtt(vlistID, -1, ia-1, attname, atttype,
+     &  attlen)
+        IF ( atttype == DATATYPE_TXT ) THEN
+	  status = vlistInqAttTxt(vlistID, -1, attname, 80,
+     &         atttxt)
+          WRITE(0,*) attname(1:10), attlen, atttxt(1:attlen)
+!	  atttxt[attlen] = 0;
+!	  fprintf(fp, "  %s=\"%s\"\n", attname, atttxt);
+        ENDIF
+      END DO
+
+!     Loop over the number of time steps
+      DO tsID = 0, nts-1
+!        Inquire the time step
+         status = streamInqTimestep(streamID, tsID)
+
+!        Get the verification date and time
+         vdate = taxisInqVdate(taxisID)
+         vtime = taxisInqVtime(taxisID)
+
+!        Read var1 and var2
+         CALL streamReadVar(streamID, varID1, var1, nmiss)
+         CALL streamReadVar(streamID, varID2, var2, nmiss)
+      END DO
+
+!     Close the input stream
+      CALL streamClose(streamID)
+
+!      CALL cdiReset()
+
+      END
diff --git a/examples/cdi_read_simple.f b/examples/cdi_read_simple.f
new file mode 100644
index 0000000000000000000000000000000000000000..9c61df060bcf5b145211c6904f323460948c39fe
--- /dev/null
+++ b/examples/cdi_read_simple.f
@@ -0,0 +1,55 @@
+      PROGRAM CDIREAD
+
+      IMPLICIT NONE
+
+      INCLUDE 'cdi.inc'
+
+      INTEGER nlon, nlat, nlev, nts
+      PARAMETER (nlon = 12)   ! Number of longitudes
+      PARAMETER (nlat =  6)   ! Number of latitudes
+      PARAMETER (nlev =  5)   ! Number of levels
+      PARAMETER (nts  =  3)   ! Number of time steps
+
+      INTEGER inst
+      INTEGER gridID, zaxisID1, zaxisID2, taxisID
+      INTEGER vlistID, varID1, varID2, streamID, tsID
+      INTEGER nmiss, status, vdate, vtime
+      REAL*8 var1(nlon*nlat), var2(nlon*nlat*nlev)
+
+!     Open the dataset
+      streamID = streamOpenRead("example.grb")
+      IF ( streamID < 0 ) THEN
+         WRITE(0,*) cdiStringError(streamID)
+         STOP
+      END IF
+
+!     Get the variable list of the dataset
+      vlistID = streamInqVlist(streamID)
+
+!     Set the variable IDs
+      varID1 = 0
+      varID2 = 1
+
+!     Get the Time axis from the variable list
+      taxisID = vlistInqTaxis(vlistID)
+
+!     Loop over the number of time steps
+      DO tsID = 0, nts-1
+!        Inquire the time step
+         status = streamInqTimestep(streamID, tsID)
+
+!        Get the verification date and time
+         vdate = taxisInqVdate(taxisID)
+         vtime = taxisInqVtime(taxisID)
+
+!        Read var1 and var2
+         CALL streamReadVar(streamID, varID1, var1, nmiss)
+         CALL streamReadVar(streamID, varID2, var2, nmiss)
+      END DO
+
+!     Close the input stream
+      CALL streamClose(streamID)
+
+!      CALL cdiReset()
+
+      END
diff --git a/examples/cdi_read_sst.f b/examples/cdi_read_sst.f
new file mode 100644
index 0000000000000000000000000000000000000000..556a9b0425e9c43c8f352256a9828314cbace930
--- /dev/null
+++ b/examples/cdi_read_sst.f
@@ -0,0 +1,51 @@
+      PROGRAM CDIREADSST
+
+      IMPLICIT NONE
+
+      INCLUDE 'cdi.inc'
+
+      INTEGER nvals
+      PARAMETER (nvals = 20480)
+
+      INTEGER gridID, taxisID
+      INTEGER vlistID, varID1, streamID, tsID
+      INTEGER nmiss, status, vdate, vtime
+      REAL*8 sst(nvals)
+
+!      CALL cdiDebug(1)
+!     Open the dataset
+      streamID = streamOpenRead
+     & ("/Users/m214003/data/icon_amip2sst_1870-2010.nc")
+      IF ( streamID < 0 ) THEN
+         WRITE(0,*) cdiStringError(streamID)
+         STOP
+      END IF
+
+!     Get the variable list of the dataset
+      vlistID = streamInqVlist(streamID)
+
+!     Set the variable IDs
+      varID1 = 0
+
+!     Get the Time axis from the variable list
+      taxisID = vlistInqTaxis(vlistID)
+
+!     Loop over the first 10 time steps
+      DO tsID = 0, 10
+!        Inquire the time step
+         status = streamInqTimestep(streamID, tsID)
+
+!        Get the verification date and time
+         vdate = taxisInqVdate(taxisID)
+         vtime = taxisInqVtime(taxisID)
+
+!        Read sst
+         CALL streamReadVarSlice(streamID, varID1, 0, sst, nmiss)
+
+         WRITE(*,*) vdate, minval(sst), maxval(sst)
+      END DO
+
+!     Close the input stream
+      CALL streamClose(streamID)
+
+      END
diff --git a/examples/cdi_write_hybrid.c b/examples/cdi_write_hybrid.c
new file mode 100644
index 0000000000000000000000000000000000000000..dd4fc73954196671dd855f5b64d8760e38cd8f75
--- /dev/null
+++ b/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/examples/compf b/examples/compf
index dc0df0e9965387d872e89e902697b382ea9e6e92..ef152b65f568f9bdc4ecb7f6c98143b0f5026e6b 100644
--- a/examples/compf
+++ b/examples/compf
@@ -8,3 +8,7 @@ g77 -g -I../src -o cdi_write_f cdi_write_f.f -L/pf/m/m214003/local/etch-ia32/lib
 
 
 gfortran -g  -o cdi_write_simple cdi_write_simple.f  -I../src -L/Users/m214003/local/lib ../src/.libs/libcdi.a -L/Users/uwe/cdt/libs4cdo-0.0.9/build/lib -L/opt/local/lib -lgrib_api /Users/uwe/cdt/libs4cdo-0.0.9/build/lib/libjasper.dylib /Users/uwe/cdt/libs4cdo-0.0.9/build/lib/libnetcdf.dylib /opt/local/lib/libcurl.dylib /opt/local/lib/libidn.dylib /opt/local/lib/libintl.dylib -lc /opt/local/lib/libiconv.dylib -lssl -lcrypto /Users/uwe/cdt/libs4cdo-0.0.9/build/lib/libhdf5_hl.dylib /Users/uwe/cdt/libs4cdo-0.0.9/build/lib/libhdf5.dylib -lpthread /Users/uwe/cdt/libs4cdo-0.0.9/build/lib/libsz.dylib -lz -lm -pthread
+
+
+gfortran -g  -o cdi_read_sst cdi_read_sst.f  -I../src ../src/.libs/libcdi.a -L/Users/m214003/local/gribapi-1.9.16/lib -lgrib_api /opt/local/lib/libjasper.dylib /opt/local/lib/libjpeg.dylib /opt/local/lib/libnetcdf.dylib /opt/local/lib/libhdf5_hl.dylib /opt/local/lib/libhdf5.dylib /opt/local/lib/libcurl.dylib /opt/local/lib/libidn.dylib /opt/local/lib/libintl.dylib -lc /opt/local/lib/libiconv.dylib -lssl -lcrypto /opt/local/lib/libsz.dylib -lz -lm -pthread
+
diff --git a/src/Makefile.am b/src/Makefile.am
index f2c5649e0ff5021559ec4577f2f26a5d75ce1c09..4e3395e838ba762095056851a21325576d3f939a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -27,6 +27,7 @@ libcdi_la_SOURCES = 	 \
 	cdi_limits.h	 \
 	cdi_util.c       \
 	cdiFortran.c     \
+	cdiFortran.h     \
 	cfortran.h       \
 	cgribex.h	 \
 	cgribexlib.c  	 \
@@ -68,7 +69,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     \
@@ -92,8 +93,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/src/Makefile.in b/src/Makefile.in
index 57cb6c4d515f697f537ba97e5b9a8dc9ac259b16..177cdbb59f8508ee2d48cf0cfe39863ac8ae36f1 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -119,11 +119,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@am_libcdi_la_rpath =
 @ENABLE_CDI_LIB_TRUE@am_libcdi_la_rpath = -rpath $(libdir)
@@ -360,6 +359,7 @@ libcdi_la_SOURCES = \
 	cdi_limits.h	 \
 	cdi_util.c       \
 	cdiFortran.c     \
+	cdiFortran.h     \
 	cfortran.h       \
 	cgribex.h	 \
 	cgribexlib.c  	 \
@@ -401,7 +401,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     \
@@ -425,8 +425,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	 \
@@ -568,6 +568,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdf_int.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdiFortran.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdi_error.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdi_int.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdi_util.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cgribexlib.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dmemory.Plo@am__quote@
@@ -604,7 +605,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stream_gribapi.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stream_history.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stream_ieg.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stream_int.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stream_record.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stream_srv.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stream_var.Plo@am__quote@
diff --git a/src/cdf.c b/src/cdf.c
index b486d37547eae514fd58ff3dd4ee6385040ab8d8..ccd08ef0bf2d824c613067312e8480e68b4afb98 100644
--- a/src/cdf.c
+++ b/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/src/cdf_int.c b/src/cdf_int.c
index 7346fe9fe7f6437a7e93949faa4b835b4f4e1db8..fbd548ed96aa8e737e3677733009f4173c55b399 100644
--- a/src/cdf_int.c
+++ b/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"
 
 #ifdef USE_MPI
@@ -106,11 +106,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/src/cdi.h b/src/cdi.h
index 97dcc3f9bf643b1d8fe7ccfb485cee1a061d0082..72e57b59d14d6c86dcc799615f0dc54d2fcedf60 100644
--- a/src/cdi.h
+++ b/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 */
 
@@ -255,6 +256,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);
@@ -518,6 +521,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);
@@ -543,27 +552,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 */
@@ -579,14 +583,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 */
@@ -733,8 +737,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) */
@@ -818,10 +822,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/src/cdi.inc b/src/cdi.inc
index 57c5f6b2c5317ee86351484f38b5d638ca414fd3..6f868b0eda3d10e7fe6d317e981ff61bf8001780 100644
--- a/src/cdi.inc
+++ b/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,   April 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
 !
@@ -434,6 +436,10 @@
 !                     cdiPrintVersion
       EXTERNAL        cdiPrintVersion
 
+      INTEGER         cdiHaveFiletype
+!                                    (INTEGER         filetype)
+      EXTERNAL        cdiHaveFiletype
+
 !                     cdiDefMissval
 !                                    (DOUBLEPRECISION missval)
       EXTERNAL        cdiDefMissval
@@ -1085,6 +1091,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,
@@ -1201,15 +1219,10 @@
 !                                     INTEGER         forecast_type)
       EXTERNAL        vlistInqVarEnsemble
 
-!
-!  ----------------------------------
-!
-!
-!  Local change: 2013-01-28, FP (DWD)
-!
-!
-!  ----------------------------------
-!
+!                     cdiDefAdditionalKey
+!                                    (CHARACTER*(*)   string)
+      EXTERNAL        cdiDefAdditionalKey
+
 !                     vlistDefVarIntKey
 !                                    (INTEGER         vlistID,
 !                                     INTEGER         varID,
@@ -1224,34 +1237,18 @@
 !                                     DOUBLEPRECISION value)
       EXTERNAL        vlistDefVarDblKey
 
-!
-!  ----------------------------------
-!
-!
-!  Local change: 2013-02-18, FP (DWD)
-!
-!
-!  ----------------------------------
-!
-!                     vlistInqVarRawBegin
-!                                    (INTEGER         streamID,
-!                                     INTEGER         varID)
-      EXTERNAL        vlistInqVarRawBegin
-
       DOUBLEPRECISION vlistInqVarDblKey
-!                                    (INTEGER         streamID,
+!                                    (INTEGER         vlistID,
+!                                     INTEGER         varID,
 !                                     CHARACTER*(*)   name)
       EXTERNAL        vlistInqVarDblKey
 
       INTEGER         vlistInqVarIntKey
-!                                    (INTEGER         streamID,
+!                                    (INTEGER         vlistID,
+!                                     INTEGER         varID,
 !                                     CHARACTER*(*)   name)
       EXTERNAL        vlistInqVarIntKey
 
-!                     vlistInqVarRawEnd
-!                                    (INTEGER         streamID)
-      EXTERNAL        vlistInqVarRawEnd
-
 !
 !  VLIST attributes
 !
@@ -1299,7 +1296,7 @@
 !                                     INTEGER         varID,
 !                                     CHARACTER*(*)   name,
 !                                     INTEGER         len,
-!                                     CHARACTER*(*)   tp)
+!                                     CHARACTER*(*)   tp_cbuf)
       EXTERNAL        vlistDefAttTxt
 
       INTEGER         vlistInqAttInt
@@ -1323,7 +1320,7 @@
 !                                     INTEGER         varID,
 !                                     CHARACTER*(*)   name,
 !                                     INTEGER         mlen,
-!                                     CHARACTER*(*)   tp)
+!                                     CHARACTER*(*)   tp_cbuf)
       EXTERNAL        vlistInqAttTxt
 
 !
@@ -1648,12 +1645,12 @@
 
       CHARACTER(80)   gridInqUUID
 !                                    (INTEGER         gridID,
-!                                     CHARACTER*(*)   uuid)
+!                                     CHARACTER*(*)   uuid_cbuf)
       EXTERNAL        gridInqUUID
 
 !                     gridDefUUID
 !                                    (INTEGER         gridID,
-!                                     CHARACTER*(*)   uuid)
+!                                     CHARACTER*(*)   uuid_cbuf)
       EXTERNAL        gridDefUUID
 
 !
@@ -1857,12 +1854,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/src/cdiFortran.c b/src/cdiFortran.c
index 234d5ca8a9e68227712870d2fd0f59646356eb4e..0a02fc57edc7686689745c53de9e295927a3cf10 100644
--- a/src/cdiFortran.c
+++ b/src/cdiFortran.c
@@ -23,6 +23,10 @@
 #  include "cfortran.h"
 #endif
 
+#if ! defined (_CDIFORTRAN_H)
+#  include "cdiFortran.h"
+#endif
+
 
 /*  Byte order  */
 
@@ -100,6 +104,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)
@@ -248,6 +253,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)
@@ -270,30 +277,11 @@ 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)
-FCALLSCFUN2 (DOUBLE, vlistInqVarDblKey, VLISTINQVARDBLKEY, vlistinqvardblkey, INT, STRING)
-FCALLSCFUN2 (INT, vlistInqVarIntKey, VLISTINQVARINTKEY, vlistinqvarintkey, INT, STRING)
-FCALLSCSUB1 (vlistInqVarRawEnd, VLISTINQVARRAWEND, vlistinqvarrawend, INT)
+FCALLSCFUN3 (DOUBLE, vlistInqVarDblKey, VLISTINQVARDBLKEY, vlistinqvardblkey, INT, INT, STRING)
+FCALLSCFUN3 (INT, vlistInqVarIntKey, VLISTINQVARINTKEY, vlistinqvarintkey, INT, INT, STRING)
 
 /*  VLIST attributes  */
 
@@ -302,10 +290,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  */
 
@@ -382,8 +370,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)  */
 
@@ -429,8 +417,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/src/cdiFortran.h b/src/cdiFortran.h
new file mode 100644
index 0000000000000000000000000000000000000000..500a2bcd58a2b57c066ad44fef11f320ae17d473
--- /dev/null
+++ b/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/src/stream_int.c b/src/cdi_int.c
similarity index 99%
rename from src/stream_int.c
rename to src/cdi_int.c
index 632c6b401524a6db0bb050bc52a8e0e4b199cbde..f51025879868fccee03803242ea063490ca8475f 100644
--- a/src/stream_int.c
+++ b/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/src/stream_int.h b/src/cdi_int.h
similarity index 96%
rename from src/stream_int.h
rename to src/cdi_int.h
index 3e35ee75452b2af150eb5184db95cdf9ee73ddf2..3d5006995709361f16d9aa8ef7d4b841d6492308 100644
--- a/src/stream_int.h
+++ b/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"
@@ -270,7 +270,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;
@@ -336,8 +336,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/src/cdi_util.c b/src/cdi_util.c
index b5fc74fdcca04a51319d528ca958961f675c72f0..18c00b672c8c3de578763b76f927f9e3d8b7f4b0 100644
--- a/src/cdi_util.c
+++ b/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/src/cfortran.h b/src/cfortran.h
index ea0b0e91636cb5d4e7347e4d038ce2e25bdf67b2..694e40ef5c68aff283fcdc288c7fc7fd064f38ef 100644
--- a/src/cfortran.h
+++ b/src/cfortran.h
@@ -461,6 +461,8 @@ for (i=0; i<sizeofcstr/elem_len; i++) {
 } return cstr; }
 
 /* kill the trailing char t's in string s. */
+#pragma GCC push_options
+#pragma GCC optimize ("O2")
 #ifndef __CF__KnR
 static char *kill_trailing(char *s, char t)
 #else
@@ -472,6 +474,7 @@ 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; }
+#pragma GCC pop_options
 
 /* 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/src/config.h.in b/src/config.h.in
index 521e258b2b66a5db30820628409e6d6656070791..c161d198cd9d355205497c59a039852846d39b28 100644
--- a/src/config.h.in
+++ b/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/src/gribapi.c b/src/gribapi.c
index 4692671002e7cc83a2440ddd1e6b028681fab48c..79337c78068e79eccdac9f57859e69c8f1e20034 100644
--- a/src/gribapi.c
+++ b/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/src/gribapi.h b/src/gribapi.h
index 080e39d4b96a1084646ad27e9ece5df50fedc8bd..741ebaf85e82404ddb44d76b1a38726c7099dec2 100644
--- a/src/gribapi.h
+++ b/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/src/grid.c b/src/grid.c
index 72ecfa18a4d721ad484d7d60d4c45d7126023b3b..77f5014b9ac5ceb2cd7e68c2696270ccde251728 100644
--- a/src/grid.c
+++ b/src/grid.c
@@ -15,7 +15,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"
@@ -4216,7 +4216,7 @@ char *gridInqUUID(int gridID, char *uuid)
 
   grid_check_ptr(gridID, gridptr);
 
-  strncpy(uuid, gridptr->uuid, 16);
+  memcpy(uuid, gridptr->uuid, 16);
 
   return (uuid);
 }
@@ -4236,7 +4236,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/src/institution.c b/src/institution.c
index 67c2b9531e343af118213c798342645912c5d785..a21fec52a5c3969149ce6ab964f7d1ae85509764 100644
--- a/src/institution.c
+++ b/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"
@@ -199,8 +199,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 ));
@@ -235,8 +239,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/src/make_cdilib b/src/make_cdilib
index 2fdf23a8cd60958d1c1f6af1023dfa271e7ef958..4e5df7dcfa0fe6c919735c00523b9ee397211a8d 100755
--- a/src/make_cdilib
+++ b/src/make_cdilib
@@ -111,7 +111,7 @@ c="dmemory.c         \
    cdf_int.c         \
    cdi_error.c       \
    cdi_util.c        \
-   stream_int.c      \
+   cdi_int.c         \
    stream.c          \
    stream_history.c  \
    stream_cgribex.c  \
@@ -144,7 +144,7 @@ c="dmemory.c         \
 
 h="cdi_limits.h taxis.h dtypes.h file.h service.h extra.h \
    ieg.h cdi.h timebase.h calendar.h basetime.h datetime.h \
-   error.c error.h stream_int.h cgribex.h gribapi.h \
+   error.c error.h cdi_int.h cgribex.h gribapi.h \
    stream_cgribex.h  stream_gribapi.h  stream_grb.h  stream_cdf.h \
    tablepar.h table.h gaussgrid.h grid.h zaxis.h varscan.h binary.h swap.h \
    service.h stream_srv.h stream_ext.h stream_ieg.h cdf_int.h  \
@@ -176,6 +176,7 @@ echo "#undef calloc"  >>  ${PROG}
 echo "#undef free"    >>  ${PROG}
 echo "#undef DOUBLE_PRECISION" >>  ${PROG}
 cat $srcdir/cfortran.h   >>  ${PROG}
+cat $srcdir/cdiFortran.h   >>  ${PROG}
 echo "#endif" >>  ${PROG}
 cat $srcdir/cdiFortran.c >>  ${PROG}
 
diff --git a/src/make_fint.c b/src/make_fint.c
index 27e7e7d6d267987ff61ce722841ded8d3763e38d..ceac799a39c26dc9034d0ccfe0a305c5e6a70d2e 100644
--- a/src/make_fint.c
+++ b/src/make_fint.c
@@ -10,7 +10,7 @@
 
 
 //#include "config.h"
-#define VERSION "1.6.0"
+#define VERSION "1.6.1"
 typedef struct
 {
   size_t naline;
@@ -62,7 +62,7 @@ static void doctotxt(FILE *fp, Docu *doc, size_t ndoc)
 
 enum cftype {ISVOID, ISCONSTSTRING, ISINT, ISREAL, ISDOUBLE, ISMPI_COMM,
              ISXT_IDXLIST, ISCHOICE, ISINTP, ISINTV, ISINTVV, ISREALP,
-             ISDOUBLEP, ISSTRING, ISSTRINGP,
+             ISDOUBLEP, ISCBUF, ISSTRING, ISSTRINGP,
              NUM_KNOWN_ARG_TYPES};
 
 enum conversionType { CONV_ARG, CONV_RET };
@@ -122,6 +122,8 @@ static struct symbol funArgSym[]
         "^"WS"*(const"WS"+)?float"WS"+\\*"SYMRE"?"WS"*[,\\)]", 2, 0 },
       { "DOUBLEPRECISION", "PDOUBLE", "double *",
         "^"WS"*(const"WS"+)?double"WS"+\\*"SYMRE"?"WS"*[,\\)]", 2, 0 },
+      { "CHARACTER*(*)",   "CBUF",    "char *",
+        "^"WS"*(const"WS"+)?char"WS"+\\*""([A-Za-z_][A-Za-z_0-9]*_cbuf)"WS"*[,\\)]", 2 },
       { "CHARACTER*(*)",   "STRING",  "char *",
         "^"WS"*const"WS"+char"WS"+\\*"WS"*"SYMRE"?"WS"*[,\\)]", 1, 0 },
       { "CHARACTER*(*)",   "PSTRING", "char *",
@@ -279,6 +281,10 @@ static void fortran_interface(char *fname, char *fnameinc, char *fnameint)
   fprintf(fpint, "#  include \"cfortran.h\"\n");
   fprintf(fpint, "#endif\n");
   fprintf(fpint, "\n");
+  fprintf(fpint, "#if ! defined (_CDIFORTRAN_H)\n");
+  fprintf(fpint, "#  include \"cdiFortran.h\"\n");
+  fprintf(fpint, "#endif\n");
+  fprintf(fpint, "\n");
 
   ssize_t lineLen;
   while ((lineLen = getline(&line, &lineBufSize, fpin)) >= 0)
@@ -304,7 +310,7 @@ static void fortran_interface(char *fname, char *fnameinc, char *fnameint)
         regmatch_t *nameMatch = reMatch + funRet[functype].nameMatch;
         if (debug)
           printf("Found: %.*s\n",
-                 nameMatch->rm_eo - nameMatch->rm_so,
+                 (int) (nameMatch->rm_eo - nameMatch->rm_so),
                  pline + nameMatch->rm_so);
         ssize_t funNameLast = reMatch[0].rm_eo - 1;
         ssize_t nameLen = nameMatch->rm_eo - nameMatch->rm_so;
diff --git a/src/model.c b/src/model.c
index 1ee09fdba80b9cc0a699f394421d7f41ff41d7d4..83441584ede02e7334e631325cb70a62be0b6c06 100644
--- a/src/model.c
+++ b/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"
@@ -173,7 +173,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;
@@ -216,7 +216,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/src/pio_interface.c b/src/pio_interface.c
index 2574339ba7d810a5cee386cf94bbdb17a05da21e..d7bc558dfddf01119c8df9a894841e47ff0809bc 100644
--- a/src/pio_interface.c
+++ b/src/pio_interface.c
@@ -23,7 +23,7 @@
 #include "pio_rpc.h"
 #include "pio_server.h"
 #include "resource_handle.h"
-#include "stream_int.h"
+#include "cdi_int.h"
 #include "vlist.h"
 
 
diff --git a/src/pio_server.c b/src/pio_server.c
index 258d8b42acff9b865f6cefebaed0c4bf2cea8289..9d188293fe309fc3ad36a5dbe81596a0cd7305a5 100644
--- a/src/pio_server.c
+++ b/src/pio_server.c
@@ -26,7 +26,7 @@
 #include "pio_interface.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/src/stream.c b/src/stream.c
index 8625a774e1764a165041af6bf8dec1f36639ba7b..1269baa0c390016d4e2be7498ca8c157fb25fd9c 100644
--- a/src/stream.c
+++ b/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"
@@ -93,6 +93,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/src/stream_cdf.c b/src/stream_cdf.c
index 59fa4020ee07bc0ad47125858482ba2cd50ae950..a0349d516025e51afc258d5136b3a899aaec8e5a 100644
--- a/src/stream_cdf.c
+++ b/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"
@@ -81,7 +81,8 @@ typedef struct {
   int      calendar;
   int      tableID;
   int      truncation;
-  int      defmiss;
+  int      defmissval;
+  int      deffillval;
   int      xtype;
   int      ndims;
   int      gmapid;
@@ -99,6 +100,7 @@ typedef struct {
   size_t   vlen;
   double  *vdata;
   double   missval;
+  double   fillval;
   double   addoffset;
   double   scalefactor;
   double   validrange[2];
@@ -106,6 +108,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;
@@ -688,10 +691,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);
 
@@ -4205,14 +4208,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;
@@ -4515,6 +4521,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;
@@ -4527,10 +4534,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, " ");
                 }
             }
         }
@@ -4864,11 +4881,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 )
@@ -5338,7 +5360,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;
@@ -5769,6 +5791,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);
@@ -5885,7 +5914,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 )
@@ -6115,7 +6145,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;
@@ -6166,9 +6196,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);
@@ -6199,7 +6227,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,
@@ -6259,6 +6294,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++ )
@@ -6324,9 +6364,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++ )
@@ -6403,7 +6448,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;
@@ -6469,15 +6514,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;
@@ -6524,6 +6577,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;
 
@@ -6595,7 +6649,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 )
@@ -6758,7 +6812,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;
 	}
@@ -6888,7 +6950,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 */
@@ -6930,7 +6992,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);
@@ -7028,10 +7090,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/src/stream_cgribex.c b/src/stream_cgribex.c
index fdabb1da44ebfe6796e4717a895682d31a7faa3d..343d72c3eb3146bbcc2a57191819dd6bb6247c26 100644
--- a/src/stream_cgribex.c
+++ b/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"
@@ -409,7 +409,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/src/stream_ext.c b/src/stream_ext.c
index d6c3cbe9214f34efd0e77fbc8c74f8fc40c13bfd..289aa4486102460d7156b2a74d36bbe9955c2903 100644
--- a/src/stream_ext.c
+++ b/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/src/stream_grb.c b/src/stream_grb.c
index 0323a490d295e6bc23cbb81604a8197342c621e3..8b7b89956f75caff8856dacb0c485866fc26b31d 100644
--- a/src/stream_grb.c
+++ b/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/src/stream_gribapi.c b/src/stream_gribapi.c
index 2cf4ef00b824dbaa16e27ca9ef3d32b61018f0c3..47439b0a26069684fd607ce6dc4f18197192acbc 100644
--- a/src/stream_gribapi.c
+++ b/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/src/stream_gribapi.h b/src/stream_gribapi.h
index 380d0d6319cfed01ad30be28e5d292f560910bdf..11bb7aa87b9d1946a2acc36b0a6c4fd0d434c13d 100644
--- a/src/stream_gribapi.h
+++ b/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/src/stream_history.c b/src/stream_history.c
index 558482c6c57be9a2293de38139538582499d28eb..adf6492c37b03ebb9e5c5380557bb3ad95b447c7 100644
--- a/src/stream_history.c
+++ b/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/src/stream_ieg.c b/src/stream_ieg.c
index 1c48d27380b7ed0d4ab8b8f329199a6f84f6bd24..33c2484630e4b3942046c4f25c8a2cc37f690be1 100644
--- a/src/stream_ieg.c
+++ b/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/src/stream_record.c b/src/stream_record.c
index d6f0299cdabd611752f40c5cf2e83771ec75735e..8de14e4dfff903e9a02d04930c597c6477efd762 100644
--- a/src/stream_record.c
+++ b/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/src/stream_srv.c b/src/stream_srv.c
index be8cfa30c8383983eb75d46a5f4ca3eb92c18fe0..5132b5ea1b9e2b0f19fa7717a999a8780d44b78b 100644
--- a/src/stream_srv.c
+++ b/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/src/stream_var.c b/src/stream_var.c
index a069e5edf97ad40cf8d1a7e99edea585feb191df..8f9fd9aff46ab28effa7f7b0e964db45b9a570c6 100644
--- a/src/stream_var.c
+++ b/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/src/table.c b/src/table.c
index e7f5fdcbb5a75a3a8eb2a8eabcc22b28a5f67a7d..33daaafc20c40abf214b28cab7a3fd18c664ac82 100644
--- a/src/table.c
+++ b/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/src/taxis.c b/src/taxis.c
index d21d7dff27185c4499f415abbbc64b485ef0ce27..02c99c066ac016b1f282810da546cf0ff063fa29 100644
--- a/src/taxis.c
+++ b/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/src/tsteps.c b/src/tsteps.c
index 1cc139ae50c3158461e43a42f41fa92c41dd537d..7eac592cf3535c20928a3b2eb1a43c89388513b2 100644
--- a/src/tsteps.c
+++ b/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/src/util.c b/src/util.c
index 6a0f540b36d49e62e0e150def7e0143e421307c1..3fa2ad035fe13bc67c2a2d289713eb027ca81898 100644
--- a/src/util.c
+++ b/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/src/varscan.c b/src/varscan.c
index f4a3a3f8d8cc1150172c75697080d90cff467aa8..15597a97b1738dbff7f82fddd449687baa5c0f27 100644
--- a/src/varscan.c
+++ b/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/src/varscan.h b/src/varscan.h
index f24f162cd6e80fe2f31b698b6a80c8f3509d3511..084d1f6fb03d1827967c3cdee6a66c1c3548d7a5 100644
--- a/src/varscan.h
+++ b/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/src/vlist.c b/src/vlist.c
index 6adb0beac37ef78bf56a16731347e4171f707dc2..cdd4bc2008d15cca0bddf01375265974b770ca93 100644
--- a/src/vlist.c
+++ b/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;
@@ -219,6 +225,7 @@ vlist_delete(vlist_t *vlistptr)
       if ( vlistptr->vars[varID].ensdata )  free(vlistptr->vars[varID].ensdata);
       if ( vlistptr->vars[varID].deco )     free(vlistptr->vars[varID].deco);
 
+#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] )
@@ -228,6 +235,7 @@ vlist_delete(vlist_t *vlistptr)
 	if ( vlistptr->vars[varID].opt_grib_dbl_keyword[i] )
 	  free(vlistptr->vars[varID].opt_grib_dbl_keyword[i]);
       }
+#endif
 
       vlistDelAtts(vlistID, varID);
     }
@@ -322,6 +330,7 @@ void vlistCopy(int vlistID2, int vlistID1)
                      decoSize * sizeof (deco_t));
             }
 
+#if  defined  (HAVE_LIBGRIB_API)
           /* ---------------------------------- */
           /* Local change: 2013-01-28, FP (DWD) */
           /* ---------------------------------- */
@@ -341,6 +350,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);
@@ -571,6 +581,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) */
 	    /* ---------------------------------- */
@@ -590,6 +601,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);
@@ -790,6 +802,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) */
       /* ---------------------------------- */
@@ -809,6 +822,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/src/vlist.h b/src/vlist.h
index a49f3940c827b93f68b9ec306521f3136fe612c0..2e6970fa1cb8cca46ff4acd4427398a4cdebf1db 100644
--- a/src/vlist.h
+++ b/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/src/vlist_att.c b/src/vlist_att.c
index 39076cb269d104d764ffeb9cfd10cd8e1b409ac4..db29cf247c406406c1cc381e8d108b7e469fdf31 100644
--- a/src/vlist_att.c
+++ b/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
 
-@Prototype int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, int *dp)
+@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
 
-@Prototype int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, int *tp)
+@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/src/vlist_var.c b/src/vlist_var.c
index ec938fd4a86cbcd153a8ddd1e4d414fc423df54a..53ef719abee38a2cbb7fdd648deb2c63b44029db 100644
--- a/src/vlist_var.c
+++ b/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
@@ -851,16 +854,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;
       }
 }
 
@@ -1176,6 +1179,87 @@ void vlistDefVarMissval(int vlistID, int varID, double missval)
   vlistptr->vars[varID].missvalused = TRUE;
 }
 
+/*
+@Function  vlistDefVarExtra
+@Title     Define extra information of a Variable
+
+@Prototype void vlistDefVarExtra(int vlistID, int varID, const char *extra)
+@Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  varID    Variable identifier.
+    @Item  extra    Extra information.
+
+@Description
+The function @func{vlistDefVarExtra} defines the extra information of a variable.
+
+@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);
+    }
+}
+
+/*
+@Function  vlistInqVarExtra
+@Title     Get extra information of a Variable
+
+@Prototype void vlistInqVarExtra(int vlistID, int varID, char *extra)
+@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}.
+
+@Description
+The function @func{vlistInqVarExtra} returns the extra information of a variable.
+
+@Result
+@func{vlistInqVarExtra} returns the extra information of the variable to the parameter extra if available,
+otherwise the result is an empty string.
+
+@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)
 {
@@ -1816,6 +1900,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);
 
@@ -1827,11 +1912,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);
 
@@ -1843,6 +1930,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)
@@ -1850,67 +1938,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/src/zaxis.c b/src/zaxis.c
index cc9ac8647b1f8a44e2f08f07febd8351611d74f6..2d383926794bc8b89c2d13edeff53abbd97a4ca0 100644
--- a/src/zaxis.c
+++ b/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},
-@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}.
 
 @EndFunction
diff --git a/tables/echam6cmip5 b/tables/echam6cmip5
index 871b0a5a1bb84ce5312f1c64c3ee189e277b3e94..bbcf2372c5570817fa56440ff1f74d562e3c2ce7 100644
--- a/tables/echam6cmip5
+++ b/tables/echam6cmip5
@@ -1,170 +1,168 @@
-&parameter  name=low_cld           /
-&parameter  name=mid_cld           /
-&parameter  name=hih_cld           /
-&parameter  name=fage              /
-&parameter  name=snifrac           /
-&parameter  name=barefrac          /
-&parameter  name=alsom             /
-&parameter  name=alsobs            /
-&parameter  name=sicepdw           /
-&parameter  name=sicepdi           /
-&parameter  name=tsicepdi          /
-&parameter  name=sicepres          /
-&parameter  name=ameltdepth        /
-&parameter  name=ameltfrac         /
-&parameter  name=albedo_vis_dir    /
-&parameter  name=albedo_nir_dir    /
-&parameter  name=albedo_vis_dif    /
-&parameter  name=albedo_nir_dif    /
-&parameter  name=ocu               /
-&parameter  name=ocv               /
-&parameter  name=tradl                             standard_name=net_upward_longwave_flux_in_air      factor=-1  /
-&parameter  name=sradl                             standard_name=net_downward_shortwave_flux_in_air   /
-&parameter  name=trafl                             standard_name=net_upward_longwave_flux_in_air_assuming_clear_sky  factor=-1  /
-&parameter  name=srafl                             standard_name=net_downward_shortwave_flux_in_air_assuming_clear_sky  /
-&parameter  name=amlcorac          /
-&parameter  name=amlheatac         /
-&parameter  name=trfliac           /
-&parameter  name=trflwac           /
-&parameter  name=trfllac           /
-&parameter  name=sofliac           /
-&parameter  name=soflwac           /
-&parameter  name=sofllac           /
-&parameter  name=friac             /
-&parameter  name=tsi               /
-&parameter  name=tsw                               standard_name=surface_temperature_where_open_sea  /
-&parameter  name=ustri             /
-&parameter  name=vstri             /
-&parameter  name=ustrw             /
-&parameter  name=vstrw             /
-&parameter  name=ustrl             /
-&parameter  name=vstrl             /
-&parameter  name=ahfliac           /
-&parameter  name=ahflwac           /
-&parameter  name=ahfllac           /
-&parameter  name=evapiac           /
-&parameter  name=evapwac           /
-&parameter  name=evaplac           /
-&parameter  name=az0i              /
-&parameter  name=az0w              /
-&parameter  name=az0l              /
-&parameter  name=ahfsiac           /
-&parameter  name=ahfswac           /
-&parameter  name=ahfslac           /
-&parameter  name=alsoi             /
-&parameter  name=alsow             /
-&parameter  name=alsol                             standard_name=soil_albedo   /
-&parameter  name=ahfice            /
-&parameter  name=qres              /
-&parameter  name=alake             /
-&parameter  name=rintop            /
-&parameter  name=geosp                             standard_name=surface_geopotential  /
-&parameter  name=t               out_name=ta       standard_name=air_temperature  /
-&parameter  name=u               out_name=ua       standard_name=eastward_wind  /
-&parameter  name=v               out_name=va       standard_name=northward_wind  /
-&parameter  name=q               out_name=hus      standard_name=specific_humidity  /
-&parameter  name=aps             out_name=ps       standard_name=surface_air_pressure   /
-&parameter  name=omega           out_name=wap      standard_name=lagrangian_tendency_of_air_pressure  /
-&parameter  name=acdnc             /
-&parameter  name=apmeb             /
-&parameter  name=svo               /
-&parameter  name=tslm1           out_name=tslsi    standard_name=surface_temperature  /
-&parameter  name=ws                                standard_name=soil_moisture_content  /
-&parameter  name=sn                                standard_name=surface_snow_amount  /
-&parameter  name=aprl                              standard_name=large_scale_rainfall_flux  /
-&parameter  name=aprc            out_name=prc      standard_name=convective_precipitation_flux  /
-&parameter  name=aprs            out_name=prsn     standard_name=snowfall_flux  /
-&parameter  name=vdis              /
-&parameter  name=ahfs            out_name=hfss     standard_name=surface_upward_sensible_heat_flux  factor=-1  /
-&parameter  name=ahfl            out_name=hfls     standard_name=surface_upward_latent_heat_flux  factor=-1  /
-&parameter  name=stream                            standard_name=atmosphere_horizontal_streamfunction  /
-&parameter  name=velopot           /
-&parameter  name=xivi            out_name=clivi    standard_name=atmosphere_cloud_ice_content  /
-&parameter  name=slp             out_name=psl      standard_name=air_pressure_at_sea_level  /
-&parameter  name=lsp               /
-&parameter  name=xl                /
-&parameter  name=xi                /
-&parameter  name=sd                                standard_name=divergence_of_wind  /
-&parameter  name=geopoth         out_name=zg       standard_name=geopotential_height  /
-&parameter  name=rhumidity       out_name=rhs      standard_name=relative_humidity    /
-&parameter  name=wind10w           /
-&parameter  name=runoff                            standard_name=runoff_flux  /
-&parameter  name=drain             /
-&parameter  name=aclc              /
-&parameter  name=aclcv             /
-&parameter  name=aclcov                            standard_name=cloud_area_fraction  /
-&parameter  name=u10                               standard_name=eastward_wind  /
-&parameter  name=v10                               standard_name=northward_wind  /
-&parameter  name=temp2                             standard_name=air_temperature  /
-&parameter  name=dew2                              standard_name=dew_point_temperature  /
-&parameter  name=tsurf           out_name=ts       standard_name=surface_temperature  /
-&parameter  name=xvar              /
-&parameter  name=wind10                            standard_name=wind_speed  /
-&parameter  name=slm               /
-&parameter  name=az0                               standard_name=surface_roughness_length  /
-&parameter  name=alb               /
-&parameter  name=albedo                            standard_name=surface_albedo  /
-&parameter  name=srads                             standard_name=surface_net_downward_shortwave_flux  /
-&parameter  name=trads                             standard_name=surface_net_downward_longwave_flux   /
-&parameter  name=srad0           out_name=rsut     standard_name=toa_outgoing_shortwave_flux  factor=-1  /
-&parameter  name=trad0           out_name=rlut     standard_name=toa_outgoing_longwave_flux  factor=-1  /
-&parameter  name=ustr            out_name=tauu     standard_name=surface_downward_eastward_stress   /
-&parameter  name=vstr            out_name=tauv     standard_name=surface_downward_northward_stress   /
-&parameter  name=evap              /
-&parameter  name=xskew             /
-&parameter  name=srad0d          out_name=rsdt     standard_name=toa_incoming_shortwave_flux  /
-&parameter  name=srafs             /
-&parameter  name=trafs             /
-&parameter  name=sraf0           out_name=rsutcs   standard_name=toa_outgoing_shortwave_flux_assuming_clear_sky  factor=-1  /
-&parameter  name=traf0           out_name=rlutcs   standard_name=toa_outgoing_longwave_flux_assuming_clear_sky  factor=-1  /
-&parameter  name=sclfs             /
-&parameter  name=tclfs             /
-&parameter  name=sclf0             /
-&parameter  name=tclf0             /
-&parameter  name=wl                /
-&parameter  name=slf               /
-&parameter  name=ustrgw                            standard_name=atmosphere_eastward_stress_due_to_gravity_wave_drag   /
-&parameter  name=vstrgw                            standard_name=atmosphere_northward_stress_due_to_gravity_wave_drag   /
-&parameter  name=vdisgw           /
-&parameter  name=vgrat                             standard_name=vegetation_area_fraction  /
-&parameter  name=orostd           /
-&parameter  name=vlt                               standard_name=leaf_area_index  /
-&parameter  name=t2max                             standard_name=air_temperature  /
-&parameter  name=t2min                             standard_name=air_temperature  /
-&parameter  name=srad0u                            standard_name=toa_outgoing_shortwave_flux  factor=-1  /
-&parameter  name=sradsu          out_name=rsus     standard_name=surface_upwelling_shortwave_flux_in_air   factor=-1  /
-&parameter  name=tradsu          out_name=rlus     standard_name=surface_upwelling_longwave_flux_in_air  factor=-1  /
-&parameter  name=grndflux          /
-&parameter  name=tsoil                             standard_name=soil_temperature  /
-&parameter  name=ahfcon            /
-&parameter  name=ahfres            /
-&parameter  name=seaice            /
-&parameter  name=siced             /
-&parameter  name=forest            /
-&parameter  name=gld               /
-&parameter  name=sni               /
-&parameter  name=rogl              /
-&parameter  name=wimax             /
-&parameter  name=topmax            /
-&parameter  name=snmel                             standard_name=surface_snow_melt_flux  /
-&parameter  name=runtoc            /
-&parameter  name=runlnd            /
-&parameter  name=apmegl            /
-&parameter  name=snacl             /
-&parameter  name=aclcac          out_name=cl       standard_name=cloud_area_fraction_in_atmosphere_layer  /
-&parameter  name=tke               /
-&parameter  name=tkem1             /
-&parameter  name=fao                               standard_name=soil_type  /
-&parameter  name=rgcgn             /
-&parameter  name=sodif             /
-&parameter  name=wsmx                              standard_name=soil_moisture_content_at_field_capacity  /
-&parameter  name=qvi             out_name=prw      standard_name=atmosphere_water_vapor_content  /
-&parameter  name=xlvi            out_name=clwvi    standard_name=atmosphere_cloud_condensed_water_content   /
-&parameter  name=glac                              standard_name=land_ice_area_fraction   /
-&parameter  name=snc               /
-&parameter  name=rtype             /
-&parameter  name=abso4             /
-&parameter  name=ao3               /
-&parameter  name=tropo             /
-&parameter  name=windspeed       out_name=sfcWind  standard_name=wind_speed  /
-&parameter  name=precip          out_name=pr       standard_name=precipitation_flux  /
+&parameter  code=34         name=low_cld     delete=1      /
+&parameter  code=35         name=mid_cld     delete=1      /
+&parameter  code=36         name=hih_cld     delete=1      /
+&parameter  code=68         name=fage        delete=1      /
+&parameter  code=69         name=snifrac     delete=1      /
+&parameter  code=70         name=barefrac    delete=1     /
+&parameter  code=71         name=alsom       delete=1       /
+&parameter  code=72         name=alsobs      delete=1      /
+&parameter  code=73         name=sicepdw     delete=1      /
+&parameter  code=74         name=sicepdi     delete=1      /
+&parameter  code=75         name=tsicepdi    delete=1      /
+&parameter  code=76         name=sicepres    delete=1      /
+&parameter  code=77         name=ameltdepth  delete=1      /
+&parameter  code=78         name=ameltfrac    delete=1     /
+&parameter  code=79         name=albedo_vis_dir delete=1   /
+&parameter  code=80         name=albedo_nir_dir  delete=1   /
+&parameter  code=81         name=albedo_vis_dif  delete=1  /
+&parameter  code=82         name=albedo_nir_dif  delete=1  /
+&parameter  code=83         name=ocu             delete=1  /
+&parameter  code=84         name=ocv             delete=1  /
+&parameter  code=85         name=tradl                standard_name=net_upward_longwave_flux_in_air      factor=-1  delete=0/
+&parameter  code=86         name=sradl                standard_name=net_downward_shortwave_flux_in_air   delete=0/
+&parameter  code=87         name=trafl                standard_name=net_upward_longwave_flux_in_air_assuming_clear_sky  factor=-1  delete=0/
+&parameter  code=88         name=srafl                standard_name=net_downward_shortwave_flux_in_air_assuming_clear_sky delete=0 /
+&parameter  code=89         name=amlcorac         delete=1 /
+&parameter  code=90         name=amlheatac        delete=1 /
+&parameter  code=91         name=trfliac          delete=1 /
+&parameter  code=92         name=trflwac          delete=1 /
+&parameter  code=93         name=trfllac          delete=1 /
+&parameter  code=94         name=sofliac          delete=1 /
+&parameter  code=95         name=soflwac          delete=1 /
+&parameter  code=96         name=sofllac          delete=1 /
+&parameter  code=97         name=friac            delete=1 /
+&parameter  code=102        name=tsi              delete=1 /
+&parameter  code=103        name=tsw              delete=1                 standard_name=surface_temperature_where_open_sea delete=1 /
+&parameter  code=104        name=ustri            delete=1 /
+&parameter  code=105        name=vstri            delete=1 /
+&parameter  code=106        name=ustrw            delete=1 /
+&parameter  code=107        name=vstrw            delete=1 /
+&parameter  code=108        name=ustrl            delete=1 /
+&parameter  code=109        name=vstrl            delete=1 /
+&parameter  code=110        name=ahfliac          delete=1 /
+&parameter  code=111        name=ahflwac          delete=1 /
+&parameter  code=112        name=ahfllac          delete=1 /
+&parameter  code=113        name=evapiac          delete=1 /
+&parameter  code=114        name=evapwac          delete=1 /
+&parameter  code=115        name=evaplac          delete=1 /
+&parameter  code=116        name=az0i             delete=1 /
+&parameter  code=117        name=az0w             delete=1 /
+&parameter  code=118        name=az0l             delete=1 /
+&parameter  code=119        name=ahfsiac          delete=1 /
+&parameter  code=120        name=ahfswac          delete=1 /
+&parameter  code=121        name=ahfslac          delete=1 /
+&parameter  code=122        name=alsoi            delete=1 /
+&parameter  code=123        name=alsow            delete=1 /
+&parameter  code=124        name=alsol                       standard_name=soil_albedo delete=1  /
+&parameter  code=125        name=ahfice           delete=1 /
+&parameter  code=126        name=qres             delete=1 /
+&parameter  code=127        name=alake            delete=1 /
+&parameter  code=128        name=rintop           delete=1 /
+&parameter  code=129        name=geosp                             standard_name=surface_geopotential delete=1  /
+&parameter  code=130        name=t               out_name=ta       standard_name=air_temperature delete=0 /
+&parameter  code=131        name=u               out_name=ua       standard_name=eastward_wind  delete=0/
+&parameter  code=132        name=v               out_name=va       standard_name=northward_wind delete=0 /
+&parameter  code=133        name=q               out_name=hus      standard_name=specific_humidity  delete=0/
+&parameter  code=134        name=aps             out_name=ps       standard_name=surface_air_pressure   delete=0/
+&parameter  code=135        name=omega           out_name=wap      standard_name=lagrangian_tendency_of_air_pressure delete=0 /
+&parameter  code=136        name=acdnc            delete=1 /
+&parameter  code=137        name=apmeb            delete=1 /
+&parameter  code=138        name=svo              delete=1 /
+&parameter  code=140        name=ws             out_name=mrso      standard_name=soil_moisture_content factor=1000  delete=0/
+&parameter  code=141        name=sn             out_name=snw       standard_name=surface_snow_amount  factor=1000 delete=0/
+&parameter  code=142        name=aprl                              standard_name=large_scale_rainfall_flux  delete=1/
+&parameter  code=143        name=aprc            out_name=prc      standard_name=convective_precipitation_flux  delete=0/
+&parameter  code=144        name=aprs            out_name=prsn     standard_name=snowfall_flux  delete=0/
+&parameter  code=145        name=vdis             delete=1 /
+&parameter  code=146        name=ahfs            out_name=hfss     standard_name=surface_upward_sensible_heat_flux  factor=-1  delete=0/
+&parameter  code=147        name=ahfl            out_name=hfls     standard_name=surface_upward_latent_heat_flux  factor=-1  delete=0/
+&parameter  code=148        name=stream                            standard_name=atmosphere_horizontal_streamfunction  delete=1/
+&parameter  code=149        name=velopot          delete=1 /
+&parameter  code=150        name=xivi            out_name=clivi    standard_name=atmosphere_cloud_ice_content delete=0 /
+&parameter  code=151        name=slp             out_name=psl      standard_name=air_pressure_at_sea_level delete=0 /
+&parameter  code=152        name=lsp              delete=1 /
+&parameter  code=153        name=xl              out_name=clw      standard_name=cloud_water   delete=0            /
+&parameter  code=154        name=xi              out_name=cli      standard_name=cloud_ice     delete=0  /
+&parameter  code=155        name=sd                                standard_name=divergence_of_wind  delete=1/
+&parameter  code=156        name=geopoth         out_name=zg       standard_name=geopotential_height delete=0 /
+&parameter  code=157        name=rhumidity       out_name=hur      standard_name=relative_humidity   factor=100 delete=0 / 
+&parameter  code=160        name=runoff          out_name=mrro     standard_name=runoff_flux delete=0 /
+&parameter  code=161        name=drain            delete=1 /
+&parameter  code=162        name=aclc             delete=1 /
+&parameter  code=163        name=aclcv            delete=1 /
+&parameter  code=164        name=aclcov          out_name=clt      standard_name=cloud_area_fraction  factor=100 delete=0/
+&parameter  code=165        name=u10             out_name=uas      standard_name=eastward_wind  delete=0/
+&parameter  code=166        name=v10             out_name=vas      standard_name=northward_wind delete=0 /
+&parameter  code=167        name=temp2           out_name=tas      standard_name=air_temperature  delete=0/
+&parameter  code=168        name=dew2                              standard_name=dew_point_temperature  delete=1/
+&parameter  code=169        name=tsurf           out_name=ts       standard_name=surface_temperature delete=0 /
+&parameter  code=170        name=xvar              delete=1/
+&parameter  code=171        name=wind10          out_name=sfcWind  standard_name=wind_speed delete=0 /
+&parameter  code=172        name=slm              delete=1 /
+&parameter  code=173        name=az0                               standard_name=surface_roughness_length  delete=1/
+&parameter  code=174        name=alb               delete=1/
+&parameter  code=175        name=albedo                            standard_name=surface_albedo delete=1 /
+&parameter  code=176        name=srads                             standard_name=surface_net_downward_shortwave_flux delete=1 /
+&parameter  code=177        name=trads                             standard_name=surface_net_downward_longwave_flux  delete=1 /
+&parameter  code=178        name=srad0u          out_name=rsut     standard_name=toa_outgoing_shortwave_flux  factor=-1 delete=0 /
+&parameter  code=179        name=trad0           out_name=rlut     standard_name=toa_outgoing_longwave_flux  factor=-1 delete=0 /
+&parameter  code=180        name=ustr            out_name=tauu     standard_name=surface_downward_eastward_stress  delete=0 /
+&parameter  code=181        name=vstr            out_name=tauv     standard_name=surface_downward_northward_stress delete=0  /
+&parameter  code=182        name=evap            out_name=evspsbl  standard_name=evaporation  factor=-1  delete=0  /
+&parameter  code=183        name=xskew            delete=1 /
+&parameter  code=184        name=srad0d          out_name=rsdt     standard_name=toa_incoming_shortwave_flux delete=0 /
+&parameter  code=185        name=srafs                             standard_name=net_surface_solar_radiation_clear_sky  delete=1 /
+&parameter  code=186        name=trafs                             standard_name=net_surface_thermal_radiation_clear_sky delete=1 /
+&parameter  code=187        name=sraf0                             standard_name=toa_outgoing_shortwave_flux_assuming_clear_sky  factor=-1 delete=1 /
+&parameter  code=188        name=traf0           out_name=rlutcs   standard_name=toa_outgoing_longwave_flux_assuming_clear_sky  factor=-1 delete=0 /
+&parameter  code=189        name=sclfs             delete=1/
+&parameter  code=190        name=tclfs             delete=1/
+&parameter  code=191        name=sclf0             delete=1/
+&parameter  code=192        name=tclf0             delete=1/
+&parameter  code=193        name=wl                delete=1/
+&parameter  code=194        name=slf               delete=1/
+&parameter  code=195        name=ustrgw                            standard_name=atmosphere_eastward_stress_due_to_gravity_wave_drag  delete=1 /
+&parameter  code=196        name=vstrgw                            standard_name=atmosphere_northward_stress_due_to_gravity_wave_drag delete=1  /
+&parameter  code=197        name=vdisgw           delete=1/
+&parameter  code=198        name=vgrat                             standard_name=vegetation_area_fraction delete=1 /
+&parameter  code=199        name=orostd           delete=1/
+&parameter  code=200        name=vlt                               standard_name=leaf_area_index  delete=1/
+&parameter  code=201        name=t2max           out_name=tasmax   standard_name=maximum_2m_temperature delete=0 /
+&parameter  code=202        name=t2min           out_name=tasmin   standard_name=minimum_2m_temperature delete=0 /
+&parameter  code=203        name=srad0u                            standard_name=toa_outgoing_shortwave_flux  factor=-1 delete=1 /
+&parameter  code=204        name=sradsu          out_name=rsus     standard_name=surface_upwelling_shortwave_flux_in_air   factor=-1 delete=0 /
+&parameter  code=205        name=tradsu          out_name=rlus     standard_name=surface_upwelling_longwave_flux_in_air  factor=-1  delete=0/
+&parameter                  name=grndflux         delete=1 /
+&parameter                  name=tsoil                             standard_name=soil_temperature delete=1  /
+&parameter  code=208        name=ahfcon            delete=1/
+&parameter  code=209        name=ahfres            delete=1/
+&parameter  code=210        name=seaice            delete=1/
+&parameter  code=211        name=siced             delete=1/
+&parameter  code=212        name=forest            delete=1/
+&parameter  code=213        name=gld               delete=1/
+&parameter  code=214        name=sni               delete=1/
+&parameter  code=215        name=rogl              delete=1/
+&parameter  code=216        name=wimax         out_name=sfcWindmax standard_name=wind_speed  delete=0/         
+&parameter  code=217        name=topmax        out_name=cct        standard_name=maximum_height_of_convective_cloud_tops       delete=1/
+&parameter  code=218        name=snmel         out_name=snm        standard_name=surface_snow_melt_flux  delete=0/
+&parameter  code=219        name=runtoc           delete=1 /
+&parameter  code=220        name=runlnd            delete=1/
+&parameter  code=221        name=apmegl            delete=1/
+&parameter  code=222        name=snacl                             standard_name=snow_accumulation_over_land  delete=1/
+&parameter  code=223        name=aclcac          out_name=cl       standard_name=cloud_area_fraction_in_atmosphere_layer  factor=100 delete=0/
+&parameter  code=224        name=tke              delete=1 /
+&parameter  code=225        name=tkem1            delete=1 /
+&parameter  code=226        name=fao                               standard_name=soil_type delete=1 /
+&parameter  code=227        name=rgcgn             delete=1/
+&parameter  code=228        name=sodif             delete=1/
+&parameter  code=229        name=wsmx            out_name=mrsomax  standard_name=soil_moisture_content_at_field_capacity factor=1000 delete=1 /
+&parameter  code=230        name=qvi             out_name=prw      standard_name=atmosphere_water_vapor_content  delete=0/
+&parameter  code=231        name=xlvi            out_name=clwvi    standard_name=atmosphere_cloud_condensed_water_content   delete=0/
+&parameter  code=232        name=glac                              standard_name=land_ice_area_fraction   delete=1/
+&parameter  code=60         name=var60           out_name=snc      standard_name=surface_snow_area_fraction  factor=100 delete=0/
+&parameter  code=234        name=rtype                             standard_name=type_of_convection delete=1/
+&parameter  code=235        name=abso4                             standard_name=antropogenic_sulfur_burden  delete=1/
+&parameter  code=236        name=ao3             out_name=tro3     standard_name=mole_fraction_of_ozone_in_air  factor=1.e+9 delete=0/
+&parameter  code=237        name=tropo                             standard_name=WMO_defined_tropopause_height  delete=1 /
+&parameter  code=259        name=windspeed       out_name=sfcWind  standard_name=wind_speed  delete=0/
+&parameter  code=260        name=precip          out_name=pr       standard_name=precipitation_flux  delete=0/
diff --git a/tests/cksum_write.c b/tests/cksum_write.c
index 99cb8246479e0e651512a8dea86496f63d014448..7b25d6dfbef617133bc5098126421378ae3b3d2c 100644
--- a/tests/cksum_write.c
+++ b/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)
             {