From e0ecf58ae6eb37929d5548931bc96bae8aaf4305 Mon Sep 17 00:00:00 2001
From: Thomas Jahns <jahns@dkrz.de>
Date: Thu, 13 Jun 2013 14:20:55 +0000
Subject: [PATCH] Merge trunk into branch cdi-pio.

---
 .gitattributes                  |   9 +-
 ChangeLog                       |  70 +++++
 NEWS                            |  13 +
 app/cdi.c                       |  17 +-
 config/default                  |   4 +-
 configure                       | 125 ++++----
 configure.ac                    |  53 ++--
 doc/tex/c_quick_ref.tex         |  58 ++--
 doc/tex/c_ref.tex               |   4 +-
 doc/tex/c_vlist_att.tex         |   4 +-
 doc/tex/c_vlist_var.tex         |   2 +-
 doc/tex/c_zaxis.tex             |   4 +-
 doc/tex/cdi_cman.tex            |   8 +-
 doc/tex/cdi_fman.tex            |   8 +-
 doc/tex/f_quick_ref.tex         |  59 ++--
 doc/tex/f_ref.tex               |   5 +-
 doc/tex/f_vlist_att.tex         |   5 +-
 doc/tex/f_vlist_var.tex         |   2 +-
 doc/tex/f_zaxis.tex             |   4 +-
 doc/tex/formats.tex             |   1 +
 doc/tex/zaxis.tex               |   1 +
 examples/Makefile.am            |   5 +-
 examples/Makefile.in            |  19 +-
 examples/cdi_read_atts.f        |  79 ++++++
 examples/cdi_read_simple.f      |  55 ++++
 examples/cdi_read_sst.f         |  51 ++++
 examples/cdi_write_hybrid.c     | 122 ++++++++
 examples/compf                  |   4 +
 src/Makefile.am                 |   7 +-
 src/Makefile.in                 |  18 +-
 src/cdf.c                       |   2 +-
 src/cdf_int.c                   |   6 +-
 src/cdi.h                       |  44 +--
 src/cdi.inc                     |  73 +++--
 src/cdiFortran.c                |  44 ++-
 src/cdiFortran.h                |  20 ++
 src/{stream_int.c => cdi_int.c} |   8 +-
 src/{stream_int.h => cdi_int.h} |  18 +-
 src/cdi_util.c                  |  24 ++
 src/cfortran.h                  |   3 +
 src/config.h.in                 |   6 +
 src/gribapi.c                   |   2 +-
 src/gribapi.h                   |   1 +
 src/grid.c                      |   6 +-
 src/institution.c               |  14 +-
 src/make_cdilib                 |   5 +-
 src/make_fint.c                 |  12 +-
 src/model.c                     |   6 +-
 src/pio_interface.c             |   2 +-
 src/pio_server.c                |   2 +-
 src/stream.c                    |  42 ++-
 src/stream_cdf.c                | 132 ++++++---
 src/stream_cgribex.c            |   4 +-
 src/stream_ext.c                |   4 +-
 src/stream_grb.c                |  34 ++-
 src/stream_gribapi.c            | 489 ++++++++++++++++----------------
 src/stream_gribapi.h            |   2 +-
 src/stream_history.c            |   2 +-
 src/stream_ieg.c                |   4 +-
 src/stream_record.c             |   2 +-
 src/stream_srv.c                |   4 +-
 src/stream_var.c                |   4 +-
 src/table.c                     |   2 +-
 src/taxis.c                     |   2 +-
 src/tsteps.c                    |   2 +-
 src/util.c                      |   2 +-
 src/varscan.c                   | 109 ++++++-
 src/varscan.h                   |   6 +-
 src/vlist.c                     |  16 +-
 src/vlist.h                     |   8 +
 src/vlist_att.c                 |  43 +--
 src/vlist_var.c                 | 201 ++++++++++---
 src/zaxis.c                     |  17 +-
 tables/echam6cmip5              | 338 +++++++++++-----------
 tests/cksum_write.c             |  14 +-
 75 files changed, 1726 insertions(+), 871 deletions(-)
 create mode 100644 examples/cdi_read_atts.f
 create mode 100644 examples/cdi_read_simple.f
 create mode 100644 examples/cdi_read_sst.f
 create mode 100644 examples/cdi_write_hybrid.c
 create mode 100644 src/cdiFortran.h
 rename src/{stream_int.c => cdi_int.c} (99%)
 rename src/{stream_int.h => cdi_int.h} (96%)

diff --git a/.gitattributes b/.gitattributes
index dd9210965..87d02e684 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 5cb5508a9..e6f1a9c9c 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 ae614eb7b..c6825e7d7 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 92138b02e..76c4a1875 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 0599021e1..d47717759 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 020d7627a..78fcb00ac 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 784a86952..72312ca68 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 7a2fde779..089105975 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 792ecebdb..bc2a48b73 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 6da719808..f1344ab13 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 22ad2880e..409549762 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 b143fca04..05affaee1 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 c3f8e7a54..c2bf536be 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 2cc452df6..d6706294f 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 65e9b8a60..152b24b05 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 3977e36f0..759dea106 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 39a65cd57..835e1d206 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 fcf9ac74e..81adbfb3d 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 26dfacac6..7a4a4863e 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 5c6588b52..7371875fd 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 bbcbcb164..997aa9345 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 850875f3b..4baab3a5a 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 d294de129..a39b3f40e 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 000000000..259075467
--- /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 000000000..9c61df060
--- /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 000000000..556a9b042
--- /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 000000000..dd4fc7395
--- /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 dc0df0e99..ef152b65f 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 f2c5649e0..4e3395e83 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 57cb6c4d5..177cdbb59 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 b486d3754..ccd08ef0b 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 7346fe9fe..fbd548ed9 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 97dcc3f9b..72e57b59d 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 57c5f6b2c..6f868b0ed 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 234d5ca8a..0a02fc57e 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 000000000..500a2bcd5
--- /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 632c6b401..f51025879 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 3e35ee754..3d5006995 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 b5fc74fdc..18c00b672 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 ea0b0e916..694e40ef5 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 521e258b2..c161d198c 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 469267100..79337c780 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 080e39d4b..741ebaf85 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 72ecfa18a..77f5014b9 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 67c2b9531..a21fec52a 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 2fdf23a8c..4e5df7dcf 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 27e7e7d6d..ceac799a3 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 1ee09fdba..83441584e 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 2574339ba..d7bc558df 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 258d8b42a..9d188293f 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 8625a774e..1269baa0c 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 59fa4020e..a0349d516 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 fdabb1da4..343d72c3e 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 d6c3cbe92..289aa4486 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 0323a490d..8b7b89956 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 2cf4ef00b..47439b0a2 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 380d0d631..11bb7aa87 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 558482c6c..adf6492c3 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 1c48d2738..33c248463 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 d6f0299cd..8de14e4df 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 be8cfa30c..5132b5ea1 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 a069e5edf..8f9fd9aff 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 e7f5fdcbb..33daaafc2 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 d21d7dff2..02c99c066 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 1cc139ae5..7eac592cf 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 6a0f540b3..3fa2ad035 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 f4a3a3f8d..15597a97b 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 f24f162cd..084d1f6fb 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 6adb0beac..cdd4bc200 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 a49f3940c..2e6970fa1 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 39076cb26..db29cf247 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 ec938fd4a..53ef719ab 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 cc9ac8647..2d3839267 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 871b0a5a1..bbcf2372c 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 99cb82464..7b25d6dfb 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)
             {
-- 
GitLab