diff --git a/.gitattributes b/.gitattributes
index 8c1b0e423b1cc2d8535b605783ae1f54997b8606..73a5b0228ffc6d9b14d01ab384c0be4aa8161a1e 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -238,12 +238,22 @@ src/gaussgrid.h -text
 src/getline.c -text
 src/gribapi.c -text
 src/gribapi.h -text
+src/gribapi_utilities.c -text
+src/gribapi_utilities.h -text
 src/grid.c -text
 src/grid.h -text
 src/ieg.h -text
 src/ieglib.c -text
+src/input_file.c -text
+src/input_file.h -text
 src/institution.c -text
 src/institution.h -text
+src/iterator.c -text
+src/iterator.h -text
+src/iterator_fallback.c -text
+src/iterator_fallback.h -text
+src/iterator_grib.c -text
+src/iterator_grib.h -text
 src/make_cdilib -text
 src/make_fint.c -text
 src/mo_cdi.f90 -text
@@ -278,6 +288,10 @@ src/pio_util.c -text
 src/pio_util.h -text
 src/pkgconfig/cdi.pc.in -text
 src/pkgconfig/cdipio.pc.in -text
+src/proprietarySystemWorkarounds.c -text
+src/proprietarySystemWorkarounds.h -text
+src/referenceCounting.c -text
+src/referenceCounting.h -text
 src/resource_handle.c -text
 src/resource_handle.h -text
 src/resource_unpack.c -text
diff --git a/ChangeLog b/ChangeLog
index ff65c2304beee8e70caa2833775412930944cb01..a2af0ef5807e4342c56fbf7d0910e3f56f6919a5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2015-03-26  Uwe Schulzweida
+
+        * merged changes from branches/cdi_fileDrivenInput
+
 2015-03-26  Uwe Schulzweida
 
 	* Version 1.6.8 released
diff --git a/Makefile.in b/Makefile.in
index 21f4762505432c6c1cc48cff0535d00ae4468253..66cd526986a0bf7b364cc7d6654e5fddbef6e0f9 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -258,6 +258,7 @@ ENABLE_CGRIBEX = @ENABLE_CGRIBEX@
 ENABLE_EXTRA = @ENABLE_EXTRA@
 ENABLE_GRIB = @ENABLE_GRIB@
 ENABLE_IEG = @ENABLE_IEG@
+ENABLE_MPI = @ENABLE_MPI@
 ENABLE_NC2 = @ENABLE_NC2@
 ENABLE_NC4 = @ENABLE_NC4@
 ENABLE_NETCDF = @ENABLE_NETCDF@
diff --git a/NEWS b/NEWS
index 17fc3c3e65aec690497f7c13fe484f29f4321d5a..2f1232d21edcac58d3dd1404143a45b901bdcbf9 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,14 @@
 CDI NEWS
 --------
 
+Version 1.6.8 (26 March 2015):
+
+   Fixed bugs:
+     * cdfCopyRecord: incorrect checksum for freed object [Bug #5461]
+     * scan netcdf time units attribute
+     * fixed rounding error for negativ timevalue
+     * time unit second rounding error
+
 Version 1.6.7 (5 December 2014):
 
    Fixed bugs:
diff --git a/app/Makefile.in b/app/Makefile.in
index c826be658dfd0f7d5759e0c631dd0cfd7b5996a6..b130d304eaf69661ec917fcc3f1b3008c3020006 100644
--- a/app/Makefile.in
+++ b/app/Makefile.in
@@ -231,6 +231,7 @@ ENABLE_CGRIBEX = @ENABLE_CGRIBEX@
 ENABLE_EXTRA = @ENABLE_EXTRA@
 ENABLE_GRIB = @ENABLE_GRIB@
 ENABLE_IEG = @ENABLE_IEG@
+ENABLE_MPI = @ENABLE_MPI@
 ENABLE_NC2 = @ENABLE_NC2@
 ENABLE_NC4 = @ENABLE_NC4@
 ENABLE_NETCDF = @ENABLE_NETCDF@
diff --git a/app/cdi.c b/app/cdi.c
index 277e1281ccdb9fb96a876ec585a5a0d66ac3ab97..912dbd39889ccc135db7e34acc6039eeaa63b227 100644
--- a/app/cdi.c
+++ b/app/cdi.c
@@ -141,7 +141,7 @@ void version(void)
 static
 void usage(void)
 {
-  char *name;
+  const char *name;
   int id;
 
   fprintf(stderr, "usage : %s  [Option]  [ifile]  [ofile]\n", Progname);
diff --git a/examples/Makefile.in b/examples/Makefile.in
index 91fbf0e42ddf79e167c0c22381c1cdbc74fcbd07..e7ec26b544d0033eafd5c2539805e6dbb5d99dc2 100644
--- a/examples/Makefile.in
+++ b/examples/Makefile.in
@@ -279,6 +279,7 @@ ENABLE_CGRIBEX = @ENABLE_CGRIBEX@
 ENABLE_EXTRA = @ENABLE_EXTRA@
 ENABLE_GRIB = @ENABLE_GRIB@
 ENABLE_IEG = @ENABLE_IEG@
+ENABLE_MPI = @ENABLE_MPI@
 ENABLE_NC2 = @ENABLE_NC2@
 ENABLE_NC4 = @ENABLE_NC4@
 ENABLE_NETCDF = @ENABLE_NETCDF@
diff --git a/examples/cdi_read_f2003.f90 b/examples/cdi_read_f2003.f90
index 9128712f9cecabdfa27a75eff5e25c6bd2ac915a..1281e1b5c8b8462a62c8e54babfff7a1713d7709 100644
--- a/examples/cdi_read_f2003.f90
+++ b/examples/cdi_read_f2003.f90
@@ -11,7 +11,7 @@ PROGRAM CDIREADF2003
   DOUBLE PRECISION, ALLOCATABLE :: field(:,:)
   CHARACTER(kind=c_char), POINTER, DIMENSION(:) :: &
        msg, cdi_version
-  CHARACTER(kind=c_char), DIMENSION(cdi_max_name + 1) :: &
+  CHARACTER(kind=c_char, LEN = cdi_max_name + 1) :: &
        name, longname, units
   INTEGER :: name_c_len, longname_c_len, units_c_len
 
diff --git a/examples/pio/Makefile.in b/examples/pio/Makefile.in
index 0588e1e81a32cbbe29ca0186e0284e06cc563042..dee19eadfcaaaa2b3e4078d80261c9a68fc54a00 100644
--- a/examples/pio/Makefile.in
+++ b/examples/pio/Makefile.in
@@ -273,6 +273,7 @@ ENABLE_CGRIBEX = @ENABLE_CGRIBEX@
 ENABLE_EXTRA = @ENABLE_EXTRA@
 ENABLE_GRIB = @ENABLE_GRIB@
 ENABLE_IEG = @ENABLE_IEG@
+ENABLE_MPI = @ENABLE_MPI@
 ENABLE_NC2 = @ENABLE_NC2@
 ENABLE_NC4 = @ENABLE_NC4@
 ENABLE_NETCDF = @ENABLE_NETCDF@
diff --git a/interfaces/Makefile.in b/interfaces/Makefile.in
index 26a901514740ba4de73259f05880fa0639564858..646a909aaad40acfe6727085f0b1bb0f13109a17 100644
--- a/interfaces/Makefile.in
+++ b/interfaces/Makefile.in
@@ -257,6 +257,7 @@ ENABLE_CGRIBEX = @ENABLE_CGRIBEX@
 ENABLE_EXTRA = @ENABLE_EXTRA@
 ENABLE_GRIB = @ENABLE_GRIB@
 ENABLE_IEG = @ENABLE_IEG@
+ENABLE_MPI = @ENABLE_MPI@
 ENABLE_NC2 = @ENABLE_NC2@
 ENABLE_NC4 = @ENABLE_NC4@
 ENABLE_NETCDF = @ENABLE_NETCDF@
diff --git a/interfaces/cdi.hpp b/interfaces/cdi.hpp
index a248568b2cda030de66dd9c78027a7200219f14b..96bdbb0e19504f380f240ee94237c418b5887701 100644
--- a/interfaces/cdi.hpp
+++ b/interfaces/cdi.hpp
@@ -40,7 +40,8 @@ class CdiTaxis {
     int ntsteps, unit;
     int rdate, rtime, vdate, vtime;
     int type, calendar, hasBounds;
-    char name[CHARSIZE], *unitname;
+    char name[CHARSIZE];
+    const char *unitname;
 };
 
 class CdiZaxis {
diff --git a/interfaces/f2003/bindGen.rb b/interfaces/f2003/bindGen.rb
index 6cff4300f861349d1eb3c4effcac14a26adc3a68..b643f474b6ceaaa9a4f219aabe51c0e81fad0f80 100755
--- a/interfaces/f2003/bindGen.rb
+++ b/interfaces/f2003/bindGen.rb
@@ -1,508 +1,780 @@
 #!/usr/bin/env ruby
-require 'optparse'
-################################################################
-# CONFIGURATION:
-CFTypeInfo             = {
-  'int'                  => {:namedConst       => 'c_int'                , :ftype => 'integer'},
-  'short int'            => {:namedConst       => 'c_short'              , :ftype => 'integer'},
-  'long int'             => {:namedConst       => 'c_long'               , :ftype => 'integer'},
-  'long long int'        => {:namedConst       => 'c_long_long'          , :ftype => 'integer'},
-  'signed char'          => {:namedConst       => 'c_signed_char'        , :ftype => 'integer'},
-  'unsigned char'        => {:namedConst       => 'c_signed_char'        , :ftype => 'integer'},
-  'size_t'               => {:namedConst       => 'c_size_t'             , :ftype => 'integer'},
-  'int8_t'               => {:namedConst       => 'c_int8_t'             , :ftype => 'integer'},
-  'int16_t'              => {:namedConst       => 'c_int16_t'            , :ftype => 'integer'},
-  'int32_t'              => {:namedConst       => 'c_int32_t'            , :ftype => 'integer'},
-  'int64_t'              => {:namedConst       => 'c_int64_t'            , :ftype => 'integer'},
-  'int_fast8_t'          => {:namedConst       => 'c_int_fast8_t'        , :ftype => 'integer'},
-  'int_fast16_t'         => {:namedConst       => 'c_int_fast16_t'       , :ftype => 'integer'},
-  'int_fast32_t'         => {:namedConst       => 'c_int_fast32_t'       , :ftype => 'integer'},
-  'int_fast64_t'         => {:namedConst       => 'c_int_fast64_t'       , :ftype => 'integer'},
-  'int_least8_t'         => {:namedConst       => 'c_int_least8_t'       , :ftype => 'integer'},
-  'int_least16_t'        => {:namedConst       => 'c_int_least16_t'      , :ftype => 'integer'},
-  'int_least32_t'        => {:namedConst       => 'c_int_least32_t'      , :ftype => 'integer'},
-  'int_least64_t'        => {:namedConst       => 'c_int_least64_t'      , :ftype => 'integer'},
-  'intmax_t'             => {:namedConst       => 'c_intmax_t'           , :ftype => 'integer'},
-  'intptr_t'             => {:namedConst       => 'c_intptr_t'           , :ftype => 'integer'},
-
-  'float'                => {:namedConst       => 'c_float'              , :ftype => 'real'},
-  'double'               => {:namedConst       => 'c_double'             , :ftype => 'real'},
-  'long double'          => {:namedConst       => 'c_long_double'        , :ftype => 'real'},
-
-  'float _Complex'       => {:namedConst       => 'c_float_complex'      , :ftype => 'complex'},
-  'double _Complex'      => {:namedConst       => 'c_double_complex'     , :ftype => 'complex'},
-  'long double _Complex' => {:namedConst       => 'c_long_double_complex', :ftype => 'complex'},
-  '_Bool'                => {:namedConst       => 'c_bool'               , :ftype => 'logical'},
-  'char'                 => {:namedConst       => 'c_char'               , :ftype => 'character'}
-}
-# how the module should be invoked from fortran
-ModuleName    = 'mo_cdi'
-# which conversion is to use generating the fortran routine names, this could
-# be any ruby String method.
-FNameMethod   = :noop
-# FNameMethod = :downcase
-# FNameMethod = :noop
-# FNameMethod = :upcase
-class String;def noop;self;end;end
-# fortran subroutines are not allowed to have a parameters with the same name,
-# so in case of a match, these parameters have to get an new name
-FParamExtension = 'v'
-# Naming convention from above: 
-# all non scalar variables should have the postfix '_vec' in there name
-Vectors = /_vec$/i
-################################################################################
-FortranMaxLineLength = 132
-# read the c header file and grep out name, return type and paramterlist of
-# each function
-def getFuncInfo(filename)
-  typelist = %w[char int float double void]
-  cppflags = ENV['CPPFLAGS'].nil? ? '' : ENV['CPPFLAGS']
-  funclist = IO.popen("cpp #{cppflags} #{filename} | cpp -fpreprocessed").readlines.delete_if {|line| line.include?('#')}.collect {|line| line.chomp}
-  # delete everything, that do not look like a function prototype
-  typeRegexp = /^.*(#{typelist.join('|')}) \**\w+\s*\(.*\)/
-  funclist.delete_if {|line|
-    not typeRegexp.match(line.lstrip)
-  }
-  funclist.collect! {|line|
-    md = /(\w+)+ +(\**)(\w+)\s*\((.*)\)/.match(line)
-    returnType, returnPointer, funcName, paramList = md[1,4]
-    paramList = paramList.split(',').collect {|p| p.split(' ').each {|_p| _p.strip}}
-    [funcName, returnType, returnPointer, paramList]
-  }
-  funclist
-end
 
-# grep the #define C-Constants, which should be available within the fortran CDI API
-def getDefines(filename)
-  defines = File.open(filename,'r').readlines.grep(/^#define/).collect {|line|
-    md = / +(\w+) +(-*\d+)/.match(line)
-  }.select {|item| not item.nil?}.collect {|match| match[1..2]}
+# This script generates a fortran source file that uses the ISO_C_BINDINGS to interface to the functions defined in the given C header file.
+# The basic approach is, that every C function is wrapped in a fortran function/subroutine, which internally uses a bind(c) interface to the C code.
+# This wrapper based approach has the advantage that the wrapper is free to provide a true fortran interface
+# that enables full type checking of its arguments; the pure bind(c) interface would not be able to distinguish
+# between different opaque pointer types, for instance, nor would it be able to infer the size of a static string returned by a C function.
+#
+# Within this header file, the following constructs are recognized:
+#
+#   * #define FOO 123
+#   * typedef struct foo foo;
+#   * typedef struct foo { ... } foo;
+#   * ... foo(...);
+#
+# These constructs are used to divide a source line into parts that are recognizable by the templates defined below.
+# A function definition, for instance, is divided into a return type, a function name, and a number of argument definitions,
+# the return type and argument descriptions are matched against templates which define the translation of these parts into fortran code.
+# Note that all these constructs must be one-liners since processing in this script is line based.
+#
+# Every template is a hash that contains an entry :regex, which is used to match it against the corresponding C declaration.
+# There are a couple of placeholders that may be used within these regex strings, they are expanded by matchTemplate() before a Regexp object is constructed from the string in :regex.
+# These placeholders are:
+#	<integerTypes>	matches the C integer types that can be used within Fortran by prefixing 'c_' to the type
+#	<floatTypes>	matches the C floating point types that can be used within Fortran by prefixing 'c_' to the type
+#	<opaqueTypes>	matches all the opaque types defined within the header
+#	<publicTypes>	matches all the public types defined within the header
+#
+# In the case of argument and type templates, this :regex may contain one or more named subexpressions /(?<name>...)/,
+# which can be included in the other fields by means of a corresponding placeholder "<name>".
+# The names of the subexpressions that are to be substituted in this way need to be listed in the :placeholders key.
+# This is usually used to capture the variable name, and then use "<name>_foo" to derive fortran variable names from the argument name,
+# but it may also be used to capture the size of an array declaration.
+# Since fortran uses so many keywords that can easily conflict with C argument names, it is a good idea not to use a naked "<name>";
+# always append something to it as in "<name>_dummy"
+#
+# Argument templates must provide the following fields:
+#	:regex	A regex that matches the whole definition of a C argument. Make sure it only matches the cases that the template can actually handle!
+#	:placeholders	An array of the name of the named subexpressions used in the regex. For the :regex => /(?<foo>.),(?<bar>.)/ you would use :placeholders => %w[foo bar]
+#	:dummyName	The name of the fortran dummy argument. Both the wrapper function and the `bind(c)` interface use the same name.
+#	:acceptAs	The declaration of the dummy argument in the fortran wrapper.
+#	:helperVars	Declarations of additional variables needed to provide the desired functionality in the wrapper function.
+#	:precallStatements	Code that needs to be executed before the C function is called.
+#	:callExpression	The actual argument that the wrapper passes to the C function.
+#	:passAs	The declaration of the dummy argument in the `bind(c)` interface.
+#	:postcallStatements	Code that needs to be executed after the C function returns.
+#
+#
+#
+# Return type templates are similar to argument templates, but they have to deal with the fact that fortran differentiates between subroutines and functions. Because of this, return type templates add the :isVoid key which is only true if the C function returns `void`.
+#
+# Return type templates must provide the following fields:
+#	:regex	A regex that matches the whole definition of a C return type. Make sure it only matches the cases that the template can actually handle!
+#	:isVoid	Always false, except for the template for `void`.
+#	:returnAs	The type of the fortran wrapper function.
+#	:helperVars	Declarations of additional variables needed to provide the desired functionality in the wrapper function.
+#	:precallStatements	Code that needs to be executed before the C function is called.
+#	:recieveAs	The type of the `bind(c)` interface function.
+#	:assignVariable	The expression that the result of the C function is assigned to.
+#	:postcallStatements	Code that needs to be executed after the C function returns.
+#
+#
+#
+# Type templates are used for the variables in public `struct` definitions. These are much simpler as they only have to translate a C variable declaration into an interoperable fortran variable declaration.
+#
+# Type templates must provide the following fields:
+#	:regex	A regex that matches the whole C variable definition. Make sure it only matches the cases that the template can actually handle!
+#	:placeholders	An array of the name of the named subexpressions used in the regex. Same semantics as in an argument template.
+#	:declareAs	The declaration of the corresponding fortran derived type member.
+#
+#
+#
+# The wrapper that is generated for a non-void C function looks like this:
+#
+#	function fname(:dummyName...) result(result)
+#		:returnAs :: result
+#		:acceptAs...
+#		:helperVars...
+#		interface
+#			:recieveAs function lib_fname(:dummyName...) bind(c, name = 'fname')
+#				import <importConstants>
+#				:passAs...
+#			end function lib_fname
+#		end interface
+#		:precallStatements
+#		:assignVariable = lib_fname(:callExpression)
+#		:postcallStatements
+#	end function fname
+#
+#
+#
+# The wrapper that is generated for a void C function looks like this:
+#
+#	subroutine fname(:dummyName...)
+#		:acceptAs...
+#		:helperVars...
+#		interface
+#			subroutine lib_fname(:dummyName...) bind(c, name = 'fname')
+#				import <importConstants>
+#				:passAs...
+#			end subroutine lib_fname
+#		end interface
+#		:precallStatements
+#		call lib_fname(:callExpression)
+#		:postcallStatements
+#	end subroutine fname
+
+####################################################################################################
+# Template definitions #############################################################################
+####################################################################################################
+
+$argumentTemplates = [
+	{	#Dummy for declarations using foo(void).
+		:regex => '^\s*void\s*$',
+		:placeholders => %w[],
+		:dummyName => '',
+		:acceptAs => '',
+		:helperVars => '',
+		:precallStatements => '',
+		:callExpression => '',
+		:passAs => '',
+		:postcallStatements => ''
+	}, {	#<integerTypes>
+		:regex => '^\s*(?<type><integerTypes>)\s+(?<name>\w+)\s*$',
+		:placeholders => %w[name type],
+		:dummyName => '<name>_dummy',
+		:acceptAs => 'integer(c_<type>), value :: <name>_dummy',
+		:helperVars => '',
+		:precallStatements => '',
+		:callExpression => '<name>_dummy',
+		:passAs => 'integer(c_<type>), value :: <name>_dummy',
+		:postcallStatements => ''
+	}, {	#<floatTypes>
+		:regex => '^\s*(?<type><floatTypes>)\s+(?<name>\w+)\s*$',
+		:placeholders => %w[name type],
+		:dummyName => '<name>_dummy',
+		:acceptAs => 'real(c_<type>), value :: <name>_dummy',
+		:helperVars => '',
+		:precallStatements => '',
+		:callExpression => '<name>_dummy',
+		:passAs => 'real(c_<type>), value :: <name>_dummy',
+		:postcallStatements => ''
+	},
+	#Array arguments. These are marked by a `_vec` suffix by convention.
+	#Since it's near impossible to write regexs that only match names that do *not* end in a given suffix,
+	#these templates must precede the more general templates for pointer arguments.
+	#That way, we can override the more general template with the more special one if both match.
+	{	#<integerTypes>* <name>_vec
+		:regex => '^\s*(?<type><integerTypes>)\s*\*\s*(?<name>\w+_vec)\s*$',
+		:placeholders => %w[name type],
+		:dummyName => '<name>_dummy',
+		:acceptAs => 'integer(c_<type>), intent(inout) :: <name>_dummy(*)',
+		:helperVars => "",
+		:precallStatements => "",
+		:callExpression => '<name>_dummy',
+		:passAs => 'integer(c_<type>), intent(inout) :: <name>_dummy(*)',
+		:postcallStatements => ""
+	}, {	#<floatTypes>* <name>_vec
+		:regex => '^\s*(?<type><floatTypes>)\s*\*\s*(?<name>\w+_vec)\s*$',
+		:placeholders => %w[name type],
+		:dummyName => '<name>_dummy',
+		:acceptAs => 'real(c_<type>), intent(inout) :: <name>_dummy(*)',
+		:helperVars => "",
+		:precallStatements => "",
+		:callExpression => '<name>_dummy',
+		:passAs => 'real(c_<type>), intent(inout) :: <name>_dummy(*)',
+		:postcallStatements => ""
+	}, {	#unsigned char <name>[<size>]
+		:regex => '^\s*unsigned\s+char\s+(?<name>\w+)\s*\[\s*(?<size>[^\]]+)\s*\]\s*$',
+		:placeholders => %w[name size],
+		:dummyName => '<name>_dummy',
+		:acceptAs => 'character(kind = c_char), intent(inout) :: <name>_dummy(<size>)',
+		:helperVars => "",
+		:precallStatements => "",
+		:callExpression => '<name>_dummy',
+		:passAs => 'character(kind = c_char), intent(inout) :: <name>_dummy(*)',
+		:postcallStatements => ""
+	}, {	#const <integerTypes>* <name>_vec
+		:regex => '^\s*const\s+(?<type><integerTypes>)\s*\*\s*(?<name>\w+_vec)\s*$',
+		:placeholders => %w[name type],
+		:dummyName => '<name>_dummy',
+		:acceptAs => 'integer(c_<type>), intent(in) :: <name>_dummy(*)',
+		:helperVars => "",
+		:precallStatements => "",
+		:callExpression => '<name>_dummy',
+		:passAs => 'integer(c_<type>), intent(in) :: <name>_dummy(*)',
+		:postcallStatements => ""
+	}, {	#const <floatTypes>* <name>_vec
+		:regex => '^\s*const\s+(?<type><floatTypes>)\s*\*\s*(?<name>\w+_vec)\s*$',
+		:placeholders => %w[name type],
+		:dummyName => '<name>_dummy',
+		:acceptAs => 'real(c_<type>), intent(in) :: <name>_dummy(*)',
+		:helperVars => "",
+		:precallStatements => "",
+		:callExpression => '<name>_dummy',
+		:passAs => 'real(c_<type>), intent(in) :: <name>_dummy(*)',
+		:postcallStatements => ""
+	}, {	#const unsigned char <name>[<size>]
+		:regex => '^\s*(const\s+unsigned\s+char|unsigned\s+char\s+const)\s+(?<name>\w+)\s*\[\s*(?<size>[^\]]+)\s*\]\s*$',
+		:placeholders => %w[name size],
+		:dummyName => '<name>_dummy',
+		:acceptAs => 'character(kind = c_char), intent(in) :: <name>_dummy(<size>)',
+		:helperVars => "",
+		:precallStatements => "",
+		:callExpression => '<name>_dummy',
+		:passAs => 'character(kind = c_char), intent(in) :: <name>_dummy(*)',
+		:postcallStatements => ""
+	}, {	#const <integerTypes> <name>[<lineCount>][<lineSize>]
+		:regex => '^\s*const\s+(?<type><integerTypes>)\s+(?<name>\w+)\s*\[\s*(?<lineCount>[^\]]+)\s*\]\s*\[\s*(?<lineSize>[^\]]+)\s*\]\s*$',
+		:placeholders => %w[name type lineCount lineSize],
+		:dummyName => '<name>_dummy',
+		:acceptAs => 'integer(c_<type>), intent(in) :: <name>_dummy(<lineSize>, <lineCount>)',
+		:helperVars => "",
+		:precallStatements => "",
+		:callExpression => '<name>_dummy',
+		:passAs => 'integer(c_<type>), intent(in) :: <name>_dummy(*)',
+		:postcallStatements => ""
+	},
+	#Pointer arguments. These match both pointers and arrays, so they must appear after the more special array templates.
+	#Most of these are wrapped by optional arguments which have to be named in calling code, which is why we don't use the _dummy suffix for them.
+	{	#<integerTypes>*
+		:regex => '^\s*(?<type><integerTypes>)\s*\*\s*(?<name>\w+)\s*$',
+		:placeholders => %w[name type],
+		:dummyName => '<name>',
+		:acceptAs => 'integer(c_<type>), optional, intent(inout) :: <name>',
+		:helperVars => "integer(c_<type>), target :: <name>_temp\ntype(c_ptr) :: <name>_ptr",
+		:precallStatements => "<name>_ptr = c_null_ptr\nif(present(<name>)) <name>_ptr = c_loc(<name>_temp)",
+		:callExpression => '<name>_ptr',
+		:passAs => 'type(c_ptr), value :: <name>',
+		:postcallStatements => "if(present(<name>)) <name> = <name>_temp"
+	}, {	#<floatTypes>*
+		:regex => '^\s*(?<type><floatTypes>)\s*\*\s*(?<name>\w+)\s*$',
+		:placeholders => %w[name type],
+		:dummyName => '<name>',
+		:acceptAs => 'real(c_<type>), optional, intent(inout) :: <name>',
+		:helperVars => "real(c_<type>), target :: <name>_temp\ntype(c_ptr) :: <name>_ptr",
+		:precallStatements => "<name>_ptr = c_null_ptr\nif(present(<name>)) <name>_ptr = c_loc(<name>_temp)",
+		:callExpression => '<name>_ptr',
+		:passAs => 'type(c_ptr), value :: <name>',
+		:postcallStatements => "if(present(<name>)) <name> = <name>_temp"
+	}, {	#unsigned char (*<name>)[<size>]
+		:regex => '^\s*unsigned\s+char\s*\(\s*\*\s*(?<name>\w+)\s*\)\s*\[\s*(?<size>[^\]]+)\s*\]\s*$',
+		:placeholders => %w[name size],
+		:dummyName => '<name>',
+		:acceptAs => 'character(kind = c_char), optional, intent(inout) :: <name>(<size>)',
+		:helperVars => "character(kind = c_char), target :: <name>_temp(<size>)\ntype(c_ptr) :: <name>_ptr",
+		:precallStatements => "<name>_ptr = c_null_ptr\nif(present(<name>)) <name>_ptr = c_loc(<name>_temp)",
+		:callExpression => '<name>_ptr',
+		:passAs => 'type(c_ptr), value :: <name>',
+		:postcallStatements => "if(present(<name>)) <name> = <name>_temp"
+	},
+	#String arguments.
+	{	#char*	Unsafe buffer passing
+		:regex => '^\s*char\s*\*\s*(?<name>\w+)\s*$',
+		:placeholders => %w[name],
+		:dummyName => '<name>_dummy',
+		:acceptAs => 'character(kind = c_char, len = *), intent(inout) :: <name>_dummy',
+		:helperVars => "character(kind = c_char) :: <name>_temp(len(<name>_dummy))\n" +
+		               "integer :: <name>_i\n" +
+		               "logical :: <name>_padding = .true.",
+		:precallStatements => "do <name>_i = len(<name>_dummy), 1, -1\n" +
+		                      "\tif(<name>_dummy(<name>_i:<name>_i) /= ' ') <name>_padding = .false.\n" +
+		                      "\tif(<name>_padding) then\n" +
+		                      "\t\t<name>_temp(<name>_i) = c_null_char\n" +
+		                      "\telse\n" +
+		                      "\t\t<name>_temp(<name>_i) = <name>_dummy(<name>_i:<name>_i)\n" +
+		                      "\tend if\n" +
+		                      "end do",
+		:callExpression => '<name>_temp',
+		:passAs => 'character(kind = c_char) :: <name>_dummy(*)',
+		:postcallStatements => "<name>_padding = .false.\n" +
+		                       "do <name>_i = 1, len(<name>_dummy)\n" +
+		                       "\tif(<name>_temp(<name>_i) == c_null_char) <name>_padding = .true.\n" +
+		                       "\tif(<name>_padding) then\n" +
+		                       "\t\t<name>_dummy(<name>_i:<name>_i) = ' '\n" +
+		                       "\telse\n" +
+		                       "\t\t<name>_dummy(<name>_i:<name>_i) = <name>_temp(<name>_i)\n" +
+		                       "\tend if\n" +
+		                       "end do"
+	}, {	#const char*	Safe passing of an input string.
+		:regex => '^\s*(const\s+char|char\sconst)\s*\*\s*(?<name>\w+)\s*$',
+		:placeholders => %w[name],
+		:dummyName => '<name>_dummy',
+		:acceptAs => 'character(kind = c_char, len = *), intent(in) :: <name>_dummy',
+		:helperVars => "character(kind = c_char) :: <name>_temp(len(<name>_dummy) + 1)\ninteger :: <name>_i",
+		:precallStatements => "do <name>_i = 1, len(<name>_dummy)\n<name>_temp(<name>_i) = <name>_dummy(<name>_i:<name>_i)\nend do\n<name>_temp(len(<name>_dummy) + 1) = c_null_char",
+		:callExpression => '<name>_temp',
+		:passAs => 'character(kind = c_char) :: <name>_dummy(*)',
+		:postcallStatements => ''
+	}, {	#char**	Safe returning of an output string.
+		:regex => '^\s*char\s*\*\s*\*\s*(?<name>\w+)\s*$',
+		:placeholders => %w[name],
+		:dummyName => '<name>',
+		:acceptAs => 'character(kind = c_char), pointer, optional, intent(inout) :: <name>(:)',
+		:helperVars => "type(c_ptr), target :: <name>_ptr\n" +
+		               "type(c_ptr) :: <name>_handle\n" +
+		               "integer :: <name>_shape(1)\n" +
+		               "character(kind = c_char), pointer :: <name>_fptr(:)",
+		:precallStatements => "<name>_handle = c_null_ptr\n" +
+		                      "if(present(<name>)) <name>_handle = c_loc(<name>_ptr)",
+		:callExpression => '<name>_handle',
+		:passAs => 'type(c_ptr), value :: <name>',
+		:postcallStatements => "if(present(<name>)) then\n" +
+		                       "\tif(c_associated(<name>_ptr)) then\n" +
+		                       "\t\t<name>_shape(1) = int(lib_strlen(<name>_ptr))\n" +
+		                       "\t\tcall c_f_pointer(<name>_ptr, <name>_fptr, <name>_shape)\n" +
+		                       "\t\tallocate(<name>(<name>_shape(1)))\n" +
+		                       "\t\t<name> = <name>_fptr\n" +
+		                       "\t\tcall lib_free(<name>_ptr)\n" +
+		                       "\telse\n" +
+		                       "\t\t<name> => null()\n" +
+		                       "\tend if\n" +
+		                       "end if"
+	},
+	#Public and opaque types
+	{	#[const] <opaqueTypes>*
+		:regex => '^\s*(const\s+|)(?<type><opaqueTypes>)(\s+const|)\s*\*\s*(?<name>\w+)\s*$',
+		:placeholders => %w[name type],
+		:dummyName => '<name>_dummy',
+		:acceptAs => 'type(t_<type>), intent(in) :: <name>_dummy',
+		:helperVars => '',
+		:precallStatements => '',
+		:callExpression => '<name>_dummy%ptr',
+		:passAs => 'type(c_ptr), value :: <name>_dummy',
+		:postcallStatements => ''
+	}
+]
+
+$returnTypeTemplates = [
+	{	#void
+		:regex => '^\s*void\s*$',
+		:placeholders => %w[],
+		:isVoid => true
+	}, {	#<integerTypes>
+		:regex => '^\s*(?<type><integerTypes>)\s*$',
+		:placeholders => %w[type],
+		:isVoid => false,
+		:returnAs => 'integer(c_<type>)',
+		:helperVars => '',
+		:precallStatements => '',
+		:recieveAs => 'integer(c_<type>)',
+		:assignVariable => 'result',
+		:postcallStatements => ''
+	}, {	#<floatTypes>
+		:regex => '^\s*(?<type><floatTypes>)\s*$',
+		:placeholders => %w[type],
+		:isVoid => false,
+		:returnAs => 'real(c_<type>)',
+		:helperVars => '',
+		:precallStatements => '',
+		:recieveAs => 'real(c_<type>)',
+		:assignVariable => 'result',
+		:postcallStatements => ''
+	}, {	#char*
+		:regex => '^\s*char\s*\*\s*$',
+		:placeholders => %w[],
+		:isVoid => false,
+		:returnAs => 'character(kind = c_char), dimension(:), pointer',
+		:helperVars => "type(c_ptr) :: cString\n" +
+		               "integer :: shape(1)\n" +
+		               "character(kind = c_char), dimension(:), pointer :: temp",
+		:precallStatements => '',
+		:recieveAs => 'type(c_ptr)',
+		:assignVariable => 'cString',
+		:postcallStatements => "if(c_associated(cString)) then\n" +
+		                       "\tshape(1) = int(lib_strlen(cString))\n" +
+		                       "\tcall c_f_pointer(cString, temp, shape)\n" +
+		                       "\tallocate(result(shape(1)))\n" +
+		                       "\tresult = temp\n" +
+		                       "\tcall lib_free(cString)\n" +
+		                       "else\n" +
+		                       "\tresult => null()\n" +
+		                       "end if"
+	}, {	#const char*
+		:regex => '^\s*const\s+char\s*\*\s*$',
+		:placeholders => %w[],
+		:isVoid => false,
+		:returnAs => 'character(kind = c_char), dimension(:), pointer',
+		:helperVars => "type(c_ptr) :: ptr\ninteger :: shape(1)",
+		:precallStatements => 'result => null()',
+		:recieveAs => 'type(c_ptr)',
+		:assignVariable => 'ptr',
+		:postcallStatements => "if(c_associated(ptr)) then\n" +
+		                       "\tshape(1) = int(lib_strlen(ptr))\n" +
+		                       "\tcall c_f_pointer(ptr, result, shape)\n" +
+		                       "end if"
+	}, {	#const int*	This returns the naked pointer because we can't know the length of the returned array within the wrapper. The user has to call c_f_pointer() himself.
+		:regex => '^\s*const\s+(?<type><integerTypes>)\s*\*\s*$',
+		:placeholders => %w[type],
+		:isVoid => false,
+		:returnAs => 'type(c_ptr)',
+		:helperVars => '',
+		:precallStatements => '',
+		:recieveAs => 'type(c_ptr)',
+		:assignVariable => 'result',
+		:postcallStatements => ''
+	}, {	#const double*	This returns the naked pointer because we can't know the length of the returned array within the wrapper. The user has to call c_f_pointer() himself.
+		:regex => '^\s*const\s+(?<type><floatTypes>)\s*\*\s*$',
+		:placeholders => %w[type],
+		:isVoid => false,
+		:returnAs => 'type(c_ptr)',
+		:helperVars => '',
+		:precallStatements => '',
+		:recieveAs => 'type(c_ptr)',
+		:assignVariable => 'result',
+		:postcallStatements => ''
+	},
+	#Public and opaque types.
+	{	#<publicTypes>
+		:regex => '^\s*(?<type><publicTypes>)\s+$',
+		:placeholders => %w[type],
+		:isVoid => false,
+		:returnAs => 'type(t_<type>)',
+		:helperVars => '',
+		:precallStatements => '',
+		:recieveAs => 'type(t_<type>)',
+		:assignVariable => 'result',
+		:postcallStatements => ''
+	}, {	#<opaqueTypes>*
+		:regex => '^\s*(?<type><opaqueTypes>)\s*\*\s*$',
+		:placeholders => %w[type],
+		:isVoid => false,
+		:returnAs => 'type(t_<type>)',
+		:helperVars => '',
+		:precallStatements => '',
+		:recieveAs => 'type(c_ptr)',
+		:assignVariable => 'result%ptr',
+		:postcallStatements => ''
+	}
+]
+
+$typeTemplates = [
+	{	#<integerTypes>
+		:regex => '^\s*(?<type><integerTypes>)\s+(?<name>\w+)\s*;$',
+		:placeholders => %w[name type],
+		:declareAs => "integer(c_<type>) :: <name>"
+	}, {	#<floatTypes>
+		:regex => '^\s*(?<type><floatTypes>)\s+(?<name>\w+)\s*;$',
+		:placeholders => %w[name type],
+		:declareAs => "real(c_<type>) :: <name>"
+	}
+]
+
+####################################################################################################
+# Verbatim Fortran Code ############################################################################
+####################################################################################################
+
+$verbatimDeclarations = '
+	public ctrim
+	public c_len
+
+	interface
+		integer(c_size_t) function lib_strlen(charPtr) bind(c, name = "strlen")
+			import c_size_t, c_ptr
+			type(c_ptr), value :: charPtr
+		end function lib_strlen
+
+		subroutine lib_free(pointer) bind(c, name = "free")
+			import c_ptr
+			type(c_ptr), value :: pointer
+		end subroutine lib_free
+	end interface
+'
+
+$verbatimDefinitions = "
+	subroutine ctrim(str)
+		character(kind = c_char, len = *), intent(inout) :: str
+		integer :: i
+
+		do i=1,len(str)
+			if (str(i:i) == c_null_char) then
+				str(i:len(str)) = ' '
+				exit
+			end if
+		end do
+	end subroutine ctrim
+
+	function c_len(s) result(i)
+		character(kind = c_char, len = *), intent(in) :: s
+		integer :: i
+
+		do i = 1, len(s)
+			if (s(i:i) == c_null_char) exit
+		end do
+		i = i - 1
+	end function
+"
+
+####################################################################################################
+# Code to interpret the templates ##################################################################
+####################################################################################################
+
+$declarationLines = []
+$definitionLines = []
+$opaqueTypes = []
+$publicTypes = []
+
+#This substitutes the placeholders <opaqueTypes> and <publicTypes> in the regexString prior to constructing a Regexp out of it.
+def matchTemplate(regexString, matchString)
+	opaqueTypesString = "(#{ $opaqueTypes.collect{ |type| type }.join('|') })"
+	regexString = regexString.gsub("<opaqueTypes>", opaqueTypesString)
+	publicTypesString = "(#{ $publicTypes.collect{ |type| type }.join('|') })"
+	regexString = regexString.gsub("<publicTypes>", publicTypesString)
+	regexString = regexString.gsub("<integerTypes>", '(short|int|long|size_t|intmax_t|int_(least|fast)(8|16|32|64)_t)')
+	regexString = regexString.gsub("<floatTypes>",  '(float|double)')
+	return Regexp.new(regexString).match(matchString)
 end
 
-# create continuation for lines longer that 132 sign, which would create an
-# error with some fortran compilers
-def genContinuation(iline)
-  # leave the input untouched
-  line = iline
-  # try to create readable line breaks, i.e. do not split name, labels or keywords
-  regexp = /,[^,]*$/
-
-  matchIndex = line[0,FortranMaxLineLength] =~ regexp
-
-  if matchIndex.nil?
-    line[FortranMaxLineLength-2] = "&\n"+line[FortranMaxLineLength-2,1]+"&"
-  else
-    line[matchIndex] = ",&\n" + ' '*7
-  end
-  line
+class TemplateInstanciation
+	def initialize(argumentString, template)
+		@template = template
+		@matchData = matchTemplate(template[:regex], argumentString)
+		@placeholders = []
+		template[:placeholders].each { |placeholder|
+			@placeholders.push({ :name => placeholder, :regex => Regexp.new("<#{placeholder}>") })
+		}
+	end
+
+	def expandTemplate(templateKey)
+		result = @template[templateKey]
+		#Replace all placeholders with their expansion.
+		@placeholders.each { |current|
+			result = result.gsub(current[:regex], @matchData[current[:name]])
+		}
+		return result
+	end
 end
 
-
-# create fortran module variables
-def genModParams(vars)
-  vars.collect {|var, value|
-    "      integer, parameter :: #{var} = #{value}"
-  }.join("\n")
+def formatLines(lineArray, indentation, string)
+	if string == "" && indentation == 0
+		lineArray.push("")	#split() does not return anything if the string is empty, killing our empty lines
+	end
+	string.split("\n").each { |line|
+		lineArray.push("\t"*indentation + line)
+	}
 end
 
-# return the fortran version of the c parameters (name, named constant within
-# iso-c-bindig, fortran type)
-def fortranParamsWithTypes(paramList)
-  paramList.collect {|paramInfo|
-    ctype, param = paramInfo[-2,2]
-    ftype, nc    = CFTypeInfo[ctype][:ftype], CFTypeInfo[ctype][:namedConst]
-    # fortran parameters can be configured out of the c parameters
-    [param.send(FNameMethod),nc,ftype, paramInfo.include?('const')]
-  }
+def dumpStatements(indentation, argumentArray, templateKey)
+	argumentArray.each{ |argument|
+		formatLines($definitionLines, indentation, argument.expandTemplate(templateKey))
+	}
 end
-def startMod(name)
-  "
-module #{name}
-      use, intrinsic :: iso_c_binding
-
-      implicit none
 
-      private
-  "
+def defineConstant(name, value)
+	if /^(\+|-|)\d+$/.match(value)
+		formatLines($declarationLines, 1, "integer(c_int), public, parameter :: #{name} = #{value}")
+	else
+		puts("Error: value '#{value}' of constant '#{name}' is not an integer literal")
+	end
 end
-def endMod(name)
-  "\nend module #{name}\n"
-end
-def isBadFunction(returnType, returnPointer, paramList)
-  return true if (
-    # external return type
-    (returnType != 'void' and not CFTypeInfo.keys.include?(returnType)) or
-    # pointer2pointer return type
-    returnPointer.length > 1
-  )
-  paramList.each {|paramInfo|
-    next if paramInfo == ['void']
-    next if paramInfo[0] == 'void' and /^\*\w+$/.match(paramInfo[1])
-    ctype, param = paramInfo[-2,2]
-    # TJ: unnamed arguments shouldn't be matched at all but because
-    # pointer * is parsed as part of the name those need to be rejected here
-    return true if (
-      CFTypeInfo[ctype].nil? or                        # derived data type
-      param == '*' or                                  # unnamed pointer
-      param[0,2] == '**' or                            # pointer2pointer
-      (param[0,1] == '*' and /\w\[\w*\]/.match(param)) # array of pointers
-    )
-  }
-  return false
+
+def defineOpaqueType(name)
+	formatLines($declarationLines, 0, "")
+	formatLines($declarationLines, 1, "public t_#{name}")
+	formatLines($declarationLines, 1, "type t_#{name}")
+	formatLines($declarationLines, 2, "type(c_ptr) :: ptr")
+	formatLines($declarationLines, 1, "end type t_#{name}")
+	$opaqueTypes.push(name)
 end
 
-def hasDimension(paramName, paramFType)
-  return true if paramFType == 'character'
-  return true if ( %w[integer real].include?(paramFType) and Vectors.match(paramName) )
-  return false
+def findTemplate(string, templateArray)
+	templateArray.each do |template|
+		if matchTemplate(template[:regex], string)
+			return template
+		end
+	end
+	return nil
 end
 
-# collect further information about the original c type of the params and
-# in case of a match between param name and function name, the parameter name
-# is changed
-def setFortranParams(paramswithtypes,fFuncname)
-  # special treatment of empty parameter list
-  return [[],[]] if paramswithtypes == [[]]
-
-  originalParameters = paramswithtypes.transpose[0]
-  paramswithtypes.collect {|param, paramCType, fType, isConstant|
-    # test for pointers/arrays
-    isPointer, isArray, arraySize = false, false, nil
-    if param[0,1] == '*'
-      isPointer = true
-      # remove '*' from funcnames and paramnames
-      param.sub!('*','')
-    end
-    if ( md = /\w\[(\w*)\]/.match(param); not md.nil? )
-      isArray   = true
-      arraySize = md[1] == '' ? '*' : md[1]
-      param[md.begin(1)-1,md.end(1)-1] = ''
-    end
-
-    # change param name if it equals the funcname
-    if param == fFuncname or param.downcase == fFuncname.downcase
-      param += FParamExtension
-      # but maybe the result is the name of another parameter. -> play it again sam...
-      param += FParamExtension while ( originalParameters.include?(param) )
-    end
-    if param[0,1] == '_'
-      param = 'p' + param
-    end
-
-    [param,paramCType,fType,isPointer,isArray,arraySize,isConstant]
-  }
+def definePublicType(name, body)
+	formatLines($declarationLines, 0, "")
+	formatLines($declarationLines, 1, "public t_#{name}")
+	formatLines($declarationLines, 1, "type, bind(c) :: t_#{name}")
+	body.gsub(/[^;]+;/) do |variableDeclaration|
+		if template = findTemplate(variableDeclaration, $typeTemplates)
+			variable = TemplateInstanciation.new(variableDeclaration, template)
+			formatLines($declarationLines, 2, "#{variable.expandTemplate(:declareAs)}")
+		else
+			puts("Error: Can't translate the declaration '#{variableDeclaration}'")
+		end
+	end
+	formatLines($declarationLines, 1, "end type t_#{name}")
+	$publicTypes.push(name)
 end
 
-def printParams(fParams, indent)
-  out = ''
-  fParams.each {|param,paramType,ftype,ispointer,isarray,arraysize,isconstant|
-    dimension     = isarray ? "dimension(#{arraysize})" : ( (ispointer and hasDimension(param, ftype) ) ? 'dimension(*)' : nil)
-    intent, value = nil, nil
-    if (ispointer or isarray)
-      if not isconstant
-        intent = 'intent(out)'
-      else
-        intent = 'intent(in)'
-      end unless paramType == 'c_char'
-    else
-      #intent = 'intent(in)'
-      value  = 'value'
-    end
-
-    typeinfo = [value,intent,dimension].select {|s| ! s.nil?}.join(', ')
-    out << "  #{indent}#{ftype}"
-    out << (paramType == 'c_ptr' ? '' : "(kind=#{paramType})")
-    out << ", #{typeinfo} :: #{param}\n"
-  }
-  return out
+def collectImportConstants(importConstantsArray, typeString)
+	if importConstant = typeString[/\b[ct]_\w+\b/]
+		importConstantsArray.push(importConstant)
+	end
 end
 
-# creates the actual binding within the module for the given c function
-# unsupported types of function a ignored, see RESTRICTIONS (top) for details
-def genInterface(cFuncname, returnType, returnPointer, paramList, debug)
-
-  # do not create interfaces for unsupported functions
-  if isBadFunction( returnType, returnPointer, paramList)
-    warn "parameterlist of '#{cFuncname}' is not supported -> function ignored."
-    return ['','']
-  end
-  return ['', ''] if (cFuncname[0,1] == '_')
-  # the void argument type can be left out: if 'void' occurs in the
-  # parameterlist (which is only the case, if it is the only parameter
-  # information), it is simply removed and a empty paramter list is left.
-  paramList = [[],[]] if paramList.flatten == [ 'void' ] or paramList.flatten.empty?
-
-  out = ''
-  isWrapper = false
-
-  # create new names for the fortran routines, see CONFIGURATION (top)
-  fFuncname = cFuncname.send(FNameMethod)
-
-  paramsWithTypes = []
-  # divide between empty and non empty parameter lists
-  if paramList == [[],[]]
-    fParams, fParams4Import, fTypes4Import = [], [],[]
-  else
-    # collect information for setting the correct fortran type for each parameter
-    paramsWithTypes = paramList.collect {|paramInfo|
-      ctype, param = paramInfo[-2,2]
-      integral_type = /^(:?char|int|long|short)$/.match(ctype);
-      if (integral_type)
-        while (/^(:?un)?signed/.match(paramInfo[-3]))
-          ctype = paramInfo[-3] << ' ' << ctype
-          paramInfo.delete_at(-3)
-          paramInfo[-2] = ctype
-          pp [paramInfo] if debug
-        end
-      end
-      ptr_match = /^\*(\w+)$/.match(param)
-      if (/^(:?const)? *void$/.match(ctype) and ptr_match)
-        param = ptr_match[1]
-        ftype = 'type(c_ptr)'
-        nc = 'c_ptr'
-      else
-        ftype, nc    = CFTypeInfo[ctype][:ftype], CFTypeInfo[ctype][:namedConst]
-      end
-      # fortran parameters can be configured out of the c parameters
-      [param.send(FNameMethod),nc,ftype, paramInfo.include?('const')]
-    }
-
-    # get deeper information about parameterlists and filter out functions with
-    # non supported parameters
-    fParams = setFortranParams(paramsWithTypes,fFuncname)
-    fParams4Import, fTypes4Import, = fParams.transpose
-  end
-
-  fReturnInfo                    = CFTypeInfo[returnType]
-  indent = '      '
-  if not fReturnInfo.nil?
-    fReturnString = "function"
-    fEnd    = ["#{fReturnInfo[:ftype]}(kind=#{fReturnInfo[:namedConst]}) :: #{fFuncname}\n", "end function" ]
-    fTypes4Import << fReturnInfo[:namedConst]
-  elsif returnType == 'void'
-    fReturnString = "subroutine"
-    fEnd    = ["end subroutine"]
-  end
-  fFuncname_suffix = ''
-
-  if (returnType == 'char' and returnPointer == '*')
-    out << "#{indent}function #{fFuncname}(#{fParams4Import.join(',')})\n"
-    out << printParams(fParams, indent)
-    fTypes4Import.unshift('c_ptr') unless fTypes4Import.include?('c_ptr')
-    isWrapper = true
-    fwEnd = [ "end function" ]
-    fFuncname_suffix = '_c'
-    indent = '        '
-    fEnd = [ "type(c_ptr) :: #{fFuncname}#{fFuncname_suffix}\n",
-             "end function" ]
-  end
-  out << "#{indent}interface
-#{indent}  #{fReturnString} #{fFuncname}#{fFuncname_suffix}(#{fParams4Import.join(',')}) bind(c,name='#{cFuncname}')\n"
-  out << "#{indent}    import :: #{fTypes4Import.uniq.join(',')}\n" unless fTypes4Import.empty?
-
-  out << printParams(fParams, indent + '  ')
-
-  fEnd.each_with_index do |line, i|
-    extra_indent = '    '
-    if i == fEnd.length - 1
-      extra_indent = '  '
-    end
-    out << indent + extra_indent + line
-  end
-  out << " #{fFuncname}#{fFuncname_suffix}\n#{indent}end interface\n"
-  if (returnType == 'char' and returnPointer == '*')
-    indent = '      '
-    out << "#{indent}  character(len=1, kind=c_char), pointer :: #{fFuncname}(:)
-#{indent}  type(c_ptr) :: cptr
-#{indent}  integer :: slen(1)
-
-#{indent}  cptr = #{fFuncname}#{fFuncname_suffix}("
-    out << fParams4Import.join(",&
-#{indent}    ") << ")\n"
-    out << "#{indent}  #{fFuncname} => null()\n"
-    out << "#{indent}  slen(1) = int(strlen(cptr))\n"
-    out << "#{indent}  call c_f_pointer(cptr, #{fFuncname}, slen)\n"
-    fwEnd.each_with_index do |line,i|
-      extra_indent = '  '
-      if i == fwEnd.length - 1
-        extra_indent = ''
-      end
-      out << indent + extra_indent + line
-    end
-    out << " #{fFuncname}\n"
-  end
-  [out, makePublic(fFuncname), isWrapper]
+#Collect the c_* and t_* constants/types from the arguments and the return type and build the corresponding `import` statement from them.
+def importStatement(returnType, argumentArray)
+	importConstants = []
+	collectImportConstants(importConstants, returnType)
+	argumentArray.each { |arg|
+		collectImportConstants(importConstants, arg.expandTemplate(:passAs))
+	}
+	return (importConstants.length != 0) ? "import #{importConstants.sort.uniq.join(", ")}" : ""
 end
-def makePublic(*fFuncnameList)
-  fFuncnameList.collect {|fname| 
-    "      public :: #{fname.tr('*','')}"
-  }.join("\n") << "\n"
+
+def defineFunction(name, arguments, returnType)
+	#Find the relevant templates.
+	if returnTemplate = findTemplate(returnType, $returnTypeTemplates)
+		returnData = TemplateInstanciation.new(returnType, returnTemplate)
+		argArray = []
+		arguments.gsub(/[^,]+/) do |argument|
+			if template = findTemplate(argument, $argumentTemplates)
+				argArray.push(TemplateInstanciation.new(argument, template))
+			else
+				puts("Error: type of argument '#{argument}' to function #{name}() is not supported")
+				return
+			end
+		end
+	else
+		puts("Error: Can't translate return type '#{returnType}' of function #{name}()")
+		return
+	end
+
+	#Generate the wrapper function.
+	dummyArguments = argArray.collect{ |arg|
+		arg.expandTemplate(:dummyName)
+	}.join(", ")
+	if returnTemplate[:isVoid]
+		formatLines($definitionLines, 1, "subroutine #{name}(#{dummyArguments})")
+		dumpStatements(               2, argArray, :acceptAs)
+		dumpStatements(               2, argArray, :helperVars)
+		formatLines($definitionLines, 2, "interface")
+		formatLines($definitionLines, 3, "subroutine lib_#{name}(#{dummyArguments}) bind(c, name = '#{name}')")
+		formatLines($definitionLines, 4, "#{importStatement("", argArray)}")
+		dumpStatements(               4, argArray, :passAs)
+		formatLines($definitionLines, 3, "end subroutine lib_#{name}")
+		formatLines($definitionLines, 2, "end interface")
+		dumpStatements(               2, argArray, :precallStatements)
+		formatLines($definitionLines, 2, "call lib_#{name}(#{argArray.collect{ |arg|
+			arg.expandTemplate(:callExpression)
+		}.join(", ")})")
+		dumpStatements(               2, argArray, :postcallStatements)
+		formatLines($definitionLines, 1, "end subroutine #{name}")
+	else
+		formatLines($definitionLines, 1, "function #{name}(#{dummyArguments}) result(result)")
+		formatLines($definitionLines, 2, "#{returnData.expandTemplate(:returnAs)} :: result")
+		dumpStatements(               2, argArray, :acceptAs)
+		dumpStatements(               2, argArray, :helperVars)
+		formatLines($definitionLines, 2, "#{returnData.expandTemplate(:helperVars)}")
+		formatLines($definitionLines, 2, "interface")
+		formatLines($definitionLines, 3, "#{returnData.expandTemplate(:recieveAs)} function lib_#{name}(#{dummyArguments}) bind(c, name = '#{name}')")
+		formatLines($definitionLines, 4, "#{importStatement(returnData.expandTemplate(:recieveAs), argArray)}")
+		dumpStatements(               4, argArray, :passAs)
+		formatLines($definitionLines, 3, "end function lib_#{name}")
+		formatLines($definitionLines, 2, "end interface")
+		dumpStatements(               2, argArray, :precallStatements)
+		formatLines($definitionLines, 2, "#{returnData.expandTemplate(:precallStatements)}")
+		formatLines($definitionLines, 2, "#{returnData.expandTemplate(:assignVariable)} = lib_#{name}(#{argArray.collect{ |arg|
+			arg.expandTemplate(:callExpression)
+		}.join(", ")})")
+		dumpStatements(               2, argArray, :postcallStatements)
+		formatLines($definitionLines, 2, "#{returnData.expandTemplate(:postcallStatements)}")
+		formatLines($definitionLines, 1, "end function #{name}")
+	end
+	formatLines($definitionLines, 0, "")
+	formatLines($declarationLines, 1, "public #{name}")
+
 end
-def ctrim
-  "
-    subroutine ctrim(str)
-    character(kind=c_char), intent(inout) :: str(:)
-    character(kind=c_char) :: c
-    integer :: i
-
-    do i=1,size(str)
-      c = str(i)
-      if (c == c_null_char) then
-        str(i:size(str)) = ' '
-        exit
-      end if
-    end do
-
-    end subroutine ctrim\n"
+
+#Scan the given header and collect the interface information in the global variables.
+def scanHeader(headerPath)
+	#Scan the given header.
+	headerLines = IO.popen("cpp -fpreprocessed -dD #{headerPath}").readlines	#The options cause the preprocessor to strip all comments, but retain all #defines, and ignore #includes.
+	headerLines.each do |line|
+		line.chomp!
+
+		if /^\s*$/.match(line)
+			#Empty lines are ignored.
+
+		#Preprocessor stuff
+		elsif matchedLine = /^\s*#\s*define\s+(?<symbol>\w+)\s+(?<value>.+)$/.match(line)
+			defineConstant(matchedLine['symbol'], matchedLine['value'])
+		elsif /^\s*#/.match(line)
+			#All other preprocessor directives are ignored.
+
+		#User defined types
+		elsif matchedLine = /^\s*typedef\s+struct\s+(?<typeName>\w+)\s+\k<typeName>\s*;\s*$/.match(line)
+			defineOpaqueType(matchedLine['typeName'])
+		elsif matchedLine = /^\s*typedef\s+struct\s+(?<typeName>\w+)\s*{(?<body>.*)}\s*\k<typeName>\s*;\s*$/.match(line)
+			definePublicType(matchedLine['typeName'], matchedLine['body'])
+
+		#Function declarations
+		elsif matchedLine = /^\s*(?<returnType>[^()]+)\b(?<functionName>\w+)\s*\((?<arguments>.*)\)\s*;\s*$/.match(line)
+			defineFunction(matchedLine['functionName'], matchedLine['arguments'], matchedLine['returnType'])
+
+		else
+			puts("Warning: Unrecognized line '#{line}'")
+		end
+	end
 end
 
-def clen
-  "
-    function c_len(s) result(i)
-      character(kind=c_char), intent(in) :: s(:)
-      integer :: i
-      do i = 1, size(s)
-        if (s(i) == c_null_char) then
-          exit
-        end if
-      end do
-      i = i - 1
-    end function\n"
+#Prints the line if it does not consist only of indentation, adding continuation lines as necessary.
+def fortranLine(file, line)
+	unless /^\t+$/.match(line)	#Intentionally empty lines don't contain indentation, so we preserve totally empty lines while throwing away the ones with leading tabs.
+		indentation = /^\t*/.match(line)[0]
+		while line.length > 131
+			file.puts(line[0...131] + "&")
+			line = indentation + "&" + line[131...line.length]
+		end
+		file.puts(line)
+	end
 end
 
-################################################################################
-if __FILE__ == $0
-require 'optparse'
-require 'pp'
-
-debug = false
-OptionParser.new do |opts|
-  opts.on("-d","--debug") {debug = true}
-  opts.on_tail("--help","-h","-H","Display this help message.") do
-    puts <<-'END'
-#== Synopsis
-# Create Fortran iso-c-bindings form a given c header file
-# 
-#== Usage
-#   binGen.rb <headerFile> <fortranLibraryFile> [<modName>] [--help|--debug]  
-#
-# headerFile:
-#   A general c header file: function prototypes and '#defines' with numerical
-#   value will be taken for the fortran module construction. Furthermore there
-#   are some restrictions to what is provided in fortran: Currently internal
-#   datatypes and (arrays|pointers) to internal datatypes are supported, i.e.
-#   no arrays of pointers, no pointer to pointers, no typedefs
-#
-# fortranLibraryFile:
-#   file name for generated bindings
-#
-# modName:
-#   This will be the name of the Fortran module, so it has to obey the fortran 
-#   restriction for module names. default: mo_cdi
-#  
-#== Author
-# Ralf Mueller, ralf.mueller@zmaw.de
-#
-#== RESTRICTIONS:
-# ONLY SUPPORT FOR INTERNAL DATATYPES AND (ARRAYS|POINTERS) TO INTERNAL
-# DATATYPES, I.E. NO ARRAYS OF POINTERS, NO POINTER TO POINTERS, NO TYPEDEFS
-#
-#=== Special: naming convention
-# Pointers can have different sizes, which cannot be detetermined by parsing a
-# function prototype. Therefor a convention according the parameter names can
-# be used to take this decision precisely:
-# * Pointers to numbers are expected to be scalars unless the name of the
-#   parameter end with '_vec'
-# * Pointers to char are allways referenced as vectors
-#
-#== LICENSE: 
-# BSD License
-#
-#  Copyright (c) 2009-2012, Ralf Mueller (ralf.mueller@zmaw.de)
-#  All rights reserved.
-#  
-#  Redistribution and use in source and binary forms, with or without
-#  modification, are permitted provided that the following conditions are met:
-#  
-#      * Redistributions of source code must retain the above copyright notice,
-#        this list of conditions and the following disclaimer.
-#  
-#      * Redistributions in binary form must reproduce the above copyright
-#        notice, this list of conditions and the following disclaimer in the
-#        documentation and/or other materials provided with the distribution.
-#  
-#      * The names of its contributors may not be used to endorse or promote
-#        products derived from this software without specific prior written
-#        permission.
-#  
-#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-#  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-#  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-#  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-#  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-#  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-#  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-#  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-END
-  exit
-  end
-end.parse!
-
-  if ARGV[1] == nil
-    warn 'no outputile given'
-    exit
-  end
-
-  outputString      = ''
-  modname           = ARGV[2].nil? ? ModuleName : ARGV[2]
-
-  cDefines          = getDefines(ARGV[0])
-  pp cDefines if debug
-  unless cDefines.empty?
-    makeModVarsPublic = makePublic(*cDefines.transpose[0]) 
-    moduleVariables   = genModParams(cDefines)
-  end
-
-  interfaces, makepublics, subroutines = '', '', "contains\n"
-  indent = '    '
-
-  funcdecls = [ [ 'strlen', 'size_t', '', [ [ 'void', '*s' ] ] ] ]
-  funcdecls.concat(getFuncInfo(ARGV[0]))
-
-  funcdecls.each {| funcName, returnType, returnPointer, paramList|
-    pp [funcName, returnType, returnPointer, paramList] if debug
-    interface, makepublic, isWrapper = genInterface(funcName,returnType, returnPointer, paramList, debug)
-    if isWrapper
-      subroutines << interface
-    else
-      interfaces  << interface
-    end
-    makepublics << makepublic
-  }
-
-  # add a specialized trim for wierd c strings
-  makepublics << makePublic('ctrim') << makePublic('c_len')
-  subroutines << ctrim << clen
-
-  File.open(ARGV[1],"w") {|f|
-    [ startMod(modname),
-      moduleVariables ||= '',
-      interfaces,
-      makepublics,
-      makeModVarsPublic ||= '',
-      subroutines,
-      endMod(modname)
-    ].join("\n").split("\n").each {|line| 
-      # check the length of each line before writing to file
-      if line.length > FortranMaxLineLength
-        f << genContinuation(line) << "\n"
-      else
-        f << line << "\n"
-      end
-    }
-  }
+#Output the interface information in the global variables to a fortran file.
+def writeFortranModule(scriptPath, headerPath, modulePath, moduleName)
+	file = File.new(modulePath, "w")
+	fortranLine(file, "! >>> Warning: This is a generated file. If you modify it, you get what you deserve. <<<")
+	fortranLine(file, "!")
+	fortranLine(file, "! Generated by \"#{scriptPath}\" from input file \"#{headerPath}\".")
+	fortranLine(file, "");
+
+	fortranLine(file, "module #{moduleName}")
+	fortranLine(file, "\tuse iso_c_binding")
+	fortranLine(file, "\timplicit none")
+	fortranLine(file, "\tprivate")
+
+	file.puts($verbatimDeclarations)
+	fortranLine(file, "")
+	$declarationLines.each do |line|
+		fortranLine(file, line)
+	end
+	fortranLine(file, "")
+
+	fortranLine(file, "contains")
+	file.puts($verbatimDefinitions)
+	fortranLine(file, "")
+	$definitionLines.each do |line|
+		fortranLine(file, line)
+	end
+
+	fortranLine(file, "end module #{moduleName}")
+end
 
+def main
+	printUsage = false
+	ARGV.each { |argument|
+		if argument == "-h" || argument == "--help"
+			printUsage = true
+		end
+	}
+	unless printUsage
+		case ARGV.length
+			when 0
+				puts("Error: no input file given")
+				printUsage = true
+			when 1
+				puts("Error: no output file given")
+				printUsage = true
+			when 2
+				moduleName = /(?<basename>[^.\/]+)\.[^\/]+/.match(ARGV[1])['basename']
+			when 3
+				moduleName = ARGV[2]
+			else
+				puts("Error: too many arguments")
+				printUsage = true
+		end
+	end
+	unless printUsage
+		headerPath = ARGV[0]
+		outputPath = ARGV[1]
+		scanHeader(headerPath)
+		writeFortranModule($0, headerPath, outputPath, moduleName)
+	else
+		puts("Usage:")
+		puts("#{$0} cHeader outputPath [ moduleName ]")
+		puts("#{$0} ( -h | --help )")
+		puts("")
+		puts("\tcHeader:    input C header file")
+		puts("\toutputPath: output fortran file name")
+		puts("\tmoduleName: name of the resulting fortran module, defaults to the basename of outputPath")
+	end
 end
+
+main()
diff --git a/src/Makefile.am b/src/Makefile.am
index b2465d8bc0f677ebc7676f1427e9dddb2a8d936d..12d0f2dd97a7dfd83c490fdc2b7a06907f4df25d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -51,18 +51,32 @@ libcdi_la_SOURCES = 	 \
 	gaussgrid.h	 \
 	gribapi.c  	 \
 	gribapi.h	 \
+	gribapi_utilities.c \
+	gribapi_utilities.h \
 	grid.c           \
 	grid.h	 	 \
 	ieg.h	 	 \
 	ieglib.c         \
+	input_file.c	\
+	input_file.h	\
 	institution.c  	 \
 	institution.h  	 \
+	iterator.c       \
+	iterator.h       \
+	iterator_fallback.c \
+	iterator_fallback.h \
+	iterator_grib.c \
+	iterator_grib.h  \
 	model.c        	 \
 	model.h        	 \
 	namespace.c      \
 	namespace.h      \
 	serialize.h	\
 	serialize.c	\
+	proprietarySystemWorkarounds.c \
+	proprietarySystemWorkarounds.h \
+	referenceCounting.c \
+	referenceCounting.h \
 	resource_handle.c\
 	resource_handle.h\
 	service.h	 \
diff --git a/src/Makefile.in b/src/Makefile.in
index dad9c3a9491f3aa0c93c7367d18f653b1fbd034c..89166ab2229734fe5cd9664004cea95cb00bcdb7 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -159,8 +159,11 @@ libcdi_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
 am_libcdi_la_OBJECTS = basetime.lo binary.lo calendar.lo cdf.lo \
 	cdf_int.lo cdi_error.lo cdi_util.lo cdiFortran.lo \
 	cgribexlib.lo dmemory.lo cksum.lo cdi_cksum.lo error.lo \
-	extralib.lo file.lo gaussgrid.lo gribapi.lo grid.lo ieglib.lo \
-	institution.lo model.lo namespace.lo serialize.lo \
+	extralib.lo file.lo gaussgrid.lo gribapi.lo \
+	gribapi_utilities.lo grid.lo ieglib.lo input_file.lo \
+	institution.lo iterator.lo iterator_fallback.lo \
+	iterator_grib.lo model.lo namespace.lo serialize.lo \
+	proprietarySystemWorkarounds.lo referenceCounting.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 \
@@ -290,6 +293,7 @@ ENABLE_CGRIBEX = @ENABLE_CGRIBEX@
 ENABLE_EXTRA = @ENABLE_EXTRA@
 ENABLE_GRIB = @ENABLE_GRIB@
 ENABLE_IEG = @ENABLE_IEG@
+ENABLE_MPI = @ENABLE_MPI@
 ENABLE_NC2 = @ENABLE_NC2@
 ENABLE_NC4 = @ENABLE_NC4@
 ENABLE_NETCDF = @ENABLE_NETCDF@
@@ -494,18 +498,32 @@ libcdi_la_SOURCES = \
 	gaussgrid.h	 \
 	gribapi.c  	 \
 	gribapi.h	 \
+	gribapi_utilities.c \
+	gribapi_utilities.h \
 	grid.c           \
 	grid.h	 	 \
 	ieg.h	 	 \
 	ieglib.c         \
+	input_file.c	\
+	input_file.h	\
 	institution.c  	 \
 	institution.h  	 \
+	iterator.c       \
+	iterator.h       \
+	iterator_fallback.c \
+	iterator_fallback.h \
+	iterator_grib.c \
+	iterator_grib.h  \
 	model.c        	 \
 	model.h        	 \
 	namespace.c      \
 	namespace.h      \
 	serialize.h	\
 	serialize.c	\
+	proprietarySystemWorkarounds.c \
+	proprietarySystemWorkarounds.h \
+	referenceCounting.c \
+	referenceCounting.h \
 	resource_handle.c\
 	resource_handle.h\
 	service.h	 \
@@ -734,9 +752,14 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gaussgrid.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gribapi.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gribapi_utilities.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/grid.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ieglib.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/input_file.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/institution.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iterator.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iterator_fallback.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iterator_grib.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/model.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/namespace.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pio.Plo@am__quote@
@@ -754,6 +777,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pio_serialize.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pio_server.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pio_util.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proprietarySystemWorkarounds.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/referenceCounting.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/resource_handle.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/resource_unpack.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/serialize.Plo@am__quote@
diff --git a/src/cdf_int.h b/src/cdf_int.h
index 59ef92227750ae841ffd1979a9c37cb6a59f8c0e..759d447701eb781f88aee5e59484e8899af71820 100644
--- a/src/cdf_int.h
+++ b/src/cdf_int.h
@@ -4,7 +4,7 @@
 #if  defined  (HAVE_LIBNETCDF)
 
 #include <stdlib.h>
-#include "netcdf.h"
+#include <netcdf.h>
 
 void cdf_create (const char *path, int cmode, int *idp);
 int  cdf_open   (const char *path, int omode, int *idp);
diff --git a/src/cdi.h b/src/cdi.h
index 6a087d530b8c25e70074e9c578c2e7684998bd6b..8f6baa43fe67637b1c753e8a2a717a4a1b48b256 100644
--- a/src/cdi.h
+++ b/src/cdi.h
@@ -31,6 +31,7 @@ extern "C" {
 /* Error identifier */
 
 #define	 CDI_NOERR        	  0   /* No Error                             */
+#define  CDI_EEOF                -1   /* The end of file was encountered      */
 #define  CDI_ESYSTEM            -10   /* Operating system error               */
 #define  CDI_EINVAL             -20   /* Invalid argument                     */
 #define  CDI_EUFTYPE            -21   /* Unsupported file type                */
@@ -222,6 +223,17 @@ extern "C" {
 /* number of unsigned char needed to store UUID */
 #define  CDI_UUID_SIZE           16
 
+/* Structs that are used to return data to the user */
+
+typedef struct CdiParam { int discipline; int category; int number; } CdiParam;
+
+
+/* Opaque types */
+
+typedef struct CdiIterator CdiIterator;
+typedef struct CdiGribIterator CdiGribIterator;
+
+
 /* CDI control routines */
 
 void    cdiReset(void);
@@ -319,8 +331,9 @@ int     streamInqTimestep(int streamID, int tsID);
 /*      PIO: query currently set timestep id  */
 int     streamInqCurTimestepID(int streamID);
 
-char   *streamFilename(int streamID);
-const char *streamFilesuffix(int filetype);
+const char* streamFilename(int streamID);
+const char* streamFilesuffix(int filetype);
+
 off_t   streamNvals(int streamID);
 
 int     streamInqNvars ( int streamID );
@@ -343,8 +356,7 @@ void    streamWriteVarSliceF(int streamID, int varID, int levelID, const float *
 void    streamReadVarSlice(int streamID, int varID, int levelID, double *data_vec, int *nmiss);
 void    streamReadVarSliceF(int streamID, int varID, int levelID, float *data_vec, int *nmiss);
 
-void    streamWriteVarChunk(int streamID, int varID, const int rect[][2],
-                            const double *data_vec, int nmiss);
+void    streamWriteVarChunk(int streamID, int varID, const int rect[3][2], const double *data_vec, int nmiss);
 
 
 /* STREAM record I/O routines */
@@ -358,6 +370,62 @@ void    streamCopyRecord(int streamIDdest, int streamIDsrc);
 
 void    streamInqGRIBinfo(int streamID, int *intnum, float *fltnum, off_t *bignum);
 
+
+/* File driven I/O (may yield better performance than using the streamXXX functions) */
+
+//Creation & Destruction
+CdiIterator* cdiIterator_new(const char* path);  //Requires a subsequent call to cdiIteratorNextField() to point the iterator at the first field.
+CdiIterator* cdiIterator_clone(CdiIterator* me);
+char* cdiIterator_serialize(CdiIterator* me);  //Returns a malloc'ed string.
+CdiIterator* cdiIterator_deserialize(const char* description);  //description is a string that was returned by cdiIteratorSerialize(). Returns a copy of the original iterator.
+void cdiIterator_print(CdiIterator* me, FILE* stream);
+void cdiIterator_delete(CdiIterator* me);
+
+//Advancing an iterator
+int cdiIterator_nextField(CdiIterator* me);      //Points the iterator at the next field, returns CDI_EEOF if there are no more fields in the file.
+
+//Introspecting metadata
+//All outXXX arguments to these functions may be NULL.
+char* cdiIterator_inqStartTime(CdiIterator* me);      //Returns the (start) time as an ISO-8601 coded string. The caller is responsible to free() the returned string.
+char* cdiIterator_inqEndTime(CdiIterator* me);      //Returns the end time of an integration period as an ISO-8601 coded string, or NULL if there is no end time. The caller is responsible to free() the returned string.
+char* cdiIterator_inqVTime(CdiIterator* me);      //Returns the validity date as an ISO-8601 coded string. The caller is responsible to free() the returned string.
+int cdiIterator_inqLevelType(CdiIterator* me, int levelSelector, char** outName, char** outLongName, char** outStdName, char** outUnit);      //callers are responsible to free() strings that they request
+int cdiIterator_inqLevel(CdiIterator* me, int levelSelector, double* outValue1, double* outValue2);       //outValue2 is only written to if the level is a hybrid level
+int cdiIterator_inqLevelUuid(CdiIterator* me, int* outVgridNumber, int* outLevelCount, unsigned char (*outUuid)[CDI_UUID_SIZE]);   //outUuid must point to a buffer of 16 bytes, returns an error code if no generalized zaxis is used.
+CdiParam cdiIterator_inqParam(CdiIterator* me);
+int cdiIterator_inqDatatype(CdiIterator* me);
+int cdiIterator_inqTsteptype(CdiIterator* me);
+char* cdiIterator_inqVariableName(CdiIterator* me);        //The caller is responsible to free() the returned buffer.
+int cdiIterator_inqGridId(CdiIterator* me);         //The returned id is only valid until the next call to cdiIteratorNextField().
+
+//Reading data
+void cdiIterator_readField(CdiIterator* me, double* data_vec, size_t* nmiss);
+void cdiIterator_readFieldF(CdiIterator* me, float* data_vec, size_t* nmiss);
+//TODO[NH]: Add functions to read partial fields.
+
+
+//Direct access to grib fields
+CdiGribIterator* cdiGribIterator_clone(CdiIterator* me);  //Returns NULL if the associated file is not a GRIB file.
+void cdiGribIterator_delete(CdiGribIterator* me);
+
+//Callthroughs to GRIB-API
+int cdiGribIterator_getLong(CdiGribIterator* me, const char* key, long* value); //Same semantics as grib_get_long().
+int cdiGribIterator_getDouble(CdiGribIterator* me, const char* key, double* value); //Same semantics as grib_get_double().
+int cdiGribIterator_getLength(CdiGribIterator* me, const char* key, size_t* value);     //Same semantics as grib_get_length().
+int cdiGribIterator_getString(CdiGribIterator* me, const char* key, char* value, size_t* length);       //Same semantics as grib_get_string().
+int cdiGribIterator_getSize(CdiGribIterator* me, const char* key, size_t* value);     //Same semantics as grib_get_size().
+int cdiGribIterator_getLongArray(CdiGribIterator* me, const char* key, long* value, size_t* array_size);       //Same semantics as grib_get_long_array().
+int cdiGribIterator_getDoubleArray(CdiGribIterator* me, const char* key, double* value, size_t* array_size);       //Same semantics as grib_get_double_array().
+
+//Convenience functions for accessing GRIB-API keys
+int cdiGribIterator_inqEdition(CdiGribIterator* me);
+long cdiGribIterator_inqLongValue(CdiGribIterator* me, const char* key);   //Aborts on failure to fetch the given key.
+long cdiGribIterator_inqLongDefaultValue(CdiGribIterator* me, const char* key, long defaultValue); //Returns the default value if the given key is not present.
+double cdiGribIterator_inqDoubleValue(CdiGribIterator* me, const char* key);   //Aborts on failure to fetch the given key.
+double cdiGribIterator_inqDoubleDefaultValue(CdiGribIterator* me, const char* key, double defaultValue); //Returns the default value if the given key is not present.
+char* cdiGribIterator_inqStringValue(CdiGribIterator* me, const char* key);        //Returns a malloc'ed string.
+
+
 /* VLIST routines */
 
 /*      vlistCreate: Create a variable list */
@@ -486,6 +554,9 @@ void    vlistDefVarName(int vlistID, int varID, const char *name);
 /*      vlistInqVarName: Get the name of a Variable */
 void    vlistInqVarName(int vlistID, int varID, char *name);
 
+/*      vlistCopyVarName: Safe and convenient version of vlistInqVarName */
+char* vlistCopyVarName(int vlistId, int varId);
+
 /*      vlistDefVarStdname: Define the standard name of a Variable */
 void    vlistDefVarStdname(int vlistID, int varID, const char *stdname);
 
@@ -787,7 +858,7 @@ void    gridDefYbounds(int gridID, const double *ybounds_vec);
 /*      gridInqYbounds: Get the bounds of a Y-axis */
 int     gridInqYbounds(int gridID, double *ybounds_vec);
 
-void    gridDefRowlon(int gridID, int nrowlon, const int rowlon_vec[]);
+void    gridDefRowlon(int gridID, int nrowlon, const int* rowlon_vec);
 void    gridInqRowlon(int gridID, int *rowlon_vec);
 void    gridChangeType(int gridID, int gridtype);
 
@@ -975,7 +1046,7 @@ int     taxisInqType(int taxisID);
 
 int     taxisInqNumavg(int taxisID);
 
-char   *tunitNamePtr(int tunitID);
+const char* tunitNamePtr(int tunitID);
 
 
 /* Institut routines */
@@ -986,7 +1057,7 @@ int     institutInqNumber(void);
 int     institutInqCenter(int instID);
 int     institutInqSubcenter(int instID);
 const char *institutInqNamePtr(int instID);
-char   *institutInqLongnamePtr(int instID);
+const char* institutInqLongnamePtr(int instID);
 
 /* Model routines */
 
@@ -1004,7 +1075,7 @@ void    tableWrite(const char *filename, int tableID);
 int     tableRead(const char *tablefile);
 int     tableDef(int modelID, int tablenum, const char *tablename);
 
-char   *tableInqNamePtr(int tableID);
+const char* tableInqNamePtr(int tableID);
 void    tableDefEntry(int tableID, int code, const char *name, const char *longname, const char *units);
 
 int     tableInq(int modelID, int tablenum, const char *tablename);
diff --git a/src/cdi.inc b/src/cdi.inc
index 25c4e7aa7f242e1daefba4e9a0d3f02a441e7d81..675b23044ac9b266069c7b07ac92dad47660488a 100644
--- a/src/cdi.inc
+++ b/src/cdi.inc
@@ -4,7 +4,7 @@
 !
 ! Author:
 ! -------
-! Uwe Schulzweida, MPI-MET, Hamburg,   February 2015
+! Uwe Schulzweida, MPI-MET, Hamburg,   March 2015
 !
 
       INTEGER    CDI_MAX_NAME          
@@ -31,6 +31,8 @@
 !
       INTEGER    CDI_NOERR             
       PARAMETER (CDI_NOERR              =  0)
+      INTEGER    CDI_EEOF              
+      PARAMETER (CDI_EEOF               = -1)
       INTEGER    CDI_ESYSTEM           
       PARAMETER (CDI_ESYSTEM            = -10)
       INTEGER    CDI_EINVAL            
@@ -377,6 +379,12 @@
       INTEGER    CDI_UUID_SIZE         
       PARAMETER (CDI_UUID_SIZE          = 16)
 !
+!  Structs that are used to return data to the user
+!
+!
+!  Opaque types
+!
+!
 !  CDI control routines
 !
 !                     cdiReset
@@ -570,14 +578,6 @@
 !                                    (INTEGER         streamID)
       EXTERNAL        streamInqCurTimestepID
 
-      CHARACTER(80)   streamFilename
-!                                    (INTEGER         streamID)
-      EXTERNAL        streamFilename
-
-      CHARACTER(80)   streamFilesuffix
-!                                    (INTEGER         filetype)
-      EXTERNAL        streamFilesuffix
-
       INTEGER         streamInqNvars
 !                                    (INTEGER         streamID)
       EXTERNAL        streamInqNvars
@@ -691,6 +691,9 @@
 !                                     INTEGER         streamIDsrc)
       EXTERNAL        streamCopyRecord
 
+!
+!  File driven I/O (may yield better performance than using the streamXXX functions)
+!
 !
 !  VLIST routines
 !
@@ -1783,12 +1786,6 @@
 !                                     DOUBLEPRECISION ybounds_vec)
       EXTERNAL        gridInqYbounds
 
-!                     gridDefRowlon
-!                                    (INTEGER         gridID,
-!                                     INTEGER         nrowlon,
-!                                     INTEGER         rowlon_vec)
-      EXTERNAL        gridDefRowlon
-
 !                     gridInqRowlon
 !                                    (INTEGER         gridID,
 !                                     INTEGER         rowlon_vec)
@@ -2178,10 +2175,6 @@
 !                                    (INTEGER         taxisID)
       EXTERNAL        taxisInqNumavg
 
-      CHARACTER(80)   tunitNamePtr
-!                                    (INTEGER         tunitID)
-      EXTERNAL        tunitNamePtr
-
 !
 !  Institut routines
 !
@@ -2214,10 +2207,6 @@
 !                                    (INTEGER         instID)
       EXTERNAL        institutInqNamePtr
 
-      CHARACTER(80)   institutInqLongnamePtr
-!                                    (INTEGER         instID)
-      EXTERNAL        institutInqLongnamePtr
-
 !
 !  Model routines
 !
@@ -2268,10 +2257,6 @@
 !                                     CHARACTER*(*)   tablename)
       EXTERNAL        tableDef
 
-      CHARACTER(80)   tableInqNamePtr
-!                                    (INTEGER         tableID)
-      EXTERNAL        tableInqNamePtr
-
 !                     tableDefEntry
 !                                    (INTEGER         tableID,
 !                                     INTEGER         code,
diff --git a/src/cdiFortran.c b/src/cdiFortran.c
index 0af68916b5425888d7ed73fdfc651f0fbb38339d..baec75b588549a726a913c89264bed4ddd33894f 100644
--- a/src/cdiFortran.c
+++ b/src/cdiFortran.c
@@ -60,6 +60,12 @@
 /*  number of unsigned char needed to store UUID  */
 
 
+/*  Structs that are used to return data to the user  */
+
+
+/*  Opaque types  */
+
+
 /*  CDI control routines  */
 
 FCALLSCSUB0 (cdiReset, CDIRESET, cdireset)
@@ -118,8 +124,6 @@ FCALLSCFUN1 (INT, streamInqCompLevel, STREAMINQCOMPLEVEL, streaminqcomplevel, IN
 FCALLSCFUN2 (INT, streamDefTimestep, STREAMDEFTIMESTEP, streamdeftimestep, INT, INT)
 FCALLSCFUN2 (INT, streamInqTimestep, STREAMINQTIMESTEP, streaminqtimestep, INT, INT)
 FCALLSCFUN1 (INT, streamInqCurTimestepID, STREAMINQCURTIMESTEPID, streaminqcurtimestepid, INT)
-FCALLSCFUN1 (STRING, streamFilename, STREAMFILENAME, streamfilename, INT)
-FCALLSCFUN1 (STRING, streamFilesuffix, STREAMFILESUFFIX, streamfilesuffix, INT)
 FCALLSCFUN1 (INT, streamInqNvars, STREAMINQNVARS, streaminqnvars, INT)
 
 /*  STREAM var I/O routines  */
@@ -143,6 +147,9 @@ FCALLSCSUB3 (streamWriteRecordF, STREAMWRITERECORDF, streamwriterecordf, INT, PF
 FCALLSCSUB3 (streamReadRecord, STREAMREADRECORD, streamreadrecord, INT, PDOUBLE, PINT)
 FCALLSCSUB2 (streamCopyRecord, STREAMCOPYRECORD, streamcopyrecord, INT, INT)
 
+/*  File driven I/O (may yield better performance than using the streamXXX functions)  */
+
+
 /*  VLIST routines  */
 
 FCALLSCFUN0 (INT, vlistCreate, VLISTCREATE, vlistcreate)
@@ -373,7 +380,6 @@ FCALLSCSUB2 (gridDefXbounds, GRIDDEFXBOUNDS, griddefxbounds, INT, PDOUBLE)
 FCALLSCFUN2 (INT, gridInqXbounds, GRIDINQXBOUNDS, gridinqxbounds, INT, PDOUBLE)
 FCALLSCSUB2 (gridDefYbounds, GRIDDEFYBOUNDS, griddefybounds, INT, PDOUBLE)
 FCALLSCFUN2 (INT, gridInqYbounds, GRIDINQYBOUNDS, gridinqybounds, INT, PDOUBLE)
-FCALLSCSUB3 (gridDefRowlon, GRIDDEFROWLON, griddefrowlon, INT, INT, INTV)
 FCALLSCSUB2 (gridInqRowlon, GRIDINQROWLON, gridinqrowlon, INT, PINT)
 FCALLSCSUB2 (gridChangeType, GRIDCHANGETYPE, gridchangetype, INT, INT)
 FCALLSCSUB2 (gridDefComplexPacking, GRIDDEFCOMPLEXPACKING, griddefcomplexpacking, INT, INT)
@@ -461,7 +467,6 @@ FCALLSCFUN1 (DOUBLE, taxisInqForecastPeriod, TAXISINQFORECASTPERIOD, taxisinqfor
 FCALLSCSUB2 (taxisDefNumavg, TAXISDEFNUMAVG, taxisdefnumavg, INT, INT)
 FCALLSCFUN1 (INT, taxisInqType, TAXISINQTYPE, taxisinqtype, INT)
 FCALLSCFUN1 (INT, taxisInqNumavg, TAXISINQNUMAVG, taxisinqnumavg, INT)
-FCALLSCFUN1 (STRING, tunitNamePtr, TUNITNAMEPTR, tunitnameptr, INT)
 
 /*  Institut routines  */
 
@@ -471,7 +476,6 @@ FCALLSCFUN0 (INT, institutInqNumber, INSTITUTINQNUMBER, institutinqnumber)
 FCALLSCFUN1 (INT, institutInqCenter, INSTITUTINQCENTER, institutinqcenter, INT)
 FCALLSCFUN1 (INT, institutInqSubcenter, INSTITUTINQSUBCENTER, institutinqsubcenter, INT)
 FCALLSCFUN1 (STRING, institutInqNamePtr, INSTITUTINQNAMEPTR, institutinqnameptr, INT)
-FCALLSCFUN1 (STRING, institutInqLongnamePtr, INSTITUTINQLONGNAMEPTR, institutinqlongnameptr, INT)
 
 /*  Model routines  */
 
@@ -487,7 +491,6 @@ FCALLSCSUB2 (tableWriteC, TABLEWRITEC, tablewritec, STRING, INT)
 FCALLSCSUB2 (tableWrite, TABLEWRITE, tablewrite, STRING, INT)
 FCALLSCFUN1 (INT, tableRead, TABLEREAD, tableread, STRING)
 FCALLSCFUN3 (INT, tableDef, TABLEDEF, tabledef, INT, INT, STRING)
-FCALLSCFUN1 (STRING, tableInqNamePtr, TABLEINQNAMEPTR, tableinqnameptr, INT)
 FCALLSCSUB5 (tableDefEntry, TABLEDEFENTRY, tabledefentry, INT, INT, STRING, STRING, STRING)
 FCALLSCFUN3 (INT, tableInq, TABLEINQ, tableinq, INT, INT, STRING)
 FCALLSCFUN0 (INT, tableInqNumber, TABLEINQNUMBER, tableinqnumber)
diff --git a/src/cdi_int.h b/src/cdi_int.h
index 9fa869e502b366e5cdadc752873de04ae0a178d5..d85041d47fd4d3b51aa355d0ffa3658dd88286e9 100644
--- a/src/cdi_int.h
+++ b/src/cdi_int.h
@@ -325,13 +325,15 @@ void  cdiInitialize(void);
 
 void uuid2str(const unsigned char *uuid, char *uuidstr);
 int str2uuid(const char *uuidstr, unsigned char *uuid);
-static inline int
-cdiUUIDIsNull(const unsigned char uuid[CDI_UUID_SIZE])
+
+static inline int cdiUUIDIsNull(const unsigned char uuid[CDI_UUID_SIZE])
 {
   static const unsigned char uuid_nil[CDI_UUID_SIZE];
   return !memcmp(uuid, uuid_nil, CDI_UUID_SIZE);
 }
 
+char* cdiEscapeSpaces(const char* string);
+char* cdiUnescapeSpaces(const char* string, const char** outStringEnd);
 
 #define CDI_UNIT_PA   1
 #define CDI_UNIT_HPA  2
diff --git a/src/dmemory.h b/src/dmemory.h
index 52795f49f51d3863b19100c37489621bcf1020d7..dced53710a76f4ff9d6080f86ca4a4f781e865c1 100644
--- a/src/dmemory.h
+++ b/src/dmemory.h
@@ -1,7 +1,11 @@
 #ifndef _DMEMORY_H
 #define _DMEMORY_H
 
+//Ensure that all standard headers that may declare malloc() and friends are already included so that our macros won't clobber their definitions.
 #include <stdlib.h>
+#ifdef HAVE_MALLOC_H
+    #include <malloc.h>
+#endif
 
 /*
  * if DEBUG_MEMORY is defined setenv MEMORY_DEBUG to debug memory
diff --git a/src/gribapi.h b/src/gribapi.h
index 9233cf268fd04b3974b8bdca65aa59d72e12df22..ab11feb58bf52607a0b13a12ccd00a5eb2b72a3a 100644
--- a/src/gribapi.h
+++ b/src/gribapi.h
@@ -2,11 +2,15 @@
 #define _GRIBAPI_H
 
 #ifdef HAVE_LIBGRIB_API
-#  include "error.h"
-#  include <grib_api.h>
+#include <grib_api.h>
+#ifndef  _ERROR_H
+#include "error.h"
+#endif
 #endif
 
+#ifndef  _CDI_INT_H
 #include "cdi_int.h"
+#endif
 
 #define  GRIBAPI_MISSVAL  -9.E33
 
diff --git a/src/gribapi_utilities.c b/src/gribapi_utilities.c
new file mode 100644
index 0000000000000000000000000000000000000000..67e8ba6c1cf3c2385d8aa78eeb1f6d0eadd89b1a
--- /dev/null
+++ b/src/gribapi_utilities.c
@@ -0,0 +1,706 @@
+static int dummy;
+
+#ifdef HAVE_LIBGRIB_API
+
+#include "gribapi_utilities.h"
+
+#include "cdi.h"
+#include "dmemory.h"
+#include "error.h"
+#include "gribapi.h"
+#include "proprietarySystemWorkarounds.h"
+
+#include <assert.h>
+#include <time.h>
+
+#define FAIL_ON_GRIB_ERROR(function, gribHandle, key, ...) do\
+{\
+  int errorCode = function(gribHandle, key, __VA_ARGS__);\
+  if(errorCode)\
+    {\
+      fprintf(stderr, "%s:%d: Error in function `%s`: `%s` returned error code %d for key \"%s\"", __FILE__, __LINE__, __func__, #function, errorCode, key);\
+      exit(errorCode);\
+    }\
+} while(0)
+
+//A simple wrapper for grib_get_string() that returns a newly allocated string.
+char* gribCopyString(grib_handle* gribHandle, const char* key)
+{
+  size_t length;
+  if(grib_get_length(gribHandle, key, &length)) return NULL;
+  char* result = xmalloc(length);
+  if(!grib_get_string(gribHandle, key, result, &length)) return result;
+  free(result);
+  return NULL;
+}
+
+//A simple wrapper for grib_get_string() for the usecase that the result is only compared to a given constant string.
+//Returns true if the key exists and the value is equal to the given string.
+bool gribCheckString(grib_handle* gribHandle, const char* key, const char* expectedValue)
+{
+  size_t expectedLength = strlen(expectedValue) + 1, length;
+  if(grib_get_length(gribHandle, key, &length)) return false;
+  if(length != expectedLength) return false;
+  char value[length];
+  if(grib_get_string(gribHandle, key, value, &length)) return false;
+  return !strcmp(value, expectedValue);
+}
+
+//A simple wrapper for grib_get_long() for the usecase that the result is only compared to a given constant value.
+//Returns true if the key exists and the value is equal to the given one.
+bool gribCheckLong(grib_handle* gribHandle, const char* key, long expectedValue)
+{
+  long value;
+  if(grib_get_long(gribHandle, key, &value)) return false;
+  return value == expectedValue;
+}
+
+//A simple wrapper for grib_get_long() for the usecase that failure to fetch the value is fatal.
+long gribGetLong(grib_handle* gh, const char* key)
+{
+  long result;
+  FAIL_ON_GRIB_ERROR(grib_get_long, gh, key, &result);
+  return result;
+}
+
+//A simple wrapper for grib_get_long() for the usecase that a default value is used in the case that the operation fails.
+long gribGetLongDefault(grib_handle* gribHandle, const char* key, long defaultValue)
+{
+  long result;
+  if(grib_get_long(gribHandle, key, &result)) return defaultValue;
+  if(result == GRIB_MISSING_LONG) return defaultValue;
+  return result;
+}
+
+//A simple wrapper for grib_get_double() for the usecase that failure to fetch the value is fatal.
+double gribGetDouble(grib_handle* gh, const char* key)
+{
+  double result;
+  FAIL_ON_GRIB_ERROR(grib_get_double, gh, key, &result);
+  return result;
+}
+
+//A sample wrapper for grib_get_double() for the usecase that a default value is used in the case that the operation fails.
+double gribGetDoubleDefault(grib_handle* gribHandle, const char* key, double defaultValue)
+{
+  double result;
+  if(grib_get_double(gribHandle, key, &result)) return defaultValue;
+  if(result == GRIB_MISSING_DOUBLE) return defaultValue;
+  return result;
+}
+
+//A simple wrapper for grib_get_size() for the usecase that failure to fetch the value is fatal.
+size_t gribGetArraySize(grib_handle* gribHandle, const char* key)
+{
+  size_t result;
+  FAIL_ON_GRIB_ERROR(grib_get_size, gribHandle, key, &result);
+  return result;
+}
+
+//A simple wrapper for grib_get_double_array() for the usecase that failure to fetch the data is fatal.
+void gribGetDoubleArray(grib_handle* gribHandle, const char* key, double* array)
+{
+  size_t valueCount = gribGetArraySize(gribHandle, key);
+  FAIL_ON_GRIB_ERROR(grib_get_double_array, gribHandle, key, array, &valueCount);
+}
+
+//A simple wrapper for grib_get_long_array() for the usecase that failure to fetch the data is fatal.
+void gribGetLongArray(grib_handle* gribHandle, const char* key, long* array)
+{
+  size_t valueCount = gribGetArraySize(gribHandle, key);
+  FAIL_ON_GRIB_ERROR(grib_get_long_array, gribHandle, key, array, &valueCount);
+}
+
+
+//We need the edition number so frequently, that it's convenient to give it its own function.
+long gribEditionNumber(grib_handle* gh)
+{
+  return gribGetLong(gh, "editionNumber");
+}
+
+//This return value of this should be passed to a call to resetTz(), it is a malloc'ed string with the content of the TZ environment variable before the call (or NULL if that was not set).
+static char* setUtc()
+{
+  char* temp = getenv("TZ"), *result = NULL;
+  if(temp) result = myStrDup(temp);
+  setenv("TZ", "UTC", 1);
+  return result;
+}
+
+//Undoes the effect of setUtc(), pass to it the return value of the corresponding setUtc() call, it will free the string.
+static void resetTz(char* savedTz)
+{
+  if(savedTz)
+    {
+      setenv("TZ", savedTz, 1);
+      free(savedTz);
+    }
+  else
+    {
+      unsetenv("TZ");
+    }
+}
+
+//This function uses the system functions to normalize the date representation according to the gregorian calendar.
+//Returns zero on success.
+static int normalizeDays(struct tm* me)
+{
+  char* savedTz = setUtc();     //Ensure that mktime() does not interprete the date according to our local time zone.
+
+  int result = mktime(me) == (time_t)-1;        //This does all the heavy lifting.
+
+  resetTz(savedTz);
+  return result;
+}
+
+//Returns zero on success.
+static int addSecondsToDate(struct tm* me, long long amount)
+{
+  //It is irrelevant here whether days are zero or one based, the correction would have be undone again so that it is effectless.
+  long long seconds = ((me->tm_mday*24ll + me->tm_hour)*60 + me->tm_min)*60 + me->tm_sec;    //The portion of the date that uses fixed increments.
+  seconds += amount;
+  me->tm_mday = seconds/24/60/60;
+  seconds -= me->tm_mday*24*60*60;
+  me->tm_hour = seconds/60/60;
+  seconds -= me->tm_hour*60*60;
+  me->tm_min = seconds/60;
+  seconds -= me->tm_min*60;
+  me->tm_sec = seconds;
+  return normalizeDays(me);
+}
+
+static void addMonthsToDate(struct tm* me, long long amount)
+{
+  long long months = me->tm_year*12ll + me->tm_mon;
+  months += amount;
+  me->tm_year = months/12;
+  months -= me->tm_year*12;
+  me->tm_mon = months;
+}
+
+//unit is a value according to code table 4.4 of the GRIB2 specification, returns non-zero on error
+static int addToDate(struct tm* me, long long amount, long unit)
+{
+  switch(unit)
+    {
+      case 0: return addSecondsToDate(me,       60*amount);   // minute
+      case 1: return addSecondsToDate(me,    60*60*amount);   // hour
+      case 2: return addSecondsToDate(me, 24*60*60*amount);   // day
+
+      case 3: addMonthsToDate(me,        amount); return 0;   // month
+      case 4: addMonthsToDate(me,     12*amount); return 0;   // year
+      case 5: addMonthsToDate(me,  10*12*amount); return 0;   // decade
+      case 6: addMonthsToDate(me,  30*12*amount); return 0;   // normal
+      case 7: addMonthsToDate(me, 100*12*amount); return 0;   // century
+
+      case 10: return addSecondsToDate(me,  3*60*60*amount);  // eighth of a day
+      case 11: return addSecondsToDate(me,  6*60*60*amount);  // quarter day
+      case 12: return addSecondsToDate(me, 12*60*60*amount);  // half day
+      case 13: return addSecondsToDate(me,          amount);  // second
+
+      default: return 1;        //reserved, unknown, or missing
+    }
+}
+
+static char* makeDateString(struct tm* me)
+{
+  return myAsprintf("%04d-%02d-%02dT%02d:%02d:%02d.000", me->tm_year + 1900, me->tm_mon + 1, me->tm_mday, me->tm_hour, me->tm_min, me->tm_sec);
+}
+
+//FIXME: This ignores any calendar definition that might be present.
+//XXX: Identification templates are not implemented in grib_api-1.12.3, so even if I implemented the other calendars now, it wouldn't be possible to use them.
+static int getAvailabilityOfRelativeTimes(grib_handle* gh, bool* outHaveForecastTime, bool* outHaveTimeRange)
+{
+  switch(gribGetLong(gh, "productDefinitionTemplateNumber"))
+    {
+      case 20: case 30: case 31: case 254: case 311: case 2000:
+        *outHaveForecastTime = false, *outHaveTimeRange = false;
+        return 0;
+
+      case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 15: case 32: case 33: case 40: case 41: case 44: case 45: case 48: case 51: case 53: case 54: case 60: case 1000: case 1002: case 1100: case 40033:
+        *outHaveForecastTime = true, *outHaveTimeRange = false;
+        return 0;
+
+      case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 34: case 42: case 43: case 46: case 47: case 61: case 91: case 1001: case 1101: case 40034:
+        *outHaveForecastTime = true, *outHaveTimeRange = true;
+        return 0;
+
+      default:
+        return 1;
+    }
+}
+
+char* gribMakeTimeString(grib_handle* gh, bool getEndTime)
+{
+  //Get the parts of the reference date.
+  struct tm date = {
+      .tm_mon = gribGetLong(gh, "month") - 1,   //months are zero based in struct tm and one based in GRIB
+      .tm_mday = gribGetLong(gh, "day"),
+      .tm_hour = gribGetLong(gh, "hour"),
+      .tm_min = gribGetLong(gh, "minute")
+  };
+  if(gribEditionNumber(gh) == 1)
+    {
+      date.tm_year = gribGetLong(gh, "yearOfCentury");  //years are -1900 based both in struct tm and GRIB1
+    }
+  else
+    {
+      date.tm_year = gribGetLong(gh, "year") - 1900;   //years are -1900 based in struct tm and zero based in GRIB2
+      date.tm_sec = gribGetLong(gh, "second");
+
+      //Determine whether we have a forecast time and a time range.
+      bool haveForecastTime, haveTimeRange;
+      if(getAvailabilityOfRelativeTimes(gh, &haveForecastTime, &haveTimeRange)) return NULL;
+      if(getEndTime && !haveTimeRange) return NULL;     //tell the caller that the requested time does not exist
+
+      //If we have relative times, apply them to the date
+      if(haveForecastTime)
+        {
+          long offset = gribGetLongDefault(gh, "forecastTime", 0);  //if(stepUnits == indicatorOfUnitOfTimeRange) assert(startStep == forecastTime)
+          long offsetUnit = gribGetLongDefault(gh, "indicatorOfUnitOfTimeRange", 255);
+          if(addToDate(&date, offset, offsetUnit)) return NULL;
+          if(getEndTime)
+            {
+              assert(haveTimeRange);
+              long range = gribGetLongDefault(gh, "lengthOfTimeRange", 0);       //if(stepUnits == indicatorOfUnitForTimeRange) assert(endStep == startStep + lengthOfTimeRange)
+              long rangeUnit = gribGetLongDefault(gh, "indicatorOfUnitForTimeRange", 255);
+              if(addToDate(&date, range, rangeUnit)) return NULL;
+            }
+        }
+    }
+
+  //Bake the date into a string.
+  return makeDateString(&date);
+}
+
+int gribapiTimeIsFC(grib_handle *gh)
+{
+  if(gribEditionNumber(gh) <= 1) return true;
+
+  long sigofrtime;
+  FAIL_ON_GRIB_ERROR(grib_get_long, gh, "significanceOfReferenceTime", &sigofrtime);
+  return sigofrtime != 3;
+}
+
+//Fetches the value of the "stepType" key and converts it into a constant in the TSTEP_* range.
+int gribapiGetTsteptype(grib_handle *gh)
+{
+  int tsteptype = TSTEP_INSTANT;
+  static bool lprint = true;
+
+  if ( gribapiTimeIsFC(gh) )
+    {
+      int status;
+      size_t len = 256;
+      char stepType[256];
+
+      status = grib_get_string(gh, "stepType", stepType, &len);
+      if ( status == 0 && len > 1 && len < 256 )
+        {
+          if      ( strncmp("instant", stepType, len) == 0 ) tsteptype = TSTEP_INSTANT;
+          else if ( strncmp("avg",     stepType, len) == 0 ) tsteptype = TSTEP_AVG;
+          else if ( strncmp("accum",   stepType, len) == 0 ) tsteptype = TSTEP_ACCUM;
+          else if ( strncmp("max",     stepType, len) == 0 ) tsteptype = TSTEP_MAX;
+          else if ( strncmp("min",     stepType, len) == 0 ) tsteptype = TSTEP_MIN;
+          else if ( strncmp("diff",    stepType, len) == 0 ) tsteptype = TSTEP_DIFF;
+          else if ( strncmp("rms",     stepType, len) == 0 ) tsteptype = TSTEP_RMS;
+          else if ( strncmp("sd",      stepType, len) == 0 ) tsteptype = TSTEP_SD;
+          else if ( strncmp("cov",     stepType, len) == 0 ) tsteptype = TSTEP_COV;
+          else if ( strncmp("ratio",   stepType, len) == 0 ) tsteptype = TSTEP_RATIO;
+          else if ( lprint )
+            {
+              Message("Time stepType %s unsupported, set to instant!", stepType);
+              lprint = false;
+            }
+
+          // printf("stepType: %s %ld %d\n", stepType, len, tsteptype);
+        }
+    }
+
+  return (tsteptype);
+}
+
+int gribGetDatatype(grib_handle* gribHandle)
+{
+  int datatype;
+  if(gribEditionNumber(gribHandle) > 1 && gribCheckString(gribHandle, "packingType", "grid_ieee"))
+    {
+      datatype = gribCheckLong(gribHandle, "precision", 1) ? DATATYPE_FLT32 : DATATYPE_FLT64;
+    }
+  else
+    {
+      long bitsPerValue;
+      datatype = (!grib_get_long(gribHandle, "bitsPerValue", &bitsPerValue) && bitsPerValue > 0 && bitsPerValue <= 32) ? (int)bitsPerValue : DATATYPE_PACK;
+    }
+  return datatype;
+}
+
+int gribapiGetParam(grib_handle *gh)
+{
+  long pdis, pcat, pnum;
+  if ( gribEditionNumber(gh) <= 1 )
+    {
+      pdis = 255;
+      FAIL_ON_GRIB_ERROR(grib_get_long, gh, "table2Version", &pcat);
+      FAIL_ON_GRIB_ERROR(grib_get_long, gh, "indicatorOfParameter", &pnum);
+    }
+  else
+    {
+      FAIL_ON_GRIB_ERROR(grib_get_long, gh, "discipline", &pdis);
+      if(grib_get_long(gh, "parameterCategory", &pcat)) pcat = 0;
+      if(grib_get_long(gh, "parameterNumber", &pnum)) pnum = 0;
+    }
+  return cdiEncodeParam((int)pnum, (int)pcat, (int)pdis);
+}
+
+int gribapiGetGridType(grib_handle *gh)
+{
+  int gridtype = GRID_GENERIC;
+  switch (gribGetLongDefault(gh, "gridDefinitionTemplateNumber", -1))
+    {
+      case  GRIB2_GTYPE_LATLON:
+        gridtype = ( gribGetLong(gh, "Ni") == (long) GRIB_MISSING_LONG ) ? GRID_GENERIC : GRID_LONLAT;
+        break;
+
+      case  GRIB2_GTYPE_GAUSSIAN:
+        gridtype = ( gribGetLong(gh, "Ni") == (long) GRIB_MISSING_LONG ) ? GRID_GAUSSIAN_REDUCED : GRID_GAUSSIAN;
+        break;
+
+      case GRIB2_GTYPE_LATLON_ROT:   gridtype = GRID_LONLAT; break;
+      case GRIB2_GTYPE_LCC:          gridtype = GRID_LCC; break;
+      case GRIB2_GTYPE_SPECTRAL:     gridtype = GRID_SPECTRAL; break;
+      case GRIB2_GTYPE_GME:          gridtype = GRID_GME; break;
+      case GRIB2_GTYPE_UNSTRUCTURED: gridtype = GRID_UNSTRUCTURED; break;
+    }
+
+  return gridtype;
+}
+
+static
+int gribapiGetIsRotated(grib_handle *gh)
+{
+  return gribGetLongDefault(gh, "gridDefinitionTemplateNumber", -1) == GRIB2_GTYPE_LATLON_ROT;
+}
+
+//TODO: Simplify by use of the convenience functions (gribGetLong(), gribGetLongDefault(), etc.).
+void gribapiGetGrid(grib_handle *gh, grid_t *grid)
+{
+  long editionNumber = gribEditionNumber(gh);
+  int gridtype = gribapiGetGridType(gh);
+  /*
+  if ( streamptr->unreduced && gridtype == GRID_GAUSSIAN_REDUCED )
+    {
+      gridtype = GRID_GAUSSIAN;
+      ISEC2_NumLon = 2*ISEC2_NumLat;
+      ISEC4_NumValues = ISEC2_NumLon*ISEC2_NumLat;
+    }
+  */
+  memset(grid, 0, sizeof(grid_t));
+
+  size_t datasize;
+  FAIL_ON_GRIB_ERROR(grib_get_size, gh, "values", &datasize);
+  long numberOfPoints;
+  FAIL_ON_GRIB_ERROR(grib_get_long, gh, "numberOfPoints", &numberOfPoints);
+
+  switch (gridtype)
+    {
+    case GRID_LONLAT:
+    case GRID_GAUSSIAN:
+      {
+        long lpar;
+        FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Ni", &lpar);
+        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
+        int nlon = (int)lpar;
+        FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Nj", &lpar);
+        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
+        int nlat = (int)lpar;
+
+        if ( gridtype == GRID_GAUSSIAN )
+          {
+            FAIL_ON_GRIB_ERROR(grib_get_long, gh, "numberOfParallelsBetweenAPoleAndTheEquator", &lpar);
+            grid->np = (int)lpar;
+          }
+
+        if ( numberOfPoints != nlon*nlat )
+          Error("numberOfPoints (%ld) and gridSize (%d) differ!", numberOfPoints, nlon*nlat);
+
+        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
+        grid->size  = (int)numberOfPoints;
+        grid->xsize = nlon;
+        grid->ysize = nlat;
+        grid->xinc  = 0;
+        grid->yinc  = 0;
+        grid->xdef  = 0;
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfFirstGridPointInDegrees", &grid->xfirst);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfLastGridPointInDegrees",  &grid->xlast);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfFirstGridPointInDegrees",  &grid->yfirst);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfLastGridPointInDegrees",   &grid->ylast);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "iDirectionIncrementInDegrees", &grid->xinc);
+        if ( gridtype == GRID_LONLAT )
+          FAIL_ON_GRIB_ERROR(grib_get_double, gh, "jDirectionIncrementInDegrees", &grid->yinc);
+
+        if ( IS_EQUAL(grid->xinc, GRIB_MISSING_DOUBLE) ) grid->xinc = 0;
+
+        /* if ( IS_NOT_EQUAL(grid->xfirst, 0) || IS_NOT_EQUAL(grid->xlast, 0) ) */
+          {
+            if ( grid->xsize > 1 )
+              {
+                if ( (grid->xfirst >= grid->xlast) && (grid->xfirst >= 180) ) grid->xfirst -= 360;
+
+                if ( editionNumber <= 1 )
+                  {
+                    /* correct xinc if necessary */
+                    if ( IS_EQUAL(grid->xfirst, 0) && grid->xlast > 354 )
+                      {
+                        double xinc = 360. / grid->xsize;
+
+                        if ( fabs(grid->xinc-xinc) > 0.0 )
+                          {
+                            grid->xinc = xinc;
+                            if ( CDI_Debug ) Message("set xinc to %g", grid->xinc);
+                          }
+                      }
+                  }
+              }
+            grid->xdef = 2;
+          }
+        grid->ydef = 0;
+        /* if ( IS_NOT_EQUAL(grid->yfirst, 0) || IS_NOT_EQUAL(grid->ylast, 0) ) */
+          {
+            if ( grid->ysize > 1 )
+              {
+                if ( editionNumber <= 1 )
+                  {
+                  }
+              }
+            grid->ydef = 2;
+          }
+        break;
+      }
+    case GRID_GAUSSIAN_REDUCED:
+      {
+        size_t dummy;
+        long *pl;
+
+        long lpar;
+        FAIL_ON_GRIB_ERROR(grib_get_long, gh, "numberOfParallelsBetweenAPoleAndTheEquator", &lpar);
+        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
+        grid->np = (int)lpar;
+
+        FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Nj", &lpar);
+        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
+        int nlat = (int)lpar;
+
+        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
+        grid->size   = (int)numberOfPoints;
+
+        grid->rowlon = (int *) malloc((size_t)nlat * sizeof (int));
+        pl          = (long *) malloc((size_t)nlat * sizeof (long));
+        dummy       = (size_t)nlat;
+        FAIL_ON_GRIB_ERROR(grib_get_long_array, gh, "pl", pl, &dummy);
+        /* FIXME: assert(pl[i] >= INT_MIN && pl[i] <= INT_MIN) */
+        for (int i = 0; i < nlat; ++i ) grid->rowlon[i] = (int)pl[i];
+        free(pl);
+
+        grid->ysize  = nlat;
+        grid->xinc   = 0;
+        grid->yinc   = 0;
+        grid->xdef   = 0;
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfFirstGridPointInDegrees", &grid->xfirst);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfLastGridPointInDegrees",  &grid->xlast);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfFirstGridPointInDegrees",  &grid->yfirst);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfLastGridPointInDegrees",   &grid->ylast);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "iDirectionIncrementInDegrees", &grid->xinc);
+
+        if ( IS_EQUAL(grid->xinc, GRIB_MISSING_DOUBLE) ) grid->xinc = 0;
+
+        /* if ( IS_NOT_EQUAL(grid->xfirst, 0) || IS_NOT_EQUAL(grid->xlast, 0) ) */
+          {
+            if ( grid->xsize > 1 )
+              {
+                if ( (grid->xfirst > grid->xlast) && (grid->xfirst >= 180) ) grid->xfirst -= 360;
+
+                if ( editionNumber <= 1 )
+                  {
+                    /* correct xinc if necessary */
+                    if ( IS_EQUAL(grid->xfirst, 0) && grid->xlast > 354 )
+                      {
+                        double xinc = 360. / grid->xsize;
+
+                        if ( fabs(grid->xinc-xinc) > 0.0 )
+                          {
+                            grid->xinc = xinc;
+                            if ( CDI_Debug ) Message("set xinc to %g", grid->xinc);
+                          }
+                      }
+                  }
+              }
+            grid->xdef = 2;
+          }
+        grid->ydef  = 0;
+        /* if ( IS_NOT_EQUAL(grid->yfirst, 0) || IS_NOT_EQUAL(grid->ylast, 0) ) */
+          {
+            if ( grid->ysize > 1 )
+              {
+                if ( editionNumber <= 1 )
+                  {
+                  }
+              }
+            grid->ydef = 2;
+          }
+        break;
+      }
+    case GRID_LCC:
+      {
+        int nlon, nlat;
+        long lpar;
+
+        FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Nx", &lpar);
+        nlon = lpar;
+        FAIL_ON_GRIB_ERROR(grib_get_long, gh, "Ny", &lpar);
+        nlat = lpar;
+
+        if ( numberOfPoints != nlon*nlat )
+          Error("numberOfPoints (%d) and gridSize (%d) differ!", (int)numberOfPoints, nlon*nlat);
+
+        grid->size  = numberOfPoints;
+        grid->xsize = nlon;
+        grid->ysize = nlat;
+
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "DxInMetres", &grid->lcc_xinc);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "DyInMetres", &grid->lcc_yinc);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfFirstGridPointInDegrees", &grid->lcc_originLon);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfFirstGridPointInDegrees", &grid->lcc_originLat);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "LoVInDegrees", &grid->lcc_lonParY);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "Latin1InDegrees", &grid->lcc_lat1);
+        FAIL_ON_GRIB_ERROR(grib_get_double, gh, "Latin2InDegrees", &grid->lcc_lat2);
+
+        if ( editionNumber <= 1 )
+          {
+            FAIL_ON_GRIB_ERROR(grib_get_long, gh, "projectionCenterFlag", &lpar);
+            grid->lcc_projflag  = (int) lpar;
+            FAIL_ON_GRIB_ERROR(grib_get_long, gh, "scanningMode", &lpar);
+            grid->lcc_scanflag  = (int) lpar;
+          }
+
+        grid->xdef   = 0;
+        grid->ydef   = 0;
+
+        break;
+      }
+    case GRID_SPECTRAL:
+      {
+        size_t len = 256;
+        char typeOfPacking[256];
+        FAIL_ON_GRIB_ERROR(grib_get_string, gh, "packingType", typeOfPacking, &len);
+        grid->lcomplex = 0;
+        if ( strncmp(typeOfPacking, "spectral_complex", len) == 0 ) grid->lcomplex = 1;
+
+        /* FIXME: assert(datasize >= INT_MIN && datasize <= INT_MAX) */
+        grid->size  = (int)datasize;
+        long lpar;
+        FAIL_ON_GRIB_ERROR(grib_get_long, gh, "J", &lpar);
+        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
+        grid->trunc = (int)lpar;
+
+        break;
+      }
+    case GRID_GME:
+      {
+        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
+        grid->size  = (int)numberOfPoints;
+        long lpar;
+        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
+        if ( grib_get_long(gh, "nd", &lpar) == 0 ) grid->nd  = (int)lpar;
+        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
+        if ( grib_get_long(gh, "Ni", &lpar) == 0 ) grid->ni  = (int)lpar;
+        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
+        if ( grib_get_long(gh, "n2", &lpar) == 0 ) grid->ni2 = (int)lpar;
+        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
+        if ( grib_get_long(gh, "n3", &lpar) == 0 ) grid->ni3 = (int)lpar;
+
+        break;
+      }
+    case GRID_UNSTRUCTURED:
+      {
+        unsigned char uuid[CDI_UUID_SIZE];
+        /*
+        char reference_link[8192];
+        size_t len = sizeof(reference_link);
+        reference_link[0] = 0;
+        */
+
+        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
+            grid->size  = (int)numberOfPoints;
+        long lpar;
+        if ( grib_get_long(gh, "numberOfGridUsed", &lpar) == 0 )
+          {
+            /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
+            grid->number   = (int)lpar;
+            /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
+            if ( grib_get_long(gh, "numberOfGridInReference", &lpar) == 0 )
+              grid->position = (int)lpar;
+            /*
+            if ( grib_get_string(gh, "gridDescriptionFile", reference_link, &len) == 0 )
+              {
+                if ( strncmp(reference_link, "file://", 7) == 0 )
+                  grid->reference = strdupx(reference_link);
+              }
+            */
+            size_t len = (size_t)CDI_UUID_SIZE;
+            if ( grib_get_bytes(gh, "uuidOfHGrid", uuid, &len) == 0)
+              {
+                memcpy(grid->uuid, uuid, CDI_UUID_SIZE);
+              }
+          }
+        break;
+      }
+    case GRID_GENERIC:
+      {
+        int nlon = 0, nlat = 0;
+        long lpar;
+        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
+        if ( grib_get_long(gh, "Ni", &lpar) == 0 ) nlon = (int)lpar;
+        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
+        if ( grib_get_long(gh, "Nj", &lpar) == 0 ) nlat = (int)lpar;
+
+        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
+        grid->size  = (int)numberOfPoints;
+
+        if ( nlon > 0 && nlat > 0 && nlon*nlat == grid->size )
+          {
+            grid->xsize = nlon;
+            grid->ysize = nlat;
+          }
+        else
+          {
+            grid->xsize = 0;
+            grid->ysize = 0;
+          }
+
+        break;
+      }
+    default:
+      {
+        Error("Unsupported grid type: %s", gridNamePtr(gridtype));
+        break;
+      }
+    }
+
+  grid->isRotated = FALSE;
+  if ( gribapiGetIsRotated(gh) )
+    {
+      grid->isRotated = TRUE;
+      FAIL_ON_GRIB_ERROR(grib_get_double, gh, "latitudeOfSouthernPoleInDegrees",  &grid->ypole);
+      FAIL_ON_GRIB_ERROR(grib_get_double, gh, "longitudeOfSouthernPoleInDegrees", &grid->xpole);
+      FAIL_ON_GRIB_ERROR(grib_get_double, gh, "angleOfRotation", &grid->angle);
+      /* change from south to north pole */
+      grid->ypole = -grid->ypole;
+      grid->xpole =  grid->xpole - 180;
+    }
+
+  grid->xvals = NULL;
+  grid->yvals = NULL;
+  grid->type  = gridtype;
+}
+#endif
diff --git a/src/gribapi_utilities.h b/src/gribapi_utilities.h
new file mode 100644
index 0000000000000000000000000000000000000000..6c7672372eb7ca6a2e5e7a276afd10befc896233
--- /dev/null
+++ b/src/gribapi_utilities.h
@@ -0,0 +1,37 @@
+#ifndef INCLUDE_GUARD_CDI_GRIBAPI_UTILITIES_H
+#define INCLUDE_GUARD_CDI_GRIBAPI_UTILITIES_H
+
+#ifdef HAVE_LIBGRIB_API
+
+#include "grid.h"
+
+#include <grib_api.h>
+
+#include <stdbool.h>
+
+char* gribCopyString(grib_handle* gribHandle, const char* key);
+bool gribCheckString(grib_handle* gribHandle, const char* key, const char* expectedValue);
+
+bool gribCheckLong(grib_handle* gribHandle, const char* key, long expectedValue);
+long gribGetLong(grib_handle* gh, const char* key);
+long gribGetLongDefault(grib_handle* gribHandle, const char* key, long defaultValue);
+
+double gribGetDouble(grib_handle* gh, const char* key);
+double gribGetDoubleDefault(grib_handle* gribHandle, const char* key, double defaultValue);
+
+size_t gribGetArraySize(grib_handle* gribHandle, const char* key);
+void gribGetDoubleArray(grib_handle* gribHandle, const char* key, double* array);       //The caller is responsible to ensure a sufficiently large buffer.
+void gribGetLongArray(grib_handle* gribHandle, const char* key, long* array);   //The caller is responsible to ensure a sufficiently large buffer.
+
+long gribEditionNumber(grib_handle* gh);
+char* gribMakeTimeString(grib_handle* gh, bool getEndTime);     //For statistical fields, setting getEndTime produces the time of the end of the integration period, otherwise the time of the start of the integration period is returned. Returns NULL if getEndTime is set and the field does not have an integration period.
+int gribapiTimeIsFC(grib_handle *gh);
+int gribapiGetTsteptype(grib_handle *gh);
+int gribGetDatatype(grib_handle* gribHandle);
+int gribapiGetParam(grib_handle *gh);
+int gribapiGetGridType(grib_handle *gh);
+void gribapiGetGrid(grib_handle *gh, grid_t *grid);
+
+#endif
+
+#endif
diff --git a/src/grid.h b/src/grid.h
index bde677d2256ffdf1a3f710102bafc8e6fa5f62b8..cd30879242624c5ee8eb7c443242c984a0f779d9 100644
--- a/src/grid.h
+++ b/src/grid.h
@@ -2,7 +2,9 @@
 #define _GRID_H
 
 #include "cdi.h"
+#ifndef RESOURCE_HANDLE_H
 #include "resource_handle.h"
+#endif
 
 typedef unsigned char mask_t;
 
diff --git a/src/input_file.c b/src/input_file.c
new file mode 100644
index 0000000000000000000000000000000000000000..5d1e36fcff160622b1483a0234dc8d0a0984205b
--- /dev/null
+++ b/src/input_file.c
@@ -0,0 +1,141 @@
+#include "input_file.h"
+
+#include "cdi.h"
+#include "dmemory.h"
+#include "proprietarySystemWorkarounds.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <string.h>
+#include <unistd.h>
+
+static void cdiInputFile_destruct(CdiInputFile* me);
+
+//For an explanation of the condestruct() pattern, see the comment in iterator_grib.c
+//path != NULL -> construction
+//path = NULL -> destruction
+static CdiInputFile* cdiInputFile_condestruct(CdiInputFile* me, const char* path)
+{
+  #define super() (&me->super)
+  if(!path) goto destruct;
+  cdiRefObject_construct(super());
+  me->path = myStrDup(path);
+  if(!me->path) goto destructSuper;
+  do
+    {
+      me->fileDescriptor = open(me->path, O_RDONLY);
+    }
+  while(me->fileDescriptor == -1 && (errno == EINTR || errno == EAGAIN));
+  if(me->fileDescriptor == -1) goto freePath;
+  //construction successfull, now we can set our own destructor
+  super()->destructor = (void(*)(CdiReferencedObject*))cdiInputFile_destruct;
+  goto success;
+
+// ^        constructor code       ^
+// |                               |
+// v destructor/error-cleanup code v
+
+destruct:
+  close(me->fileDescriptor);
+freePath:
+  free(me->path);
+destructSuper:
+  cdiRefObject_destruct(super());
+  me = NULL;
+
+success:
+  return me;
+  #undef super
+}
+
+static CdiInputFile** openFileList = NULL;
+static size_t openFileCount = 0, openFileListSize = 0;
+static pthread_mutex_t openFileListLock = PTHREAD_MUTEX_INITIALIZER;
+
+//This either returns a new object, or retains and returns a preexisting open file.
+CdiInputFile* cdiInputFile_make(const char* path)
+{
+  CdiInputFile* result = NULL;
+  xassert(path);
+  int error = pthread_mutex_lock(&openFileListLock);
+  xassert(!error);
+    {
+      //Check the list of open files for the given path.
+      for(size_t i = openFileCount; i-- && !result; )
+        {
+          if(!strcmp(path, openFileList[i]->path)) result = openFileList[i];
+        }
+      //If no open file was found, we open one, otherwise we just retain the existing one one more time.
+      if(result)
+        {
+          cdiRefObject_retain(&result->super);
+        }
+      else
+        {
+          result = xmalloc(sizeof(*result));
+          if(!cdiInputFile_condestruct(result, path))
+            {
+              //An error occured during construction, avoid a memory leak.
+              free(result);
+              result = NULL;
+            }
+          else
+            {
+              //Add the new file to the list of open files.
+              if(openFileCount == openFileListSize)
+                {
+                  openFileListSize *= 2;
+                  if(openFileListSize < 16) openFileListSize = 16;
+                  openFileList = xrealloc(openFileList, openFileListSize);
+                }
+              xassert(openFileCount < openFileListSize);
+              openFileList[openFileCount++] = result;
+            }
+        }
+    }
+  error = pthread_mutex_unlock(&openFileListLock);
+  xassert(!error);
+  return result;
+}
+
+int cdiInputFile_read(const CdiInputFile* me, off_t readPosition, size_t readSize, size_t* outActualReadSize, void* buffer)
+{
+  char* byteBuffer = buffer;
+  size_t trash;
+  if(!outActualReadSize) outActualReadSize = &trash;
+  *outActualReadSize = 0;
+  while(readSize)
+    {
+      ssize_t bytesRead = pread(me->fileDescriptor, byteBuffer, readSize, readPosition);
+      if(bytesRead == -1) return (errno == EINVAL) ?  CDI_EINVAL : CDI_ESYSTEM;
+      if(bytesRead == 0) return CDI_EEOF;
+      byteBuffer += bytesRead;
+      readPosition += bytesRead;
+      readSize -= bytesRead;
+      *outActualReadSize += bytesRead;
+    }
+  return CDI_NOERR;
+}
+
+char* cdiInputFile_copyPath(const CdiInputFile* me)
+{
+  return myStrDup(me->path);
+}
+
+void cdiInputFile_destruct(CdiInputFile* me)
+{
+  int error = pthread_mutex_lock(&openFileListLock);
+  xassert(!error);
+    {
+      //Find the position of me in the list of open files.
+      ssize_t position;
+      for(position = openFileCount; position--; ) if(openFileList[position] == me) break;
+      xassert(position != -1);
+      //Remove me from the list
+      openFileList[position] = openFileList[--openFileCount];
+    }
+  error = pthread_mutex_unlock(&openFileListLock);
+  xassert(!error);
+  cdiInputFile_condestruct(me, NULL);
+}
diff --git a/src/input_file.h b/src/input_file.h
new file mode 100644
index 0000000000000000000000000000000000000000..ab3c8d312e88baca0187968822983eeb3b0d71e9
--- /dev/null
+++ b/src/input_file.h
@@ -0,0 +1,27 @@
+#ifndef INCLUDE_GUARD_CDI_GRIB_FILE_H
+#define INCLUDE_GUARD_CDI_GRIB_FILE_H
+
+#include "referenceCounting.h"
+
+/*
+CdiInputFile is a file abstraction that allows accessing an input file through any number of channels:
+It is reference counted, so that it is closed at the right place,
+and it is stateless, so that accesses from different callers cannot interfere with each other.
+Once the reference counting code is threadsafe, CdiInputFile will also be threadsafe.
+*/
+typedef struct CdiInputFile {
+  //public:
+    CdiReferencedObject super;
+
+  //private:
+    char* path;
+    int fileDescriptor;
+} CdiInputFile;
+
+//Final class, the constructor is private and not defined here.
+CdiInputFile* cdiInputFile_make(const char* path);   //The caller is responsible to call cdiRefObject_release() on the returned object.
+int cdiInputFile_read(const CdiInputFile* me, off_t readPosition, size_t readSize, size_t* outActualReadSize, void* buffer);       //Returns one of CDI_EINVAL, CDI_ESYSTEM, CDI_EEOF, OR CDI_NOERR.
+char* cdiInputFile_copyPath(const CdiInputFile* me);    //Returns a malloc'ed string, don't forget to free() it.
+//Destructor is private as well.
+
+#endif
diff --git a/src/institution.c b/src/institution.c
index 081ac84191feb3c73231d27166b7746514003481..b4cdadb4b475e14bceba7d3694f3dd9818b14e0f 100644
--- a/src/institution.c
+++ b/src/institution.c
@@ -232,7 +232,7 @@ const char *institutInqNamePtr(int instID)
 }
 
 
-char *institutInqLongnamePtr(int instID)
+const char *institutInqLongnamePtr(int instID)
 {
   institute_t * instituteptr = NULL;
 
diff --git a/src/iterator.c b/src/iterator.c
new file mode 100644
index 0000000000000000000000000000000000000000..6e398a6077bfa96d16096d65afb722276c6e9a6d
--- /dev/null
+++ b/src/iterator.c
@@ -0,0 +1,958 @@
+#include "cdi.h"
+#include "iterator.h"
+#include "iterator_fallback.h"
+#include "iterator_grib.h"
+#include "cdi_int.h"
+#include "proprietarySystemWorkarounds.h"
+
+#include <assert.h>
+#include <ctype.h>
+
+const char* const kUnexpectedFileTypeMessage = "Internal error: Unexpected file type encountered in iterator.\nThis is either due to an illegal memory access by the application or an internal logical error in CDI (unlikely, but possible).";
+const char* const kAdvancedString = "advanced";
+const char* const kUnadvancedString = "unadvanced";
+
+//Returns a static string.
+static const char* fileType2String(int fileType)
+{
+  switch(fileType)
+    {
+      #ifdef HAVE_LIBGRIB
+        case FILETYPE_GRB: return "CDI::Iterator::GRIB1";
+        case FILETYPE_GRB2: return "CDI::Iterator::GRIB2";
+      #endif
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC: return "CDI::Iterator::NetCDF";
+        case FILETYPE_NC2: return "CDI::Iterator::NetCDF2";
+        case FILETYPE_NC4: return "CDI::Iterator::NetCDF4";
+        case FILETYPE_NC4C: return "CDI::Iterator::NetCDF4C";
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV: return "CDI::Iterator::SRV";
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT: return "CDI::Iterator::EXT";
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG: return "CDI::Iterator::IEG";
+      #endif
+
+      default: return NULL;
+    }
+}
+
+static int string2FileType(const char* fileType, const char** outRestString)
+{
+  //This first part unconditionally checks all known type strings, and only if the given string matches one of these strings, we use fileType2string() to check whether support for this type has been compiled in. This is to avoid throwing "invalid type string" errors when we just have a library version mismatch.
+  #define check(givenString, typeString, typeConstant) do \
+    { \
+      if(givenString == strstr(givenString, typeString)) \
+        { \
+          if(outRestString) *outRestString = givenString + strlen(typeString); \
+          if(fileType2String(typeConstant)) return typeConstant; \
+          Error("Support for " typeString " not compiled in. Please check that the result of `cdiIterator_serialize()` is only passed to a `cdiIterator_deserialize()` implementation of the same CDI library version."); \
+          return FILETYPE_UNDEF; \
+        } \
+    } while(0)
+  check(fileType, "CDI::Iterator::GRIB1", FILETYPE_GRB);
+  check(fileType, "CDI::Iterator::GRIB2", FILETYPE_GRB2);
+  check(fileType, "CDI::Iterator::NetCDF", FILETYPE_NC);
+  check(fileType, "CDI::Iterator::NetCDF2", FILETYPE_NC2);
+  check(fileType, "CDI::Iterator::NetCDF4", FILETYPE_NC4);
+  check(fileType, "CDI::Iterator::NetCDF4C", FILETYPE_NC4C);
+  check(fileType, "CDI::Iterator::SRV", FILETYPE_SRV);
+  check(fileType, "CDI::Iterator::EXT", FILETYPE_EXT);
+  check(fileType, "CDI::Iterator::IEG", FILETYPE_IEG);
+  #undef check
+
+  //If this point is reached, the given string does not seem to be produced by a cdiIterator_serialize() call.
+  Error("The string \"%s\" does not start with a valid iterator type. Please check the source of this string.", fileType);
+  *outRestString = fileType;
+  return FILETYPE_UNDEF;
+}
+
+/**
+@Function cdiIterator_new
+@Title Create an iterator for an input file
+
+@Prototype CdiIterator* cdiIterator_new(const char* path)
+@Parameter
+    @item path Path to the file that is to be read.
+
+@Result An iterator for the given file.
+
+@Description
+    Combined allocator and constructor for CdiIterator.
+
+    The returned iterator does not point to the first field yet,
+    it must first be advanced once before the first field can be introspected.
+    This design decision has two benefits: 1. Empty files require no special cases, 2. Users can start a while(!cdiIterator_nextField(iterator)) loop right after the call to cdiIterator_new().
+*/
+CdiIterator* cdiIterator_new(const char* path)
+{
+  int trash;
+  int filetype = cdiGetFiletype(path, &trash);
+  switch(filetype)
+    {
+      case FILETYPE_UNDEF:
+        Warning("Can't open file \"%s\": unknown format\n", path);
+        return NULL;
+
+      #ifdef HAVE_LIBGRIB
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return cdiGribIterator_new(path, filetype);
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return cdiFallbackIterator_new(path, filetype);
+
+      default:
+        Warning("the file \"%s\" is of type %s, but support for this format is not compiled in!", path, strfiletype(filetype));
+        return NULL;
+    }
+}
+
+void baseIterConstruct(CdiIterator* me, int filetype)
+{
+  me->filetype = filetype;
+  me->isAdvanced = false;
+}
+
+const char* baseIter_constructFromString(CdiIterator* me, const char* description)
+{
+  const char* result = description;
+  me->filetype = string2FileType(result, &result);
+  assert(me->filetype != FILETYPE_UNDEF && "Please report this error.");        //This condition should have been checked for in a calling function.
+  for(; *result && isspace(*result); result++);
+  if(result == strstr(result, kAdvancedString))
+    {
+      me->isAdvanced = true;
+      result += strlen(kAdvancedString);
+    }
+  else if(result == strstr(result, kUnadvancedString))
+    {
+      me->isAdvanced = false;
+      result += strlen(kUnadvancedString);
+    }
+  else
+    {
+      Error("Invalid iterator description string \"%s\". Please check the origin of this string.", description);
+      return NULL;
+    }
+  return result;
+}
+
+#define sanityCheck(me) do { \
+    if(!me) xabort("NULL was passed to %s as an iterator. Please check the return value of cdiIterator_new().", __func__); \
+    if(!me->isAdvanced) xabort("Calling %s is not allowed without calling cdiIterator_nextField() first.", __func__); \
+} while(0)
+
+/**
+@Function cdiIterator_clone
+@Title Make a copy of an iterator
+
+@Prototype CdiIterator* cdiIterator_clone(CdiIterator* me)
+@Parameter
+    @item iterator The iterator to copy.
+
+@Result The clone.
+
+@Description
+    Clones the given iterator. Make sure to call cdiIterator_delete() on both the copy and the original.
+
+    This is not a cheap operation: Depending on the type of the file, it will either make a copy of the current field in memory (GRIB files), or reopen the file (all other file types). Use it sparingly. And if you do, try to avoid keeping too many clones around: their memory footprint is significant.
+*/
+CdiIterator* cdiIterator_clone(CdiIterator* me)
+{
+  sanityCheck(me);
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return &cdiGribIterator_clone(me)->super;
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return &cdiFallbackIterator_clone(me)->super;
+
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return NULL;
+    }
+}
+
+/**
+@Function cdiGribIterator_clone
+@Title Gain access to GRIB specific functionality
+
+@Prototype CdiGribIterator* cdiGribIterator_clone(CdiIterator* me)
+@Parameter
+    @item iterator The iterator to operate on.
+
+@Result A clone that allows access to GRIB specific functionality, or NULL if the underlying file is not a GRIB file.
+
+@Description
+    Clones the given iterator iff the underlying file is a GRIB file, the returned iterator allows access to GRIB specific functionality.
+    Make sure to check that the return value is not NULL, and to call cdiGribIterator_delete() on the copy.
+
+    This is not a cheap operation: It will make a copy of the current field in memory. Use it sparingly. And if you do, try to avoid keeping too many clones around, their memory footprint is significant.
+*/
+CdiGribIterator* cdiGribIterator_clone(CdiIterator* me)
+{
+  sanityCheck(me);
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return cdiGribIterator_makeClone(me);
+      #endif
+
+      default:
+        return NULL;
+    }
+}
+
+/**
+@Function cdiIterator_serialize
+@Title Serialize an iterator for sending it to another process
+
+@Prototype char* cdiIterator_serialize(CdiIterator* me)
+@Parameter
+    @item iterator The iterator to operate on.
+
+@Result A malloc'ed string that contains the full description of the iterator.
+
+@Description
+    Make sure to call free() on the resulting string.
+*/
+char* cdiIterator_serialize(CdiIterator* me)
+{
+  if(!me) xabort("NULL was passed to %s as an iterator. Please check the return value of cdiIterator_new().", __func__); \
+  char* subclassDescription = NULL;
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          subclassDescription = cdiGribIterator_serialize(me);
+          break;
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          subclassDescription = cdiFallbackIterator_serialize(me);
+          break;
+
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return NULL;
+    }
+
+  char* result = myAsprintf("%s %s %s", fileType2String(me->filetype), (me->isAdvanced ? kAdvancedString : kUnadvancedString), subclassDescription);
+  free(subclassDescription);
+  return result;
+}
+
+/**
+@Function cdiIterator_deserialize
+@Title Recreate an iterator from its textual description
+
+@Prototype CdiIterator* cdiIterator_deserialize(const char* description)
+@Parameter
+    @item description The result of a call to cdiIterator_serialize().
+
+@Result A clone of the original iterator.
+
+@Description
+    A pair of cdiIterator_serialize() and cdiIterator_deserialize() is functionally equivalent to a call to cdiIterator_clone()
+
+    This function will reread the current field from disk, so don't expect immediate return.
+*/
+//This only checks the type of the iterator and calls the corresponding subclass function,
+//the real deserialization is done in baseIter_constructFromString().
+CdiIterator* cdiIterator_deserialize(const char* description)
+{
+  switch(string2FileType(description, NULL))
+    {
+      #ifdef HAVE_LIBGRIB
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return &cdiGribIterator_deserialize(description)->super;
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return &cdiFallbackIterator_deserialize(description)->super;
+
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return NULL;
+    }
+}
+
+
+/**
+@Function cdiIterator_print
+@Title Print a textual description of the iterator to a stream
+
+@Prototype void cdiIterator_print(CdiIterator* iterator, FILE* stream);
+@Parameter
+    @item iterator The iterator to print.
+    @item stream The stream to print to.
+
+@Description
+    Use for debugging output.
+*/
+void cdiIterator_print(CdiIterator* me, FILE* stream)
+{
+  char* description = cdiIterator_serialize(me);
+  fprintf(stream, "%s\n", description);
+  free(description);
+}
+
+
+/**
+@Function cdiIterator_nextField
+@Title Advance an iterator to the next field in the file
+
+@Prototype int cdiIterator_nextField(CdiIterator* iterator)
+@Parameter
+    @item iterator The iterator to operate on.
+
+@Result An error code. May be one of:
+  * CDI_NOERR: The iterator has successfully been advanced to the next field.
+  * CDI_EEOF: No more fields to read in this file.
+
+@Description
+    One call to cdiIterator_nextField() is required before the metadata of the first field can be examined.
+    Usually, it will be used directly as the condition for a while() loop.
+*/
+int cdiIterator_nextField(CdiIterator* me)
+{
+  if(!me) xabort("NULL was passed in as an iterator. Please check the return value of cdiIterator_new().");
+  me->isAdvanced = true;
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return cdiGribIterator_nextField(me);
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return cdiFallbackIterator_nextField(me);
+
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return CDI_EINVAL;
+    }
+}
+
+static char* cdiIterator_inqTime(CdiIterator* me, bool getEndTime)
+{
+  sanityCheck(me);
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return cdiGribIterator_inqTime(me, getEndTime);
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return cdiFallbackIterator_inqTime(me, getEndTime);
+
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return NULL;
+    }
+}
+
+/**
+@Function cdiIterator_inqStartTime
+@Title Get the start time of a measurement
+
+@Prototype char* cdiIterator_inqStartTime(CdiIterator* me)
+@Parameter
+    @item iterator The iterator to operate on.
+
+@Result A malloc'ed string containing the (start) time of the current field in the format "YYYY-MM-DDTHH:MM:SS.mmm".
+
+@Description
+The returned time is either the time of the data (fields defined at a time point),
+or the start time of an integration time range (statistical fields).
+
+Converts the time to the ISO-8601 format and returns it in a newly allocated buffer.
+The caller is responsible to free() the resulting string.
+
+If the file is a GRIB file, the calendar that is used to resolve the relative times is the proleptic calendar
+as it is implemented by the standard C mktime() function.
+This is due to the fact that GRIB-API version 1.12.3 still does not implement the calendar identification fields.
+*/
+char* cdiIterator_inqStartTime(CdiIterator* me)
+{
+  return cdiIterator_inqTime(me, false);
+}
+
+/**
+@Function cdiIterator_inqEndTime
+@Title Get the end time of a measurement
+
+@Prototype char* cdiIterator_inqEndTime(CdiIterator* me)
+@Parameter
+    @item iterator The iterator to operate on.
+
+@Result A malloc'ed string containing the end time of the current field in the format "YYYY-MM-DDTHH:MM:SS.mmm", or NULL if no such time is defined.
+
+@Description
+The returned time is the end time of an integration period if such a time exists (statistical fields).
+Otherwise, NULL is returned.
+
+Converts the time to the ISO-8601 format and returns it in a newly allocated buffer.
+The caller is responsible to free() the resulting string.
+
+If the file is a GRIB file, the calendar that is used to resolve the relative times is the proleptic calendar
+as it is implemented by the standard C mktime() function.
+This is due to the fact that GRIB-API version 1.12.3 still does not implement the calendar identification fields.
+*/
+char* cdiIterator_inqEndTime(CdiIterator* me)
+{
+  return cdiIterator_inqTime(me, true);
+}
+
+/**
+@Function cdiIterator_inqVTime
+@Title Get the validity time of the current field
+
+@Prototype char* cdiIterator_inqVTime(CdiIterator* me)
+@Parameter
+    @item iterator The iterator to operate on.
+
+@Result A malloc'ed string containing the validity time of the current field in the format "YYYY-MM-DDTHH:MM:SS.mmm".
+
+@Description
+The returned time is the validity time as it is returned by taxisInqVtime(), only more precise.
+That is, if the field is a time point, its time is returned,
+if it is a statistical field with an integration period, the end time of the integration period is returned.
+
+Converts the time to the ISO-8601 format and returns it in a newly allocated buffer.
+The caller is responsible to free() the resulting string.
+
+If the file is a GRIB file, the calendar that is used to resolve the relative times is the proleptic calendar
+as it is implemented by the standard C mktime() function.
+This is due to the fact that GRIB-API version 1.12.3 still does not implement the calendar identification fields.
+*/
+char* cdiIterator_inqVTime(CdiIterator* me)
+{
+  char* result = cdiIterator_inqEndTime(me);
+  return (result) ? result : cdiIterator_inqStartTime(me);
+}
+
+/**
+@Function cdiIterator_inqLevelType
+@Title Get the type of a level
+
+@Prototype int cdiIterator_inqLevelType(CdiIterator* me, int levelSelector, char** outName = NULL, char** outLongName = NULL, char** outStdName = NULL, char** outUnit = NULL)
+@Parameter
+    @item iterator The iterator to operate on.
+    @item levelSelector Zero for the top level, one for the bottom level
+    @item outName Will be set to a malloc()'ed string with the name of the level if not NULL.
+    @item outLongName Will be set to a malloc()'ed string with the long name of the level if not NULL.
+    @item outStdName Will be set to a malloc()'ed string with the standard name of the level if not NULL.
+    @item outUnit Will be set to a malloc()'ed string with the unit of the level if not NULL.
+
+@Result An integer indicating the type of the level.
+
+@Description
+Find out some basic information about the given level, the levelSelector selects the function of the requested level.
+If the requested level does not exist, this returns CDI_UNDEFID.
+*/
+int cdiIterator_inqLevelType(CdiIterator* me, int levelSelector, char** outName, char** outLongName, char** outStdName, char** outUnit)
+{
+  sanityCheck(me);
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return cdiGribIterator_levelType(me, levelSelector, outName, outLongName, outStdName, outUnit);
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return cdiFallbackIterator_levelType(me, levelSelector, outName, outLongName, outStdName, outUnit);
+
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return CDI_UNDEFID;
+    }
+}
+
+/**
+@Function cdiIterator_inqLevel
+@Title Get the value of the z-coordinate
+
+@Prototype void cdiIterator_inqLevel(CdiIterator* me, int levelSelector, double* outValue1, double* outValue2 = NULL)
+@Parameter
+    @item iterator The iterator to operate on.
+    @item levelSelector Zero for the top level, one for the bottom level
+    @item outValue1 For "normal" levels this returns the value, for hybrid levels the first coordinate, for generalized levels the level number.
+    @item outValue2 Zero for "normal" levels, for hybrid levels, this returns the second coordinate, for generalized levels the level count.
+
+@Result An error code.
+
+@Description
+Returns the value of the z-coordinate, whatever that may be.
+*/
+int cdiIterator_inqLevel(CdiIterator* me, int levelSelector, double* outValue1, double* outValue2)
+{
+  sanityCheck(me);
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return cdiGribIterator_level(me, levelSelector, outValue1, outValue2);
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return cdiFallbackIterator_level(me, levelSelector, outValue1, outValue2);
+
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return CDI_EINVAL;
+    }
+}
+
+/**
+@Function cdiIterator_inqLevelUuid
+@Title Get the UUID of the z-axis used by this field
+
+@Prototype int cdiIterator_inqLevelUuid(CdiIterator* me, int levelSelector, unsigned char (*outUuid)[16])
+@Parameter
+    @item iterator The iterator to operate on.
+    @item outVgridNumber The number of the associated vertical grid description.
+    @item outLevelCount The number of levels in the associated vertical grid description.
+    @item outUuid A pointer to a user supplied buffer of 16 bytes to store the UUID in.
+
+@Result An error code.
+
+@Description
+Returns identifying information for the external z-axis description. May only be called for generalized levels.
+*/
+int cdiIterator_inqLevelUuid(CdiIterator* me, int* outVgridNumber, int* outLevelCount, unsigned char (*outUuid)[16])
+{
+  sanityCheck(me);
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return cdiGribIterator_zaxisUuid(me, outVgridNumber, outLevelCount, outUuid);
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return cdiFallbackIterator_zaxisUuid(me, outVgridNumber, outLevelCount, outUuid);
+
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return CDI_ELIBNAVAIL;
+    }
+}
+
+/**
+@Function cdiIterator_inqParam
+@Title Get discipline, category, and number
+
+@Prototype CdiParam cdiIterator_inqParam(CdiIterator* iterator)
+@Parameter
+    @item iterator The iterator to operate on.
+
+@Result A struct containing the requested information.
+
+@Description
+    Simple metadata inspection function.
+*/
+CdiParam cdiIterator_inqParam(CdiIterator* me)
+{
+  sanityCheck(me);
+  return me->param;
+}
+
+/**
+@Function cdiIterator_inqDatatype
+@Title Get the datatype of the current field
+
+@Prototype int cdiIterator_inqDatatype(CdiIterator* iterator)
+@Parameter
+    @item iterator The iterator to operate on.
+
+@Result The datatype that is used to store this field on disk.
+
+@Description
+    Simple metadata inspection function.
+*/
+int cdiIterator_inqDatatype(CdiIterator* me)
+{
+  sanityCheck(me);
+  return me->datatype;
+}
+
+/**
+@Function cdiIterator_inqTsteptype
+@Title Get the timestep type
+
+@Prototype int cdiIterator_inqTsteptype(CdiIterator* iterator)
+@Parameter
+    @item iterator The iterator to operate on.
+
+@Result The timestep type.
+
+@Description
+    Simple metadata inspection function.
+*/
+int cdiIterator_inqTsteptype(CdiIterator* me)
+{
+  sanityCheck(me);
+  return me->timesteptype;
+}
+
+/**
+@Function cdiIterator_inqVariableName
+@Title Get the variable name of the current field
+
+@Prototype char* cdiIterator_inqVariableName(CdiIterator* iterator)
+@Parameter
+    @item iterator The iterator to operate on.
+
+@Result A pointer to a C-string containing the name. The storage for this string is allocated with malloc(), and it is the responsibility of the caller to free() it.
+
+@Description
+    Allocates a buffer to hold the string, copies the current variable name into this buffer, and returns the buffer.
+    The caller is responsible to make the corresponding free() call.
+*/
+char* cdiIterator_inqVariableName(CdiIterator* me)
+{
+  sanityCheck(me);
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          return cdiGribIterator_copyVariableName(me);
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          return cdiFallbackIterator_copyVariableName(me);
+
+      default:
+        Error(kUnexpectedFileTypeMessage);
+        return NULL;
+    }
+}
+
+/**
+@Function cdiIterator_inqGridId
+@Title Get the ID of the current grid
+
+@Prototype int cdiIterator_inqGridId(CdiIterator* iterator)
+@Parameter
+    @item iterator The iterator to operate on.
+
+@Result A gridId that can be used for further introspection.
+
+@Description
+    This provides access to the grid related metadata.
+    The resulting ID is only valid until the next time cdiIterator_nextField() is called.
+*/
+int cdiIterator_inqGridId(CdiIterator* me)
+{
+  sanityCheck(me);
+  return me->gridId;
+}
+
+/**
+@Function cdiIterator_readField
+@Title Read the whole field into a double buffer
+
+@Prototype void cdiIterator_readField(CdiIterator* me, double* buffer, size_t* nmiss)
+@Parameter
+    @item iterator The iterator to operate on.
+    @item buffer A pointer to the double array that the data should be written to.
+    @item nmiss A pointer to a variable where the count of missing values will be stored. May be NULL.
+
+@Description
+    It is assumed that the caller first analyses the return value of cdiIterator_inqGridId to determine the required size of the buffer.
+    Failing to do so results in undefined behavior. You have been warned.
+*/
+void cdiIterator_readField(CdiIterator* me, double* buffer, size_t* nmiss)
+{
+  sanityCheck(me);
+  if(!buffer) xabort("NULL was passed in a buffer. Please provide a suitable buffer.");
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          cdiGribIterator_readField(me, buffer, nmiss);
+	  return;
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          cdiFallbackIterator_readField(me, buffer, nmiss);
+          return;
+      default:
+        Error(kUnexpectedFileTypeMessage);
+    }
+}
+
+/**
+@Function cdiIterator_readFieldF
+@Title Read the whole field into a double buffer
+
+@Prototype void cdiIterator_readFieldF(CdiIterator* me, float* buffer, size_t* nmiss)
+@Parameter
+    @item iterator The iterator to operate on.
+    @item buffer A pointer to the double array that the data should be written to.
+    @item nmiss A pointer to a variable where the count of missing values will be stored. May be NULL.
+
+@Description
+    It is assumed that the caller first analyses the return value of cdiIterator_inqGridId to determine the required size of the buffer.
+    Failing to do so results in undefined behavior. You have been warned.
+*/
+void cdiIterator_readFieldF(CdiIterator* me, float* buffer, size_t* nmiss)
+{
+  sanityCheck(me);
+  if(!buffer) xabort("NULL was passed in a buffer. Please provide a suitable buffer.");
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          cdiGribIterator_readFieldF(me, buffer, nmiss);
+	  return;
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          cdiFallbackIterator_readFieldF(me, buffer, nmiss);
+          return; 
+      default:
+        Error(kUnexpectedFileTypeMessage);
+    }
+}
+
+/**
+@Function cdiIterator_delete
+@Title Destroy an iterator
+
+@Prototype void cdiIterator_delete(CdiIterator* iterator)
+@Parameter
+    @item iterator The iterator to operate on.
+
+@Description
+    Combined destructor & deallocator.
+*/
+void cdiIterator_delete(CdiIterator* me)
+{
+  if(!me) xabort("NULL was passed in as an iterator. Please check the return value of cdiIterator_new().");
+  switch(me->filetype)
+    {
+      #ifdef HAVE_LIBGRIB
+        case FILETYPE_GRB:
+        case FILETYPE_GRB2:
+          cdiGribIterator_delete((CdiGribIterator*)me);
+          break;
+      #endif
+
+      #ifdef HAVE_LIBNETCDF
+        case FILETYPE_NC:
+        case FILETYPE_NC2:
+        case FILETYPE_NC4:
+        case FILETYPE_NC4C:
+      #endif
+      #ifdef HAVE_LIBSERVICE
+        case FILETYPE_SRV:
+      #endif
+      #ifdef HAVE_LIBEXTRA
+        case FILETYPE_EXT:
+      #endif
+      #ifdef HAVE_LIBIEG
+        case FILETYPE_IEG:
+      #endif
+          cdiFallbackIterator_delete(me);
+          break;
+
+      default:
+        Error(kUnexpectedFileTypeMessage);
+    }
+}
+
+void baseIterDestruct(CdiIterator* me) { /*currently empty, but that's no reason not to call it*/ }
diff --git a/src/iterator.h b/src/iterator.h
new file mode 100644
index 0000000000000000000000000000000000000000..a65ef37dccbb916c20a24d70cc9ce92771623648
--- /dev/null
+++ b/src/iterator.h
@@ -0,0 +1,48 @@
+/*
+ * This file is for the use of iterator.c and the CdiIterator subclasses only.
+ */
+
+#ifndef INCLUDE_GUARD_CDI_ITERATOR_INT_H
+#define INCLUDE_GUARD_CDI_ITERATOR_INT_H
+
+#include "cdi.h"
+
+#include <stdbool.h>
+
+/*
+class CdiIterator
+
+An iterator is an object that identifies the position of one record in a file, where a record is defined as the data belonging to one level, timestep, and variable.
+Using iterators to read a file can be significantly faster than using streams, because they can avoid building an index of the file.
+For file formats like grib that do not provide an index within the file, this makes the difference between reading the file once or reading the file twice.
+
+CdiIterator is an abstract base class. Which derived class is used depends on the type of the file. The class hierarchy currently looks like this:
+
+    CdiIterator <|--+-- CdiFallbackIterator
+                    |
+                    +-- CdiGribIterator
+
+The fallback implementation currently uses the stream interface of CDI under the hood to provide full functionality for all filetypes for which no iterator implementation exists yet.
+*/
+//TODO[NH]: Debug messages, print function.
+
+struct CdiIterator {
+  int filetype;      //This is used to dispatch calls to the correct subclass.
+  bool isAdvanced;    //Used to catch inquiries before the first call to CdiIteratorNextField(). //XXX: Advanced is probably not a good word (initialized?)
+
+  //The metadata that can be accessed by the inquiry calls.
+  //While theoretically redundant, these fields allow the handling of most inquiry calls within the base class.
+  //Only the name is excempted because it needs an allocation.
+  //These fields are set by the subclasses in the xxxIterNextField() method.
+  int datatype, timesteptype;
+  int gridId;
+  CdiParam param;
+
+  //The status information for reading/advancing is added in the subclasses.
+};
+
+void baseIterConstruct(CdiIterator* me, int filetype);
+const char* baseIter_constructFromString(CdiIterator* me, const char* description);     //Returns a pointer past the end of the parsed portion of the description string.
+void baseIterDestruct(CdiIterator* me);
+
+#endif
diff --git a/src/iterator_fallback.c b/src/iterator_fallback.c
new file mode 100644
index 0000000000000000000000000000000000000000..be0b6cfba9e928334783ae390595b5df92a35483
--- /dev/null
+++ b/src/iterator_fallback.c
@@ -0,0 +1,285 @@
+#include "iterator_fallback.h"
+
+#include "cdi.h"
+#include "cdi_int.h"
+#include "dmemory.h"
+#include "proprietarySystemWorkarounds.h"
+#include "vlist.h"      //Required for vlist_t, which we require because there is no safe function available to access a variable name.
+
+#include <assert.h>
+#include <stdlib.h>
+
+//For more information on the condestruct() pattern, see comment in src/iterator_grib.c
+static CdiFallbackIterator* cdiFallbackIterator_condestruct(CdiFallbackIterator* me, const char* path, int filetype)
+{
+  if(me) goto destruct;
+
+  me = xmalloc(sizeof(*me));
+  baseIterConstruct(&me->super, filetype);
+
+  me->streamId = streamOpenRead(path);
+  if(me->streamId == CDI_UNDEFID) goto destructSuper;
+  me->vlistId = streamInqVlist(me->streamId);
+  if(me->vlistId == CDI_UNDEFID) goto closeStream;
+  me->variableCount = vlistNvars(me->vlistId);
+  if(me->variableCount <= 0) goto closeStream;
+  me->curLevelCount = -1;        //Will be set in cdiFallbackIterator_nextField()
+
+  //These values are chosen so that the natural increment at the start of cdiFallbackIterator_nextField() will correctly position us at the first slice.
+  me->curTimestep = 0;
+  if(streamInqTimestep(me->streamId, me->curTimestep) <= 0) goto closeStream;
+  me->curVariable = 0;
+  me->curLevel = -1;
+  me->path = myStrDup(path);
+  if(!me->path) goto closeStream;
+
+  return me;
+
+// ^        constructor code        ^
+// |                                |
+// v destructor/error-cleanup code  v
+
+destruct:
+  free(me->path);
+closeStream:
+  streamClose(me->streamId);
+destructSuper:
+  baseIterDestruct(&me->super);
+  free(me);
+  return NULL;
+}
+
+CdiIterator* cdiFallbackIterator_new(const char* path, int filetype)
+{
+  return &cdiFallbackIterator_condestruct(NULL, path, filetype)->super;
+}
+
+//Fetches the info that is published by the variables in the base class from the current field.
+static void fetchSuperInfo(CdiFallbackIterator* me)
+{
+  me->super.datatype = vlistInqVarDatatype(me->vlistId, me->curVariable);
+  me->super.timesteptype = vlistInqVarTsteptype(me->vlistId, me->curVariable);
+  me->super.gridId = vlistInqVarGrid(me->vlistId, me->curVariable);
+  int param = vlistInqVarParam(me->vlistId, me->curVariable);
+  cdiDecodeParam(param, &me->super.param.number, &me->super.param.category, &me->super.param.discipline);
+}
+
+CdiFallbackIterator* cdiFallbackIterator_clone(CdiIterator* super)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+
+  //Make another stream for this file. This yields an unadvanced iterator.
+  CdiFallbackIterator* clone = cdiFallbackIterator_condestruct(NULL, me->path, me->super.filetype);
+  if(!clone) return NULL;
+
+  //Point the clone to the same position in the file.
+  clone->variableCount = me->variableCount;
+  clone->curVariable = me->curVariable;
+  clone->curLevelCount = me->curLevelCount;
+  clone->curLevel = me->curLevel;
+  clone->curTimestep = me->curTimestep;
+
+  clone->super.isAdvanced = super->isAdvanced;
+  if(super->isAdvanced) fetchSuperInfo(clone);
+
+  return clone;
+}
+
+char* cdiFallbackIterator_serialize(CdiIterator* super)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+
+  char* escapedPath = cdiEscapeSpaces(me->path);
+  char* result = myAsprintf("%s %d %d %d %d %d", escapedPath, me->variableCount, me->curVariable, me->curLevelCount, me->curLevel, me->curTimestep);
+  free(escapedPath);
+  return result;
+}
+
+CdiFallbackIterator* cdiFallbackIterator_deserialize(const char* description)
+{
+  CdiFallbackIterator* me = xmalloc(sizeof(*me));
+  if(!me) goto fail;
+
+  description = baseIter_constructFromString(&me->super, description);
+
+  while(*description == ' ') description++;
+  me->path = cdiUnescapeSpaces(description, &description);
+  if(!me->path) goto destructSuper;
+
+  me->streamId = streamOpenRead(me->path);
+  if(me->streamId == CDI_UNDEFID) goto freePath;
+  me->vlistId = streamInqVlist(me->streamId);
+  if(me->vlistId == CDI_UNDEFID) goto closeStream;
+
+  //This reads one variable from the description string, does error checking, and advances the given string pointer.
+  #define decodeValue(variable, description) do \
+    { \
+      const char* savedStart = description; \
+      long long decodedValue = strtoll(description, (char**)&description, 0);   /*The cast is a workaround for the wrong signature of strtoll().*/ \
+      variable = (int)decodedValue; \
+      if(savedStart == description) goto closeStream; \
+      if((long long)decodedValue != (long long)variable) goto closeStream; \
+    } while(0)
+  decodeValue(me->variableCount, description);
+  decodeValue(me->curVariable, description);
+  decodeValue(me->curLevelCount, description);
+  decodeValue(me->curLevel, description);
+  decodeValue(me->curTimestep, description);
+  #undef decodeValue
+
+  if(streamInqTimestep(me->streamId, me->curTimestep) <= 0) goto closeStream;
+  if(me->super.isAdvanced) fetchSuperInfo(me);
+
+  return me;
+
+closeStream:
+  streamClose(me->streamId);
+freePath:
+  free(me->path);
+destructSuper:
+  baseIterDestruct(&me->super);
+  free(me);
+fail:
+  return NULL;
+}
+
+static int advance(CdiFallbackIterator* me)
+{
+  me->curLevel++;
+  if(me->curLevel == me->curLevelCount)
+    {
+      me->curLevel = 0;
+      me->curVariable++;
+      if(me->curVariable == me->variableCount)
+        {
+          me->curVariable = 0;
+          me->curTimestep++;
+          if(streamInqTimestep(me->streamId, me->curTimestep) <= 0) return CDI_EEOF;
+        }
+    }
+  return CDI_NOERR;
+}
+
+int cdiFallbackIterator_nextField(CdiIterator* super)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  int result = advance(me);
+  if(result) return result;
+
+  if(!me->curLevel)
+    { //Fetch the information that may have changed (we are processing a new variable/timestep if this point is reached).
+      fetchSuperInfo(me);
+      me->curLevelCount = zaxisInqSize(vlistInqVarZaxis(me->vlistId, me->curVariable));
+    }
+  return CDI_NOERR;
+}
+
+char* cdiFallbackIterator_inqTime(CdiIterator* super, bool getEndTime)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  if(getEndTime) return NULL;   //The stream interface does not export the start/end times of statistical fields, so we treat all data as point of time data, returning the validity time as the start time.
+  int taxisId = vlistInqTaxis(me->vlistId);
+  int date = taxisInqVdate(taxisId);
+  int time = taxisInqVtime(taxisId);
+  int year, month, day, hour, minute, second;
+  cdiDecodeDate(date, &year, &month, &day);
+  cdiDecodeTime(time, &hour, &minute, &second);
+  return myAsprintf("%04d-%02d-%02dT%02d:%02d:%02d.000", year, month, day, hour, minute, second);
+}
+
+int cdiFallbackIterator_levelType(CdiIterator* super, int levelSelector, char** outName, char** outLongName, char** outStdName, char** outUnit)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  int zaxisId = vlistInqVarZaxis(me->vlistId, me->curVariable);
+  #define copyString(outPointer, function) do \
+    { \
+      if(outPointer) \
+        { \
+          char tempBuffer[CDI_MAX_NAME]; \
+          function(zaxisId, tempBuffer); \
+          *outPointer = myStrDup(tempBuffer); \
+        } \
+    } \
+  while(0)
+  copyString(outName, zaxisInqName);    //FIXME: zaxisInqName is unsafe.
+  copyString(outLongName, zaxisInqLongname);    //FIXME: zaxisInqLongname is unsafe.
+  copyString(outStdName, zaxisInqStdname);    //FIXME: zaxisInqStdname is unsafe.
+  copyString(outUnit, zaxisInqUnits);    //FIXME: zaxisInqUnits is unsafe.
+  #undef copyString
+  return zaxisInqLtype(zaxisId);
+}
+
+int cdiFallbackIterator_level(CdiIterator* super, int levelSelector, double* outValue1, double* outValue2)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  int zaxisId = vlistInqVarZaxis(me->vlistId, me->curVariable);
+
+  //handle NULL pointers once and for all
+  double trash;
+  if(!outValue1) outValue1 = &trash;
+  if(!outValue2) outValue2 = &trash;
+
+  //get the level value
+  if(levelSelector)
+    {
+      *outValue1 = (zaxisInqLbounds(zaxisId, NULL))
+                 ? zaxisInqLbound(zaxisId, me->curLevel)
+                 : zaxisInqLevel(zaxisId, me->curLevel);
+    }
+  else
+    {
+      *outValue1 = (zaxisInqUbounds(zaxisId, NULL))
+                 ? zaxisInqUbound(zaxisId, me->curLevel)
+                 : zaxisInqLevel(zaxisId, me->curLevel);
+    }
+  *outValue2 = 0.0;
+
+  //if this is a hybrid zaxis, lookup the coordinates in the vertical coordinate table
+  ssize_t intLevel = (ssize_t)(2**outValue1);
+  if(0 <= intLevel && intLevel < zaxisInqVctSize(zaxisId) - 1)
+    {
+      const double* coordinateTable = zaxisInqVctPtr(zaxisId);
+      *outValue1 = coordinateTable[intLevel];
+      *outValue2 = coordinateTable[intLevel + 1];
+    }
+  return CDI_NOERR;
+}
+
+int cdiFallbackIterator_zaxisUuid(CdiIterator* super, int* outVgridNumber, int* outLevelCount, unsigned char (*outUuid)[16])
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  int zaxisId = vlistInqVarZaxis(me->vlistId, me->curVariable);
+  if(zaxisInqLtype(zaxisId) != ZAXIS_HYBRID) return CDI_EINVAL;
+  if(outVgridNumber) *outVgridNumber = zaxisInqNumber(zaxisId);
+  if(outLevelCount) *outLevelCount = zaxisInqNlevRef(zaxisId);
+  if(outUuid) zaxisInqUUID(zaxisId, *outUuid);
+  return CDI_NOERR;
+}
+
+char* cdiFallbackIterator_copyVariableName(CdiIterator* super)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  return vlistCopyVarName(me->vlistId, me->curVariable);
+}
+
+void cdiFallbackIterator_readField(CdiIterator* super, double* buffer, size_t* nmiss)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  int missingValues = 0;
+  streamReadVarSlice(me->streamId, me->curVariable, me->curLevel, buffer, &missingValues);
+  if(nmiss) *nmiss = missingValues;
+}
+
+void cdiFallbackIterator_readFieldF(CdiIterator* super, float* buffer, size_t* nmiss)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  int missingValues = 0;
+  streamReadVarSliceF(me->streamId, me->curVariable, me->curLevel, buffer, &missingValues);
+  if(nmiss) *nmiss = missingValues;
+}
+
+void cdiFallbackIterator_delete(CdiIterator* super)
+{
+  CdiFallbackIterator* me = (CdiFallbackIterator*)super;
+  cdiFallbackIterator_condestruct(me, NULL, 0);
+}
diff --git a/src/iterator_fallback.h b/src/iterator_fallback.h
new file mode 100644
index 0000000000000000000000000000000000000000..1128746144b5fee26bfc226467ac10abec98dd84
--- /dev/null
+++ b/src/iterator_fallback.h
@@ -0,0 +1,41 @@
+/*
+ * A fallback implementation of the iterator interface that opens a stream under the hood.
+ *
+ * This implementation is mainly available to provide iterator access to file formats that don't support iterator access natively,
+ * nevertheless, it allows the file to dictate the order in which data is read, possibly providing performance benefits.
+ */
+
+#ifndef INCLUDE_GUARD_CDI_ITERATOR_FALLBACK_H
+#define INCLUDE_GUARD_CDI_ITERATOR_FALLBACK_H
+
+#include "iterator.h"
+
+typedef struct CdiFallbackIterator {
+  CdiIterator super;
+  int streamId, vlistId;
+  char* path;   //needed for clone() & serialize()
+
+  int variableCount, curVariable;
+  int curLevelCount, curLevel;
+  int curTimestep;
+} CdiFallbackIterator;
+
+CdiIterator* cdiFallbackIterator_new(const char* path, int filetype);
+CdiFallbackIterator* cdiFallbackIterator_clone(CdiIterator* me);
+char* cdiFallbackIterator_serialize(CdiIterator* me);
+CdiFallbackIterator* cdiFallbackIterator_deserialize(const char* me);
+
+int cdiFallbackIterator_nextField(CdiIterator* me);
+
+char* cdiFallbackIterator_inqTime(CdiIterator* me, bool getEndTime);
+int cdiFallbackIterator_levelType(CdiIterator* me, int levelSelector, char** outName, char** outLongName, char** outStdName, char** outUnit);
+int cdiFallbackIterator_level(CdiIterator* me, int levelSelector, double* outValue1, double* outValue2);
+int cdiFallbackIterator_zaxisUuid(CdiIterator* me, int* outVgridNumber, int* outLevelCount, unsigned char (*outUuid)[16]);
+char* cdiFallbackIterator_copyVariableName(CdiIterator* me);
+
+void cdiFallbackIterator_readField(CdiIterator* me, double* buffer, size_t* nmiss);
+void cdiFallbackIterator_readFieldF(CdiIterator* me, float* buffer, size_t* nmiss);
+
+void cdiFallbackIterator_delete(CdiIterator* super);
+
+#endif
diff --git a/src/iterator_grib.c b/src/iterator_grib.c
new file mode 100644
index 0000000000000000000000000000000000000000..3016814a9147aac839a27aa412ae8bb30a948887
--- /dev/null
+++ b/src/iterator_grib.c
@@ -0,0 +1,814 @@
+#include "iterator_grib.h"
+
+#include "cdi_int.h"
+#include "cgribex.h"
+#include "dmemory.h"
+#include "error.h"
+#include "gribapi.h"
+#include "gribapi_utilities.h"
+#include "proprietarySystemWorkarounds.h"
+#include "stream_grb.h"
+#include "zaxis.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#ifdef HAVE_LIBGRIB_API
+
+//Since the error handling in constructors is usually very closely related to the workings of a destructor,
+//this function combines both functions in one, using a centralized exit.
+//The mode of operation depends on whether me is a NULL pointer on entry:
+//If it is NULL, a new object is allocated and constructed, which is returned if construction is successful.
+//If a non-NULL pointer is passed in, the object is destructed and NULL is returned. In this case, the other arguments are ignored.
+static CdiGribIterator* cdiGribIterator_condestruct(CdiGribIterator* me, const char* path, int filetype)
+{
+  #define super() (&me->super)
+  if(me) goto destruct;
+  me = xmalloc(sizeof(*me));
+  baseIterConstruct(super(), filetype);
+
+  me->file = cdiInputFile_make(path);
+  if(!me->file) goto destructSuper;
+  me->fileOffset = 0;
+  me->gribHandle = NULL;
+  me->gribBuffer = NULL;
+  me->bufferSize = me->curRecordSize = 0;
+  me->super.gridId = CDI_UNDEFID;
+
+  goto success;
+
+// ^        constructor code        ^
+// |                                |
+// v destructor/error-cleanup code  v
+
+destruct:
+  if(me->super.gridId != CDI_UNDEFID) gridDestroy(me->super.gridId);
+  if(me->gribHandle) grib_handle_delete(me->gribHandle);
+  free(me->gribBuffer);
+  cdiRefObject_release(&me->file->super);
+destructSuper:
+  baseIterDestruct(super());
+  free(me);
+  me = NULL;
+
+success:
+  return me;
+  #undef super
+}
+
+CdiIterator* cdiGribIterator_new(const char* path, int filetype)
+{
+  return &cdiGribIterator_condestruct(NULL, path, filetype)->super;
+}
+
+CdiGribIterator* cdiGribIterator_makeClone(CdiIterator* super)
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
+
+  //Allocate memory and copy data. (operations that may fail)
+  CdiGribIterator* result = xmalloc(sizeof(*result));
+  if(!result) goto fail;
+  *result = (CdiGribIterator)
+    {
+      .file = me->file,
+      .fileOffset = me->fileOffset,
+      .gribBuffer = NULL,
+      .bufferSize = me->bufferSize,
+      .curRecordSize = me->curRecordSize,
+      .gribHandle = NULL
+    };
+  if(me->gribBuffer)
+    {
+      result->gribBuffer = xmalloc(me->bufferSize);
+      if(!result->gribBuffer) goto freeResult;
+      memcpy(result->gribBuffer, me->gribBuffer, me->curRecordSize);
+    }
+  if(me->gribHandle)
+    {
+      result->gribHandle = grib_handle_new_from_message(NULL, result->gribBuffer, result->curRecordSize);
+      if(!result->gribHandle) goto freeBuffer;
+    }
+  if(super->gridId != CDI_UNDEFID)
+    {
+      result->super.gridId = gridDuplicate(super->gridId);
+      if(result->super.gridId == CDI_UNDEFID) goto deleteGribHandle;
+    }
+
+  //Finish construction. (operations that cannot fail)
+  baseIterConstruct(&result->super, super->filetype);
+  result->super.datatype = super->datatype;
+  result->super.timesteptype = super->timesteptype;
+  result->super.param = super->param;
+  cdiRefObject_retain(&result->file->super);
+
+  return result;
+
+  //Error handling.
+deleteGribHandle:
+  if(result->gribHandle) grib_handle_delete(result->gribHandle);
+freeBuffer:
+  free(result->gribBuffer);
+freeResult:
+  free(result);
+fail:
+  return NULL;
+}
+
+char* cdiGribIterator_serialize(CdiIterator* super)
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
+
+  char* path = cdiInputFile_copyPath(me->file);
+  char* escapedPath = cdiEscapeSpaces(path);
+  free(path);
+  char* result = myAsprintf("%s %zu", escapedPath, me->fileOffset);
+  free(escapedPath);
+  return result;
+}
+#endif
+
+CdiGribIterator* cdiGribIterator_deserialize(const char* description)
+{
+  char* path;
+  CdiGribIterator* me = xmalloc(sizeof(*me));
+  if(!me) goto fail;
+
+  description = baseIter_constructFromString(&me->super, description);
+
+  while(*description == ' ') description++;
+  path = cdiUnescapeSpaces(description, &description);
+  if(!path) goto destructSuper;
+
+  me->file = cdiInputFile_make(path);
+  free(path);
+  if(!me->file) goto destructSuper;
+
+  {
+    const char* savedStart = description;
+    long long decodedOffset = strtoll(description, (char**)&description, 0);    //The cast is a workaround for the wrong signature of strtoll() (it should have been `long long strtoll(const char*, const char**, int)`, not `long long strtoll(const char*, char**, int)`.
+    me->fileOffset = (off_t)decodedOffset;
+    if(savedStart == description) goto closeFile;
+    if((unsigned long long)decodedOffset > (unsigned long long)me->fileOffset) goto closeFile;
+  }
+
+  me->gribBuffer = NULL;
+  me->bufferSize = me->curRecordSize = 0;
+  me->gribHandle = NULL;
+  me->super.gridId = CDI_UNDEFID;
+  if(me->super.isAdvanced && cdiGribIterator_nextField(&me->super)) goto closeFile;
+
+  return me;
+
+
+closeFile:
+  cdiRefObject_release(&me->file->super);
+destructSuper:
+  baseIterDestruct(&me->super);
+  free(me);
+fail:
+  return NULL;
+}
+
+#ifdef HAVE_LIBGRIB_API
+static void cdiGribIterator_ensureBuffer(CdiGribIterator* me, size_t requiredSize)
+{
+  if(me->bufferSize < requiredSize)
+    {
+      me->bufferSize *= 2;
+      if(me->bufferSize < requiredSize) me->bufferSize = requiredSize;
+      me->gribBuffer = xrealloc(me->gribBuffer, me->bufferSize);
+    }
+}
+
+static bool isGrib1DualLevel(int levelType)
+{
+  switch(levelType)
+    {
+      case 101: case 104: case 106: case 108: case 110: case 112:
+      case 114: case 116: case 120: case 121: case 128: case 141:   //This is the complete list after grib_api-1.12.3/definitions/grib1/sections.1.def:106-117:, the code in cdi/src/stream_gribapi.c:grib1GetLevel() seems to be incomplete.
+        return true;
+      default:
+        return false;
+    }
+}
+
+static const unsigned char* positionOfGribMarker(const unsigned char* data, size_t size)
+{
+  for(const unsigned char* currentPosition = data, *end = data + size; currentPosition < end; currentPosition++)
+    {
+      currentPosition = memchr(currentPosition, 'G', size - (currentPosition - data) - 3);      //-3 to ensure that we don't overrun the buffer during the strncmp() call.
+      if(!currentPosition) return NULL;
+      if(!strncmp((const char*)currentPosition, "GRIB", 4)) return currentPosition;
+    }
+  return NULL;
+}
+
+//This clobbers the contents of the gribBuffer!
+//Returns the file offset of the next 'GRIB' marker.
+static ssize_t scanToGribMarker(CdiGribIterator* me)
+{
+  cdiGribIterator_ensureBuffer(me, 8*1024);
+  const size_t kMaxScanSize = 16*1024*1024;
+  for(size_t scannedBytes = 0, scanSize; scannedBytes < kMaxScanSize; scannedBytes += scanSize)
+    {
+      //Load a chunk of data into our buffer.
+      scanSize = me->bufferSize;
+      if(scannedBytes + scanSize > kMaxScanSize) scanSize = kMaxScanSize - scannedBytes;
+      assert(scanSize <= me->bufferSize);
+      int status = cdiInputFile_read(me->file, me->fileOffset + scannedBytes, scanSize, &scanSize, me->gribBuffer);
+      if(status != CDI_NOERR && status != CDI_EEOF) return status;
+
+      const unsigned char* startPosition = positionOfGribMarker(me->gribBuffer, scanSize);
+      if(startPosition)
+        {
+          return me->fileOffset + scannedBytes + (startPosition - me->gribBuffer);
+        }
+
+      //Get the offset for the next iteration if there is a next iteration.
+      scanSize -= 3;        //so that we won't miss a 'GRIB' sequence that happens to be cut off
+      scannedBytes += scanSize;
+      scannedBytes &= ~0xf; //make 16 bytes aligned
+    }
+  return -1;
+}
+
+static unsigned decode24(void* beData)
+{
+  unsigned char* bytes = beData;
+  return ((unsigned)bytes[0] << 16) + ((unsigned)bytes[1] << 8) + (unsigned)bytes[2];
+}
+
+static uint64_t decode64(void* beData)
+{
+  unsigned char* bytes = beData;
+  uint64_t result = 0;
+  for(size_t i = 0; i < 8; i++) result = (result << 8) + bytes[i];
+  return result;
+}
+
+//Determine the size of the GRIB record that begins at the given file offset.
+static int getRecordSize(CdiGribIterator* me, off_t gribFileOffset, size_t* outRecordSize)
+{
+  char buffer[16];
+  size_t readSize;
+  int status = cdiInputFile_read(me->file, gribFileOffset, sizeof(buffer), &readSize, buffer);
+  if(status != CDI_NOERR && status != CDI_EEOF) return status;
+  if(readSize < sizeof(buffer)) return CDI_EEOF;
+  *outRecordSize = 0;
+  switch(buffer[7])
+    {
+      case 1:
+        *outRecordSize = decode24(&buffer[4]);
+        if(*outRecordSize & (1 << 23))
+          {
+            *outRecordSize = 120*(*outRecordSize & ((1 << 23) - 1));    //Rescaling for long records.
+            //The corresponding code in cgribexlib.c:4532-4570: is much more complicated
+            //due to the fact that it subtracts the padding bytes that are inserted after section 4.
+            //However, we are only interested in the total size of data we need to read here,
+            //so we can ignore the presence of some padding bytes.
+          }
+        return CDI_NOERR;
+
+      case 2:
+        *outRecordSize =  decode64(&buffer[8]);
+        return CDI_NOERR;
+
+      default:
+        return CDI_EUFTYPE;
+    }
+}
+
+#if 0
+static void hexdump(void* data, size_t size)
+{
+  unsigned char* charData = data;
+  for(size_t offset = 0; offset < size; )
+    {
+      printf("%016zx:", offset);
+      for(size_t i = 0; i < 64 && offset < size; i++, offset++)
+        {
+          if((i & 63) && !(i & 15)) printf(" |");
+          if((i & 15) && !(i & 3)) printf("  ");
+          printf(" %02x", charData[offset]);
+        }
+      printf("\n");
+    }
+}
+#endif
+
+//Read a record into memory and wrap it in a grib_handle.
+//XXX: I have omitted checking for szip compression as it is done in grbReadVarDP() & friends since that appears to be a non-standard extension of the GRIB1 standard: bit 1 in octet 14 of the binary data section which is used to signal szip compressio is defined to be reserved in the standard. As such, it seems prudent not to support this and to encourage people with such szip compressed files to switch to the GRIB2/JPEG2000 format. However, in the case that this reasoning is wrong, this function is probably the place to add the check for zsip compression.
+static int readMessage(CdiGribIterator* me)
+{
+  //Destroy the old grib_handle.
+  if(me->gribHandle) grib_handle_delete(me->gribHandle), me->gribHandle = NULL;
+  me->fileOffset += me->curRecordSize;
+
+  //Find the next record and determine its size.
+  ssize_t gribFileOffset = scanToGribMarker(me);
+  int result = CDI_EEOF;
+  if(gribFileOffset < 0) goto fail;
+  result = getRecordSize(me, gribFileOffset, &me->curRecordSize);
+  if(result) goto fail;
+
+  //Load the whole record into our buffer and create a grib_handle for it.
+  cdiGribIterator_ensureBuffer(me, me->curRecordSize);
+  result = cdiInputFile_read(me->file, gribFileOffset, me->curRecordSize, NULL, me->gribBuffer);
+  if(result) goto fail;
+  me->gribHandle = grib_handle_new_from_message(NULL, me->gribBuffer, me->curRecordSize);
+  result = CDI_EUFSTRUCT;
+  if(!me->gribHandle) goto fail;
+
+  return CDI_NOERR;
+
+fail:
+  me->curRecordSize = 0;        //This ensures that we won't jump to an uncontrolled file position if cdiGribIterator_nextField() is called another time after it has returned an error.
+  return result;
+}
+
+int cdiGribIterator_nextField(CdiIterator* super)
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
+
+  if(super->gridId != CDI_UNDEFID) gridDestroy(super->gridId), super->gridId = CDI_UNDEFID;
+
+  //Get the next GRIB message into our buffer.
+  int result = readMessage(me);
+  if(result) return result;
+
+  //Get the metadata that's published as variables in the base class.
+  super->datatype = gribGetDatatype(me->gribHandle);
+  super->timesteptype = gribapiGetTsteptype(me->gribHandle);
+  cdiDecodeParam(gribapiGetParam(me->gribHandle), &super->param.number, &super->param.category, &super->param.discipline);
+  grid_t grid;
+  gribapiGetGrid(me->gribHandle, &grid);
+  super->gridId = gridGenerate(&grid);
+
+  return CDI_NOERR;
+}
+
+char* cdiGribIterator_inqTime(CdiIterator* super, bool getEndTime)
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
+  return gribMakeTimeString(me->gribHandle, getEndTime);
+}
+
+int cdiGribIterator_levelType(CdiIterator* super, int levelSelector, char** outName, char** outLongName, char** outStdName, char** outUnit)
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
+
+  //First determine the zaxis type corresponding to the given level.
+  int zaxisType = ZAXIS_GENERIC;
+  if(gribEditionNumber(me->gribHandle) <= 1)
+    {
+      int levelType = gribGetLongDefault(me->gribHandle, "indicatorOfTypeOfLevel", 255);
+      if(levelSelector && !isGrib1DualLevel(levelType)) levelType = 255;
+      zaxisType = grib1ltypeToZaxisType(levelType);
+    }
+  else
+    {
+      int levelType = gribGetLongDefault(me->gribHandle, levelSelector ? "typeOfSecondFixedSurface" : "typeOfFirstFixedSurface", 255);
+      zaxisType = grib2ltypeToZaxisType(levelType);
+    }
+
+  //Then lookup the requested names.
+  const char* name, *longName, *stdName, *unit;
+  zaxisGetTypeDescription(zaxisType, NULL, &name, &longName, &stdName, &unit);
+  if(outName) *outName = myStrDup(name);
+  if(outLongName) *outLongName = myStrDup(longName);
+  if(outStdName) *outStdName = myStrDup(stdName);
+  if(outUnit) *outUnit = myStrDup(unit);
+
+  return zaxisType;
+}
+
+static double logicalLevelValue2(long gribType, long storedValue, long power)
+{
+  double factor = 1;
+  while(power--) factor *= 10;      //this is precise up to factor == 22.
+  switch(gribType)
+    {
+      case GRIB2_LTYPE_LANDDEPTH:
+      case GRIB2_LTYPE_ISOBARIC:
+      case GRIB2_LTYPE_SIGMA:
+        return storedValue*(1000/factor);      //The evaluation order allows the factors of ten to cancel out before rounding.
+
+      case 255:
+        return 0;
+
+      default:
+        return storedValue/factor;
+    }
+}
+
+//The output values must be preinitialized, this function does not always write them.
+static int readLevel2(grib_handle* gribHandle, const char* levelTypeKey, const char* powerKey, const char* valueKey, double* outValue1, double* outValue2)
+{
+  assert(levelTypeKey && powerKey && valueKey && outValue1 && outValue2);
+
+  long levelType = gribGetLongDefault(gribHandle, levelTypeKey, 255);   //1 byte
+  switch(levelType)
+    {
+      case 255: break;
+
+      case 105: case 113:
+        {
+          unsigned long value = (unsigned long)gribGetLongDefault(gribHandle, valueKey, 0);
+          unsigned long coordinateCount = (unsigned long)gribGetLongDefault(gribHandle, "numberOfCoordinatesValues", 0);
+          if(value >= coordinateCount/2)
+            {
+              Error("Invalid level coordinate: Level has the hybrid coordinate index %lu, but only %lu coordinate pairs are present.", value, coordinateCount/2);
+              return CDI_EUFSTRUCT;
+            }
+          int status;
+          //XXX: I'm not 100% sure about how the coordinate pairs are stored in the file.
+          //     I'm assuming an array of pairs due to the example code in grib_api-1.12.3/examples/F90/set_pv.f90, but that may be wrong.
+          if((status = grib_get_double_element(gribHandle, "pv", value*2    , outValue1))) return status;
+          if((status = grib_get_double_element(gribHandle, "pv", value*2 + 1, outValue2))) return status;
+          break;
+        }
+
+      default:
+        {
+          long power = gribGetLongDefault(gribHandle, powerKey, 0);  //1 byte
+          if(power == 255) power = 0;
+          long value = gribGetLongDefault(gribHandle, valueKey, 0);   //4 bytes
+          *outValue1 = logicalLevelValue2(levelType, value, power);
+        }
+    }
+  return CDI_NOERR;
+}
+
+int cdiGribIterator_level(CdiIterator* super, int levelSelector, double* outValue1, double* outValue2)
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
+  double trash;
+  if(!outValue1) outValue1 = &trash;
+  if(!outValue2) outValue2 = &trash;
+  *outValue1 = *outValue2 = 0;
+
+  if(gribEditionNumber(me->gribHandle) > 1)
+    {
+      if(levelSelector)
+        {
+          return readLevel2(me->gribHandle, "typeOfFirstFixedSurface", "scaleFactorOfFirstFixedSurface", "scaledValueOfFirstFixedSurface", outValue1, outValue2);
+        }
+      else
+        {
+          return readLevel2(me->gribHandle, "typeOfSecondFixedSurface", "scaleFactorOfSecondFixedSurface", "scaledValueOfSecondFixedSurface", outValue1, outValue2);
+        }
+    }
+  else
+    {
+      long levelType = (uint8_t)gribGetLongDefault(me->gribHandle, "indicatorOfTypeOfLevel", -1);    //1 byte
+      if(levelType == 255)
+        {}
+      else if(isGrib1DualLevel(levelType))
+        {
+          *outValue1 = gribGetLongDefault(me->gribHandle, (levelSelector ? "bottomLevel" : "topLevel"), 0);
+        }
+      else if(levelType == 100)
+        {
+          *outValue1 = 100*gribGetLongDefault(me->gribHandle, "level", 0);        //2 bytes
+        }
+      else
+        {
+          *outValue1 = gribGetLongDefault(me->gribHandle, "level", 0);        //2 bytes
+        }
+    }
+  return CDI_NOERR;
+}
+
+int cdiGribIterator_zaxisUuid(CdiIterator* super, int* outVgridNumber, int* outLevelCount, unsigned char (*outUuid)[16])
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
+
+  if(outVgridNumber)
+    {
+      long temp;
+      if(grib_get_long(me->gribHandle, "numberOfVGridUsed", &temp)) return CDI_EINVAL;
+      *outVgridNumber = (int)temp;
+    }
+  if(outLevelCount)
+    {
+      long temp;
+      if(grib_get_long(me->gribHandle, "nlev", &temp)) return CDI_EINVAL;
+      *outLevelCount = (int)temp;
+    }
+  if(outUuid)
+    {
+      size_t size = sizeof(*outUuid);
+      if(grib_get_bytes(me->gribHandle, "uuidOfVGrid", *outUuid, &size)) return CDI_EINVAL;
+      if(size != sizeof(*outUuid)) return CDI_EUFSTRUCT;
+    }
+
+  return CDI_NOERR;
+}
+
+char* cdiGribIterator_copyVariableName(CdiIterator* super)
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
+  return gribCopyString(me->gribHandle, "shortName");
+}
+
+void cdiGribIterator_readField(CdiIterator* super, double* buffer, size_t* nmiss)
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
+
+  gribGetDoubleArray(me->gribHandle, "values", buffer);
+  long gridType = gribGetLong(me->gribHandle, "gridDefinitionTemplateNumber");
+  if(nmiss)
+    {
+      *nmiss = (gridType >= 50 && gridType <= 53) ? 0 : (int)gribGetLong(me->gribHandle, "numberOfMissing");        //The condition excludes harmonic data.
+    }
+}
+
+void cdiGribIterator_readFieldF(CdiIterator* super, float* buffer, size_t* nmiss)
+{
+  CdiGribIterator* me = (CdiGribIterator*)super;
+
+  size_t valueCount = gribGetArraySize(me->gribHandle, "values");
+  double* temp = malloc(valueCount*sizeof(*temp));
+  cdiGribIterator_readField(super, temp, nmiss);
+  for(size_t i = valueCount; i--; ) buffer[i] = temp[i];
+  free(temp);
+}
+
+/**
+@Function cdiGribIterator_delete
+@Title Dispose off a CdiGribIterator instance.
+
+@Prototype void cdiGribIterator_delete(CdiGribIterator* me)
+@Parameter
+    @item me The iterator to delete.
+
+@Description
+    Combined destructor and deallocator. Make sure to match every call to cdiGribIterator_clone() with a call to this function.
+*/
+void cdiGribIterator_delete(CdiGribIterator* me)
+{
+  if(me) cdiGribIterator_condestruct(me, NULL, 0);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// callthroughs to provide direct access to the grib keys //////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/**
+@Function cdiGribIterator_inqEdition
+@Title Get the version of the GRIB standard that is used
+
+@Prototype int cdiGribIterator_inqEdition(CdiGribIterator* me)
+@Parameter
+    @item me The iterator to operate on.
+
+@Result The GRIB version.
+
+@Description
+    Returns the version of the file format.
+*/
+int cdiGribIterator_inqEdition(CdiGribIterator* me)
+{
+  return gribEditionNumber(me->gribHandle);
+}
+
+/**
+@Function cdiGribIterator_getLong
+@Title Access to grib_get_long()
+
+@Prototype int cdiGribIterator_getLong(CdiGribIterator* me, const char* key, long* result)
+@Parameter
+    @item me The iterator to operate on.
+    @item ... The arguments to the underlying GRIB-API function.
+
+@Result An error code.
+
+@Description
+    Callthrough to grib_get_long().
+*/
+int cdiGribIterator_getLong(CdiGribIterator* me, const char* key, long* result)
+{
+  return grib_get_long(me->gribHandle, key, result);
+}
+
+/**
+@Function cdiGribIterator_getLength
+@Title Access to grib_get_length()
+
+@Prototype int cdiGribIterator_getLength(CdiGribIterator* me, const char* key, size_t* result)
+@Parameter
+    @item me The iterator to operate on.
+    @item ... The arguments to the underlying GRIB-API function.
+
+@Result An error code.
+
+@Description
+    Callthrough to grib_get_length().
+*/
+int cdiGribIterator_getLength(CdiGribIterator* me, const char* key, size_t* result)
+{
+  return grib_get_length(me->gribHandle, key, result);
+}
+
+/**
+@Function cdiGribIterator_getString
+@Title Access to grib_get_string()
+
+@Prototype int cdiGribIterator_getString(CdiGribIterator* me, const char* key, char* result, size_t* length)
+@Parameter
+    @item me The iterator to operate on.
+    @item ... The arguments to the underlying GRIB-API function.
+
+@Result An error code.
+
+@Description
+    Callthrough to grib_get_string().
+*/
+int cdiGribIterator_getString(CdiGribIterator* me, const char* key, char* result, size_t* length)
+{
+  return grib_get_string(me->gribHandle, key, result, length);
+}
+
+/**
+@Function cdiGribIterator_inqLongValue
+@Title Get the value of a GRIB-API key as a long
+
+@Prototype long cdiGribIterator_inqLongValue(CdiGribIterator* me, const char* key)
+@Parameter
+    @item me The iterator to operate on.
+    @item key The GRIB-API key to retrieve.
+
+@Result The value of the key.
+
+@Description
+    Use this to fetch a grib value if you are certain that the given key must be present.
+    This will abort the process if the key cannot be retrieved.
+*/
+long cdiGribIterator_inqLongValue(CdiGribIterator* me, const char* key)
+{
+  return gribGetLong(me->gribHandle, key);
+}
+
+/**
+@Function cdiGribIterator_inqLongDefaultValue
+@Title Get the value of a GRIB-API key as a long
+
+@Prototype long cdiGribIterator_inqLongDefaultValue(CdiGribIterator* me, const char* key, long defaultValue)
+@Parameter
+    @item me The iterator to operate on.
+    @item key The GRIB-API key to retrieve.
+    @item defaultValue The value to return if the key is not present.
+
+@Result The value of the key or the given default value.
+
+@Description
+    Use this if you can handle failure to fetch the key by supplying a default value.
+    This function cannot fail.
+*/
+long cdiGribIterator_inqLongDefaultValue(CdiGribIterator* me, const char* key, long defaultValue)
+{
+  return gribGetLongDefault(me->gribHandle, key, defaultValue);
+}
+
+/**
+@Function cdiGribIterator_inqStringValue
+@Title Safely retrieve a GRIB-API key with a string value
+
+@Prototype char* cdiGribIterator_inqStringValue(CdiGribIterator* me, const char* key)
+@Parameter
+    @item me The iterator to operate on.
+    @item key The GRIB-API key to retrieve.
+
+@Result A malloc'ed string or NULL.
+
+@Description
+    This will first call grib_get_length() to inquire the actual size of the string,
+    allocate memory accordingly, call grib_get_string(), and return the pointer to the new string.
+    Returns NULL on failure.
+*/
+char* cdiGribIterator_inqStringValue(CdiGribIterator* me, const char* key)
+{
+  return gribCopyString(me->gribHandle, key);
+}
+
+/**
+@Function cdiGribIterator_getDouble
+@Title Access to grib_get_double()
+
+@Prototype int cdiGribIterator_getDouble(CdiGribIterator* me, const char* key, double* result)
+@Parameter
+    @item me The iterator to operate on.
+    @item ... The arguments to the underlying GRIB-API function.
+
+@Result An error code.
+
+@Description
+    Callthrough to grib_get_double().
+*/
+int cdiGribIterator_getDouble(CdiGribIterator* me, const char* key, double* result)
+{
+  return grib_get_double(me->gribHandle, key, result);
+}
+
+/**
+@Function cdiGribIterator_getSize
+@Title Access to grib_get_size()
+
+@Prototype int cdiGribIterator_getSize(CdiGribIterator* me, const char* key, size_t* result)
+@Parameter
+    @item me The iterator to operate on.
+    @item ... The arguments to the underlying GRIB-API function.
+
+@Result An error code.
+
+@Description
+    Callthrough to grib_get_size().
+*/
+int cdiGribIterator_getSize(CdiGribIterator* me, const char* key, size_t* result)
+{
+  return grib_get_size(me->gribHandle, key, result);
+}
+
+/**
+@Function cdiGribIterator_getLongArray
+@Title Access to grib_get_long_array()
+
+@Prototype int cdiGribIterator_getLongArray(CdiGribIterator* me, const char* key, long* result, size_t* size)
+@Parameter
+    @item me The iterator to operate on.
+    @item ... The arguments to the underlying GRIB-API function.
+
+@Result An error code.
+
+@Description
+    Callthrough to grib_get_long_array().
+*/
+int cdiGribIterator_getLongArray(CdiGribIterator* me, const char* key, long* result, size_t* size)
+{
+  return grib_get_long_array(me->gribHandle, key, result, size);
+}
+
+/**
+@Function cdiGribIterator_getDoubleArray
+@Title Access to grib_get_double_array()
+
+@Prototype int cdiGribIterator_getDoubleArray(CdiGribIterator* me, const char* key, double* result, size_t* size)
+@Parameter
+    @item me The iterator to operate on.
+    @item ... The arguments to the underlying GRIB-API function.
+
+@Result An error code.
+
+@Description
+    Callthrough to grib_get_double_array().
+*/
+int cdiGribIterator_getDoubleArray(CdiGribIterator* me, const char* key, double* result, size_t* size)
+{
+  return grib_get_double_array(me->gribHandle, key, result, size);
+}
+
+/**
+@Function cdiGribIterator_inqDoubleValue
+@Title Get the value of a GRIB-API key as a double
+
+@Prototype double cdiGribIterator_inqDoubleValue(CdiGribIterator* me, const char* key)
+@Parameter
+    @item me The iterator to operate on.
+    @item key The GRIB-API key to retrieve.
+
+@Result The value of the key.
+
+@Description
+    Use this to fetch a grib value if you are certain that the given key must be present.
+    This will abort the process if the key cannot be retrieved.
+*/
+double cdiGribIterator_inqDoubleValue(CdiGribIterator* me, const char* key)
+{
+  return gribGetDouble(me->gribHandle, key);
+}
+
+/**
+@Function cdiGribIterator_inqDoubleDefaultValue
+@Title Get the value of a GRIB-API key as a double
+
+@Prototype double cdiGribIterator_inqDoubleDefaultValue(CdiGribIterator* me, const char* key, double defaultValue)
+@Parameter
+    @item me The iterator to operate on.
+    @item key The GRIB-API key to retrieve.
+    @item defaultValue The value to return if the key is not present.
+
+@Result The value of the key or the given default value.
+
+@Description
+    Use this if you can handle failure to fetch the key by supplying a default value.
+    This function cannot fail.
+*/
+double cdiGribIterator_inqDoubleDefaultValue(CdiGribIterator* me, const char* key, double defaultValue)
+{
+  return gribGetDoubleDefault(me->gribHandle, key, defaultValue);
+}
+
+#endif
diff --git a/src/iterator_grib.h b/src/iterator_grib.h
new file mode 100644
index 0000000000000000000000000000000000000000..f72ee74fa96990773c0aebd02921912b699d94ae
--- /dev/null
+++ b/src/iterator_grib.h
@@ -0,0 +1,48 @@
+/*
+ * An implementation of the iterator interface for GRIB files.
+ * Since GRIB files do not contain an index, this avoids scanning the entire file to generate an in-memory index as streamOpenRead() does.
+ * Consequently, using this interface is much more efficient for GRIB files.
+ */
+
+#ifndef INCLUDE_GUARD_CDI_ITERATOR_GRIB_H
+#define INCLUDE_GUARD_CDI_ITERATOR_GRIB_H
+
+#include "iterator.h"
+#include "input_file.h"
+
+#ifdef HAVE_LIBGRIB_API
+#include <grib_api.h>
+#endif
+
+typedef struct recordList recordList;
+typedef struct CdiGribIterator {
+  CdiIterator super;
+
+  CdiInputFile* file;
+  off_t fileOffset;
+  unsigned char* gribBuffer;
+  size_t bufferSize, curRecordSize;
+#ifdef HAVE_LIBGRIB_API
+  grib_handle* gribHandle;
+#else
+  void* gribHandle;
+#endif
+} CdiGribIterator;
+
+CdiIterator* cdiGribIterator_new(const char* path, int filetype);
+CdiGribIterator* cdiGribIterator_makeClone(CdiIterator* me);
+char* cdiGribIterator_serialize(CdiIterator* me);
+CdiGribIterator* cdiGribIterator_deserialize(const char* me);
+
+int cdiGribIterator_nextField(CdiIterator* me);
+
+char* cdiGribIterator_inqTime(CdiIterator* me, bool getEndTime);
+int cdiGribIterator_levelType(CdiIterator* me, int levelSelector, char** outName, char** outLongName, char** outStdName, char** outUnit);
+int cdiGribIterator_level(CdiIterator* me, int levelSelector, double* outValue1, double* outValue2);
+int cdiGribIterator_zaxisUuid(CdiIterator* me, int* outVgridNumber, int* outLevelCount, unsigned char (*outUuid)[16]);
+char* cdiGribIterator_copyVariableName(CdiIterator* me);
+
+void cdiGribIterator_readField(CdiIterator* me, double* buffer, size_t* nmiss);
+void cdiGribIterator_readFieldF(CdiIterator* me, float* buffer, size_t* nmiss);
+
+#endif
diff --git a/src/make_cdilib b/src/make_cdilib
index 0b4e55bce65fef19e65e0c7a353c4d1068630072..7974b517a7c78d7ba3c2f926253438e334d35756 100755
--- a/src/make_cdilib
+++ b/src/make_cdilib
@@ -6,7 +6,7 @@
 # pretty generic script -- just echos, cats and greps.
 #
 #
-srcdir=./
+srcdir=.
 if [ ! -z $1 ] ; then
 srcdir=$1
 fi
@@ -89,73 +89,98 @@ cat > ${PROG} << EOR
 
 EOR
 
-c="dmemory.c         \
-   dmemory.h         \
-   cksum.c           \
-   cdi_cksum.c       \
-   taxis.c           \
-   timebase.c        \
-   calendar.c        \
-   model.c           \
-   institution.c     \
-   table.c           \
-   util.c            \
-   gaussgrid.c       \
-   varscan.c         \
-   vlist.c           \
-   vlist_att.c       \
-   vlist_var.c       \
-   basetime.c        \
-   servicelib.c      \
-   extralib.c        \
-   ieglib.c          \
-   grid.c            \
-   zaxis.c           \
-   cdf_int.c         \
-   cdi_error.c       \
-   cdi_util.c        \
-   cdi_int.c         \
-   stream.c          \
-   stream_history.c  \
-   stream_cgribex.c  \
-   stream_gribapi.c  \
-   stream_fcommon.c  \
-   stream_grb.c      \
-   stream_srv.c      \
-   stream_ext.c      \
-   stream_ieg.c      \
-   stream_cdf.c      \
-   stream_var.c      \
-   stream_record.c   \
-   tsteps.c          \
-   file.c            \
-   cgribexlib.c      \
-   gribapi.c         \
-   swap.c            \
-   binary.c          \
-   cdf.c             \
-   namespace.c       \
-   serialize.c       \
-   resource_handle.c"
-
-h="cdi_limits.h resource_handle.h taxis.h dtypes.h file.h service.h extra.h \
-   ieg.h cdi.h timebase.h calendar.h basetime.h datetime.h namespace.h \
-   cksum.h cdi_cksum.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  \
-   cdf.h vlist.h vlist_var.h vlist_att.h model.h institution.h \
-   resource_unpack.h serialize.h stream_fcommon.h"
-
-#cat $h >> ${PROG}
-#cat $c | grep -v '#include' | grep -v '#  include' >> ${PROG}
-
-for hfile in $h ; do
-  cat $srcdir/$hfile  >> ${PROG}
+files="basetime.c \
+   binary.c \
+   calendar.c \
+   cdf.c \
+   cdf_int.c \
+   cdi_cksum.c \
+   cdi_error.c \
+   cdi_int.c \
+   cdi_util.c \
+   cgribexlib.c \
+   cksum.c \
+   dmemory.c \
+   error.c \
+   extralib.c \
+   file.c \
+   gaussgrid.c \
+   gribapi.c \
+   gribapi_utilities.c \
+   grid.c \
+   ieglib.c \
+   input_file.c \
+   institution.c \
+   iterator.c \
+   iterator_fallback.c \
+   iterator_grib.c \
+   model.c \
+   namespace.c \
+   proprietarySystemWorkarounds.c \
+   referenceCounting.c \
+   resource_handle.c \
+   serialize.c \
+   servicelib.c \
+   stream.c \
+   stream_cdf.c \
+   stream_cgribex.c \
+   stream_ext.c \
+   stream_fcommon.c \
+   stream_grb.c \
+   stream_gribapi.c \
+   stream_history.c \
+   stream_ieg.c \
+   stream_record.c \
+   stream_srv.c \
+   stream_var.c \
+   swap.c \
+   table.c \
+   taxis.c \
+   timebase.c \
+   tsteps.c \
+   util.c \
+   varscan.c \
+   vlist.c \
+   vlist_att.c \
+   vlist_var.c \
+   zaxis.c"
+
+car () {
+    echo "$1"
+}
+cdr () {
+    shift
+    echo "$@"
+}
+listIncludes () {
+    grep '^ *# *include  *"' "$1" | sed 's/^ *# *include  *"\(.*\)".*$/\1/'
+}
+
+scanlist="$files"
+fileList=
+until test "foo$scanlist" = "foo" ; do
+    curFile="$(car $scanlist)"
+    scanlist="$(cdr $scanlist)"
+    case $curFile in
+        (\<*\>)
+            fileList="$fileList $(echo "$curFile" | sed 's/<\(.*\)>/\1/')"
+            ;;
+        (*)
+            if echo "$fileList" | grep -q '\<'"$curFile"'\>' ; then
+                true    #Nothing to do, we have already scanned this header.
+            else
+                #Prepend the includes of the current header to the scanlist so that we will scan them in the order that the preprocessor would.
+                scanlist="$(listIncludes "$curFile") <$curFile> $scanlist"
+            fi
+            ;;
+    esac
 done
 
-for cfile in $c ; do
-  cat $srcdir/$cfile | grep -v '#include "' | grep -v '#  include "' >> ${PROG}
+echo file list:
+echo $fileList
+
+for file in $fileList ; do
+  cat $srcdir/$file | grep -v '^ *# *include  *"'  >> ${PROG}
 done
 
 
diff --git a/src/mo_cdi.f90 b/src/mo_cdi.f90
index fc2ce7cc2ee21ee9f36a2fe25e821c19a846edab..079ffd33acdb8f450e63e447e4003b2e53e3a3dc 100644
--- a/src/mo_cdi.f90
+++ b/src/mo_cdi.f90
@@ -1,3744 +1,7918 @@
+! >>> Warning: This is a generated file. If you modify it, you get what you deserve. <<<
+!
+! Generated by "../interfaces/f2003/bindGen.rb" from input file "../src/cdi.h".
 
 module mo_cdi
-      use, intrinsic :: iso_c_binding
-
-      implicit none
-
-      private
-  
-      integer, parameter :: CDI_MAX_NAME = 256
-      integer, parameter :: CDI_UNDEFID = -1
-      integer, parameter :: CDI_GLOBAL = -1
-      integer, parameter :: CDI_BIGENDIAN = 0
-      integer, parameter :: CDI_LITTLEENDIAN = 1
-      integer, parameter :: CDI_REAL = 1
-      integer, parameter :: CDI_COMP = 2
-      integer, parameter :: CDI_BOTH = 3
-      integer, parameter :: CDI_ESYSTEM = -10
-      integer, parameter :: CDI_EINVAL = -20
-      integer, parameter :: CDI_EUFTYPE = -21
-      integer, parameter :: CDI_ELIBNAVAIL = -22
-      integer, parameter :: CDI_EUFSTRUCT = -23
-      integer, parameter :: CDI_EUNC4 = -24
-      integer, parameter :: CDI_ELIMIT = -99
-      integer, parameter :: FILETYPE_UNDEF = -1
-      integer, parameter :: FILETYPE_GRB = 1
-      integer, parameter :: FILETYPE_GRB2 = 2
-      integer, parameter :: FILETYPE_NC = 3
-      integer, parameter :: FILETYPE_NC2 = 4
-      integer, parameter :: FILETYPE_NC4 = 5
-      integer, parameter :: FILETYPE_NC4C = 6
-      integer, parameter :: FILETYPE_SRV = 7
-      integer, parameter :: FILETYPE_EXT = 8
-      integer, parameter :: FILETYPE_IEG = 9
-      integer, parameter :: COMPRESS_NONE = 0
-      integer, parameter :: COMPRESS_SZIP = 1
-      integer, parameter :: COMPRESS_GZIP = 2
-      integer, parameter :: COMPRESS_BZIP2 = 3
-      integer, parameter :: COMPRESS_ZIP = 4
-      integer, parameter :: COMPRESS_JPEG = 5
-      integer, parameter :: DATATYPE_PACK = 0
-      integer, parameter :: DATATYPE_PACK1 = 1
-      integer, parameter :: DATATYPE_PACK2 = 2
-      integer, parameter :: DATATYPE_PACK3 = 3
-      integer, parameter :: DATATYPE_PACK4 = 4
-      integer, parameter :: DATATYPE_PACK5 = 5
-      integer, parameter :: DATATYPE_PACK6 = 6
-      integer, parameter :: DATATYPE_PACK7 = 7
-      integer, parameter :: DATATYPE_PACK8 = 8
-      integer, parameter :: DATATYPE_PACK9 = 9
-      integer, parameter :: DATATYPE_PACK10 = 10
-      integer, parameter :: DATATYPE_PACK11 = 11
-      integer, parameter :: DATATYPE_PACK12 = 12
-      integer, parameter :: DATATYPE_PACK13 = 13
-      integer, parameter :: DATATYPE_PACK14 = 14
-      integer, parameter :: DATATYPE_PACK15 = 15
-      integer, parameter :: DATATYPE_PACK16 = 16
-      integer, parameter :: DATATYPE_PACK17 = 17
-      integer, parameter :: DATATYPE_PACK18 = 18
-      integer, parameter :: DATATYPE_PACK19 = 19
-      integer, parameter :: DATATYPE_PACK20 = 20
-      integer, parameter :: DATATYPE_PACK21 = 21
-      integer, parameter :: DATATYPE_PACK22 = 22
-      integer, parameter :: DATATYPE_PACK23 = 23
-      integer, parameter :: DATATYPE_PACK24 = 24
-      integer, parameter :: DATATYPE_PACK25 = 25
-      integer, parameter :: DATATYPE_PACK26 = 26
-      integer, parameter :: DATATYPE_PACK27 = 27
-      integer, parameter :: DATATYPE_PACK28 = 28
-      integer, parameter :: DATATYPE_PACK29 = 29
-      integer, parameter :: DATATYPE_PACK30 = 30
-      integer, parameter :: DATATYPE_PACK31 = 31
-      integer, parameter :: DATATYPE_PACK32 = 32
-      integer, parameter :: DATATYPE_CPX32 = 64
-      integer, parameter :: DATATYPE_CPX64 = 128
-      integer, parameter :: DATATYPE_FLT32 = 132
-      integer, parameter :: DATATYPE_FLT64 = 164
-      integer, parameter :: DATATYPE_INT8 = 208
-      integer, parameter :: DATATYPE_INT16 = 216
-      integer, parameter :: DATATYPE_INT32 = 232
-      integer, parameter :: DATATYPE_UINT8 = 308
-      integer, parameter :: DATATYPE_UINT16 = 316
-      integer, parameter :: DATATYPE_UINT32 = 332
-      integer, parameter :: DATATYPE_INT = 251
-      integer, parameter :: DATATYPE_FLT = 252
-      integer, parameter :: DATATYPE_TXT = 253
-      integer, parameter :: DATATYPE_CPX = 254
-      integer, parameter :: DATATYPE_UCHAR = 255
-      integer, parameter :: DATATYPE_LONG = 256
-      integer, parameter :: CHUNK_AUTO = 1
-      integer, parameter :: CHUNK_GRID = 2
-      integer, parameter :: CHUNK_LINES = 3
-      integer, parameter :: GRID_GENERIC = 1
-      integer, parameter :: GRID_GAUSSIAN = 2
-      integer, parameter :: GRID_GAUSSIAN_REDUCED = 3
-      integer, parameter :: GRID_LONLAT = 4
-      integer, parameter :: GRID_SPECTRAL = 5
-      integer, parameter :: GRID_FOURIER = 6
-      integer, parameter :: GRID_GME = 7
-      integer, parameter :: GRID_TRAJECTORY = 8
-      integer, parameter :: GRID_UNSTRUCTURED = 9
-      integer, parameter :: GRID_CURVILINEAR = 10
-      integer, parameter :: GRID_LCC = 11
-      integer, parameter :: GRID_LCC2 = 12
-      integer, parameter :: GRID_LAEA = 13
-      integer, parameter :: GRID_SINUSOIDAL = 14
-      integer, parameter :: GRID_PROJECTION = 15
-      integer, parameter :: ZAXIS_SURFACE = 0
-      integer, parameter :: ZAXIS_GENERIC = 1
-      integer, parameter :: ZAXIS_HYBRID = 2
-      integer, parameter :: ZAXIS_HYBRID_HALF = 3
-      integer, parameter :: ZAXIS_PRESSURE = 4
-      integer, parameter :: ZAXIS_HEIGHT = 5
-      integer, parameter :: ZAXIS_DEPTH_BELOW_SEA = 6
-      integer, parameter :: ZAXIS_DEPTH_BELOW_LAND = 7
-      integer, parameter :: ZAXIS_ISENTROPIC = 8
-      integer, parameter :: ZAXIS_TRAJECTORY = 9
-      integer, parameter :: ZAXIS_ALTITUDE = 10
-      integer, parameter :: ZAXIS_SIGMA = 11
-      integer, parameter :: ZAXIS_MEANSEA = 12
-      integer, parameter :: ZAXIS_TOA = 13
-      integer, parameter :: ZAXIS_SEA_BOTTOM = 14
-      integer, parameter :: ZAXIS_ATMOSPHERE = 15
-      integer, parameter :: ZAXIS_CLOUD_BASE = 16
-      integer, parameter :: ZAXIS_CLOUD_TOP = 17
-      integer, parameter :: ZAXIS_ISOTHERM_ZERO = 18
-      integer, parameter :: ZAXIS_SNOW = 19
-      integer, parameter :: ZAXIS_LAKE_BOTTOM = 20
-      integer, parameter :: ZAXIS_SEDIMENT_BOTTOM = 21
-      integer, parameter :: ZAXIS_SEDIMENT_BOTTOM_TA = 22
-      integer, parameter :: ZAXIS_SEDIMENT_BOTTOM_TW = 23
-      integer, parameter :: ZAXIS_MIX_LAYER = 24
-      integer, parameter :: ZAXIS_REFERENCE = 25
-      integer, parameter :: TIME_CONSTANT = 0
-      integer, parameter :: TIME_VARIABLE = 1
-      integer, parameter :: TSTEP_CONSTANT = 0
-      integer, parameter :: TSTEP_INSTANT = 1
-      integer, parameter :: TSTEP_AVG = 2
-      integer, parameter :: TSTEP_ACCUM = 3
-      integer, parameter :: TSTEP_MAX = 4
-      integer, parameter :: TSTEP_MIN = 5
-      integer, parameter :: TSTEP_DIFF = 6
-      integer, parameter :: TSTEP_RMS = 7
-      integer, parameter :: TSTEP_SD = 8
-      integer, parameter :: TSTEP_COV = 9
-      integer, parameter :: TSTEP_RATIO = 10
-      integer, parameter :: TSTEP_RANGE = 11
-      integer, parameter :: TSTEP_INSTANT2 = 12
-      integer, parameter :: TSTEP_INSTANT3 = 13
-      integer, parameter :: TAXIS_ABSOLUTE = 1
-      integer, parameter :: TAXIS_RELATIVE = 2
-      integer, parameter :: TAXIS_FORECAST = 3
-      integer, parameter :: TUNIT_SECOND = 1
-      integer, parameter :: TUNIT_MINUTE = 2
-      integer, parameter :: TUNIT_QUARTER = 3
-      integer, parameter :: TUNIT_30MINUTES = 4
-      integer, parameter :: TUNIT_HOUR = 5
-      integer, parameter :: TUNIT_3HOURS = 6
-      integer, parameter :: TUNIT_6HOURS = 7
-      integer, parameter :: TUNIT_12HOURS = 8
-      integer, parameter :: TUNIT_DAY = 9
-      integer, parameter :: TUNIT_MONTH = 10
-      integer, parameter :: TUNIT_YEAR = 11
-      integer, parameter :: CALENDAR_STANDARD = 0
-      integer, parameter :: CALENDAR_PROLEPTIC = 1
-      integer, parameter :: CALENDAR_360DAYS = 2
-      integer, parameter :: CALENDAR_365DAYS = 3
-      integer, parameter :: CALENDAR_366DAYS = 4
-      integer, parameter :: CALENDAR_NONE = 5
-      integer, parameter :: CDI_UUID_SIZE = 16
-      interface
-        function strlen(s) bind(c,name='strlen')
-          import :: c_ptr,c_size_t
-          type(c_ptr), value :: s
-          integer(kind=c_size_t) :: strlen
-        end function strlen
-      end interface
-      interface
-        function getchar() bind(c,name='getchar')
-          import :: c_int
-          integer(kind=c_int) :: getchar
-        end function getchar
-      end interface
-      interface
-        function getchar_unlocked() bind(c,name='getchar_unlocked')
-          import :: c_int
-          integer(kind=c_int) :: getchar_unlocked
-        end function getchar_unlocked
-      end interface
-      interface
-        subroutine cdiReset() bind(c,name='cdiReset')
-        end subroutine cdiReset
-      end interface
-      interface
-        subroutine cdiDebug(debug) bind(c,name='cdiDebug')
-          import :: c_int
-          integer(kind=c_int), value :: debug
-        end subroutine cdiDebug
-      end interface
-      interface
-        subroutine cdiPrintVersion() bind(c,name='cdiPrintVersion')
-        end subroutine cdiPrintVersion
-      end interface
-      interface
-        function cdiHaveFiletype(filetype) bind(c,name='cdiHaveFiletype')
-          import :: c_int
-          integer(kind=c_int), value :: filetype
-          integer(kind=c_int) :: cdiHaveFiletype
-        end function cdiHaveFiletype
-      end interface
-      interface
-        subroutine cdiDefMissval(missval) bind(c,name='cdiDefMissval')
-          import :: c_double
-          real(kind=c_double), value :: missval
-        end subroutine cdiDefMissval
-      end interface
-      interface
-        function cdiInqMissval() bind(c,name='cdiInqMissval')
-          import :: c_double
-          real(kind=c_double) :: cdiInqMissval
-        end function cdiInqMissval
-      end interface
-      interface
-        subroutine cdiDefGlobal(string,val) bind(c,name='cdiDefGlobal')
-          import :: c_char,c_int
-          character(kind=c_char), dimension(*) :: string
-          integer(kind=c_int), value :: val
-        end subroutine cdiDefGlobal
-      end interface
-      interface
-        function namespaceNew() bind(c,name='namespaceNew')
-          import :: c_int
-          integer(kind=c_int) :: namespaceNew
-        end function namespaceNew
-      end interface
-      interface
-        subroutine namespaceSetActive(namespaceID) bind(c,name='namespaceSetActive')
-          import :: c_int
-          integer(kind=c_int), value :: namespaceID
-        end subroutine namespaceSetActive
-      end interface
-      interface
-        subroutine namespaceDelete(namespaceID) bind(c,name='namespaceDelete')
-          import :: c_int
-          integer(kind=c_int), value :: namespaceID
-        end subroutine namespaceDelete
-      end interface
-      interface
-        subroutine cdiParamToString(param,paramstr,maxlen) bind(c,name='cdiParamToString')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: param
-          character(kind=c_char), dimension(*) :: paramstr
-          integer(kind=c_int), value :: maxlen
-        end subroutine cdiParamToString
-      end interface
-      interface
-        subroutine cdiDecodeParam(param,pnum,pcat,pdis) bind(c,name='cdiDecodeParam')
-          import :: c_int
-          integer(kind=c_int), value :: param
-          integer(kind=c_int), intent(out) :: pnum
-          integer(kind=c_int), intent(out) :: pcat
-          integer(kind=c_int), intent(out) :: pdis
-        end subroutine cdiDecodeParam
-      end interface
-      interface
-        function cdiEncodeParam(pnum,pcat,pdis) bind(c,name='cdiEncodeParam')
-          import :: c_int
-          integer(kind=c_int), value :: pnum
-          integer(kind=c_int), value :: pcat
-          integer(kind=c_int), value :: pdis
-          integer(kind=c_int) :: cdiEncodeParam
-        end function cdiEncodeParam
-      end interface
-      interface
-        subroutine cdiDecodeDate(date,year,month,day) bind(c,name='cdiDecodeDate')
-          import :: c_int
-          integer(kind=c_int), value :: date
-          integer(kind=c_int), intent(out) :: year
-          integer(kind=c_int), intent(out) :: month
-          integer(kind=c_int), intent(out) :: day
-        end subroutine cdiDecodeDate
-      end interface
-      interface
-        function cdiEncodeDate(year,month,day) bind(c,name='cdiEncodeDate')
-          import :: c_int
-          integer(kind=c_int), value :: year
-          integer(kind=c_int), value :: month
-          integer(kind=c_int), value :: day
-          integer(kind=c_int) :: cdiEncodeDate
-        end function cdiEncodeDate
-      end interface
-      interface
-        subroutine cdiDecodeTime(time,hour,minute,second) bind(c,name='cdiDecodeTime')
-          import :: c_int
-          integer(kind=c_int), value :: time
-          integer(kind=c_int), intent(out) :: hour
-          integer(kind=c_int), intent(out) :: minute
-          integer(kind=c_int), intent(out) :: second
-        end subroutine cdiDecodeTime
-      end interface
-      interface
-        function cdiEncodeTime(hour,minute,second) bind(c,name='cdiEncodeTime')
-          import :: c_int
-          integer(kind=c_int), value :: hour
-          integer(kind=c_int), value :: minute
-          integer(kind=c_int), value :: second
-          integer(kind=c_int) :: cdiEncodeTime
-        end function cdiEncodeTime
-      end interface
-      interface
-        function cdiGetFiletype(path,byteorder) bind(c,name='cdiGetFiletype')
-          import :: c_char,c_int
-          character(kind=c_char), dimension(*) :: path
-          integer(kind=c_int), intent(out) :: byteorder
-          integer(kind=c_int) :: cdiGetFiletype
-        end function cdiGetFiletype
-      end interface
-      interface
-        function streamOpenRead(path) bind(c,name='streamOpenRead')
-          import :: c_char,c_int
-          character(kind=c_char), dimension(*) :: path
-          integer(kind=c_int) :: streamOpenRead
-        end function streamOpenRead
-      end interface
-      interface
-        function streamOpenWrite(path,filetype) bind(c,name='streamOpenWrite')
-          import :: c_char,c_int
-          character(kind=c_char), dimension(*) :: path
-          integer(kind=c_int), value :: filetype
-          integer(kind=c_int) :: streamOpenWrite
-        end function streamOpenWrite
-      end interface
-      interface
-        function streamOpenAppend(path) bind(c,name='streamOpenAppend')
-          import :: c_char,c_int
-          character(kind=c_char), dimension(*) :: path
-          integer(kind=c_int) :: streamOpenAppend
-        end function streamOpenAppend
-      end interface
-      interface
-        subroutine streamClose(streamID) bind(c,name='streamClose')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-        end subroutine streamClose
-      end interface
-      interface
-        subroutine streamSync(streamID) bind(c,name='streamSync')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-        end subroutine streamSync
-      end interface
-      interface
-        subroutine streamDefVlist(streamID,vlistID) bind(c,name='streamDefVlist')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: vlistID
-        end subroutine streamDefVlist
-      end interface
-      interface
-        function streamInqVlist(streamID) bind(c,name='streamInqVlist')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int) :: streamInqVlist
-        end function streamInqVlist
-      end interface
-      interface
-        function streamInqVlistIDorig(streamID) bind(c,name='streamInqVlistIDorig')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int) :: streamInqVlistIDorig
-        end function streamInqVlistIDorig
-      end interface
-      interface
-        function streamInqFiletype(streamID) bind(c,name='streamInqFiletype')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int) :: streamInqFiletype
-        end function streamInqFiletype
-      end interface
-      interface
-        subroutine streamDefByteorder(streamID,byteorder) bind(c,name='streamDefByteorder')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: byteorder
-        end subroutine streamDefByteorder
-      end interface
-      interface
-        function streamInqByteorder(streamID) bind(c,name='streamInqByteorder')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int) :: streamInqByteorder
-        end function streamInqByteorder
-      end interface
-      interface
-        subroutine streamDefCompType(streamID,comptype) bind(c,name='streamDefCompType')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: comptype
-        end subroutine streamDefCompType
-      end interface
-      interface
-        function streamInqCompType(streamID) bind(c,name='streamInqCompType')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int) :: streamInqCompType
-        end function streamInqCompType
-      end interface
-      interface
-        subroutine streamDefCompLevel(streamID,complevel) bind(c,name='streamDefCompLevel')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: complevel
-        end subroutine streamDefCompLevel
-      end interface
-      interface
-        function streamInqCompLevel(streamID) bind(c,name='streamInqCompLevel')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int) :: streamInqCompLevel
-        end function streamInqCompLevel
-      end interface
-      interface
-        function streamDefTimestep(streamID,tsID) bind(c,name='streamDefTimestep')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: tsID
-          integer(kind=c_int) :: streamDefTimestep
-        end function streamDefTimestep
-      end interface
-      interface
-        function streamInqTimestep(streamID,tsID) bind(c,name='streamInqTimestep')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: tsID
-          integer(kind=c_int) :: streamInqTimestep
-        end function streamInqTimestep
-      end interface
-      interface
-        function streamInqCurTimestepID(streamID) bind(c,name='streamInqCurTimestepID')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int) :: streamInqCurTimestepID
-        end function streamInqCurTimestepID
-      end interface
-      interface
-        function streamInqNvars(streamID) bind(c,name='streamInqNvars')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int) :: streamInqNvars
-        end function streamInqNvars
-      end interface
-      interface
-        subroutine streamWriteVar(streamID,varID,data_vec,nmiss) bind(c,name='streamWriteVar')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: varID
-          real(kind=c_double), intent(in), dimension(*) :: data_vec
-          integer(kind=c_int), value :: nmiss
-        end subroutine streamWriteVar
-      end interface
-      interface
-        subroutine streamWriteVarF(streamID,varID,data_vec,nmiss) bind(c,name='streamWriteVarF')
-          import :: c_int,c_float
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: varID
-          real(kind=c_float), intent(in), dimension(*) :: data_vec
-          integer(kind=c_int), value :: nmiss
-        end subroutine streamWriteVarF
-      end interface
-      interface
-        subroutine streamReadVar(streamID,varID,data_vec,nmiss) bind(c,name='streamReadVar')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: varID
-          real(kind=c_double), intent(out), dimension(*) :: data_vec
-          integer(kind=c_int), intent(out) :: nmiss
-        end subroutine streamReadVar
-      end interface
-      interface
-        subroutine streamReadVarF(streamID,varID,data_vec,nmiss) bind(c,name='streamReadVarF')
-          import :: c_int,c_float
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: varID
-          real(kind=c_float), intent(out), dimension(*) :: data_vec
-          integer(kind=c_int), intent(out) :: nmiss
-        end subroutine streamReadVarF
-      end interface
-      interface
-        subroutine streamWriteVarSlice(streamID,varID,levelID,data_vec,nmiss) bind(c,name='streamWriteVarSlice')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: levelID
-          real(kind=c_double), intent(in), dimension(*) :: data_vec
-          integer(kind=c_int), value :: nmiss
-        end subroutine streamWriteVarSlice
-      end interface
-      interface
-        subroutine streamWriteVarSliceF(streamID,varID,levelID,data_vec,nmiss) bind(c,name='streamWriteVarSliceF')
-          import :: c_int,c_float
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: levelID
-          real(kind=c_float), intent(in), dimension(*) :: data_vec
-          integer(kind=c_int), value :: nmiss
-        end subroutine streamWriteVarSliceF
-      end interface
-      interface
-        subroutine streamReadVarSlice(streamID,varID,levelID,data_vec,nmiss) bind(c,name='streamReadVarSlice')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: levelID
-          real(kind=c_double), intent(out), dimension(*) :: data_vec
-          integer(kind=c_int), intent(out) :: nmiss
-        end subroutine streamReadVarSlice
-      end interface
-      interface
-        subroutine streamReadVarSliceF(streamID,varID,levelID,data_vec,nmiss) bind(c,name='streamReadVarSliceF')
-          import :: c_int,c_float
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: levelID
-          real(kind=c_float), intent(out), dimension(*) :: data_vec
-          integer(kind=c_int), intent(out) :: nmiss
-        end subroutine streamReadVarSliceF
-      end interface
-      interface
-        subroutine streamDefRecord(streamID,varID,levelID) bind(c,name='streamDefRecord')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: levelID
-        end subroutine streamDefRecord
-      end interface
-      interface
-        subroutine streamInqRecord(streamID,varID,levelID) bind(c,name='streamInqRecord')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), intent(out) :: varID
-          integer(kind=c_int), intent(out) :: levelID
-        end subroutine streamInqRecord
-      end interface
-      interface
-        subroutine streamWriteRecord(streamID,data_vec,nmiss) bind(c,name='streamWriteRecord')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: streamID
-          real(kind=c_double), intent(in), dimension(*) :: data_vec
-          integer(kind=c_int), value :: nmiss
-        end subroutine streamWriteRecord
-      end interface
-      interface
-        subroutine streamWriteRecordF(streamID,data_vec,nmiss) bind(c,name='streamWriteRecordF')
-          import :: c_int,c_float
-          integer(kind=c_int), value :: streamID
-          real(kind=c_float), intent(in), dimension(*) :: data_vec
-          integer(kind=c_int), value :: nmiss
-        end subroutine streamWriteRecordF
-      end interface
-      interface
-        subroutine streamReadRecord(streamID,data_vec,nmiss) bind(c,name='streamReadRecord')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: streamID
-          real(kind=c_double), intent(out), dimension(*) :: data_vec
-          integer(kind=c_int), intent(out) :: nmiss
-        end subroutine streamReadRecord
-      end interface
-      interface
-        subroutine streamCopyRecord(streamIDdest,streamIDsrc) bind(c,name='streamCopyRecord')
-          import :: c_int
-          integer(kind=c_int), value :: streamIDdest
-          integer(kind=c_int), value :: streamIDsrc
-        end subroutine streamCopyRecord
-      end interface
-      interface
-        function vlistCreate() bind(c,name='vlistCreate')
-          import :: c_int
-          integer(kind=c_int) :: vlistCreate
-        end function vlistCreate
-      end interface
-      interface
-        subroutine vlistDestroy(vlistID) bind(c,name='vlistDestroy')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-        end subroutine vlistDestroy
-      end interface
-      interface
-        function vlistDuplicate(vlistID) bind(c,name='vlistDuplicate')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int) :: vlistDuplicate
-        end function vlistDuplicate
-      end interface
-      interface
-        subroutine vlistCopy(vlistID2,vlistID1) bind(c,name='vlistCopy')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID2
-          integer(kind=c_int), value :: vlistID1
-        end subroutine vlistCopy
-      end interface
-      interface
-        subroutine vlistCopyFlag(vlistID2,vlistID1) bind(c,name='vlistCopyFlag')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID2
-          integer(kind=c_int), value :: vlistID1
-        end subroutine vlistCopyFlag
-      end interface
-      interface
-        subroutine vlistClearFlag(vlistID) bind(c,name='vlistClearFlag')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-        end subroutine vlistClearFlag
-      end interface
-      interface
-        subroutine vlistCat(vlistID2,vlistID1) bind(c,name='vlistCat')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID2
-          integer(kind=c_int), value :: vlistID1
-        end subroutine vlistCat
-      end interface
-      interface
-        subroutine vlistMerge(vlistID2,vlistID1) bind(c,name='vlistMerge')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID2
-          integer(kind=c_int), value :: vlistID1
-        end subroutine vlistMerge
-      end interface
-      interface
-        subroutine vlistPrint(vlistID) bind(c,name='vlistPrint')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-        end subroutine vlistPrint
-      end interface
-      interface
-        function vlistNumber(vlistID) bind(c,name='vlistNumber')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int) :: vlistNumber
-        end function vlistNumber
-      end interface
-      interface
-        function vlistNvars(vlistID) bind(c,name='vlistNvars')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int) :: vlistNvars
-        end function vlistNvars
-      end interface
-      interface
-        function vlistNgrids(vlistID) bind(c,name='vlistNgrids')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int) :: vlistNgrids
-        end function vlistNgrids
-      end interface
-      interface
-        function vlistNzaxis(vlistID) bind(c,name='vlistNzaxis')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int) :: vlistNzaxis
-        end function vlistNzaxis
-      end interface
-      interface
-        subroutine vlistDefNtsteps(vlistID,nts) bind(c,name='vlistDefNtsteps')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: nts
-        end subroutine vlistDefNtsteps
-      end interface
-      interface
-        function vlistNtsteps(vlistID) bind(c,name='vlistNtsteps')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int) :: vlistNtsteps
-        end function vlistNtsteps
-      end interface
-      interface
-        function vlistGridsizeMax(vlistID) bind(c,name='vlistGridsizeMax')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int) :: vlistGridsizeMax
-        end function vlistGridsizeMax
-      end interface
-      interface
-        function vlistGrid(vlistID,index) bind(c,name='vlistGrid')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: index
-          integer(kind=c_int) :: vlistGrid
-        end function vlistGrid
-      end interface
-      interface
-        function vlistGridIndex(vlistID,gridID) bind(c,name='vlistGridIndex')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: vlistGridIndex
-        end function vlistGridIndex
-      end interface
-      interface
-        subroutine vlistChangeGridIndex(vlistID,index,gridID) bind(c,name='vlistChangeGridIndex')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: index
-          integer(kind=c_int), value :: gridID
-        end subroutine vlistChangeGridIndex
-      end interface
-      interface
-        subroutine vlistChangeGrid(vlistID,gridID1,gridID2) bind(c,name='vlistChangeGrid')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: gridID1
-          integer(kind=c_int), value :: gridID2
-        end subroutine vlistChangeGrid
-      end interface
-      interface
-        function vlistZaxis(vlistID,index) bind(c,name='vlistZaxis')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: index
-          integer(kind=c_int) :: vlistZaxis
-        end function vlistZaxis
-      end interface
-      interface
-        function vlistZaxisIndex(vlistID,zaxisID) bind(c,name='vlistZaxisIndex')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int) :: vlistZaxisIndex
-        end function vlistZaxisIndex
-      end interface
-      interface
-        subroutine vlistChangeZaxisIndex(vlistID,index,zaxisID) bind(c,name='vlistChangeZaxisIndex')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: index
-          integer(kind=c_int), value :: zaxisID
-        end subroutine vlistChangeZaxisIndex
-      end interface
-      interface
-        subroutine vlistChangeZaxis(vlistID,zaxisID1,zaxisID2) bind(c,name='vlistChangeZaxis')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: zaxisID1
-          integer(kind=c_int), value :: zaxisID2
-        end subroutine vlistChangeZaxis
-      end interface
-      interface
-        function vlistNrecs(vlistID) bind(c,name='vlistNrecs')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int) :: vlistNrecs
-        end function vlistNrecs
-      end interface
-      interface
-        subroutine vlistDefTaxis(vlistID,taxisID) bind(c,name='vlistDefTaxis')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: taxisID
-        end subroutine vlistDefTaxis
-      end interface
-      interface
-        function vlistInqTaxis(vlistID) bind(c,name='vlistInqTaxis')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int) :: vlistInqTaxis
-        end function vlistInqTaxis
-      end interface
-      interface
-        subroutine vlistDefTable(vlistID,tableID) bind(c,name='vlistDefTable')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: tableID
-        end subroutine vlistDefTable
-      end interface
-      interface
-        function vlistInqTable(vlistID) bind(c,name='vlistInqTable')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int) :: vlistInqTable
-        end function vlistInqTable
-      end interface
-      interface
-        subroutine vlistDefInstitut(vlistID,instID) bind(c,name='vlistDefInstitut')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: instID
-        end subroutine vlistDefInstitut
-      end interface
-      interface
-        function vlistInqInstitut(vlistID) bind(c,name='vlistInqInstitut')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int) :: vlistInqInstitut
-        end function vlistInqInstitut
-      end interface
-      interface
-        subroutine vlistDefModel(vlistID,modelID) bind(c,name='vlistDefModel')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: modelID
-        end subroutine vlistDefModel
-      end interface
-      interface
-        function vlistInqModel(vlistID) bind(c,name='vlistInqModel')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int) :: vlistInqModel
-        end function vlistInqModel
-      end interface
-      interface
-        function vlistDefVar(vlistID,gridID,zaxisID,tsteptype) bind(c,name='vlistDefVar')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int), value :: tsteptype
-          integer(kind=c_int) :: vlistDefVar
-        end function vlistDefVar
-      end interface
-      interface
-        subroutine vlistChangeVarGrid(vlistID,varID,gridID) bind(c,name='vlistChangeVarGrid')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: gridID
-        end subroutine vlistChangeVarGrid
-      end interface
-      interface
-        subroutine vlistChangeVarZaxis(vlistID,varID,zaxisID) bind(c,name='vlistChangeVarZaxis')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: zaxisID
-        end subroutine vlistChangeVarZaxis
-      end interface
-      interface
-        subroutine vlistInqVar(vlistID,varID,gridID,zaxisID,tsteptype) bind(c,name='vlistInqVar')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), intent(out) :: gridID
-          integer(kind=c_int), intent(out) :: zaxisID
-          integer(kind=c_int), intent(out) :: tsteptype
-        end subroutine vlistInqVar
-      end interface
-      interface
-        function vlistInqVarGrid(vlistID,varID) bind(c,name='vlistInqVarGrid')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarGrid
-        end function vlistInqVarGrid
-      end interface
-      interface
-        function vlistInqVarZaxis(vlistID,varID) bind(c,name='vlistInqVarZaxis')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarZaxis
-        end function vlistInqVarZaxis
-      end interface
-      interface
-        function vlistInqVarID(vlistID,code) bind(c,name='vlistInqVarID')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: code
-          integer(kind=c_int) :: vlistInqVarID
-        end function vlistInqVarID
-      end interface
-      interface
-        subroutine vlistDefVarTsteptype(vlistID,varID,tsteptype) bind(c,name='vlistDefVarTsteptype')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: tsteptype
-        end subroutine vlistDefVarTsteptype
-      end interface
-      interface
-        function vlistInqVarTsteptype(vlistID,varID) bind(c,name='vlistInqVarTsteptype')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarTsteptype
-        end function vlistInqVarTsteptype
-      end interface
-      interface
-        subroutine vlistDefVarCompType(vlistID,varID,comptype) bind(c,name='vlistDefVarCompType')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: comptype
-        end subroutine vlistDefVarCompType
-      end interface
-      interface
-        function vlistInqVarCompType(vlistID,varID) bind(c,name='vlistInqVarCompType')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarCompType
-        end function vlistInqVarCompType
-      end interface
-      interface
-        subroutine vlistDefVarCompLevel(vlistID,varID,complevel) bind(c,name='vlistDefVarCompLevel')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: complevel
-        end subroutine vlistDefVarCompLevel
-      end interface
-      interface
-        function vlistInqVarCompLevel(vlistID,varID) bind(c,name='vlistInqVarCompLevel')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarCompLevel
-        end function vlistInqVarCompLevel
-      end interface
-      interface
-        subroutine vlistDefVarParam(vlistID,varID,param) bind(c,name='vlistDefVarParam')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: param
-        end subroutine vlistDefVarParam
-      end interface
-      interface
-        function vlistInqVarParam(vlistID,varID) bind(c,name='vlistInqVarParam')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarParam
-        end function vlistInqVarParam
-      end interface
-      interface
-        subroutine vlistDefVarCode(vlistID,varID,code) bind(c,name='vlistDefVarCode')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: code
-        end subroutine vlistDefVarCode
-      end interface
-      interface
-        function vlistInqVarCode(vlistID,varID) bind(c,name='vlistInqVarCode')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarCode
-        end function vlistInqVarCode
-      end interface
-      interface
-        subroutine vlistDefVarDatatype(vlistID,varID,datatype) bind(c,name='vlistDefVarDatatype')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: datatype
-        end subroutine vlistDefVarDatatype
-      end interface
-      interface
-        function vlistInqVarDatatype(vlistID,varID) bind(c,name='vlistInqVarDatatype')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarDatatype
-        end function vlistInqVarDatatype
-      end interface
-      interface
-        subroutine vlistDefVarChunkType(vlistID,varID,chunktype) bind(c,name='vlistDefVarChunkType')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: chunktype
-        end subroutine vlistDefVarChunkType
-      end interface
-      interface
-        function vlistInqVarChunkType(vlistID,varID) bind(c,name='vlistInqVarChunkType')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarChunkType
-        end function vlistInqVarChunkType
-      end interface
-      interface
-        subroutine vlistDefVarXYZ(vlistID,varID,xyz) bind(c,name='vlistDefVarXYZ')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: xyz
-        end subroutine vlistDefVarXYZ
-      end interface
-      interface
-        function vlistInqVarXYZ(vlistID,varID) bind(c,name='vlistInqVarXYZ')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarXYZ
-        end function vlistInqVarXYZ
-      end interface
-      interface
-        function vlistInqVarNumber(vlistID,varID) bind(c,name='vlistInqVarNumber')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarNumber
-        end function vlistInqVarNumber
-      end interface
-      interface
-        subroutine vlistDefVarInstitut(vlistID,varID,instID) bind(c,name='vlistDefVarInstitut')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: instID
-        end subroutine vlistDefVarInstitut
-      end interface
-      interface
-        function vlistInqVarInstitut(vlistID,varID) bind(c,name='vlistInqVarInstitut')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarInstitut
-        end function vlistInqVarInstitut
-      end interface
-      interface
-        subroutine vlistDefVarModel(vlistID,varID,modelID) bind(c,name='vlistDefVarModel')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: modelID
-        end subroutine vlistDefVarModel
-      end interface
-      interface
-        function vlistInqVarModel(vlistID,varID) bind(c,name='vlistInqVarModel')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarModel
-        end function vlistInqVarModel
-      end interface
-      interface
-        subroutine vlistDefVarTable(vlistID,varID,tableID) bind(c,name='vlistDefVarTable')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: tableID
-        end subroutine vlistDefVarTable
-      end interface
-      interface
-        function vlistInqVarTable(vlistID,varID) bind(c,name='vlistInqVarTable')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarTable
-        end function vlistInqVarTable
-      end interface
-      interface
-        subroutine vlistDefVarName(vlistID,varID,name) bind(c,name='vlistDefVarName')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-        end subroutine vlistDefVarName
-      end interface
-      interface
-        subroutine vlistInqVarName(vlistID,varID,name) bind(c,name='vlistInqVarName')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-        end subroutine vlistInqVarName
-      end interface
-      interface
-        subroutine vlistDefVarStdname(vlistID,varID,stdname) bind(c,name='vlistDefVarStdname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: stdname
-        end subroutine vlistDefVarStdname
-      end interface
-      interface
-        subroutine vlistInqVarStdname(vlistID,varID,stdname) bind(c,name='vlistInqVarStdname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: stdname
-        end subroutine vlistInqVarStdname
-      end interface
-      interface
-        subroutine vlistDefVarLongname(vlistID,varID,longname) bind(c,name='vlistDefVarLongname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: longname
-        end subroutine vlistDefVarLongname
-      end interface
-      interface
-        subroutine vlistInqVarLongname(vlistID,varID,longname) bind(c,name='vlistInqVarLongname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: longname
-        end subroutine vlistInqVarLongname
-      end interface
-      interface
-        subroutine vlistDefVarUnits(vlistID,varID,units) bind(c,name='vlistDefVarUnits')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: units
-        end subroutine vlistDefVarUnits
-      end interface
-      interface
-        subroutine vlistInqVarUnits(vlistID,varID,units) bind(c,name='vlistInqVarUnits')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: units
-        end subroutine vlistInqVarUnits
-      end interface
-      interface
-        subroutine vlistDefVarMissval(vlistID,varID,missval) bind(c,name='vlistDefVarMissval')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          real(kind=c_double), value :: missval
-        end subroutine vlistDefVarMissval
-      end interface
-      interface
-        function vlistInqVarMissval(vlistID,varID) bind(c,name='vlistInqVarMissval')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          real(kind=c_double) :: vlistInqVarMissval
-        end function vlistInqVarMissval
-      end interface
-      interface
-        subroutine vlistDefVarExtra(vlistID,varID,extra) bind(c,name='vlistDefVarExtra')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: extra
-        end subroutine vlistDefVarExtra
-      end interface
-      interface
-        subroutine vlistInqVarExtra(vlistID,varID,extra) bind(c,name='vlistInqVarExtra')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: extra
-        end subroutine vlistInqVarExtra
-      end interface
-      interface
-        subroutine vlistDefVarScalefactor(vlistID,varID,scalefactor) bind(c,name='vlistDefVarScalefactor')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          real(kind=c_double), value :: scalefactor
-        end subroutine vlistDefVarScalefactor
-      end interface
-      interface
-        function vlistInqVarScalefactor(vlistID,varID) bind(c,name='vlistInqVarScalefactor')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          real(kind=c_double) :: vlistInqVarScalefactor
-        end function vlistInqVarScalefactor
-      end interface
-      interface
-        subroutine vlistDefVarAddoffset(vlistID,varID,addoffset) bind(c,name='vlistDefVarAddoffset')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          real(kind=c_double), value :: addoffset
-        end subroutine vlistDefVarAddoffset
-      end interface
-      interface
-        function vlistInqVarAddoffset(vlistID,varID) bind(c,name='vlistInqVarAddoffset')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          real(kind=c_double) :: vlistInqVarAddoffset
-        end function vlistInqVarAddoffset
-      end interface
-      interface
-        subroutine vlistDefVarTimave(vlistID,varID,timave) bind(c,name='vlistDefVarTimave')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: timave
-        end subroutine vlistDefVarTimave
-      end interface
-      interface
-        function vlistInqVarTimave(vlistID,varID) bind(c,name='vlistInqVarTimave')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarTimave
-        end function vlistInqVarTimave
-      end interface
-      interface
-        subroutine vlistDefVarTimaccu(vlistID,varID,timaccu) bind(c,name='vlistDefVarTimaccu')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: timaccu
-        end subroutine vlistDefVarTimaccu
-      end interface
-      interface
-        function vlistInqVarTimaccu(vlistID,varID) bind(c,name='vlistInqVarTimaccu')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarTimaccu
-        end function vlistInqVarTimaccu
-      end interface
-      interface
-        subroutine vlistDefVarTypeOfGeneratingProcess(vlistID,varID,typeOfGeneratingProcess) bind(c,&
-       name='vlistDefVarTypeOfGeneratingProcess')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: typeOfGeneratingProcess
-        end subroutine vlistDefVarTypeOfGeneratingProcess
-      end interface
-      interface
-        function vlistInqVarTypeOfGeneratingProcess(vlistID,varID) bind(c,name='vlistInqVarTypeOfGeneratingProcess')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarTypeOfGeneratingProcess
-        end function vlistInqVarTypeOfGeneratingProcess
-      end interface
-      interface
-        subroutine vlistDefVarProductDefinitionTemplate(vlistID,varID,productDefinitionTemplate) bind(c,&
-       name='vlistDefVarProductDefinitionTemplate')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: productDefinitionTemplate
-        end subroutine vlistDefVarProductDefinitionTemplate
-      end interface
-      interface
-        function vlistInqVarProductDefinitionTemplate(vlistID,varID) bind(c,name='vlistInqVarProductDefinitionTemplate')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarProductDefinitionTemplate
-        end function vlistInqVarProductDefinitionTemplate
-      end interface
-      interface
-        function vlistInqVarSize(vlistID,varID) bind(c,name='vlistInqVarSize')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistInqVarSize
-        end function vlistInqVarSize
-      end interface
-      interface
-        subroutine vlistDefIndex(vlistID,varID,levID,index) bind(c,name='vlistDefIndex')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: levID
-          integer(kind=c_int), value :: index
-        end subroutine vlistDefIndex
-      end interface
-      interface
-        function vlistInqIndex(vlistID,varID,levID) bind(c,name='vlistInqIndex')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: levID
-          integer(kind=c_int) :: vlistInqIndex
-        end function vlistInqIndex
-      end interface
-      interface
-        subroutine vlistDefFlag(vlistID,varID,levID,flag) bind(c,name='vlistDefFlag')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: levID
-          integer(kind=c_int), value :: flag
-        end subroutine vlistDefFlag
-      end interface
-      interface
-        function vlistInqFlag(vlistID,varID,levID) bind(c,name='vlistInqFlag')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: levID
-          integer(kind=c_int) :: vlistInqFlag
-        end function vlistInqFlag
-      end interface
-      interface
-        function vlistFindVar(vlistID,fvarID) bind(c,name='vlistFindVar')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: fvarID
-          integer(kind=c_int) :: vlistFindVar
-        end function vlistFindVar
-      end interface
-      interface
-        function vlistFindLevel(vlistID,fvarID,flevelID) bind(c,name='vlistFindLevel')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: fvarID
-          integer(kind=c_int), value :: flevelID
-          integer(kind=c_int) :: vlistFindLevel
-        end function vlistFindLevel
-      end interface
-      interface
-        function vlistMergedVar(vlistID,varID) bind(c,name='vlistMergedVar')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int) :: vlistMergedVar
-        end function vlistMergedVar
-      end interface
-      interface
-        function vlistMergedLevel(vlistID,varID,levelID) bind(c,name='vlistMergedLevel')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: levelID
-          integer(kind=c_int) :: vlistMergedLevel
-        end function vlistMergedLevel
-      end interface
-      interface
-        subroutine vlistDefVarEnsemble(vlistID,varID,ensID,ensCount,forecast_type) bind(c,name='vlistDefVarEnsemble')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: ensID
-          integer(kind=c_int), value :: ensCount
-          integer(kind=c_int), value :: forecast_type
-        end subroutine vlistDefVarEnsemble
-      end interface
-      interface
-        function vlistInqVarEnsemble(vlistID,varID,ensID,ensCount,forecast_type) bind(c,name='vlistInqVarEnsemble')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), intent(out) :: ensID
-          integer(kind=c_int), intent(out) :: ensCount
-          integer(kind=c_int), intent(out) :: forecast_type
-          integer(kind=c_int) :: vlistInqVarEnsemble
-        end function vlistInqVarEnsemble
-      end interface
-      interface
-        subroutine cdiClearAdditionalKeys() bind(c,name='cdiClearAdditionalKeys')
-        end subroutine cdiClearAdditionalKeys
-      end interface
-      interface
-        subroutine cdiDefAdditionalKey(string) bind(c,name='cdiDefAdditionalKey')
-          import :: c_char
-          character(kind=c_char), dimension(*) :: string
-        end subroutine cdiDefAdditionalKey
-      end interface
-      interface
-        subroutine vlistDefVarIntKey(vlistID,varID,name,value) bind(c,name='vlistDefVarIntKey')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int), value :: value
-        end subroutine vlistDefVarIntKey
-      end interface
-      interface
-        subroutine vlistDefVarDblKey(vlistID,varID,name,value) bind(c,name='vlistDefVarDblKey')
-          import :: c_int,c_char,c_double
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-          real(kind=c_double), value :: value
-        end subroutine vlistDefVarDblKey
-      end interface
-      interface
-        function vlistHasVarKey(vlistID,varID,name) bind(c,name='vlistHasVarKey')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int) :: vlistHasVarKey
-        end function vlistHasVarKey
-      end interface
-      interface
-        function vlistInqVarDblKey(vlistID,varID,name) bind(c,name='vlistInqVarDblKey')
-          import :: c_int,c_char,c_double
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-          real(kind=c_double) :: vlistInqVarDblKey
-        end function vlistInqVarDblKey
-      end interface
-      interface
-        function vlistInqVarIntKey(vlistID,varID,name) bind(c,name='vlistInqVarIntKey')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int) :: vlistInqVarIntKey
-        end function vlistInqVarIntKey
-      end interface
-      interface
-        function vlistInqNatts(vlistID,varID,nattsp) bind(c,name='vlistInqNatts')
-          import :: c_int
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), intent(out) :: nattsp
-          integer(kind=c_int) :: vlistInqNatts
-        end function vlistInqNatts
-      end interface
-      interface
-        function vlistInqAtt(vlistID,varID,attrnum,name,typep,lenp) bind(c,name='vlistInqAtt')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          integer(kind=c_int), value :: attrnum
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int), intent(out) :: typep
-          integer(kind=c_int), intent(out) :: lenp
-          integer(kind=c_int) :: vlistInqAtt
-        end function vlistInqAtt
-      end interface
-      interface
-        function vlistDelAtt(vlistID,varID,name) bind(c,name='vlistDelAtt')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int) :: vlistDelAtt
-        end function vlistDelAtt
-      end interface
-      interface
-        function vlistDefAttInt(vlistID,varID,name,type,len,ip_vec) bind(c,name='vlistDefAttInt')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int), value :: type
-          integer(kind=c_int), value :: len
-          integer(kind=c_int), intent(in), dimension(*) :: ip_vec
-          integer(kind=c_int) :: vlistDefAttInt
-        end function vlistDefAttInt
-      end interface
-      interface
-        function vlistDefAttFlt(vlistID,varID,name,type,len,dp_vec) bind(c,name='vlistDefAttFlt')
-          import :: c_int,c_char,c_double
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int), value :: type
-          integer(kind=c_int), value :: len
-          real(kind=c_double), intent(in), dimension(*) :: dp_vec
-          integer(kind=c_int) :: vlistDefAttFlt
-        end function vlistDefAttFlt
-      end interface
-      interface
-        function vlistDefAttTxt(vlistID,varID,name,len,tp_cbuf) bind(c,name='vlistDefAttTxt')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int), value :: len
-          character(kind=c_char), dimension(*) :: tp_cbuf
-          integer(kind=c_int) :: vlistDefAttTxt
-        end function vlistDefAttTxt
-      end interface
-      interface
-        function vlistInqAttInt(vlistID,varID,name,mlen,ip_vec) bind(c,name='vlistInqAttInt')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int), value :: mlen
-          integer(kind=c_int), intent(out), dimension(*) :: ip_vec
-          integer(kind=c_int) :: vlistInqAttInt
-        end function vlistInqAttInt
-      end interface
-      interface
-        function vlistInqAttFlt(vlistID,varID,name,mlen,dp_vec) bind(c,name='vlistInqAttFlt')
-          import :: c_int,c_char,c_double
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int), value :: mlen
-          real(kind=c_double), intent(out), dimension(*) :: dp_vec
-          integer(kind=c_int) :: vlistInqAttFlt
-        end function vlistInqAttFlt
-      end interface
-      interface
-        function vlistInqAttTxt(vlistID,varID,name,mlen,tp_cbuf) bind(c,name='vlistInqAttTxt')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: vlistID
-          integer(kind=c_int), value :: varID
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int), value :: mlen
-          character(kind=c_char), dimension(*) :: tp_cbuf
-          integer(kind=c_int) :: vlistInqAttTxt
-        end function vlistInqAttTxt
-      end interface
-      interface
-        subroutine gridName(gridtype,gridnamev) bind(c,name='gridName')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridtype
-          character(kind=c_char), dimension(*) :: gridnamev
-        end subroutine gridName
-      end interface
-      interface
-        subroutine gridCompress(gridID) bind(c,name='gridCompress')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-        end subroutine gridCompress
-      end interface
-      interface
-        subroutine gridDefMaskGME(gridID,mask_vec) bind(c,name='gridDefMaskGME')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), intent(in), dimension(*) :: mask_vec
-        end subroutine gridDefMaskGME
-      end interface
-      interface
-        function gridInqMaskGME(gridID,mask_vec) bind(c,name='gridInqMaskGME')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), intent(out), dimension(*) :: mask_vec
-          integer(kind=c_int) :: gridInqMaskGME
-        end function gridInqMaskGME
-      end interface
-      interface
-        subroutine gridDefMask(gridID,mask_vec) bind(c,name='gridDefMask')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), intent(in), dimension(*) :: mask_vec
-        end subroutine gridDefMask
-      end interface
-      interface
-        function gridInqMask(gridID,mask_vec) bind(c,name='gridInqMask')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), intent(out), dimension(*) :: mask_vec
-          integer(kind=c_int) :: gridInqMask
-        end function gridInqMask
-      end interface
-      interface
-        subroutine gridPrint(gridID,index,opt) bind(c,name='gridPrint')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: index
-          integer(kind=c_int), value :: opt
-        end subroutine gridPrint
-      end interface
-      interface
-        function gridCreate(gridtype,size) bind(c,name='gridCreate')
-          import :: c_int
-          integer(kind=c_int), value :: gridtype
-          integer(kind=c_int), value :: size
-          integer(kind=c_int) :: gridCreate
-        end function gridCreate
-      end interface
-      interface
-        subroutine gridDestroy(gridID) bind(c,name='gridDestroy')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-        end subroutine gridDestroy
-      end interface
-      interface
-        function gridDuplicate(gridID) bind(c,name='gridDuplicate')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridDuplicate
-        end function gridDuplicate
-      end interface
-      interface
-        function gridInqType(gridID) bind(c,name='gridInqType')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqType
-        end function gridInqType
-      end interface
-      interface
-        function gridInqSize(gridID) bind(c,name='gridInqSize')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqSize
-        end function gridInqSize
-      end interface
-      interface
-        subroutine gridDefXsize(gridID,xsize) bind(c,name='gridDefXsize')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: xsize
-        end subroutine gridDefXsize
-      end interface
-      interface
-        function gridInqXsize(gridID) bind(c,name='gridInqXsize')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqXsize
-        end function gridInqXsize
-      end interface
-      interface
-        subroutine gridDefYsize(gridID,ysize) bind(c,name='gridDefYsize')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: ysize
-        end subroutine gridDefYsize
-      end interface
-      interface
-        function gridInqYsize(gridID) bind(c,name='gridInqYsize')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqYsize
-        end function gridInqYsize
-      end interface
-      interface
-        subroutine gridDefNP(gridID,np) bind(c,name='gridDefNP')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: np
-        end subroutine gridDefNP
-      end interface
-      interface
-        function gridInqNP(gridID) bind(c,name='gridInqNP')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqNP
-        end function gridInqNP
-      end interface
-      interface
-        subroutine gridDefXvals(gridID,xvals_vec) bind(c,name='gridDefXvals')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), intent(in), dimension(*) :: xvals_vec
-        end subroutine gridDefXvals
-      end interface
-      interface
-        function gridInqXvals(gridID,xvals_vec) bind(c,name='gridInqXvals')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), intent(out), dimension(*) :: xvals_vec
-          integer(kind=c_int) :: gridInqXvals
-        end function gridInqXvals
-      end interface
-      interface
-        subroutine gridDefYvals(gridID,yvals_vec) bind(c,name='gridDefYvals')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), intent(in), dimension(*) :: yvals_vec
-        end subroutine gridDefYvals
-      end interface
-      interface
-        function gridInqYvals(gridID,yvals_vec) bind(c,name='gridInqYvals')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), intent(out), dimension(*) :: yvals_vec
-          integer(kind=c_int) :: gridInqYvals
-        end function gridInqYvals
-      end interface
-      interface
-        subroutine gridDefXname(gridID,xname) bind(c,name='gridDefXname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: xname
-        end subroutine gridDefXname
-      end interface
-      interface
-        subroutine gridInqXname(gridID,xname) bind(c,name='gridInqXname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: xname
-        end subroutine gridInqXname
-      end interface
-      interface
-        subroutine gridDefXlongname(gridID,xlongname) bind(c,name='gridDefXlongname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: xlongname
-        end subroutine gridDefXlongname
-      end interface
-      interface
-        subroutine gridInqXlongname(gridID,xlongname) bind(c,name='gridInqXlongname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: xlongname
-        end subroutine gridInqXlongname
-      end interface
-      interface
-        subroutine gridDefXunits(gridID,xunits) bind(c,name='gridDefXunits')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: xunits
-        end subroutine gridDefXunits
-      end interface
-      interface
-        subroutine gridInqXunits(gridID,xunits) bind(c,name='gridInqXunits')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: xunits
-        end subroutine gridInqXunits
-      end interface
-      interface
-        subroutine gridDefYname(gridID,yname) bind(c,name='gridDefYname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: yname
-        end subroutine gridDefYname
-      end interface
-      interface
-        subroutine gridInqYname(gridID,yname) bind(c,name='gridInqYname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: yname
-        end subroutine gridInqYname
-      end interface
-      interface
-        subroutine gridDefYlongname(gridID,ylongname) bind(c,name='gridDefYlongname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: ylongname
-        end subroutine gridDefYlongname
-      end interface
-      interface
-        subroutine gridInqYlongname(gridID,ylongname) bind(c,name='gridInqYlongname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: ylongname
-        end subroutine gridInqYlongname
-      end interface
-      interface
-        subroutine gridDefYunits(gridID,yunits) bind(c,name='gridDefYunits')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: yunits
-        end subroutine gridDefYunits
-      end interface
-      interface
-        subroutine gridInqYunits(gridID,yunits) bind(c,name='gridInqYunits')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: yunits
-        end subroutine gridInqYunits
-      end interface
-      interface
-        subroutine gridInqXstdname(gridID,xstdname) bind(c,name='gridInqXstdname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: xstdname
-        end subroutine gridInqXstdname
-      end interface
-      interface
-        subroutine gridInqYstdname(gridID,ystdname) bind(c,name='gridInqYstdname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: ystdname
-        end subroutine gridInqYstdname
-      end interface
-      interface
-        subroutine gridDefPrec(gridID,prec) bind(c,name='gridDefPrec')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: prec
-        end subroutine gridDefPrec
-      end interface
-      interface
-        function gridInqPrec(gridID) bind(c,name='gridInqPrec')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqPrec
-        end function gridInqPrec
-      end interface
-      interface
-        function gridInqXval(gridID,index) bind(c,name='gridInqXval')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: index
-          real(kind=c_double) :: gridInqXval
-        end function gridInqXval
-      end interface
-      interface
-        function gridInqYval(gridID,index) bind(c,name='gridInqYval')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: index
-          real(kind=c_double) :: gridInqYval
-        end function gridInqYval
-      end interface
-      interface
-        function gridInqXinc(gridID) bind(c,name='gridInqXinc')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double) :: gridInqXinc
-        end function gridInqXinc
-      end interface
-      interface
-        function gridInqYinc(gridID) bind(c,name='gridInqYinc')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double) :: gridInqYinc
-        end function gridInqYinc
-      end interface
-      interface
-        function gridIsCircular(gridID) bind(c,name='gridIsCircular')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridIsCircular
-        end function gridIsCircular
-      end interface
-      interface
-        function gridIsRotated(gridID) bind(c,name='gridIsRotated')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridIsRotated
-        end function gridIsRotated
-      end interface
-      interface
-        subroutine gridDefXpole(gridID,xpole) bind(c,name='gridDefXpole')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), value :: xpole
-        end subroutine gridDefXpole
-      end interface
-      interface
-        function gridInqXpole(gridID) bind(c,name='gridInqXpole')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double) :: gridInqXpole
-        end function gridInqXpole
-      end interface
-      interface
-        subroutine gridDefYpole(gridID,ypole) bind(c,name='gridDefYpole')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), value :: ypole
-        end subroutine gridDefYpole
-      end interface
-      interface
-        function gridInqYpole(gridID) bind(c,name='gridInqYpole')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double) :: gridInqYpole
-        end function gridInqYpole
-      end interface
-      interface
-        subroutine gridDefAngle(gridID,angle) bind(c,name='gridDefAngle')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), value :: angle
-        end subroutine gridDefAngle
-      end interface
-      interface
-        function gridInqAngle(gridID) bind(c,name='gridInqAngle')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double) :: gridInqAngle
-        end function gridInqAngle
-      end interface
-      interface
-        function gridInqTrunc(gridID) bind(c,name='gridInqTrunc')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqTrunc
-        end function gridInqTrunc
-      end interface
-      interface
-        subroutine gridDefTrunc(gridID,trunc) bind(c,name='gridDefTrunc')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: trunc
-        end subroutine gridDefTrunc
-      end interface
-      interface
-        subroutine gridDefGMEnd(gridID,nd) bind(c,name='gridDefGMEnd')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: nd
-        end subroutine gridDefGMEnd
-      end interface
-      interface
-        function gridInqGMEnd(gridID) bind(c,name='gridInqGMEnd')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqGMEnd
-        end function gridInqGMEnd
-      end interface
-      interface
-        subroutine gridDefGMEni(gridID,ni) bind(c,name='gridDefGMEni')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: ni
-        end subroutine gridDefGMEni
-      end interface
-      interface
-        function gridInqGMEni(gridID) bind(c,name='gridInqGMEni')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqGMEni
-        end function gridInqGMEni
-      end interface
-      interface
-        subroutine gridDefGMEni2(gridID,ni2) bind(c,name='gridDefGMEni2')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: ni2
-        end subroutine gridDefGMEni2
-      end interface
-      interface
-        function gridInqGMEni2(gridID) bind(c,name='gridInqGMEni2')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqGMEni2
-        end function gridInqGMEni2
-      end interface
-      interface
-        subroutine gridDefGMEni3(gridID,ni3) bind(c,name='gridDefGMEni3')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: ni3
-        end subroutine gridDefGMEni3
-      end interface
-      interface
-        function gridInqGMEni3(gridID) bind(c,name='gridInqGMEni3')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqGMEni3
-        end function gridInqGMEni3
-      end interface
-      interface
-        subroutine gridDefNumber(gridID,number) bind(c,name='gridDefNumber')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: number
-        end subroutine gridDefNumber
-      end interface
-      interface
-        function gridInqNumber(gridID) bind(c,name='gridInqNumber')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqNumber
-        end function gridInqNumber
-      end interface
-      interface
-        subroutine gridDefPosition(gridID,position) bind(c,name='gridDefPosition')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: position
-        end subroutine gridDefPosition
-      end interface
-      interface
-        function gridInqPosition(gridID) bind(c,name='gridInqPosition')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqPosition
-        end function gridInqPosition
-      end interface
-      interface
-        subroutine gridDefReference(gridID,reference) bind(c,name='gridDefReference')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: reference
-        end subroutine gridDefReference
-      end interface
-      interface
-        function gridInqReference(gridID,reference) bind(c,name='gridInqReference')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: gridID
-          character(kind=c_char), dimension(*) :: reference
-          integer(kind=c_int) :: gridInqReference
-        end function gridInqReference
-      end interface
-      interface
-        subroutine gridDefUUID(gridID,uuid) bind(c,name='gridDefUUID')
-          import :: c_int,c_signed_char
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_signed_char), intent(in), dimension(16) :: uuid
-        end subroutine gridDefUUID
-      end interface
-      interface
-        subroutine gridInqUUID(gridID,uuid) bind(c,name='gridInqUUID')
-          import :: c_int,c_signed_char
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_signed_char), intent(out), dimension(16) :: uuid
-        end subroutine gridInqUUID
-      end interface
-      interface
-        subroutine gridDefLCC(gridID,originLon,originLat,lonParY,lat1,lat2,xinc,yinc,projflag,scanflag) bind(c,name='gridDefLCC')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), value :: originLon
-          real(kind=c_double), value :: originLat
-          real(kind=c_double), value :: lonParY
-          real(kind=c_double), value :: lat1
-          real(kind=c_double), value :: lat2
-          real(kind=c_double), value :: xinc
-          real(kind=c_double), value :: yinc
-          integer(kind=c_int), value :: projflag
-          integer(kind=c_int), value :: scanflag
-        end subroutine gridDefLCC
-      end interface
-      interface
-        subroutine gridInqLCC(gridID,originLon,originLat,lonParY,lat1,lat2,xinc,yinc,projflag,scanflag) bind(c,name='gridInqLCC')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), intent(out) :: originLon
-          real(kind=c_double), intent(out) :: originLat
-          real(kind=c_double), intent(out) :: lonParY
-          real(kind=c_double), intent(out) :: lat1
-          real(kind=c_double), intent(out) :: lat2
-          real(kind=c_double), intent(out) :: xinc
-          real(kind=c_double), intent(out) :: yinc
-          integer(kind=c_int), intent(out) :: projflag
-          integer(kind=c_int), intent(out) :: scanflag
-        end subroutine gridInqLCC
-      end interface
-      interface
-        subroutine gridDefLcc2(gridID,earth_radius,lon_0,lat_0,lat_1,lat_2) bind(c,name='gridDefLcc2')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), value :: earth_radius
-          real(kind=c_double), value :: lon_0
-          real(kind=c_double), value :: lat_0
-          real(kind=c_double), value :: lat_1
-          real(kind=c_double), value :: lat_2
-        end subroutine gridDefLcc2
-      end interface
-      interface
-        subroutine gridInqLcc2(gridID,earth_radius,lon_0,lat_0,lat_1,lat_2) bind(c,name='gridInqLcc2')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), intent(out) :: earth_radius
-          real(kind=c_double), intent(out) :: lon_0
-          real(kind=c_double), intent(out) :: lat_0
-          real(kind=c_double), intent(out) :: lat_1
-          real(kind=c_double), intent(out) :: lat_2
-        end subroutine gridInqLcc2
-      end interface
-      interface
-        subroutine gridDefLaea(gridID,earth_radius,lon_0,lat_0) bind(c,name='gridDefLaea')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), value :: earth_radius
-          real(kind=c_double), value :: lon_0
-          real(kind=c_double), value :: lat_0
-        end subroutine gridDefLaea
-      end interface
-      interface
-        subroutine gridInqLaea(gridID,earth_radius,lon_0,lat_0) bind(c,name='gridInqLaea')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), intent(out) :: earth_radius
-          real(kind=c_double), intent(out) :: lon_0
-          real(kind=c_double), intent(out) :: lat_0
-        end subroutine gridInqLaea
-      end interface
-      interface
-        subroutine gridDefArea(gridID,area_vec) bind(c,name='gridDefArea')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), intent(in), dimension(*) :: area_vec
-        end subroutine gridDefArea
-      end interface
-      interface
-        subroutine gridInqArea(gridID,area_vec) bind(c,name='gridInqArea')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), intent(out), dimension(*) :: area_vec
-        end subroutine gridInqArea
-      end interface
-      interface
-        function gridHasArea(gridID) bind(c,name='gridHasArea')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridHasArea
-        end function gridHasArea
-      end interface
-      interface
-        subroutine gridDefNvertex(gridID,nvertex) bind(c,name='gridDefNvertex')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: nvertex
-        end subroutine gridDefNvertex
-      end interface
-      interface
-        function gridInqNvertex(gridID) bind(c,name='gridInqNvertex')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqNvertex
-        end function gridInqNvertex
-      end interface
-      interface
-        subroutine gridDefXbounds(gridID,xbounds_vec) bind(c,name='gridDefXbounds')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), intent(in), dimension(*) :: xbounds_vec
-        end subroutine gridDefXbounds
-      end interface
-      interface
-        function gridInqXbounds(gridID,xbounds_vec) bind(c,name='gridInqXbounds')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), intent(out), dimension(*) :: xbounds_vec
-          integer(kind=c_int) :: gridInqXbounds
-        end function gridInqXbounds
-      end interface
-      interface
-        subroutine gridDefYbounds(gridID,ybounds_vec) bind(c,name='gridDefYbounds')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), intent(in), dimension(*) :: ybounds_vec
-        end subroutine gridDefYbounds
-      end interface
-      interface
-        function gridInqYbounds(gridID,ybounds_vec) bind(c,name='gridInqYbounds')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: gridID
-          real(kind=c_double), intent(out), dimension(*) :: ybounds_vec
-          integer(kind=c_int) :: gridInqYbounds
-        end function gridInqYbounds
-      end interface
-      interface
-        subroutine gridDefRowlon(gridID,nrowlon,rowlon_vec) bind(c,name='gridDefRowlon')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: nrowlon
-          integer(kind=c_int), intent(in), dimension(*) :: rowlon_vec
-        end subroutine gridDefRowlon
-      end interface
-      interface
-        subroutine gridInqRowlon(gridID,rowlon_vec) bind(c,name='gridInqRowlon')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), intent(out), dimension(*) :: rowlon_vec
-        end subroutine gridInqRowlon
-      end interface
-      interface
-        subroutine gridChangeType(gridID,gridtype) bind(c,name='gridChangeType')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: gridtype
-        end subroutine gridChangeType
-      end interface
-      interface
-        subroutine gridDefComplexPacking(gridID,lpack) bind(c,name='gridDefComplexPacking')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: lpack
-        end subroutine gridDefComplexPacking
-      end interface
-      interface
-        function gridInqComplexPacking(gridID) bind(c,name='gridInqComplexPacking')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: gridInqComplexPacking
-        end function gridInqComplexPacking
-      end interface
-      interface
-        subroutine zaxisName(zaxistype,zaxisnamev) bind(c,name='zaxisName')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: zaxistype
-          character(kind=c_char), dimension(*) :: zaxisnamev
-        end subroutine zaxisName
-      end interface
-      interface
-        function zaxisCreate(zaxistype,size) bind(c,name='zaxisCreate')
-          import :: c_int
-          integer(kind=c_int), value :: zaxistype
-          integer(kind=c_int), value :: size
-          integer(kind=c_int) :: zaxisCreate
-        end function zaxisCreate
-      end interface
-      interface
-        subroutine zaxisDestroy(zaxisID) bind(c,name='zaxisDestroy')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-        end subroutine zaxisDestroy
-      end interface
-      interface
-        function zaxisInqType(zaxisID) bind(c,name='zaxisInqType')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int) :: zaxisInqType
-        end function zaxisInqType
-      end interface
-      interface
-        function zaxisInqSize(zaxisID) bind(c,name='zaxisInqSize')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int) :: zaxisInqSize
-        end function zaxisInqSize
-      end interface
-      interface
-        function zaxisDuplicate(zaxisID) bind(c,name='zaxisDuplicate')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int) :: zaxisDuplicate
-        end function zaxisDuplicate
-      end interface
-      interface
-        subroutine zaxisResize(zaxisID,size) bind(c,name='zaxisResize')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int), value :: size
-        end subroutine zaxisResize
-      end interface
-      interface
-        subroutine zaxisPrint(zaxisID,index) bind(c,name='zaxisPrint')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int), value :: index
-        end subroutine zaxisPrint
-      end interface
-      interface
-        subroutine zaxisDefLevels(zaxisID,levels_vec) bind(c,name='zaxisDefLevels')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          real(kind=c_double), intent(in), dimension(*) :: levels_vec
-        end subroutine zaxisDefLevels
-      end interface
-      interface
-        subroutine zaxisInqLevels(zaxisID,levels_vec) bind(c,name='zaxisInqLevels')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          real(kind=c_double), intent(out), dimension(*) :: levels_vec
-        end subroutine zaxisInqLevels
-      end interface
-      interface
-        subroutine zaxisDefLevel(zaxisID,levelID,levels) bind(c,name='zaxisDefLevel')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int), value :: levelID
-          real(kind=c_double), value :: levels
-        end subroutine zaxisDefLevel
-      end interface
-      interface
-        function zaxisInqLevel(zaxisID,levelID) bind(c,name='zaxisInqLevel')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int), value :: levelID
-          real(kind=c_double) :: zaxisInqLevel
-        end function zaxisInqLevel
-      end interface
-      interface
-        subroutine zaxisDefNlevRef(gridID,nhlev) bind(c,name='zaxisDefNlevRef')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: nhlev
-        end subroutine zaxisDefNlevRef
-      end interface
-      interface
-        function zaxisInqNlevRef(gridID) bind(c,name='zaxisInqNlevRef')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: zaxisInqNlevRef
-        end function zaxisInqNlevRef
-      end interface
-      interface
-        subroutine zaxisDefNumber(gridID,number) bind(c,name='zaxisDefNumber')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int), value :: number
-        end subroutine zaxisDefNumber
-      end interface
-      interface
-        function zaxisInqNumber(gridID) bind(c,name='zaxisInqNumber')
-          import :: c_int
-          integer(kind=c_int), value :: gridID
-          integer(kind=c_int) :: zaxisInqNumber
-        end function zaxisInqNumber
-      end interface
-      interface
-        subroutine zaxisDefUUID(zaxisID,uuid) bind(c,name='zaxisDefUUID')
-          import :: c_int,c_signed_char
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_signed_char), intent(in), dimension(16) :: uuid
-        end subroutine zaxisDefUUID
-      end interface
-      interface
-        subroutine zaxisInqUUID(zaxisID,uuid) bind(c,name='zaxisInqUUID')
-          import :: c_int,c_signed_char
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_signed_char), intent(out), dimension(16) :: uuid
-        end subroutine zaxisInqUUID
-      end interface
-      interface
-        subroutine zaxisDefName(zaxisID,name) bind(c,name='zaxisDefName')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: zaxisID
-          character(kind=c_char), dimension(*) :: name
-        end subroutine zaxisDefName
-      end interface
-      interface
-        subroutine zaxisInqName(zaxisID,name) bind(c,name='zaxisInqName')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: zaxisID
-          character(kind=c_char), dimension(*) :: name
-        end subroutine zaxisInqName
-      end interface
-      interface
-        subroutine zaxisDefLongname(zaxisID,longname) bind(c,name='zaxisDefLongname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: zaxisID
-          character(kind=c_char), dimension(*) :: longname
-        end subroutine zaxisDefLongname
-      end interface
-      interface
-        subroutine zaxisInqLongname(zaxisID,longname) bind(c,name='zaxisInqLongname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: zaxisID
-          character(kind=c_char), dimension(*) :: longname
-        end subroutine zaxisInqLongname
-      end interface
-      interface
-        subroutine zaxisDefUnits(zaxisID,units) bind(c,name='zaxisDefUnits')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: zaxisID
-          character(kind=c_char), dimension(*) :: units
-        end subroutine zaxisDefUnits
-      end interface
-      interface
-        subroutine zaxisInqUnits(zaxisID,units) bind(c,name='zaxisInqUnits')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: zaxisID
-          character(kind=c_char), dimension(*) :: units
-        end subroutine zaxisInqUnits
-      end interface
-      interface
-        subroutine zaxisInqStdname(zaxisID,stdname) bind(c,name='zaxisInqStdname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: zaxisID
-          character(kind=c_char), dimension(*) :: stdname
-        end subroutine zaxisInqStdname
-      end interface
-      interface
-        subroutine zaxisDefPrec(zaxisID,prec) bind(c,name='zaxisDefPrec')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int), value :: prec
-        end subroutine zaxisDefPrec
-      end interface
-      interface
-        function zaxisInqPrec(zaxisID) bind(c,name='zaxisInqPrec')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int) :: zaxisInqPrec
-        end function zaxisInqPrec
-      end interface
-      interface
-        subroutine zaxisDefPositive(zaxisID,positive) bind(c,name='zaxisDefPositive')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int), value :: positive
-        end subroutine zaxisDefPositive
-      end interface
-      interface
-        function zaxisInqPositive(zaxisID) bind(c,name='zaxisInqPositive')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int) :: zaxisInqPositive
-        end function zaxisInqPositive
-      end interface
-      interface
-        subroutine zaxisDefLtype(zaxisID,ltype) bind(c,name='zaxisDefLtype')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int), value :: ltype
-        end subroutine zaxisDefLtype
-      end interface
-      interface
-        function zaxisInqLtype(zaxisID) bind(c,name='zaxisInqLtype')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int) :: zaxisInqLtype
-        end function zaxisInqLtype
-      end interface
-      interface
-        function zaxisInqLevelsPtr(zaxisID) bind(c,name='zaxisInqLevelsPtr')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          real(kind=c_double) :: zaxisInqLevelsPtr
-        end function zaxisInqLevelsPtr
-      end interface
-      interface
-        subroutine zaxisDefVct(zaxisID,size,vct_vec) bind(c,name='zaxisDefVct')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int), value :: size
-          real(kind=c_double), intent(in), dimension(*) :: vct_vec
-        end subroutine zaxisDefVct
-      end interface
-      interface
-        subroutine zaxisInqVct(zaxisID,vct_vec) bind(c,name='zaxisInqVct')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          real(kind=c_double), intent(out), dimension(*) :: vct_vec
-        end subroutine zaxisInqVct
-      end interface
-      interface
-        function zaxisInqVctSize(zaxisID) bind(c,name='zaxisInqVctSize')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int) :: zaxisInqVctSize
-        end function zaxisInqVctSize
-      end interface
-      interface
-        function zaxisInqVctPtr(zaxisID) bind(c,name='zaxisInqVctPtr')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          real(kind=c_double) :: zaxisInqVctPtr
-        end function zaxisInqVctPtr
-      end interface
-      interface
-        subroutine zaxisDefLbounds(zaxisID,lbounds_vec) bind(c,name='zaxisDefLbounds')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          real(kind=c_double), intent(in), dimension(*) :: lbounds_vec
-        end subroutine zaxisDefLbounds
-      end interface
-      interface
-        function zaxisInqLbounds(zaxisID,lbounds_vec) bind(c,name='zaxisInqLbounds')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          real(kind=c_double), intent(out), dimension(*) :: lbounds_vec
-          integer(kind=c_int) :: zaxisInqLbounds
-        end function zaxisInqLbounds
-      end interface
-      interface
-        function zaxisInqLbound(zaxisID,index) bind(c,name='zaxisInqLbound')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int), value :: index
-          real(kind=c_double) :: zaxisInqLbound
-        end function zaxisInqLbound
-      end interface
-      interface
-        subroutine zaxisDefUbounds(zaxisID,ubounds_vec) bind(c,name='zaxisDefUbounds')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          real(kind=c_double), intent(in), dimension(*) :: ubounds_vec
-        end subroutine zaxisDefUbounds
-      end interface
-      interface
-        function zaxisInqUbounds(zaxisID,ubounds_vec) bind(c,name='zaxisInqUbounds')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          real(kind=c_double), intent(out), dimension(*) :: ubounds_vec
-          integer(kind=c_int) :: zaxisInqUbounds
-        end function zaxisInqUbounds
-      end interface
-      interface
-        function zaxisInqUbound(zaxisID,index) bind(c,name='zaxisInqUbound')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int), value :: index
-          real(kind=c_double) :: zaxisInqUbound
-        end function zaxisInqUbound
-      end interface
-      interface
-        subroutine zaxisDefWeights(zaxisID,weights_vec) bind(c,name='zaxisDefWeights')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          real(kind=c_double), intent(in), dimension(*) :: weights_vec
-        end subroutine zaxisDefWeights
-      end interface
-      interface
-        function zaxisInqWeights(zaxisID,weights_vec) bind(c,name='zaxisInqWeights')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: zaxisID
-          real(kind=c_double), intent(out), dimension(*) :: weights_vec
-          integer(kind=c_int) :: zaxisInqWeights
-        end function zaxisInqWeights
-      end interface
-      interface
-        subroutine zaxisChangeType(zaxisID,zaxistype) bind(c,name='zaxisChangeType')
-          import :: c_int
-          integer(kind=c_int), value :: zaxisID
-          integer(kind=c_int), value :: zaxistype
-        end subroutine zaxisChangeType
-      end interface
-      interface
-        function taxisCreate(timetype) bind(c,name='taxisCreate')
-          import :: c_int
-          integer(kind=c_int), value :: timetype
-          integer(kind=c_int) :: taxisCreate
-        end function taxisCreate
-      end interface
-      interface
-        subroutine taxisDestroy(taxisID) bind(c,name='taxisDestroy')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-        end subroutine taxisDestroy
-      end interface
-      interface
-        function taxisDuplicate(taxisID) bind(c,name='taxisDuplicate')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int) :: taxisDuplicate
-        end function taxisDuplicate
-      end interface
-      interface
-        subroutine taxisCopyTimestep(taxisIDdes,taxisIDsrc) bind(c,name='taxisCopyTimestep')
-          import :: c_int
-          integer(kind=c_int), value :: taxisIDdes
-          integer(kind=c_int), value :: taxisIDsrc
-        end subroutine taxisCopyTimestep
-      end interface
-      interface
-        subroutine taxisDefType(taxisID,type) bind(c,name='taxisDefType')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), value :: type
-        end subroutine taxisDefType
-      end interface
-      interface
-        subroutine taxisDefVdate(taxisID,date) bind(c,name='taxisDefVdate')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), value :: date
-        end subroutine taxisDefVdate
-      end interface
-      interface
-        subroutine taxisDefVtime(taxisID,time) bind(c,name='taxisDefVtime')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), value :: time
-        end subroutine taxisDefVtime
-      end interface
-      interface
-        function taxisInqVdate(taxisID) bind(c,name='taxisInqVdate')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int) :: taxisInqVdate
-        end function taxisInqVdate
-      end interface
-      interface
-        function taxisInqVtime(taxisID) bind(c,name='taxisInqVtime')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int) :: taxisInqVtime
-        end function taxisInqVtime
-      end interface
-      interface
-        subroutine taxisDefRdate(taxisID,date) bind(c,name='taxisDefRdate')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), value :: date
-        end subroutine taxisDefRdate
-      end interface
-      interface
-        subroutine taxisDefRtime(taxisID,time) bind(c,name='taxisDefRtime')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), value :: time
-        end subroutine taxisDefRtime
-      end interface
-      interface
-        function taxisInqRdate(taxisID) bind(c,name='taxisInqRdate')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int) :: taxisInqRdate
-        end function taxisInqRdate
-      end interface
-      interface
-        function taxisInqRtime(taxisID) bind(c,name='taxisInqRtime')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int) :: taxisInqRtime
-        end function taxisInqRtime
-      end interface
-      interface
-        subroutine taxisDefFdate(taxisID,date) bind(c,name='taxisDefFdate')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), value :: date
-        end subroutine taxisDefFdate
-      end interface
-      interface
-        subroutine taxisDefFtime(taxisID,time) bind(c,name='taxisDefFtime')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), value :: time
-        end subroutine taxisDefFtime
-      end interface
-      interface
-        function taxisInqFdate(taxisID) bind(c,name='taxisInqFdate')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int) :: taxisInqFdate
-        end function taxisInqFdate
-      end interface
-      interface
-        function taxisInqFtime(taxisID) bind(c,name='taxisInqFtime')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int) :: taxisInqFtime
-        end function taxisInqFtime
-      end interface
-      interface
-        function taxisHasBounds(taxisID) bind(c,name='taxisHasBounds')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int) :: taxisHasBounds
-        end function taxisHasBounds
-      end interface
-      interface
-        subroutine taxisDeleteBounds(taxisID) bind(c,name='taxisDeleteBounds')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-        end subroutine taxisDeleteBounds
-      end interface
-      interface
-        subroutine taxisDefVdateBounds(taxisID,vdate_lb,vdate_ub) bind(c,name='taxisDefVdateBounds')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), value :: vdate_lb
-          integer(kind=c_int), value :: vdate_ub
-        end subroutine taxisDefVdateBounds
-      end interface
-      interface
-        subroutine taxisDefVtimeBounds(taxisID,vtime_lb,vtime_ub) bind(c,name='taxisDefVtimeBounds')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), value :: vtime_lb
-          integer(kind=c_int), value :: vtime_ub
-        end subroutine taxisDefVtimeBounds
-      end interface
-      interface
-        subroutine taxisInqVdateBounds(taxisID,vdate_lb,vdate_ub) bind(c,name='taxisInqVdateBounds')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), intent(out) :: vdate_lb
-          integer(kind=c_int), intent(out) :: vdate_ub
-        end subroutine taxisInqVdateBounds
-      end interface
-      interface
-        subroutine taxisInqVtimeBounds(taxisID,vtime_lb,vtime_ub) bind(c,name='taxisInqVtimeBounds')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), intent(out) :: vtime_lb
-          integer(kind=c_int), intent(out) :: vtime_ub
-        end subroutine taxisInqVtimeBounds
-      end interface
-      interface
-        subroutine taxisDefCalendar(taxisID,calendar) bind(c,name='taxisDefCalendar')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), value :: calendar
-        end subroutine taxisDefCalendar
-      end interface
-      interface
-        function taxisInqCalendar(taxisID) bind(c,name='taxisInqCalendar')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int) :: taxisInqCalendar
-        end function taxisInqCalendar
-      end interface
-      interface
-        subroutine taxisDefTunit(taxisID,tunit) bind(c,name='taxisDefTunit')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), value :: tunit
-        end subroutine taxisDefTunit
-      end interface
-      interface
-        function taxisInqTunit(taxisID) bind(c,name='taxisInqTunit')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int) :: taxisInqTunit
-        end function taxisInqTunit
-      end interface
-      interface
-        subroutine taxisDefForecastTunit(taxisID,tunit) bind(c,name='taxisDefForecastTunit')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), value :: tunit
-        end subroutine taxisDefForecastTunit
-      end interface
-      interface
-        function taxisInqForecastTunit(taxisID) bind(c,name='taxisInqForecastTunit')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int) :: taxisInqForecastTunit
-        end function taxisInqForecastTunit
-      end interface
-      interface
-        subroutine taxisDefForecastPeriod(taxisID,fc_period) bind(c,name='taxisDefForecastPeriod')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: taxisID
-          real(kind=c_double), value :: fc_period
-        end subroutine taxisDefForecastPeriod
-      end interface
-      interface
-        function taxisInqForecastPeriod(taxisID) bind(c,name='taxisInqForecastPeriod')
-          import :: c_int,c_double
-          integer(kind=c_int), value :: taxisID
-          real(kind=c_double) :: taxisInqForecastPeriod
-        end function taxisInqForecastPeriod
-      end interface
-      interface
-        subroutine taxisDefNumavg(taxisID,numavg) bind(c,name='taxisDefNumavg')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int), value :: numavg
-        end subroutine taxisDefNumavg
-      end interface
-      interface
-        function taxisInqType(taxisID) bind(c,name='taxisInqType')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int) :: taxisInqType
-        end function taxisInqType
-      end interface
-      interface
-        function taxisInqNumavg(taxisID) bind(c,name='taxisInqNumavg')
-          import :: c_int
-          integer(kind=c_int), value :: taxisID
-          integer(kind=c_int) :: taxisInqNumavg
-        end function taxisInqNumavg
-      end interface
-      interface
-        function institutDef(center,subcenter,name,longname) bind(c,name='institutDef')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: center
-          integer(kind=c_int), value :: subcenter
-          character(kind=c_char), dimension(*) :: name
-          character(kind=c_char), dimension(*) :: longname
-          integer(kind=c_int) :: institutDef
-        end function institutDef
-      end interface
-      interface
-        function institutInq(center,subcenter,name,longname) bind(c,name='institutInq')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: center
-          integer(kind=c_int), value :: subcenter
-          character(kind=c_char), dimension(*) :: name
-          character(kind=c_char), dimension(*) :: longname
-          integer(kind=c_int) :: institutInq
-        end function institutInq
-      end interface
-      interface
-        function institutInqNumber() bind(c,name='institutInqNumber')
-          import :: c_int
-          integer(kind=c_int) :: institutInqNumber
-        end function institutInqNumber
-      end interface
-      interface
-        function institutInqCenter(instID) bind(c,name='institutInqCenter')
-          import :: c_int
-          integer(kind=c_int), value :: instID
-          integer(kind=c_int) :: institutInqCenter
-        end function institutInqCenter
-      end interface
-      interface
-        function institutInqSubcenter(instID) bind(c,name='institutInqSubcenter')
-          import :: c_int
-          integer(kind=c_int), value :: instID
-          integer(kind=c_int) :: institutInqSubcenter
-        end function institutInqSubcenter
-      end interface
-      interface
-        function modelDef(instID,modelgribID,name) bind(c,name='modelDef')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: instID
-          integer(kind=c_int), value :: modelgribID
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int) :: modelDef
-        end function modelDef
-      end interface
-      interface
-        function modelInq(instID,modelgribID,name) bind(c,name='modelInq')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: instID
-          integer(kind=c_int), value :: modelgribID
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int) :: modelInq
-        end function modelInq
-      end interface
-      interface
-        function modelInqInstitut(modelID) bind(c,name='modelInqInstitut')
-          import :: c_int
-          integer(kind=c_int), value :: modelID
-          integer(kind=c_int) :: modelInqInstitut
-        end function modelInqInstitut
-      end interface
-      interface
-        function modelInqGribID(modelID) bind(c,name='modelInqGribID')
-          import :: c_int
-          integer(kind=c_int), value :: modelID
-          integer(kind=c_int) :: modelInqGribID
-        end function modelInqGribID
-      end interface
-      interface
-        subroutine tableWriteC(filename,tableID) bind(c,name='tableWriteC')
-          import :: c_char,c_int
-          character(kind=c_char), dimension(*) :: filename
-          integer(kind=c_int), value :: tableID
-        end subroutine tableWriteC
-      end interface
-      interface
-        subroutine tableWrite(filename,tableID) bind(c,name='tableWrite')
-          import :: c_char,c_int
-          character(kind=c_char), dimension(*) :: filename
-          integer(kind=c_int), value :: tableID
-        end subroutine tableWrite
-      end interface
-      interface
-        function tableRead(tablefile) bind(c,name='tableRead')
-          import :: c_char,c_int
-          character(kind=c_char), dimension(*) :: tablefile
-          integer(kind=c_int) :: tableRead
-        end function tableRead
-      end interface
-      interface
-        function tableDef(modelID,tablenum,tablename) bind(c,name='tableDef')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: modelID
-          integer(kind=c_int), value :: tablenum
-          character(kind=c_char), dimension(*) :: tablename
-          integer(kind=c_int) :: tableDef
-        end function tableDef
-      end interface
-      interface
-        subroutine tableDefEntry(tableID,code,name,longname,units) bind(c,name='tableDefEntry')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: tableID
-          integer(kind=c_int), value :: code
-          character(kind=c_char), dimension(*) :: name
-          character(kind=c_char), dimension(*) :: longname
-          character(kind=c_char), dimension(*) :: units
-        end subroutine tableDefEntry
-      end interface
-      interface
-        function tableInq(modelID,tablenum,tablename) bind(c,name='tableInq')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: modelID
-          integer(kind=c_int), value :: tablenum
-          character(kind=c_char), dimension(*) :: tablename
-          integer(kind=c_int) :: tableInq
-        end function tableInq
-      end interface
-      interface
-        function tableInqNumber() bind(c,name='tableInqNumber')
-          import :: c_int
-          integer(kind=c_int) :: tableInqNumber
-        end function tableInqNumber
-      end interface
-      interface
-        function tableInqNum(tableID) bind(c,name='tableInqNum')
-          import :: c_int
-          integer(kind=c_int), value :: tableID
-          integer(kind=c_int) :: tableInqNum
-        end function tableInqNum
-      end interface
-      interface
-        function tableInqModel(tableID) bind(c,name='tableInqModel')
-          import :: c_int
-          integer(kind=c_int), value :: tableID
-          integer(kind=c_int) :: tableInqModel
-        end function tableInqModel
-      end interface
-      interface
-        subroutine tableInqPar(tableID,code,name,longname,units) bind(c,name='tableInqPar')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: tableID
-          integer(kind=c_int), value :: code
-          character(kind=c_char), dimension(*) :: name
-          character(kind=c_char), dimension(*) :: longname
-          character(kind=c_char), dimension(*) :: units
-        end subroutine tableInqPar
-      end interface
-      interface
-        function tableInqParCode(tableID,name,code) bind(c,name='tableInqParCode')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: tableID
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int), intent(out) :: code
-          integer(kind=c_int) :: tableInqParCode
-        end function tableInqParCode
-      end interface
-      interface
-        function tableInqParName(tableID,code,name) bind(c,name='tableInqParName')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: tableID
-          integer(kind=c_int), value :: code
-          character(kind=c_char), dimension(*) :: name
-          integer(kind=c_int) :: tableInqParName
-        end function tableInqParName
-      end interface
-      interface
-        function tableInqParLongname(tableID,code,longname) bind(c,name='tableInqParLongname')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: tableID
-          integer(kind=c_int), value :: code
-          character(kind=c_char), dimension(*) :: longname
-          integer(kind=c_int) :: tableInqParLongname
-        end function tableInqParLongname
-      end interface
-      interface
-        function tableInqParUnits(tableID,code,units) bind(c,name='tableInqParUnits')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: tableID
-          integer(kind=c_int), value :: code
-          character(kind=c_char), dimension(*) :: units
-          integer(kind=c_int) :: tableInqParUnits
-        end function tableInqParUnits
-      end interface
-      interface
-        subroutine streamDefHistory(streamID,size,history) bind(c,name='streamDefHistory')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int), value :: size
-          character(kind=c_char), dimension(*) :: history
-        end subroutine streamDefHistory
-      end interface
-      interface
-        function streamInqHistorySize(streamID) bind(c,name='streamInqHistorySize')
-          import :: c_int
-          integer(kind=c_int), value :: streamID
-          integer(kind=c_int) :: streamInqHistorySize
-        end function streamInqHistorySize
-      end interface
-      interface
-        subroutine streamInqHistoryString(streamID,history) bind(c,name='streamInqHistoryString')
-          import :: c_int,c_char
-          integer(kind=c_int), value :: streamID
-          character(kind=c_char), dimension(*) :: history
-        end subroutine streamInqHistoryString
-      end interface
-      interface
-        subroutine gribapiLibraryVersion(major_version,minor_version,revision_version) bind(c,name='gribapiLibraryVersion')
-          import :: c_int
-          integer(kind=c_int), intent(out) :: major_version
-          integer(kind=c_int), intent(out) :: minor_version
-          integer(kind=c_int), intent(out) :: revision_version
-        end subroutine gribapiLibraryVersion
-      end interface
-
-      public :: strlen
-      public :: getchar
-      public :: getchar_unlocked
-      public :: cdiReset
-      public :: cdiStringError
-      public :: cdiDebug
-      public :: cdiLibraryVersion
-      public :: cdiPrintVersion
-      public :: cdiHaveFiletype
-      public :: cdiDefMissval
-      public :: cdiInqMissval
-      public :: cdiDefGlobal
-      public :: namespaceNew
-      public :: namespaceSetActive
-      public :: namespaceDelete
-      public :: cdiParamToString
-      public :: cdiDecodeParam
-      public :: cdiEncodeParam
-      public :: cdiDecodeDate
-      public :: cdiEncodeDate
-      public :: cdiDecodeTime
-      public :: cdiEncodeTime
-      public :: cdiGetFiletype
-      public :: streamOpenRead
-      public :: streamOpenWrite
-      public :: streamOpenAppend
-      public :: streamClose
-      public :: streamSync
-      public :: streamDefVlist
-      public :: streamInqVlist
-      public :: streamInqVlistIDorig
-      public :: streamInqFiletype
-      public :: streamDefByteorder
-      public :: streamInqByteorder
-      public :: streamDefCompType
-      public :: streamInqCompType
-      public :: streamDefCompLevel
-      public :: streamInqCompLevel
-      public :: streamDefTimestep
-      public :: streamInqTimestep
-      public :: streamInqCurTimestepID
-      public :: streamFilename
-      public :: streamFilesuffix
-      public :: streamInqNvars
-      public :: streamWriteVar
-      public :: streamWriteVarF
-      public :: streamReadVar
-      public :: streamReadVarF
-      public :: streamWriteVarSlice
-      public :: streamWriteVarSliceF
-      public :: streamReadVarSlice
-      public :: streamReadVarSliceF
-      public :: streamDefRecord
-      public :: streamInqRecord
-      public :: streamWriteRecord
-      public :: streamWriteRecordF
-      public :: streamReadRecord
-      public :: streamCopyRecord
-      public :: vlistCreate
-      public :: vlistDestroy
-      public :: vlistDuplicate
-      public :: vlistCopy
-      public :: vlistCopyFlag
-      public :: vlistClearFlag
-      public :: vlistCat
-      public :: vlistMerge
-      public :: vlistPrint
-      public :: vlistNumber
-      public :: vlistNvars
-      public :: vlistNgrids
-      public :: vlistNzaxis
-      public :: vlistDefNtsteps
-      public :: vlistNtsteps
-      public :: vlistGridsizeMax
-      public :: vlistGrid
-      public :: vlistGridIndex
-      public :: vlistChangeGridIndex
-      public :: vlistChangeGrid
-      public :: vlistZaxis
-      public :: vlistZaxisIndex
-      public :: vlistChangeZaxisIndex
-      public :: vlistChangeZaxis
-      public :: vlistNrecs
-      public :: vlistDefTaxis
-      public :: vlistInqTaxis
-      public :: vlistDefTable
-      public :: vlistInqTable
-      public :: vlistDefInstitut
-      public :: vlistInqInstitut
-      public :: vlistDefModel
-      public :: vlistInqModel
-      public :: vlistDefVar
-      public :: vlistChangeVarGrid
-      public :: vlistChangeVarZaxis
-      public :: vlistInqVar
-      public :: vlistInqVarGrid
-      public :: vlistInqVarZaxis
-      public :: vlistInqVarID
-      public :: vlistDefVarTsteptype
-      public :: vlistInqVarTsteptype
-      public :: vlistDefVarCompType
-      public :: vlistInqVarCompType
-      public :: vlistDefVarCompLevel
-      public :: vlistInqVarCompLevel
-      public :: vlistDefVarParam
-      public :: vlistInqVarParam
-      public :: vlistDefVarCode
-      public :: vlistInqVarCode
-      public :: vlistDefVarDatatype
-      public :: vlistInqVarDatatype
-      public :: vlistDefVarChunkType
-      public :: vlistInqVarChunkType
-      public :: vlistDefVarXYZ
-      public :: vlistInqVarXYZ
-      public :: vlistInqVarNumber
-      public :: vlistDefVarInstitut
-      public :: vlistInqVarInstitut
-      public :: vlistDefVarModel
-      public :: vlistInqVarModel
-      public :: vlistDefVarTable
-      public :: vlistInqVarTable
-      public :: vlistDefVarName
-      public :: vlistInqVarName
-      public :: vlistDefVarStdname
-      public :: vlistInqVarStdname
-      public :: vlistDefVarLongname
-      public :: vlistInqVarLongname
-      public :: vlistDefVarUnits
-      public :: vlistInqVarUnits
-      public :: vlistDefVarMissval
-      public :: vlistInqVarMissval
-      public :: vlistDefVarExtra
-      public :: vlistInqVarExtra
-      public :: vlistDefVarScalefactor
-      public :: vlistInqVarScalefactor
-      public :: vlistDefVarAddoffset
-      public :: vlistInqVarAddoffset
-      public :: vlistDefVarTimave
-      public :: vlistInqVarTimave
-      public :: vlistDefVarTimaccu
-      public :: vlistInqVarTimaccu
-      public :: vlistDefVarTypeOfGeneratingProcess
-      public :: vlistInqVarTypeOfGeneratingProcess
-      public :: vlistDefVarProductDefinitionTemplate
-      public :: vlistInqVarProductDefinitionTemplate
-      public :: vlistInqVarSize
-      public :: vlistDefIndex
-      public :: vlistInqIndex
-      public :: vlistDefFlag
-      public :: vlistInqFlag
-      public :: vlistFindVar
-      public :: vlistFindLevel
-      public :: vlistMergedVar
-      public :: vlistMergedLevel
-      public :: vlistDefVarEnsemble
-      public :: vlistInqVarEnsemble
-      public :: cdiClearAdditionalKeys
-      public :: cdiDefAdditionalKey
-      public :: vlistDefVarIntKey
-      public :: vlistDefVarDblKey
-      public :: vlistHasVarKey
-      public :: vlistInqVarDblKey
-      public :: vlistInqVarIntKey
-      public :: vlistInqNatts
-      public :: vlistInqAtt
-      public :: vlistDelAtt
-      public :: vlistDefAttInt
-      public :: vlistDefAttFlt
-      public :: vlistDefAttTxt
-      public :: vlistInqAttInt
-      public :: vlistInqAttFlt
-      public :: vlistInqAttTxt
-      public :: gridName
-      public :: gridNamePtr
-      public :: gridCompress
-      public :: gridDefMaskGME
-      public :: gridInqMaskGME
-      public :: gridDefMask
-      public :: gridInqMask
-      public :: gridPrint
-      public :: gridCreate
-      public :: gridDestroy
-      public :: gridDuplicate
-      public :: gridInqType
-      public :: gridInqSize
-      public :: gridDefXsize
-      public :: gridInqXsize
-      public :: gridDefYsize
-      public :: gridInqYsize
-      public :: gridDefNP
-      public :: gridInqNP
-      public :: gridDefXvals
-      public :: gridInqXvals
-      public :: gridDefYvals
-      public :: gridInqYvals
-      public :: gridDefXname
-      public :: gridInqXname
-      public :: gridDefXlongname
-      public :: gridInqXlongname
-      public :: gridDefXunits
-      public :: gridInqXunits
-      public :: gridDefYname
-      public :: gridInqYname
-      public :: gridDefYlongname
-      public :: gridInqYlongname
-      public :: gridDefYunits
-      public :: gridInqYunits
-      public :: gridInqXstdname
-      public :: gridInqYstdname
-      public :: gridDefPrec
-      public :: gridInqPrec
-      public :: gridInqXval
-      public :: gridInqYval
-      public :: gridInqXinc
-      public :: gridInqYinc
-      public :: gridIsCircular
-      public :: gridIsRotated
-      public :: gridDefXpole
-      public :: gridInqXpole
-      public :: gridDefYpole
-      public :: gridInqYpole
-      public :: gridDefAngle
-      public :: gridInqAngle
-      public :: gridInqTrunc
-      public :: gridDefTrunc
-      public :: gridDefGMEnd
-      public :: gridInqGMEnd
-      public :: gridDefGMEni
-      public :: gridInqGMEni
-      public :: gridDefGMEni2
-      public :: gridInqGMEni2
-      public :: gridDefGMEni3
-      public :: gridInqGMEni3
-      public :: gridDefNumber
-      public :: gridInqNumber
-      public :: gridDefPosition
-      public :: gridInqPosition
-      public :: gridDefReference
-      public :: gridInqReference
-      public :: gridDefUUID
-      public :: gridInqUUID
-      public :: gridDefLCC
-      public :: gridInqLCC
-      public :: gridDefLcc2
-      public :: gridInqLcc2
-      public :: gridDefLaea
-      public :: gridInqLaea
-      public :: gridDefArea
-      public :: gridInqArea
-      public :: gridHasArea
-      public :: gridDefNvertex
-      public :: gridInqNvertex
-      public :: gridDefXbounds
-      public :: gridInqXbounds
-      public :: gridDefYbounds
-      public :: gridInqYbounds
-      public :: gridDefRowlon
-      public :: gridInqRowlon
-      public :: gridChangeType
-      public :: gridDefComplexPacking
-      public :: gridInqComplexPacking
-      public :: zaxisName
-      public :: zaxisCreate
-      public :: zaxisDestroy
-      public :: zaxisInqType
-      public :: zaxisInqSize
-      public :: zaxisDuplicate
-      public :: zaxisResize
-      public :: zaxisPrint
-      public :: zaxisDefLevels
-      public :: zaxisInqLevels
-      public :: zaxisDefLevel
-      public :: zaxisInqLevel
-      public :: zaxisDefNlevRef
-      public :: zaxisInqNlevRef
-      public :: zaxisDefNumber
-      public :: zaxisInqNumber
-      public :: zaxisDefUUID
-      public :: zaxisInqUUID
-      public :: zaxisDefName
-      public :: zaxisInqName
-      public :: zaxisDefLongname
-      public :: zaxisInqLongname
-      public :: zaxisDefUnits
-      public :: zaxisInqUnits
-      public :: zaxisInqStdname
-      public :: zaxisDefPrec
-      public :: zaxisInqPrec
-      public :: zaxisDefPositive
-      public :: zaxisInqPositive
-      public :: zaxisDefLtype
-      public :: zaxisInqLtype
-      public :: zaxisInqLevelsPtr
-      public :: zaxisDefVct
-      public :: zaxisInqVct
-      public :: zaxisInqVctSize
-      public :: zaxisInqVctPtr
-      public :: zaxisDefLbounds
-      public :: zaxisInqLbounds
-      public :: zaxisInqLbound
-      public :: zaxisDefUbounds
-      public :: zaxisInqUbounds
-      public :: zaxisInqUbound
-      public :: zaxisDefWeights
-      public :: zaxisInqWeights
-      public :: zaxisChangeType
-      public :: taxisCreate
-      public :: taxisDestroy
-      public :: taxisDuplicate
-      public :: taxisCopyTimestep
-      public :: taxisDefType
-      public :: taxisDefVdate
-      public :: taxisDefVtime
-      public :: taxisInqVdate
-      public :: taxisInqVtime
-      public :: taxisDefRdate
-      public :: taxisDefRtime
-      public :: taxisInqRdate
-      public :: taxisInqRtime
-      public :: taxisDefFdate
-      public :: taxisDefFtime
-      public :: taxisInqFdate
-      public :: taxisInqFtime
-      public :: taxisHasBounds
-      public :: taxisDeleteBounds
-      public :: taxisDefVdateBounds
-      public :: taxisDefVtimeBounds
-      public :: taxisInqVdateBounds
-      public :: taxisInqVtimeBounds
-      public :: taxisDefCalendar
-      public :: taxisInqCalendar
-      public :: taxisDefTunit
-      public :: taxisInqTunit
-      public :: taxisDefForecastTunit
-      public :: taxisInqForecastTunit
-      public :: taxisDefForecastPeriod
-      public :: taxisInqForecastPeriod
-      public :: taxisDefNumavg
-      public :: taxisInqType
-      public :: taxisInqNumavg
-      public :: tunitNamePtr
-      public :: institutDef
-      public :: institutInq
-      public :: institutInqNumber
-      public :: institutInqCenter
-      public :: institutInqSubcenter
-      public :: institutInqNamePtr
-      public :: institutInqLongnamePtr
-      public :: modelDef
-      public :: modelInq
-      public :: modelInqInstitut
-      public :: modelInqGribID
-      public :: modelInqNamePtr
-      public :: tableWriteC
-      public :: tableWrite
-      public :: tableRead
-      public :: tableDef
-      public :: tableInqNamePtr
-      public :: tableDefEntry
-      public :: tableInq
-      public :: tableInqNumber
-      public :: tableInqNum
-      public :: tableInqModel
-      public :: tableInqPar
-      public :: tableInqParCode
-      public :: tableInqParName
-      public :: tableInqParLongname
-      public :: tableInqParUnits
-      public :: tableInqParNamePtr
-      public :: tableInqParLongnamePtr
-      public :: tableInqParUnitsPtr
-      public :: streamDefHistory
-      public :: streamInqHistorySize
-      public :: streamInqHistoryString
-      public :: gribapiLibraryVersion
-      public :: ctrim
-      public :: c_len
-
-      public :: CDI_MAX_NAME
-      public :: CDI_UNDEFID
-      public :: CDI_GLOBAL
-      public :: CDI_BIGENDIAN
-      public :: CDI_LITTLEENDIAN
-      public :: CDI_REAL
-      public :: CDI_COMP
-      public :: CDI_BOTH
-      public :: CDI_ESYSTEM
-      public :: CDI_EINVAL
-      public :: CDI_EUFTYPE
-      public :: CDI_ELIBNAVAIL
-      public :: CDI_EUFSTRUCT
-      public :: CDI_EUNC4
-      public :: CDI_ELIMIT
-      public :: FILETYPE_UNDEF
-      public :: FILETYPE_GRB
-      public :: FILETYPE_GRB2
-      public :: FILETYPE_NC
-      public :: FILETYPE_NC2
-      public :: FILETYPE_NC4
-      public :: FILETYPE_NC4C
-      public :: FILETYPE_SRV
-      public :: FILETYPE_EXT
-      public :: FILETYPE_IEG
-      public :: COMPRESS_NONE
-      public :: COMPRESS_SZIP
-      public :: COMPRESS_GZIP
-      public :: COMPRESS_BZIP2
-      public :: COMPRESS_ZIP
-      public :: COMPRESS_JPEG
-      public :: DATATYPE_PACK
-      public :: DATATYPE_PACK1
-      public :: DATATYPE_PACK2
-      public :: DATATYPE_PACK3
-      public :: DATATYPE_PACK4
-      public :: DATATYPE_PACK5
-      public :: DATATYPE_PACK6
-      public :: DATATYPE_PACK7
-      public :: DATATYPE_PACK8
-      public :: DATATYPE_PACK9
-      public :: DATATYPE_PACK10
-      public :: DATATYPE_PACK11
-      public :: DATATYPE_PACK12
-      public :: DATATYPE_PACK13
-      public :: DATATYPE_PACK14
-      public :: DATATYPE_PACK15
-      public :: DATATYPE_PACK16
-      public :: DATATYPE_PACK17
-      public :: DATATYPE_PACK18
-      public :: DATATYPE_PACK19
-      public :: DATATYPE_PACK20
-      public :: DATATYPE_PACK21
-      public :: DATATYPE_PACK22
-      public :: DATATYPE_PACK23
-      public :: DATATYPE_PACK24
-      public :: DATATYPE_PACK25
-      public :: DATATYPE_PACK26
-      public :: DATATYPE_PACK27
-      public :: DATATYPE_PACK28
-      public :: DATATYPE_PACK29
-      public :: DATATYPE_PACK30
-      public :: DATATYPE_PACK31
-      public :: DATATYPE_PACK32
-      public :: DATATYPE_CPX32
-      public :: DATATYPE_CPX64
-      public :: DATATYPE_FLT32
-      public :: DATATYPE_FLT64
-      public :: DATATYPE_INT8
-      public :: DATATYPE_INT16
-      public :: DATATYPE_INT32
-      public :: DATATYPE_UINT8
-      public :: DATATYPE_UINT16
-      public :: DATATYPE_UINT32
-      public :: DATATYPE_INT
-      public :: DATATYPE_FLT
-      public :: DATATYPE_TXT
-      public :: DATATYPE_CPX
-      public :: DATATYPE_UCHAR
-      public :: DATATYPE_LONG
-      public :: CHUNK_AUTO
-      public :: CHUNK_GRID
-      public :: CHUNK_LINES
-      public :: GRID_GENERIC
-      public :: GRID_GAUSSIAN
-      public :: GRID_GAUSSIAN_REDUCED
-      public :: GRID_LONLAT
-      public :: GRID_SPECTRAL
-      public :: GRID_FOURIER
-      public :: GRID_GME
-      public :: GRID_TRAJECTORY
-      public :: GRID_UNSTRUCTURED
-      public :: GRID_CURVILINEAR
-      public :: GRID_LCC
-      public :: GRID_LCC2
-      public :: GRID_LAEA
-      public :: GRID_SINUSOIDAL
-      public :: GRID_PROJECTION
-      public :: ZAXIS_SURFACE
-      public :: ZAXIS_GENERIC
-      public :: ZAXIS_HYBRID
-      public :: ZAXIS_HYBRID_HALF
-      public :: ZAXIS_PRESSURE
-      public :: ZAXIS_HEIGHT
-      public :: ZAXIS_DEPTH_BELOW_SEA
-      public :: ZAXIS_DEPTH_BELOW_LAND
-      public :: ZAXIS_ISENTROPIC
-      public :: ZAXIS_TRAJECTORY
-      public :: ZAXIS_ALTITUDE
-      public :: ZAXIS_SIGMA
-      public :: ZAXIS_MEANSEA
-      public :: ZAXIS_TOA
-      public :: ZAXIS_SEA_BOTTOM
-      public :: ZAXIS_ATMOSPHERE
-      public :: ZAXIS_CLOUD_BASE
-      public :: ZAXIS_CLOUD_TOP
-      public :: ZAXIS_ISOTHERM_ZERO
-      public :: ZAXIS_SNOW
-      public :: ZAXIS_LAKE_BOTTOM
-      public :: ZAXIS_SEDIMENT_BOTTOM
-      public :: ZAXIS_SEDIMENT_BOTTOM_TA
-      public :: ZAXIS_SEDIMENT_BOTTOM_TW
-      public :: ZAXIS_MIX_LAYER
-      public :: ZAXIS_REFERENCE
-      public :: TIME_CONSTANT
-      public :: TIME_VARIABLE
-      public :: TSTEP_CONSTANT
-      public :: TSTEP_INSTANT
-      public :: TSTEP_AVG
-      public :: TSTEP_ACCUM
-      public :: TSTEP_MAX
-      public :: TSTEP_MIN
-      public :: TSTEP_DIFF
-      public :: TSTEP_RMS
-      public :: TSTEP_SD
-      public :: TSTEP_COV
-      public :: TSTEP_RATIO
-      public :: TSTEP_RANGE
-      public :: TSTEP_INSTANT2
-      public :: TSTEP_INSTANT3
-      public :: TAXIS_ABSOLUTE
-      public :: TAXIS_RELATIVE
-      public :: TAXIS_FORECAST
-      public :: TUNIT_SECOND
-      public :: TUNIT_MINUTE
-      public :: TUNIT_QUARTER
-      public :: TUNIT_30MINUTES
-      public :: TUNIT_HOUR
-      public :: TUNIT_3HOURS
-      public :: TUNIT_6HOURS
-      public :: TUNIT_12HOURS
-      public :: TUNIT_DAY
-      public :: TUNIT_MONTH
-      public :: TUNIT_YEAR
-      public :: CALENDAR_STANDARD
-      public :: CALENDAR_PROLEPTIC
-      public :: CALENDAR_360DAYS
-      public :: CALENDAR_365DAYS
-      public :: CALENDAR_366DAYS
-      public :: CALENDAR_NONE
-      public :: CDI_UUID_SIZE
+	use iso_c_binding
+	implicit none
+	private
+
+	public ctrim
+	public c_len
+
+	interface
+		integer(c_size_t) function lib_strlen(charPtr) bind(c, name = "strlen")
+			import c_size_t, c_ptr
+			type(c_ptr), value :: charPtr
+		end function lib_strlen
+
+		subroutine lib_free(pointer) bind(c, name = "free")
+			import c_ptr
+			type(c_ptr), value :: pointer
+		end subroutine lib_free
+	end interface
+
+	integer(c_int), public, parameter :: CDI_MAX_NAME = 256
+	integer(c_int), public, parameter :: CDI_UNDEFID = -1
+	integer(c_int), public, parameter :: CDI_GLOBAL = -1
+	integer(c_int), public, parameter :: CDI_BIGENDIAN = 0
+	integer(c_int), public, parameter :: CDI_LITTLEENDIAN = 1
+	integer(c_int), public, parameter :: CDI_REAL = 1
+	integer(c_int), public, parameter :: CDI_COMP = 2
+	integer(c_int), public, parameter :: CDI_BOTH = 3
+	integer(c_int), public, parameter :: CDI_NOERR = 0
+	integer(c_int), public, parameter :: CDI_EEOF = -1
+	integer(c_int), public, parameter :: CDI_ESYSTEM = -10
+	integer(c_int), public, parameter :: CDI_EINVAL = -20
+	integer(c_int), public, parameter :: CDI_EUFTYPE = -21
+	integer(c_int), public, parameter :: CDI_ELIBNAVAIL = -22
+	integer(c_int), public, parameter :: CDI_EUFSTRUCT = -23
+	integer(c_int), public, parameter :: CDI_EUNC4 = -24
+	integer(c_int), public, parameter :: CDI_ELIMIT = -99
+	integer(c_int), public, parameter :: FILETYPE_UNDEF = -1
+	integer(c_int), public, parameter :: FILETYPE_GRB = 1
+	integer(c_int), public, parameter :: FILETYPE_GRB2 = 2
+	integer(c_int), public, parameter :: FILETYPE_NC = 3
+	integer(c_int), public, parameter :: FILETYPE_NC2 = 4
+	integer(c_int), public, parameter :: FILETYPE_NC4 = 5
+	integer(c_int), public, parameter :: FILETYPE_NC4C = 6
+	integer(c_int), public, parameter :: FILETYPE_SRV = 7
+	integer(c_int), public, parameter :: FILETYPE_EXT = 8
+	integer(c_int), public, parameter :: FILETYPE_IEG = 9
+	integer(c_int), public, parameter :: COMPRESS_NONE = 0
+	integer(c_int), public, parameter :: COMPRESS_SZIP = 1
+	integer(c_int), public, parameter :: COMPRESS_GZIP = 2
+	integer(c_int), public, parameter :: COMPRESS_BZIP2 = 3
+	integer(c_int), public, parameter :: COMPRESS_ZIP = 4
+	integer(c_int), public, parameter :: COMPRESS_JPEG = 5
+	integer(c_int), public, parameter :: DATATYPE_PACK = 0
+	integer(c_int), public, parameter :: DATATYPE_PACK1 = 1
+	integer(c_int), public, parameter :: DATATYPE_PACK2 = 2
+	integer(c_int), public, parameter :: DATATYPE_PACK3 = 3
+	integer(c_int), public, parameter :: DATATYPE_PACK4 = 4
+	integer(c_int), public, parameter :: DATATYPE_PACK5 = 5
+	integer(c_int), public, parameter :: DATATYPE_PACK6 = 6
+	integer(c_int), public, parameter :: DATATYPE_PACK7 = 7
+	integer(c_int), public, parameter :: DATATYPE_PACK8 = 8
+	integer(c_int), public, parameter :: DATATYPE_PACK9 = 9
+	integer(c_int), public, parameter :: DATATYPE_PACK10 = 10
+	integer(c_int), public, parameter :: DATATYPE_PACK11 = 11
+	integer(c_int), public, parameter :: DATATYPE_PACK12 = 12
+	integer(c_int), public, parameter :: DATATYPE_PACK13 = 13
+	integer(c_int), public, parameter :: DATATYPE_PACK14 = 14
+	integer(c_int), public, parameter :: DATATYPE_PACK15 = 15
+	integer(c_int), public, parameter :: DATATYPE_PACK16 = 16
+	integer(c_int), public, parameter :: DATATYPE_PACK17 = 17
+	integer(c_int), public, parameter :: DATATYPE_PACK18 = 18
+	integer(c_int), public, parameter :: DATATYPE_PACK19 = 19
+	integer(c_int), public, parameter :: DATATYPE_PACK20 = 20
+	integer(c_int), public, parameter :: DATATYPE_PACK21 = 21
+	integer(c_int), public, parameter :: DATATYPE_PACK22 = 22
+	integer(c_int), public, parameter :: DATATYPE_PACK23 = 23
+	integer(c_int), public, parameter :: DATATYPE_PACK24 = 24
+	integer(c_int), public, parameter :: DATATYPE_PACK25 = 25
+	integer(c_int), public, parameter :: DATATYPE_PACK26 = 26
+	integer(c_int), public, parameter :: DATATYPE_PACK27 = 27
+	integer(c_int), public, parameter :: DATATYPE_PACK28 = 28
+	integer(c_int), public, parameter :: DATATYPE_PACK29 = 29
+	integer(c_int), public, parameter :: DATATYPE_PACK30 = 30
+	integer(c_int), public, parameter :: DATATYPE_PACK31 = 31
+	integer(c_int), public, parameter :: DATATYPE_PACK32 = 32
+	integer(c_int), public, parameter :: DATATYPE_CPX32 = 64
+	integer(c_int), public, parameter :: DATATYPE_CPX64 = 128
+	integer(c_int), public, parameter :: DATATYPE_FLT32 = 132
+	integer(c_int), public, parameter :: DATATYPE_FLT64 = 164
+	integer(c_int), public, parameter :: DATATYPE_INT8 = 208
+	integer(c_int), public, parameter :: DATATYPE_INT16 = 216
+	integer(c_int), public, parameter :: DATATYPE_INT32 = 232
+	integer(c_int), public, parameter :: DATATYPE_UINT8 = 308
+	integer(c_int), public, parameter :: DATATYPE_UINT16 = 316
+	integer(c_int), public, parameter :: DATATYPE_UINT32 = 332
+	integer(c_int), public, parameter :: DATATYPE_INT = 251
+	integer(c_int), public, parameter :: DATATYPE_FLT = 252
+	integer(c_int), public, parameter :: DATATYPE_TXT = 253
+	integer(c_int), public, parameter :: DATATYPE_CPX = 254
+	integer(c_int), public, parameter :: DATATYPE_UCHAR = 255
+	integer(c_int), public, parameter :: DATATYPE_LONG = 256
+	integer(c_int), public, parameter :: CHUNK_AUTO = 1
+	integer(c_int), public, parameter :: CHUNK_GRID = 2
+	integer(c_int), public, parameter :: CHUNK_LINES = 3
+	integer(c_int), public, parameter :: GRID_GENERIC = 1
+	integer(c_int), public, parameter :: GRID_GAUSSIAN = 2
+	integer(c_int), public, parameter :: GRID_GAUSSIAN_REDUCED = 3
+	integer(c_int), public, parameter :: GRID_LONLAT = 4
+	integer(c_int), public, parameter :: GRID_SPECTRAL = 5
+	integer(c_int), public, parameter :: GRID_FOURIER = 6
+	integer(c_int), public, parameter :: GRID_GME = 7
+	integer(c_int), public, parameter :: GRID_TRAJECTORY = 8
+	integer(c_int), public, parameter :: GRID_UNSTRUCTURED = 9
+	integer(c_int), public, parameter :: GRID_CURVILINEAR = 10
+	integer(c_int), public, parameter :: GRID_LCC = 11
+	integer(c_int), public, parameter :: GRID_LCC2 = 12
+	integer(c_int), public, parameter :: GRID_LAEA = 13
+	integer(c_int), public, parameter :: GRID_SINUSOIDAL = 14
+	integer(c_int), public, parameter :: GRID_PROJECTION = 15
+	integer(c_int), public, parameter :: ZAXIS_SURFACE = 0
+	integer(c_int), public, parameter :: ZAXIS_GENERIC = 1
+	integer(c_int), public, parameter :: ZAXIS_HYBRID = 2
+	integer(c_int), public, parameter :: ZAXIS_HYBRID_HALF = 3
+	integer(c_int), public, parameter :: ZAXIS_PRESSURE = 4
+	integer(c_int), public, parameter :: ZAXIS_HEIGHT = 5
+	integer(c_int), public, parameter :: ZAXIS_DEPTH_BELOW_SEA = 6
+	integer(c_int), public, parameter :: ZAXIS_DEPTH_BELOW_LAND = 7
+	integer(c_int), public, parameter :: ZAXIS_ISENTROPIC = 8
+	integer(c_int), public, parameter :: ZAXIS_TRAJECTORY = 9
+	integer(c_int), public, parameter :: ZAXIS_ALTITUDE = 10
+	integer(c_int), public, parameter :: ZAXIS_SIGMA = 11
+	integer(c_int), public, parameter :: ZAXIS_MEANSEA = 12
+	integer(c_int), public, parameter :: ZAXIS_TOA = 13
+	integer(c_int), public, parameter :: ZAXIS_SEA_BOTTOM = 14
+	integer(c_int), public, parameter :: ZAXIS_ATMOSPHERE = 15
+	integer(c_int), public, parameter :: ZAXIS_CLOUD_BASE = 16
+	integer(c_int), public, parameter :: ZAXIS_CLOUD_TOP = 17
+	integer(c_int), public, parameter :: ZAXIS_ISOTHERM_ZERO = 18
+	integer(c_int), public, parameter :: ZAXIS_SNOW = 19
+	integer(c_int), public, parameter :: ZAXIS_LAKE_BOTTOM = 20
+	integer(c_int), public, parameter :: ZAXIS_SEDIMENT_BOTTOM = 21
+	integer(c_int), public, parameter :: ZAXIS_SEDIMENT_BOTTOM_TA = 22
+	integer(c_int), public, parameter :: ZAXIS_SEDIMENT_BOTTOM_TW = 23
+	integer(c_int), public, parameter :: ZAXIS_MIX_LAYER = 24
+	integer(c_int), public, parameter :: ZAXIS_REFERENCE = 25
+	integer(c_int), public, parameter :: TIME_CONSTANT = 0
+	integer(c_int), public, parameter :: TIME_VARIABLE = 1
+	integer(c_int), public, parameter :: TSTEP_CONSTANT = 0
+	integer(c_int), public, parameter :: TSTEP_INSTANT = 1
+	integer(c_int), public, parameter :: TSTEP_AVG = 2
+	integer(c_int), public, parameter :: TSTEP_ACCUM = 3
+	integer(c_int), public, parameter :: TSTEP_MAX = 4
+	integer(c_int), public, parameter :: TSTEP_MIN = 5
+	integer(c_int), public, parameter :: TSTEP_DIFF = 6
+	integer(c_int), public, parameter :: TSTEP_RMS = 7
+	integer(c_int), public, parameter :: TSTEP_SD = 8
+	integer(c_int), public, parameter :: TSTEP_COV = 9
+	integer(c_int), public, parameter :: TSTEP_RATIO = 10
+	integer(c_int), public, parameter :: TSTEP_RANGE = 11
+	integer(c_int), public, parameter :: TSTEP_INSTANT2 = 12
+	integer(c_int), public, parameter :: TSTEP_INSTANT3 = 13
+	integer(c_int), public, parameter :: TAXIS_ABSOLUTE = 1
+	integer(c_int), public, parameter :: TAXIS_RELATIVE = 2
+	integer(c_int), public, parameter :: TAXIS_FORECAST = 3
+	integer(c_int), public, parameter :: TUNIT_SECOND = 1
+	integer(c_int), public, parameter :: TUNIT_MINUTE = 2
+	integer(c_int), public, parameter :: TUNIT_QUARTER = 3
+	integer(c_int), public, parameter :: TUNIT_30MINUTES = 4
+	integer(c_int), public, parameter :: TUNIT_HOUR = 5
+	integer(c_int), public, parameter :: TUNIT_3HOURS = 6
+	integer(c_int), public, parameter :: TUNIT_6HOURS = 7
+	integer(c_int), public, parameter :: TUNIT_12HOURS = 8
+	integer(c_int), public, parameter :: TUNIT_DAY = 9
+	integer(c_int), public, parameter :: TUNIT_MONTH = 10
+	integer(c_int), public, parameter :: TUNIT_YEAR = 11
+	integer(c_int), public, parameter :: CALENDAR_STANDARD = 0
+	integer(c_int), public, parameter :: CALENDAR_PROLEPTIC = 1
+	integer(c_int), public, parameter :: CALENDAR_360DAYS = 2
+	integer(c_int), public, parameter :: CALENDAR_365DAYS = 3
+	integer(c_int), public, parameter :: CALENDAR_366DAYS = 4
+	integer(c_int), public, parameter :: CALENDAR_NONE = 5
+	integer(c_int), public, parameter :: CDI_UUID_SIZE = 16
+
+	public t_CdiParam
+	type, bind(c) :: t_CdiParam
+		integer(c_int) :: discipline
+		integer(c_int) :: category
+		integer(c_int) :: number
+	end type t_CdiParam
+
+	public t_CdiIterator
+	type t_CdiIterator
+		type(c_ptr) :: ptr
+	end type t_CdiIterator
+
+	public t_CdiGribIterator
+	type t_CdiGribIterator
+		type(c_ptr) :: ptr
+	end type t_CdiGribIterator
+	public cdiReset
+	public cdiStringError
+	public cdiDebug
+	public cdiLibraryVersion
+	public cdiPrintVersion
+	public cdiHaveFiletype
+	public cdiDefMissval
+	public cdiInqMissval
+	public cdiDefGlobal
+	public namespaceNew
+	public namespaceSetActive
+	public namespaceDelete
+	public cdiParamToString
+	public cdiDecodeParam
+	public cdiEncodeParam
+	public cdiDecodeDate
+	public cdiEncodeDate
+	public cdiDecodeTime
+	public cdiEncodeTime
+	public cdiGetFiletype
+	public streamOpenRead
+	public streamOpenWrite
+	public streamOpenAppend
+	public streamClose
+	public streamSync
+	public streamDefVlist
+	public streamInqVlist
+	public streamInqVlistIDorig
+	public streamInqFiletype
+	public streamDefByteorder
+	public streamInqByteorder
+	public streamDefCompType
+	public streamInqCompType
+	public streamDefCompLevel
+	public streamInqCompLevel
+	public streamDefTimestep
+	public streamInqTimestep
+	public streamInqCurTimestepID
+	public streamFilename
+	public streamFilesuffix
+	public streamInqNvars
+	public streamWriteVar
+	public streamWriteVarF
+	public streamReadVar
+	public streamReadVarF
+	public streamWriteVarSlice
+	public streamWriteVarSliceF
+	public streamReadVarSlice
+	public streamReadVarSliceF
+	public streamWriteVarChunk
+	public streamDefRecord
+	public streamInqRecord
+	public streamWriteRecord
+	public streamWriteRecordF
+	public streamReadRecord
+	public streamCopyRecord
+	public cdiIterator_new
+	public cdiIterator_clone
+	public cdiIterator_serialize
+	public cdiIterator_deserialize
+	public cdiIterator_delete
+	public cdiIterator_nextField
+	public cdiIterator_inqStartTime
+	public cdiIterator_inqEndTime
+	public cdiIterator_inqVTime
+	public cdiIterator_inqLevelType
+	public cdiIterator_inqLevel
+	public cdiIterator_inqLevelUuid
+	public cdiIterator_inqParam
+	public cdiIterator_inqDatatype
+	public cdiIterator_inqTsteptype
+	public cdiIterator_inqVariableName
+	public cdiIterator_inqGridId
+	public cdiIterator_readField
+	public cdiIterator_readFieldF
+	public cdiGribIterator_clone
+	public cdiGribIterator_delete
+	public cdiGribIterator_getLong
+	public cdiGribIterator_getDouble
+	public cdiGribIterator_getLength
+	public cdiGribIterator_getString
+	public cdiGribIterator_getSize
+	public cdiGribIterator_getLongArray
+	public cdiGribIterator_getDoubleArray
+	public cdiGribIterator_inqEdition
+	public cdiGribIterator_inqLongValue
+	public cdiGribIterator_inqLongDefaultValue
+	public cdiGribIterator_inqDoubleValue
+	public cdiGribIterator_inqDoubleDefaultValue
+	public cdiGribIterator_inqStringValue
+	public vlistCreate
+	public vlistDestroy
+	public vlistDuplicate
+	public vlistCopy
+	public vlistCopyFlag
+	public vlistClearFlag
+	public vlistCat
+	public vlistMerge
+	public vlistPrint
+	public vlistNumber
+	public vlistNvars
+	public vlistNgrids
+	public vlistNzaxis
+	public vlistDefNtsteps
+	public vlistNtsteps
+	public vlistGridsizeMax
+	public vlistGrid
+	public vlistGridIndex
+	public vlistChangeGridIndex
+	public vlistChangeGrid
+	public vlistZaxis
+	public vlistZaxisIndex
+	public vlistChangeZaxisIndex
+	public vlistChangeZaxis
+	public vlistNrecs
+	public vlistDefTaxis
+	public vlistInqTaxis
+	public vlistDefTable
+	public vlistInqTable
+	public vlistDefInstitut
+	public vlistInqInstitut
+	public vlistDefModel
+	public vlistInqModel
+	public vlistDefVar
+	public vlistChangeVarGrid
+	public vlistChangeVarZaxis
+	public vlistInqVar
+	public vlistInqVarGrid
+	public vlistInqVarZaxis
+	public vlistInqVarID
+	public vlistDefVarTsteptype
+	public vlistInqVarTsteptype
+	public vlistDefVarCompType
+	public vlistInqVarCompType
+	public vlistDefVarCompLevel
+	public vlistInqVarCompLevel
+	public vlistDefVarParam
+	public vlistInqVarParam
+	public vlistDefVarCode
+	public vlistInqVarCode
+	public vlistDefVarDatatype
+	public vlistInqVarDatatype
+	public vlistDefVarChunkType
+	public vlistInqVarChunkType
+	public vlistDefVarXYZ
+	public vlistInqVarXYZ
+	public vlistInqVarNumber
+	public vlistDefVarInstitut
+	public vlistInqVarInstitut
+	public vlistDefVarModel
+	public vlistInqVarModel
+	public vlistDefVarTable
+	public vlistInqVarTable
+	public vlistDefVarName
+	public vlistInqVarName
+	public vlistCopyVarName
+	public vlistDefVarStdname
+	public vlistInqVarStdname
+	public vlistDefVarLongname
+	public vlistInqVarLongname
+	public vlistDefVarUnits
+	public vlistInqVarUnits
+	public vlistDefVarMissval
+	public vlistInqVarMissval
+	public vlistDefVarExtra
+	public vlistInqVarExtra
+	public vlistDefVarScalefactor
+	public vlistInqVarScalefactor
+	public vlistDefVarAddoffset
+	public vlistInqVarAddoffset
+	public vlistDefVarTimave
+	public vlistInqVarTimave
+	public vlistDefVarTimaccu
+	public vlistInqVarTimaccu
+	public vlistDefVarTypeOfGeneratingProcess
+	public vlistInqVarTypeOfGeneratingProcess
+	public vlistDefVarProductDefinitionTemplate
+	public vlistInqVarProductDefinitionTemplate
+	public vlistInqVarSize
+	public vlistDefIndex
+	public vlistInqIndex
+	public vlistDefFlag
+	public vlistInqFlag
+	public vlistFindVar
+	public vlistFindLevel
+	public vlistMergedVar
+	public vlistMergedLevel
+	public vlistDefVarEnsemble
+	public vlistInqVarEnsemble
+	public cdiClearAdditionalKeys
+	public cdiDefAdditionalKey
+	public vlistDefVarIntKey
+	public vlistDefVarDblKey
+	public vlistHasVarKey
+	public vlistInqVarDblKey
+	public vlistInqVarIntKey
+	public vlistInqNatts
+	public vlistInqAtt
+	public vlistDelAtt
+	public vlistDefAttInt
+	public vlistDefAttFlt
+	public vlistDefAttTxt
+	public vlistInqAttInt
+	public vlistInqAttFlt
+	public vlistInqAttTxt
+	public gridName
+	public gridNamePtr
+	public gridCompress
+	public gridDefMaskGME
+	public gridInqMaskGME
+	public gridDefMask
+	public gridInqMask
+	public gridPrint
+	public gridCreate
+	public gridDestroy
+	public gridDuplicate
+	public gridInqType
+	public gridInqSize
+	public gridDefXsize
+	public gridInqXsize
+	public gridDefYsize
+	public gridInqYsize
+	public gridDefNP
+	public gridInqNP
+	public gridDefXvals
+	public gridInqXvals
+	public gridDefYvals
+	public gridInqYvals
+	public gridDefXname
+	public gridInqXname
+	public gridDefXlongname
+	public gridInqXlongname
+	public gridDefXunits
+	public gridInqXunits
+	public gridDefYname
+	public gridInqYname
+	public gridDefYlongname
+	public gridInqYlongname
+	public gridDefYunits
+	public gridInqYunits
+	public gridInqXstdname
+	public gridInqYstdname
+	public gridDefPrec
+	public gridInqPrec
+	public gridInqXval
+	public gridInqYval
+	public gridInqXinc
+	public gridInqYinc
+	public gridIsCircular
+	public gridIsRotated
+	public gridDefXpole
+	public gridInqXpole
+	public gridDefYpole
+	public gridInqYpole
+	public gridDefAngle
+	public gridInqAngle
+	public gridInqTrunc
+	public gridDefTrunc
+	public gridDefGMEnd
+	public gridInqGMEnd
+	public gridDefGMEni
+	public gridInqGMEni
+	public gridDefGMEni2
+	public gridInqGMEni2
+	public gridDefGMEni3
+	public gridInqGMEni3
+	public gridDefNumber
+	public gridInqNumber
+	public gridDefPosition
+	public gridInqPosition
+	public gridDefReference
+	public gridInqReference
+	public gridDefUUID
+	public gridInqUUID
+	public gridDefLCC
+	public gridInqLCC
+	public gridDefLcc2
+	public gridInqLcc2
+	public gridDefLaea
+	public gridInqLaea
+	public gridDefArea
+	public gridInqArea
+	public gridHasArea
+	public gridDefNvertex
+	public gridInqNvertex
+	public gridDefXbounds
+	public gridInqXbounds
+	public gridDefYbounds
+	public gridInqYbounds
+	public gridDefRowlon
+	public gridInqRowlon
+	public gridChangeType
+	public gridDefComplexPacking
+	public gridInqComplexPacking
+	public zaxisName
+	public zaxisCreate
+	public zaxisDestroy
+	public zaxisInqType
+	public zaxisInqSize
+	public zaxisDuplicate
+	public zaxisResize
+	public zaxisPrint
+	public zaxisDefLevels
+	public zaxisInqLevels
+	public zaxisDefLevel
+	public zaxisInqLevel
+	public zaxisDefNlevRef
+	public zaxisInqNlevRef
+	public zaxisDefNumber
+	public zaxisInqNumber
+	public zaxisDefUUID
+	public zaxisInqUUID
+	public zaxisDefName
+	public zaxisInqName
+	public zaxisDefLongname
+	public zaxisInqLongname
+	public zaxisDefUnits
+	public zaxisInqUnits
+	public zaxisInqStdname
+	public zaxisDefPrec
+	public zaxisInqPrec
+	public zaxisDefPositive
+	public zaxisInqPositive
+	public zaxisDefLtype
+	public zaxisInqLtype
+	public zaxisInqLevelsPtr
+	public zaxisDefVct
+	public zaxisInqVct
+	public zaxisInqVctSize
+	public zaxisInqVctPtr
+	public zaxisDefLbounds
+	public zaxisInqLbounds
+	public zaxisInqLbound
+	public zaxisDefUbounds
+	public zaxisInqUbounds
+	public zaxisInqUbound
+	public zaxisDefWeights
+	public zaxisInqWeights
+	public zaxisChangeType
+	public taxisCreate
+	public taxisDestroy
+	public taxisDuplicate
+	public taxisCopyTimestep
+	public taxisDefType
+	public taxisDefVdate
+	public taxisDefVtime
+	public taxisInqVdate
+	public taxisInqVtime
+	public taxisDefRdate
+	public taxisDefRtime
+	public taxisInqRdate
+	public taxisInqRtime
+	public taxisDefFdate
+	public taxisDefFtime
+	public taxisInqFdate
+	public taxisInqFtime
+	public taxisHasBounds
+	public taxisDeleteBounds
+	public taxisDefVdateBounds
+	public taxisDefVtimeBounds
+	public taxisInqVdateBounds
+	public taxisInqVtimeBounds
+	public taxisDefCalendar
+	public taxisInqCalendar
+	public taxisDefTunit
+	public taxisInqTunit
+	public taxisDefForecastTunit
+	public taxisInqForecastTunit
+	public taxisDefForecastPeriod
+	public taxisInqForecastPeriod
+	public taxisDefNumavg
+	public taxisInqType
+	public taxisInqNumavg
+	public tunitNamePtr
+	public institutDef
+	public institutInq
+	public institutInqNumber
+	public institutInqCenter
+	public institutInqSubcenter
+	public institutInqNamePtr
+	public institutInqLongnamePtr
+	public modelDef
+	public modelInq
+	public modelInqInstitut
+	public modelInqGribID
+	public modelInqNamePtr
+	public tableWriteC
+	public tableWrite
+	public tableRead
+	public tableDef
+	public tableInqNamePtr
+	public tableDefEntry
+	public tableInq
+	public tableInqNumber
+	public tableInqNum
+	public tableInqModel
+	public tableInqPar
+	public tableInqParCode
+	public tableInqParName
+	public tableInqParLongname
+	public tableInqParUnits
+	public tableInqParNamePtr
+	public tableInqParLongnamePtr
+	public tableInqParUnitsPtr
+	public streamDefHistory
+	public streamInqHistorySize
+	public streamInqHistoryString
+	public gribapiLibraryVersion
 
 contains
-      function cdiStringError(cdiErrno)
-        integer(kind=c_int), value :: cdiErrno
-        interface
-          function cdiStringError_c(cdiErrno) bind(c,name='cdiStringError')
-            import :: c_ptr,c_int,c_char
-            integer(kind=c_int), value :: cdiErrno
-            type(c_ptr) :: cdiStringError_c
-          end function cdiStringError_c
-        end interface
-        character(len=1, kind=c_char), pointer :: cdiStringError(:)
-        type(c_ptr) :: cptr
-        integer :: slen(1)
-
-        cptr = cdiStringError_c(cdiErrno)
-        cdiStringError => null()
-        slen(1) = int(strlen(cptr))
-        call c_f_pointer(cptr, cdiStringError, slen)
-      end function cdiStringError
-      function cdiLibraryVersion()
-        interface
-          function cdiLibraryVersion_c() bind(c,name='cdiLibraryVersion')
-            import :: c_ptr,c_char
-            type(c_ptr) :: cdiLibraryVersion_c
-          end function cdiLibraryVersion_c
-        end interface
-        character(len=1, kind=c_char), pointer :: cdiLibraryVersion(:)
-        type(c_ptr) :: cptr
-        integer :: slen(1)
-
-        cptr = cdiLibraryVersion_c()
-        cdiLibraryVersion => null()
-        slen(1) = int(strlen(cptr))
-        call c_f_pointer(cptr, cdiLibraryVersion, slen)
-      end function cdiLibraryVersion
-      function streamFilename(streamID)
-        integer(kind=c_int), value :: streamID
-        interface
-          function streamFilename_c(streamID) bind(c,name='streamFilename')
-            import :: c_ptr,c_int,c_char
-            integer(kind=c_int), value :: streamID
-            type(c_ptr) :: streamFilename_c
-          end function streamFilename_c
-        end interface
-        character(len=1, kind=c_char), pointer :: streamFilename(:)
-        type(c_ptr) :: cptr
-        integer :: slen(1)
-
-        cptr = streamFilename_c(streamID)
-        streamFilename => null()
-        slen(1) = int(strlen(cptr))
-        call c_f_pointer(cptr, streamFilename, slen)
-      end function streamFilename
-      function streamFilesuffix(filetype)
-        integer(kind=c_int), value :: filetype
-        interface
-          function streamFilesuffix_c(filetype) bind(c,name='streamFilesuffix')
-            import :: c_ptr,c_int,c_char
-            integer(kind=c_int), value :: filetype
-            type(c_ptr) :: streamFilesuffix_c
-          end function streamFilesuffix_c
-        end interface
-        character(len=1, kind=c_char), pointer :: streamFilesuffix(:)
-        type(c_ptr) :: cptr
-        integer :: slen(1)
-
-        cptr = streamFilesuffix_c(filetype)
-        streamFilesuffix => null()
-        slen(1) = int(strlen(cptr))
-        call c_f_pointer(cptr, streamFilesuffix, slen)
-      end function streamFilesuffix
-      function gridNamePtr(gridtype)
-        integer(kind=c_int), value :: gridtype
-        interface
-          function gridNamePtr_c(gridtype) bind(c,name='gridNamePtr')
-            import :: c_ptr,c_int,c_char
-            integer(kind=c_int), value :: gridtype
-            type(c_ptr) :: gridNamePtr_c
-          end function gridNamePtr_c
-        end interface
-        character(len=1, kind=c_char), pointer :: gridNamePtr(:)
-        type(c_ptr) :: cptr
-        integer :: slen(1)
-
-        cptr = gridNamePtr_c(gridtype)
-        gridNamePtr => null()
-        slen(1) = int(strlen(cptr))
-        call c_f_pointer(cptr, gridNamePtr, slen)
-      end function gridNamePtr
-      function tunitNamePtr(tunitID)
-        integer(kind=c_int), value :: tunitID
-        interface
-          function tunitNamePtr_c(tunitID) bind(c,name='tunitNamePtr')
-            import :: c_ptr,c_int,c_char
-            integer(kind=c_int), value :: tunitID
-            type(c_ptr) :: tunitNamePtr_c
-          end function tunitNamePtr_c
-        end interface
-        character(len=1, kind=c_char), pointer :: tunitNamePtr(:)
-        type(c_ptr) :: cptr
-        integer :: slen(1)
-
-        cptr = tunitNamePtr_c(tunitID)
-        tunitNamePtr => null()
-        slen(1) = int(strlen(cptr))
-        call c_f_pointer(cptr, tunitNamePtr, slen)
-      end function tunitNamePtr
-      function institutInqNamePtr(instID)
-        integer(kind=c_int), value :: instID
-        interface
-          function institutInqNamePtr_c(instID) bind(c,name='institutInqNamePtr')
-            import :: c_ptr,c_int,c_char
-            integer(kind=c_int), value :: instID
-            type(c_ptr) :: institutInqNamePtr_c
-          end function institutInqNamePtr_c
-        end interface
-        character(len=1, kind=c_char), pointer :: institutInqNamePtr(:)
-        type(c_ptr) :: cptr
-        integer :: slen(1)
-
-        cptr = institutInqNamePtr_c(instID)
-        institutInqNamePtr => null()
-        slen(1) = int(strlen(cptr))
-        call c_f_pointer(cptr, institutInqNamePtr, slen)
-      end function institutInqNamePtr
-      function institutInqLongnamePtr(instID)
-        integer(kind=c_int), value :: instID
-        interface
-          function institutInqLongnamePtr_c(instID) bind(c,name='institutInqLongnamePtr')
-            import :: c_ptr,c_int,c_char
-            integer(kind=c_int), value :: instID
-            type(c_ptr) :: institutInqLongnamePtr_c
-          end function institutInqLongnamePtr_c
-        end interface
-        character(len=1, kind=c_char), pointer :: institutInqLongnamePtr(:)
-        type(c_ptr) :: cptr
-        integer :: slen(1)
-
-        cptr = institutInqLongnamePtr_c(instID)
-        institutInqLongnamePtr => null()
-        slen(1) = int(strlen(cptr))
-        call c_f_pointer(cptr, institutInqLongnamePtr, slen)
-      end function institutInqLongnamePtr
-      function modelInqNamePtr(modelID)
-        integer(kind=c_int), value :: modelID
-        interface
-          function modelInqNamePtr_c(modelID) bind(c,name='modelInqNamePtr')
-            import :: c_ptr,c_int,c_char
-            integer(kind=c_int), value :: modelID
-            type(c_ptr) :: modelInqNamePtr_c
-          end function modelInqNamePtr_c
-        end interface
-        character(len=1, kind=c_char), pointer :: modelInqNamePtr(:)
-        type(c_ptr) :: cptr
-        integer :: slen(1)
-
-        cptr = modelInqNamePtr_c(modelID)
-        modelInqNamePtr => null()
-        slen(1) = int(strlen(cptr))
-        call c_f_pointer(cptr, modelInqNamePtr, slen)
-      end function modelInqNamePtr
-      function tableInqNamePtr(tableID)
-        integer(kind=c_int), value :: tableID
-        interface
-          function tableInqNamePtr_c(tableID) bind(c,name='tableInqNamePtr')
-            import :: c_ptr,c_int,c_char
-            integer(kind=c_int), value :: tableID
-            type(c_ptr) :: tableInqNamePtr_c
-          end function tableInqNamePtr_c
-        end interface
-        character(len=1, kind=c_char), pointer :: tableInqNamePtr(:)
-        type(c_ptr) :: cptr
-        integer :: slen(1)
-
-        cptr = tableInqNamePtr_c(tableID)
-        tableInqNamePtr => null()
-        slen(1) = int(strlen(cptr))
-        call c_f_pointer(cptr, tableInqNamePtr, slen)
-      end function tableInqNamePtr
-      function tableInqParNamePtr(tableID,parID)
-        integer(kind=c_int), value :: tableID
-        integer(kind=c_int), value :: parID
-        interface
-          function tableInqParNamePtr_c(tableID,parID) bind(c,name='tableInqParNamePtr')
-            import :: c_ptr,c_int,c_char
-            integer(kind=c_int), value :: tableID
-            integer(kind=c_int), value :: parID
-            type(c_ptr) :: tableInqParNamePtr_c
-          end function tableInqParNamePtr_c
-        end interface
-        character(len=1, kind=c_char), pointer :: tableInqParNamePtr(:)
-        type(c_ptr) :: cptr
-        integer :: slen(1)
-
-        cptr = tableInqParNamePtr_c(tableID,&
-          parID)
-        tableInqParNamePtr => null()
-        slen(1) = int(strlen(cptr))
-        call c_f_pointer(cptr, tableInqParNamePtr, slen)
-      end function tableInqParNamePtr
-      function tableInqParLongnamePtr(tableID,parID)
-        integer(kind=c_int), value :: tableID
-        integer(kind=c_int), value :: parID
-        interface
-          function tableInqParLongnamePtr_c(tableID,parID) bind(c,name='tableInqParLongnamePtr')
-            import :: c_ptr,c_int,c_char
-            integer(kind=c_int), value :: tableID
-            integer(kind=c_int), value :: parID
-            type(c_ptr) :: tableInqParLongnamePtr_c
-          end function tableInqParLongnamePtr_c
-        end interface
-        character(len=1, kind=c_char), pointer :: tableInqParLongnamePtr(:)
-        type(c_ptr) :: cptr
-        integer :: slen(1)
-
-        cptr = tableInqParLongnamePtr_c(tableID,&
-          parID)
-        tableInqParLongnamePtr => null()
-        slen(1) = int(strlen(cptr))
-        call c_f_pointer(cptr, tableInqParLongnamePtr, slen)
-      end function tableInqParLongnamePtr
-      function tableInqParUnitsPtr(tableID,parID)
-        integer(kind=c_int), value :: tableID
-        integer(kind=c_int), value :: parID
-        interface
-          function tableInqParUnitsPtr_c(tableID,parID) bind(c,name='tableInqParUnitsPtr')
-            import :: c_ptr,c_int,c_char
-            integer(kind=c_int), value :: tableID
-            integer(kind=c_int), value :: parID
-            type(c_ptr) :: tableInqParUnitsPtr_c
-          end function tableInqParUnitsPtr_c
-        end interface
-        character(len=1, kind=c_char), pointer :: tableInqParUnitsPtr(:)
-        type(c_ptr) :: cptr
-        integer :: slen(1)
-
-        cptr = tableInqParUnitsPtr_c(tableID,&
-          parID)
-        tableInqParUnitsPtr => null()
-        slen(1) = int(strlen(cptr))
-        call c_f_pointer(cptr, tableInqParUnitsPtr, slen)
-      end function tableInqParUnitsPtr
-
-    subroutine ctrim(str)
-    character(kind=c_char), intent(inout) :: str(:)
-    character(kind=c_char) :: c
-    integer :: i
-
-    do i=1,size(str)
-      c = str(i)
-      if (c == c_null_char) then
-        str(i:size(str)) = ' '
-        exit
-      end if
-    end do
-
-    end subroutine ctrim
-
-    function c_len(s) result(i)
-      character(kind=c_char), intent(in) :: s(:)
-      integer :: i
-      do i = 1, size(s)
-        if (s(i) == c_null_char) then
-          exit
-        end if
-      end do
-      i = i - 1
-    end function
 
+	subroutine ctrim(str)
+		character(kind = c_char, len = *), intent(inout) :: str
+		integer :: i
+
+		do i=1,len(str)
+			if (str(i:i) == c_null_char) then
+				str(i:len(str)) = ' '
+				exit
+			end if
+		end do
+	end subroutine ctrim
+
+	function c_len(s) result(i)
+		character(kind = c_char, len = *), intent(in) :: s
+		integer :: i
+
+		do i = 1, len(s)
+			if (s(i:i) == c_null_char) exit
+		end do
+		i = i - 1
+	end function
+
+	subroutine cdiReset()
+		interface
+			subroutine lib_cdiReset() bind(c, name = 'cdiReset')
+			end subroutine lib_cdiReset
+		end interface
+		call lib_cdiReset()
+	end subroutine cdiReset
+
+	function cdiStringError(cdiErrno_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		integer(c_int), value :: cdiErrno_dummy
+		type(c_ptr) :: ptr
+		integer :: shape(1)
+		interface
+			type(c_ptr) function lib_cdiStringError(cdiErrno_dummy) bind(c, name = 'cdiStringError')
+				import c_int, c_ptr
+				integer(c_int), value :: cdiErrno_dummy
+			end function lib_cdiStringError
+		end interface
+		result => null()
+		ptr = lib_cdiStringError(cdiErrno_dummy)
+		if(c_associated(ptr)) then
+			shape(1) = int(lib_strlen(ptr))
+			call c_f_pointer(ptr, result, shape)
+		end if
+	end function cdiStringError
+
+	subroutine cdiDebug(debug_dummy)
+		integer(c_int), value :: debug_dummy
+		interface
+			subroutine lib_cdiDebug(debug_dummy) bind(c, name = 'cdiDebug')
+				import c_int
+				integer(c_int), value :: debug_dummy
+			end subroutine lib_cdiDebug
+		end interface
+		call lib_cdiDebug(debug_dummy)
+	end subroutine cdiDebug
+
+	function cdiLibraryVersion() result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		type(c_ptr) :: ptr
+		integer :: shape(1)
+		interface
+			type(c_ptr) function lib_cdiLibraryVersion() bind(c, name = 'cdiLibraryVersion')
+				import c_ptr
+			end function lib_cdiLibraryVersion
+		end interface
+		result => null()
+		ptr = lib_cdiLibraryVersion()
+		if(c_associated(ptr)) then
+			shape(1) = int(lib_strlen(ptr))
+			call c_f_pointer(ptr, result, shape)
+		end if
+	end function cdiLibraryVersion
+
+	subroutine cdiPrintVersion()
+		interface
+			subroutine lib_cdiPrintVersion() bind(c, name = 'cdiPrintVersion')
+			end subroutine lib_cdiPrintVersion
+		end interface
+		call lib_cdiPrintVersion()
+	end subroutine cdiPrintVersion
+
+	function cdiHaveFiletype(filetype_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: filetype_dummy
+		interface
+			integer(c_int) function lib_cdiHaveFiletype(filetype_dummy) bind(c, name = 'cdiHaveFiletype')
+				import c_int
+				integer(c_int), value :: filetype_dummy
+			end function lib_cdiHaveFiletype
+		end interface
+		result = lib_cdiHaveFiletype(filetype_dummy)
+	end function cdiHaveFiletype
+
+	subroutine cdiDefMissval(missval_dummy)
+		real(c_double), value :: missval_dummy
+		interface
+			subroutine lib_cdiDefMissval(missval_dummy) bind(c, name = 'cdiDefMissval')
+				import c_double
+				real(c_double), value :: missval_dummy
+			end subroutine lib_cdiDefMissval
+		end interface
+		call lib_cdiDefMissval(missval_dummy)
+	end subroutine cdiDefMissval
+
+	function cdiInqMissval() result(result)
+		real(c_double) :: result
+		interface
+			real(c_double) function lib_cdiInqMissval() bind(c, name = 'cdiInqMissval')
+				import c_double
+			end function lib_cdiInqMissval
+		end interface
+		result = lib_cdiInqMissval()
+	end function cdiInqMissval
+
+	subroutine cdiDefGlobal(string_dummy, val_dummy)
+		character(kind = c_char, len = *), intent(in) :: string_dummy
+		integer(c_int), value :: val_dummy
+		character(kind = c_char) :: string_temp(len(string_dummy) + 1)
+		integer :: string_i
+		interface
+			subroutine lib_cdiDefGlobal(string_dummy, val_dummy) bind(c, name = 'cdiDefGlobal')
+				import c_char, c_int
+				character(kind = c_char) :: string_dummy(*)
+				integer(c_int), value :: val_dummy
+			end subroutine lib_cdiDefGlobal
+		end interface
+		do string_i = 1, len(string_dummy)
+		string_temp(string_i) = string_dummy(string_i:string_i)
+		end do
+		string_temp(len(string_dummy) + 1) = c_null_char
+		call lib_cdiDefGlobal(string_temp, val_dummy)
+	end subroutine cdiDefGlobal
+
+	function namespaceNew() result(result)
+		integer(c_int) :: result
+		interface
+			integer(c_int) function lib_namespaceNew() bind(c, name = 'namespaceNew')
+				import c_int
+			end function lib_namespaceNew
+		end interface
+		result = lib_namespaceNew()
+	end function namespaceNew
+
+	subroutine namespaceSetActive(namespaceID_dummy)
+		integer(c_int), value :: namespaceID_dummy
+		interface
+			subroutine lib_namespaceSetActive(namespaceID_dummy) bind(c, name = 'namespaceSetActive')
+				import c_int
+				integer(c_int), value :: namespaceID_dummy
+			end subroutine lib_namespaceSetActive
+		end interface
+		call lib_namespaceSetActive(namespaceID_dummy)
+	end subroutine namespaceSetActive
+
+	subroutine namespaceDelete(namespaceID_dummy)
+		integer(c_int), value :: namespaceID_dummy
+		interface
+			subroutine lib_namespaceDelete(namespaceID_dummy) bind(c, name = 'namespaceDelete')
+				import c_int
+				integer(c_int), value :: namespaceID_dummy
+			end subroutine lib_namespaceDelete
+		end interface
+		call lib_namespaceDelete(namespaceID_dummy)
+	end subroutine namespaceDelete
+
+	subroutine cdiParamToString(param_dummy, paramstr_dummy, maxlen_dummy)
+		integer(c_int), value :: param_dummy
+		character(kind = c_char, len = *), intent(inout) :: paramstr_dummy
+		integer(c_int), value :: maxlen_dummy
+		character(kind = c_char) :: paramstr_temp(len(paramstr_dummy))
+		integer :: paramstr_i
+		logical :: paramstr_padding = .true.
+		interface
+			subroutine lib_cdiParamToString(param_dummy, paramstr_dummy, maxlen_dummy) bind(c, name = 'cdiParamToString')
+				import c_char, c_int
+				integer(c_int), value :: param_dummy
+				character(kind = c_char) :: paramstr_dummy(*)
+				integer(c_int), value :: maxlen_dummy
+			end subroutine lib_cdiParamToString
+		end interface
+		do paramstr_i = len(paramstr_dummy), 1, -1
+			if(paramstr_dummy(paramstr_i:paramstr_i) /= ' ') paramstr_padding = .false.
+			if(paramstr_padding) then
+				paramstr_temp(paramstr_i) = c_null_char
+			else
+				paramstr_temp(paramstr_i) = paramstr_dummy(paramstr_i:paramstr_i)
+			end if
+		end do
+		call lib_cdiParamToString(param_dummy, paramstr_temp, maxlen_dummy)
+		paramstr_padding = .false.
+		do paramstr_i = 1, len(paramstr_dummy)
+			if(paramstr_temp(paramstr_i) == c_null_char) paramstr_padding = .true.
+			if(paramstr_padding) then
+				paramstr_dummy(paramstr_i:paramstr_i) = ' '
+			else
+				paramstr_dummy(paramstr_i:paramstr_i) = paramstr_temp(paramstr_i)
+			end if
+		end do
+	end subroutine cdiParamToString
+
+	subroutine cdiDecodeParam(param_dummy, pnum, pcat, pdis)
+		integer(c_int), value :: param_dummy
+		integer(c_int), optional, intent(inout) :: pnum
+		integer(c_int), optional, intent(inout) :: pcat
+		integer(c_int), optional, intent(inout) :: pdis
+		integer(c_int), target :: pnum_temp
+		type(c_ptr) :: pnum_ptr
+		integer(c_int), target :: pcat_temp
+		type(c_ptr) :: pcat_ptr
+		integer(c_int), target :: pdis_temp
+		type(c_ptr) :: pdis_ptr
+		interface
+			subroutine lib_cdiDecodeParam(param_dummy, pnum, pcat, pdis) bind(c, name = 'cdiDecodeParam')
+				import c_int, c_ptr
+				integer(c_int), value :: param_dummy
+				type(c_ptr), value :: pnum
+				type(c_ptr), value :: pcat
+				type(c_ptr), value :: pdis
+			end subroutine lib_cdiDecodeParam
+		end interface
+		pnum_ptr = c_null_ptr
+		if(present(pnum)) pnum_ptr = c_loc(pnum_temp)
+		pcat_ptr = c_null_ptr
+		if(present(pcat)) pcat_ptr = c_loc(pcat_temp)
+		pdis_ptr = c_null_ptr
+		if(present(pdis)) pdis_ptr = c_loc(pdis_temp)
+		call lib_cdiDecodeParam(param_dummy, pnum_ptr, pcat_ptr, pdis_ptr)
+		if(present(pnum)) pnum = pnum_temp
+		if(present(pcat)) pcat = pcat_temp
+		if(present(pdis)) pdis = pdis_temp
+	end subroutine cdiDecodeParam
+
+	function cdiEncodeParam(pnum_dummy, pcat_dummy, pdis_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: pnum_dummy
+		integer(c_int), value :: pcat_dummy
+		integer(c_int), value :: pdis_dummy
+		interface
+			integer(c_int) function lib_cdiEncodeParam(pnum_dummy, pcat_dummy, pdis_dummy) bind(c, name = 'cdiEncodeParam')
+				import c_int
+				integer(c_int), value :: pnum_dummy
+				integer(c_int), value :: pcat_dummy
+				integer(c_int), value :: pdis_dummy
+			end function lib_cdiEncodeParam
+		end interface
+		result = lib_cdiEncodeParam(pnum_dummy, pcat_dummy, pdis_dummy)
+	end function cdiEncodeParam
+
+	subroutine cdiDecodeDate(date_dummy, year, month, day)
+		integer(c_int), value :: date_dummy
+		integer(c_int), optional, intent(inout) :: year
+		integer(c_int), optional, intent(inout) :: month
+		integer(c_int), optional, intent(inout) :: day
+		integer(c_int), target :: year_temp
+		type(c_ptr) :: year_ptr
+		integer(c_int), target :: month_temp
+		type(c_ptr) :: month_ptr
+		integer(c_int), target :: day_temp
+		type(c_ptr) :: day_ptr
+		interface
+			subroutine lib_cdiDecodeDate(date_dummy, year, month, day) bind(c, name = 'cdiDecodeDate')
+				import c_int, c_ptr
+				integer(c_int), value :: date_dummy
+				type(c_ptr), value :: year
+				type(c_ptr), value :: month
+				type(c_ptr), value :: day
+			end subroutine lib_cdiDecodeDate
+		end interface
+		year_ptr = c_null_ptr
+		if(present(year)) year_ptr = c_loc(year_temp)
+		month_ptr = c_null_ptr
+		if(present(month)) month_ptr = c_loc(month_temp)
+		day_ptr = c_null_ptr
+		if(present(day)) day_ptr = c_loc(day_temp)
+		call lib_cdiDecodeDate(date_dummy, year_ptr, month_ptr, day_ptr)
+		if(present(year)) year = year_temp
+		if(present(month)) month = month_temp
+		if(present(day)) day = day_temp
+	end subroutine cdiDecodeDate
+
+	function cdiEncodeDate(year_dummy, month_dummy, day_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: year_dummy
+		integer(c_int), value :: month_dummy
+		integer(c_int), value :: day_dummy
+		interface
+			integer(c_int) function lib_cdiEncodeDate(year_dummy, month_dummy, day_dummy) bind(c, name = 'cdiEncodeDate')
+				import c_int
+				integer(c_int), value :: year_dummy
+				integer(c_int), value :: month_dummy
+				integer(c_int), value :: day_dummy
+			end function lib_cdiEncodeDate
+		end interface
+		result = lib_cdiEncodeDate(year_dummy, month_dummy, day_dummy)
+	end function cdiEncodeDate
+
+	subroutine cdiDecodeTime(time_dummy, hour, minute, second)
+		integer(c_int), value :: time_dummy
+		integer(c_int), optional, intent(inout) :: hour
+		integer(c_int), optional, intent(inout) :: minute
+		integer(c_int), optional, intent(inout) :: second
+		integer(c_int), target :: hour_temp
+		type(c_ptr) :: hour_ptr
+		integer(c_int), target :: minute_temp
+		type(c_ptr) :: minute_ptr
+		integer(c_int), target :: second_temp
+		type(c_ptr) :: second_ptr
+		interface
+			subroutine lib_cdiDecodeTime(time_dummy, hour, minute, second) bind(c, name = 'cdiDecodeTime')
+				import c_int, c_ptr
+				integer(c_int), value :: time_dummy
+				type(c_ptr), value :: hour
+				type(c_ptr), value :: minute
+				type(c_ptr), value :: second
+			end subroutine lib_cdiDecodeTime
+		end interface
+		hour_ptr = c_null_ptr
+		if(present(hour)) hour_ptr = c_loc(hour_temp)
+		minute_ptr = c_null_ptr
+		if(present(minute)) minute_ptr = c_loc(minute_temp)
+		second_ptr = c_null_ptr
+		if(present(second)) second_ptr = c_loc(second_temp)
+		call lib_cdiDecodeTime(time_dummy, hour_ptr, minute_ptr, second_ptr)
+		if(present(hour)) hour = hour_temp
+		if(present(minute)) minute = minute_temp
+		if(present(second)) second = second_temp
+	end subroutine cdiDecodeTime
+
+	function cdiEncodeTime(hour_dummy, minute_dummy, second_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: hour_dummy
+		integer(c_int), value :: minute_dummy
+		integer(c_int), value :: second_dummy
+		interface
+			integer(c_int) function lib_cdiEncodeTime(hour_dummy, minute_dummy, second_dummy) bind(c, name = 'cdiEncodeTime')
+				import c_int
+				integer(c_int), value :: hour_dummy
+				integer(c_int), value :: minute_dummy
+				integer(c_int), value :: second_dummy
+			end function lib_cdiEncodeTime
+		end interface
+		result = lib_cdiEncodeTime(hour_dummy, minute_dummy, second_dummy)
+	end function cdiEncodeTime
+
+	function cdiGetFiletype(path_dummy, byteorder) result(result)
+		integer(c_int) :: result
+		character(kind = c_char, len = *), intent(in) :: path_dummy
+		integer(c_int), optional, intent(inout) :: byteorder
+		character(kind = c_char) :: path_temp(len(path_dummy) + 1)
+		integer :: path_i
+		integer(c_int), target :: byteorder_temp
+		type(c_ptr) :: byteorder_ptr
+		interface
+			integer(c_int) function lib_cdiGetFiletype(path_dummy, byteorder) bind(c, name = 'cdiGetFiletype')
+				import c_char, c_int, c_ptr
+				character(kind = c_char) :: path_dummy(*)
+				type(c_ptr), value :: byteorder
+			end function lib_cdiGetFiletype
+		end interface
+		do path_i = 1, len(path_dummy)
+		path_temp(path_i) = path_dummy(path_i:path_i)
+		end do
+		path_temp(len(path_dummy) + 1) = c_null_char
+		byteorder_ptr = c_null_ptr
+		if(present(byteorder)) byteorder_ptr = c_loc(byteorder_temp)
+		result = lib_cdiGetFiletype(path_temp, byteorder_ptr)
+		if(present(byteorder)) byteorder = byteorder_temp
+	end function cdiGetFiletype
+
+	function streamOpenRead(path_dummy) result(result)
+		integer(c_int) :: result
+		character(kind = c_char, len = *), intent(in) :: path_dummy
+		character(kind = c_char) :: path_temp(len(path_dummy) + 1)
+		integer :: path_i
+		interface
+			integer(c_int) function lib_streamOpenRead(path_dummy) bind(c, name = 'streamOpenRead')
+				import c_char, c_int
+				character(kind = c_char) :: path_dummy(*)
+			end function lib_streamOpenRead
+		end interface
+		do path_i = 1, len(path_dummy)
+		path_temp(path_i) = path_dummy(path_i:path_i)
+		end do
+		path_temp(len(path_dummy) + 1) = c_null_char
+		result = lib_streamOpenRead(path_temp)
+	end function streamOpenRead
+
+	function streamOpenWrite(path_dummy, filetype_dummy) result(result)
+		integer(c_int) :: result
+		character(kind = c_char, len = *), intent(in) :: path_dummy
+		integer(c_int), value :: filetype_dummy
+		character(kind = c_char) :: path_temp(len(path_dummy) + 1)
+		integer :: path_i
+		interface
+			integer(c_int) function lib_streamOpenWrite(path_dummy, filetype_dummy) bind(c, name = 'streamOpenWrite')
+				import c_char, c_int
+				character(kind = c_char) :: path_dummy(*)
+				integer(c_int), value :: filetype_dummy
+			end function lib_streamOpenWrite
+		end interface
+		do path_i = 1, len(path_dummy)
+		path_temp(path_i) = path_dummy(path_i:path_i)
+		end do
+		path_temp(len(path_dummy) + 1) = c_null_char
+		result = lib_streamOpenWrite(path_temp, filetype_dummy)
+	end function streamOpenWrite
+
+	function streamOpenAppend(path_dummy) result(result)
+		integer(c_int) :: result
+		character(kind = c_char, len = *), intent(in) :: path_dummy
+		character(kind = c_char) :: path_temp(len(path_dummy) + 1)
+		integer :: path_i
+		interface
+			integer(c_int) function lib_streamOpenAppend(path_dummy) bind(c, name = 'streamOpenAppend')
+				import c_char, c_int
+				character(kind = c_char) :: path_dummy(*)
+			end function lib_streamOpenAppend
+		end interface
+		do path_i = 1, len(path_dummy)
+		path_temp(path_i) = path_dummy(path_i:path_i)
+		end do
+		path_temp(len(path_dummy) + 1) = c_null_char
+		result = lib_streamOpenAppend(path_temp)
+	end function streamOpenAppend
+
+	subroutine streamClose(streamID_dummy)
+		integer(c_int), value :: streamID_dummy
+		interface
+			subroutine lib_streamClose(streamID_dummy) bind(c, name = 'streamClose')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+			end subroutine lib_streamClose
+		end interface
+		call lib_streamClose(streamID_dummy)
+	end subroutine streamClose
+
+	subroutine streamSync(streamID_dummy)
+		integer(c_int), value :: streamID_dummy
+		interface
+			subroutine lib_streamSync(streamID_dummy) bind(c, name = 'streamSync')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+			end subroutine lib_streamSync
+		end interface
+		call lib_streamSync(streamID_dummy)
+	end subroutine streamSync
+
+	subroutine streamDefVlist(streamID_dummy, vlistID_dummy)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: vlistID_dummy
+		interface
+			subroutine lib_streamDefVlist(streamID_dummy, vlistID_dummy) bind(c, name = 'streamDefVlist')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: vlistID_dummy
+			end subroutine lib_streamDefVlist
+		end interface
+		call lib_streamDefVlist(streamID_dummy, vlistID_dummy)
+	end subroutine streamDefVlist
+
+	function streamInqVlist(streamID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: streamID_dummy
+		interface
+			integer(c_int) function lib_streamInqVlist(streamID_dummy) bind(c, name = 'streamInqVlist')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+			end function lib_streamInqVlist
+		end interface
+		result = lib_streamInqVlist(streamID_dummy)
+	end function streamInqVlist
+
+	function streamInqVlistIDorig(streamID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: streamID_dummy
+		interface
+			integer(c_int) function lib_streamInqVlistIDorig(streamID_dummy) bind(c, name = 'streamInqVlistIDorig')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+			end function lib_streamInqVlistIDorig
+		end interface
+		result = lib_streamInqVlistIDorig(streamID_dummy)
+	end function streamInqVlistIDorig
+
+	function streamInqFiletype(streamID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: streamID_dummy
+		interface
+			integer(c_int) function lib_streamInqFiletype(streamID_dummy) bind(c, name = 'streamInqFiletype')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+			end function lib_streamInqFiletype
+		end interface
+		result = lib_streamInqFiletype(streamID_dummy)
+	end function streamInqFiletype
+
+	subroutine streamDefByteorder(streamID_dummy, byteorder_dummy)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: byteorder_dummy
+		interface
+			subroutine lib_streamDefByteorder(streamID_dummy, byteorder_dummy) bind(c, name = 'streamDefByteorder')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: byteorder_dummy
+			end subroutine lib_streamDefByteorder
+		end interface
+		call lib_streamDefByteorder(streamID_dummy, byteorder_dummy)
+	end subroutine streamDefByteorder
+
+	function streamInqByteorder(streamID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: streamID_dummy
+		interface
+			integer(c_int) function lib_streamInqByteorder(streamID_dummy) bind(c, name = 'streamInqByteorder')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+			end function lib_streamInqByteorder
+		end interface
+		result = lib_streamInqByteorder(streamID_dummy)
+	end function streamInqByteorder
+
+	subroutine streamDefCompType(streamID_dummy, comptype_dummy)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: comptype_dummy
+		interface
+			subroutine lib_streamDefCompType(streamID_dummy, comptype_dummy) bind(c, name = 'streamDefCompType')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: comptype_dummy
+			end subroutine lib_streamDefCompType
+		end interface
+		call lib_streamDefCompType(streamID_dummy, comptype_dummy)
+	end subroutine streamDefCompType
+
+	function streamInqCompType(streamID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: streamID_dummy
+		interface
+			integer(c_int) function lib_streamInqCompType(streamID_dummy) bind(c, name = 'streamInqCompType')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+			end function lib_streamInqCompType
+		end interface
+		result = lib_streamInqCompType(streamID_dummy)
+	end function streamInqCompType
+
+	subroutine streamDefCompLevel(streamID_dummy, complevel_dummy)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: complevel_dummy
+		interface
+			subroutine lib_streamDefCompLevel(streamID_dummy, complevel_dummy) bind(c, name = 'streamDefCompLevel')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: complevel_dummy
+			end subroutine lib_streamDefCompLevel
+		end interface
+		call lib_streamDefCompLevel(streamID_dummy, complevel_dummy)
+	end subroutine streamDefCompLevel
+
+	function streamInqCompLevel(streamID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: streamID_dummy
+		interface
+			integer(c_int) function lib_streamInqCompLevel(streamID_dummy) bind(c, name = 'streamInqCompLevel')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+			end function lib_streamInqCompLevel
+		end interface
+		result = lib_streamInqCompLevel(streamID_dummy)
+	end function streamInqCompLevel
+
+	function streamDefTimestep(streamID_dummy, tsID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: tsID_dummy
+		interface
+			integer(c_int) function lib_streamDefTimestep(streamID_dummy, tsID_dummy) bind(c, name = 'streamDefTimestep')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: tsID_dummy
+			end function lib_streamDefTimestep
+		end interface
+		result = lib_streamDefTimestep(streamID_dummy, tsID_dummy)
+	end function streamDefTimestep
+
+	function streamInqTimestep(streamID_dummy, tsID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: tsID_dummy
+		interface
+			integer(c_int) function lib_streamInqTimestep(streamID_dummy, tsID_dummy) bind(c, name = 'streamInqTimestep')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: tsID_dummy
+			end function lib_streamInqTimestep
+		end interface
+		result = lib_streamInqTimestep(streamID_dummy, tsID_dummy)
+	end function streamInqTimestep
+
+	function streamInqCurTimestepID(streamID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: streamID_dummy
+		interface
+			integer(c_int) function lib_streamInqCurTimestepID(streamID_dummy) bind(c, name = 'streamInqCurTimestepID')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+			end function lib_streamInqCurTimestepID
+		end interface
+		result = lib_streamInqCurTimestepID(streamID_dummy)
+	end function streamInqCurTimestepID
+
+	function streamFilename(streamID_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		integer(c_int), value :: streamID_dummy
+		type(c_ptr) :: ptr
+		integer :: shape(1)
+		interface
+			type(c_ptr) function lib_streamFilename(streamID_dummy) bind(c, name = 'streamFilename')
+				import c_int, c_ptr
+				integer(c_int), value :: streamID_dummy
+			end function lib_streamFilename
+		end interface
+		result => null()
+		ptr = lib_streamFilename(streamID_dummy)
+		if(c_associated(ptr)) then
+			shape(1) = int(lib_strlen(ptr))
+			call c_f_pointer(ptr, result, shape)
+		end if
+	end function streamFilename
+
+	function streamFilesuffix(filetype_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		integer(c_int), value :: filetype_dummy
+		type(c_ptr) :: ptr
+		integer :: shape(1)
+		interface
+			type(c_ptr) function lib_streamFilesuffix(filetype_dummy) bind(c, name = 'streamFilesuffix')
+				import c_int, c_ptr
+				integer(c_int), value :: filetype_dummy
+			end function lib_streamFilesuffix
+		end interface
+		result => null()
+		ptr = lib_streamFilesuffix(filetype_dummy)
+		if(c_associated(ptr)) then
+			shape(1) = int(lib_strlen(ptr))
+			call c_f_pointer(ptr, result, shape)
+		end if
+	end function streamFilesuffix
+
+	function streamInqNvars(streamID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: streamID_dummy
+		interface
+			integer(c_int) function lib_streamInqNvars(streamID_dummy) bind(c, name = 'streamInqNvars')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+			end function lib_streamInqNvars
+		end interface
+		result = lib_streamInqNvars(streamID_dummy)
+	end function streamInqNvars
+
+	subroutine streamWriteVar(streamID_dummy, varID_dummy, data_vec_dummy, nmiss_dummy)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: varID_dummy
+		real(c_double), intent(in) :: data_vec_dummy(*)
+		integer(c_int), value :: nmiss_dummy
+		interface
+			subroutine lib_streamWriteVar(streamID_dummy, varID_dummy, data_vec_dummy, nmiss_dummy) bind(c, name = 'streamWriteVar')
+				import c_double, c_int
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: varID_dummy
+				real(c_double), intent(in) :: data_vec_dummy(*)
+				integer(c_int), value :: nmiss_dummy
+			end subroutine lib_streamWriteVar
+		end interface
+		call lib_streamWriteVar(streamID_dummy, varID_dummy, data_vec_dummy, nmiss_dummy)
+	end subroutine streamWriteVar
+
+	subroutine streamWriteVarF(streamID_dummy, varID_dummy, data_vec_dummy, nmiss_dummy)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: varID_dummy
+		real(c_float), intent(in) :: data_vec_dummy(*)
+		integer(c_int), value :: nmiss_dummy
+		interface
+			subroutine lib_streamWriteVarF(streamID_dummy, varID_dummy, data_vec_dummy, nmiss_dummy) bind(c, name = 'streamWriteVarF')
+				import c_float, c_int
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: varID_dummy
+				real(c_float), intent(in) :: data_vec_dummy(*)
+				integer(c_int), value :: nmiss_dummy
+			end subroutine lib_streamWriteVarF
+		end interface
+		call lib_streamWriteVarF(streamID_dummy, varID_dummy, data_vec_dummy, nmiss_dummy)
+	end subroutine streamWriteVarF
+
+	subroutine streamReadVar(streamID_dummy, varID_dummy, data_vec_dummy, nmiss)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: varID_dummy
+		real(c_double), intent(inout) :: data_vec_dummy(*)
+		integer(c_int), optional, intent(inout) :: nmiss
+		integer(c_int), target :: nmiss_temp
+		type(c_ptr) :: nmiss_ptr
+		interface
+			subroutine lib_streamReadVar(streamID_dummy, varID_dummy, data_vec_dummy, nmiss) bind(c, name = 'streamReadVar')
+				import c_double, c_int, c_ptr
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: varID_dummy
+				real(c_double), intent(inout) :: data_vec_dummy(*)
+				type(c_ptr), value :: nmiss
+			end subroutine lib_streamReadVar
+		end interface
+		nmiss_ptr = c_null_ptr
+		if(present(nmiss)) nmiss_ptr = c_loc(nmiss_temp)
+		call lib_streamReadVar(streamID_dummy, varID_dummy, data_vec_dummy, nmiss_ptr)
+		if(present(nmiss)) nmiss = nmiss_temp
+	end subroutine streamReadVar
+
+	subroutine streamReadVarF(streamID_dummy, varID_dummy, data_vec_dummy, nmiss)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: varID_dummy
+		real(c_float), intent(inout) :: data_vec_dummy(*)
+		integer(c_int), optional, intent(inout) :: nmiss
+		integer(c_int), target :: nmiss_temp
+		type(c_ptr) :: nmiss_ptr
+		interface
+			subroutine lib_streamReadVarF(streamID_dummy, varID_dummy, data_vec_dummy, nmiss) bind(c, name = 'streamReadVarF')
+				import c_float, c_int, c_ptr
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: varID_dummy
+				real(c_float), intent(inout) :: data_vec_dummy(*)
+				type(c_ptr), value :: nmiss
+			end subroutine lib_streamReadVarF
+		end interface
+		nmiss_ptr = c_null_ptr
+		if(present(nmiss)) nmiss_ptr = c_loc(nmiss_temp)
+		call lib_streamReadVarF(streamID_dummy, varID_dummy, data_vec_dummy, nmiss_ptr)
+		if(present(nmiss)) nmiss = nmiss_temp
+	end subroutine streamReadVarF
+
+	subroutine streamWriteVarSlice(streamID_dummy, varID_dummy, levelID_dummy, data_vec_dummy, nmiss_dummy)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: levelID_dummy
+		real(c_double), intent(in) :: data_vec_dummy(*)
+		integer(c_int), value :: nmiss_dummy
+		interface
+			subroutine lib_streamWriteVarSlice(streamID_dummy, varID_dummy, levelID_dummy, data_vec_dummy, nmiss_dummy) bind(c, name = 'stre&
+			&amWriteVarSlice')
+				import c_double, c_int
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: levelID_dummy
+				real(c_double), intent(in) :: data_vec_dummy(*)
+				integer(c_int), value :: nmiss_dummy
+			end subroutine lib_streamWriteVarSlice
+		end interface
+		call lib_streamWriteVarSlice(streamID_dummy, varID_dummy, levelID_dummy, data_vec_dummy, nmiss_dummy)
+	end subroutine streamWriteVarSlice
+
+	subroutine streamWriteVarSliceF(streamID_dummy, varID_dummy, levelID_dummy, data_vec_dummy, nmiss_dummy)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: levelID_dummy
+		real(c_float), intent(in) :: data_vec_dummy(*)
+		integer(c_int), value :: nmiss_dummy
+		interface
+			subroutine lib_streamWriteVarSliceF(streamID_dummy, varID_dummy, levelID_dummy, data_vec_dummy, nmiss_dummy) bind(c, name = 'str&
+			&eamWriteVarSliceF')
+				import c_float, c_int
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: levelID_dummy
+				real(c_float), intent(in) :: data_vec_dummy(*)
+				integer(c_int), value :: nmiss_dummy
+			end subroutine lib_streamWriteVarSliceF
+		end interface
+		call lib_streamWriteVarSliceF(streamID_dummy, varID_dummy, levelID_dummy, data_vec_dummy, nmiss_dummy)
+	end subroutine streamWriteVarSliceF
+
+	subroutine streamReadVarSlice(streamID_dummy, varID_dummy, levelID_dummy, data_vec_dummy, nmiss)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: levelID_dummy
+		real(c_double), intent(inout) :: data_vec_dummy(*)
+		integer(c_int), optional, intent(inout) :: nmiss
+		integer(c_int), target :: nmiss_temp
+		type(c_ptr) :: nmiss_ptr
+		interface
+			subroutine lib_streamReadVarSlice(streamID_dummy, varID_dummy, levelID_dummy, data_vec_dummy, nmiss) bind(c, name = 'streamReadV&
+			&arSlice')
+				import c_double, c_int, c_ptr
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: levelID_dummy
+				real(c_double), intent(inout) :: data_vec_dummy(*)
+				type(c_ptr), value :: nmiss
+			end subroutine lib_streamReadVarSlice
+		end interface
+		nmiss_ptr = c_null_ptr
+		if(present(nmiss)) nmiss_ptr = c_loc(nmiss_temp)
+		call lib_streamReadVarSlice(streamID_dummy, varID_dummy, levelID_dummy, data_vec_dummy, nmiss_ptr)
+		if(present(nmiss)) nmiss = nmiss_temp
+	end subroutine streamReadVarSlice
+
+	subroutine streamReadVarSliceF(streamID_dummy, varID_dummy, levelID_dummy, data_vec_dummy, nmiss)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: levelID_dummy
+		real(c_float), intent(inout) :: data_vec_dummy(*)
+		integer(c_int), optional, intent(inout) :: nmiss
+		integer(c_int), target :: nmiss_temp
+		type(c_ptr) :: nmiss_ptr
+		interface
+			subroutine lib_streamReadVarSliceF(streamID_dummy, varID_dummy, levelID_dummy, data_vec_dummy, nmiss) bind(c, name = 'streamRead&
+			&VarSliceF')
+				import c_float, c_int, c_ptr
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: levelID_dummy
+				real(c_float), intent(inout) :: data_vec_dummy(*)
+				type(c_ptr), value :: nmiss
+			end subroutine lib_streamReadVarSliceF
+		end interface
+		nmiss_ptr = c_null_ptr
+		if(present(nmiss)) nmiss_ptr = c_loc(nmiss_temp)
+		call lib_streamReadVarSliceF(streamID_dummy, varID_dummy, levelID_dummy, data_vec_dummy, nmiss_ptr)
+		if(present(nmiss)) nmiss = nmiss_temp
+	end subroutine streamReadVarSliceF
+
+	subroutine streamWriteVarChunk(streamID_dummy, varID_dummy, rect_dummy, data_vec_dummy, nmiss_dummy)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), intent(in) :: rect_dummy(2, 3)
+		real(c_double), intent(in) :: data_vec_dummy(*)
+		integer(c_int), value :: nmiss_dummy
+		interface
+			subroutine lib_streamWriteVarChunk(streamID_dummy, varID_dummy, rect_dummy, data_vec_dummy, nmiss_dummy) bind(c, name = 'streamW&
+			&riteVarChunk')
+				import c_double, c_int
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), intent(in) :: rect_dummy(*)
+				real(c_double), intent(in) :: data_vec_dummy(*)
+				integer(c_int), value :: nmiss_dummy
+			end subroutine lib_streamWriteVarChunk
+		end interface
+		call lib_streamWriteVarChunk(streamID_dummy, varID_dummy, rect_dummy, data_vec_dummy, nmiss_dummy)
+	end subroutine streamWriteVarChunk
+
+	subroutine streamDefRecord(streamID_dummy, varID_dummy, levelID_dummy)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: levelID_dummy
+		interface
+			subroutine lib_streamDefRecord(streamID_dummy, varID_dummy, levelID_dummy) bind(c, name = 'streamDefRecord')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: levelID_dummy
+			end subroutine lib_streamDefRecord
+		end interface
+		call lib_streamDefRecord(streamID_dummy, varID_dummy, levelID_dummy)
+	end subroutine streamDefRecord
+
+	subroutine streamInqRecord(streamID_dummy, varID, levelID)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), optional, intent(inout) :: varID
+		integer(c_int), optional, intent(inout) :: levelID
+		integer(c_int), target :: varID_temp
+		type(c_ptr) :: varID_ptr
+		integer(c_int), target :: levelID_temp
+		type(c_ptr) :: levelID_ptr
+		interface
+			subroutine lib_streamInqRecord(streamID_dummy, varID, levelID) bind(c, name = 'streamInqRecord')
+				import c_int, c_ptr
+				integer(c_int), value :: streamID_dummy
+				type(c_ptr), value :: varID
+				type(c_ptr), value :: levelID
+			end subroutine lib_streamInqRecord
+		end interface
+		varID_ptr = c_null_ptr
+		if(present(varID)) varID_ptr = c_loc(varID_temp)
+		levelID_ptr = c_null_ptr
+		if(present(levelID)) levelID_ptr = c_loc(levelID_temp)
+		call lib_streamInqRecord(streamID_dummy, varID_ptr, levelID_ptr)
+		if(present(varID)) varID = varID_temp
+		if(present(levelID)) levelID = levelID_temp
+	end subroutine streamInqRecord
+
+	subroutine streamWriteRecord(streamID_dummy, data_vec_dummy, nmiss_dummy)
+		integer(c_int), value :: streamID_dummy
+		real(c_double), intent(in) :: data_vec_dummy(*)
+		integer(c_int), value :: nmiss_dummy
+		interface
+			subroutine lib_streamWriteRecord(streamID_dummy, data_vec_dummy, nmiss_dummy) bind(c, name = 'streamWriteRecord')
+				import c_double, c_int
+				integer(c_int), value :: streamID_dummy
+				real(c_double), intent(in) :: data_vec_dummy(*)
+				integer(c_int), value :: nmiss_dummy
+			end subroutine lib_streamWriteRecord
+		end interface
+		call lib_streamWriteRecord(streamID_dummy, data_vec_dummy, nmiss_dummy)
+	end subroutine streamWriteRecord
+
+	subroutine streamWriteRecordF(streamID_dummy, data_vec_dummy, nmiss_dummy)
+		integer(c_int), value :: streamID_dummy
+		real(c_float), intent(in) :: data_vec_dummy(*)
+		integer(c_int), value :: nmiss_dummy
+		interface
+			subroutine lib_streamWriteRecordF(streamID_dummy, data_vec_dummy, nmiss_dummy) bind(c, name = 'streamWriteRecordF')
+				import c_float, c_int
+				integer(c_int), value :: streamID_dummy
+				real(c_float), intent(in) :: data_vec_dummy(*)
+				integer(c_int), value :: nmiss_dummy
+			end subroutine lib_streamWriteRecordF
+		end interface
+		call lib_streamWriteRecordF(streamID_dummy, data_vec_dummy, nmiss_dummy)
+	end subroutine streamWriteRecordF
+
+	subroutine streamReadRecord(streamID_dummy, data_vec_dummy, nmiss)
+		integer(c_int), value :: streamID_dummy
+		real(c_double), intent(inout) :: data_vec_dummy(*)
+		integer(c_int), optional, intent(inout) :: nmiss
+		integer(c_int), target :: nmiss_temp
+		type(c_ptr) :: nmiss_ptr
+		interface
+			subroutine lib_streamReadRecord(streamID_dummy, data_vec_dummy, nmiss) bind(c, name = 'streamReadRecord')
+				import c_double, c_int, c_ptr
+				integer(c_int), value :: streamID_dummy
+				real(c_double), intent(inout) :: data_vec_dummy(*)
+				type(c_ptr), value :: nmiss
+			end subroutine lib_streamReadRecord
+		end interface
+		nmiss_ptr = c_null_ptr
+		if(present(nmiss)) nmiss_ptr = c_loc(nmiss_temp)
+		call lib_streamReadRecord(streamID_dummy, data_vec_dummy, nmiss_ptr)
+		if(present(nmiss)) nmiss = nmiss_temp
+	end subroutine streamReadRecord
+
+	subroutine streamCopyRecord(streamIDdest_dummy, streamIDsrc_dummy)
+		integer(c_int), value :: streamIDdest_dummy
+		integer(c_int), value :: streamIDsrc_dummy
+		interface
+			subroutine lib_streamCopyRecord(streamIDdest_dummy, streamIDsrc_dummy) bind(c, name = 'streamCopyRecord')
+				import c_int
+				integer(c_int), value :: streamIDdest_dummy
+				integer(c_int), value :: streamIDsrc_dummy
+			end subroutine lib_streamCopyRecord
+		end interface
+		call lib_streamCopyRecord(streamIDdest_dummy, streamIDsrc_dummy)
+	end subroutine streamCopyRecord
+
+	function cdiIterator_new(path_dummy) result(result)
+		type(t_CdiIterator) :: result
+		character(kind = c_char, len = *), intent(in) :: path_dummy
+		character(kind = c_char) :: path_temp(len(path_dummy) + 1)
+		integer :: path_i
+		interface
+			type(c_ptr) function lib_cdiIterator_new(path_dummy) bind(c, name = 'cdiIterator_new')
+				import c_char, c_ptr
+				character(kind = c_char) :: path_dummy(*)
+			end function lib_cdiIterator_new
+		end interface
+		do path_i = 1, len(path_dummy)
+		path_temp(path_i) = path_dummy(path_i:path_i)
+		end do
+		path_temp(len(path_dummy) + 1) = c_null_char
+		result%ptr = lib_cdiIterator_new(path_temp)
+	end function cdiIterator_new
+
+	function cdiIterator_clone(me_dummy) result(result)
+		type(t_CdiIterator) :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		interface
+			type(c_ptr) function lib_cdiIterator_clone(me_dummy) bind(c, name = 'cdiIterator_clone')
+				import c_ptr
+				type(c_ptr), value :: me_dummy
+			end function lib_cdiIterator_clone
+		end interface
+		result%ptr = lib_cdiIterator_clone(me_dummy%ptr)
+	end function cdiIterator_clone
+
+	function cdiIterator_serialize(me_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		type(c_ptr) :: cString
+		integer :: shape(1)
+		character(kind = c_char), dimension(:), pointer :: temp
+		interface
+			type(c_ptr) function lib_cdiIterator_serialize(me_dummy) bind(c, name = 'cdiIterator_serialize')
+				import c_ptr
+				type(c_ptr), value :: me_dummy
+			end function lib_cdiIterator_serialize
+		end interface
+		cString = lib_cdiIterator_serialize(me_dummy%ptr)
+		if(c_associated(cString)) then
+			shape(1) = int(lib_strlen(cString))
+			call c_f_pointer(cString, temp, shape)
+			allocate(result(shape(1)))
+			result = temp
+			call lib_free(cString)
+		else
+			result => null()
+		end if
+	end function cdiIterator_serialize
+
+	function cdiIterator_deserialize(description_dummy) result(result)
+		type(t_CdiIterator) :: result
+		character(kind = c_char, len = *), intent(in) :: description_dummy
+		character(kind = c_char) :: description_temp(len(description_dummy) + 1)
+		integer :: description_i
+		interface
+			type(c_ptr) function lib_cdiIterator_deserialize(description_dummy) bind(c, name = 'cdiIterator_deserialize')
+				import c_char, c_ptr
+				character(kind = c_char) :: description_dummy(*)
+			end function lib_cdiIterator_deserialize
+		end interface
+		do description_i = 1, len(description_dummy)
+		description_temp(description_i) = description_dummy(description_i:description_i)
+		end do
+		description_temp(len(description_dummy) + 1) = c_null_char
+		result%ptr = lib_cdiIterator_deserialize(description_temp)
+	end function cdiIterator_deserialize
+
+	subroutine cdiIterator_delete(me_dummy)
+		type(t_CdiIterator), intent(in) :: me_dummy
+		interface
+			subroutine lib_cdiIterator_delete(me_dummy) bind(c, name = 'cdiIterator_delete')
+				import c_ptr
+				type(c_ptr), value :: me_dummy
+			end subroutine lib_cdiIterator_delete
+		end interface
+		call lib_cdiIterator_delete(me_dummy%ptr)
+	end subroutine cdiIterator_delete
+
+	function cdiIterator_nextField(me_dummy) result(result)
+		integer(c_int) :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		interface
+			integer(c_int) function lib_cdiIterator_nextField(me_dummy) bind(c, name = 'cdiIterator_nextField')
+				import c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+			end function lib_cdiIterator_nextField
+		end interface
+		result = lib_cdiIterator_nextField(me_dummy%ptr)
+	end function cdiIterator_nextField
+
+	function cdiIterator_inqStartTime(me_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		type(c_ptr) :: cString
+		integer :: shape(1)
+		character(kind = c_char), dimension(:), pointer :: temp
+		interface
+			type(c_ptr) function lib_cdiIterator_inqStartTime(me_dummy) bind(c, name = 'cdiIterator_inqStartTime')
+				import c_ptr
+				type(c_ptr), value :: me_dummy
+			end function lib_cdiIterator_inqStartTime
+		end interface
+		cString = lib_cdiIterator_inqStartTime(me_dummy%ptr)
+		if(c_associated(cString)) then
+			shape(1) = int(lib_strlen(cString))
+			call c_f_pointer(cString, temp, shape)
+			allocate(result(shape(1)))
+			result = temp
+			call lib_free(cString)
+		else
+			result => null()
+		end if
+	end function cdiIterator_inqStartTime
+
+	function cdiIterator_inqEndTime(me_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		type(c_ptr) :: cString
+		integer :: shape(1)
+		character(kind = c_char), dimension(:), pointer :: temp
+		interface
+			type(c_ptr) function lib_cdiIterator_inqEndTime(me_dummy) bind(c, name = 'cdiIterator_inqEndTime')
+				import c_ptr
+				type(c_ptr), value :: me_dummy
+			end function lib_cdiIterator_inqEndTime
+		end interface
+		cString = lib_cdiIterator_inqEndTime(me_dummy%ptr)
+		if(c_associated(cString)) then
+			shape(1) = int(lib_strlen(cString))
+			call c_f_pointer(cString, temp, shape)
+			allocate(result(shape(1)))
+			result = temp
+			call lib_free(cString)
+		else
+			result => null()
+		end if
+	end function cdiIterator_inqEndTime
+
+	function cdiIterator_inqVTime(me_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		type(c_ptr) :: cString
+		integer :: shape(1)
+		character(kind = c_char), dimension(:), pointer :: temp
+		interface
+			type(c_ptr) function lib_cdiIterator_inqVTime(me_dummy) bind(c, name = 'cdiIterator_inqVTime')
+				import c_ptr
+				type(c_ptr), value :: me_dummy
+			end function lib_cdiIterator_inqVTime
+		end interface
+		cString = lib_cdiIterator_inqVTime(me_dummy%ptr)
+		if(c_associated(cString)) then
+			shape(1) = int(lib_strlen(cString))
+			call c_f_pointer(cString, temp, shape)
+			allocate(result(shape(1)))
+			result = temp
+			call lib_free(cString)
+		else
+			result => null()
+		end if
+	end function cdiIterator_inqVTime
+
+	function cdiIterator_inqLevelType(me_dummy, levelSelector_dummy, outName, outLongName, outStdName, outUnit) result(result)
+		integer(c_int) :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		integer(c_int), value :: levelSelector_dummy
+		character(kind = c_char), pointer, optional, intent(inout) :: outName(:)
+		character(kind = c_char), pointer, optional, intent(inout) :: outLongName(:)
+		character(kind = c_char), pointer, optional, intent(inout) :: outStdName(:)
+		character(kind = c_char), pointer, optional, intent(inout) :: outUnit(:)
+		type(c_ptr), target :: outName_ptr
+		type(c_ptr) :: outName_handle
+		integer :: outName_shape(1)
+		character(kind = c_char), pointer :: outName_fptr(:)
+		type(c_ptr), target :: outLongName_ptr
+		type(c_ptr) :: outLongName_handle
+		integer :: outLongName_shape(1)
+		character(kind = c_char), pointer :: outLongName_fptr(:)
+		type(c_ptr), target :: outStdName_ptr
+		type(c_ptr) :: outStdName_handle
+		integer :: outStdName_shape(1)
+		character(kind = c_char), pointer :: outStdName_fptr(:)
+		type(c_ptr), target :: outUnit_ptr
+		type(c_ptr) :: outUnit_handle
+		integer :: outUnit_shape(1)
+		character(kind = c_char), pointer :: outUnit_fptr(:)
+		interface
+			integer(c_int) function lib_cdiIterator_inqLevelType(me_dummy, levelSelector_dummy, outName, outLongName, outStdName, outUnit) b&
+			&ind(c, name = 'cdiIterator_inqLevelType')
+				import c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+				integer(c_int), value :: levelSelector_dummy
+				type(c_ptr), value :: outName
+				type(c_ptr), value :: outLongName
+				type(c_ptr), value :: outStdName
+				type(c_ptr), value :: outUnit
+			end function lib_cdiIterator_inqLevelType
+		end interface
+		outName_handle = c_null_ptr
+		if(present(outName)) outName_handle = c_loc(outName_ptr)
+		outLongName_handle = c_null_ptr
+		if(present(outLongName)) outLongName_handle = c_loc(outLongName_ptr)
+		outStdName_handle = c_null_ptr
+		if(present(outStdName)) outStdName_handle = c_loc(outStdName_ptr)
+		outUnit_handle = c_null_ptr
+		if(present(outUnit)) outUnit_handle = c_loc(outUnit_ptr)
+		result = lib_cdiIterator_inqLevelType(me_dummy%ptr, levelSelector_dummy, outName_handle, outLongName_handle, outStdName_handle, o&
+		&utUnit_handle)
+		if(present(outName)) then
+			if(c_associated(outName_ptr)) then
+				outName_shape(1) = int(lib_strlen(outName_ptr))
+				call c_f_pointer(outName_ptr, outName_fptr, outName_shape)
+				allocate(outName(outName_shape(1)))
+				outName = outName_fptr
+				call lib_free(outName_ptr)
+			else
+				outName => null()
+			end if
+		end if
+		if(present(outLongName)) then
+			if(c_associated(outLongName_ptr)) then
+				outLongName_shape(1) = int(lib_strlen(outLongName_ptr))
+				call c_f_pointer(outLongName_ptr, outLongName_fptr, outLongName_shape)
+				allocate(outLongName(outLongName_shape(1)))
+				outLongName = outLongName_fptr
+				call lib_free(outLongName_ptr)
+			else
+				outLongName => null()
+			end if
+		end if
+		if(present(outStdName)) then
+			if(c_associated(outStdName_ptr)) then
+				outStdName_shape(1) = int(lib_strlen(outStdName_ptr))
+				call c_f_pointer(outStdName_ptr, outStdName_fptr, outStdName_shape)
+				allocate(outStdName(outStdName_shape(1)))
+				outStdName = outStdName_fptr
+				call lib_free(outStdName_ptr)
+			else
+				outStdName => null()
+			end if
+		end if
+		if(present(outUnit)) then
+			if(c_associated(outUnit_ptr)) then
+				outUnit_shape(1) = int(lib_strlen(outUnit_ptr))
+				call c_f_pointer(outUnit_ptr, outUnit_fptr, outUnit_shape)
+				allocate(outUnit(outUnit_shape(1)))
+				outUnit = outUnit_fptr
+				call lib_free(outUnit_ptr)
+			else
+				outUnit => null()
+			end if
+		end if
+	end function cdiIterator_inqLevelType
+
+	function cdiIterator_inqLevel(me_dummy, levelSelector_dummy, outValue1, outValue2) result(result)
+		integer(c_int) :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		integer(c_int), value :: levelSelector_dummy
+		real(c_double), optional, intent(inout) :: outValue1
+		real(c_double), optional, intent(inout) :: outValue2
+		real(c_double), target :: outValue1_temp
+		type(c_ptr) :: outValue1_ptr
+		real(c_double), target :: outValue2_temp
+		type(c_ptr) :: outValue2_ptr
+		interface
+			integer(c_int) function lib_cdiIterator_inqLevel(me_dummy, levelSelector_dummy, outValue1, outValue2) bind(c, name = 'cdiIterato&
+			&r_inqLevel')
+				import c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+				integer(c_int), value :: levelSelector_dummy
+				type(c_ptr), value :: outValue1
+				type(c_ptr), value :: outValue2
+			end function lib_cdiIterator_inqLevel
+		end interface
+		outValue1_ptr = c_null_ptr
+		if(present(outValue1)) outValue1_ptr = c_loc(outValue1_temp)
+		outValue2_ptr = c_null_ptr
+		if(present(outValue2)) outValue2_ptr = c_loc(outValue2_temp)
+		result = lib_cdiIterator_inqLevel(me_dummy%ptr, levelSelector_dummy, outValue1_ptr, outValue2_ptr)
+		if(present(outValue1)) outValue1 = outValue1_temp
+		if(present(outValue2)) outValue2 = outValue2_temp
+	end function cdiIterator_inqLevel
+
+	function cdiIterator_inqLevelUuid(me_dummy, outVgridNumber, outLevelCount, outUuid) result(result)
+		integer(c_int) :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		integer(c_int), optional, intent(inout) :: outVgridNumber
+		integer(c_int), optional, intent(inout) :: outLevelCount
+		character(kind = c_char), optional, intent(inout) :: outUuid(CDI_UUID_SIZE)
+		integer(c_int), target :: outVgridNumber_temp
+		type(c_ptr) :: outVgridNumber_ptr
+		integer(c_int), target :: outLevelCount_temp
+		type(c_ptr) :: outLevelCount_ptr
+		character(kind = c_char), target :: outUuid_temp(CDI_UUID_SIZE)
+		type(c_ptr) :: outUuid_ptr
+		interface
+			integer(c_int) function lib_cdiIterator_inqLevelUuid(me_dummy, outVgridNumber, outLevelCount, outUuid) bind(c, name = 'cdiIterat&
+			&or_inqLevelUuid')
+				import c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+				type(c_ptr), value :: outVgridNumber
+				type(c_ptr), value :: outLevelCount
+				type(c_ptr), value :: outUuid
+			end function lib_cdiIterator_inqLevelUuid
+		end interface
+		outVgridNumber_ptr = c_null_ptr
+		if(present(outVgridNumber)) outVgridNumber_ptr = c_loc(outVgridNumber_temp)
+		outLevelCount_ptr = c_null_ptr
+		if(present(outLevelCount)) outLevelCount_ptr = c_loc(outLevelCount_temp)
+		outUuid_ptr = c_null_ptr
+		if(present(outUuid)) outUuid_ptr = c_loc(outUuid_temp)
+		result = lib_cdiIterator_inqLevelUuid(me_dummy%ptr, outVgridNumber_ptr, outLevelCount_ptr, outUuid_ptr)
+		if(present(outVgridNumber)) outVgridNumber = outVgridNumber_temp
+		if(present(outLevelCount)) outLevelCount = outLevelCount_temp
+		if(present(outUuid)) outUuid = outUuid_temp
+	end function cdiIterator_inqLevelUuid
+
+	function cdiIterator_inqParam(me_dummy) result(result)
+		type(t_CdiParam) :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		interface
+			type(t_CdiParam) function lib_cdiIterator_inqParam(me_dummy) bind(c, name = 'cdiIterator_inqParam')
+				import c_ptr, t_CdiParam
+				type(c_ptr), value :: me_dummy
+			end function lib_cdiIterator_inqParam
+		end interface
+		result = lib_cdiIterator_inqParam(me_dummy%ptr)
+	end function cdiIterator_inqParam
+
+	function cdiIterator_inqDatatype(me_dummy) result(result)
+		integer(c_int) :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		interface
+			integer(c_int) function lib_cdiIterator_inqDatatype(me_dummy) bind(c, name = 'cdiIterator_inqDatatype')
+				import c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+			end function lib_cdiIterator_inqDatatype
+		end interface
+		result = lib_cdiIterator_inqDatatype(me_dummy%ptr)
+	end function cdiIterator_inqDatatype
+
+	function cdiIterator_inqTsteptype(me_dummy) result(result)
+		integer(c_int) :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		interface
+			integer(c_int) function lib_cdiIterator_inqTsteptype(me_dummy) bind(c, name = 'cdiIterator_inqTsteptype')
+				import c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+			end function lib_cdiIterator_inqTsteptype
+		end interface
+		result = lib_cdiIterator_inqTsteptype(me_dummy%ptr)
+	end function cdiIterator_inqTsteptype
+
+	function cdiIterator_inqVariableName(me_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		type(c_ptr) :: cString
+		integer :: shape(1)
+		character(kind = c_char), dimension(:), pointer :: temp
+		interface
+			type(c_ptr) function lib_cdiIterator_inqVariableName(me_dummy) bind(c, name = 'cdiIterator_inqVariableName')
+				import c_ptr
+				type(c_ptr), value :: me_dummy
+			end function lib_cdiIterator_inqVariableName
+		end interface
+		cString = lib_cdiIterator_inqVariableName(me_dummy%ptr)
+		if(c_associated(cString)) then
+			shape(1) = int(lib_strlen(cString))
+			call c_f_pointer(cString, temp, shape)
+			allocate(result(shape(1)))
+			result = temp
+			call lib_free(cString)
+		else
+			result => null()
+		end if
+	end function cdiIterator_inqVariableName
+
+	function cdiIterator_inqGridId(me_dummy) result(result)
+		integer(c_int) :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		interface
+			integer(c_int) function lib_cdiIterator_inqGridId(me_dummy) bind(c, name = 'cdiIterator_inqGridId')
+				import c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+			end function lib_cdiIterator_inqGridId
+		end interface
+		result = lib_cdiIterator_inqGridId(me_dummy%ptr)
+	end function cdiIterator_inqGridId
+
+	subroutine cdiIterator_readField(me_dummy, data_vec_dummy, nmiss)
+		type(t_CdiIterator), intent(in) :: me_dummy
+		real(c_double), intent(inout) :: data_vec_dummy(*)
+		integer(c_size_t), optional, intent(inout) :: nmiss
+		integer(c_size_t), target :: nmiss_temp
+		type(c_ptr) :: nmiss_ptr
+		interface
+			subroutine lib_cdiIterator_readField(me_dummy, data_vec_dummy, nmiss) bind(c, name = 'cdiIterator_readField')
+				import c_double, c_ptr
+				type(c_ptr), value :: me_dummy
+				real(c_double), intent(inout) :: data_vec_dummy(*)
+				type(c_ptr), value :: nmiss
+			end subroutine lib_cdiIterator_readField
+		end interface
+		nmiss_ptr = c_null_ptr
+		if(present(nmiss)) nmiss_ptr = c_loc(nmiss_temp)
+		call lib_cdiIterator_readField(me_dummy%ptr, data_vec_dummy, nmiss_ptr)
+		if(present(nmiss)) nmiss = nmiss_temp
+	end subroutine cdiIterator_readField
+
+	subroutine cdiIterator_readFieldF(me_dummy, data_vec_dummy, nmiss)
+		type(t_CdiIterator), intent(in) :: me_dummy
+		real(c_float), intent(inout) :: data_vec_dummy(*)
+		integer(c_size_t), optional, intent(inout) :: nmiss
+		integer(c_size_t), target :: nmiss_temp
+		type(c_ptr) :: nmiss_ptr
+		interface
+			subroutine lib_cdiIterator_readFieldF(me_dummy, data_vec_dummy, nmiss) bind(c, name = 'cdiIterator_readFieldF')
+				import c_float, c_ptr
+				type(c_ptr), value :: me_dummy
+				real(c_float), intent(inout) :: data_vec_dummy(*)
+				type(c_ptr), value :: nmiss
+			end subroutine lib_cdiIterator_readFieldF
+		end interface
+		nmiss_ptr = c_null_ptr
+		if(present(nmiss)) nmiss_ptr = c_loc(nmiss_temp)
+		call lib_cdiIterator_readFieldF(me_dummy%ptr, data_vec_dummy, nmiss_ptr)
+		if(present(nmiss)) nmiss = nmiss_temp
+	end subroutine cdiIterator_readFieldF
+
+	function cdiGribIterator_clone(me_dummy) result(result)
+		type(t_CdiGribIterator) :: result
+		type(t_CdiIterator), intent(in) :: me_dummy
+		interface
+			type(c_ptr) function lib_cdiGribIterator_clone(me_dummy) bind(c, name = 'cdiGribIterator_clone')
+				import c_ptr
+				type(c_ptr), value :: me_dummy
+			end function lib_cdiGribIterator_clone
+		end interface
+		result%ptr = lib_cdiGribIterator_clone(me_dummy%ptr)
+	end function cdiGribIterator_clone
+
+	subroutine cdiGribIterator_delete(me_dummy)
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		interface
+			subroutine lib_cdiGribIterator_delete(me_dummy) bind(c, name = 'cdiGribIterator_delete')
+				import c_ptr
+				type(c_ptr), value :: me_dummy
+			end subroutine lib_cdiGribIterator_delete
+		end interface
+		call lib_cdiGribIterator_delete(me_dummy%ptr)
+	end subroutine cdiGribIterator_delete
+
+	function cdiGribIterator_getLong(me_dummy, key_dummy, value) result(result)
+		integer(c_int) :: result
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		character(kind = c_char, len = *), intent(in) :: key_dummy
+		integer(c_long), optional, intent(inout) :: value
+		character(kind = c_char) :: key_temp(len(key_dummy) + 1)
+		integer :: key_i
+		integer(c_long), target :: value_temp
+		type(c_ptr) :: value_ptr
+		interface
+			integer(c_int) function lib_cdiGribIterator_getLong(me_dummy, key_dummy, value) bind(c, name = 'cdiGribIterator_getLong')
+				import c_char, c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+				character(kind = c_char) :: key_dummy(*)
+				type(c_ptr), value :: value
+			end function lib_cdiGribIterator_getLong
+		end interface
+		do key_i = 1, len(key_dummy)
+		key_temp(key_i) = key_dummy(key_i:key_i)
+		end do
+		key_temp(len(key_dummy) + 1) = c_null_char
+		value_ptr = c_null_ptr
+		if(present(value)) value_ptr = c_loc(value_temp)
+		result = lib_cdiGribIterator_getLong(me_dummy%ptr, key_temp, value_ptr)
+		if(present(value)) value = value_temp
+	end function cdiGribIterator_getLong
+
+	function cdiGribIterator_getDouble(me_dummy, key_dummy, value) result(result)
+		integer(c_int) :: result
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		character(kind = c_char, len = *), intent(in) :: key_dummy
+		real(c_double), optional, intent(inout) :: value
+		character(kind = c_char) :: key_temp(len(key_dummy) + 1)
+		integer :: key_i
+		real(c_double), target :: value_temp
+		type(c_ptr) :: value_ptr
+		interface
+			integer(c_int) function lib_cdiGribIterator_getDouble(me_dummy, key_dummy, value) bind(c, name = 'cdiGribIterator_getDouble')
+				import c_char, c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+				character(kind = c_char) :: key_dummy(*)
+				type(c_ptr), value :: value
+			end function lib_cdiGribIterator_getDouble
+		end interface
+		do key_i = 1, len(key_dummy)
+		key_temp(key_i) = key_dummy(key_i:key_i)
+		end do
+		key_temp(len(key_dummy) + 1) = c_null_char
+		value_ptr = c_null_ptr
+		if(present(value)) value_ptr = c_loc(value_temp)
+		result = lib_cdiGribIterator_getDouble(me_dummy%ptr, key_temp, value_ptr)
+		if(present(value)) value = value_temp
+	end function cdiGribIterator_getDouble
+
+	function cdiGribIterator_getLength(me_dummy, key_dummy, value) result(result)
+		integer(c_int) :: result
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		character(kind = c_char, len = *), intent(in) :: key_dummy
+		integer(c_size_t), optional, intent(inout) :: value
+		character(kind = c_char) :: key_temp(len(key_dummy) + 1)
+		integer :: key_i
+		integer(c_size_t), target :: value_temp
+		type(c_ptr) :: value_ptr
+		interface
+			integer(c_int) function lib_cdiGribIterator_getLength(me_dummy, key_dummy, value) bind(c, name = 'cdiGribIterator_getLength')
+				import c_char, c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+				character(kind = c_char) :: key_dummy(*)
+				type(c_ptr), value :: value
+			end function lib_cdiGribIterator_getLength
+		end interface
+		do key_i = 1, len(key_dummy)
+		key_temp(key_i) = key_dummy(key_i:key_i)
+		end do
+		key_temp(len(key_dummy) + 1) = c_null_char
+		value_ptr = c_null_ptr
+		if(present(value)) value_ptr = c_loc(value_temp)
+		result = lib_cdiGribIterator_getLength(me_dummy%ptr, key_temp, value_ptr)
+		if(present(value)) value = value_temp
+	end function cdiGribIterator_getLength
+
+	function cdiGribIterator_getString(me_dummy, key_dummy, value_dummy, length) result(result)
+		integer(c_int) :: result
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		character(kind = c_char, len = *), intent(in) :: key_dummy
+		character(kind = c_char, len = *), intent(inout) :: value_dummy
+		integer(c_size_t), optional, intent(inout) :: length
+		character(kind = c_char) :: key_temp(len(key_dummy) + 1)
+		integer :: key_i
+		character(kind = c_char) :: value_temp(len(value_dummy))
+		integer :: value_i
+		logical :: value_padding = .true.
+		integer(c_size_t), target :: length_temp
+		type(c_ptr) :: length_ptr
+		interface
+			integer(c_int) function lib_cdiGribIterator_getString(me_dummy, key_dummy, value_dummy, length) bind(c, name = 'cdiGribIterator_&
+			&getString')
+				import c_char, c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+				character(kind = c_char) :: key_dummy(*)
+				character(kind = c_char) :: value_dummy(*)
+				type(c_ptr), value :: length
+			end function lib_cdiGribIterator_getString
+		end interface
+		do key_i = 1, len(key_dummy)
+		key_temp(key_i) = key_dummy(key_i:key_i)
+		end do
+		key_temp(len(key_dummy) + 1) = c_null_char
+		do value_i = len(value_dummy), 1, -1
+			if(value_dummy(value_i:value_i) /= ' ') value_padding = .false.
+			if(value_padding) then
+				value_temp(value_i) = c_null_char
+			else
+				value_temp(value_i) = value_dummy(value_i:value_i)
+			end if
+		end do
+		length_ptr = c_null_ptr
+		if(present(length)) length_ptr = c_loc(length_temp)
+		result = lib_cdiGribIterator_getString(me_dummy%ptr, key_temp, value_temp, length_ptr)
+		value_padding = .false.
+		do value_i = 1, len(value_dummy)
+			if(value_temp(value_i) == c_null_char) value_padding = .true.
+			if(value_padding) then
+				value_dummy(value_i:value_i) = ' '
+			else
+				value_dummy(value_i:value_i) = value_temp(value_i)
+			end if
+		end do
+		if(present(length)) length = length_temp
+	end function cdiGribIterator_getString
+
+	function cdiGribIterator_getSize(me_dummy, key_dummy, value) result(result)
+		integer(c_int) :: result
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		character(kind = c_char, len = *), intent(in) :: key_dummy
+		integer(c_size_t), optional, intent(inout) :: value
+		character(kind = c_char) :: key_temp(len(key_dummy) + 1)
+		integer :: key_i
+		integer(c_size_t), target :: value_temp
+		type(c_ptr) :: value_ptr
+		interface
+			integer(c_int) function lib_cdiGribIterator_getSize(me_dummy, key_dummy, value) bind(c, name = 'cdiGribIterator_getSize')
+				import c_char, c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+				character(kind = c_char) :: key_dummy(*)
+				type(c_ptr), value :: value
+			end function lib_cdiGribIterator_getSize
+		end interface
+		do key_i = 1, len(key_dummy)
+		key_temp(key_i) = key_dummy(key_i:key_i)
+		end do
+		key_temp(len(key_dummy) + 1) = c_null_char
+		value_ptr = c_null_ptr
+		if(present(value)) value_ptr = c_loc(value_temp)
+		result = lib_cdiGribIterator_getSize(me_dummy%ptr, key_temp, value_ptr)
+		if(present(value)) value = value_temp
+	end function cdiGribIterator_getSize
+
+	function cdiGribIterator_getLongArray(me_dummy, key_dummy, value, array_size) result(result)
+		integer(c_int) :: result
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		character(kind = c_char, len = *), intent(in) :: key_dummy
+		integer(c_long), optional, intent(inout) :: value
+		integer(c_size_t), optional, intent(inout) :: array_size
+		character(kind = c_char) :: key_temp(len(key_dummy) + 1)
+		integer :: key_i
+		integer(c_long), target :: value_temp
+		type(c_ptr) :: value_ptr
+		integer(c_size_t), target :: array_size_temp
+		type(c_ptr) :: array_size_ptr
+		interface
+			integer(c_int) function lib_cdiGribIterator_getLongArray(me_dummy, key_dummy, value, array_size) bind(c, name = 'cdiGribIterator&
+			&_getLongArray')
+				import c_char, c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+				character(kind = c_char) :: key_dummy(*)
+				type(c_ptr), value :: value
+				type(c_ptr), value :: array_size
+			end function lib_cdiGribIterator_getLongArray
+		end interface
+		do key_i = 1, len(key_dummy)
+		key_temp(key_i) = key_dummy(key_i:key_i)
+		end do
+		key_temp(len(key_dummy) + 1) = c_null_char
+		value_ptr = c_null_ptr
+		if(present(value)) value_ptr = c_loc(value_temp)
+		array_size_ptr = c_null_ptr
+		if(present(array_size)) array_size_ptr = c_loc(array_size_temp)
+		result = lib_cdiGribIterator_getLongArray(me_dummy%ptr, key_temp, value_ptr, array_size_ptr)
+		if(present(value)) value = value_temp
+		if(present(array_size)) array_size = array_size_temp
+	end function cdiGribIterator_getLongArray
+
+	function cdiGribIterator_getDoubleArray(me_dummy, key_dummy, value, array_size) result(result)
+		integer(c_int) :: result
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		character(kind = c_char, len = *), intent(in) :: key_dummy
+		real(c_double), optional, intent(inout) :: value
+		integer(c_size_t), optional, intent(inout) :: array_size
+		character(kind = c_char) :: key_temp(len(key_dummy) + 1)
+		integer :: key_i
+		real(c_double), target :: value_temp
+		type(c_ptr) :: value_ptr
+		integer(c_size_t), target :: array_size_temp
+		type(c_ptr) :: array_size_ptr
+		interface
+			integer(c_int) function lib_cdiGribIterator_getDoubleArray(me_dummy, key_dummy, value, array_size) bind(c, name = 'cdiGribIterat&
+			&or_getDoubleArray')
+				import c_char, c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+				character(kind = c_char) :: key_dummy(*)
+				type(c_ptr), value :: value
+				type(c_ptr), value :: array_size
+			end function lib_cdiGribIterator_getDoubleArray
+		end interface
+		do key_i = 1, len(key_dummy)
+		key_temp(key_i) = key_dummy(key_i:key_i)
+		end do
+		key_temp(len(key_dummy) + 1) = c_null_char
+		value_ptr = c_null_ptr
+		if(present(value)) value_ptr = c_loc(value_temp)
+		array_size_ptr = c_null_ptr
+		if(present(array_size)) array_size_ptr = c_loc(array_size_temp)
+		result = lib_cdiGribIterator_getDoubleArray(me_dummy%ptr, key_temp, value_ptr, array_size_ptr)
+		if(present(value)) value = value_temp
+		if(present(array_size)) array_size = array_size_temp
+	end function cdiGribIterator_getDoubleArray
+
+	function cdiGribIterator_inqEdition(me_dummy) result(result)
+		integer(c_int) :: result
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		interface
+			integer(c_int) function lib_cdiGribIterator_inqEdition(me_dummy) bind(c, name = 'cdiGribIterator_inqEdition')
+				import c_int, c_ptr
+				type(c_ptr), value :: me_dummy
+			end function lib_cdiGribIterator_inqEdition
+		end interface
+		result = lib_cdiGribIterator_inqEdition(me_dummy%ptr)
+	end function cdiGribIterator_inqEdition
+
+	function cdiGribIterator_inqLongValue(me_dummy, key_dummy) result(result)
+		integer(c_long) :: result
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		character(kind = c_char, len = *), intent(in) :: key_dummy
+		character(kind = c_char) :: key_temp(len(key_dummy) + 1)
+		integer :: key_i
+		interface
+			integer(c_long) function lib_cdiGribIterator_inqLongValue(me_dummy, key_dummy) bind(c, name = 'cdiGribIterator_inqLongValue')
+				import c_char, c_long, c_ptr
+				type(c_ptr), value :: me_dummy
+				character(kind = c_char) :: key_dummy(*)
+			end function lib_cdiGribIterator_inqLongValue
+		end interface
+		do key_i = 1, len(key_dummy)
+		key_temp(key_i) = key_dummy(key_i:key_i)
+		end do
+		key_temp(len(key_dummy) + 1) = c_null_char
+		result = lib_cdiGribIterator_inqLongValue(me_dummy%ptr, key_temp)
+	end function cdiGribIterator_inqLongValue
+
+	function cdiGribIterator_inqLongDefaultValue(me_dummy, key_dummy, defaultValue_dummy) result(result)
+		integer(c_long) :: result
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		character(kind = c_char, len = *), intent(in) :: key_dummy
+		integer(c_long), value :: defaultValue_dummy
+		character(kind = c_char) :: key_temp(len(key_dummy) + 1)
+		integer :: key_i
+		interface
+			integer(c_long) function lib_cdiGribIterator_inqLongDefaultValue(me_dummy, key_dummy, defaultValue_dummy) bind(c, name = 'cdiGri&
+			&bIterator_inqLongDefaultValue')
+				import c_char, c_long, c_ptr
+				type(c_ptr), value :: me_dummy
+				character(kind = c_char) :: key_dummy(*)
+				integer(c_long), value :: defaultValue_dummy
+			end function lib_cdiGribIterator_inqLongDefaultValue
+		end interface
+		do key_i = 1, len(key_dummy)
+		key_temp(key_i) = key_dummy(key_i:key_i)
+		end do
+		key_temp(len(key_dummy) + 1) = c_null_char
+		result = lib_cdiGribIterator_inqLongDefaultValue(me_dummy%ptr, key_temp, defaultValue_dummy)
+	end function cdiGribIterator_inqLongDefaultValue
+
+	function cdiGribIterator_inqDoubleValue(me_dummy, key_dummy) result(result)
+		real(c_double) :: result
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		character(kind = c_char, len = *), intent(in) :: key_dummy
+		character(kind = c_char) :: key_temp(len(key_dummy) + 1)
+		integer :: key_i
+		interface
+			real(c_double) function lib_cdiGribIterator_inqDoubleValue(me_dummy, key_dummy) bind(c, name = 'cdiGribIterator_inqDoubleValue')
+				import c_char, c_double, c_ptr
+				type(c_ptr), value :: me_dummy
+				character(kind = c_char) :: key_dummy(*)
+			end function lib_cdiGribIterator_inqDoubleValue
+		end interface
+		do key_i = 1, len(key_dummy)
+		key_temp(key_i) = key_dummy(key_i:key_i)
+		end do
+		key_temp(len(key_dummy) + 1) = c_null_char
+		result = lib_cdiGribIterator_inqDoubleValue(me_dummy%ptr, key_temp)
+	end function cdiGribIterator_inqDoubleValue
+
+	function cdiGribIterator_inqDoubleDefaultValue(me_dummy, key_dummy, defaultValue_dummy) result(result)
+		real(c_double) :: result
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		character(kind = c_char, len = *), intent(in) :: key_dummy
+		real(c_double), value :: defaultValue_dummy
+		character(kind = c_char) :: key_temp(len(key_dummy) + 1)
+		integer :: key_i
+		interface
+			real(c_double) function lib_cdiGribIterator_inqDoubleDefaultValue(me_dummy, key_dummy, defaultValue_dummy) bind(c, name = 'cdiGr&
+			&ibIterator_inqDoubleDefaultValue')
+				import c_char, c_double, c_ptr
+				type(c_ptr), value :: me_dummy
+				character(kind = c_char) :: key_dummy(*)
+				real(c_double), value :: defaultValue_dummy
+			end function lib_cdiGribIterator_inqDoubleDefaultValue
+		end interface
+		do key_i = 1, len(key_dummy)
+		key_temp(key_i) = key_dummy(key_i:key_i)
+		end do
+		key_temp(len(key_dummy) + 1) = c_null_char
+		result = lib_cdiGribIterator_inqDoubleDefaultValue(me_dummy%ptr, key_temp, defaultValue_dummy)
+	end function cdiGribIterator_inqDoubleDefaultValue
+
+	function cdiGribIterator_inqStringValue(me_dummy, key_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		type(t_CdiGribIterator), intent(in) :: me_dummy
+		character(kind = c_char, len = *), intent(in) :: key_dummy
+		character(kind = c_char) :: key_temp(len(key_dummy) + 1)
+		integer :: key_i
+		type(c_ptr) :: cString
+		integer :: shape(1)
+		character(kind = c_char), dimension(:), pointer :: temp
+		interface
+			type(c_ptr) function lib_cdiGribIterator_inqStringValue(me_dummy, key_dummy) bind(c, name = 'cdiGribIterator_inqStringValue')
+				import c_char, c_ptr
+				type(c_ptr), value :: me_dummy
+				character(kind = c_char) :: key_dummy(*)
+			end function lib_cdiGribIterator_inqStringValue
+		end interface
+		do key_i = 1, len(key_dummy)
+		key_temp(key_i) = key_dummy(key_i:key_i)
+		end do
+		key_temp(len(key_dummy) + 1) = c_null_char
+		cString = lib_cdiGribIterator_inqStringValue(me_dummy%ptr, key_temp)
+		if(c_associated(cString)) then
+			shape(1) = int(lib_strlen(cString))
+			call c_f_pointer(cString, temp, shape)
+			allocate(result(shape(1)))
+			result = temp
+			call lib_free(cString)
+		else
+			result => null()
+		end if
+	end function cdiGribIterator_inqStringValue
+
+	function vlistCreate() result(result)
+		integer(c_int) :: result
+		interface
+			integer(c_int) function lib_vlistCreate() bind(c, name = 'vlistCreate')
+				import c_int
+			end function lib_vlistCreate
+		end interface
+		result = lib_vlistCreate()
+	end function vlistCreate
+
+	subroutine vlistDestroy(vlistID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		interface
+			subroutine lib_vlistDestroy(vlistID_dummy) bind(c, name = 'vlistDestroy')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end subroutine lib_vlistDestroy
+		end interface
+		call lib_vlistDestroy(vlistID_dummy)
+	end subroutine vlistDestroy
+
+	function vlistDuplicate(vlistID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		interface
+			integer(c_int) function lib_vlistDuplicate(vlistID_dummy) bind(c, name = 'vlistDuplicate')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end function lib_vlistDuplicate
+		end interface
+		result = lib_vlistDuplicate(vlistID_dummy)
+	end function vlistDuplicate
+
+	subroutine vlistCopy(vlistID2_dummy, vlistID1_dummy)
+		integer(c_int), value :: vlistID2_dummy
+		integer(c_int), value :: vlistID1_dummy
+		interface
+			subroutine lib_vlistCopy(vlistID2_dummy, vlistID1_dummy) bind(c, name = 'vlistCopy')
+				import c_int
+				integer(c_int), value :: vlistID2_dummy
+				integer(c_int), value :: vlistID1_dummy
+			end subroutine lib_vlistCopy
+		end interface
+		call lib_vlistCopy(vlistID2_dummy, vlistID1_dummy)
+	end subroutine vlistCopy
+
+	subroutine vlistCopyFlag(vlistID2_dummy, vlistID1_dummy)
+		integer(c_int), value :: vlistID2_dummy
+		integer(c_int), value :: vlistID1_dummy
+		interface
+			subroutine lib_vlistCopyFlag(vlistID2_dummy, vlistID1_dummy) bind(c, name = 'vlistCopyFlag')
+				import c_int
+				integer(c_int), value :: vlistID2_dummy
+				integer(c_int), value :: vlistID1_dummy
+			end subroutine lib_vlistCopyFlag
+		end interface
+		call lib_vlistCopyFlag(vlistID2_dummy, vlistID1_dummy)
+	end subroutine vlistCopyFlag
+
+	subroutine vlistClearFlag(vlistID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		interface
+			subroutine lib_vlistClearFlag(vlistID_dummy) bind(c, name = 'vlistClearFlag')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end subroutine lib_vlistClearFlag
+		end interface
+		call lib_vlistClearFlag(vlistID_dummy)
+	end subroutine vlistClearFlag
+
+	subroutine vlistCat(vlistID2_dummy, vlistID1_dummy)
+		integer(c_int), value :: vlistID2_dummy
+		integer(c_int), value :: vlistID1_dummy
+		interface
+			subroutine lib_vlistCat(vlistID2_dummy, vlistID1_dummy) bind(c, name = 'vlistCat')
+				import c_int
+				integer(c_int), value :: vlistID2_dummy
+				integer(c_int), value :: vlistID1_dummy
+			end subroutine lib_vlistCat
+		end interface
+		call lib_vlistCat(vlistID2_dummy, vlistID1_dummy)
+	end subroutine vlistCat
+
+	subroutine vlistMerge(vlistID2_dummy, vlistID1_dummy)
+		integer(c_int), value :: vlistID2_dummy
+		integer(c_int), value :: vlistID1_dummy
+		interface
+			subroutine lib_vlistMerge(vlistID2_dummy, vlistID1_dummy) bind(c, name = 'vlistMerge')
+				import c_int
+				integer(c_int), value :: vlistID2_dummy
+				integer(c_int), value :: vlistID1_dummy
+			end subroutine lib_vlistMerge
+		end interface
+		call lib_vlistMerge(vlistID2_dummy, vlistID1_dummy)
+	end subroutine vlistMerge
+
+	subroutine vlistPrint(vlistID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		interface
+			subroutine lib_vlistPrint(vlistID_dummy) bind(c, name = 'vlistPrint')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end subroutine lib_vlistPrint
+		end interface
+		call lib_vlistPrint(vlistID_dummy)
+	end subroutine vlistPrint
+
+	function vlistNumber(vlistID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		interface
+			integer(c_int) function lib_vlistNumber(vlistID_dummy) bind(c, name = 'vlistNumber')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end function lib_vlistNumber
+		end interface
+		result = lib_vlistNumber(vlistID_dummy)
+	end function vlistNumber
+
+	function vlistNvars(vlistID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		interface
+			integer(c_int) function lib_vlistNvars(vlistID_dummy) bind(c, name = 'vlistNvars')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end function lib_vlistNvars
+		end interface
+		result = lib_vlistNvars(vlistID_dummy)
+	end function vlistNvars
+
+	function vlistNgrids(vlistID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		interface
+			integer(c_int) function lib_vlistNgrids(vlistID_dummy) bind(c, name = 'vlistNgrids')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end function lib_vlistNgrids
+		end interface
+		result = lib_vlistNgrids(vlistID_dummy)
+	end function vlistNgrids
+
+	function vlistNzaxis(vlistID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		interface
+			integer(c_int) function lib_vlistNzaxis(vlistID_dummy) bind(c, name = 'vlistNzaxis')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end function lib_vlistNzaxis
+		end interface
+		result = lib_vlistNzaxis(vlistID_dummy)
+	end function vlistNzaxis
+
+	subroutine vlistDefNtsteps(vlistID_dummy, nts_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: nts_dummy
+		interface
+			subroutine lib_vlistDefNtsteps(vlistID_dummy, nts_dummy) bind(c, name = 'vlistDefNtsteps')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: nts_dummy
+			end subroutine lib_vlistDefNtsteps
+		end interface
+		call lib_vlistDefNtsteps(vlistID_dummy, nts_dummy)
+	end subroutine vlistDefNtsteps
+
+	function vlistNtsteps(vlistID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		interface
+			integer(c_int) function lib_vlistNtsteps(vlistID_dummy) bind(c, name = 'vlistNtsteps')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end function lib_vlistNtsteps
+		end interface
+		result = lib_vlistNtsteps(vlistID_dummy)
+	end function vlistNtsteps
+
+	function vlistGridsizeMax(vlistID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		interface
+			integer(c_int) function lib_vlistGridsizeMax(vlistID_dummy) bind(c, name = 'vlistGridsizeMax')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end function lib_vlistGridsizeMax
+		end interface
+		result = lib_vlistGridsizeMax(vlistID_dummy)
+	end function vlistGridsizeMax
+
+	function vlistGrid(vlistID_dummy, index_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: index_dummy
+		interface
+			integer(c_int) function lib_vlistGrid(vlistID_dummy, index_dummy) bind(c, name = 'vlistGrid')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: index_dummy
+			end function lib_vlistGrid
+		end interface
+		result = lib_vlistGrid(vlistID_dummy, index_dummy)
+	end function vlistGrid
+
+	function vlistGridIndex(vlistID_dummy, gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_vlistGridIndex(vlistID_dummy, gridID_dummy) bind(c, name = 'vlistGridIndex')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: gridID_dummy
+			end function lib_vlistGridIndex
+		end interface
+		result = lib_vlistGridIndex(vlistID_dummy, gridID_dummy)
+	end function vlistGridIndex
+
+	subroutine vlistChangeGridIndex(vlistID_dummy, index_dummy, gridID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: index_dummy
+		integer(c_int), value :: gridID_dummy
+		interface
+			subroutine lib_vlistChangeGridIndex(vlistID_dummy, index_dummy, gridID_dummy) bind(c, name = 'vlistChangeGridIndex')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: index_dummy
+				integer(c_int), value :: gridID_dummy
+			end subroutine lib_vlistChangeGridIndex
+		end interface
+		call lib_vlistChangeGridIndex(vlistID_dummy, index_dummy, gridID_dummy)
+	end subroutine vlistChangeGridIndex
+
+	subroutine vlistChangeGrid(vlistID_dummy, gridID1_dummy, gridID2_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: gridID1_dummy
+		integer(c_int), value :: gridID2_dummy
+		interface
+			subroutine lib_vlistChangeGrid(vlistID_dummy, gridID1_dummy, gridID2_dummy) bind(c, name = 'vlistChangeGrid')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: gridID1_dummy
+				integer(c_int), value :: gridID2_dummy
+			end subroutine lib_vlistChangeGrid
+		end interface
+		call lib_vlistChangeGrid(vlistID_dummy, gridID1_dummy, gridID2_dummy)
+	end subroutine vlistChangeGrid
+
+	function vlistZaxis(vlistID_dummy, index_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: index_dummy
+		interface
+			integer(c_int) function lib_vlistZaxis(vlistID_dummy, index_dummy) bind(c, name = 'vlistZaxis')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: index_dummy
+			end function lib_vlistZaxis
+		end interface
+		result = lib_vlistZaxis(vlistID_dummy, index_dummy)
+	end function vlistZaxis
+
+	function vlistZaxisIndex(vlistID_dummy, zaxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: zaxisID_dummy
+		interface
+			integer(c_int) function lib_vlistZaxisIndex(vlistID_dummy, zaxisID_dummy) bind(c, name = 'vlistZaxisIndex')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: zaxisID_dummy
+			end function lib_vlistZaxisIndex
+		end interface
+		result = lib_vlistZaxisIndex(vlistID_dummy, zaxisID_dummy)
+	end function vlistZaxisIndex
+
+	subroutine vlistChangeZaxisIndex(vlistID_dummy, index_dummy, zaxisID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: index_dummy
+		integer(c_int), value :: zaxisID_dummy
+		interface
+			subroutine lib_vlistChangeZaxisIndex(vlistID_dummy, index_dummy, zaxisID_dummy) bind(c, name = 'vlistChangeZaxisIndex')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: index_dummy
+				integer(c_int), value :: zaxisID_dummy
+			end subroutine lib_vlistChangeZaxisIndex
+		end interface
+		call lib_vlistChangeZaxisIndex(vlistID_dummy, index_dummy, zaxisID_dummy)
+	end subroutine vlistChangeZaxisIndex
+
+	subroutine vlistChangeZaxis(vlistID_dummy, zaxisID1_dummy, zaxisID2_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: zaxisID1_dummy
+		integer(c_int), value :: zaxisID2_dummy
+		interface
+			subroutine lib_vlistChangeZaxis(vlistID_dummy, zaxisID1_dummy, zaxisID2_dummy) bind(c, name = 'vlistChangeZaxis')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: zaxisID1_dummy
+				integer(c_int), value :: zaxisID2_dummy
+			end subroutine lib_vlistChangeZaxis
+		end interface
+		call lib_vlistChangeZaxis(vlistID_dummy, zaxisID1_dummy, zaxisID2_dummy)
+	end subroutine vlistChangeZaxis
+
+	function vlistNrecs(vlistID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		interface
+			integer(c_int) function lib_vlistNrecs(vlistID_dummy) bind(c, name = 'vlistNrecs')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end function lib_vlistNrecs
+		end interface
+		result = lib_vlistNrecs(vlistID_dummy)
+	end function vlistNrecs
+
+	subroutine vlistDefTaxis(vlistID_dummy, taxisID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: taxisID_dummy
+		interface
+			subroutine lib_vlistDefTaxis(vlistID_dummy, taxisID_dummy) bind(c, name = 'vlistDefTaxis')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: taxisID_dummy
+			end subroutine lib_vlistDefTaxis
+		end interface
+		call lib_vlistDefTaxis(vlistID_dummy, taxisID_dummy)
+	end subroutine vlistDefTaxis
+
+	function vlistInqTaxis(vlistID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		interface
+			integer(c_int) function lib_vlistInqTaxis(vlistID_dummy) bind(c, name = 'vlistInqTaxis')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end function lib_vlistInqTaxis
+		end interface
+		result = lib_vlistInqTaxis(vlistID_dummy)
+	end function vlistInqTaxis
+
+	subroutine vlistDefTable(vlistID_dummy, tableID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: tableID_dummy
+		interface
+			subroutine lib_vlistDefTable(vlistID_dummy, tableID_dummy) bind(c, name = 'vlistDefTable')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: tableID_dummy
+			end subroutine lib_vlistDefTable
+		end interface
+		call lib_vlistDefTable(vlistID_dummy, tableID_dummy)
+	end subroutine vlistDefTable
+
+	function vlistInqTable(vlistID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		interface
+			integer(c_int) function lib_vlistInqTable(vlistID_dummy) bind(c, name = 'vlistInqTable')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end function lib_vlistInqTable
+		end interface
+		result = lib_vlistInqTable(vlistID_dummy)
+	end function vlistInqTable
+
+	subroutine vlistDefInstitut(vlistID_dummy, instID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: instID_dummy
+		interface
+			subroutine lib_vlistDefInstitut(vlistID_dummy, instID_dummy) bind(c, name = 'vlistDefInstitut')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: instID_dummy
+			end subroutine lib_vlistDefInstitut
+		end interface
+		call lib_vlistDefInstitut(vlistID_dummy, instID_dummy)
+	end subroutine vlistDefInstitut
+
+	function vlistInqInstitut(vlistID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		interface
+			integer(c_int) function lib_vlistInqInstitut(vlistID_dummy) bind(c, name = 'vlistInqInstitut')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end function lib_vlistInqInstitut
+		end interface
+		result = lib_vlistInqInstitut(vlistID_dummy)
+	end function vlistInqInstitut
+
+	subroutine vlistDefModel(vlistID_dummy, modelID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: modelID_dummy
+		interface
+			subroutine lib_vlistDefModel(vlistID_dummy, modelID_dummy) bind(c, name = 'vlistDefModel')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: modelID_dummy
+			end subroutine lib_vlistDefModel
+		end interface
+		call lib_vlistDefModel(vlistID_dummy, modelID_dummy)
+	end subroutine vlistDefModel
+
+	function vlistInqModel(vlistID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		interface
+			integer(c_int) function lib_vlistInqModel(vlistID_dummy) bind(c, name = 'vlistInqModel')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+			end function lib_vlistInqModel
+		end interface
+		result = lib_vlistInqModel(vlistID_dummy)
+	end function vlistInqModel
+
+	function vlistDefVar(vlistID_dummy, gridID_dummy, zaxisID_dummy, tsteptype_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: zaxisID_dummy
+		integer(c_int), value :: tsteptype_dummy
+		interface
+			integer(c_int) function lib_vlistDefVar(vlistID_dummy, gridID_dummy, zaxisID_dummy, tsteptype_dummy) bind(c, name = 'vlistDefVar&
+			&')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: zaxisID_dummy
+				integer(c_int), value :: tsteptype_dummy
+			end function lib_vlistDefVar
+		end interface
+		result = lib_vlistDefVar(vlistID_dummy, gridID_dummy, zaxisID_dummy, tsteptype_dummy)
+	end function vlistDefVar
+
+	subroutine vlistChangeVarGrid(vlistID_dummy, varID_dummy, gridID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: gridID_dummy
+		interface
+			subroutine lib_vlistChangeVarGrid(vlistID_dummy, varID_dummy, gridID_dummy) bind(c, name = 'vlistChangeVarGrid')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: gridID_dummy
+			end subroutine lib_vlistChangeVarGrid
+		end interface
+		call lib_vlistChangeVarGrid(vlistID_dummy, varID_dummy, gridID_dummy)
+	end subroutine vlistChangeVarGrid
+
+	subroutine vlistChangeVarZaxis(vlistID_dummy, varID_dummy, zaxisID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: zaxisID_dummy
+		interface
+			subroutine lib_vlistChangeVarZaxis(vlistID_dummy, varID_dummy, zaxisID_dummy) bind(c, name = 'vlistChangeVarZaxis')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: zaxisID_dummy
+			end subroutine lib_vlistChangeVarZaxis
+		end interface
+		call lib_vlistChangeVarZaxis(vlistID_dummy, varID_dummy, zaxisID_dummy)
+	end subroutine vlistChangeVarZaxis
+
+	subroutine vlistInqVar(vlistID_dummy, varID_dummy, gridID, zaxisID, tsteptype)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), optional, intent(inout) :: gridID
+		integer(c_int), optional, intent(inout) :: zaxisID
+		integer(c_int), optional, intent(inout) :: tsteptype
+		integer(c_int), target :: gridID_temp
+		type(c_ptr) :: gridID_ptr
+		integer(c_int), target :: zaxisID_temp
+		type(c_ptr) :: zaxisID_ptr
+		integer(c_int), target :: tsteptype_temp
+		type(c_ptr) :: tsteptype_ptr
+		interface
+			subroutine lib_vlistInqVar(vlistID_dummy, varID_dummy, gridID, zaxisID, tsteptype) bind(c, name = 'vlistInqVar')
+				import c_int, c_ptr
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				type(c_ptr), value :: gridID
+				type(c_ptr), value :: zaxisID
+				type(c_ptr), value :: tsteptype
+			end subroutine lib_vlistInqVar
+		end interface
+		gridID_ptr = c_null_ptr
+		if(present(gridID)) gridID_ptr = c_loc(gridID_temp)
+		zaxisID_ptr = c_null_ptr
+		if(present(zaxisID)) zaxisID_ptr = c_loc(zaxisID_temp)
+		tsteptype_ptr = c_null_ptr
+		if(present(tsteptype)) tsteptype_ptr = c_loc(tsteptype_temp)
+		call lib_vlistInqVar(vlistID_dummy, varID_dummy, gridID_ptr, zaxisID_ptr, tsteptype_ptr)
+		if(present(gridID)) gridID = gridID_temp
+		if(present(zaxisID)) zaxisID = zaxisID_temp
+		if(present(tsteptype)) tsteptype = tsteptype_temp
+	end subroutine vlistInqVar
+
+	function vlistInqVarGrid(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarGrid(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarGrid')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarGrid
+		end interface
+		result = lib_vlistInqVarGrid(vlistID_dummy, varID_dummy)
+	end function vlistInqVarGrid
+
+	function vlistInqVarZaxis(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarZaxis(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarZaxis')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarZaxis
+		end interface
+		result = lib_vlistInqVarZaxis(vlistID_dummy, varID_dummy)
+	end function vlistInqVarZaxis
+
+	function vlistInqVarID(vlistID_dummy, code_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: code_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarID(vlistID_dummy, code_dummy) bind(c, name = 'vlistInqVarID')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: code_dummy
+			end function lib_vlistInqVarID
+		end interface
+		result = lib_vlistInqVarID(vlistID_dummy, code_dummy)
+	end function vlistInqVarID
+
+	subroutine vlistDefVarTsteptype(vlistID_dummy, varID_dummy, tsteptype_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: tsteptype_dummy
+		interface
+			subroutine lib_vlistDefVarTsteptype(vlistID_dummy, varID_dummy, tsteptype_dummy) bind(c, name = 'vlistDefVarTsteptype')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: tsteptype_dummy
+			end subroutine lib_vlistDefVarTsteptype
+		end interface
+		call lib_vlistDefVarTsteptype(vlistID_dummy, varID_dummy, tsteptype_dummy)
+	end subroutine vlistDefVarTsteptype
+
+	function vlistInqVarTsteptype(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarTsteptype(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarTsteptype')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarTsteptype
+		end interface
+		result = lib_vlistInqVarTsteptype(vlistID_dummy, varID_dummy)
+	end function vlistInqVarTsteptype
+
+	subroutine vlistDefVarCompType(vlistID_dummy, varID_dummy, comptype_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: comptype_dummy
+		interface
+			subroutine lib_vlistDefVarCompType(vlistID_dummy, varID_dummy, comptype_dummy) bind(c, name = 'vlistDefVarCompType')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: comptype_dummy
+			end subroutine lib_vlistDefVarCompType
+		end interface
+		call lib_vlistDefVarCompType(vlistID_dummy, varID_dummy, comptype_dummy)
+	end subroutine vlistDefVarCompType
+
+	function vlistInqVarCompType(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarCompType(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarCompType')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarCompType
+		end interface
+		result = lib_vlistInqVarCompType(vlistID_dummy, varID_dummy)
+	end function vlistInqVarCompType
+
+	subroutine vlistDefVarCompLevel(vlistID_dummy, varID_dummy, complevel_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: complevel_dummy
+		interface
+			subroutine lib_vlistDefVarCompLevel(vlistID_dummy, varID_dummy, complevel_dummy) bind(c, name = 'vlistDefVarCompLevel')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: complevel_dummy
+			end subroutine lib_vlistDefVarCompLevel
+		end interface
+		call lib_vlistDefVarCompLevel(vlistID_dummy, varID_dummy, complevel_dummy)
+	end subroutine vlistDefVarCompLevel
+
+	function vlistInqVarCompLevel(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarCompLevel(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarCompLevel')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarCompLevel
+		end interface
+		result = lib_vlistInqVarCompLevel(vlistID_dummy, varID_dummy)
+	end function vlistInqVarCompLevel
+
+	subroutine vlistDefVarParam(vlistID_dummy, varID_dummy, param_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: param_dummy
+		interface
+			subroutine lib_vlistDefVarParam(vlistID_dummy, varID_dummy, param_dummy) bind(c, name = 'vlistDefVarParam')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: param_dummy
+			end subroutine lib_vlistDefVarParam
+		end interface
+		call lib_vlistDefVarParam(vlistID_dummy, varID_dummy, param_dummy)
+	end subroutine vlistDefVarParam
+
+	function vlistInqVarParam(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarParam(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarParam')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarParam
+		end interface
+		result = lib_vlistInqVarParam(vlistID_dummy, varID_dummy)
+	end function vlistInqVarParam
+
+	subroutine vlistDefVarCode(vlistID_dummy, varID_dummy, code_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: code_dummy
+		interface
+			subroutine lib_vlistDefVarCode(vlistID_dummy, varID_dummy, code_dummy) bind(c, name = 'vlistDefVarCode')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: code_dummy
+			end subroutine lib_vlistDefVarCode
+		end interface
+		call lib_vlistDefVarCode(vlistID_dummy, varID_dummy, code_dummy)
+	end subroutine vlistDefVarCode
+
+	function vlistInqVarCode(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarCode(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarCode')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarCode
+		end interface
+		result = lib_vlistInqVarCode(vlistID_dummy, varID_dummy)
+	end function vlistInqVarCode
+
+	subroutine vlistDefVarDatatype(vlistID_dummy, varID_dummy, datatype_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: datatype_dummy
+		interface
+			subroutine lib_vlistDefVarDatatype(vlistID_dummy, varID_dummy, datatype_dummy) bind(c, name = 'vlistDefVarDatatype')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: datatype_dummy
+			end subroutine lib_vlistDefVarDatatype
+		end interface
+		call lib_vlistDefVarDatatype(vlistID_dummy, varID_dummy, datatype_dummy)
+	end subroutine vlistDefVarDatatype
+
+	function vlistInqVarDatatype(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarDatatype(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarDatatype')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarDatatype
+		end interface
+		result = lib_vlistInqVarDatatype(vlistID_dummy, varID_dummy)
+	end function vlistInqVarDatatype
+
+	subroutine vlistDefVarChunkType(vlistID_dummy, varID_dummy, chunktype_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: chunktype_dummy
+		interface
+			subroutine lib_vlistDefVarChunkType(vlistID_dummy, varID_dummy, chunktype_dummy) bind(c, name = 'vlistDefVarChunkType')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: chunktype_dummy
+			end subroutine lib_vlistDefVarChunkType
+		end interface
+		call lib_vlistDefVarChunkType(vlistID_dummy, varID_dummy, chunktype_dummy)
+	end subroutine vlistDefVarChunkType
+
+	function vlistInqVarChunkType(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarChunkType(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarChunkType')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarChunkType
+		end interface
+		result = lib_vlistInqVarChunkType(vlistID_dummy, varID_dummy)
+	end function vlistInqVarChunkType
+
+	subroutine vlistDefVarXYZ(vlistID_dummy, varID_dummy, xyz_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: xyz_dummy
+		interface
+			subroutine lib_vlistDefVarXYZ(vlistID_dummy, varID_dummy, xyz_dummy) bind(c, name = 'vlistDefVarXYZ')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: xyz_dummy
+			end subroutine lib_vlistDefVarXYZ
+		end interface
+		call lib_vlistDefVarXYZ(vlistID_dummy, varID_dummy, xyz_dummy)
+	end subroutine vlistDefVarXYZ
+
+	function vlistInqVarXYZ(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarXYZ(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarXYZ')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarXYZ
+		end interface
+		result = lib_vlistInqVarXYZ(vlistID_dummy, varID_dummy)
+	end function vlistInqVarXYZ
+
+	function vlistInqVarNumber(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarNumber(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarNumber')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarNumber
+		end interface
+		result = lib_vlistInqVarNumber(vlistID_dummy, varID_dummy)
+	end function vlistInqVarNumber
+
+	subroutine vlistDefVarInstitut(vlistID_dummy, varID_dummy, instID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: instID_dummy
+		interface
+			subroutine lib_vlistDefVarInstitut(vlistID_dummy, varID_dummy, instID_dummy) bind(c, name = 'vlistDefVarInstitut')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: instID_dummy
+			end subroutine lib_vlistDefVarInstitut
+		end interface
+		call lib_vlistDefVarInstitut(vlistID_dummy, varID_dummy, instID_dummy)
+	end subroutine vlistDefVarInstitut
+
+	function vlistInqVarInstitut(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarInstitut(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarInstitut')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarInstitut
+		end interface
+		result = lib_vlistInqVarInstitut(vlistID_dummy, varID_dummy)
+	end function vlistInqVarInstitut
+
+	subroutine vlistDefVarModel(vlistID_dummy, varID_dummy, modelID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: modelID_dummy
+		interface
+			subroutine lib_vlistDefVarModel(vlistID_dummy, varID_dummy, modelID_dummy) bind(c, name = 'vlistDefVarModel')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: modelID_dummy
+			end subroutine lib_vlistDefVarModel
+		end interface
+		call lib_vlistDefVarModel(vlistID_dummy, varID_dummy, modelID_dummy)
+	end subroutine vlistDefVarModel
+
+	function vlistInqVarModel(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarModel(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarModel')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarModel
+		end interface
+		result = lib_vlistInqVarModel(vlistID_dummy, varID_dummy)
+	end function vlistInqVarModel
+
+	subroutine vlistDefVarTable(vlistID_dummy, varID_dummy, tableID_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: tableID_dummy
+		interface
+			subroutine lib_vlistDefVarTable(vlistID_dummy, varID_dummy, tableID_dummy) bind(c, name = 'vlistDefVarTable')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: tableID_dummy
+			end subroutine lib_vlistDefVarTable
+		end interface
+		call lib_vlistDefVarTable(vlistID_dummy, varID_dummy, tableID_dummy)
+	end subroutine vlistDefVarTable
+
+	function vlistInqVarTable(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarTable(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarTable')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarTable
+		end interface
+		result = lib_vlistInqVarTable(vlistID_dummy, varID_dummy)
+	end function vlistInqVarTable
+
+	subroutine vlistDefVarName(vlistID_dummy, varID_dummy, name_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		interface
+			subroutine lib_vlistDefVarName(vlistID_dummy, varID_dummy, name_dummy) bind(c, name = 'vlistDefVarName')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+			end subroutine lib_vlistDefVarName
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		call lib_vlistDefVarName(vlistID_dummy, varID_dummy, name_temp)
+	end subroutine vlistDefVarName
+
+	subroutine vlistInqVarName(vlistID_dummy, varID_dummy, name_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(inout) :: name_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy))
+		integer :: name_i
+		logical :: name_padding = .true.
+		interface
+			subroutine lib_vlistInqVarName(vlistID_dummy, varID_dummy, name_dummy) bind(c, name = 'vlistInqVarName')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+			end subroutine lib_vlistInqVarName
+		end interface
+		do name_i = len(name_dummy), 1, -1
+			if(name_dummy(name_i:name_i) /= ' ') name_padding = .false.
+			if(name_padding) then
+				name_temp(name_i) = c_null_char
+			else
+				name_temp(name_i) = name_dummy(name_i:name_i)
+			end if
+		end do
+		call lib_vlistInqVarName(vlistID_dummy, varID_dummy, name_temp)
+		name_padding = .false.
+		do name_i = 1, len(name_dummy)
+			if(name_temp(name_i) == c_null_char) name_padding = .true.
+			if(name_padding) then
+				name_dummy(name_i:name_i) = ' '
+			else
+				name_dummy(name_i:name_i) = name_temp(name_i)
+			end if
+		end do
+	end subroutine vlistInqVarName
+
+	function vlistCopyVarName(vlistId_dummy, varId_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		integer(c_int), value :: vlistId_dummy
+		integer(c_int), value :: varId_dummy
+		type(c_ptr) :: cString
+		integer :: shape(1)
+		character(kind = c_char), dimension(:), pointer :: temp
+		interface
+			type(c_ptr) function lib_vlistCopyVarName(vlistId_dummy, varId_dummy) bind(c, name = 'vlistCopyVarName')
+				import c_int, c_ptr
+				integer(c_int), value :: vlistId_dummy
+				integer(c_int), value :: varId_dummy
+			end function lib_vlistCopyVarName
+		end interface
+		cString = lib_vlistCopyVarName(vlistId_dummy, varId_dummy)
+		if(c_associated(cString)) then
+			shape(1) = int(lib_strlen(cString))
+			call c_f_pointer(cString, temp, shape)
+			allocate(result(shape(1)))
+			result = temp
+			call lib_free(cString)
+		else
+			result => null()
+		end if
+	end function vlistCopyVarName
+
+	subroutine vlistDefVarStdname(vlistID_dummy, varID_dummy, stdname_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: stdname_dummy
+		character(kind = c_char) :: stdname_temp(len(stdname_dummy) + 1)
+		integer :: stdname_i
+		interface
+			subroutine lib_vlistDefVarStdname(vlistID_dummy, varID_dummy, stdname_dummy) bind(c, name = 'vlistDefVarStdname')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: stdname_dummy(*)
+			end subroutine lib_vlistDefVarStdname
+		end interface
+		do stdname_i = 1, len(stdname_dummy)
+		stdname_temp(stdname_i) = stdname_dummy(stdname_i:stdname_i)
+		end do
+		stdname_temp(len(stdname_dummy) + 1) = c_null_char
+		call lib_vlistDefVarStdname(vlistID_dummy, varID_dummy, stdname_temp)
+	end subroutine vlistDefVarStdname
+
+	subroutine vlistInqVarStdname(vlistID_dummy, varID_dummy, stdname_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(inout) :: stdname_dummy
+		character(kind = c_char) :: stdname_temp(len(stdname_dummy))
+		integer :: stdname_i
+		logical :: stdname_padding = .true.
+		interface
+			subroutine lib_vlistInqVarStdname(vlistID_dummy, varID_dummy, stdname_dummy) bind(c, name = 'vlistInqVarStdname')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: stdname_dummy(*)
+			end subroutine lib_vlistInqVarStdname
+		end interface
+		do stdname_i = len(stdname_dummy), 1, -1
+			if(stdname_dummy(stdname_i:stdname_i) /= ' ') stdname_padding = .false.
+			if(stdname_padding) then
+				stdname_temp(stdname_i) = c_null_char
+			else
+				stdname_temp(stdname_i) = stdname_dummy(stdname_i:stdname_i)
+			end if
+		end do
+		call lib_vlistInqVarStdname(vlistID_dummy, varID_dummy, stdname_temp)
+		stdname_padding = .false.
+		do stdname_i = 1, len(stdname_dummy)
+			if(stdname_temp(stdname_i) == c_null_char) stdname_padding = .true.
+			if(stdname_padding) then
+				stdname_dummy(stdname_i:stdname_i) = ' '
+			else
+				stdname_dummy(stdname_i:stdname_i) = stdname_temp(stdname_i)
+			end if
+		end do
+	end subroutine vlistInqVarStdname
+
+	subroutine vlistDefVarLongname(vlistID_dummy, varID_dummy, longname_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: longname_dummy
+		character(kind = c_char) :: longname_temp(len(longname_dummy) + 1)
+		integer :: longname_i
+		interface
+			subroutine lib_vlistDefVarLongname(vlistID_dummy, varID_dummy, longname_dummy) bind(c, name = 'vlistDefVarLongname')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: longname_dummy(*)
+			end subroutine lib_vlistDefVarLongname
+		end interface
+		do longname_i = 1, len(longname_dummy)
+		longname_temp(longname_i) = longname_dummy(longname_i:longname_i)
+		end do
+		longname_temp(len(longname_dummy) + 1) = c_null_char
+		call lib_vlistDefVarLongname(vlistID_dummy, varID_dummy, longname_temp)
+	end subroutine vlistDefVarLongname
+
+	subroutine vlistInqVarLongname(vlistID_dummy, varID_dummy, longname_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(inout) :: longname_dummy
+		character(kind = c_char) :: longname_temp(len(longname_dummy))
+		integer :: longname_i
+		logical :: longname_padding = .true.
+		interface
+			subroutine lib_vlistInqVarLongname(vlistID_dummy, varID_dummy, longname_dummy) bind(c, name = 'vlistInqVarLongname')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: longname_dummy(*)
+			end subroutine lib_vlistInqVarLongname
+		end interface
+		do longname_i = len(longname_dummy), 1, -1
+			if(longname_dummy(longname_i:longname_i) /= ' ') longname_padding = .false.
+			if(longname_padding) then
+				longname_temp(longname_i) = c_null_char
+			else
+				longname_temp(longname_i) = longname_dummy(longname_i:longname_i)
+			end if
+		end do
+		call lib_vlistInqVarLongname(vlistID_dummy, varID_dummy, longname_temp)
+		longname_padding = .false.
+		do longname_i = 1, len(longname_dummy)
+			if(longname_temp(longname_i) == c_null_char) longname_padding = .true.
+			if(longname_padding) then
+				longname_dummy(longname_i:longname_i) = ' '
+			else
+				longname_dummy(longname_i:longname_i) = longname_temp(longname_i)
+			end if
+		end do
+	end subroutine vlistInqVarLongname
+
+	subroutine vlistDefVarUnits(vlistID_dummy, varID_dummy, units_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: units_dummy
+		character(kind = c_char) :: units_temp(len(units_dummy) + 1)
+		integer :: units_i
+		interface
+			subroutine lib_vlistDefVarUnits(vlistID_dummy, varID_dummy, units_dummy) bind(c, name = 'vlistDefVarUnits')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: units_dummy(*)
+			end subroutine lib_vlistDefVarUnits
+		end interface
+		do units_i = 1, len(units_dummy)
+		units_temp(units_i) = units_dummy(units_i:units_i)
+		end do
+		units_temp(len(units_dummy) + 1) = c_null_char
+		call lib_vlistDefVarUnits(vlistID_dummy, varID_dummy, units_temp)
+	end subroutine vlistDefVarUnits
+
+	subroutine vlistInqVarUnits(vlistID_dummy, varID_dummy, units_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(inout) :: units_dummy
+		character(kind = c_char) :: units_temp(len(units_dummy))
+		integer :: units_i
+		logical :: units_padding = .true.
+		interface
+			subroutine lib_vlistInqVarUnits(vlistID_dummy, varID_dummy, units_dummy) bind(c, name = 'vlistInqVarUnits')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: units_dummy(*)
+			end subroutine lib_vlistInqVarUnits
+		end interface
+		do units_i = len(units_dummy), 1, -1
+			if(units_dummy(units_i:units_i) /= ' ') units_padding = .false.
+			if(units_padding) then
+				units_temp(units_i) = c_null_char
+			else
+				units_temp(units_i) = units_dummy(units_i:units_i)
+			end if
+		end do
+		call lib_vlistInqVarUnits(vlistID_dummy, varID_dummy, units_temp)
+		units_padding = .false.
+		do units_i = 1, len(units_dummy)
+			if(units_temp(units_i) == c_null_char) units_padding = .true.
+			if(units_padding) then
+				units_dummy(units_i:units_i) = ' '
+			else
+				units_dummy(units_i:units_i) = units_temp(units_i)
+			end if
+		end do
+	end subroutine vlistInqVarUnits
+
+	subroutine vlistDefVarMissval(vlistID_dummy, varID_dummy, missval_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		real(c_double), value :: missval_dummy
+		interface
+			subroutine lib_vlistDefVarMissval(vlistID_dummy, varID_dummy, missval_dummy) bind(c, name = 'vlistDefVarMissval')
+				import c_double, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				real(c_double), value :: missval_dummy
+			end subroutine lib_vlistDefVarMissval
+		end interface
+		call lib_vlistDefVarMissval(vlistID_dummy, varID_dummy, missval_dummy)
+	end subroutine vlistDefVarMissval
+
+	function vlistInqVarMissval(vlistID_dummy, varID_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			real(c_double) function lib_vlistInqVarMissval(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarMissval')
+				import c_double, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarMissval
+		end interface
+		result = lib_vlistInqVarMissval(vlistID_dummy, varID_dummy)
+	end function vlistInqVarMissval
+
+	subroutine vlistDefVarExtra(vlistID_dummy, varID_dummy, extra_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: extra_dummy
+		character(kind = c_char) :: extra_temp(len(extra_dummy) + 1)
+		integer :: extra_i
+		interface
+			subroutine lib_vlistDefVarExtra(vlistID_dummy, varID_dummy, extra_dummy) bind(c, name = 'vlistDefVarExtra')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: extra_dummy(*)
+			end subroutine lib_vlistDefVarExtra
+		end interface
+		do extra_i = 1, len(extra_dummy)
+		extra_temp(extra_i) = extra_dummy(extra_i:extra_i)
+		end do
+		extra_temp(len(extra_dummy) + 1) = c_null_char
+		call lib_vlistDefVarExtra(vlistID_dummy, varID_dummy, extra_temp)
+	end subroutine vlistDefVarExtra
+
+	subroutine vlistInqVarExtra(vlistID_dummy, varID_dummy, extra_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(inout) :: extra_dummy
+		character(kind = c_char) :: extra_temp(len(extra_dummy))
+		integer :: extra_i
+		logical :: extra_padding = .true.
+		interface
+			subroutine lib_vlistInqVarExtra(vlistID_dummy, varID_dummy, extra_dummy) bind(c, name = 'vlistInqVarExtra')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: extra_dummy(*)
+			end subroutine lib_vlistInqVarExtra
+		end interface
+		do extra_i = len(extra_dummy), 1, -1
+			if(extra_dummy(extra_i:extra_i) /= ' ') extra_padding = .false.
+			if(extra_padding) then
+				extra_temp(extra_i) = c_null_char
+			else
+				extra_temp(extra_i) = extra_dummy(extra_i:extra_i)
+			end if
+		end do
+		call lib_vlistInqVarExtra(vlistID_dummy, varID_dummy, extra_temp)
+		extra_padding = .false.
+		do extra_i = 1, len(extra_dummy)
+			if(extra_temp(extra_i) == c_null_char) extra_padding = .true.
+			if(extra_padding) then
+				extra_dummy(extra_i:extra_i) = ' '
+			else
+				extra_dummy(extra_i:extra_i) = extra_temp(extra_i)
+			end if
+		end do
+	end subroutine vlistInqVarExtra
+
+	subroutine vlistDefVarScalefactor(vlistID_dummy, varID_dummy, scalefactor_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		real(c_double), value :: scalefactor_dummy
+		interface
+			subroutine lib_vlistDefVarScalefactor(vlistID_dummy, varID_dummy, scalefactor_dummy) bind(c, name = 'vlistDefVarScalefactor')
+				import c_double, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				real(c_double), value :: scalefactor_dummy
+			end subroutine lib_vlistDefVarScalefactor
+		end interface
+		call lib_vlistDefVarScalefactor(vlistID_dummy, varID_dummy, scalefactor_dummy)
+	end subroutine vlistDefVarScalefactor
+
+	function vlistInqVarScalefactor(vlistID_dummy, varID_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			real(c_double) function lib_vlistInqVarScalefactor(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarScalefactor')
+				import c_double, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarScalefactor
+		end interface
+		result = lib_vlistInqVarScalefactor(vlistID_dummy, varID_dummy)
+	end function vlistInqVarScalefactor
+
+	subroutine vlistDefVarAddoffset(vlistID_dummy, varID_dummy, addoffset_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		real(c_double), value :: addoffset_dummy
+		interface
+			subroutine lib_vlistDefVarAddoffset(vlistID_dummy, varID_dummy, addoffset_dummy) bind(c, name = 'vlistDefVarAddoffset')
+				import c_double, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				real(c_double), value :: addoffset_dummy
+			end subroutine lib_vlistDefVarAddoffset
+		end interface
+		call lib_vlistDefVarAddoffset(vlistID_dummy, varID_dummy, addoffset_dummy)
+	end subroutine vlistDefVarAddoffset
+
+	function vlistInqVarAddoffset(vlistID_dummy, varID_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			real(c_double) function lib_vlistInqVarAddoffset(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarAddoffset')
+				import c_double, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarAddoffset
+		end interface
+		result = lib_vlistInqVarAddoffset(vlistID_dummy, varID_dummy)
+	end function vlistInqVarAddoffset
+
+	subroutine vlistDefVarTimave(vlistID_dummy, varID_dummy, timave_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: timave_dummy
+		interface
+			subroutine lib_vlistDefVarTimave(vlistID_dummy, varID_dummy, timave_dummy) bind(c, name = 'vlistDefVarTimave')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: timave_dummy
+			end subroutine lib_vlistDefVarTimave
+		end interface
+		call lib_vlistDefVarTimave(vlistID_dummy, varID_dummy, timave_dummy)
+	end subroutine vlistDefVarTimave
+
+	function vlistInqVarTimave(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarTimave(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarTimave')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarTimave
+		end interface
+		result = lib_vlistInqVarTimave(vlistID_dummy, varID_dummy)
+	end function vlistInqVarTimave
+
+	subroutine vlistDefVarTimaccu(vlistID_dummy, varID_dummy, timaccu_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: timaccu_dummy
+		interface
+			subroutine lib_vlistDefVarTimaccu(vlistID_dummy, varID_dummy, timaccu_dummy) bind(c, name = 'vlistDefVarTimaccu')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: timaccu_dummy
+			end subroutine lib_vlistDefVarTimaccu
+		end interface
+		call lib_vlistDefVarTimaccu(vlistID_dummy, varID_dummy, timaccu_dummy)
+	end subroutine vlistDefVarTimaccu
+
+	function vlistInqVarTimaccu(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarTimaccu(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarTimaccu')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarTimaccu
+		end interface
+		result = lib_vlistInqVarTimaccu(vlistID_dummy, varID_dummy)
+	end function vlistInqVarTimaccu
+
+	subroutine vlistDefVarTypeOfGeneratingProcess(vlistID_dummy, varID_dummy, typeOfGeneratingProcess_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: typeOfGeneratingProcess_dummy
+		interface
+			subroutine lib_vlistDefVarTypeOfGeneratingProcess(vlistID_dummy, varID_dummy, typeOfGeneratingProcess_dummy) bind(c, name = 'vli&
+			&stDefVarTypeOfGeneratingProcess')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: typeOfGeneratingProcess_dummy
+			end subroutine lib_vlistDefVarTypeOfGeneratingProcess
+		end interface
+		call lib_vlistDefVarTypeOfGeneratingProcess(vlistID_dummy, varID_dummy, typeOfGeneratingProcess_dummy)
+	end subroutine vlistDefVarTypeOfGeneratingProcess
+
+	function vlistInqVarTypeOfGeneratingProcess(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarTypeOfGeneratingProcess(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarTypeOfGene&
+			&ratingProcess')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarTypeOfGeneratingProcess
+		end interface
+		result = lib_vlistInqVarTypeOfGeneratingProcess(vlistID_dummy, varID_dummy)
+	end function vlistInqVarTypeOfGeneratingProcess
+
+	subroutine vlistDefVarProductDefinitionTemplate(vlistID_dummy, varID_dummy, productDefinitionTemplate_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: productDefinitionTemplate_dummy
+		interface
+			subroutine lib_vlistDefVarProductDefinitionTemplate(vlistID_dummy, varID_dummy, productDefinitionTemplate_dummy) bind(c, name = &
+			&'vlistDefVarProductDefinitionTemplate')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: productDefinitionTemplate_dummy
+			end subroutine lib_vlistDefVarProductDefinitionTemplate
+		end interface
+		call lib_vlistDefVarProductDefinitionTemplate(vlistID_dummy, varID_dummy, productDefinitionTemplate_dummy)
+	end subroutine vlistDefVarProductDefinitionTemplate
+
+	function vlistInqVarProductDefinitionTemplate(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarProductDefinitionTemplate(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarProductD&
+			&efinitionTemplate')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarProductDefinitionTemplate
+		end interface
+		result = lib_vlistInqVarProductDefinitionTemplate(vlistID_dummy, varID_dummy)
+	end function vlistInqVarProductDefinitionTemplate
+
+	function vlistInqVarSize(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistInqVarSize(vlistID_dummy, varID_dummy) bind(c, name = 'vlistInqVarSize')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistInqVarSize
+		end interface
+		result = lib_vlistInqVarSize(vlistID_dummy, varID_dummy)
+	end function vlistInqVarSize
+
+	subroutine vlistDefIndex(vlistID_dummy, varID_dummy, levID_dummy, index_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: levID_dummy
+		integer(c_int), value :: index_dummy
+		interface
+			subroutine lib_vlistDefIndex(vlistID_dummy, varID_dummy, levID_dummy, index_dummy) bind(c, name = 'vlistDefIndex')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: levID_dummy
+				integer(c_int), value :: index_dummy
+			end subroutine lib_vlistDefIndex
+		end interface
+		call lib_vlistDefIndex(vlistID_dummy, varID_dummy, levID_dummy, index_dummy)
+	end subroutine vlistDefIndex
+
+	function vlistInqIndex(vlistID_dummy, varID_dummy, levID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: levID_dummy
+		interface
+			integer(c_int) function lib_vlistInqIndex(vlistID_dummy, varID_dummy, levID_dummy) bind(c, name = 'vlistInqIndex')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: levID_dummy
+			end function lib_vlistInqIndex
+		end interface
+		result = lib_vlistInqIndex(vlistID_dummy, varID_dummy, levID_dummy)
+	end function vlistInqIndex
+
+	subroutine vlistDefFlag(vlistID_dummy, varID_dummy, levID_dummy, flag_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: levID_dummy
+		integer(c_int), value :: flag_dummy
+		interface
+			subroutine lib_vlistDefFlag(vlistID_dummy, varID_dummy, levID_dummy, flag_dummy) bind(c, name = 'vlistDefFlag')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: levID_dummy
+				integer(c_int), value :: flag_dummy
+			end subroutine lib_vlistDefFlag
+		end interface
+		call lib_vlistDefFlag(vlistID_dummy, varID_dummy, levID_dummy, flag_dummy)
+	end subroutine vlistDefFlag
+
+	function vlistInqFlag(vlistID_dummy, varID_dummy, levID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: levID_dummy
+		interface
+			integer(c_int) function lib_vlistInqFlag(vlistID_dummy, varID_dummy, levID_dummy) bind(c, name = 'vlistInqFlag')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: levID_dummy
+			end function lib_vlistInqFlag
+		end interface
+		result = lib_vlistInqFlag(vlistID_dummy, varID_dummy, levID_dummy)
+	end function vlistInqFlag
+
+	function vlistFindVar(vlistID_dummy, fvarID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: fvarID_dummy
+		interface
+			integer(c_int) function lib_vlistFindVar(vlistID_dummy, fvarID_dummy) bind(c, name = 'vlistFindVar')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: fvarID_dummy
+			end function lib_vlistFindVar
+		end interface
+		result = lib_vlistFindVar(vlistID_dummy, fvarID_dummy)
+	end function vlistFindVar
+
+	function vlistFindLevel(vlistID_dummy, fvarID_dummy, flevelID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: fvarID_dummy
+		integer(c_int), value :: flevelID_dummy
+		interface
+			integer(c_int) function lib_vlistFindLevel(vlistID_dummy, fvarID_dummy, flevelID_dummy) bind(c, name = 'vlistFindLevel')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: fvarID_dummy
+				integer(c_int), value :: flevelID_dummy
+			end function lib_vlistFindLevel
+		end interface
+		result = lib_vlistFindLevel(vlistID_dummy, fvarID_dummy, flevelID_dummy)
+	end function vlistFindLevel
+
+	function vlistMergedVar(vlistID_dummy, varID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		interface
+			integer(c_int) function lib_vlistMergedVar(vlistID_dummy, varID_dummy) bind(c, name = 'vlistMergedVar')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+			end function lib_vlistMergedVar
+		end interface
+		result = lib_vlistMergedVar(vlistID_dummy, varID_dummy)
+	end function vlistMergedVar
+
+	function vlistMergedLevel(vlistID_dummy, varID_dummy, levelID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: levelID_dummy
+		interface
+			integer(c_int) function lib_vlistMergedLevel(vlistID_dummy, varID_dummy, levelID_dummy) bind(c, name = 'vlistMergedLevel')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: levelID_dummy
+			end function lib_vlistMergedLevel
+		end interface
+		result = lib_vlistMergedLevel(vlistID_dummy, varID_dummy, levelID_dummy)
+	end function vlistMergedLevel
+
+	subroutine vlistDefVarEnsemble(vlistID_dummy, varID_dummy, ensID_dummy, ensCount_dummy, forecast_type_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: ensID_dummy
+		integer(c_int), value :: ensCount_dummy
+		integer(c_int), value :: forecast_type_dummy
+		interface
+			subroutine lib_vlistDefVarEnsemble(vlistID_dummy, varID_dummy, ensID_dummy, ensCount_dummy, forecast_type_dummy) bind(c, name = &
+			&'vlistDefVarEnsemble')
+				import c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: ensID_dummy
+				integer(c_int), value :: ensCount_dummy
+				integer(c_int), value :: forecast_type_dummy
+			end subroutine lib_vlistDefVarEnsemble
+		end interface
+		call lib_vlistDefVarEnsemble(vlistID_dummy, varID_dummy, ensID_dummy, ensCount_dummy, forecast_type_dummy)
+	end subroutine vlistDefVarEnsemble
+
+	function vlistInqVarEnsemble(vlistID_dummy, varID_dummy, ensID, ensCount, forecast_type) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), optional, intent(inout) :: ensID
+		integer(c_int), optional, intent(inout) :: ensCount
+		integer(c_int), optional, intent(inout) :: forecast_type
+		integer(c_int), target :: ensID_temp
+		type(c_ptr) :: ensID_ptr
+		integer(c_int), target :: ensCount_temp
+		type(c_ptr) :: ensCount_ptr
+		integer(c_int), target :: forecast_type_temp
+		type(c_ptr) :: forecast_type_ptr
+		interface
+			integer(c_int) function lib_vlistInqVarEnsemble(vlistID_dummy, varID_dummy, ensID, ensCount, forecast_type) bind(c, name = 'vlis&
+			&tInqVarEnsemble')
+				import c_int, c_ptr
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				type(c_ptr), value :: ensID
+				type(c_ptr), value :: ensCount
+				type(c_ptr), value :: forecast_type
+			end function lib_vlistInqVarEnsemble
+		end interface
+		ensID_ptr = c_null_ptr
+		if(present(ensID)) ensID_ptr = c_loc(ensID_temp)
+		ensCount_ptr = c_null_ptr
+		if(present(ensCount)) ensCount_ptr = c_loc(ensCount_temp)
+		forecast_type_ptr = c_null_ptr
+		if(present(forecast_type)) forecast_type_ptr = c_loc(forecast_type_temp)
+		result = lib_vlistInqVarEnsemble(vlistID_dummy, varID_dummy, ensID_ptr, ensCount_ptr, forecast_type_ptr)
+		if(present(ensID)) ensID = ensID_temp
+		if(present(ensCount)) ensCount = ensCount_temp
+		if(present(forecast_type)) forecast_type = forecast_type_temp
+	end function vlistInqVarEnsemble
+
+	subroutine cdiClearAdditionalKeys()
+		interface
+			subroutine lib_cdiClearAdditionalKeys() bind(c, name = 'cdiClearAdditionalKeys')
+			end subroutine lib_cdiClearAdditionalKeys
+		end interface
+		call lib_cdiClearAdditionalKeys()
+	end subroutine cdiClearAdditionalKeys
+
+	subroutine cdiDefAdditionalKey(string_dummy)
+		character(kind = c_char, len = *), intent(in) :: string_dummy
+		character(kind = c_char) :: string_temp(len(string_dummy) + 1)
+		integer :: string_i
+		interface
+			subroutine lib_cdiDefAdditionalKey(string_dummy) bind(c, name = 'cdiDefAdditionalKey')
+				import c_char
+				character(kind = c_char) :: string_dummy(*)
+			end subroutine lib_cdiDefAdditionalKey
+		end interface
+		do string_i = 1, len(string_dummy)
+		string_temp(string_i) = string_dummy(string_i:string_i)
+		end do
+		string_temp(len(string_dummy) + 1) = c_null_char
+		call lib_cdiDefAdditionalKey(string_temp)
+	end subroutine cdiDefAdditionalKey
+
+	subroutine vlistDefVarIntKey(vlistID_dummy, varID_dummy, name_dummy, value_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		integer(c_int), value :: value_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		interface
+			subroutine lib_vlistDefVarIntKey(vlistID_dummy, varID_dummy, name_dummy, value_dummy) bind(c, name = 'vlistDefVarIntKey')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+				integer(c_int), value :: value_dummy
+			end subroutine lib_vlistDefVarIntKey
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		call lib_vlistDefVarIntKey(vlistID_dummy, varID_dummy, name_temp, value_dummy)
+	end subroutine vlistDefVarIntKey
+
+	subroutine vlistDefVarDblKey(vlistID_dummy, varID_dummy, name_dummy, value_dummy)
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		real(c_double), value :: value_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		interface
+			subroutine lib_vlistDefVarDblKey(vlistID_dummy, varID_dummy, name_dummy, value_dummy) bind(c, name = 'vlistDefVarDblKey')
+				import c_char, c_double, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+				real(c_double), value :: value_dummy
+			end subroutine lib_vlistDefVarDblKey
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		call lib_vlistDefVarDblKey(vlistID_dummy, varID_dummy, name_temp, value_dummy)
+	end subroutine vlistDefVarDblKey
+
+	function vlistHasVarKey(vlistID_dummy, varID_dummy, name_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		interface
+			integer(c_int) function lib_vlistHasVarKey(vlistID_dummy, varID_dummy, name_dummy) bind(c, name = 'vlistHasVarKey')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+			end function lib_vlistHasVarKey
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		result = lib_vlistHasVarKey(vlistID_dummy, varID_dummy, name_temp)
+	end function vlistHasVarKey
+
+	function vlistInqVarDblKey(vlistID_dummy, varID_dummy, name_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		interface
+			real(c_double) function lib_vlistInqVarDblKey(vlistID_dummy, varID_dummy, name_dummy) bind(c, name = 'vlistInqVarDblKey')
+				import c_char, c_double, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+			end function lib_vlistInqVarDblKey
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		result = lib_vlistInqVarDblKey(vlistID_dummy, varID_dummy, name_temp)
+	end function vlistInqVarDblKey
+
+	function vlistInqVarIntKey(vlistID_dummy, varID_dummy, name_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		interface
+			integer(c_int) function lib_vlistInqVarIntKey(vlistID_dummy, varID_dummy, name_dummy) bind(c, name = 'vlistInqVarIntKey')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+			end function lib_vlistInqVarIntKey
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		result = lib_vlistInqVarIntKey(vlistID_dummy, varID_dummy, name_temp)
+	end function vlistInqVarIntKey
+
+	function vlistInqNatts(vlistID_dummy, varID_dummy, nattsp) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), optional, intent(inout) :: nattsp
+		integer(c_int), target :: nattsp_temp
+		type(c_ptr) :: nattsp_ptr
+		interface
+			integer(c_int) function lib_vlistInqNatts(vlistID_dummy, varID_dummy, nattsp) bind(c, name = 'vlistInqNatts')
+				import c_int, c_ptr
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				type(c_ptr), value :: nattsp
+			end function lib_vlistInqNatts
+		end interface
+		nattsp_ptr = c_null_ptr
+		if(present(nattsp)) nattsp_ptr = c_loc(nattsp_temp)
+		result = lib_vlistInqNatts(vlistID_dummy, varID_dummy, nattsp_ptr)
+		if(present(nattsp)) nattsp = nattsp_temp
+	end function vlistInqNatts
+
+	function vlistInqAtt(vlistID_dummy, varID_dummy, attrnum_dummy, name_dummy, typep, lenp) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		integer(c_int), value :: attrnum_dummy
+		character(kind = c_char, len = *), intent(inout) :: name_dummy
+		integer(c_int), optional, intent(inout) :: typep
+		integer(c_int), optional, intent(inout) :: lenp
+		character(kind = c_char) :: name_temp(len(name_dummy))
+		integer :: name_i
+		logical :: name_padding = .true.
+		integer(c_int), target :: typep_temp
+		type(c_ptr) :: typep_ptr
+		integer(c_int), target :: lenp_temp
+		type(c_ptr) :: lenp_ptr
+		interface
+			integer(c_int) function lib_vlistInqAtt(vlistID_dummy, varID_dummy, attrnum_dummy, name_dummy, typep, lenp) bind(c, name = 'vlis&
+			&tInqAtt')
+				import c_char, c_int, c_ptr
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				integer(c_int), value :: attrnum_dummy
+				character(kind = c_char) :: name_dummy(*)
+				type(c_ptr), value :: typep
+				type(c_ptr), value :: lenp
+			end function lib_vlistInqAtt
+		end interface
+		do name_i = len(name_dummy), 1, -1
+			if(name_dummy(name_i:name_i) /= ' ') name_padding = .false.
+			if(name_padding) then
+				name_temp(name_i) = c_null_char
+			else
+				name_temp(name_i) = name_dummy(name_i:name_i)
+			end if
+		end do
+		typep_ptr = c_null_ptr
+		if(present(typep)) typep_ptr = c_loc(typep_temp)
+		lenp_ptr = c_null_ptr
+		if(present(lenp)) lenp_ptr = c_loc(lenp_temp)
+		result = lib_vlistInqAtt(vlistID_dummy, varID_dummy, attrnum_dummy, name_temp, typep_ptr, lenp_ptr)
+		name_padding = .false.
+		do name_i = 1, len(name_dummy)
+			if(name_temp(name_i) == c_null_char) name_padding = .true.
+			if(name_padding) then
+				name_dummy(name_i:name_i) = ' '
+			else
+				name_dummy(name_i:name_i) = name_temp(name_i)
+			end if
+		end do
+		if(present(typep)) typep = typep_temp
+		if(present(lenp)) lenp = lenp_temp
+	end function vlistInqAtt
+
+	function vlistDelAtt(vlistID_dummy, varID_dummy, name_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		interface
+			integer(c_int) function lib_vlistDelAtt(vlistID_dummy, varID_dummy, name_dummy) bind(c, name = 'vlistDelAtt')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+			end function lib_vlistDelAtt
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		result = lib_vlistDelAtt(vlistID_dummy, varID_dummy, name_temp)
+	end function vlistDelAtt
+
+	function vlistDefAttInt(vlistID_dummy, varID_dummy, name_dummy, type_dummy, len_dummy, ip_vec_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		integer(c_int), value :: type_dummy
+		integer(c_int), value :: len_dummy
+		integer(c_int), intent(in) :: ip_vec_dummy(*)
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		interface
+			integer(c_int) function lib_vlistDefAttInt(vlistID_dummy, varID_dummy, name_dummy, type_dummy, len_dummy, ip_vec_dummy) bind(c, &
+			&name = 'vlistDefAttInt')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+				integer(c_int), value :: type_dummy
+				integer(c_int), value :: len_dummy
+				integer(c_int), intent(in) :: ip_vec_dummy(*)
+			end function lib_vlistDefAttInt
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		result = lib_vlistDefAttInt(vlistID_dummy, varID_dummy, name_temp, type_dummy, len_dummy, ip_vec_dummy)
+	end function vlistDefAttInt
+
+	function vlistDefAttFlt(vlistID_dummy, varID_dummy, name_dummy, type_dummy, len_dummy, dp_vec_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		integer(c_int), value :: type_dummy
+		integer(c_int), value :: len_dummy
+		real(c_double), intent(in) :: dp_vec_dummy(*)
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		interface
+			integer(c_int) function lib_vlistDefAttFlt(vlistID_dummy, varID_dummy, name_dummy, type_dummy, len_dummy, dp_vec_dummy) bind(c, &
+			&name = 'vlistDefAttFlt')
+				import c_char, c_double, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+				integer(c_int), value :: type_dummy
+				integer(c_int), value :: len_dummy
+				real(c_double), intent(in) :: dp_vec_dummy(*)
+			end function lib_vlistDefAttFlt
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		result = lib_vlistDefAttFlt(vlistID_dummy, varID_dummy, name_temp, type_dummy, len_dummy, dp_vec_dummy)
+	end function vlistDefAttFlt
+
+	function vlistDefAttTxt(vlistID_dummy, varID_dummy, name_dummy, len_dummy, tp_cbuf_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		integer(c_int), value :: len_dummy
+		character(kind = c_char, len = *), intent(in) :: tp_cbuf_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		character(kind = c_char) :: tp_cbuf_temp(len(tp_cbuf_dummy) + 1)
+		integer :: tp_cbuf_i
+		interface
+			integer(c_int) function lib_vlistDefAttTxt(vlistID_dummy, varID_dummy, name_dummy, len_dummy, tp_cbuf_dummy) bind(c, name = 'vli&
+			&stDefAttTxt')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+				integer(c_int), value :: len_dummy
+				character(kind = c_char) :: tp_cbuf_dummy(*)
+			end function lib_vlistDefAttTxt
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		do tp_cbuf_i = 1, len(tp_cbuf_dummy)
+		tp_cbuf_temp(tp_cbuf_i) = tp_cbuf_dummy(tp_cbuf_i:tp_cbuf_i)
+		end do
+		tp_cbuf_temp(len(tp_cbuf_dummy) + 1) = c_null_char
+		result = lib_vlistDefAttTxt(vlistID_dummy, varID_dummy, name_temp, len_dummy, tp_cbuf_temp)
+	end function vlistDefAttTxt
+
+	function vlistInqAttInt(vlistID_dummy, varID_dummy, name_dummy, mlen_dummy, ip_vec_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		integer(c_int), value :: mlen_dummy
+		integer(c_int), intent(inout) :: ip_vec_dummy(*)
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		interface
+			integer(c_int) function lib_vlistInqAttInt(vlistID_dummy, varID_dummy, name_dummy, mlen_dummy, ip_vec_dummy) bind(c, name = 'vli&
+			&stInqAttInt')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+				integer(c_int), value :: mlen_dummy
+				integer(c_int), intent(inout) :: ip_vec_dummy(*)
+			end function lib_vlistInqAttInt
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		result = lib_vlistInqAttInt(vlistID_dummy, varID_dummy, name_temp, mlen_dummy, ip_vec_dummy)
+	end function vlistInqAttInt
+
+	function vlistInqAttFlt(vlistID_dummy, varID_dummy, name_dummy, mlen_dummy, dp_vec_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		integer(c_int), value :: mlen_dummy
+		real(c_double), intent(inout) :: dp_vec_dummy(*)
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		interface
+			integer(c_int) function lib_vlistInqAttFlt(vlistID_dummy, varID_dummy, name_dummy, mlen_dummy, dp_vec_dummy) bind(c, name = 'vli&
+			&stInqAttFlt')
+				import c_char, c_double, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+				integer(c_int), value :: mlen_dummy
+				real(c_double), intent(inout) :: dp_vec_dummy(*)
+			end function lib_vlistInqAttFlt
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		result = lib_vlistInqAttFlt(vlistID_dummy, varID_dummy, name_temp, mlen_dummy, dp_vec_dummy)
+	end function vlistInqAttFlt
+
+	function vlistInqAttTxt(vlistID_dummy, varID_dummy, name_dummy, mlen_dummy, tp_cbuf_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: vlistID_dummy
+		integer(c_int), value :: varID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		integer(c_int), value :: mlen_dummy
+		character(kind = c_char, len = *), intent(inout) :: tp_cbuf_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		character(kind = c_char) :: tp_cbuf_temp(len(tp_cbuf_dummy))
+		integer :: tp_cbuf_i
+		logical :: tp_cbuf_padding = .true.
+		interface
+			integer(c_int) function lib_vlistInqAttTxt(vlistID_dummy, varID_dummy, name_dummy, mlen_dummy, tp_cbuf_dummy) bind(c, name = 'vl&
+			&istInqAttTxt')
+				import c_char, c_int
+				integer(c_int), value :: vlistID_dummy
+				integer(c_int), value :: varID_dummy
+				character(kind = c_char) :: name_dummy(*)
+				integer(c_int), value :: mlen_dummy
+				character(kind = c_char) :: tp_cbuf_dummy(*)
+			end function lib_vlistInqAttTxt
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		do tp_cbuf_i = len(tp_cbuf_dummy), 1, -1
+			if(tp_cbuf_dummy(tp_cbuf_i:tp_cbuf_i) /= ' ') tp_cbuf_padding = .false.
+			if(tp_cbuf_padding) then
+				tp_cbuf_temp(tp_cbuf_i) = c_null_char
+			else
+				tp_cbuf_temp(tp_cbuf_i) = tp_cbuf_dummy(tp_cbuf_i:tp_cbuf_i)
+			end if
+		end do
+		result = lib_vlistInqAttTxt(vlistID_dummy, varID_dummy, name_temp, mlen_dummy, tp_cbuf_temp)
+		tp_cbuf_padding = .false.
+		do tp_cbuf_i = 1, len(tp_cbuf_dummy)
+			if(tp_cbuf_temp(tp_cbuf_i) == c_null_char) tp_cbuf_padding = .true.
+			if(tp_cbuf_padding) then
+				tp_cbuf_dummy(tp_cbuf_i:tp_cbuf_i) = ' '
+			else
+				tp_cbuf_dummy(tp_cbuf_i:tp_cbuf_i) = tp_cbuf_temp(tp_cbuf_i)
+			end if
+		end do
+	end function vlistInqAttTxt
+
+	subroutine gridName(gridtype_dummy, gridname_dummy)
+		integer(c_int), value :: gridtype_dummy
+		character(kind = c_char, len = *), intent(inout) :: gridname_dummy
+		character(kind = c_char) :: gridname_temp(len(gridname_dummy))
+		integer :: gridname_i
+		logical :: gridname_padding = .true.
+		interface
+			subroutine lib_gridName(gridtype_dummy, gridname_dummy) bind(c, name = 'gridName')
+				import c_char, c_int
+				integer(c_int), value :: gridtype_dummy
+				character(kind = c_char) :: gridname_dummy(*)
+			end subroutine lib_gridName
+		end interface
+		do gridname_i = len(gridname_dummy), 1, -1
+			if(gridname_dummy(gridname_i:gridname_i) /= ' ') gridname_padding = .false.
+			if(gridname_padding) then
+				gridname_temp(gridname_i) = c_null_char
+			else
+				gridname_temp(gridname_i) = gridname_dummy(gridname_i:gridname_i)
+			end if
+		end do
+		call lib_gridName(gridtype_dummy, gridname_temp)
+		gridname_padding = .false.
+		do gridname_i = 1, len(gridname_dummy)
+			if(gridname_temp(gridname_i) == c_null_char) gridname_padding = .true.
+			if(gridname_padding) then
+				gridname_dummy(gridname_i:gridname_i) = ' '
+			else
+				gridname_dummy(gridname_i:gridname_i) = gridname_temp(gridname_i)
+			end if
+		end do
+	end subroutine gridName
+
+	function gridNamePtr(gridtype_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		integer(c_int), value :: gridtype_dummy
+		type(c_ptr) :: ptr
+		integer :: shape(1)
+		interface
+			type(c_ptr) function lib_gridNamePtr(gridtype_dummy) bind(c, name = 'gridNamePtr')
+				import c_int, c_ptr
+				integer(c_int), value :: gridtype_dummy
+			end function lib_gridNamePtr
+		end interface
+		result => null()
+		ptr = lib_gridNamePtr(gridtype_dummy)
+		if(c_associated(ptr)) then
+			shape(1) = int(lib_strlen(ptr))
+			call c_f_pointer(ptr, result, shape)
+		end if
+	end function gridNamePtr
+
+	subroutine gridCompress(gridID_dummy)
+		integer(c_int), value :: gridID_dummy
+		interface
+			subroutine lib_gridCompress(gridID_dummy) bind(c, name = 'gridCompress')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end subroutine lib_gridCompress
+		end interface
+		call lib_gridCompress(gridID_dummy)
+	end subroutine gridCompress
+
+	subroutine gridDefMaskGME(gridID_dummy, mask_vec_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), intent(in) :: mask_vec_dummy(*)
+		interface
+			subroutine lib_gridDefMaskGME(gridID_dummy, mask_vec_dummy) bind(c, name = 'gridDefMaskGME')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), intent(in) :: mask_vec_dummy(*)
+			end subroutine lib_gridDefMaskGME
+		end interface
+		call lib_gridDefMaskGME(gridID_dummy, mask_vec_dummy)
+	end subroutine gridDefMaskGME
+
+	function gridInqMaskGME(gridID_dummy, mask_vec_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), intent(inout) :: mask_vec_dummy(*)
+		interface
+			integer(c_int) function lib_gridInqMaskGME(gridID_dummy, mask_vec_dummy) bind(c, name = 'gridInqMaskGME')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), intent(inout) :: mask_vec_dummy(*)
+			end function lib_gridInqMaskGME
+		end interface
+		result = lib_gridInqMaskGME(gridID_dummy, mask_vec_dummy)
+	end function gridInqMaskGME
+
+	subroutine gridDefMask(gridID_dummy, mask_vec_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), intent(in) :: mask_vec_dummy(*)
+		interface
+			subroutine lib_gridDefMask(gridID_dummy, mask_vec_dummy) bind(c, name = 'gridDefMask')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), intent(in) :: mask_vec_dummy(*)
+			end subroutine lib_gridDefMask
+		end interface
+		call lib_gridDefMask(gridID_dummy, mask_vec_dummy)
+	end subroutine gridDefMask
+
+	function gridInqMask(gridID_dummy, mask_vec_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), intent(inout) :: mask_vec_dummy(*)
+		interface
+			integer(c_int) function lib_gridInqMask(gridID_dummy, mask_vec_dummy) bind(c, name = 'gridInqMask')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), intent(inout) :: mask_vec_dummy(*)
+			end function lib_gridInqMask
+		end interface
+		result = lib_gridInqMask(gridID_dummy, mask_vec_dummy)
+	end function gridInqMask
+
+	subroutine gridPrint(gridID_dummy, index_dummy, opt_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: index_dummy
+		integer(c_int), value :: opt_dummy
+		interface
+			subroutine lib_gridPrint(gridID_dummy, index_dummy, opt_dummy) bind(c, name = 'gridPrint')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: index_dummy
+				integer(c_int), value :: opt_dummy
+			end subroutine lib_gridPrint
+		end interface
+		call lib_gridPrint(gridID_dummy, index_dummy, opt_dummy)
+	end subroutine gridPrint
+
+	function gridCreate(gridtype_dummy, size_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridtype_dummy
+		integer(c_int), value :: size_dummy
+		interface
+			integer(c_int) function lib_gridCreate(gridtype_dummy, size_dummy) bind(c, name = 'gridCreate')
+				import c_int
+				integer(c_int), value :: gridtype_dummy
+				integer(c_int), value :: size_dummy
+			end function lib_gridCreate
+		end interface
+		result = lib_gridCreate(gridtype_dummy, size_dummy)
+	end function gridCreate
+
+	subroutine gridDestroy(gridID_dummy)
+		integer(c_int), value :: gridID_dummy
+		interface
+			subroutine lib_gridDestroy(gridID_dummy) bind(c, name = 'gridDestroy')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end subroutine lib_gridDestroy
+		end interface
+		call lib_gridDestroy(gridID_dummy)
+	end subroutine gridDestroy
+
+	function gridDuplicate(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridDuplicate(gridID_dummy) bind(c, name = 'gridDuplicate')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridDuplicate
+		end interface
+		result = lib_gridDuplicate(gridID_dummy)
+	end function gridDuplicate
+
+	function gridInqType(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqType(gridID_dummy) bind(c, name = 'gridInqType')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqType
+		end interface
+		result = lib_gridInqType(gridID_dummy)
+	end function gridInqType
+
+	function gridInqSize(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqSize(gridID_dummy) bind(c, name = 'gridInqSize')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqSize
+		end interface
+		result = lib_gridInqSize(gridID_dummy)
+	end function gridInqSize
+
+	subroutine gridDefXsize(gridID_dummy, xsize_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: xsize_dummy
+		interface
+			subroutine lib_gridDefXsize(gridID_dummy, xsize_dummy) bind(c, name = 'gridDefXsize')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: xsize_dummy
+			end subroutine lib_gridDefXsize
+		end interface
+		call lib_gridDefXsize(gridID_dummy, xsize_dummy)
+	end subroutine gridDefXsize
+
+	function gridInqXsize(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqXsize(gridID_dummy) bind(c, name = 'gridInqXsize')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqXsize
+		end interface
+		result = lib_gridInqXsize(gridID_dummy)
+	end function gridInqXsize
+
+	subroutine gridDefYsize(gridID_dummy, ysize_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: ysize_dummy
+		interface
+			subroutine lib_gridDefYsize(gridID_dummy, ysize_dummy) bind(c, name = 'gridDefYsize')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: ysize_dummy
+			end subroutine lib_gridDefYsize
+		end interface
+		call lib_gridDefYsize(gridID_dummy, ysize_dummy)
+	end subroutine gridDefYsize
+
+	function gridInqYsize(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqYsize(gridID_dummy) bind(c, name = 'gridInqYsize')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqYsize
+		end interface
+		result = lib_gridInqYsize(gridID_dummy)
+	end function gridInqYsize
+
+	subroutine gridDefNP(gridID_dummy, np_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: np_dummy
+		interface
+			subroutine lib_gridDefNP(gridID_dummy, np_dummy) bind(c, name = 'gridDefNP')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: np_dummy
+			end subroutine lib_gridDefNP
+		end interface
+		call lib_gridDefNP(gridID_dummy, np_dummy)
+	end subroutine gridDefNP
+
+	function gridInqNP(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqNP(gridID_dummy) bind(c, name = 'gridInqNP')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqNP
+		end interface
+		result = lib_gridInqNP(gridID_dummy)
+	end function gridInqNP
+
+	subroutine gridDefXvals(gridID_dummy, xvals_vec_dummy)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), intent(in) :: xvals_vec_dummy(*)
+		interface
+			subroutine lib_gridDefXvals(gridID_dummy, xvals_vec_dummy) bind(c, name = 'gridDefXvals')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), intent(in) :: xvals_vec_dummy(*)
+			end subroutine lib_gridDefXvals
+		end interface
+		call lib_gridDefXvals(gridID_dummy, xvals_vec_dummy)
+	end subroutine gridDefXvals
+
+	function gridInqXvals(gridID_dummy, xvals_vec_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		real(c_double), intent(inout) :: xvals_vec_dummy(*)
+		interface
+			integer(c_int) function lib_gridInqXvals(gridID_dummy, xvals_vec_dummy) bind(c, name = 'gridInqXvals')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), intent(inout) :: xvals_vec_dummy(*)
+			end function lib_gridInqXvals
+		end interface
+		result = lib_gridInqXvals(gridID_dummy, xvals_vec_dummy)
+	end function gridInqXvals
+
+	subroutine gridDefYvals(gridID_dummy, yvals_vec_dummy)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), intent(in) :: yvals_vec_dummy(*)
+		interface
+			subroutine lib_gridDefYvals(gridID_dummy, yvals_vec_dummy) bind(c, name = 'gridDefYvals')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), intent(in) :: yvals_vec_dummy(*)
+			end subroutine lib_gridDefYvals
+		end interface
+		call lib_gridDefYvals(gridID_dummy, yvals_vec_dummy)
+	end subroutine gridDefYvals
+
+	function gridInqYvals(gridID_dummy, yvals_vec_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		real(c_double), intent(inout) :: yvals_vec_dummy(*)
+		interface
+			integer(c_int) function lib_gridInqYvals(gridID_dummy, yvals_vec_dummy) bind(c, name = 'gridInqYvals')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), intent(inout) :: yvals_vec_dummy(*)
+			end function lib_gridInqYvals
+		end interface
+		result = lib_gridInqYvals(gridID_dummy, yvals_vec_dummy)
+	end function gridInqYvals
+
+	subroutine gridDefXname(gridID_dummy, xname_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(in) :: xname_dummy
+		character(kind = c_char) :: xname_temp(len(xname_dummy) + 1)
+		integer :: xname_i
+		interface
+			subroutine lib_gridDefXname(gridID_dummy, xname_dummy) bind(c, name = 'gridDefXname')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: xname_dummy(*)
+			end subroutine lib_gridDefXname
+		end interface
+		do xname_i = 1, len(xname_dummy)
+		xname_temp(xname_i) = xname_dummy(xname_i:xname_i)
+		end do
+		xname_temp(len(xname_dummy) + 1) = c_null_char
+		call lib_gridDefXname(gridID_dummy, xname_temp)
+	end subroutine gridDefXname
+
+	subroutine gridInqXname(gridID_dummy, xname_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(inout) :: xname_dummy
+		character(kind = c_char) :: xname_temp(len(xname_dummy))
+		integer :: xname_i
+		logical :: xname_padding = .true.
+		interface
+			subroutine lib_gridInqXname(gridID_dummy, xname_dummy) bind(c, name = 'gridInqXname')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: xname_dummy(*)
+			end subroutine lib_gridInqXname
+		end interface
+		do xname_i = len(xname_dummy), 1, -1
+			if(xname_dummy(xname_i:xname_i) /= ' ') xname_padding = .false.
+			if(xname_padding) then
+				xname_temp(xname_i) = c_null_char
+			else
+				xname_temp(xname_i) = xname_dummy(xname_i:xname_i)
+			end if
+		end do
+		call lib_gridInqXname(gridID_dummy, xname_temp)
+		xname_padding = .false.
+		do xname_i = 1, len(xname_dummy)
+			if(xname_temp(xname_i) == c_null_char) xname_padding = .true.
+			if(xname_padding) then
+				xname_dummy(xname_i:xname_i) = ' '
+			else
+				xname_dummy(xname_i:xname_i) = xname_temp(xname_i)
+			end if
+		end do
+	end subroutine gridInqXname
+
+	subroutine gridDefXlongname(gridID_dummy, xlongname_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(in) :: xlongname_dummy
+		character(kind = c_char) :: xlongname_temp(len(xlongname_dummy) + 1)
+		integer :: xlongname_i
+		interface
+			subroutine lib_gridDefXlongname(gridID_dummy, xlongname_dummy) bind(c, name = 'gridDefXlongname')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: xlongname_dummy(*)
+			end subroutine lib_gridDefXlongname
+		end interface
+		do xlongname_i = 1, len(xlongname_dummy)
+		xlongname_temp(xlongname_i) = xlongname_dummy(xlongname_i:xlongname_i)
+		end do
+		xlongname_temp(len(xlongname_dummy) + 1) = c_null_char
+		call lib_gridDefXlongname(gridID_dummy, xlongname_temp)
+	end subroutine gridDefXlongname
+
+	subroutine gridInqXlongname(gridID_dummy, xlongname_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(inout) :: xlongname_dummy
+		character(kind = c_char) :: xlongname_temp(len(xlongname_dummy))
+		integer :: xlongname_i
+		logical :: xlongname_padding = .true.
+		interface
+			subroutine lib_gridInqXlongname(gridID_dummy, xlongname_dummy) bind(c, name = 'gridInqXlongname')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: xlongname_dummy(*)
+			end subroutine lib_gridInqXlongname
+		end interface
+		do xlongname_i = len(xlongname_dummy), 1, -1
+			if(xlongname_dummy(xlongname_i:xlongname_i) /= ' ') xlongname_padding = .false.
+			if(xlongname_padding) then
+				xlongname_temp(xlongname_i) = c_null_char
+			else
+				xlongname_temp(xlongname_i) = xlongname_dummy(xlongname_i:xlongname_i)
+			end if
+		end do
+		call lib_gridInqXlongname(gridID_dummy, xlongname_temp)
+		xlongname_padding = .false.
+		do xlongname_i = 1, len(xlongname_dummy)
+			if(xlongname_temp(xlongname_i) == c_null_char) xlongname_padding = .true.
+			if(xlongname_padding) then
+				xlongname_dummy(xlongname_i:xlongname_i) = ' '
+			else
+				xlongname_dummy(xlongname_i:xlongname_i) = xlongname_temp(xlongname_i)
+			end if
+		end do
+	end subroutine gridInqXlongname
+
+	subroutine gridDefXunits(gridID_dummy, xunits_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(in) :: xunits_dummy
+		character(kind = c_char) :: xunits_temp(len(xunits_dummy) + 1)
+		integer :: xunits_i
+		interface
+			subroutine lib_gridDefXunits(gridID_dummy, xunits_dummy) bind(c, name = 'gridDefXunits')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: xunits_dummy(*)
+			end subroutine lib_gridDefXunits
+		end interface
+		do xunits_i = 1, len(xunits_dummy)
+		xunits_temp(xunits_i) = xunits_dummy(xunits_i:xunits_i)
+		end do
+		xunits_temp(len(xunits_dummy) + 1) = c_null_char
+		call lib_gridDefXunits(gridID_dummy, xunits_temp)
+	end subroutine gridDefXunits
+
+	subroutine gridInqXunits(gridID_dummy, xunits_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(inout) :: xunits_dummy
+		character(kind = c_char) :: xunits_temp(len(xunits_dummy))
+		integer :: xunits_i
+		logical :: xunits_padding = .true.
+		interface
+			subroutine lib_gridInqXunits(gridID_dummy, xunits_dummy) bind(c, name = 'gridInqXunits')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: xunits_dummy(*)
+			end subroutine lib_gridInqXunits
+		end interface
+		do xunits_i = len(xunits_dummy), 1, -1
+			if(xunits_dummy(xunits_i:xunits_i) /= ' ') xunits_padding = .false.
+			if(xunits_padding) then
+				xunits_temp(xunits_i) = c_null_char
+			else
+				xunits_temp(xunits_i) = xunits_dummy(xunits_i:xunits_i)
+			end if
+		end do
+		call lib_gridInqXunits(gridID_dummy, xunits_temp)
+		xunits_padding = .false.
+		do xunits_i = 1, len(xunits_dummy)
+			if(xunits_temp(xunits_i) == c_null_char) xunits_padding = .true.
+			if(xunits_padding) then
+				xunits_dummy(xunits_i:xunits_i) = ' '
+			else
+				xunits_dummy(xunits_i:xunits_i) = xunits_temp(xunits_i)
+			end if
+		end do
+	end subroutine gridInqXunits
+
+	subroutine gridDefYname(gridID_dummy, yname_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(in) :: yname_dummy
+		character(kind = c_char) :: yname_temp(len(yname_dummy) + 1)
+		integer :: yname_i
+		interface
+			subroutine lib_gridDefYname(gridID_dummy, yname_dummy) bind(c, name = 'gridDefYname')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: yname_dummy(*)
+			end subroutine lib_gridDefYname
+		end interface
+		do yname_i = 1, len(yname_dummy)
+		yname_temp(yname_i) = yname_dummy(yname_i:yname_i)
+		end do
+		yname_temp(len(yname_dummy) + 1) = c_null_char
+		call lib_gridDefYname(gridID_dummy, yname_temp)
+	end subroutine gridDefYname
+
+	subroutine gridInqYname(gridID_dummy, yname_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(inout) :: yname_dummy
+		character(kind = c_char) :: yname_temp(len(yname_dummy))
+		integer :: yname_i
+		logical :: yname_padding = .true.
+		interface
+			subroutine lib_gridInqYname(gridID_dummy, yname_dummy) bind(c, name = 'gridInqYname')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: yname_dummy(*)
+			end subroutine lib_gridInqYname
+		end interface
+		do yname_i = len(yname_dummy), 1, -1
+			if(yname_dummy(yname_i:yname_i) /= ' ') yname_padding = .false.
+			if(yname_padding) then
+				yname_temp(yname_i) = c_null_char
+			else
+				yname_temp(yname_i) = yname_dummy(yname_i:yname_i)
+			end if
+		end do
+		call lib_gridInqYname(gridID_dummy, yname_temp)
+		yname_padding = .false.
+		do yname_i = 1, len(yname_dummy)
+			if(yname_temp(yname_i) == c_null_char) yname_padding = .true.
+			if(yname_padding) then
+				yname_dummy(yname_i:yname_i) = ' '
+			else
+				yname_dummy(yname_i:yname_i) = yname_temp(yname_i)
+			end if
+		end do
+	end subroutine gridInqYname
+
+	subroutine gridDefYlongname(gridID_dummy, ylongname_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(in) :: ylongname_dummy
+		character(kind = c_char) :: ylongname_temp(len(ylongname_dummy) + 1)
+		integer :: ylongname_i
+		interface
+			subroutine lib_gridDefYlongname(gridID_dummy, ylongname_dummy) bind(c, name = 'gridDefYlongname')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: ylongname_dummy(*)
+			end subroutine lib_gridDefYlongname
+		end interface
+		do ylongname_i = 1, len(ylongname_dummy)
+		ylongname_temp(ylongname_i) = ylongname_dummy(ylongname_i:ylongname_i)
+		end do
+		ylongname_temp(len(ylongname_dummy) + 1) = c_null_char
+		call lib_gridDefYlongname(gridID_dummy, ylongname_temp)
+	end subroutine gridDefYlongname
+
+	subroutine gridInqYlongname(gridID_dummy, ylongname_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(inout) :: ylongname_dummy
+		character(kind = c_char) :: ylongname_temp(len(ylongname_dummy))
+		integer :: ylongname_i
+		logical :: ylongname_padding = .true.
+		interface
+			subroutine lib_gridInqYlongname(gridID_dummy, ylongname_dummy) bind(c, name = 'gridInqYlongname')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: ylongname_dummy(*)
+			end subroutine lib_gridInqYlongname
+		end interface
+		do ylongname_i = len(ylongname_dummy), 1, -1
+			if(ylongname_dummy(ylongname_i:ylongname_i) /= ' ') ylongname_padding = .false.
+			if(ylongname_padding) then
+				ylongname_temp(ylongname_i) = c_null_char
+			else
+				ylongname_temp(ylongname_i) = ylongname_dummy(ylongname_i:ylongname_i)
+			end if
+		end do
+		call lib_gridInqYlongname(gridID_dummy, ylongname_temp)
+		ylongname_padding = .false.
+		do ylongname_i = 1, len(ylongname_dummy)
+			if(ylongname_temp(ylongname_i) == c_null_char) ylongname_padding = .true.
+			if(ylongname_padding) then
+				ylongname_dummy(ylongname_i:ylongname_i) = ' '
+			else
+				ylongname_dummy(ylongname_i:ylongname_i) = ylongname_temp(ylongname_i)
+			end if
+		end do
+	end subroutine gridInqYlongname
+
+	subroutine gridDefYunits(gridID_dummy, yunits_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(in) :: yunits_dummy
+		character(kind = c_char) :: yunits_temp(len(yunits_dummy) + 1)
+		integer :: yunits_i
+		interface
+			subroutine lib_gridDefYunits(gridID_dummy, yunits_dummy) bind(c, name = 'gridDefYunits')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: yunits_dummy(*)
+			end subroutine lib_gridDefYunits
+		end interface
+		do yunits_i = 1, len(yunits_dummy)
+		yunits_temp(yunits_i) = yunits_dummy(yunits_i:yunits_i)
+		end do
+		yunits_temp(len(yunits_dummy) + 1) = c_null_char
+		call lib_gridDefYunits(gridID_dummy, yunits_temp)
+	end subroutine gridDefYunits
+
+	subroutine gridInqYunits(gridID_dummy, yunits_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(inout) :: yunits_dummy
+		character(kind = c_char) :: yunits_temp(len(yunits_dummy))
+		integer :: yunits_i
+		logical :: yunits_padding = .true.
+		interface
+			subroutine lib_gridInqYunits(gridID_dummy, yunits_dummy) bind(c, name = 'gridInqYunits')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: yunits_dummy(*)
+			end subroutine lib_gridInqYunits
+		end interface
+		do yunits_i = len(yunits_dummy), 1, -1
+			if(yunits_dummy(yunits_i:yunits_i) /= ' ') yunits_padding = .false.
+			if(yunits_padding) then
+				yunits_temp(yunits_i) = c_null_char
+			else
+				yunits_temp(yunits_i) = yunits_dummy(yunits_i:yunits_i)
+			end if
+		end do
+		call lib_gridInqYunits(gridID_dummy, yunits_temp)
+		yunits_padding = .false.
+		do yunits_i = 1, len(yunits_dummy)
+			if(yunits_temp(yunits_i) == c_null_char) yunits_padding = .true.
+			if(yunits_padding) then
+				yunits_dummy(yunits_i:yunits_i) = ' '
+			else
+				yunits_dummy(yunits_i:yunits_i) = yunits_temp(yunits_i)
+			end if
+		end do
+	end subroutine gridInqYunits
+
+	subroutine gridInqXstdname(gridID_dummy, xstdname_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(inout) :: xstdname_dummy
+		character(kind = c_char) :: xstdname_temp(len(xstdname_dummy))
+		integer :: xstdname_i
+		logical :: xstdname_padding = .true.
+		interface
+			subroutine lib_gridInqXstdname(gridID_dummy, xstdname_dummy) bind(c, name = 'gridInqXstdname')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: xstdname_dummy(*)
+			end subroutine lib_gridInqXstdname
+		end interface
+		do xstdname_i = len(xstdname_dummy), 1, -1
+			if(xstdname_dummy(xstdname_i:xstdname_i) /= ' ') xstdname_padding = .false.
+			if(xstdname_padding) then
+				xstdname_temp(xstdname_i) = c_null_char
+			else
+				xstdname_temp(xstdname_i) = xstdname_dummy(xstdname_i:xstdname_i)
+			end if
+		end do
+		call lib_gridInqXstdname(gridID_dummy, xstdname_temp)
+		xstdname_padding = .false.
+		do xstdname_i = 1, len(xstdname_dummy)
+			if(xstdname_temp(xstdname_i) == c_null_char) xstdname_padding = .true.
+			if(xstdname_padding) then
+				xstdname_dummy(xstdname_i:xstdname_i) = ' '
+			else
+				xstdname_dummy(xstdname_i:xstdname_i) = xstdname_temp(xstdname_i)
+			end if
+		end do
+	end subroutine gridInqXstdname
+
+	subroutine gridInqYstdname(gridID_dummy, ystdname_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(inout) :: ystdname_dummy
+		character(kind = c_char) :: ystdname_temp(len(ystdname_dummy))
+		integer :: ystdname_i
+		logical :: ystdname_padding = .true.
+		interface
+			subroutine lib_gridInqYstdname(gridID_dummy, ystdname_dummy) bind(c, name = 'gridInqYstdname')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: ystdname_dummy(*)
+			end subroutine lib_gridInqYstdname
+		end interface
+		do ystdname_i = len(ystdname_dummy), 1, -1
+			if(ystdname_dummy(ystdname_i:ystdname_i) /= ' ') ystdname_padding = .false.
+			if(ystdname_padding) then
+				ystdname_temp(ystdname_i) = c_null_char
+			else
+				ystdname_temp(ystdname_i) = ystdname_dummy(ystdname_i:ystdname_i)
+			end if
+		end do
+		call lib_gridInqYstdname(gridID_dummy, ystdname_temp)
+		ystdname_padding = .false.
+		do ystdname_i = 1, len(ystdname_dummy)
+			if(ystdname_temp(ystdname_i) == c_null_char) ystdname_padding = .true.
+			if(ystdname_padding) then
+				ystdname_dummy(ystdname_i:ystdname_i) = ' '
+			else
+				ystdname_dummy(ystdname_i:ystdname_i) = ystdname_temp(ystdname_i)
+			end if
+		end do
+	end subroutine gridInqYstdname
+
+	subroutine gridDefPrec(gridID_dummy, prec_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: prec_dummy
+		interface
+			subroutine lib_gridDefPrec(gridID_dummy, prec_dummy) bind(c, name = 'gridDefPrec')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: prec_dummy
+			end subroutine lib_gridDefPrec
+		end interface
+		call lib_gridDefPrec(gridID_dummy, prec_dummy)
+	end subroutine gridDefPrec
+
+	function gridInqPrec(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqPrec(gridID_dummy) bind(c, name = 'gridInqPrec')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqPrec
+		end interface
+		result = lib_gridInqPrec(gridID_dummy)
+	end function gridInqPrec
+
+	function gridInqXval(gridID_dummy, index_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: index_dummy
+		interface
+			real(c_double) function lib_gridInqXval(gridID_dummy, index_dummy) bind(c, name = 'gridInqXval')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: index_dummy
+			end function lib_gridInqXval
+		end interface
+		result = lib_gridInqXval(gridID_dummy, index_dummy)
+	end function gridInqXval
+
+	function gridInqYval(gridID_dummy, index_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: index_dummy
+		interface
+			real(c_double) function lib_gridInqYval(gridID_dummy, index_dummy) bind(c, name = 'gridInqYval')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: index_dummy
+			end function lib_gridInqYval
+		end interface
+		result = lib_gridInqYval(gridID_dummy, index_dummy)
+	end function gridInqYval
+
+	function gridInqXinc(gridID_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			real(c_double) function lib_gridInqXinc(gridID_dummy) bind(c, name = 'gridInqXinc')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqXinc
+		end interface
+		result = lib_gridInqXinc(gridID_dummy)
+	end function gridInqXinc
+
+	function gridInqYinc(gridID_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			real(c_double) function lib_gridInqYinc(gridID_dummy) bind(c, name = 'gridInqYinc')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqYinc
+		end interface
+		result = lib_gridInqYinc(gridID_dummy)
+	end function gridInqYinc
+
+	function gridIsCircular(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridIsCircular(gridID_dummy) bind(c, name = 'gridIsCircular')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridIsCircular
+		end interface
+		result = lib_gridIsCircular(gridID_dummy)
+	end function gridIsCircular
+
+	function gridIsRotated(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridIsRotated(gridID_dummy) bind(c, name = 'gridIsRotated')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridIsRotated
+		end interface
+		result = lib_gridIsRotated(gridID_dummy)
+	end function gridIsRotated
+
+	subroutine gridDefXpole(gridID_dummy, xpole_dummy)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), value :: xpole_dummy
+		interface
+			subroutine lib_gridDefXpole(gridID_dummy, xpole_dummy) bind(c, name = 'gridDefXpole')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), value :: xpole_dummy
+			end subroutine lib_gridDefXpole
+		end interface
+		call lib_gridDefXpole(gridID_dummy, xpole_dummy)
+	end subroutine gridDefXpole
+
+	function gridInqXpole(gridID_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			real(c_double) function lib_gridInqXpole(gridID_dummy) bind(c, name = 'gridInqXpole')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqXpole
+		end interface
+		result = lib_gridInqXpole(gridID_dummy)
+	end function gridInqXpole
+
+	subroutine gridDefYpole(gridID_dummy, ypole_dummy)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), value :: ypole_dummy
+		interface
+			subroutine lib_gridDefYpole(gridID_dummy, ypole_dummy) bind(c, name = 'gridDefYpole')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), value :: ypole_dummy
+			end subroutine lib_gridDefYpole
+		end interface
+		call lib_gridDefYpole(gridID_dummy, ypole_dummy)
+	end subroutine gridDefYpole
+
+	function gridInqYpole(gridID_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			real(c_double) function lib_gridInqYpole(gridID_dummy) bind(c, name = 'gridInqYpole')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqYpole
+		end interface
+		result = lib_gridInqYpole(gridID_dummy)
+	end function gridInqYpole
+
+	subroutine gridDefAngle(gridID_dummy, angle_dummy)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), value :: angle_dummy
+		interface
+			subroutine lib_gridDefAngle(gridID_dummy, angle_dummy) bind(c, name = 'gridDefAngle')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), value :: angle_dummy
+			end subroutine lib_gridDefAngle
+		end interface
+		call lib_gridDefAngle(gridID_dummy, angle_dummy)
+	end subroutine gridDefAngle
+
+	function gridInqAngle(gridID_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			real(c_double) function lib_gridInqAngle(gridID_dummy) bind(c, name = 'gridInqAngle')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqAngle
+		end interface
+		result = lib_gridInqAngle(gridID_dummy)
+	end function gridInqAngle
+
+	function gridInqTrunc(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqTrunc(gridID_dummy) bind(c, name = 'gridInqTrunc')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqTrunc
+		end interface
+		result = lib_gridInqTrunc(gridID_dummy)
+	end function gridInqTrunc
+
+	subroutine gridDefTrunc(gridID_dummy, trunc_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: trunc_dummy
+		interface
+			subroutine lib_gridDefTrunc(gridID_dummy, trunc_dummy) bind(c, name = 'gridDefTrunc')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: trunc_dummy
+			end subroutine lib_gridDefTrunc
+		end interface
+		call lib_gridDefTrunc(gridID_dummy, trunc_dummy)
+	end subroutine gridDefTrunc
+
+	subroutine gridDefGMEnd(gridID_dummy, nd_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: nd_dummy
+		interface
+			subroutine lib_gridDefGMEnd(gridID_dummy, nd_dummy) bind(c, name = 'gridDefGMEnd')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: nd_dummy
+			end subroutine lib_gridDefGMEnd
+		end interface
+		call lib_gridDefGMEnd(gridID_dummy, nd_dummy)
+	end subroutine gridDefGMEnd
+
+	function gridInqGMEnd(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqGMEnd(gridID_dummy) bind(c, name = 'gridInqGMEnd')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqGMEnd
+		end interface
+		result = lib_gridInqGMEnd(gridID_dummy)
+	end function gridInqGMEnd
+
+	subroutine gridDefGMEni(gridID_dummy, ni_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: ni_dummy
+		interface
+			subroutine lib_gridDefGMEni(gridID_dummy, ni_dummy) bind(c, name = 'gridDefGMEni')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: ni_dummy
+			end subroutine lib_gridDefGMEni
+		end interface
+		call lib_gridDefGMEni(gridID_dummy, ni_dummy)
+	end subroutine gridDefGMEni
+
+	function gridInqGMEni(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqGMEni(gridID_dummy) bind(c, name = 'gridInqGMEni')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqGMEni
+		end interface
+		result = lib_gridInqGMEni(gridID_dummy)
+	end function gridInqGMEni
+
+	subroutine gridDefGMEni2(gridID_dummy, ni2_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: ni2_dummy
+		interface
+			subroutine lib_gridDefGMEni2(gridID_dummy, ni2_dummy) bind(c, name = 'gridDefGMEni2')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: ni2_dummy
+			end subroutine lib_gridDefGMEni2
+		end interface
+		call lib_gridDefGMEni2(gridID_dummy, ni2_dummy)
+	end subroutine gridDefGMEni2
+
+	function gridInqGMEni2(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqGMEni2(gridID_dummy) bind(c, name = 'gridInqGMEni2')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqGMEni2
+		end interface
+		result = lib_gridInqGMEni2(gridID_dummy)
+	end function gridInqGMEni2
+
+	subroutine gridDefGMEni3(gridID_dummy, ni3_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: ni3_dummy
+		interface
+			subroutine lib_gridDefGMEni3(gridID_dummy, ni3_dummy) bind(c, name = 'gridDefGMEni3')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: ni3_dummy
+			end subroutine lib_gridDefGMEni3
+		end interface
+		call lib_gridDefGMEni3(gridID_dummy, ni3_dummy)
+	end subroutine gridDefGMEni3
+
+	function gridInqGMEni3(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqGMEni3(gridID_dummy) bind(c, name = 'gridInqGMEni3')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqGMEni3
+		end interface
+		result = lib_gridInqGMEni3(gridID_dummy)
+	end function gridInqGMEni3
+
+	subroutine gridDefNumber(gridID_dummy, number_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: number_dummy
+		interface
+			subroutine lib_gridDefNumber(gridID_dummy, number_dummy) bind(c, name = 'gridDefNumber')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: number_dummy
+			end subroutine lib_gridDefNumber
+		end interface
+		call lib_gridDefNumber(gridID_dummy, number_dummy)
+	end subroutine gridDefNumber
+
+	function gridInqNumber(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqNumber(gridID_dummy) bind(c, name = 'gridInqNumber')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqNumber
+		end interface
+		result = lib_gridInqNumber(gridID_dummy)
+	end function gridInqNumber
+
+	subroutine gridDefPosition(gridID_dummy, position_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: position_dummy
+		interface
+			subroutine lib_gridDefPosition(gridID_dummy, position_dummy) bind(c, name = 'gridDefPosition')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: position_dummy
+			end subroutine lib_gridDefPosition
+		end interface
+		call lib_gridDefPosition(gridID_dummy, position_dummy)
+	end subroutine gridDefPosition
+
+	function gridInqPosition(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqPosition(gridID_dummy) bind(c, name = 'gridInqPosition')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqPosition
+		end interface
+		result = lib_gridInqPosition(gridID_dummy)
+	end function gridInqPosition
+
+	subroutine gridDefReference(gridID_dummy, reference_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(in) :: reference_dummy
+		character(kind = c_char) :: reference_temp(len(reference_dummy) + 1)
+		integer :: reference_i
+		interface
+			subroutine lib_gridDefReference(gridID_dummy, reference_dummy) bind(c, name = 'gridDefReference')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: reference_dummy(*)
+			end subroutine lib_gridDefReference
+		end interface
+		do reference_i = 1, len(reference_dummy)
+		reference_temp(reference_i) = reference_dummy(reference_i:reference_i)
+		end do
+		reference_temp(len(reference_dummy) + 1) = c_null_char
+		call lib_gridDefReference(gridID_dummy, reference_temp)
+	end subroutine gridDefReference
+
+	function gridInqReference(gridID_dummy, reference_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char, len = *), intent(inout) :: reference_dummy
+		character(kind = c_char) :: reference_temp(len(reference_dummy))
+		integer :: reference_i
+		logical :: reference_padding = .true.
+		interface
+			integer(c_int) function lib_gridInqReference(gridID_dummy, reference_dummy) bind(c, name = 'gridInqReference')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char) :: reference_dummy(*)
+			end function lib_gridInqReference
+		end interface
+		do reference_i = len(reference_dummy), 1, -1
+			if(reference_dummy(reference_i:reference_i) /= ' ') reference_padding = .false.
+			if(reference_padding) then
+				reference_temp(reference_i) = c_null_char
+			else
+				reference_temp(reference_i) = reference_dummy(reference_i:reference_i)
+			end if
+		end do
+		result = lib_gridInqReference(gridID_dummy, reference_temp)
+		reference_padding = .false.
+		do reference_i = 1, len(reference_dummy)
+			if(reference_temp(reference_i) == c_null_char) reference_padding = .true.
+			if(reference_padding) then
+				reference_dummy(reference_i:reference_i) = ' '
+			else
+				reference_dummy(reference_i:reference_i) = reference_temp(reference_i)
+			end if
+		end do
+	end function gridInqReference
+
+	subroutine gridDefUUID(gridID_dummy, uuid_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char), intent(in) :: uuid_dummy(CDI_UUID_SIZE)
+		interface
+			subroutine lib_gridDefUUID(gridID_dummy, uuid_dummy) bind(c, name = 'gridDefUUID')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char), intent(in) :: uuid_dummy(*)
+			end subroutine lib_gridDefUUID
+		end interface
+		call lib_gridDefUUID(gridID_dummy, uuid_dummy)
+	end subroutine gridDefUUID
+
+	subroutine gridInqUUID(gridID_dummy, uuid_dummy)
+		integer(c_int), value :: gridID_dummy
+		character(kind = c_char), intent(inout) :: uuid_dummy(CDI_UUID_SIZE)
+		interface
+			subroutine lib_gridInqUUID(gridID_dummy, uuid_dummy) bind(c, name = 'gridInqUUID')
+				import c_char, c_int
+				integer(c_int), value :: gridID_dummy
+				character(kind = c_char), intent(inout) :: uuid_dummy(*)
+			end subroutine lib_gridInqUUID
+		end interface
+		call lib_gridInqUUID(gridID_dummy, uuid_dummy)
+	end subroutine gridInqUUID
+
+	subroutine gridDefLCC(gridID_dummy, originLon_dummy, originLat_dummy, lonParY_dummy, lat1_dummy, lat2_dummy, xinc_dummy, yinc_dumm&
+	&y, projflag_dummy, scanflag_dummy)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), value :: originLon_dummy
+		real(c_double), value :: originLat_dummy
+		real(c_double), value :: lonParY_dummy
+		real(c_double), value :: lat1_dummy
+		real(c_double), value :: lat2_dummy
+		real(c_double), value :: xinc_dummy
+		real(c_double), value :: yinc_dummy
+		integer(c_int), value :: projflag_dummy
+		integer(c_int), value :: scanflag_dummy
+		interface
+			subroutine lib_gridDefLCC(gridID_dummy, originLon_dummy, originLat_dummy, lonParY_dummy, lat1_dummy, lat2_dummy, xinc_dummy, yin&
+			&c_dummy, projflag_dummy, scanflag_dummy) bind(c, name = 'gridDefLCC')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), value :: originLon_dummy
+				real(c_double), value :: originLat_dummy
+				real(c_double), value :: lonParY_dummy
+				real(c_double), value :: lat1_dummy
+				real(c_double), value :: lat2_dummy
+				real(c_double), value :: xinc_dummy
+				real(c_double), value :: yinc_dummy
+				integer(c_int), value :: projflag_dummy
+				integer(c_int), value :: scanflag_dummy
+			end subroutine lib_gridDefLCC
+		end interface
+		call lib_gridDefLCC(gridID_dummy, originLon_dummy, originLat_dummy, lonParY_dummy, lat1_dummy, lat2_dummy, xinc_dummy, yinc_dummy&
+		&, projflag_dummy, scanflag_dummy)
+	end subroutine gridDefLCC
+
+	subroutine gridInqLCC(gridID_dummy, originLon, originLat, lonParY, lat1, lat2, xinc, yinc, projflag, scanflag)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), optional, intent(inout) :: originLon
+		real(c_double), optional, intent(inout) :: originLat
+		real(c_double), optional, intent(inout) :: lonParY
+		real(c_double), optional, intent(inout) :: lat1
+		real(c_double), optional, intent(inout) :: lat2
+		real(c_double), optional, intent(inout) :: xinc
+		real(c_double), optional, intent(inout) :: yinc
+		integer(c_int), optional, intent(inout) :: projflag
+		integer(c_int), optional, intent(inout) :: scanflag
+		real(c_double), target :: originLon_temp
+		type(c_ptr) :: originLon_ptr
+		real(c_double), target :: originLat_temp
+		type(c_ptr) :: originLat_ptr
+		real(c_double), target :: lonParY_temp
+		type(c_ptr) :: lonParY_ptr
+		real(c_double), target :: lat1_temp
+		type(c_ptr) :: lat1_ptr
+		real(c_double), target :: lat2_temp
+		type(c_ptr) :: lat2_ptr
+		real(c_double), target :: xinc_temp
+		type(c_ptr) :: xinc_ptr
+		real(c_double), target :: yinc_temp
+		type(c_ptr) :: yinc_ptr
+		integer(c_int), target :: projflag_temp
+		type(c_ptr) :: projflag_ptr
+		integer(c_int), target :: scanflag_temp
+		type(c_ptr) :: scanflag_ptr
+		interface
+			subroutine lib_gridInqLCC(gridID_dummy, originLon, originLat, lonParY, lat1, lat2, xinc, yinc, projflag, scanflag) bind(c, name &
+			&= 'gridInqLCC')
+				import c_int, c_ptr
+				integer(c_int), value :: gridID_dummy
+				type(c_ptr), value :: originLon
+				type(c_ptr), value :: originLat
+				type(c_ptr), value :: lonParY
+				type(c_ptr), value :: lat1
+				type(c_ptr), value :: lat2
+				type(c_ptr), value :: xinc
+				type(c_ptr), value :: yinc
+				type(c_ptr), value :: projflag
+				type(c_ptr), value :: scanflag
+			end subroutine lib_gridInqLCC
+		end interface
+		originLon_ptr = c_null_ptr
+		if(present(originLon)) originLon_ptr = c_loc(originLon_temp)
+		originLat_ptr = c_null_ptr
+		if(present(originLat)) originLat_ptr = c_loc(originLat_temp)
+		lonParY_ptr = c_null_ptr
+		if(present(lonParY)) lonParY_ptr = c_loc(lonParY_temp)
+		lat1_ptr = c_null_ptr
+		if(present(lat1)) lat1_ptr = c_loc(lat1_temp)
+		lat2_ptr = c_null_ptr
+		if(present(lat2)) lat2_ptr = c_loc(lat2_temp)
+		xinc_ptr = c_null_ptr
+		if(present(xinc)) xinc_ptr = c_loc(xinc_temp)
+		yinc_ptr = c_null_ptr
+		if(present(yinc)) yinc_ptr = c_loc(yinc_temp)
+		projflag_ptr = c_null_ptr
+		if(present(projflag)) projflag_ptr = c_loc(projflag_temp)
+		scanflag_ptr = c_null_ptr
+		if(present(scanflag)) scanflag_ptr = c_loc(scanflag_temp)
+		call lib_gridInqLCC(gridID_dummy, originLon_ptr, originLat_ptr, lonParY_ptr, lat1_ptr, lat2_ptr, xinc_ptr, yinc_ptr, projflag_ptr&
+		&, scanflag_ptr)
+		if(present(originLon)) originLon = originLon_temp
+		if(present(originLat)) originLat = originLat_temp
+		if(present(lonParY)) lonParY = lonParY_temp
+		if(present(lat1)) lat1 = lat1_temp
+		if(present(lat2)) lat2 = lat2_temp
+		if(present(xinc)) xinc = xinc_temp
+		if(present(yinc)) yinc = yinc_temp
+		if(present(projflag)) projflag = projflag_temp
+		if(present(scanflag)) scanflag = scanflag_temp
+	end subroutine gridInqLCC
+
+	subroutine gridDefLcc2(gridID_dummy, earth_radius_dummy, lon_0_dummy, lat_0_dummy, lat_1_dummy, lat_2_dummy)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), value :: earth_radius_dummy
+		real(c_double), value :: lon_0_dummy
+		real(c_double), value :: lat_0_dummy
+		real(c_double), value :: lat_1_dummy
+		real(c_double), value :: lat_2_dummy
+		interface
+			subroutine lib_gridDefLcc2(gridID_dummy, earth_radius_dummy, lon_0_dummy, lat_0_dummy, lat_1_dummy, lat_2_dummy) bind(c, name = &
+			&'gridDefLcc2')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), value :: earth_radius_dummy
+				real(c_double), value :: lon_0_dummy
+				real(c_double), value :: lat_0_dummy
+				real(c_double), value :: lat_1_dummy
+				real(c_double), value :: lat_2_dummy
+			end subroutine lib_gridDefLcc2
+		end interface
+		call lib_gridDefLcc2(gridID_dummy, earth_radius_dummy, lon_0_dummy, lat_0_dummy, lat_1_dummy, lat_2_dummy)
+	end subroutine gridDefLcc2
+
+	subroutine gridInqLcc2(gridID_dummy, earth_radius, lon_0, lat_0, lat_1, lat_2)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), optional, intent(inout) :: earth_radius
+		real(c_double), optional, intent(inout) :: lon_0
+		real(c_double), optional, intent(inout) :: lat_0
+		real(c_double), optional, intent(inout) :: lat_1
+		real(c_double), optional, intent(inout) :: lat_2
+		real(c_double), target :: earth_radius_temp
+		type(c_ptr) :: earth_radius_ptr
+		real(c_double), target :: lon_0_temp
+		type(c_ptr) :: lon_0_ptr
+		real(c_double), target :: lat_0_temp
+		type(c_ptr) :: lat_0_ptr
+		real(c_double), target :: lat_1_temp
+		type(c_ptr) :: lat_1_ptr
+		real(c_double), target :: lat_2_temp
+		type(c_ptr) :: lat_2_ptr
+		interface
+			subroutine lib_gridInqLcc2(gridID_dummy, earth_radius, lon_0, lat_0, lat_1, lat_2) bind(c, name = 'gridInqLcc2')
+				import c_int, c_ptr
+				integer(c_int), value :: gridID_dummy
+				type(c_ptr), value :: earth_radius
+				type(c_ptr), value :: lon_0
+				type(c_ptr), value :: lat_0
+				type(c_ptr), value :: lat_1
+				type(c_ptr), value :: lat_2
+			end subroutine lib_gridInqLcc2
+		end interface
+		earth_radius_ptr = c_null_ptr
+		if(present(earth_radius)) earth_radius_ptr = c_loc(earth_radius_temp)
+		lon_0_ptr = c_null_ptr
+		if(present(lon_0)) lon_0_ptr = c_loc(lon_0_temp)
+		lat_0_ptr = c_null_ptr
+		if(present(lat_0)) lat_0_ptr = c_loc(lat_0_temp)
+		lat_1_ptr = c_null_ptr
+		if(present(lat_1)) lat_1_ptr = c_loc(lat_1_temp)
+		lat_2_ptr = c_null_ptr
+		if(present(lat_2)) lat_2_ptr = c_loc(lat_2_temp)
+		call lib_gridInqLcc2(gridID_dummy, earth_radius_ptr, lon_0_ptr, lat_0_ptr, lat_1_ptr, lat_2_ptr)
+		if(present(earth_radius)) earth_radius = earth_radius_temp
+		if(present(lon_0)) lon_0 = lon_0_temp
+		if(present(lat_0)) lat_0 = lat_0_temp
+		if(present(lat_1)) lat_1 = lat_1_temp
+		if(present(lat_2)) lat_2 = lat_2_temp
+	end subroutine gridInqLcc2
+
+	subroutine gridDefLaea(gridID_dummy, earth_radius_dummy, lon_0_dummy, lat_0_dummy)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), value :: earth_radius_dummy
+		real(c_double), value :: lon_0_dummy
+		real(c_double), value :: lat_0_dummy
+		interface
+			subroutine lib_gridDefLaea(gridID_dummy, earth_radius_dummy, lon_0_dummy, lat_0_dummy) bind(c, name = 'gridDefLaea')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), value :: earth_radius_dummy
+				real(c_double), value :: lon_0_dummy
+				real(c_double), value :: lat_0_dummy
+			end subroutine lib_gridDefLaea
+		end interface
+		call lib_gridDefLaea(gridID_dummy, earth_radius_dummy, lon_0_dummy, lat_0_dummy)
+	end subroutine gridDefLaea
+
+	subroutine gridInqLaea(gridID_dummy, earth_radius, lon_0, lat_0)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), optional, intent(inout) :: earth_radius
+		real(c_double), optional, intent(inout) :: lon_0
+		real(c_double), optional, intent(inout) :: lat_0
+		real(c_double), target :: earth_radius_temp
+		type(c_ptr) :: earth_radius_ptr
+		real(c_double), target :: lon_0_temp
+		type(c_ptr) :: lon_0_ptr
+		real(c_double), target :: lat_0_temp
+		type(c_ptr) :: lat_0_ptr
+		interface
+			subroutine lib_gridInqLaea(gridID_dummy, earth_radius, lon_0, lat_0) bind(c, name = 'gridInqLaea')
+				import c_int, c_ptr
+				integer(c_int), value :: gridID_dummy
+				type(c_ptr), value :: earth_radius
+				type(c_ptr), value :: lon_0
+				type(c_ptr), value :: lat_0
+			end subroutine lib_gridInqLaea
+		end interface
+		earth_radius_ptr = c_null_ptr
+		if(present(earth_radius)) earth_radius_ptr = c_loc(earth_radius_temp)
+		lon_0_ptr = c_null_ptr
+		if(present(lon_0)) lon_0_ptr = c_loc(lon_0_temp)
+		lat_0_ptr = c_null_ptr
+		if(present(lat_0)) lat_0_ptr = c_loc(lat_0_temp)
+		call lib_gridInqLaea(gridID_dummy, earth_radius_ptr, lon_0_ptr, lat_0_ptr)
+		if(present(earth_radius)) earth_radius = earth_radius_temp
+		if(present(lon_0)) lon_0 = lon_0_temp
+		if(present(lat_0)) lat_0 = lat_0_temp
+	end subroutine gridInqLaea
+
+	subroutine gridDefArea(gridID_dummy, area_vec_dummy)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), intent(in) :: area_vec_dummy(*)
+		interface
+			subroutine lib_gridDefArea(gridID_dummy, area_vec_dummy) bind(c, name = 'gridDefArea')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), intent(in) :: area_vec_dummy(*)
+			end subroutine lib_gridDefArea
+		end interface
+		call lib_gridDefArea(gridID_dummy, area_vec_dummy)
+	end subroutine gridDefArea
+
+	subroutine gridInqArea(gridID_dummy, area_vec_dummy)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), intent(inout) :: area_vec_dummy(*)
+		interface
+			subroutine lib_gridInqArea(gridID_dummy, area_vec_dummy) bind(c, name = 'gridInqArea')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), intent(inout) :: area_vec_dummy(*)
+			end subroutine lib_gridInqArea
+		end interface
+		call lib_gridInqArea(gridID_dummy, area_vec_dummy)
+	end subroutine gridInqArea
+
+	function gridHasArea(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridHasArea(gridID_dummy) bind(c, name = 'gridHasArea')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridHasArea
+		end interface
+		result = lib_gridHasArea(gridID_dummy)
+	end function gridHasArea
+
+	subroutine gridDefNvertex(gridID_dummy, nvertex_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: nvertex_dummy
+		interface
+			subroutine lib_gridDefNvertex(gridID_dummy, nvertex_dummy) bind(c, name = 'gridDefNvertex')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: nvertex_dummy
+			end subroutine lib_gridDefNvertex
+		end interface
+		call lib_gridDefNvertex(gridID_dummy, nvertex_dummy)
+	end subroutine gridDefNvertex
+
+	function gridInqNvertex(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqNvertex(gridID_dummy) bind(c, name = 'gridInqNvertex')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqNvertex
+		end interface
+		result = lib_gridInqNvertex(gridID_dummy)
+	end function gridInqNvertex
+
+	subroutine gridDefXbounds(gridID_dummy, xbounds_vec_dummy)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), intent(in) :: xbounds_vec_dummy(*)
+		interface
+			subroutine lib_gridDefXbounds(gridID_dummy, xbounds_vec_dummy) bind(c, name = 'gridDefXbounds')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), intent(in) :: xbounds_vec_dummy(*)
+			end subroutine lib_gridDefXbounds
+		end interface
+		call lib_gridDefXbounds(gridID_dummy, xbounds_vec_dummy)
+	end subroutine gridDefXbounds
+
+	function gridInqXbounds(gridID_dummy, xbounds_vec_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		real(c_double), intent(inout) :: xbounds_vec_dummy(*)
+		interface
+			integer(c_int) function lib_gridInqXbounds(gridID_dummy, xbounds_vec_dummy) bind(c, name = 'gridInqXbounds')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), intent(inout) :: xbounds_vec_dummy(*)
+			end function lib_gridInqXbounds
+		end interface
+		result = lib_gridInqXbounds(gridID_dummy, xbounds_vec_dummy)
+	end function gridInqXbounds
+
+	subroutine gridDefYbounds(gridID_dummy, ybounds_vec_dummy)
+		integer(c_int), value :: gridID_dummy
+		real(c_double), intent(in) :: ybounds_vec_dummy(*)
+		interface
+			subroutine lib_gridDefYbounds(gridID_dummy, ybounds_vec_dummy) bind(c, name = 'gridDefYbounds')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), intent(in) :: ybounds_vec_dummy(*)
+			end subroutine lib_gridDefYbounds
+		end interface
+		call lib_gridDefYbounds(gridID_dummy, ybounds_vec_dummy)
+	end subroutine gridDefYbounds
+
+	function gridInqYbounds(gridID_dummy, ybounds_vec_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		real(c_double), intent(inout) :: ybounds_vec_dummy(*)
+		interface
+			integer(c_int) function lib_gridInqYbounds(gridID_dummy, ybounds_vec_dummy) bind(c, name = 'gridInqYbounds')
+				import c_double, c_int
+				integer(c_int), value :: gridID_dummy
+				real(c_double), intent(inout) :: ybounds_vec_dummy(*)
+			end function lib_gridInqYbounds
+		end interface
+		result = lib_gridInqYbounds(gridID_dummy, ybounds_vec_dummy)
+	end function gridInqYbounds
+
+	subroutine gridDefRowlon(gridID_dummy, nrowlon_dummy, rowlon_vec_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: nrowlon_dummy
+		integer(c_int), intent(in) :: rowlon_vec_dummy(*)
+		interface
+			subroutine lib_gridDefRowlon(gridID_dummy, nrowlon_dummy, rowlon_vec_dummy) bind(c, name = 'gridDefRowlon')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: nrowlon_dummy
+				integer(c_int), intent(in) :: rowlon_vec_dummy(*)
+			end subroutine lib_gridDefRowlon
+		end interface
+		call lib_gridDefRowlon(gridID_dummy, nrowlon_dummy, rowlon_vec_dummy)
+	end subroutine gridDefRowlon
+
+	subroutine gridInqRowlon(gridID_dummy, rowlon_vec_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), intent(inout) :: rowlon_vec_dummy(*)
+		interface
+			subroutine lib_gridInqRowlon(gridID_dummy, rowlon_vec_dummy) bind(c, name = 'gridInqRowlon')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), intent(inout) :: rowlon_vec_dummy(*)
+			end subroutine lib_gridInqRowlon
+		end interface
+		call lib_gridInqRowlon(gridID_dummy, rowlon_vec_dummy)
+	end subroutine gridInqRowlon
+
+	subroutine gridChangeType(gridID_dummy, gridtype_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: gridtype_dummy
+		interface
+			subroutine lib_gridChangeType(gridID_dummy, gridtype_dummy) bind(c, name = 'gridChangeType')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: gridtype_dummy
+			end subroutine lib_gridChangeType
+		end interface
+		call lib_gridChangeType(gridID_dummy, gridtype_dummy)
+	end subroutine gridChangeType
+
+	subroutine gridDefComplexPacking(gridID_dummy, lpack_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: lpack_dummy
+		interface
+			subroutine lib_gridDefComplexPacking(gridID_dummy, lpack_dummy) bind(c, name = 'gridDefComplexPacking')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: lpack_dummy
+			end subroutine lib_gridDefComplexPacking
+		end interface
+		call lib_gridDefComplexPacking(gridID_dummy, lpack_dummy)
+	end subroutine gridDefComplexPacking
+
+	function gridInqComplexPacking(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_gridInqComplexPacking(gridID_dummy) bind(c, name = 'gridInqComplexPacking')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_gridInqComplexPacking
+		end interface
+		result = lib_gridInqComplexPacking(gridID_dummy)
+	end function gridInqComplexPacking
+
+	subroutine zaxisName(zaxistype_dummy, zaxisname_dummy)
+		integer(c_int), value :: zaxistype_dummy
+		character(kind = c_char, len = *), intent(inout) :: zaxisname_dummy
+		character(kind = c_char) :: zaxisname_temp(len(zaxisname_dummy))
+		integer :: zaxisname_i
+		logical :: zaxisname_padding = .true.
+		interface
+			subroutine lib_zaxisName(zaxistype_dummy, zaxisname_dummy) bind(c, name = 'zaxisName')
+				import c_char, c_int
+				integer(c_int), value :: zaxistype_dummy
+				character(kind = c_char) :: zaxisname_dummy(*)
+			end subroutine lib_zaxisName
+		end interface
+		do zaxisname_i = len(zaxisname_dummy), 1, -1
+			if(zaxisname_dummy(zaxisname_i:zaxisname_i) /= ' ') zaxisname_padding = .false.
+			if(zaxisname_padding) then
+				zaxisname_temp(zaxisname_i) = c_null_char
+			else
+				zaxisname_temp(zaxisname_i) = zaxisname_dummy(zaxisname_i:zaxisname_i)
+			end if
+		end do
+		call lib_zaxisName(zaxistype_dummy, zaxisname_temp)
+		zaxisname_padding = .false.
+		do zaxisname_i = 1, len(zaxisname_dummy)
+			if(zaxisname_temp(zaxisname_i) == c_null_char) zaxisname_padding = .true.
+			if(zaxisname_padding) then
+				zaxisname_dummy(zaxisname_i:zaxisname_i) = ' '
+			else
+				zaxisname_dummy(zaxisname_i:zaxisname_i) = zaxisname_temp(zaxisname_i)
+			end if
+		end do
+	end subroutine zaxisName
+
+	function zaxisCreate(zaxistype_dummy, size_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: zaxistype_dummy
+		integer(c_int), value :: size_dummy
+		interface
+			integer(c_int) function lib_zaxisCreate(zaxistype_dummy, size_dummy) bind(c, name = 'zaxisCreate')
+				import c_int
+				integer(c_int), value :: zaxistype_dummy
+				integer(c_int), value :: size_dummy
+			end function lib_zaxisCreate
+		end interface
+		result = lib_zaxisCreate(zaxistype_dummy, size_dummy)
+	end function zaxisCreate
+
+	subroutine zaxisDestroy(zaxisID_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		interface
+			subroutine lib_zaxisDestroy(zaxisID_dummy) bind(c, name = 'zaxisDestroy')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+			end subroutine lib_zaxisDestroy
+		end interface
+		call lib_zaxisDestroy(zaxisID_dummy)
+	end subroutine zaxisDestroy
+
+	function zaxisInqType(zaxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: zaxisID_dummy
+		interface
+			integer(c_int) function lib_zaxisInqType(zaxisID_dummy) bind(c, name = 'zaxisInqType')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+			end function lib_zaxisInqType
+		end interface
+		result = lib_zaxisInqType(zaxisID_dummy)
+	end function zaxisInqType
+
+	function zaxisInqSize(zaxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: zaxisID_dummy
+		interface
+			integer(c_int) function lib_zaxisInqSize(zaxisID_dummy) bind(c, name = 'zaxisInqSize')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+			end function lib_zaxisInqSize
+		end interface
+		result = lib_zaxisInqSize(zaxisID_dummy)
+	end function zaxisInqSize
+
+	function zaxisDuplicate(zaxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: zaxisID_dummy
+		interface
+			integer(c_int) function lib_zaxisDuplicate(zaxisID_dummy) bind(c, name = 'zaxisDuplicate')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+			end function lib_zaxisDuplicate
+		end interface
+		result = lib_zaxisDuplicate(zaxisID_dummy)
+	end function zaxisDuplicate
+
+	subroutine zaxisResize(zaxisID_dummy, size_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		integer(c_int), value :: size_dummy
+		interface
+			subroutine lib_zaxisResize(zaxisID_dummy, size_dummy) bind(c, name = 'zaxisResize')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+				integer(c_int), value :: size_dummy
+			end subroutine lib_zaxisResize
+		end interface
+		call lib_zaxisResize(zaxisID_dummy, size_dummy)
+	end subroutine zaxisResize
+
+	subroutine zaxisPrint(zaxisID_dummy, index_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		integer(c_int), value :: index_dummy
+		interface
+			subroutine lib_zaxisPrint(zaxisID_dummy, index_dummy) bind(c, name = 'zaxisPrint')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+				integer(c_int), value :: index_dummy
+			end subroutine lib_zaxisPrint
+		end interface
+		call lib_zaxisPrint(zaxisID_dummy, index_dummy)
+	end subroutine zaxisPrint
+
+	subroutine zaxisDefLevels(zaxisID_dummy, levels_vec_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		real(c_double), intent(in) :: levels_vec_dummy(*)
+		interface
+			subroutine lib_zaxisDefLevels(zaxisID_dummy, levels_vec_dummy) bind(c, name = 'zaxisDefLevels')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				real(c_double), intent(in) :: levels_vec_dummy(*)
+			end subroutine lib_zaxisDefLevels
+		end interface
+		call lib_zaxisDefLevels(zaxisID_dummy, levels_vec_dummy)
+	end subroutine zaxisDefLevels
+
+	subroutine zaxisInqLevels(zaxisID_dummy, levels_vec_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		real(c_double), intent(inout) :: levels_vec_dummy(*)
+		interface
+			subroutine lib_zaxisInqLevels(zaxisID_dummy, levels_vec_dummy) bind(c, name = 'zaxisInqLevels')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				real(c_double), intent(inout) :: levels_vec_dummy(*)
+			end subroutine lib_zaxisInqLevels
+		end interface
+		call lib_zaxisInqLevels(zaxisID_dummy, levels_vec_dummy)
+	end subroutine zaxisInqLevels
+
+	subroutine zaxisDefLevel(zaxisID_dummy, levelID_dummy, levels_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		integer(c_int), value :: levelID_dummy
+		real(c_double), value :: levels_dummy
+		interface
+			subroutine lib_zaxisDefLevel(zaxisID_dummy, levelID_dummy, levels_dummy) bind(c, name = 'zaxisDefLevel')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				integer(c_int), value :: levelID_dummy
+				real(c_double), value :: levels_dummy
+			end subroutine lib_zaxisDefLevel
+		end interface
+		call lib_zaxisDefLevel(zaxisID_dummy, levelID_dummy, levels_dummy)
+	end subroutine zaxisDefLevel
+
+	function zaxisInqLevel(zaxisID_dummy, levelID_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: zaxisID_dummy
+		integer(c_int), value :: levelID_dummy
+		interface
+			real(c_double) function lib_zaxisInqLevel(zaxisID_dummy, levelID_dummy) bind(c, name = 'zaxisInqLevel')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				integer(c_int), value :: levelID_dummy
+			end function lib_zaxisInqLevel
+		end interface
+		result = lib_zaxisInqLevel(zaxisID_dummy, levelID_dummy)
+	end function zaxisInqLevel
+
+	subroutine zaxisDefNlevRef(gridID_dummy, nhlev_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: nhlev_dummy
+		interface
+			subroutine lib_zaxisDefNlevRef(gridID_dummy, nhlev_dummy) bind(c, name = 'zaxisDefNlevRef')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: nhlev_dummy
+			end subroutine lib_zaxisDefNlevRef
+		end interface
+		call lib_zaxisDefNlevRef(gridID_dummy, nhlev_dummy)
+	end subroutine zaxisDefNlevRef
+
+	function zaxisInqNlevRef(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_zaxisInqNlevRef(gridID_dummy) bind(c, name = 'zaxisInqNlevRef')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_zaxisInqNlevRef
+		end interface
+		result = lib_zaxisInqNlevRef(gridID_dummy)
+	end function zaxisInqNlevRef
+
+	subroutine zaxisDefNumber(gridID_dummy, number_dummy)
+		integer(c_int), value :: gridID_dummy
+		integer(c_int), value :: number_dummy
+		interface
+			subroutine lib_zaxisDefNumber(gridID_dummy, number_dummy) bind(c, name = 'zaxisDefNumber')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+				integer(c_int), value :: number_dummy
+			end subroutine lib_zaxisDefNumber
+		end interface
+		call lib_zaxisDefNumber(gridID_dummy, number_dummy)
+	end subroutine zaxisDefNumber
+
+	function zaxisInqNumber(gridID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: gridID_dummy
+		interface
+			integer(c_int) function lib_zaxisInqNumber(gridID_dummy) bind(c, name = 'zaxisInqNumber')
+				import c_int
+				integer(c_int), value :: gridID_dummy
+			end function lib_zaxisInqNumber
+		end interface
+		result = lib_zaxisInqNumber(gridID_dummy)
+	end function zaxisInqNumber
+
+	subroutine zaxisDefUUID(zaxisID_dummy, uuid_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		character(kind = c_char), intent(in) :: uuid_dummy(CDI_UUID_SIZE)
+		interface
+			subroutine lib_zaxisDefUUID(zaxisID_dummy, uuid_dummy) bind(c, name = 'zaxisDefUUID')
+				import c_char, c_int
+				integer(c_int), value :: zaxisID_dummy
+				character(kind = c_char), intent(in) :: uuid_dummy(*)
+			end subroutine lib_zaxisDefUUID
+		end interface
+		call lib_zaxisDefUUID(zaxisID_dummy, uuid_dummy)
+	end subroutine zaxisDefUUID
+
+	subroutine zaxisInqUUID(zaxisID_dummy, uuid_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		character(kind = c_char), intent(inout) :: uuid_dummy(CDI_UUID_SIZE)
+		interface
+			subroutine lib_zaxisInqUUID(zaxisID_dummy, uuid_dummy) bind(c, name = 'zaxisInqUUID')
+				import c_char, c_int
+				integer(c_int), value :: zaxisID_dummy
+				character(kind = c_char), intent(inout) :: uuid_dummy(*)
+			end subroutine lib_zaxisInqUUID
+		end interface
+		call lib_zaxisInqUUID(zaxisID_dummy, uuid_dummy)
+	end subroutine zaxisInqUUID
+
+	subroutine zaxisDefName(zaxisID_dummy, name_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		interface
+			subroutine lib_zaxisDefName(zaxisID_dummy, name_dummy) bind(c, name = 'zaxisDefName')
+				import c_char, c_int
+				integer(c_int), value :: zaxisID_dummy
+				character(kind = c_char) :: name_dummy(*)
+			end subroutine lib_zaxisDefName
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		call lib_zaxisDefName(zaxisID_dummy, name_temp)
+	end subroutine zaxisDefName
+
+	subroutine zaxisInqName(zaxisID_dummy, name_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		character(kind = c_char, len = *), intent(inout) :: name_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy))
+		integer :: name_i
+		logical :: name_padding = .true.
+		interface
+			subroutine lib_zaxisInqName(zaxisID_dummy, name_dummy) bind(c, name = 'zaxisInqName')
+				import c_char, c_int
+				integer(c_int), value :: zaxisID_dummy
+				character(kind = c_char) :: name_dummy(*)
+			end subroutine lib_zaxisInqName
+		end interface
+		do name_i = len(name_dummy), 1, -1
+			if(name_dummy(name_i:name_i) /= ' ') name_padding = .false.
+			if(name_padding) then
+				name_temp(name_i) = c_null_char
+			else
+				name_temp(name_i) = name_dummy(name_i:name_i)
+			end if
+		end do
+		call lib_zaxisInqName(zaxisID_dummy, name_temp)
+		name_padding = .false.
+		do name_i = 1, len(name_dummy)
+			if(name_temp(name_i) == c_null_char) name_padding = .true.
+			if(name_padding) then
+				name_dummy(name_i:name_i) = ' '
+			else
+				name_dummy(name_i:name_i) = name_temp(name_i)
+			end if
+		end do
+	end subroutine zaxisInqName
+
+	subroutine zaxisDefLongname(zaxisID_dummy, longname_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		character(kind = c_char, len = *), intent(in) :: longname_dummy
+		character(kind = c_char) :: longname_temp(len(longname_dummy) + 1)
+		integer :: longname_i
+		interface
+			subroutine lib_zaxisDefLongname(zaxisID_dummy, longname_dummy) bind(c, name = 'zaxisDefLongname')
+				import c_char, c_int
+				integer(c_int), value :: zaxisID_dummy
+				character(kind = c_char) :: longname_dummy(*)
+			end subroutine lib_zaxisDefLongname
+		end interface
+		do longname_i = 1, len(longname_dummy)
+		longname_temp(longname_i) = longname_dummy(longname_i:longname_i)
+		end do
+		longname_temp(len(longname_dummy) + 1) = c_null_char
+		call lib_zaxisDefLongname(zaxisID_dummy, longname_temp)
+	end subroutine zaxisDefLongname
+
+	subroutine zaxisInqLongname(zaxisID_dummy, longname_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		character(kind = c_char, len = *), intent(inout) :: longname_dummy
+		character(kind = c_char) :: longname_temp(len(longname_dummy))
+		integer :: longname_i
+		logical :: longname_padding = .true.
+		interface
+			subroutine lib_zaxisInqLongname(zaxisID_dummy, longname_dummy) bind(c, name = 'zaxisInqLongname')
+				import c_char, c_int
+				integer(c_int), value :: zaxisID_dummy
+				character(kind = c_char) :: longname_dummy(*)
+			end subroutine lib_zaxisInqLongname
+		end interface
+		do longname_i = len(longname_dummy), 1, -1
+			if(longname_dummy(longname_i:longname_i) /= ' ') longname_padding = .false.
+			if(longname_padding) then
+				longname_temp(longname_i) = c_null_char
+			else
+				longname_temp(longname_i) = longname_dummy(longname_i:longname_i)
+			end if
+		end do
+		call lib_zaxisInqLongname(zaxisID_dummy, longname_temp)
+		longname_padding = .false.
+		do longname_i = 1, len(longname_dummy)
+			if(longname_temp(longname_i) == c_null_char) longname_padding = .true.
+			if(longname_padding) then
+				longname_dummy(longname_i:longname_i) = ' '
+			else
+				longname_dummy(longname_i:longname_i) = longname_temp(longname_i)
+			end if
+		end do
+	end subroutine zaxisInqLongname
+
+	subroutine zaxisDefUnits(zaxisID_dummy, units_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		character(kind = c_char, len = *), intent(in) :: units_dummy
+		character(kind = c_char) :: units_temp(len(units_dummy) + 1)
+		integer :: units_i
+		interface
+			subroutine lib_zaxisDefUnits(zaxisID_dummy, units_dummy) bind(c, name = 'zaxisDefUnits')
+				import c_char, c_int
+				integer(c_int), value :: zaxisID_dummy
+				character(kind = c_char) :: units_dummy(*)
+			end subroutine lib_zaxisDefUnits
+		end interface
+		do units_i = 1, len(units_dummy)
+		units_temp(units_i) = units_dummy(units_i:units_i)
+		end do
+		units_temp(len(units_dummy) + 1) = c_null_char
+		call lib_zaxisDefUnits(zaxisID_dummy, units_temp)
+	end subroutine zaxisDefUnits
+
+	subroutine zaxisInqUnits(zaxisID_dummy, units_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		character(kind = c_char, len = *), intent(inout) :: units_dummy
+		character(kind = c_char) :: units_temp(len(units_dummy))
+		integer :: units_i
+		logical :: units_padding = .true.
+		interface
+			subroutine lib_zaxisInqUnits(zaxisID_dummy, units_dummy) bind(c, name = 'zaxisInqUnits')
+				import c_char, c_int
+				integer(c_int), value :: zaxisID_dummy
+				character(kind = c_char) :: units_dummy(*)
+			end subroutine lib_zaxisInqUnits
+		end interface
+		do units_i = len(units_dummy), 1, -1
+			if(units_dummy(units_i:units_i) /= ' ') units_padding = .false.
+			if(units_padding) then
+				units_temp(units_i) = c_null_char
+			else
+				units_temp(units_i) = units_dummy(units_i:units_i)
+			end if
+		end do
+		call lib_zaxisInqUnits(zaxisID_dummy, units_temp)
+		units_padding = .false.
+		do units_i = 1, len(units_dummy)
+			if(units_temp(units_i) == c_null_char) units_padding = .true.
+			if(units_padding) then
+				units_dummy(units_i:units_i) = ' '
+			else
+				units_dummy(units_i:units_i) = units_temp(units_i)
+			end if
+		end do
+	end subroutine zaxisInqUnits
+
+	subroutine zaxisInqStdname(zaxisID_dummy, stdname_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		character(kind = c_char, len = *), intent(inout) :: stdname_dummy
+		character(kind = c_char) :: stdname_temp(len(stdname_dummy))
+		integer :: stdname_i
+		logical :: stdname_padding = .true.
+		interface
+			subroutine lib_zaxisInqStdname(zaxisID_dummy, stdname_dummy) bind(c, name = 'zaxisInqStdname')
+				import c_char, c_int
+				integer(c_int), value :: zaxisID_dummy
+				character(kind = c_char) :: stdname_dummy(*)
+			end subroutine lib_zaxisInqStdname
+		end interface
+		do stdname_i = len(stdname_dummy), 1, -1
+			if(stdname_dummy(stdname_i:stdname_i) /= ' ') stdname_padding = .false.
+			if(stdname_padding) then
+				stdname_temp(stdname_i) = c_null_char
+			else
+				stdname_temp(stdname_i) = stdname_dummy(stdname_i:stdname_i)
+			end if
+		end do
+		call lib_zaxisInqStdname(zaxisID_dummy, stdname_temp)
+		stdname_padding = .false.
+		do stdname_i = 1, len(stdname_dummy)
+			if(stdname_temp(stdname_i) == c_null_char) stdname_padding = .true.
+			if(stdname_padding) then
+				stdname_dummy(stdname_i:stdname_i) = ' '
+			else
+				stdname_dummy(stdname_i:stdname_i) = stdname_temp(stdname_i)
+			end if
+		end do
+	end subroutine zaxisInqStdname
+
+	subroutine zaxisDefPrec(zaxisID_dummy, prec_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		integer(c_int), value :: prec_dummy
+		interface
+			subroutine lib_zaxisDefPrec(zaxisID_dummy, prec_dummy) bind(c, name = 'zaxisDefPrec')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+				integer(c_int), value :: prec_dummy
+			end subroutine lib_zaxisDefPrec
+		end interface
+		call lib_zaxisDefPrec(zaxisID_dummy, prec_dummy)
+	end subroutine zaxisDefPrec
+
+	function zaxisInqPrec(zaxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: zaxisID_dummy
+		interface
+			integer(c_int) function lib_zaxisInqPrec(zaxisID_dummy) bind(c, name = 'zaxisInqPrec')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+			end function lib_zaxisInqPrec
+		end interface
+		result = lib_zaxisInqPrec(zaxisID_dummy)
+	end function zaxisInqPrec
+
+	subroutine zaxisDefPositive(zaxisID_dummy, positive_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		integer(c_int), value :: positive_dummy
+		interface
+			subroutine lib_zaxisDefPositive(zaxisID_dummy, positive_dummy) bind(c, name = 'zaxisDefPositive')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+				integer(c_int), value :: positive_dummy
+			end subroutine lib_zaxisDefPositive
+		end interface
+		call lib_zaxisDefPositive(zaxisID_dummy, positive_dummy)
+	end subroutine zaxisDefPositive
+
+	function zaxisInqPositive(zaxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: zaxisID_dummy
+		interface
+			integer(c_int) function lib_zaxisInqPositive(zaxisID_dummy) bind(c, name = 'zaxisInqPositive')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+			end function lib_zaxisInqPositive
+		end interface
+		result = lib_zaxisInqPositive(zaxisID_dummy)
+	end function zaxisInqPositive
+
+	subroutine zaxisDefLtype(zaxisID_dummy, ltype_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		integer(c_int), value :: ltype_dummy
+		interface
+			subroutine lib_zaxisDefLtype(zaxisID_dummy, ltype_dummy) bind(c, name = 'zaxisDefLtype')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+				integer(c_int), value :: ltype_dummy
+			end subroutine lib_zaxisDefLtype
+		end interface
+		call lib_zaxisDefLtype(zaxisID_dummy, ltype_dummy)
+	end subroutine zaxisDefLtype
+
+	function zaxisInqLtype(zaxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: zaxisID_dummy
+		interface
+			integer(c_int) function lib_zaxisInqLtype(zaxisID_dummy) bind(c, name = 'zaxisInqLtype')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+			end function lib_zaxisInqLtype
+		end interface
+		result = lib_zaxisInqLtype(zaxisID_dummy)
+	end function zaxisInqLtype
+
+	function zaxisInqLevelsPtr(zaxisID_dummy) result(result)
+		type(c_ptr) :: result
+		integer(c_int), value :: zaxisID_dummy
+		interface
+			type(c_ptr) function lib_zaxisInqLevelsPtr(zaxisID_dummy) bind(c, name = 'zaxisInqLevelsPtr')
+				import c_int, c_ptr
+				integer(c_int), value :: zaxisID_dummy
+			end function lib_zaxisInqLevelsPtr
+		end interface
+		result = lib_zaxisInqLevelsPtr(zaxisID_dummy)
+	end function zaxisInqLevelsPtr
+
+	subroutine zaxisDefVct(zaxisID_dummy, size_dummy, vct_vec_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		integer(c_int), value :: size_dummy
+		real(c_double), intent(in) :: vct_vec_dummy(*)
+		interface
+			subroutine lib_zaxisDefVct(zaxisID_dummy, size_dummy, vct_vec_dummy) bind(c, name = 'zaxisDefVct')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				integer(c_int), value :: size_dummy
+				real(c_double), intent(in) :: vct_vec_dummy(*)
+			end subroutine lib_zaxisDefVct
+		end interface
+		call lib_zaxisDefVct(zaxisID_dummy, size_dummy, vct_vec_dummy)
+	end subroutine zaxisDefVct
+
+	subroutine zaxisInqVct(zaxisID_dummy, vct_vec_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		real(c_double), intent(inout) :: vct_vec_dummy(*)
+		interface
+			subroutine lib_zaxisInqVct(zaxisID_dummy, vct_vec_dummy) bind(c, name = 'zaxisInqVct')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				real(c_double), intent(inout) :: vct_vec_dummy(*)
+			end subroutine lib_zaxisInqVct
+		end interface
+		call lib_zaxisInqVct(zaxisID_dummy, vct_vec_dummy)
+	end subroutine zaxisInqVct
+
+	function zaxisInqVctSize(zaxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: zaxisID_dummy
+		interface
+			integer(c_int) function lib_zaxisInqVctSize(zaxisID_dummy) bind(c, name = 'zaxisInqVctSize')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+			end function lib_zaxisInqVctSize
+		end interface
+		result = lib_zaxisInqVctSize(zaxisID_dummy)
+	end function zaxisInqVctSize
+
+	function zaxisInqVctPtr(zaxisID_dummy) result(result)
+		type(c_ptr) :: result
+		integer(c_int), value :: zaxisID_dummy
+		interface
+			type(c_ptr) function lib_zaxisInqVctPtr(zaxisID_dummy) bind(c, name = 'zaxisInqVctPtr')
+				import c_int, c_ptr
+				integer(c_int), value :: zaxisID_dummy
+			end function lib_zaxisInqVctPtr
+		end interface
+		result = lib_zaxisInqVctPtr(zaxisID_dummy)
+	end function zaxisInqVctPtr
+
+	subroutine zaxisDefLbounds(zaxisID_dummy, lbounds_vec_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		real(c_double), intent(in) :: lbounds_vec_dummy(*)
+		interface
+			subroutine lib_zaxisDefLbounds(zaxisID_dummy, lbounds_vec_dummy) bind(c, name = 'zaxisDefLbounds')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				real(c_double), intent(in) :: lbounds_vec_dummy(*)
+			end subroutine lib_zaxisDefLbounds
+		end interface
+		call lib_zaxisDefLbounds(zaxisID_dummy, lbounds_vec_dummy)
+	end subroutine zaxisDefLbounds
+
+	function zaxisInqLbounds(zaxisID_dummy, lbounds_vec_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: zaxisID_dummy
+		real(c_double), intent(inout) :: lbounds_vec_dummy(*)
+		interface
+			integer(c_int) function lib_zaxisInqLbounds(zaxisID_dummy, lbounds_vec_dummy) bind(c, name = 'zaxisInqLbounds')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				real(c_double), intent(inout) :: lbounds_vec_dummy(*)
+			end function lib_zaxisInqLbounds
+		end interface
+		result = lib_zaxisInqLbounds(zaxisID_dummy, lbounds_vec_dummy)
+	end function zaxisInqLbounds
+
+	function zaxisInqLbound(zaxisID_dummy, index_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: zaxisID_dummy
+		integer(c_int), value :: index_dummy
+		interface
+			real(c_double) function lib_zaxisInqLbound(zaxisID_dummy, index_dummy) bind(c, name = 'zaxisInqLbound')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				integer(c_int), value :: index_dummy
+			end function lib_zaxisInqLbound
+		end interface
+		result = lib_zaxisInqLbound(zaxisID_dummy, index_dummy)
+	end function zaxisInqLbound
+
+	subroutine zaxisDefUbounds(zaxisID_dummy, ubounds_vec_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		real(c_double), intent(in) :: ubounds_vec_dummy(*)
+		interface
+			subroutine lib_zaxisDefUbounds(zaxisID_dummy, ubounds_vec_dummy) bind(c, name = 'zaxisDefUbounds')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				real(c_double), intent(in) :: ubounds_vec_dummy(*)
+			end subroutine lib_zaxisDefUbounds
+		end interface
+		call lib_zaxisDefUbounds(zaxisID_dummy, ubounds_vec_dummy)
+	end subroutine zaxisDefUbounds
+
+	function zaxisInqUbounds(zaxisID_dummy, ubounds_vec_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: zaxisID_dummy
+		real(c_double), intent(inout) :: ubounds_vec_dummy(*)
+		interface
+			integer(c_int) function lib_zaxisInqUbounds(zaxisID_dummy, ubounds_vec_dummy) bind(c, name = 'zaxisInqUbounds')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				real(c_double), intent(inout) :: ubounds_vec_dummy(*)
+			end function lib_zaxisInqUbounds
+		end interface
+		result = lib_zaxisInqUbounds(zaxisID_dummy, ubounds_vec_dummy)
+	end function zaxisInqUbounds
+
+	function zaxisInqUbound(zaxisID_dummy, index_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: zaxisID_dummy
+		integer(c_int), value :: index_dummy
+		interface
+			real(c_double) function lib_zaxisInqUbound(zaxisID_dummy, index_dummy) bind(c, name = 'zaxisInqUbound')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				integer(c_int), value :: index_dummy
+			end function lib_zaxisInqUbound
+		end interface
+		result = lib_zaxisInqUbound(zaxisID_dummy, index_dummy)
+	end function zaxisInqUbound
+
+	subroutine zaxisDefWeights(zaxisID_dummy, weights_vec_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		real(c_double), intent(in) :: weights_vec_dummy(*)
+		interface
+			subroutine lib_zaxisDefWeights(zaxisID_dummy, weights_vec_dummy) bind(c, name = 'zaxisDefWeights')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				real(c_double), intent(in) :: weights_vec_dummy(*)
+			end subroutine lib_zaxisDefWeights
+		end interface
+		call lib_zaxisDefWeights(zaxisID_dummy, weights_vec_dummy)
+	end subroutine zaxisDefWeights
+
+	function zaxisInqWeights(zaxisID_dummy, weights_vec_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: zaxisID_dummy
+		real(c_double), intent(inout) :: weights_vec_dummy(*)
+		interface
+			integer(c_int) function lib_zaxisInqWeights(zaxisID_dummy, weights_vec_dummy) bind(c, name = 'zaxisInqWeights')
+				import c_double, c_int
+				integer(c_int), value :: zaxisID_dummy
+				real(c_double), intent(inout) :: weights_vec_dummy(*)
+			end function lib_zaxisInqWeights
+		end interface
+		result = lib_zaxisInqWeights(zaxisID_dummy, weights_vec_dummy)
+	end function zaxisInqWeights
+
+	subroutine zaxisChangeType(zaxisID_dummy, zaxistype_dummy)
+		integer(c_int), value :: zaxisID_dummy
+		integer(c_int), value :: zaxistype_dummy
+		interface
+			subroutine lib_zaxisChangeType(zaxisID_dummy, zaxistype_dummy) bind(c, name = 'zaxisChangeType')
+				import c_int
+				integer(c_int), value :: zaxisID_dummy
+				integer(c_int), value :: zaxistype_dummy
+			end subroutine lib_zaxisChangeType
+		end interface
+		call lib_zaxisChangeType(zaxisID_dummy, zaxistype_dummy)
+	end subroutine zaxisChangeType
+
+	function taxisCreate(timetype_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: timetype_dummy
+		interface
+			integer(c_int) function lib_taxisCreate(timetype_dummy) bind(c, name = 'taxisCreate')
+				import c_int
+				integer(c_int), value :: timetype_dummy
+			end function lib_taxisCreate
+		end interface
+		result = lib_taxisCreate(timetype_dummy)
+	end function taxisCreate
+
+	subroutine taxisDestroy(taxisID_dummy)
+		integer(c_int), value :: taxisID_dummy
+		interface
+			subroutine lib_taxisDestroy(taxisID_dummy) bind(c, name = 'taxisDestroy')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end subroutine lib_taxisDestroy
+		end interface
+		call lib_taxisDestroy(taxisID_dummy)
+	end subroutine taxisDestroy
+
+	function taxisDuplicate(taxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			integer(c_int) function lib_taxisDuplicate(taxisID_dummy) bind(c, name = 'taxisDuplicate')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisDuplicate
+		end interface
+		result = lib_taxisDuplicate(taxisID_dummy)
+	end function taxisDuplicate
+
+	subroutine taxisCopyTimestep(taxisIDdes_dummy, taxisIDsrc_dummy)
+		integer(c_int), value :: taxisIDdes_dummy
+		integer(c_int), value :: taxisIDsrc_dummy
+		interface
+			subroutine lib_taxisCopyTimestep(taxisIDdes_dummy, taxisIDsrc_dummy) bind(c, name = 'taxisCopyTimestep')
+				import c_int
+				integer(c_int), value :: taxisIDdes_dummy
+				integer(c_int), value :: taxisIDsrc_dummy
+			end subroutine lib_taxisCopyTimestep
+		end interface
+		call lib_taxisCopyTimestep(taxisIDdes_dummy, taxisIDsrc_dummy)
+	end subroutine taxisCopyTimestep
+
+	subroutine taxisDefType(taxisID_dummy, type_dummy)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), value :: type_dummy
+		interface
+			subroutine lib_taxisDefType(taxisID_dummy, type_dummy) bind(c, name = 'taxisDefType')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+				integer(c_int), value :: type_dummy
+			end subroutine lib_taxisDefType
+		end interface
+		call lib_taxisDefType(taxisID_dummy, type_dummy)
+	end subroutine taxisDefType
+
+	subroutine taxisDefVdate(taxisID_dummy, date_dummy)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), value :: date_dummy
+		interface
+			subroutine lib_taxisDefVdate(taxisID_dummy, date_dummy) bind(c, name = 'taxisDefVdate')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+				integer(c_int), value :: date_dummy
+			end subroutine lib_taxisDefVdate
+		end interface
+		call lib_taxisDefVdate(taxisID_dummy, date_dummy)
+	end subroutine taxisDefVdate
+
+	subroutine taxisDefVtime(taxisID_dummy, time_dummy)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), value :: time_dummy
+		interface
+			subroutine lib_taxisDefVtime(taxisID_dummy, time_dummy) bind(c, name = 'taxisDefVtime')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+				integer(c_int), value :: time_dummy
+			end subroutine lib_taxisDefVtime
+		end interface
+		call lib_taxisDefVtime(taxisID_dummy, time_dummy)
+	end subroutine taxisDefVtime
+
+	function taxisInqVdate(taxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			integer(c_int) function lib_taxisInqVdate(taxisID_dummy) bind(c, name = 'taxisInqVdate')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisInqVdate
+		end interface
+		result = lib_taxisInqVdate(taxisID_dummy)
+	end function taxisInqVdate
+
+	function taxisInqVtime(taxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			integer(c_int) function lib_taxisInqVtime(taxisID_dummy) bind(c, name = 'taxisInqVtime')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisInqVtime
+		end interface
+		result = lib_taxisInqVtime(taxisID_dummy)
+	end function taxisInqVtime
+
+	subroutine taxisDefRdate(taxisID_dummy, date_dummy)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), value :: date_dummy
+		interface
+			subroutine lib_taxisDefRdate(taxisID_dummy, date_dummy) bind(c, name = 'taxisDefRdate')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+				integer(c_int), value :: date_dummy
+			end subroutine lib_taxisDefRdate
+		end interface
+		call lib_taxisDefRdate(taxisID_dummy, date_dummy)
+	end subroutine taxisDefRdate
+
+	subroutine taxisDefRtime(taxisID_dummy, time_dummy)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), value :: time_dummy
+		interface
+			subroutine lib_taxisDefRtime(taxisID_dummy, time_dummy) bind(c, name = 'taxisDefRtime')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+				integer(c_int), value :: time_dummy
+			end subroutine lib_taxisDefRtime
+		end interface
+		call lib_taxisDefRtime(taxisID_dummy, time_dummy)
+	end subroutine taxisDefRtime
+
+	function taxisInqRdate(taxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			integer(c_int) function lib_taxisInqRdate(taxisID_dummy) bind(c, name = 'taxisInqRdate')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisInqRdate
+		end interface
+		result = lib_taxisInqRdate(taxisID_dummy)
+	end function taxisInqRdate
+
+	function taxisInqRtime(taxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			integer(c_int) function lib_taxisInqRtime(taxisID_dummy) bind(c, name = 'taxisInqRtime')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisInqRtime
+		end interface
+		result = lib_taxisInqRtime(taxisID_dummy)
+	end function taxisInqRtime
+
+	subroutine taxisDefFdate(taxisID_dummy, date_dummy)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), value :: date_dummy
+		interface
+			subroutine lib_taxisDefFdate(taxisID_dummy, date_dummy) bind(c, name = 'taxisDefFdate')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+				integer(c_int), value :: date_dummy
+			end subroutine lib_taxisDefFdate
+		end interface
+		call lib_taxisDefFdate(taxisID_dummy, date_dummy)
+	end subroutine taxisDefFdate
+
+	subroutine taxisDefFtime(taxisID_dummy, time_dummy)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), value :: time_dummy
+		interface
+			subroutine lib_taxisDefFtime(taxisID_dummy, time_dummy) bind(c, name = 'taxisDefFtime')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+				integer(c_int), value :: time_dummy
+			end subroutine lib_taxisDefFtime
+		end interface
+		call lib_taxisDefFtime(taxisID_dummy, time_dummy)
+	end subroutine taxisDefFtime
+
+	function taxisInqFdate(taxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			integer(c_int) function lib_taxisInqFdate(taxisID_dummy) bind(c, name = 'taxisInqFdate')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisInqFdate
+		end interface
+		result = lib_taxisInqFdate(taxisID_dummy)
+	end function taxisInqFdate
+
+	function taxisInqFtime(taxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			integer(c_int) function lib_taxisInqFtime(taxisID_dummy) bind(c, name = 'taxisInqFtime')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisInqFtime
+		end interface
+		result = lib_taxisInqFtime(taxisID_dummy)
+	end function taxisInqFtime
+
+	function taxisHasBounds(taxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			integer(c_int) function lib_taxisHasBounds(taxisID_dummy) bind(c, name = 'taxisHasBounds')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisHasBounds
+		end interface
+		result = lib_taxisHasBounds(taxisID_dummy)
+	end function taxisHasBounds
+
+	subroutine taxisDeleteBounds(taxisID_dummy)
+		integer(c_int), value :: taxisID_dummy
+		interface
+			subroutine lib_taxisDeleteBounds(taxisID_dummy) bind(c, name = 'taxisDeleteBounds')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end subroutine lib_taxisDeleteBounds
+		end interface
+		call lib_taxisDeleteBounds(taxisID_dummy)
+	end subroutine taxisDeleteBounds
+
+	subroutine taxisDefVdateBounds(taxisID_dummy, vdate_lb_dummy, vdate_ub_dummy)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), value :: vdate_lb_dummy
+		integer(c_int), value :: vdate_ub_dummy
+		interface
+			subroutine lib_taxisDefVdateBounds(taxisID_dummy, vdate_lb_dummy, vdate_ub_dummy) bind(c, name = 'taxisDefVdateBounds')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+				integer(c_int), value :: vdate_lb_dummy
+				integer(c_int), value :: vdate_ub_dummy
+			end subroutine lib_taxisDefVdateBounds
+		end interface
+		call lib_taxisDefVdateBounds(taxisID_dummy, vdate_lb_dummy, vdate_ub_dummy)
+	end subroutine taxisDefVdateBounds
+
+	subroutine taxisDefVtimeBounds(taxisID_dummy, vtime_lb_dummy, vtime_ub_dummy)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), value :: vtime_lb_dummy
+		integer(c_int), value :: vtime_ub_dummy
+		interface
+			subroutine lib_taxisDefVtimeBounds(taxisID_dummy, vtime_lb_dummy, vtime_ub_dummy) bind(c, name = 'taxisDefVtimeBounds')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+				integer(c_int), value :: vtime_lb_dummy
+				integer(c_int), value :: vtime_ub_dummy
+			end subroutine lib_taxisDefVtimeBounds
+		end interface
+		call lib_taxisDefVtimeBounds(taxisID_dummy, vtime_lb_dummy, vtime_ub_dummy)
+	end subroutine taxisDefVtimeBounds
+
+	subroutine taxisInqVdateBounds(taxisID_dummy, vdate_lb, vdate_ub)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), optional, intent(inout) :: vdate_lb
+		integer(c_int), optional, intent(inout) :: vdate_ub
+		integer(c_int), target :: vdate_lb_temp
+		type(c_ptr) :: vdate_lb_ptr
+		integer(c_int), target :: vdate_ub_temp
+		type(c_ptr) :: vdate_ub_ptr
+		interface
+			subroutine lib_taxisInqVdateBounds(taxisID_dummy, vdate_lb, vdate_ub) bind(c, name = 'taxisInqVdateBounds')
+				import c_int, c_ptr
+				integer(c_int), value :: taxisID_dummy
+				type(c_ptr), value :: vdate_lb
+				type(c_ptr), value :: vdate_ub
+			end subroutine lib_taxisInqVdateBounds
+		end interface
+		vdate_lb_ptr = c_null_ptr
+		if(present(vdate_lb)) vdate_lb_ptr = c_loc(vdate_lb_temp)
+		vdate_ub_ptr = c_null_ptr
+		if(present(vdate_ub)) vdate_ub_ptr = c_loc(vdate_ub_temp)
+		call lib_taxisInqVdateBounds(taxisID_dummy, vdate_lb_ptr, vdate_ub_ptr)
+		if(present(vdate_lb)) vdate_lb = vdate_lb_temp
+		if(present(vdate_ub)) vdate_ub = vdate_ub_temp
+	end subroutine taxisInqVdateBounds
+
+	subroutine taxisInqVtimeBounds(taxisID_dummy, vtime_lb, vtime_ub)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), optional, intent(inout) :: vtime_lb
+		integer(c_int), optional, intent(inout) :: vtime_ub
+		integer(c_int), target :: vtime_lb_temp
+		type(c_ptr) :: vtime_lb_ptr
+		integer(c_int), target :: vtime_ub_temp
+		type(c_ptr) :: vtime_ub_ptr
+		interface
+			subroutine lib_taxisInqVtimeBounds(taxisID_dummy, vtime_lb, vtime_ub) bind(c, name = 'taxisInqVtimeBounds')
+				import c_int, c_ptr
+				integer(c_int), value :: taxisID_dummy
+				type(c_ptr), value :: vtime_lb
+				type(c_ptr), value :: vtime_ub
+			end subroutine lib_taxisInqVtimeBounds
+		end interface
+		vtime_lb_ptr = c_null_ptr
+		if(present(vtime_lb)) vtime_lb_ptr = c_loc(vtime_lb_temp)
+		vtime_ub_ptr = c_null_ptr
+		if(present(vtime_ub)) vtime_ub_ptr = c_loc(vtime_ub_temp)
+		call lib_taxisInqVtimeBounds(taxisID_dummy, vtime_lb_ptr, vtime_ub_ptr)
+		if(present(vtime_lb)) vtime_lb = vtime_lb_temp
+		if(present(vtime_ub)) vtime_ub = vtime_ub_temp
+	end subroutine taxisInqVtimeBounds
+
+	subroutine taxisDefCalendar(taxisID_dummy, calendar_dummy)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), value :: calendar_dummy
+		interface
+			subroutine lib_taxisDefCalendar(taxisID_dummy, calendar_dummy) bind(c, name = 'taxisDefCalendar')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+				integer(c_int), value :: calendar_dummy
+			end subroutine lib_taxisDefCalendar
+		end interface
+		call lib_taxisDefCalendar(taxisID_dummy, calendar_dummy)
+	end subroutine taxisDefCalendar
+
+	function taxisInqCalendar(taxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			integer(c_int) function lib_taxisInqCalendar(taxisID_dummy) bind(c, name = 'taxisInqCalendar')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisInqCalendar
+		end interface
+		result = lib_taxisInqCalendar(taxisID_dummy)
+	end function taxisInqCalendar
+
+	subroutine taxisDefTunit(taxisID_dummy, tunit_dummy)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), value :: tunit_dummy
+		interface
+			subroutine lib_taxisDefTunit(taxisID_dummy, tunit_dummy) bind(c, name = 'taxisDefTunit')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+				integer(c_int), value :: tunit_dummy
+			end subroutine lib_taxisDefTunit
+		end interface
+		call lib_taxisDefTunit(taxisID_dummy, tunit_dummy)
+	end subroutine taxisDefTunit
+
+	function taxisInqTunit(taxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			integer(c_int) function lib_taxisInqTunit(taxisID_dummy) bind(c, name = 'taxisInqTunit')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisInqTunit
+		end interface
+		result = lib_taxisInqTunit(taxisID_dummy)
+	end function taxisInqTunit
+
+	subroutine taxisDefForecastTunit(taxisID_dummy, tunit_dummy)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), value :: tunit_dummy
+		interface
+			subroutine lib_taxisDefForecastTunit(taxisID_dummy, tunit_dummy) bind(c, name = 'taxisDefForecastTunit')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+				integer(c_int), value :: tunit_dummy
+			end subroutine lib_taxisDefForecastTunit
+		end interface
+		call lib_taxisDefForecastTunit(taxisID_dummy, tunit_dummy)
+	end subroutine taxisDefForecastTunit
+
+	function taxisInqForecastTunit(taxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			integer(c_int) function lib_taxisInqForecastTunit(taxisID_dummy) bind(c, name = 'taxisInqForecastTunit')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisInqForecastTunit
+		end interface
+		result = lib_taxisInqForecastTunit(taxisID_dummy)
+	end function taxisInqForecastTunit
+
+	subroutine taxisDefForecastPeriod(taxisID_dummy, fc_period_dummy)
+		integer(c_int), value :: taxisID_dummy
+		real(c_double), value :: fc_period_dummy
+		interface
+			subroutine lib_taxisDefForecastPeriod(taxisID_dummy, fc_period_dummy) bind(c, name = 'taxisDefForecastPeriod')
+				import c_double, c_int
+				integer(c_int), value :: taxisID_dummy
+				real(c_double), value :: fc_period_dummy
+			end subroutine lib_taxisDefForecastPeriod
+		end interface
+		call lib_taxisDefForecastPeriod(taxisID_dummy, fc_period_dummy)
+	end subroutine taxisDefForecastPeriod
+
+	function taxisInqForecastPeriod(taxisID_dummy) result(result)
+		real(c_double) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			real(c_double) function lib_taxisInqForecastPeriod(taxisID_dummy) bind(c, name = 'taxisInqForecastPeriod')
+				import c_double, c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisInqForecastPeriod
+		end interface
+		result = lib_taxisInqForecastPeriod(taxisID_dummy)
+	end function taxisInqForecastPeriod
+
+	subroutine taxisDefNumavg(taxisID_dummy, numavg_dummy)
+		integer(c_int), value :: taxisID_dummy
+		integer(c_int), value :: numavg_dummy
+		interface
+			subroutine lib_taxisDefNumavg(taxisID_dummy, numavg_dummy) bind(c, name = 'taxisDefNumavg')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+				integer(c_int), value :: numavg_dummy
+			end subroutine lib_taxisDefNumavg
+		end interface
+		call lib_taxisDefNumavg(taxisID_dummy, numavg_dummy)
+	end subroutine taxisDefNumavg
+
+	function taxisInqType(taxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			integer(c_int) function lib_taxisInqType(taxisID_dummy) bind(c, name = 'taxisInqType')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisInqType
+		end interface
+		result = lib_taxisInqType(taxisID_dummy)
+	end function taxisInqType
+
+	function taxisInqNumavg(taxisID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: taxisID_dummy
+		interface
+			integer(c_int) function lib_taxisInqNumavg(taxisID_dummy) bind(c, name = 'taxisInqNumavg')
+				import c_int
+				integer(c_int), value :: taxisID_dummy
+			end function lib_taxisInqNumavg
+		end interface
+		result = lib_taxisInqNumavg(taxisID_dummy)
+	end function taxisInqNumavg
+
+	function tunitNamePtr(tunitID_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		integer(c_int), value :: tunitID_dummy
+		type(c_ptr) :: ptr
+		integer :: shape(1)
+		interface
+			type(c_ptr) function lib_tunitNamePtr(tunitID_dummy) bind(c, name = 'tunitNamePtr')
+				import c_int, c_ptr
+				integer(c_int), value :: tunitID_dummy
+			end function lib_tunitNamePtr
+		end interface
+		result => null()
+		ptr = lib_tunitNamePtr(tunitID_dummy)
+		if(c_associated(ptr)) then
+			shape(1) = int(lib_strlen(ptr))
+			call c_f_pointer(ptr, result, shape)
+		end if
+	end function tunitNamePtr
+
+	function institutDef(center_dummy, subcenter_dummy, name_dummy, longname_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: center_dummy
+		integer(c_int), value :: subcenter_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		character(kind = c_char, len = *), intent(in) :: longname_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		character(kind = c_char) :: longname_temp(len(longname_dummy) + 1)
+		integer :: longname_i
+		interface
+			integer(c_int) function lib_institutDef(center_dummy, subcenter_dummy, name_dummy, longname_dummy) bind(c, name = 'institutDef')
+				import c_char, c_int
+				integer(c_int), value :: center_dummy
+				integer(c_int), value :: subcenter_dummy
+				character(kind = c_char) :: name_dummy(*)
+				character(kind = c_char) :: longname_dummy(*)
+			end function lib_institutDef
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		do longname_i = 1, len(longname_dummy)
+		longname_temp(longname_i) = longname_dummy(longname_i:longname_i)
+		end do
+		longname_temp(len(longname_dummy) + 1) = c_null_char
+		result = lib_institutDef(center_dummy, subcenter_dummy, name_temp, longname_temp)
+	end function institutDef
+
+	function institutInq(center_dummy, subcenter_dummy, name_dummy, longname_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: center_dummy
+		integer(c_int), value :: subcenter_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		character(kind = c_char, len = *), intent(in) :: longname_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		character(kind = c_char) :: longname_temp(len(longname_dummy) + 1)
+		integer :: longname_i
+		interface
+			integer(c_int) function lib_institutInq(center_dummy, subcenter_dummy, name_dummy, longname_dummy) bind(c, name = 'institutInq')
+				import c_char, c_int
+				integer(c_int), value :: center_dummy
+				integer(c_int), value :: subcenter_dummy
+				character(kind = c_char) :: name_dummy(*)
+				character(kind = c_char) :: longname_dummy(*)
+			end function lib_institutInq
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		do longname_i = 1, len(longname_dummy)
+		longname_temp(longname_i) = longname_dummy(longname_i:longname_i)
+		end do
+		longname_temp(len(longname_dummy) + 1) = c_null_char
+		result = lib_institutInq(center_dummy, subcenter_dummy, name_temp, longname_temp)
+	end function institutInq
+
+	function institutInqNumber() result(result)
+		integer(c_int) :: result
+		interface
+			integer(c_int) function lib_institutInqNumber() bind(c, name = 'institutInqNumber')
+				import c_int
+			end function lib_institutInqNumber
+		end interface
+		result = lib_institutInqNumber()
+	end function institutInqNumber
+
+	function institutInqCenter(instID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: instID_dummy
+		interface
+			integer(c_int) function lib_institutInqCenter(instID_dummy) bind(c, name = 'institutInqCenter')
+				import c_int
+				integer(c_int), value :: instID_dummy
+			end function lib_institutInqCenter
+		end interface
+		result = lib_institutInqCenter(instID_dummy)
+	end function institutInqCenter
+
+	function institutInqSubcenter(instID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: instID_dummy
+		interface
+			integer(c_int) function lib_institutInqSubcenter(instID_dummy) bind(c, name = 'institutInqSubcenter')
+				import c_int
+				integer(c_int), value :: instID_dummy
+			end function lib_institutInqSubcenter
+		end interface
+		result = lib_institutInqSubcenter(instID_dummy)
+	end function institutInqSubcenter
+
+	function institutInqNamePtr(instID_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		integer(c_int), value :: instID_dummy
+		type(c_ptr) :: ptr
+		integer :: shape(1)
+		interface
+			type(c_ptr) function lib_institutInqNamePtr(instID_dummy) bind(c, name = 'institutInqNamePtr')
+				import c_int, c_ptr
+				integer(c_int), value :: instID_dummy
+			end function lib_institutInqNamePtr
+		end interface
+		result => null()
+		ptr = lib_institutInqNamePtr(instID_dummy)
+		if(c_associated(ptr)) then
+			shape(1) = int(lib_strlen(ptr))
+			call c_f_pointer(ptr, result, shape)
+		end if
+	end function institutInqNamePtr
+
+	function institutInqLongnamePtr(instID_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		integer(c_int), value :: instID_dummy
+		type(c_ptr) :: ptr
+		integer :: shape(1)
+		interface
+			type(c_ptr) function lib_institutInqLongnamePtr(instID_dummy) bind(c, name = 'institutInqLongnamePtr')
+				import c_int, c_ptr
+				integer(c_int), value :: instID_dummy
+			end function lib_institutInqLongnamePtr
+		end interface
+		result => null()
+		ptr = lib_institutInqLongnamePtr(instID_dummy)
+		if(c_associated(ptr)) then
+			shape(1) = int(lib_strlen(ptr))
+			call c_f_pointer(ptr, result, shape)
+		end if
+	end function institutInqLongnamePtr
+
+	function modelDef(instID_dummy, modelgribID_dummy, name_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: instID_dummy
+		integer(c_int), value :: modelgribID_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		interface
+			integer(c_int) function lib_modelDef(instID_dummy, modelgribID_dummy, name_dummy) bind(c, name = 'modelDef')
+				import c_char, c_int
+				integer(c_int), value :: instID_dummy
+				integer(c_int), value :: modelgribID_dummy
+				character(kind = c_char) :: name_dummy(*)
+			end function lib_modelDef
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		result = lib_modelDef(instID_dummy, modelgribID_dummy, name_temp)
+	end function modelDef
+
+	function modelInq(instID_dummy, modelgribID_dummy, name_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: instID_dummy
+		integer(c_int), value :: modelgribID_dummy
+		character(kind = c_char, len = *), intent(inout) :: name_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy))
+		integer :: name_i
+		logical :: name_padding = .true.
+		interface
+			integer(c_int) function lib_modelInq(instID_dummy, modelgribID_dummy, name_dummy) bind(c, name = 'modelInq')
+				import c_char, c_int
+				integer(c_int), value :: instID_dummy
+				integer(c_int), value :: modelgribID_dummy
+				character(kind = c_char) :: name_dummy(*)
+			end function lib_modelInq
+		end interface
+		do name_i = len(name_dummy), 1, -1
+			if(name_dummy(name_i:name_i) /= ' ') name_padding = .false.
+			if(name_padding) then
+				name_temp(name_i) = c_null_char
+			else
+				name_temp(name_i) = name_dummy(name_i:name_i)
+			end if
+		end do
+		result = lib_modelInq(instID_dummy, modelgribID_dummy, name_temp)
+		name_padding = .false.
+		do name_i = 1, len(name_dummy)
+			if(name_temp(name_i) == c_null_char) name_padding = .true.
+			if(name_padding) then
+				name_dummy(name_i:name_i) = ' '
+			else
+				name_dummy(name_i:name_i) = name_temp(name_i)
+			end if
+		end do
+	end function modelInq
+
+	function modelInqInstitut(modelID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: modelID_dummy
+		interface
+			integer(c_int) function lib_modelInqInstitut(modelID_dummy) bind(c, name = 'modelInqInstitut')
+				import c_int
+				integer(c_int), value :: modelID_dummy
+			end function lib_modelInqInstitut
+		end interface
+		result = lib_modelInqInstitut(modelID_dummy)
+	end function modelInqInstitut
+
+	function modelInqGribID(modelID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: modelID_dummy
+		interface
+			integer(c_int) function lib_modelInqGribID(modelID_dummy) bind(c, name = 'modelInqGribID')
+				import c_int
+				integer(c_int), value :: modelID_dummy
+			end function lib_modelInqGribID
+		end interface
+		result = lib_modelInqGribID(modelID_dummy)
+	end function modelInqGribID
+
+	function modelInqNamePtr(modelID_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		integer(c_int), value :: modelID_dummy
+		type(c_ptr) :: ptr
+		integer :: shape(1)
+		interface
+			type(c_ptr) function lib_modelInqNamePtr(modelID_dummy) bind(c, name = 'modelInqNamePtr')
+				import c_int, c_ptr
+				integer(c_int), value :: modelID_dummy
+			end function lib_modelInqNamePtr
+		end interface
+		result => null()
+		ptr = lib_modelInqNamePtr(modelID_dummy)
+		if(c_associated(ptr)) then
+			shape(1) = int(lib_strlen(ptr))
+			call c_f_pointer(ptr, result, shape)
+		end if
+	end function modelInqNamePtr
+
+	subroutine tableWriteC(filename_dummy, tableID_dummy)
+		character(kind = c_char, len = *), intent(in) :: filename_dummy
+		integer(c_int), value :: tableID_dummy
+		character(kind = c_char) :: filename_temp(len(filename_dummy) + 1)
+		integer :: filename_i
+		interface
+			subroutine lib_tableWriteC(filename_dummy, tableID_dummy) bind(c, name = 'tableWriteC')
+				import c_char, c_int
+				character(kind = c_char) :: filename_dummy(*)
+				integer(c_int), value :: tableID_dummy
+			end subroutine lib_tableWriteC
+		end interface
+		do filename_i = 1, len(filename_dummy)
+		filename_temp(filename_i) = filename_dummy(filename_i:filename_i)
+		end do
+		filename_temp(len(filename_dummy) + 1) = c_null_char
+		call lib_tableWriteC(filename_temp, tableID_dummy)
+	end subroutine tableWriteC
+
+	subroutine tableWrite(filename_dummy, tableID_dummy)
+		character(kind = c_char, len = *), intent(in) :: filename_dummy
+		integer(c_int), value :: tableID_dummy
+		character(kind = c_char) :: filename_temp(len(filename_dummy) + 1)
+		integer :: filename_i
+		interface
+			subroutine lib_tableWrite(filename_dummy, tableID_dummy) bind(c, name = 'tableWrite')
+				import c_char, c_int
+				character(kind = c_char) :: filename_dummy(*)
+				integer(c_int), value :: tableID_dummy
+			end subroutine lib_tableWrite
+		end interface
+		do filename_i = 1, len(filename_dummy)
+		filename_temp(filename_i) = filename_dummy(filename_i:filename_i)
+		end do
+		filename_temp(len(filename_dummy) + 1) = c_null_char
+		call lib_tableWrite(filename_temp, tableID_dummy)
+	end subroutine tableWrite
+
+	function tableRead(tablefile_dummy) result(result)
+		integer(c_int) :: result
+		character(kind = c_char, len = *), intent(in) :: tablefile_dummy
+		character(kind = c_char) :: tablefile_temp(len(tablefile_dummy) + 1)
+		integer :: tablefile_i
+		interface
+			integer(c_int) function lib_tableRead(tablefile_dummy) bind(c, name = 'tableRead')
+				import c_char, c_int
+				character(kind = c_char) :: tablefile_dummy(*)
+			end function lib_tableRead
+		end interface
+		do tablefile_i = 1, len(tablefile_dummy)
+		tablefile_temp(tablefile_i) = tablefile_dummy(tablefile_i:tablefile_i)
+		end do
+		tablefile_temp(len(tablefile_dummy) + 1) = c_null_char
+		result = lib_tableRead(tablefile_temp)
+	end function tableRead
+
+	function tableDef(modelID_dummy, tablenum_dummy, tablename_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: modelID_dummy
+		integer(c_int), value :: tablenum_dummy
+		character(kind = c_char, len = *), intent(in) :: tablename_dummy
+		character(kind = c_char) :: tablename_temp(len(tablename_dummy) + 1)
+		integer :: tablename_i
+		interface
+			integer(c_int) function lib_tableDef(modelID_dummy, tablenum_dummy, tablename_dummy) bind(c, name = 'tableDef')
+				import c_char, c_int
+				integer(c_int), value :: modelID_dummy
+				integer(c_int), value :: tablenum_dummy
+				character(kind = c_char) :: tablename_dummy(*)
+			end function lib_tableDef
+		end interface
+		do tablename_i = 1, len(tablename_dummy)
+		tablename_temp(tablename_i) = tablename_dummy(tablename_i:tablename_i)
+		end do
+		tablename_temp(len(tablename_dummy) + 1) = c_null_char
+		result = lib_tableDef(modelID_dummy, tablenum_dummy, tablename_temp)
+	end function tableDef
+
+	function tableInqNamePtr(tableID_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		integer(c_int), value :: tableID_dummy
+		type(c_ptr) :: ptr
+		integer :: shape(1)
+		interface
+			type(c_ptr) function lib_tableInqNamePtr(tableID_dummy) bind(c, name = 'tableInqNamePtr')
+				import c_int, c_ptr
+				integer(c_int), value :: tableID_dummy
+			end function lib_tableInqNamePtr
+		end interface
+		result => null()
+		ptr = lib_tableInqNamePtr(tableID_dummy)
+		if(c_associated(ptr)) then
+			shape(1) = int(lib_strlen(ptr))
+			call c_f_pointer(ptr, result, shape)
+		end if
+	end function tableInqNamePtr
+
+	subroutine tableDefEntry(tableID_dummy, code_dummy, name_dummy, longname_dummy, units_dummy)
+		integer(c_int), value :: tableID_dummy
+		integer(c_int), value :: code_dummy
+		character(kind = c_char, len = *), intent(in) :: name_dummy
+		character(kind = c_char, len = *), intent(in) :: longname_dummy
+		character(kind = c_char, len = *), intent(in) :: units_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy) + 1)
+		integer :: name_i
+		character(kind = c_char) :: longname_temp(len(longname_dummy) + 1)
+		integer :: longname_i
+		character(kind = c_char) :: units_temp(len(units_dummy) + 1)
+		integer :: units_i
+		interface
+			subroutine lib_tableDefEntry(tableID_dummy, code_dummy, name_dummy, longname_dummy, units_dummy) bind(c, name = 'tableDefEntry')
+				import c_char, c_int
+				integer(c_int), value :: tableID_dummy
+				integer(c_int), value :: code_dummy
+				character(kind = c_char) :: name_dummy(*)
+				character(kind = c_char) :: longname_dummy(*)
+				character(kind = c_char) :: units_dummy(*)
+			end subroutine lib_tableDefEntry
+		end interface
+		do name_i = 1, len(name_dummy)
+		name_temp(name_i) = name_dummy(name_i:name_i)
+		end do
+		name_temp(len(name_dummy) + 1) = c_null_char
+		do longname_i = 1, len(longname_dummy)
+		longname_temp(longname_i) = longname_dummy(longname_i:longname_i)
+		end do
+		longname_temp(len(longname_dummy) + 1) = c_null_char
+		do units_i = 1, len(units_dummy)
+		units_temp(units_i) = units_dummy(units_i:units_i)
+		end do
+		units_temp(len(units_dummy) + 1) = c_null_char
+		call lib_tableDefEntry(tableID_dummy, code_dummy, name_temp, longname_temp, units_temp)
+	end subroutine tableDefEntry
+
+	function tableInq(modelID_dummy, tablenum_dummy, tablename_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: modelID_dummy
+		integer(c_int), value :: tablenum_dummy
+		character(kind = c_char, len = *), intent(in) :: tablename_dummy
+		character(kind = c_char) :: tablename_temp(len(tablename_dummy) + 1)
+		integer :: tablename_i
+		interface
+			integer(c_int) function lib_tableInq(modelID_dummy, tablenum_dummy, tablename_dummy) bind(c, name = 'tableInq')
+				import c_char, c_int
+				integer(c_int), value :: modelID_dummy
+				integer(c_int), value :: tablenum_dummy
+				character(kind = c_char) :: tablename_dummy(*)
+			end function lib_tableInq
+		end interface
+		do tablename_i = 1, len(tablename_dummy)
+		tablename_temp(tablename_i) = tablename_dummy(tablename_i:tablename_i)
+		end do
+		tablename_temp(len(tablename_dummy) + 1) = c_null_char
+		result = lib_tableInq(modelID_dummy, tablenum_dummy, tablename_temp)
+	end function tableInq
+
+	function tableInqNumber() result(result)
+		integer(c_int) :: result
+		interface
+			integer(c_int) function lib_tableInqNumber() bind(c, name = 'tableInqNumber')
+				import c_int
+			end function lib_tableInqNumber
+		end interface
+		result = lib_tableInqNumber()
+	end function tableInqNumber
+
+	function tableInqNum(tableID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: tableID_dummy
+		interface
+			integer(c_int) function lib_tableInqNum(tableID_dummy) bind(c, name = 'tableInqNum')
+				import c_int
+				integer(c_int), value :: tableID_dummy
+			end function lib_tableInqNum
+		end interface
+		result = lib_tableInqNum(tableID_dummy)
+	end function tableInqNum
+
+	function tableInqModel(tableID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: tableID_dummy
+		interface
+			integer(c_int) function lib_tableInqModel(tableID_dummy) bind(c, name = 'tableInqModel')
+				import c_int
+				integer(c_int), value :: tableID_dummy
+			end function lib_tableInqModel
+		end interface
+		result = lib_tableInqModel(tableID_dummy)
+	end function tableInqModel
+
+	subroutine tableInqPar(tableID_dummy, code_dummy, name_dummy, longname_dummy, units_dummy)
+		integer(c_int), value :: tableID_dummy
+		integer(c_int), value :: code_dummy
+		character(kind = c_char, len = *), intent(inout) :: name_dummy
+		character(kind = c_char, len = *), intent(inout) :: longname_dummy
+		character(kind = c_char, len = *), intent(inout) :: units_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy))
+		integer :: name_i
+		logical :: name_padding = .true.
+		character(kind = c_char) :: longname_temp(len(longname_dummy))
+		integer :: longname_i
+		logical :: longname_padding = .true.
+		character(kind = c_char) :: units_temp(len(units_dummy))
+		integer :: units_i
+		logical :: units_padding = .true.
+		interface
+			subroutine lib_tableInqPar(tableID_dummy, code_dummy, name_dummy, longname_dummy, units_dummy) bind(c, name = 'tableInqPar')
+				import c_char, c_int
+				integer(c_int), value :: tableID_dummy
+				integer(c_int), value :: code_dummy
+				character(kind = c_char) :: name_dummy(*)
+				character(kind = c_char) :: longname_dummy(*)
+				character(kind = c_char) :: units_dummy(*)
+			end subroutine lib_tableInqPar
+		end interface
+		do name_i = len(name_dummy), 1, -1
+			if(name_dummy(name_i:name_i) /= ' ') name_padding = .false.
+			if(name_padding) then
+				name_temp(name_i) = c_null_char
+			else
+				name_temp(name_i) = name_dummy(name_i:name_i)
+			end if
+		end do
+		do longname_i = len(longname_dummy), 1, -1
+			if(longname_dummy(longname_i:longname_i) /= ' ') longname_padding = .false.
+			if(longname_padding) then
+				longname_temp(longname_i) = c_null_char
+			else
+				longname_temp(longname_i) = longname_dummy(longname_i:longname_i)
+			end if
+		end do
+		do units_i = len(units_dummy), 1, -1
+			if(units_dummy(units_i:units_i) /= ' ') units_padding = .false.
+			if(units_padding) then
+				units_temp(units_i) = c_null_char
+			else
+				units_temp(units_i) = units_dummy(units_i:units_i)
+			end if
+		end do
+		call lib_tableInqPar(tableID_dummy, code_dummy, name_temp, longname_temp, units_temp)
+		name_padding = .false.
+		do name_i = 1, len(name_dummy)
+			if(name_temp(name_i) == c_null_char) name_padding = .true.
+			if(name_padding) then
+				name_dummy(name_i:name_i) = ' '
+			else
+				name_dummy(name_i:name_i) = name_temp(name_i)
+			end if
+		end do
+		longname_padding = .false.
+		do longname_i = 1, len(longname_dummy)
+			if(longname_temp(longname_i) == c_null_char) longname_padding = .true.
+			if(longname_padding) then
+				longname_dummy(longname_i:longname_i) = ' '
+			else
+				longname_dummy(longname_i:longname_i) = longname_temp(longname_i)
+			end if
+		end do
+		units_padding = .false.
+		do units_i = 1, len(units_dummy)
+			if(units_temp(units_i) == c_null_char) units_padding = .true.
+			if(units_padding) then
+				units_dummy(units_i:units_i) = ' '
+			else
+				units_dummy(units_i:units_i) = units_temp(units_i)
+			end if
+		end do
+	end subroutine tableInqPar
+
+	function tableInqParCode(tableID_dummy, name_dummy, code) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: tableID_dummy
+		character(kind = c_char, len = *), intent(inout) :: name_dummy
+		integer(c_int), optional, intent(inout) :: code
+		character(kind = c_char) :: name_temp(len(name_dummy))
+		integer :: name_i
+		logical :: name_padding = .true.
+		integer(c_int), target :: code_temp
+		type(c_ptr) :: code_ptr
+		interface
+			integer(c_int) function lib_tableInqParCode(tableID_dummy, name_dummy, code) bind(c, name = 'tableInqParCode')
+				import c_char, c_int, c_ptr
+				integer(c_int), value :: tableID_dummy
+				character(kind = c_char) :: name_dummy(*)
+				type(c_ptr), value :: code
+			end function lib_tableInqParCode
+		end interface
+		do name_i = len(name_dummy), 1, -1
+			if(name_dummy(name_i:name_i) /= ' ') name_padding = .false.
+			if(name_padding) then
+				name_temp(name_i) = c_null_char
+			else
+				name_temp(name_i) = name_dummy(name_i:name_i)
+			end if
+		end do
+		code_ptr = c_null_ptr
+		if(present(code)) code_ptr = c_loc(code_temp)
+		result = lib_tableInqParCode(tableID_dummy, name_temp, code_ptr)
+		name_padding = .false.
+		do name_i = 1, len(name_dummy)
+			if(name_temp(name_i) == c_null_char) name_padding = .true.
+			if(name_padding) then
+				name_dummy(name_i:name_i) = ' '
+			else
+				name_dummy(name_i:name_i) = name_temp(name_i)
+			end if
+		end do
+		if(present(code)) code = code_temp
+	end function tableInqParCode
+
+	function tableInqParName(tableID_dummy, code_dummy, name_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: tableID_dummy
+		integer(c_int), value :: code_dummy
+		character(kind = c_char, len = *), intent(inout) :: name_dummy
+		character(kind = c_char) :: name_temp(len(name_dummy))
+		integer :: name_i
+		logical :: name_padding = .true.
+		interface
+			integer(c_int) function lib_tableInqParName(tableID_dummy, code_dummy, name_dummy) bind(c, name = 'tableInqParName')
+				import c_char, c_int
+				integer(c_int), value :: tableID_dummy
+				integer(c_int), value :: code_dummy
+				character(kind = c_char) :: name_dummy(*)
+			end function lib_tableInqParName
+		end interface
+		do name_i = len(name_dummy), 1, -1
+			if(name_dummy(name_i:name_i) /= ' ') name_padding = .false.
+			if(name_padding) then
+				name_temp(name_i) = c_null_char
+			else
+				name_temp(name_i) = name_dummy(name_i:name_i)
+			end if
+		end do
+		result = lib_tableInqParName(tableID_dummy, code_dummy, name_temp)
+		name_padding = .false.
+		do name_i = 1, len(name_dummy)
+			if(name_temp(name_i) == c_null_char) name_padding = .true.
+			if(name_padding) then
+				name_dummy(name_i:name_i) = ' '
+			else
+				name_dummy(name_i:name_i) = name_temp(name_i)
+			end if
+		end do
+	end function tableInqParName
+
+	function tableInqParLongname(tableID_dummy, code_dummy, longname_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: tableID_dummy
+		integer(c_int), value :: code_dummy
+		character(kind = c_char, len = *), intent(inout) :: longname_dummy
+		character(kind = c_char) :: longname_temp(len(longname_dummy))
+		integer :: longname_i
+		logical :: longname_padding = .true.
+		interface
+			integer(c_int) function lib_tableInqParLongname(tableID_dummy, code_dummy, longname_dummy) bind(c, name = 'tableInqParLongname')
+				import c_char, c_int
+				integer(c_int), value :: tableID_dummy
+				integer(c_int), value :: code_dummy
+				character(kind = c_char) :: longname_dummy(*)
+			end function lib_tableInqParLongname
+		end interface
+		do longname_i = len(longname_dummy), 1, -1
+			if(longname_dummy(longname_i:longname_i) /= ' ') longname_padding = .false.
+			if(longname_padding) then
+				longname_temp(longname_i) = c_null_char
+			else
+				longname_temp(longname_i) = longname_dummy(longname_i:longname_i)
+			end if
+		end do
+		result = lib_tableInqParLongname(tableID_dummy, code_dummy, longname_temp)
+		longname_padding = .false.
+		do longname_i = 1, len(longname_dummy)
+			if(longname_temp(longname_i) == c_null_char) longname_padding = .true.
+			if(longname_padding) then
+				longname_dummy(longname_i:longname_i) = ' '
+			else
+				longname_dummy(longname_i:longname_i) = longname_temp(longname_i)
+			end if
+		end do
+	end function tableInqParLongname
+
+	function tableInqParUnits(tableID_dummy, code_dummy, units_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: tableID_dummy
+		integer(c_int), value :: code_dummy
+		character(kind = c_char, len = *), intent(inout) :: units_dummy
+		character(kind = c_char) :: units_temp(len(units_dummy))
+		integer :: units_i
+		logical :: units_padding = .true.
+		interface
+			integer(c_int) function lib_tableInqParUnits(tableID_dummy, code_dummy, units_dummy) bind(c, name = 'tableInqParUnits')
+				import c_char, c_int
+				integer(c_int), value :: tableID_dummy
+				integer(c_int), value :: code_dummy
+				character(kind = c_char) :: units_dummy(*)
+			end function lib_tableInqParUnits
+		end interface
+		do units_i = len(units_dummy), 1, -1
+			if(units_dummy(units_i:units_i) /= ' ') units_padding = .false.
+			if(units_padding) then
+				units_temp(units_i) = c_null_char
+			else
+				units_temp(units_i) = units_dummy(units_i:units_i)
+			end if
+		end do
+		result = lib_tableInqParUnits(tableID_dummy, code_dummy, units_temp)
+		units_padding = .false.
+		do units_i = 1, len(units_dummy)
+			if(units_temp(units_i) == c_null_char) units_padding = .true.
+			if(units_padding) then
+				units_dummy(units_i:units_i) = ' '
+			else
+				units_dummy(units_i:units_i) = units_temp(units_i)
+			end if
+		end do
+	end function tableInqParUnits
+
+	function tableInqParNamePtr(tableID_dummy, parID_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		integer(c_int), value :: tableID_dummy
+		integer(c_int), value :: parID_dummy
+		type(c_ptr) :: ptr
+		integer :: shape(1)
+		interface
+			type(c_ptr) function lib_tableInqParNamePtr(tableID_dummy, parID_dummy) bind(c, name = 'tableInqParNamePtr')
+				import c_int, c_ptr
+				integer(c_int), value :: tableID_dummy
+				integer(c_int), value :: parID_dummy
+			end function lib_tableInqParNamePtr
+		end interface
+		result => null()
+		ptr = lib_tableInqParNamePtr(tableID_dummy, parID_dummy)
+		if(c_associated(ptr)) then
+			shape(1) = int(lib_strlen(ptr))
+			call c_f_pointer(ptr, result, shape)
+		end if
+	end function tableInqParNamePtr
+
+	function tableInqParLongnamePtr(tableID_dummy, parID_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		integer(c_int), value :: tableID_dummy
+		integer(c_int), value :: parID_dummy
+		type(c_ptr) :: ptr
+		integer :: shape(1)
+		interface
+			type(c_ptr) function lib_tableInqParLongnamePtr(tableID_dummy, parID_dummy) bind(c, name = 'tableInqParLongnamePtr')
+				import c_int, c_ptr
+				integer(c_int), value :: tableID_dummy
+				integer(c_int), value :: parID_dummy
+			end function lib_tableInqParLongnamePtr
+		end interface
+		result => null()
+		ptr = lib_tableInqParLongnamePtr(tableID_dummy, parID_dummy)
+		if(c_associated(ptr)) then
+			shape(1) = int(lib_strlen(ptr))
+			call c_f_pointer(ptr, result, shape)
+		end if
+	end function tableInqParLongnamePtr
+
+	function tableInqParUnitsPtr(tableID_dummy, parID_dummy) result(result)
+		character(kind = c_char), dimension(:), pointer :: result
+		integer(c_int), value :: tableID_dummy
+		integer(c_int), value :: parID_dummy
+		type(c_ptr) :: ptr
+		integer :: shape(1)
+		interface
+			type(c_ptr) function lib_tableInqParUnitsPtr(tableID_dummy, parID_dummy) bind(c, name = 'tableInqParUnitsPtr')
+				import c_int, c_ptr
+				integer(c_int), value :: tableID_dummy
+				integer(c_int), value :: parID_dummy
+			end function lib_tableInqParUnitsPtr
+		end interface
+		result => null()
+		ptr = lib_tableInqParUnitsPtr(tableID_dummy, parID_dummy)
+		if(c_associated(ptr)) then
+			shape(1) = int(lib_strlen(ptr))
+			call c_f_pointer(ptr, result, shape)
+		end if
+	end function tableInqParUnitsPtr
+
+	subroutine streamDefHistory(streamID_dummy, size_dummy, history_dummy)
+		integer(c_int), value :: streamID_dummy
+		integer(c_int), value :: size_dummy
+		character(kind = c_char, len = *), intent(in) :: history_dummy
+		character(kind = c_char) :: history_temp(len(history_dummy) + 1)
+		integer :: history_i
+		interface
+			subroutine lib_streamDefHistory(streamID_dummy, size_dummy, history_dummy) bind(c, name = 'streamDefHistory')
+				import c_char, c_int
+				integer(c_int), value :: streamID_dummy
+				integer(c_int), value :: size_dummy
+				character(kind = c_char) :: history_dummy(*)
+			end subroutine lib_streamDefHistory
+		end interface
+		do history_i = 1, len(history_dummy)
+		history_temp(history_i) = history_dummy(history_i:history_i)
+		end do
+		history_temp(len(history_dummy) + 1) = c_null_char
+		call lib_streamDefHistory(streamID_dummy, size_dummy, history_temp)
+	end subroutine streamDefHistory
+
+	function streamInqHistorySize(streamID_dummy) result(result)
+		integer(c_int) :: result
+		integer(c_int), value :: streamID_dummy
+		interface
+			integer(c_int) function lib_streamInqHistorySize(streamID_dummy) bind(c, name = 'streamInqHistorySize')
+				import c_int
+				integer(c_int), value :: streamID_dummy
+			end function lib_streamInqHistorySize
+		end interface
+		result = lib_streamInqHistorySize(streamID_dummy)
+	end function streamInqHistorySize
+
+	subroutine streamInqHistoryString(streamID_dummy, history_dummy)
+		integer(c_int), value :: streamID_dummy
+		character(kind = c_char, len = *), intent(inout) :: history_dummy
+		character(kind = c_char) :: history_temp(len(history_dummy))
+		integer :: history_i
+		logical :: history_padding = .true.
+		interface
+			subroutine lib_streamInqHistoryString(streamID_dummy, history_dummy) bind(c, name = 'streamInqHistoryString')
+				import c_char, c_int
+				integer(c_int), value :: streamID_dummy
+				character(kind = c_char) :: history_dummy(*)
+			end subroutine lib_streamInqHistoryString
+		end interface
+		do history_i = len(history_dummy), 1, -1
+			if(history_dummy(history_i:history_i) /= ' ') history_padding = .false.
+			if(history_padding) then
+				history_temp(history_i) = c_null_char
+			else
+				history_temp(history_i) = history_dummy(history_i:history_i)
+			end if
+		end do
+		call lib_streamInqHistoryString(streamID_dummy, history_temp)
+		history_padding = .false.
+		do history_i = 1, len(history_dummy)
+			if(history_temp(history_i) == c_null_char) history_padding = .true.
+			if(history_padding) then
+				history_dummy(history_i:history_i) = ' '
+			else
+				history_dummy(history_i:history_i) = history_temp(history_i)
+			end if
+		end do
+	end subroutine streamInqHistoryString
+
+	subroutine gribapiLibraryVersion(major_version, minor_version, revision_version)
+		integer(c_int), optional, intent(inout) :: major_version
+		integer(c_int), optional, intent(inout) :: minor_version
+		integer(c_int), optional, intent(inout) :: revision_version
+		integer(c_int), target :: major_version_temp
+		type(c_ptr) :: major_version_ptr
+		integer(c_int), target :: minor_version_temp
+		type(c_ptr) :: minor_version_ptr
+		integer(c_int), target :: revision_version_temp
+		type(c_ptr) :: revision_version_ptr
+		interface
+			subroutine lib_gribapiLibraryVersion(major_version, minor_version, revision_version) bind(c, name = 'gribapiLibraryVersion')
+				import c_ptr
+				type(c_ptr), value :: major_version
+				type(c_ptr), value :: minor_version
+				type(c_ptr), value :: revision_version
+			end subroutine lib_gribapiLibraryVersion
+		end interface
+		major_version_ptr = c_null_ptr
+		if(present(major_version)) major_version_ptr = c_loc(major_version_temp)
+		minor_version_ptr = c_null_ptr
+		if(present(minor_version)) minor_version_ptr = c_loc(minor_version_temp)
+		revision_version_ptr = c_null_ptr
+		if(present(revision_version)) revision_version_ptr = c_loc(revision_version_temp)
+		call lib_gribapiLibraryVersion(major_version_ptr, minor_version_ptr, revision_version_ptr)
+		if(present(major_version)) major_version = major_version_temp
+		if(present(minor_version)) minor_version = minor_version_temp
+		if(present(revision_version)) revision_version = revision_version_temp
+	end subroutine gribapiLibraryVersion
 
 end module mo_cdi
diff --git a/src/proprietarySystemWorkarounds.c b/src/proprietarySystemWorkarounds.c
new file mode 100644
index 0000000000000000000000000000000000000000..3c3f741aa97a3d489b57e4f8458914ed283e10f2
--- /dev/null
+++ b/src/proprietarySystemWorkarounds.c
@@ -0,0 +1,45 @@
+#include "proprietarySystemWorkarounds.h"
+#include "dmemory.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+
+char* myStrDup(const char* string)
+{
+  char* result = xmalloc(strlen(string) + 1);
+  if(result)
+    {
+      strcpy(result, string);
+    }
+  else
+    {
+      errno = ENOMEM;
+    }
+  return result;
+}
+
+char* myAsprintf(char* format, ...)
+{
+  va_list args;
+  int size = 64;
+  char *buffer = xmalloc(size);
+  int nchars;
+  //Try to print in the allocated space.
+  va_start(args, format);
+  nchars = vsnprintf(buffer, size, format, args);
+  va_end(args);
+  if (nchars >= size)
+    {
+      //Reallocate buffer now that we know how much space is needed.
+      size = nchars + 1;
+      buffer = xrealloc(buffer, size);
+      va_start(args, format);
+      vsnprintf(buffer, size, format, args);
+      va_end(args);
+    }
+  return buffer;
+}
+
diff --git a/src/proprietarySystemWorkarounds.h b/src/proprietarySystemWorkarounds.h
new file mode 100644
index 0000000000000000000000000000000000000000..ee3151e353a9e3ea4ce5da3a28a820bfd612e456
--- /dev/null
+++ b/src/proprietarySystemWorkarounds.h
@@ -0,0 +1,8 @@
+#ifndef INCLUDE_GUARD_CDI_PROPRIETARY_SYSTEM_WORKAROUNDS_H
+#define INCLUDE_GUARD_CDI_PROPRIETARY_SYSTEM_WORKAROUNDS_H
+
+char* myStrDup(const char* string);      //This exactly implements the standardized behavior of strdup().
+
+char* myAsprintf(char* format, ...) __attribute__((format(printf, 1, 2)));       //This implementation differs from standard asprintf() function in the way the resulting string pointer is returned.
+
+#endif
diff --git a/src/referenceCounting.c b/src/referenceCounting.c
new file mode 100644
index 0000000000000000000000000000000000000000..3b5172f100b8550894571f4a71c9b637abaac8d7
--- /dev/null
+++ b/src/referenceCounting.c
@@ -0,0 +1,28 @@
+#include "referenceCounting.h"
+
+#include "error.h"
+
+void cdiRefObject_construct(CdiReferencedObject* me)
+{
+  me->destructor = cdiRefObject_destruct;
+  me->refCount = 1;
+}
+
+void cdiRefObject_retain(CdiReferencedObject* me)
+{
+  size_t oldCount = me->refCount++;
+  xassert(oldCount && "A reference counted object was used after it was destructed.");
+}
+
+void cdiRefObject_release(CdiReferencedObject* me)
+{
+  size_t oldCount = me->refCount--;
+  xassert(oldCount && "A reference counted object was released too often.");
+  if(oldCount == 1)
+    {
+      me->destructor(me);
+      free(me);
+    }
+}
+
+void cdiRefObject_destruct(CdiReferencedObject* me) { /* Empty for now, but that's no reason not to call it! */ }
diff --git a/src/referenceCounting.h b/src/referenceCounting.h
new file mode 100644
index 0000000000000000000000000000000000000000..6df196c9d1d68ed11a0d859000a0e44a688094cf
--- /dev/null
+++ b/src/referenceCounting.h
@@ -0,0 +1,38 @@
+#ifndef INCLUDE_GUARD_CDI_REFERENCE_COUNTING
+#define INCLUDE_GUARD_CDI_REFERENCE_COUNTING
+
+#include "error.h"
+
+#include <sys/types.h>
+#include <stdlib.h>
+
+/*
+This is a base class for all objects that need reference counting.
+A CdiReferencedObject has a reference count of one when it is constructed, refObjectRetain() increments the reference count, refObject Release() decrements it.
+When the reference count reaches zero, the destructor function is called before the memory of the object is deallocated with free().
+
+>>> Warning <<<
+This code is currently not thread-safe.
+
+We are currently using the C99 standard, which does not have atomic types.
+Also, there are still tons of systems out there that have a gcc without wrong C11 atomics support
+(__STDC_NO_ATOMICS__ not defined even though stdatomics.h is not even present).
+Consequently, it is impossible to write preprocessor code to even check for the presence of atomic types.
+So, we have two options: provide multithreading support by means of locks, or wait a year or two before doing this right.
+I, for one, prefer doing things right.
+*/
+typedef struct CdiReferencedObject CdiReferencedObject;
+struct CdiReferencedObject {
+  //protected:
+    void (*destructor)(CdiReferencedObject* me);  //Subclass constructors should set this to their own destructor.
+
+  //private:    //Subclasses may read it to determine whether there is only one reference, though.
+    size_t refCount;
+};
+
+void cdiRefObject_construct(CdiReferencedObject* me);
+void cdiRefObject_retain(CdiReferencedObject* me);
+void cdiRefObject_release(CdiReferencedObject* me);
+void cdiRefObject_destruct(CdiReferencedObject* me);
+
+#endif
diff --git a/src/serialize.h b/src/serialize.h
index a24589fdae0a6cf0991014617a969e266154e6e2..71de8adfb3cfc9ff3cface00b546abf16f9d5a85 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -8,8 +8,12 @@
 #include <string.h>
 
 #include "cdi.h"
+#ifndef  CDI_CKSUM_H_
 #include "cdi_cksum.h"
+#endif
+#ifndef  _ERROR_H
 #include "error.h"
+#endif
 
 /*
  * Generic interfaces for (de-)marshalling
diff --git a/src/stream.c b/src/stream.c
index 1e421516d9ff0c4dc9286c55b4eae134f02a7ac7..79931f3637e203e0e86fab0063ebf13dce2ce768 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -324,7 +324,7 @@ const char *streamFilesuffix(int filetype)
 }
 
 
-char *streamFilename(int streamID)
+const char *streamFilename(int streamID)
 {
   stream_t *streamptr = stream_to_pointer(streamID);
 
diff --git a/src/stream_cdf.c b/src/stream_cdf.c
index 74ed4b7a3af584b8ab5b09b3866c7916f48cfb49..f14546a75a605017eb104140fc0a695afc4d3a3b 100644
--- a/src/stream_cdf.c
+++ b/src/stream_cdf.c
@@ -8041,7 +8041,6 @@ void cdfEndDef(stream_t *streamptr)
 static void cdfDefInstitut(stream_t *streamptr)
 {
   int fileID, instID;
-  char *longname;
   size_t len;
   int vlistID;
 
@@ -8051,7 +8050,7 @@ static void cdfDefInstitut(stream_t *streamptr)
 
   if ( instID != UNDEFID )
     {
-      longname = institutInqLongnamePtr(instID);
+      const char *longname = institutInqLongnamePtr(instID);
       if ( longname )
 	{
 	  len = strlen(longname);
diff --git a/src/stream_fcommon.h b/src/stream_fcommon.h
index a4b12e71cb3e411d8a08c3a91bf1894aad4dae8b..2296e54404666f8355652242245cee62982131b5 100644
--- a/src/stream_fcommon.h
+++ b/src/stream_fcommon.h
@@ -1,7 +1,9 @@
 #ifndef STREAM_FCOMMON_H
 #define STREAM_FCOMMON_H
 
+#ifndef  _CDI_INT_H
 #include "cdi_int.h"
+#endif
 
 enum {
   SINGLE_PRECISION = 4,
diff --git a/src/stream_gribapi.c b/src/stream_gribapi.c
index bc186df834038ea7ea5fcf3faf91cc377f09a997..00125b4317267c97f92cd9f0863f168f87436c26 100644
--- a/src/stream_gribapi.c
+++ b/src/stream_gribapi.c
@@ -8,6 +8,8 @@
 #include "cdi.h"
 #include "cdi_int.h"
 #include "file.h"
+#include "gribapi_utilities.h"
+#include "stream_grb.h"
 #include "varscan.h"
 #include "datetime.h"
 #include "vlist.h"
@@ -18,7 +20,8 @@
 #if  defined  (HAVE_LIBGRIB_API)
 #  include "cgribex.h"      /* gribGetSize, gribRead, gribGetZip, GRIB1_LTYPE_99 */
 #  include "gribapi.h"
-#  include "grib_api.h"
+
+#  include <grib_api.h>
 #endif
 
 extern int cdiInventoryMode;
@@ -61,59 +64,6 @@ int my_grib_set_string(grib_handle* h, const char* key, const char* val, size_t*
   return grib_set_string(h, key, val, length);
 }
 
-static
-int gribapiGetGridType(grib_handle *gh)
-{
-  int gridtype = GRID_GENERIC;
-  int gribgridtype = -1;
-  long lpar;
-
-    {
-      int status;
-      status = grib_get_long(gh, "gridDefinitionTemplateNumber", &lpar);
-
-      if ( status ==  0 ) gribgridtype = (int) lpar;
-
-      switch (gribgridtype)
-	{
-	case  GRIB2_GTYPE_LATLON:        { GRIB_CHECK(grib_get_long(gh, "Ni", &lpar), 0);
-	                                   if ( lpar == (long) GRIB_MISSING_LONG ) break;
-                                         }
-	case  GRIB2_GTYPE_LATLON_ROT:    { gridtype = GRID_LONLAT;    break; }
-	case  GRIB2_GTYPE_LCC:           { gridtype = GRID_LCC;       break; }
-	case  GRIB2_GTYPE_GAUSSIAN:      { GRIB_CHECK(grib_get_long(gh, "Ni", &lpar), 0);
-	                                   if ( lpar == (long) GRIB_MISSING_LONG )
-					     gridtype = GRID_GAUSSIAN_REDUCED;
-					   else
-					     gridtype = GRID_GAUSSIAN;
-				  	   break;
-                                         }
-	case  GRIB2_GTYPE_SPECTRAL:      { gridtype = GRID_SPECTRAL;  break; }
-	case  GRIB2_GTYPE_GME:           { gridtype = GRID_GME;       break; }
-	case  GRIB2_GTYPE_UNSTRUCTURED:  { gridtype = GRID_UNSTRUCTURED; break; }
-	}
-    }
-
-  return (gridtype);
-}
-
-static
-int gribapiGetIsRotated(grib_handle *gh)
-{
-  int isRotated = 0;
-  int gribgridtype = -1;
-  long lpar;
-  int status;
-
-  status = grib_get_long(gh, "gridDefinitionTemplateNumber", &lpar);
-
-  if ( status ==  0 ) gribgridtype = (int) lpar;
-
-  if ( gribgridtype == GRIB2_GTYPE_LATLON_ROT ) isRotated = 1;
-
-  return (isRotated);
-}
-
 static
 int gribapiGetZaxisType(long editionNumber, int grib_ltype)
 {
@@ -209,64 +159,6 @@ int gribapiGetEndStep(grib_handle *gh, int startStep, int timeunits)
   return (endStep);
 }
 
-static
-int gribapiTimeIsFC(grib_handle *gh)
-{
-  long editionNumber;
-  int isFC = TRUE;
-
-  GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
-
-  if ( editionNumber > 1 )
-    {
-      long sigofrtime;
-
-      GRIB_CHECK(grib_get_long(gh, "significanceOfReferenceTime", &sigofrtime), 0);
-
-      if ( sigofrtime == 3 ) isFC = FALSE;
-    }
-
-  return (isFC);
-}
-
-static
-int gribapiGetTsteptype(grib_handle *gh)
-{
-  int tsteptype = TSTEP_INSTANT;
-  static int lprint = TRUE;
-
-  if ( gribapiTimeIsFC(gh) )
-    {
-      int status;
-      size_t len = 256;
-      char stepType[256];
-
-      status = grib_get_string(gh, "stepType", stepType, &len);
-      if ( status == 0 && len > 1 && len < 256 )
-	{
-	  if      ( strncmp("instant", stepType, len) == 0 ) tsteptype = TSTEP_INSTANT;
-	  else if ( strncmp("avg",     stepType, len) == 0 ) tsteptype = TSTEP_AVG;
-	  else if ( strncmp("accum",   stepType, len) == 0 ) tsteptype = TSTEP_ACCUM;
-	  else if ( strncmp("max",     stepType, len) == 0 ) tsteptype = TSTEP_MAX;
-	  else if ( strncmp("min",     stepType, len) == 0 ) tsteptype = TSTEP_MIN;
-	  else if ( strncmp("diff",    stepType, len) == 0 ) tsteptype = TSTEP_DIFF;
-	  else if ( strncmp("rms",     stepType, len) == 0 ) tsteptype = TSTEP_RMS;
-	  else if ( strncmp("sd",      stepType, len) == 0 ) tsteptype = TSTEP_SD;
-	  else if ( strncmp("cov",     stepType, len) == 0 ) tsteptype = TSTEP_COV;
-	  else if ( strncmp("ratio",   stepType, len) == 0 ) tsteptype = TSTEP_RATIO;
-	  else if ( lprint )
-	    {
-	      Message("Time stepType %s unsupported, set to instant!", stepType);
-	      lprint = FALSE;
-	    }
-
-	  // printf("stepType: %s %ld %d\n", stepType, len, tsteptype);
-	}
-    }
-
-  return (tsteptype);
-}
-
 static
 void gribapiGetDataDateTime(grib_handle *gh, int *datadate, int *datatime)
 {
@@ -274,7 +166,7 @@ void gribapiGetDataDateTime(grib_handle *gh, int *datadate, int *datatime)
 
   GRIB_CHECK(grib_get_long(gh, "dataDate", &lpar), 0);
   *datadate = (int) lpar;
-  GRIB_CHECK(grib_get_long(gh, "dataTime", &lpar), 0);
+  GRIB_CHECK(grib_get_long(gh, "dataTime", &lpar), 0);  //FIXME: This looses the seconds in GRIB2 files.
   *datatime = (int) lpar*100;
 }
 
@@ -295,11 +187,8 @@ int gribapiGetValidityDateTime(grib_handle *gh, int *vdate, int *vtime)
   int status;
   long lpar;
   long sigofrtime = 3;
-  long editionNumber;
-
-  GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
 
-  if ( editionNumber > 1 )
+  if ( gribEditionNumber(gh) > 1 )
     {
       GRIB_CHECK(grib_get_long(gh, "significanceOfReferenceTime", &sigofrtime), 0);
     }
@@ -308,7 +197,7 @@ int gribapiGetValidityDateTime(grib_handle *gh, int *vdate, int *vtime)
       GRIB_CHECK(grib_get_long(gh, "timeRangeIndicator", &sigofrtime), 0);
     }
 
-  if ( sigofrtime == 3 )
+  if ( sigofrtime == 3 )        //XXX: This looks like a bug to me, because timeRangeIndicator == 3 does not seem to have the same meaning as significanceOfReferenceTime == 3. I would recommend replacing this condition with `if(!gribapiTimeIsFC())`.
     {
       gribapiGetDataDateTime(gh, vdate, vtime);
     }
@@ -376,330 +265,6 @@ int gribapiGetValidityDateTime(grib_handle *gh, int *vdate, int *vtime)
   return (tstepRange);
 }
 
-static
-void gribapiGetGrid(grib_handle *gh, grid_t *grid)
-{
-  long editionNumber;
-  GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
-
-  int gridtype = gribapiGetGridType(gh);
-  /*
-  if ( streamptr->unreduced && gridtype == GRID_GAUSSIAN_REDUCED )
-    {
-      gridtype = GRID_GAUSSIAN;
-      ISEC2_NumLon = 2*ISEC2_NumLat;
-      ISEC4_NumValues = ISEC2_NumLon*ISEC2_NumLat;
-    }
-  */
-  memset(grid, 0, sizeof(grid_t));
-
-  size_t datasize;
-  GRIB_CHECK(grib_get_size(gh, "values", &datasize), 0);
-  long numberOfPoints;
-  GRIB_CHECK(grib_get_long(gh, "numberOfPoints", &numberOfPoints), 0);
-
-  switch (gridtype)
-    {
-    case GRID_LONLAT:
-    case GRID_GAUSSIAN:
-      {
-        long lpar;
-	GRIB_CHECK(grib_get_long(gh, "Ni", &lpar), 0);
-        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
-	int nlon = (int)lpar;
-	GRIB_CHECK(grib_get_long(gh, "Nj", &lpar), 0);
-        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
-	int nlat = (int)lpar;
-
-	if ( gridtype == GRID_GAUSSIAN )
-          {
-            GRIB_CHECK(grib_get_long(gh, "numberOfParallelsBetweenAPoleAndTheEquator", &lpar), 0);
-            grid->np = (int)lpar;
-          }
-
-	if ( numberOfPoints != nlon*nlat )
-	  Error("numberOfPoints (%ld) and gridSize (%d) differ!", numberOfPoints, nlon*nlat);
-
-        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
-	grid->size  = (int)numberOfPoints;
-	grid->xsize = nlon;
-	grid->ysize = nlat;
-	grid->xinc  = 0;
-	grid->yinc  = 0;
-	grid->xdef  = 0;
-	GRIB_CHECK(grib_get_double(gh, "longitudeOfFirstGridPointInDegrees", &grid->xfirst), 0);
-	GRIB_CHECK(grib_get_double(gh, "longitudeOfLastGridPointInDegrees",  &grid->xlast), 0);
-	GRIB_CHECK(grib_get_double(gh, "latitudeOfFirstGridPointInDegrees",  &grid->yfirst), 0);
-	GRIB_CHECK(grib_get_double(gh, "latitudeOfLastGridPointInDegrees",   &grid->ylast), 0);
-	GRIB_CHECK(grib_get_double(gh, "iDirectionIncrementInDegrees", &grid->xinc), 0);
-	if ( gridtype == GRID_LONLAT )
-	  GRIB_CHECK(grib_get_double(gh, "jDirectionIncrementInDegrees", &grid->yinc), 0);
-
-	if ( IS_EQUAL(grid->xinc, GRIB_MISSING_DOUBLE) ) grid->xinc = 0;
-
-	/* if ( IS_NOT_EQUAL(grid->xfirst, 0) || IS_NOT_EQUAL(grid->xlast, 0) ) */
-	  {
-	    if ( grid->xsize > 1 )
-	      {
-		if ( (grid->xfirst >= grid->xlast) && (grid->xfirst >= 180) ) grid->xfirst -= 360;
-
-		if ( editionNumber <= 1 )
-		  {
-		    /* correct xinc if necessary */
-		    if ( IS_EQUAL(grid->xfirst, 0) && grid->xlast > 354 )
-		      {
-			double xinc = 360. / grid->xsize;
-
-			if ( fabs(grid->xinc-xinc) > 0.0 )
-			  {
-			    grid->xinc = xinc;
-			    if ( CDI_Debug ) Message("set xinc to %g", grid->xinc);
-			  }
-		      }
-		  }
-	      }
-	    grid->xdef = 2;
-	  }
-	grid->ydef = 0;
-        /* if ( IS_NOT_EQUAL(grid->yfirst, 0) || IS_NOT_EQUAL(grid->ylast, 0) ) */
-	  {
-	    if ( grid->ysize > 1 )
-	      {
-		if ( editionNumber <= 1 )
-		  {
-		  }
-	      }
-	    grid->ydef = 2;
-	  }
-	break;
-      }
-    case GRID_GAUSSIAN_REDUCED:
-      {
-	size_t dummy;
-	long *pl;
-
-        long lpar;
-        GRIB_CHECK(grib_get_long(gh, "numberOfParallelsBetweenAPoleAndTheEquator", &lpar), 0);
-        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
-        grid->np = (int)lpar;
-
-	GRIB_CHECK(grib_get_long(gh, "Nj", &lpar), 0);
-        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
-	int nlat = (int)lpar;
-
-        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
-	grid->size   = (int)numberOfPoints;
-
-        grid->rowlon = (int *) malloc((size_t)nlat * sizeof (int));
-        pl          = (long *) malloc((size_t)nlat * sizeof (long));
-	dummy       = (size_t)nlat;
-	GRIB_CHECK(grib_get_long_array(gh, "pl", pl, &dummy), 0);
-        /* FIXME: assert(pl[i] >= INT_MIN && pl[i] <= INT_MIN) */
-	for (int i = 0; i < nlat; ++i ) grid->rowlon[i] = (int)pl[i];
-	free(pl);
-
-	grid->ysize  = nlat;
-	grid->xinc   = 0;
-	grid->yinc   = 0;
-	grid->xdef   = 0;
-	GRIB_CHECK(grib_get_double(gh, "longitudeOfFirstGridPointInDegrees", &grid->xfirst), 0);
-	GRIB_CHECK(grib_get_double(gh, "longitudeOfLastGridPointInDegrees",  &grid->xlast), 0);
-	GRIB_CHECK(grib_get_double(gh, "latitudeOfFirstGridPointInDegrees",  &grid->yfirst), 0);
-	GRIB_CHECK(grib_get_double(gh, "latitudeOfLastGridPointInDegrees",   &grid->ylast), 0);
-	GRIB_CHECK(grib_get_double(gh, "iDirectionIncrementInDegrees", &grid->xinc), 0);
-
-	if ( IS_EQUAL(grid->xinc, GRIB_MISSING_DOUBLE) ) grid->xinc = 0;
-
-	/* if ( IS_NOT_EQUAL(grid->xfirst, 0) || IS_NOT_EQUAL(grid->xlast, 0) ) */
-	  {
-	    if ( grid->xsize > 1 )
-	      {
-		if ( (grid->xfirst > grid->xlast) && (grid->xfirst >= 180) ) grid->xfirst -= 360;
-
-		if ( editionNumber <= 1 )
-		  {
-		    /* correct xinc if necessary */
-		    if ( IS_EQUAL(grid->xfirst, 0) && grid->xlast > 354 )
-		      {
-			double xinc = 360. / grid->xsize;
-
-			if ( fabs(grid->xinc-xinc) > 0.0 )
-			  {
-			    grid->xinc = xinc;
-			    if ( CDI_Debug ) Message("set xinc to %g", grid->xinc);
-			  }
-		      }
-		  }
-	      }
-	    grid->xdef = 2;
-	  }
-	grid->ydef  = 0;
-        /* if ( IS_NOT_EQUAL(grid->yfirst, 0) || IS_NOT_EQUAL(grid->ylast, 0) ) */
-	  {
-	    if ( grid->ysize > 1 )
-	      {
-		if ( editionNumber <= 1 )
-		  {
-		  }
-	      }
-	    grid->ydef = 2;
-	  }
-	break;
-      }
-    case GRID_LCC:
-      {
-	int nlon, nlat;
-        long lpar;
-
-	GRIB_CHECK(grib_get_long(gh, "Nx", &lpar), 0);
-	nlon = lpar;
-	GRIB_CHECK(grib_get_long(gh, "Ny", &lpar), 0);
-	nlat = lpar;
-
-	if ( numberOfPoints != nlon*nlat )
-	  Error("numberOfPoints (%d) and gridSize (%d) differ!", (int)numberOfPoints, nlon*nlat);
-
-	grid->size  = numberOfPoints;
-	grid->xsize = nlon;
-	grid->ysize = nlat;
-
-	GRIB_CHECK(grib_get_double(gh, "DxInMetres", &grid->lcc_xinc), 0);
-	GRIB_CHECK(grib_get_double(gh, "DyInMetres", &grid->lcc_yinc), 0);
-	GRIB_CHECK(grib_get_double(gh, "longitudeOfFirstGridPointInDegrees", &grid->lcc_originLon), 0);
-	GRIB_CHECK(grib_get_double(gh, "latitudeOfFirstGridPointInDegrees", &grid->lcc_originLat), 0);
-	GRIB_CHECK(grib_get_double(gh, "LoVInDegrees", &grid->lcc_lonParY), 0);
-	GRIB_CHECK(grib_get_double(gh, "Latin1InDegrees", &grid->lcc_lat1), 0);
-	GRIB_CHECK(grib_get_double(gh, "Latin2InDegrees", &grid->lcc_lat2), 0);
-
-        if ( editionNumber <= 1 )
-          {
-            GRIB_CHECK(grib_get_long(gh, "projectionCenterFlag", &lpar), 0);
-            grid->lcc_projflag  = (int) lpar;
-            GRIB_CHECK(grib_get_long(gh, "scanningMode", &lpar), 0);
-            grid->lcc_scanflag  = (int) lpar;
-          }
-
-	grid->xdef   = 0;
-	grid->ydef   = 0;
-
-	break;
-      }
-    case GRID_SPECTRAL:
-      {
-	size_t len = 256;
-	char typeOfPacking[256];
-	GRIB_CHECK(grib_get_string(gh, "packingType", typeOfPacking, &len), 0);
-	grid->lcomplex = 0;
-	if ( strncmp(typeOfPacking, "spectral_complex", len) == 0 ) grid->lcomplex = 1;
-
-        /* FIXME: assert(datasize >= INT_MIN && datasize <= INT_MAX) */
-	grid->size  = (int)datasize;
-        long lpar;
-	GRIB_CHECK(grib_get_long(gh, "J", &lpar), 0);
-        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
-	grid->trunc = (int)lpar;
-
-	break;
-      }
-    case GRID_GME:
-      {
-        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
-	grid->size  = (int)numberOfPoints;
-        long lpar;
-        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
-	if ( grib_get_long(gh, "nd", &lpar) == 0 ) grid->nd  = (int)lpar;
-        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
-	if ( grib_get_long(gh, "Ni", &lpar) == 0 ) grid->ni  = (int)lpar;
-        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
-	if ( grib_get_long(gh, "n2", &lpar) == 0 ) grid->ni2 = (int)lpar;
-        /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
-	if ( grib_get_long(gh, "n3", &lpar) == 0 ) grid->ni3 = (int)lpar;
-
-	break;
-      }
-    case GRID_UNSTRUCTURED:
-      {
-        unsigned char uuid[CDI_UUID_SIZE];
-    	/*
-        char reference_link[8192];
-        size_t len = sizeof(reference_link);
-        reference_link[0] = 0;
-         */
-
-        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
-    	grid->size  = (int)numberOfPoints;
-        long lpar;
-        if ( grib_get_long(gh, "numberOfGridUsed", &lpar) == 0 )
-          {
-            /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
-            grid->number   = (int)lpar;
-            /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
-            if ( grib_get_long(gh, "numberOfGridInReference", &lpar) == 0 )
-              grid->position = (int)lpar;
-            /*
-            if ( grib_get_string(gh, "gridDescriptionFile", reference_link, &len) == 0 )
-              {
-                if ( strncmp(reference_link, "file://", 7) == 0 )
-                  grid->reference = strdupx(reference_link);
-              }
-            */
-            size_t len = (size_t)CDI_UUID_SIZE;
-            if ( grib_get_bytes(gh, "uuidOfHGrid", uuid, &len) == 0)
-              {
-                memcpy(grid->uuid, uuid, CDI_UUID_SIZE);
-              }
-          }
-	break;
-      }
-    case GRID_GENERIC:
-      {
-	int nlon = 0, nlat = 0;
-        long lpar;
-        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
-	if ( grib_get_long(gh, "Ni", &lpar) == 0 ) nlon = (int)lpar;
-        /* FIXME: assert(lpar <= INT_MAX && lpar >= INT_MIN) */
-	if ( grib_get_long(gh, "Nj", &lpar) == 0 ) nlat = (int)lpar;
-
-        /* FIXME: assert(numberOfPoints <= INT_MAX && numberOfPoints >= INT_MIN) */
-	grid->size  = (int)numberOfPoints;
-
-	if ( nlon > 0 && nlat > 0 && nlon*nlat == grid->size )
-	  {
-	    grid->xsize = nlon;
-	    grid->ysize = nlat;
-	  }
-	else
-	  {
-	    grid->xsize = 0;
-	    grid->ysize = 0;
-	  }
-
-	break;
-      }
-    default:
-      {
-	Error("Unsupported grid type: %s", gridNamePtr(gridtype));
-	break;
-      }
-    }
-
-  grid->isRotated = FALSE;
-  if ( gribapiGetIsRotated(gh) )
-    {
-      grid->isRotated = TRUE;
-      GRIB_CHECK(grib_get_double(gh, "latitudeOfSouthernPoleInDegrees",  &grid->ypole), 0);
-      GRIB_CHECK(grib_get_double(gh, "longitudeOfSouthernPoleInDegrees", &grid->xpole), 0);
-      GRIB_CHECK(grib_get_double(gh, "angleOfRotation", &grid->angle), 0);
-      /* change from south to north pole */
-      grid->ypole = -grid->ypole;
-      grid->xpole =  grid->xpole - 180;
-    }
-
-  grid->xvals = NULL;
-  grid->yvals = NULL;
-  grid->type  = gridtype;
-}
-
 static
 void grib1GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, int *level2)
 {
@@ -709,8 +274,7 @@ void grib1GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, i
   *level2    = 0;
 
   long lpar;
-  int status = grib_get_long(gh, "indicatorOfTypeOfLevel", &lpar);
-  if ( status == 0 )
+  if(!grib_get_long(gh, "indicatorOfTypeOfLevel", &lpar))       //1 byte
     {
       *leveltype = (int) lpar;
 
@@ -722,10 +286,17 @@ void grib1GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, i
 	  { *lbounds = 1; break; }
 	}
 
-      if ( *lbounds == 0 )
+      if ( *lbounds )
+	{
+	  GRIB_CHECK(grib_get_long(gh, "topLevel", &lpar), 0);  //1 byte
+	  *level1 = (int)lpar;
+	  GRIB_CHECK(grib_get_long(gh, "bottomLevel", &lpar), 0);       //1 byte
+	  *level2 = (int)lpar;
+	}
+      else
 	{
           double dlevel;
-	  GRIB_CHECK(grib_get_double(gh, "level", &dlevel), 0);
+	  GRIB_CHECK(grib_get_double(gh, "level", &dlevel), 0); //2 byte
 	  if ( *leveltype == 100 ) dlevel *= 100;
 	  if ( dlevel < -2.e9 || dlevel > 2.e9 ) dlevel = 0;
 	  if ( *leveltype == GRIB1_LTYPE_99 ) *leveltype = 100;
@@ -733,33 +304,36 @@ void grib1GetLevel(grib_handle *gh, int *leveltype, int *lbounds, int *level1, i
 	  *level1 = (int) dlevel;
 	  *level2 = 0;
 	}
-      else
-	{
-	  GRIB_CHECK(grib_get_long(gh, "topLevel", &lpar), 0);
-	  *level1 = (int)lpar;
-	  GRIB_CHECK(grib_get_long(gh, "bottomLevel", &lpar), 0);
-	  *level2 = (int)lpar;
-	}
     }
 }
 
 static
 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;
-  else if ( factor == 5 ) scaleFactor =    0.00001;
-  else if ( factor == 6 ) scaleFactor =    0.000001;
-  else if ( factor == 7 ) scaleFactor =    0.0000001;
-  else if ( factor == 8 ) scaleFactor =    0.00000001;
-  else if ( factor == 9 ) scaleFactor =    0.000000001;
-
-  return (scaleFactor);
+  switch(factor)
+    {
+      case GRIB_MISSING_LONG: return 1;
+      case 0: return 1;
+      case 1: return 0.1;
+      case 2: return 0.01;
+      case 3: return 0.001;
+      case 4: return 0.0001;
+      case 5: return 0.00001;
+      case 6: return 0.000001;
+      case 7: return 0.0000001;
+      case 8: return 0.00000001;
+      case 9: return 0.000000001;
+      default: return 0;
+    }
+}
+
+static
+int calcLevel(int level_sf, long factor, long level)
+{
+  double result = 0;
+  if(level != GRIB_MISSING_LONG) result = level*grib2ScaleFactor(factor);
+  if(level_sf) result *= level_sf;
+  return (int)result;
 }
 
 static
@@ -778,66 +352,66 @@ void grib2GetLevel(grib_handle *gh, int *leveltype1, int *leveltype2, int *lboun
   *level_sf   = 0;
   *level_unit = 0;
 
-  status = grib_get_long(gh, "typeOfFirstFixedSurface", &lpar);
+  status = grib_get_long(gh, "typeOfFirstFixedSurface", &lpar); //1 byte
   if ( status == 0 )
     {
       long llevel;
-      double dlevel1 = 0, dlevel2 = 0;
 
       *leveltype1 = (int) lpar;
 
-      status = grib_get_long(gh, "typeOfSecondFixedSurface", &lpar);
+      status = grib_get_long(gh, "typeOfSecondFixedSurface", &lpar); //1 byte
       /* FIXME: assert(lpar >= INT_MIN && lpar <= INT_MAX) */
       if ( status == 0 ) *leveltype2 = (int)lpar;
 
       if ( *leveltype1 != 255 && *leveltype2 != 255 && *leveltype2 > 0 ) *lbounds = 1;
-      if ( *leveltype1 == GRIB2_LTYPE_REFERENCE && *leveltype2 == 1 ) *lbounds = 0;
-
-      if ( *leveltype1 == GRIB2_LTYPE_LANDDEPTH )
-        {
-          *level_sf = 1000;
-          *level_unit = CDI_UNIT_M;
-        }
-      else if ( *leveltype1 == GRIB2_LTYPE_ISOBARIC )
-        {
-          *level_sf = 1000;
-          *level_unit = CDI_UNIT_PA;
-        }
-      else if ( *leveltype1 == GRIB2_LTYPE_SIGMA )
-        {
-          *level_sf = 1000;
-          *level_unit = 0;
-        }
-
-      GRIB_CHECK(grib_get_long(gh, "scaleFactorOfFirstFixedSurface", &factor), 0);
-      GRIB_CHECK(grib_get_long(gh, "scaledValueOfFirstFixedSurface", &llevel), 0);
-      if ( llevel != GRIB_MISSING_LONG )
+      switch(*leveltype1)
         {
-          if ( factor != GRIB_MISSING_LONG )
-            dlevel1 = (double)llevel * grib2ScaleFactor(factor);
-          else
-            dlevel1 = (double)llevel;
+          case GRIB2_LTYPE_REFERENCE:
+            if(*leveltype2 == 1) *lbounds = 0;
+            break;
+
+          case GRIB2_LTYPE_LANDDEPTH:
+            *level_sf = 1000;
+            *level_unit = CDI_UNIT_M;
+            break;
+
+          case GRIB2_LTYPE_ISOBARIC:
+            *level_sf = 1000;
+            *level_unit = CDI_UNIT_PA;
+            break;
+
+          case GRIB2_LTYPE_SIGMA:
+            *level_sf = 1000;
+            *level_unit = 0;
+            break;
         }
 
-      if ( *level_sf != 0 ) dlevel1 *= (double)(*level_sf);
+      GRIB_CHECK(grib_get_long(gh, "scaleFactorOfFirstFixedSurface", &factor), 0);      //1 byte
+      GRIB_CHECK(grib_get_long(gh, "scaledValueOfFirstFixedSurface", &llevel), 0);      //4 byte
+      *level1 = calcLevel(*level_sf, factor, llevel);
 
-      if ( *lbounds == 1 )
-	{
-          GRIB_CHECK(grib_get_long(gh, "scaleFactorOfSecondFixedSurface", &factor), 0);
-          GRIB_CHECK(grib_get_long(gh, "scaledValueOfSecondFixedSurface", &llevel), 0);
-          if ( llevel != GRIB_MISSING_LONG )
-            {
-              if ( factor != GRIB_MISSING_LONG )
-                dlevel2 = (double)llevel * grib2ScaleFactor(factor);
-              else
-                dlevel2 = (double)llevel;
-            }
-
-          if ( *level_sf != 0 ) dlevel2 *= (*level_sf);
+      if ( *lbounds )
+        {
+          GRIB_CHECK(grib_get_long(gh, "scaleFactorOfSecondFixedSurface", &factor), 0); //1 byte
+          GRIB_CHECK(grib_get_long(gh, "scaledValueOfSecondFixedSurface", &llevel), 0); //4 byte
+          *level2 = calcLevel(*level_sf, factor, llevel);
         }
+    }
+}
 
-      *level1 = (int) dlevel1;
-      *level2 = (int) dlevel2;
+static
+void gribGetLevel(grib_handle *gh, int* leveltype1, int* leveltype2, int* lbounds, int* level1, int* level2, int* level_sf, int* level_unit)
+{
+  if ( gribEditionNumber(gh) <= 1 )
+    {
+      grib1GetLevel(gh, leveltype1, lbounds, level1, level2);
+      *leveltype2 = -1;
+      *level_sf = 0;
+      *level_unit = 0;
+    }
+  else
+    {
+      grib2GetLevel(gh, leveltype1, leveltype2, lbounds, level1, level2, level_sf, level_unit);
     }
 }
 
@@ -854,10 +428,9 @@ void gribapiGetString(grib_handle *gh, const char *key, char *string, size_t len
 #if  defined  (HAVE_LIBGRIB_API)
 static
 void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
-		      size_t recsize, off_t position, int datatype, int comptype, size_t len, const char *varname,
+                      size_t recsize, off_t position, int datatype, int comptype, const char *varname,
                       int leveltype1, int leveltype2, int lbounds, int level1, int level2, int level_sf, int level_unit)
 {
-  long editionNumber;
   int zaxistype;
   int gridID = CDI_UNDEFID, varID;
   int levelID = 0;
@@ -882,8 +455,6 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
   // numavg  = ISEC1_AvgNum;
   numavg  = 0;
 
-  GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
-
   // fprintf(stderr, "param %d %d %d %d\n", param, level1, level2, leveltype1);
 
   (*record).size      = recsize;
@@ -893,13 +464,24 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
   (*record).ilevel2   = level2;
   (*record).ltype     = leveltype1;
   (*record).tsteptype = tsteptype;
-  memcpy((*record).varname, varname, len);
+
+  //FIXME: This may leave the variable name unterminated (which is the behavior that I found in the code).
+  //       I don't know precisely how this field is used, so I did not change this behavior to avoid regressions,
+  //       but I think that it would be better to at least add a line
+  //
+  //           record->varname[sizeof(record->varname) - 1] = 0;`
+  //
+  //       after the `strncpy()` call.
+  //
+  //       I would consider using strdup() (that requires POSIX-2008 compliance, though), or a similar homebrew approach.
+  //       I. e. kick the fixed size array and allocate enough space, whatever that may be.
+  strncpy(record->varname, varname, sizeof(record->varname));
 
   gribapiGetGrid(gh, &grid);
 
   gridID = varDefGrid(vlistID, &grid, 0);
 
-  zaxistype = gribapiGetZaxisType(editionNumber, leveltype1);
+  zaxistype = gribapiGetZaxisType(gribEditionNumber(gh), leveltype1);
 
   switch (zaxistype)
     {
@@ -1080,28 +662,6 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
 }
 #endif
 
-static
-int gribapiGetParam(grib_handle *gh)
-{
-  int pdis = 0, pcat = 0, pnum = 0;
-  int param = 0;
-  int status;
-  long lpar;
-
-  GRIB_CHECK(grib_get_long(gh, "discipline", &lpar), 0);
-  pdis = (int) lpar;
-
-  status = grib_get_long(gh, "parameterCategory", &lpar);
-  if ( status == 0 ) pcat = (int) lpar;
-
-  status = grib_get_long(gh, "parameterNumber", &lpar);
-  if ( status == 0 ) pnum = (int) lpar;
-
-  param = cdiEncodeParam(pnum, pcat, pdis);
-
-  return (param);
-}
-
 static
 compvar2_t gribapiVarSet(int param, int level1, int level2, int leveltype, int tsteptype, char *name)
 {
@@ -1146,8 +706,101 @@ int gribapiVarCompare(compvar2_t compVar, record_t record, int flag)
 }
 #endif
 
-#define gribWarning(text, nrecs, timestep, varname, paramstr, level1, level2) \
-            Warning("Record %2d (name=%s id=%s lev1=%d lev2=%d) timestep %d: %s", nrecs, varname, paramstr, level1, level2, timestep, text)
+static void ensureBufferSize(size_t requiredSize, size_t* curSize, unsigned char** buffer) {
+  if ( *curSize < requiredSize )
+    {
+      *curSize = requiredSize;
+      *buffer = realloc(*buffer, *curSize);
+    }
+}
+
+#if  defined  (HAVE_LIBGRIB_API)
+static
+grib_handle* gribapiGetDiskRepresentation(long recsize, size_t* buffersize, unsigned char** gribbuffer, int* outDatatype, int* outCompressionType, long* outUnzipsize)
+{
+  int lieee = FALSE;
+
+  grib_handle* gh = grib_handle_new_from_message(NULL, (void *) *gribbuffer, recsize);
+  if(gribEditionNumber(gh) > 1)
+    {
+      size_t len = 256;
+      char typeOfPacking[256];
+
+      if ( grib_get_string(gh, "packingType", typeOfPacking, &len) == 0 )
+        {
+          // fprintf(stderr, "packingType %d %s\n", len, typeOfPacking);
+          if      ( strncmp(typeOfPacking, "grid_jpeg", len) == 0 ) *outCompressionType = COMPRESS_JPEG;
+          else if ( strncmp(typeOfPacking, "grid_ccsds", len) == 0 ) *outCompressionType = COMPRESS_SZIP;
+          else if ( strncmp(typeOfPacking, "grid_ieee", len) == 0 ) lieee = TRUE;
+        }
+    }
+  else
+    {
+      if( gribGetZip(recsize, *gribbuffer, outUnzipsize) > 0 )
+        {
+          *outCompressionType = COMPRESS_SZIP;
+          ensureBufferSize(*outUnzipsize + 100, buffersize, gribbuffer);
+        }
+      else
+        {
+          *outCompressionType = COMPRESS_NONE;
+        }
+    }
+
+  if ( lieee )
+    {
+      *outDatatype = DATATYPE_FLT64;
+      long precision;
+      int status = grib_get_long(gh, "precision", &precision);
+      if ( status == 0 && precision == 1 ) *outDatatype = DATATYPE_FLT32;
+    }
+  else
+    {
+      *outDatatype = DATATYPE_PACK;
+      long bitsPerValue;
+      if ( grib_get_long(gh, "bitsPerValue", &bitsPerValue) == 0 )
+        {
+          if ( bitsPerValue > 0 && bitsPerValue <= 32 ) *outDatatype = (int)bitsPerValue;
+        }
+    }
+  return gh;
+}
+#endif
+
+typedef enum { CHECKTIME_OK, CHECKTIME_SKIP, CHECKTIME_STOP, CHECKTIME_INCONSISTENT } checkTimeResult;
+static checkTimeResult checkTime(stream_t* streamptr, compvar2_t compVar, const DateTime* verificationTime, const DateTime* expectedVTime) {
+  //First determine whether the current record exists already.
+  int recID = 0;
+  for ( ; recID < streamptr->nrecs; recID++ )
+    {
+      if ( gribapiVarCompare(compVar, streamptr->tsteps[0].records[recID], 1) == 0 ) break;
+    }
+  int recordExists = recID < streamptr->nrecs;
+
+  //Then we need to know whether the verification time is consistent.
+  int consistentTime = !memcmp(verificationTime, expectedVTime, sizeof(*verificationTime));
+
+  //Finally, we make a decision.
+  if ( cdiInventoryMode == 1 )
+    {
+      if ( recordExists ) return CHECKTIME_STOP;
+      if ( !consistentTime ) return CHECKTIME_INCONSISTENT;
+    }
+  else
+    {
+      if ( !consistentTime ) return CHECKTIME_STOP;
+      if ( recordExists ) return CHECKTIME_SKIP;
+    }
+  return CHECKTIME_OK;
+}
+
+#define gribWarning(text, nrecs, timestep, varname, param, level1, level2) do \
+  { \
+    char paramstr[32]; \
+    cdiParamToString(param, paramstr, sizeof(paramstr)); \
+    Warning("Record %2d (name=%s id=%s lev1=%d lev2=%d) timestep %d: %s", nrecs, varname, paramstr, level1, level2, timestep, text); \
+  } \
+while(0)
 
 int gribapiScanTimestep1(stream_t * streamptr)
 {
@@ -1155,236 +808,122 @@ int gribapiScanTimestep1(stream_t * streamptr)
   off_t recpos = 0;
   unsigned char *gribbuffer = NULL;
   size_t buffersize = 0;
-  int rstatus;
-  int status;
-  int fileID;
-  int rtabnum = 0;
-  int rcode = 0, level1 = 0, level2 = 0;
-  int vdate = 0, vtime = 0;
-  int param = 0;
-  DateTime datetime, datetime0;
-  int tsID;
-  int varID;
-  size_t readsize;
-  int nrecords, nrecs, recID;
-  int nrecs_scanned = 0;
-  int datatype;
-  size_t recsize = 0;
+  DateTime datetime0 = { .date = 10101, .time = 0 };
+  int nrecs_scanned = 0;        //Only used for debug output.
   int warn_time = TRUE;
   // int warn_numavg = TRUE;
-  int taxisID = -1;
   int rdate = 0, rtime = 0, tunit = 0, fcast = 0;
-  taxis_t *taxis;
-  int vlistID;
-  int comptype;
-  long unzipsize;
-  compvar2_t compVar;
   grib_handle *gh = NULL;
-  int leveltype1, leveltype2 = -1;
-  long editionNumber;
-  long lpar;
-  size_t len;
-  int bitsPerValue;
-  int lieee = FALSE;
-  int lbounds;
-  int level_sf, level_unit;
-  int tsteptype;
-  char paramstr[32];
-  char varname[256];
 
   streamptr->curTsID = 0;
 
-  tsID  = tstepsNewEntry(streamptr);
-  taxis = &streamptr->tsteps[tsID].taxis;
+  int tsID  = tstepsNewEntry(streamptr);
+  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
 
   if ( tsID != 0 )
     Error("Internal problem! tstepsNewEntry returns %d", tsID);
 
-  fileID = streamptr->fileID;
+  int fileID = streamptr->fileID;
 
-  nrecs = 0;
+  int nrecs = 0;
   while ( TRUE )
     {
-      level1 = 0;
-      level2 = 0;
-      recsize = (size_t)gribGetSize(fileID);
+      int level1 = 0, level2 = 0;
+      size_t recsize = (size_t)gribGetSize(fileID);
       recpos  = fileGetPos(fileID);
 
       if ( recsize == 0 )
-	{
-	  streamptr->ntsteps = 1;
-	  break;
-	}
-      if ( recsize > buffersize )
-	{
-	  buffersize = recsize;
-	  gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
-	}
+        {
+          streamptr->ntsteps = 1;
+          break;
+        }
+      ensureBufferSize(recsize, &buffersize, &gribbuffer);
 
-      readsize = recsize;
-      rstatus = gribRead(fileID, gribbuffer, &readsize);
+      size_t readsize = recsize;
+      int rstatus = gribRead(fileID, gribbuffer, &readsize);        //Search for next 'GRIB', read the following record, and position file offset after it.
       if ( rstatus ) break;
 
-      lieee = FALSE;
-
-      comptype = COMPRESS_NONE;
+      int datatype, comptype = 0;
+      long unzipsize;
+      gh = gribapiGetDiskRepresentation(recsize, &buffersize, &gribbuffer, &datatype, &comptype, &unzipsize);
 
       nrecs_scanned++;
-      gh = grib_handle_new_from_message(NULL, (void *) gribbuffer, recsize);
       GRIB_CHECK(my_grib_set_double(gh, "missingValue", cdiDefaultMissval), 0);
 
-      GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
-
-      if ( editionNumber <= 1 )
-	{
-          if ( gribGetZip((long)recsize, gribbuffer, &unzipsize) > 0 )
-            {
-              comptype = COMPRESS_SZIP;
-              unzipsize += 100;
-              if ( buffersize < (size_t)unzipsize )
-                {
-                  buffersize = (size_t)unzipsize;
-                  gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
-                }
-            }
-
-	  GRIB_CHECK(grib_get_long(gh, "table2Version", &lpar), 0);
-	  rtabnum = (int) lpar;
-	  GRIB_CHECK(grib_get_long(gh, "indicatorOfParameter", &lpar), 0);
-	  rcode = (int) lpar;
-
-	  param = cdiEncodeParam(rcode, rtabnum, 255);
-
-	  grib1GetLevel(gh, &leveltype1, &lbounds, &level1, &level2);
-          level_sf = 0;
-          level_unit = 0;
-	}
-      else
-	{
-	  size_t len = 256;
-	  char typeOfPacking[256];
-
-	  status = grib_get_string(gh, "packingType", typeOfPacking, &len);
-	  if ( status == 0 )
-	    {
-	      // fprintf(stderr, "packingType %d %s\n", len, typeOfPacking);
-	      if      ( strncmp(typeOfPacking, "grid_jpeg", len)  == 0 ) comptype = COMPRESS_JPEG;
-	      else if ( strncmp(typeOfPacking, "grid_ccsds", len) == 0 ) comptype = COMPRESS_SZIP;
-	      else if ( strncmp(typeOfPacking, "grid_ieee", len)  == 0 ) lieee = TRUE;
-	    }
-
-	  param = gribapiGetParam(gh);
-
-	  grib2GetLevel(gh, &leveltype1, &leveltype2, &lbounds, &level1, &level2, &level_sf, &level_unit);
-	}
-
-      cdiParamToString(param, paramstr, sizeof(paramstr));
+      int param = gribapiGetParam(gh);
+      int leveltype1 = -1, leveltype2 = -1, lbounds, level_sf, level_unit;
+      gribGetLevel(gh, &leveltype1, &leveltype2, &lbounds, &level1, &level2, &level_sf, &level_unit);
 
+      char varname[256];
       varname[0] = 0;
       gribapiGetString(gh, "shortName", varname, sizeof(varname));
-      len = strlen(varname);
-      if ( len > 32 ) len = 32;
-      //printf("param = %s  name = %s   l1 = %d  l2 = %d\n", paramstr, varname, level1, level2);
 
-      tsteptype = gribapiGetTsteptype(gh);
+      int tsteptype = gribapiGetTsteptype(gh);
+      int vdate = 0, vtime = 0;
       gribapiGetValidityDateTime(gh, &vdate, &vtime);
+      DateTime datetime = { .date = vdate, .time = vtime };
       /*
       printf("%d %d %d\n", vdate, vtime, leveltype1);
       */
-      if ( lieee )
+
+      if( datetime0.date == 10101 && datetime0.time == 0 )
         {
-          datatype = DATATYPE_FLT64;
-          status = grib_get_long(gh, "precision", &lpar);
-          if ( status == 0 && lpar == 1 ) datatype = DATATYPE_FLT32;
+          if( memcmp(&datetime, &datetime0, sizeof(datetime)) || !nrecs )       //Do we really need this condition? I have included it in order not to change the number of times gribapiGetDataDateTime() etc. get called. But if those are sideeffect-free, this condition should be removed.
+            {
+              datetime0 = datetime;
+
+              gribapiGetDataDateTime(gh, &rdate, &rtime);
+
+              fcast = gribapiTimeIsFC(gh);
+              if ( fcast ) tunit = gribapiGetTimeUnits(gh);
+            }
         }
-      else
+
+      if(nrecs)
         {
-          datatype = DATATYPE_PACK;
-          status = grib_get_long(gh, "bitsPerValue", &lpar);
-          if ( status == 0 )
+          checkTimeResult result = checkTime(streamptr, gribapiVarSet(param, level1, level2, leveltype1, tsteptype, varname), &datetime, &datetime0);
+          if(result == CHECKTIME_STOP)
             {
-              bitsPerValue = (int) lpar;
-              if ( bitsPerValue > 0 && bitsPerValue <= 32 )
-                datatype = bitsPerValue;
+              break;
             }
+          else if(result == CHECKTIME_SKIP)
+            {
+              gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, varname, param, level1, level2);
+              continue;
+            }
+          else if(result == CHECKTIME_INCONSISTENT && warn_time)
+            {
+              gribWarning("Inconsistent verification time!", nrecs_scanned, tsID+1, varname, param, level1, level2);
+              warn_time = FALSE;
+            }
+          assert(result == CHECKTIME_OK || result == CHECKTIME_INCONSISTENT);
         }
-
-      if ( nrecs == 0 )
-	{
-	  datetime0.date = vdate;
-	  datetime0.time = vtime;
-
-          gribapiGetDataDateTime(gh, &rdate, &rtime);
-
-	  fcast = gribapiTimeIsFC(gh);
-	  if ( fcast ) tunit = gribapiGetTimeUnits(gh);
-	}
-      else
-	{
-	  datetime.date  = vdate;
-	  datetime.time  = vtime;
-
-	  compVar = gribapiVarSet(param, level1, level2, leveltype1, tsteptype, varname);
-
-	  for ( recID = 0; recID < nrecs; recID++ )
-            if ( gribapiVarCompare(compVar, streamptr->tsteps[0].records[recID], 1) == 0 ) break;
-
-	  if ( cdiInventoryMode == 1 )
-	    {
-	      if ( recID < nrecs ) break;
-	      if ( warn_time )
-		if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 )
-		  {
-                    if ( datetime0.date == 10101 && datetime0.time == 0 )
-                      {
-                        datetime0.date = datetime.date;
-                        datetime0.time = datetime.time;
-
-                        gribapiGetDataDateTime(gh, &rdate, &rtime);
-
-                        fcast = gribapiTimeIsFC(gh);
-                        if ( fcast ) tunit = gribapiGetTimeUnits(gh);
-                      }
-                    else
-                      {
-                        gribWarning("Inconsistent verification time!", nrecs_scanned, tsID+1, varname, paramstr, level1, level2);
-                        warn_time = FALSE;
-                      }
-                  }
-	    }
-	  else
-	    {
-	      if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;
-
-	      if ( recID < nrecs )
-		{
-		  gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, varname, paramstr, level1, level2);
-		  continue;
-		}
-	    }
-	}
       /*
       if ( ISEC1_AvgNum )
-	{
-	  if (  taxis->numavg && warn_numavg && (taxis->numavg != ISEC1_AvgNum) )
-	    {
-	      Message("Change numavg from %d to %d not allowed!",
-		      taxis->numavg, ISEC1_AvgNum);
-	      warn_numavg = FALSE;
-	    }
-	  else
-	    {
-	      taxis->numavg = ISEC1_AvgNum;
-	    }
-	}
+        {
+          if (  taxis->numavg && warn_numavg && (taxis->numavg != ISEC1_AvgNum) )
+            {
+              Message("Change numavg from %d to %d not allowed!",
+                      taxis->numavg, ISEC1_AvgNum);
+              warn_numavg = FALSE;
+            }
+          else
+            {
+              taxis->numavg = ISEC1_AvgNum;
+            }
+        }
       */
       nrecs++;
 
       if ( CDI_Debug )
-	Message("%4d %8d name=%s id=%s ltype=%d lev1=%d lev2=%d vdate=%d vtime=%d",
+        {
+          char paramstr[32];
+          cdiParamToString(param, paramstr, sizeof(paramstr));
+          Message("%4d %8d name=%s id=%s ltype=%d lev1=%d lev2=%d vdate=%d vtime=%d",
                 nrecs, (int)recpos, varname, paramstr, leveltype1, level1, level2, vdate, vtime);
+        }
 
-      gribapiAddRecord(streamptr, param, gh, recsize, recpos, datatype, comptype, len, varname,
+      gribapiAddRecord(streamptr, param, gh, recsize, recpos, datatype, comptype, varname,
                        leveltype1, leveltype2, lbounds, level1, level2, level_sf, level_unit);
 
       grib_handle_delete(gh);
@@ -1399,6 +938,7 @@ int gribapiScanTimestep1(stream_t * streamptr)
 
   cdi_generate_vars(streamptr);
 
+  int taxisID = -1;
   if ( fcast )
     {
       taxisID = taxisCreate(TAXIS_RELATIVE);
@@ -1416,11 +956,11 @@ int gribapiScanTimestep1(stream_t * streamptr)
   taxis->vdate = (int)datetime0.date;
   taxis->vtime = (int)datetime0.time;
 
-  vlistID = streamptr->vlistID;
+  int vlistID = streamptr->vlistID;
   vlistDefTaxis(vlistID, taxisID);
 
-  nrecords = streamptr->tsteps[0].nallrecs;
-  if ( nrecords < streamptr->tsteps[0].recordSize )
+  int nrecords = streamptr->tsteps[0].nallrecs;
+  if ( nrecords > streamptr->tsteps[0].recordSize )
     {
       streamptr->tsteps[0].recordSize = nrecords;
       streamptr->tsteps[0].records =
@@ -1429,7 +969,7 @@ int gribapiScanTimestep1(stream_t * streamptr)
 
   streamptr->tsteps[0].recIDs = (int *) malloc(nrecords*sizeof(int));
   streamptr->tsteps[0].nrecs = nrecords;
-  for ( recID = 0; recID < nrecords; recID++ )
+  for ( int recID = 0; recID < nrecords; recID++ )
     streamptr->tsteps[0].recIDs[recID] = recID;
 
   streamptr->record->buffer     = gribbuffer;
@@ -1439,7 +979,7 @@ int gribapiScanTimestep1(stream_t * streamptr)
     {
       tsID = tstepsNewEntry(streamptr);
       if ( tsID != streamptr->rtsteps )
-	Error("Internal error. tsID = %d", tsID);
+        Error("Internal error. tsID = %d", tsID);
 
       streamptr->tsteps[tsID-1].next   = TRUE;
       streamptr->tsteps[tsID].position = recpos;
@@ -1448,13 +988,13 @@ int gribapiScanTimestep1(stream_t * streamptr)
   if ( streamptr->ntsteps == 1 )
     {
       if ( taxis->vdate == 0 && taxis->vtime == 0 )
-	{
-	  streamptr->ntsteps = 0;
-	  for ( varID = 0; varID < streamptr->nvars; varID++ )
-	    {
-	      vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
-	    }
-	}
+        {
+          streamptr->ntsteps = 0;
+          for ( int varID = 0; varID < streamptr->nvars; varID++ )
+            {
+              vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
+            }
+        }
     }
 #else
   (void)streamptr;
@@ -1473,53 +1013,32 @@ int gribapiScanTimestep2(stream_t * streamptr)
   unsigned char *gribbuffer = NULL;
   size_t buffersize = 0;
   int fileID;
-  int rtabnum = 0;
-  int rcode = 0, level1 = 0, level2 = 0, vdate = 0, vtime = 0;
-  DateTime datetime, datetime0;
-  int tsID;
-  int varID;
+  DateTime datetime0;
   // int gridID;
-  size_t readsize;
-  int nrecords, nrecs, recID, rindex;
-  int nrecs_scanned = 0;
-  size_t recsize = 0;
+  int recID;
   //  int warn_numavg = TRUE;
-  int tsteptype;
-  int taxisID = -1;
-  taxis_t *taxis;
-  int vlistID;
-  long unzipsize;
-  compvar2_t compVar;
   grib_handle *gh = NULL;
-  int leveltype1, leveltype2 = -1;
-  int param = 0;
-  long editionNumber;
-  long lpar;
-  int lbounds;
-  int level_sf, level_unit;
-  char paramstr[32];
-  char varname[256];
 
   streamptr->curTsID = 1;
 
   fileID  = streamptr->fileID;
-  vlistID = streamptr->vlistID;
-  taxisID = vlistInqTaxis(vlistID);
+  int vlistID = streamptr->vlistID;
+  int taxisID = vlistInqTaxis(vlistID);
 
   gribbuffer = (unsigned char *) streamptr->record->buffer;
   buffersize = streamptr->record->buffersize;
 
-  tsID = streamptr->rtsteps;
+  int tsID = streamptr->rtsteps;
   if ( tsID != 1 )
     Error("Internal problem! unexpected timestep %d", tsID+1);
 
-  taxis = &streamptr->tsteps[tsID].taxis;
+  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
 
   fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
   cdi_create_records(streamptr, tsID);
 
-  nrecords = streamptr->tsteps[tsID].nallrecs;
+  int nrecords = streamptr->tsteps[tsID].nallrecs;
   streamptr->tsteps[1].recIDs = (int *) malloc(nrecords*sizeof(int));
   streamptr->tsteps[1].nrecs = 0;
   for ( recID = 0; recID < nrecords; recID++ )
@@ -1527,75 +1046,45 @@ int gribapiScanTimestep2(stream_t * streamptr)
 
   for ( recID = 0; recID < nrecords; recID++ )
     {
-      varID = streamptr->tsteps[0].records[recID].varID;
       streamptr->tsteps[tsID].records[recID].position = streamptr->tsteps[0].records[recID].position;
       streamptr->tsteps[tsID].records[recID].size     = streamptr->tsteps[0].records[recID].size;
     }
 
-  nrecs_scanned = nrecords;
-  rindex = 0;
+  int nrecs_scanned = nrecords; //Only used for debug output
+  int rindex = 0;
   while ( TRUE )
     {
       if ( rindex > nrecords ) break;
 
-      recsize = (size_t)gribGetSize(fileID);
+      size_t recsize = (size_t)gribGetSize(fileID);
       recpos  = fileGetPos(fileID);
       if ( recsize == 0 )
 	{
 	  streamptr->ntsteps = 2;
 	  break;
 	}
-      if ( recsize > buffersize )
-	{
-	  buffersize = recsize;
-	  gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
-	}
+      ensureBufferSize(recsize, &buffersize, &gribbuffer);
 
-      readsize = recsize;
+      size_t readsize = recsize;
       rstatus = gribRead(fileID, gribbuffer, &readsize);
       if ( rstatus ) break;
 
-      if ( gribGetZip((long)recsize, gribbuffer, &unzipsize) > 0 )
-	{
-	  unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
-	  if ( buffersize < (size_t)unzipsize )
-	    {
-	      buffersize = (size_t)unzipsize;
-	      gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
-	    }
-	}
+      long unzipsize;
+      if ( gribGetZip((long)recsize, gribbuffer, &unzipsize) > 0 ) ensureBufferSize(unzipsize + 100, &buffersize, &gribbuffer);
 
       nrecs_scanned++;
       gh = grib_handle_new_from_message(NULL, (void *) gribbuffer, recsize);
       GRIB_CHECK(my_grib_set_double(gh, "missingValue", cdiDefaultMissval), 0);
 
-      GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
-
-      if ( editionNumber <= 1 )
-	{
-	  GRIB_CHECK(grib_get_long(gh, "table2Version", &lpar), 0);
-	  rtabnum = (int) lpar;
-	  GRIB_CHECK(grib_get_long(gh, "indicatorOfParameter", &lpar), 0);
-	  rcode = (int) lpar;
-
-	  param = cdiEncodeParam(rcode, rtabnum, 255);
-
-	  grib1GetLevel(gh, &leveltype1, &lbounds, &level1, &level2);
-          level_sf = 0;
-          level_unit = 0;
-	}
-      else
-	{
-	  param = gribapiGetParam(gh);
-
-	  grib2GetLevel(gh, &leveltype1, &leveltype2, &lbounds, &level1, &level2, &level_sf, &level_unit);
-	}
-
-      cdiParamToString(param, paramstr, sizeof(paramstr));
+      int param = gribapiGetParam(gh);
+      int level1 = 0, level2 = 0, leveltype1, leveltype2, lbounds, level_sf, level_unit;
+      gribGetLevel(gh, &leveltype1, &leveltype2, &lbounds, &level1, &level2, &level_sf, &level_unit);
 
+      char varname[256];
       varname[0] = 0;
       gribapiGetString(gh, "shortName", varname, sizeof(varname));
 
+      int vdate = 0, vtime = 0;
       gribapiGetValidityDateTime(gh, &vdate, &vtime);
 
       if ( rindex == 0 )
@@ -1619,7 +1108,7 @@ int gribapiScanTimestep2(stream_t * streamptr)
 	  datetime0.time = vtime;
 	}
 
-      tsteptype = gribapiGetTsteptype(gh);
+      int tsteptype = gribapiGetTsteptype(gh);
       /*
       if ( ISEC1_AvgNum )
 	{
@@ -1634,17 +1123,19 @@ int gribapiScanTimestep2(stream_t * streamptr)
 	    }
 	}
       */
-      datetime.date  = vdate;
-      datetime.time  = vtime;
+      DateTime datetime = {
+        .date = vdate,
+        .time = vtime
+      };
 
-      compVar = gribapiVarSet(param, level1, level2, leveltype1, tsteptype, varname);
+      compvar2_t compVar = gribapiVarSet(param, level1, level2, leveltype1, tsteptype, varname);
 
       for ( recID = 0; recID < nrecords; recID++ )
         if ( gribapiVarCompare(compVar, streamptr->tsteps[tsID].records[recID], 0) == 0 ) break;
 
       if ( recID == nrecords )
 	{
-	  gribWarning("Parameter not defined at timestep 1!", nrecs_scanned, tsID+1, varname, paramstr, level1, level2);
+	  gribWarning("Parameter not defined at timestep 1!", nrecs_scanned, tsID+1, varname, param, level1, level2);
 	  return (CDI_EUFSTRUCT);
 	}
 
@@ -1655,7 +1146,7 @@ int gribapiScanTimestep2(stream_t * streamptr)
 	    {
 	      if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;
 
-              gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, varname, paramstr, level1, level2);
+              gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, varname, param, level1, level2);
 	      continue;
 	    }
 	}
@@ -1664,8 +1155,12 @@ int gribapiScanTimestep2(stream_t * streamptr)
       streamptr->tsteps[tsID].recIDs[rindex] = recID;
 
       if ( CDI_Debug )
-	Message("%4d %8d name=%s id=%s ltype=%d lev1=%d lev2=%d vdate=%d vtime=%d",
-                nrecs_scanned, (int)recpos, varname, paramstr, leveltype1, level1, level2, vdate, vtime);
+        {
+          char paramstr[32];
+          cdiParamToString(param, paramstr, sizeof(paramstr));
+          Message("%4d %8d name=%s id=%s ltype=%d lev1=%d lev2=%d vdate=%d vtime=%d",
+                  nrecs_scanned, (int)recpos, varname, paramstr, leveltype1, level1, level2, vdate, vtime);
+        }
 
       streamptr->tsteps[tsID].records[recID].size = recsize;
 
@@ -1679,7 +1174,7 @@ int gribapiScanTimestep2(stream_t * streamptr)
 	}
 
       streamptr->tsteps[1].records[recID].position = recpos;
-      varID = streamptr->tsteps[tsID].records[recID].varID;
+      int varID = streamptr->tsteps[tsID].records[recID].varID;
       /*
       gridID = vlistInqVarGrid(vlistID, varID);
       if ( gridInqSize(gridID) == 1 && gridInqType(gridID) == GRID_LONLAT )
@@ -1700,12 +1195,12 @@ int gribapiScanTimestep2(stream_t * streamptr)
 
   if ( gh ) grib_handle_delete(gh);
 
-  nrecs = 0;
+  int nrecs = 0;
   for ( recID = 0; recID < nrecords; recID++ )
     {
       if ( ! streamptr->tsteps[tsID].records[recID].used )
 	{
-	  varID = streamptr->tsteps[tsID].records[recID].varID;
+	  int varID = streamptr->tsteps[tsID].records[recID].varID;
 	  vlistDefVarTsteptype(vlistID, varID, TSTEP_CONSTANT);
 	}
       else
@@ -1738,37 +1233,10 @@ int gribapiScanTimestep2(stream_t * streamptr)
 #if  defined  (HAVE_LIBGRIB_API)
 int gribapiScanTimestep(stream_t * streamptr)
 {
-  int rstatus = 0;
-  size_t recsize = 0;
-  off_t recpos = 0;
-  unsigned char *gribbuffer;
-  size_t buffersize = 0;
-  int fileID;
-  int rtabnum = 0;
-  int rcode = 0, level1 = 0, level2 = 0, vdate = 0, vtime = 0;
-  DateTime datetime, datetime0;
-  int tsID;
   int vrecID, recID;
   //int warn_numavg = TRUE;
-  size_t readsize;
-  int taxisID = -1;
-  taxis_t *taxis;
-  int vlistID;
-  int rindex, nrecs = 0;
-  int nrecs_scanned;
-  long unzipsize;
-  compvar2_t compVar;
-  grib_handle *gh = NULL;
-  int leveltype1, leveltype2 = -1;
-  int param = 0;
-  long editionNumber;
-  long lpar;
-  int lbounds;
-  int level_sf, level_unit;
-  char paramstr[32];
-  char varname[256];
-
-  vlistID = streamptr->vlistID;
+  int nrecs = 0;
+  int vlistID = streamptr->vlistID;
 
   if ( CDI_Debug )
     {
@@ -1778,13 +1246,13 @@ int gribapiScanTimestep(stream_t * streamptr)
       Message("nts = %d", streamptr->ntsteps);
     }
 
-  tsID  = streamptr->rtsteps;
-  taxis = &streamptr->tsteps[tsID].taxis;
+  int tsID  = streamptr->rtsteps;
+  taxis_t *taxis = &streamptr->tsteps[tsID].taxis;
 
   if ( streamptr->tsteps[tsID].recordSize == 0 )
     {
-      gribbuffer = (unsigned char *) streamptr->record->buffer;
-      buffersize = streamptr->record->buffersize;
+      unsigned char* gribbuffer = (unsigned char *) streamptr->record->buffer;
+      size_t buffersize = streamptr->record->buffersize;
 
       cdi_create_records(streamptr, tsID);
 
@@ -1795,17 +1263,21 @@ int gribapiScanTimestep(stream_t * streamptr)
       for ( recID = 0; recID < nrecs; recID++ )
 	streamptr->tsteps[tsID].recIDs[recID] = streamptr->tsteps[1].recIDs[recID];
 
-      fileID = streamptr->fileID;
+      int fileID = streamptr->fileID;
 
       fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET);
 
-      nrecs_scanned = streamptr->tsteps[0].nallrecs + streamptr->tsteps[1].nrecs*(tsID-1);
-      rindex = 0;
+      int nrecs_scanned = streamptr->tsteps[0].nallrecs + streamptr->tsteps[1].nrecs*(tsID-1);    //Only used for debug output.
+      int rindex = 0;
+      off_t recpos = 0;
+      DateTime datetime0;
+      grib_handle *gh = NULL;
+      char varname[256];
       while ( TRUE )
 	{
 	  if ( rindex > nrecs ) break;
 
-	  recsize = (size_t)gribGetSize(fileID);
+	  size_t recsize = (size_t)gribGetSize(fileID);
 	  recpos  = fileGetPos(fileID);
 	  if ( recsize == 0 )
 	    {
@@ -1815,69 +1287,38 @@ int gribapiScanTimestep(stream_t * streamptr)
 
 	  if ( rindex >= nrecs ) break;
 
-	  if ( recsize > buffersize )
-	    {
-	      buffersize = recsize;
-	      gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
-	    }
+          ensureBufferSize(recsize, &buffersize, &gribbuffer);
 
-	  readsize = recsize;
-	  rstatus = gribRead(fileID, gribbuffer, &readsize);
-	  if ( rstatus )
+	  size_t readsize = recsize;
+	  if (gribRead(fileID, gribbuffer, &readsize))
 	    {
 	      Warning("Inconsistent timestep %d (GRIB record %d/%d)!", tsID+1, rindex+1,
 		      streamptr->tsteps[tsID].recordSize);
 	      break;
 	    }
 
-	  if ( gribGetZip((long)recsize, gribbuffer, &unzipsize) > 0 )
-	    {
-	      unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */
-	      if ( buffersize < (size_t)unzipsize )
-		{
-		  buffersize = (size_t)unzipsize;
-		  gribbuffer = (unsigned char *) realloc(gribbuffer, buffersize);
-		}
-	    }
+          long unzipsize;
+	  if ( gribGetZip((long)recsize, gribbuffer, &unzipsize) > 0 ) ensureBufferSize(unzipsize + 100, &buffersize, &gribbuffer);
 
           nrecs_scanned++;
 	  gh = grib_handle_new_from_message(NULL, (void *) gribbuffer, recsize);
 	  GRIB_CHECK(my_grib_set_double(gh, "missingValue", cdiDefaultMissval), 0);
 
-	  GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
-
-	  if ( editionNumber <= 1 )
-	    {
-	      GRIB_CHECK(grib_get_long(gh, "table2Version", &lpar), 0);
-	      rtabnum = (int) lpar;
-	      GRIB_CHECK(grib_get_long(gh, "indicatorOfParameter", &lpar), 0);
-	      rcode = (int) lpar;
-
-	      param = cdiEncodeParam(rcode, rtabnum, 255);
-
-	      grib1GetLevel(gh, &leveltype1, &lbounds, &level1, &level2);
-              level_sf = 0;
-              level_unit = 0;
-	    }
-	  else
-	    {
-	      param = gribapiGetParam(gh);
-
-	      grib2GetLevel(gh, &leveltype1, &leveltype2, &lbounds, &level1, &level2, &level_sf, &level_unit);
-	    }
-
-          cdiParamToString(param, paramstr, sizeof(paramstr));
+          int param = gribapiGetParam(gh);
+          int level1 = 0, level2 = 0, leveltype1, leveltype2 = -1, lbounds, level_sf, level_unit;
+          gribGetLevel(gh, &leveltype1, &leveltype2, &lbounds, &level1, &level2, &level_sf, &level_unit);
 
           varname[0] = 0;
 	  gribapiGetString(gh, "shortName", varname, sizeof(varname));
 
+          int vdate = 0, vtime = 0;
 	  gribapiGetValidityDateTime(gh, &vdate, &vtime);
 
 	  if ( rindex == nrecs ) break;
 
 	  if ( rindex == 0 )
 	    {
-	      taxisID = vlistInqTaxis(vlistID);
+              int taxisID = vlistInqTaxis(vlistID);
 	      if ( taxisInqType(taxisID) == TAXIS_RELATIVE )
 		{
 		  taxis->type  = TAXIS_RELATIVE;
@@ -1910,12 +1351,14 @@ int gribapiScanTimestep(stream_t * streamptr)
 		}
 	    }
 	  */
-	  datetime.date  = vdate;
-	  datetime.time  = vtime;
+          DateTime datetime = {
+            .date  = vdate,
+            .time  = vtime
+          };
 
           int tsteptype = gribapiGetTsteptype(gh);
 
-	  compVar = gribapiVarSet(param, level1, level2, leveltype1, tsteptype, varname);
+          compvar2_t compVar = gribapiVarSet(param, level1, level2, leveltype1, tsteptype, varname);
 
 	  for ( vrecID = 0; vrecID < nrecs; vrecID++ )
 	    {
@@ -1925,7 +1368,7 @@ int gribapiScanTimestep(stream_t * streamptr)
 
 	  if ( vrecID == nrecs )
 	    {
-	      gribWarning("Parameter not defined at timestep 1!", nrecs_scanned, tsID+1, varname, paramstr, level1, level2);
+	      gribWarning("Parameter not defined at timestep 1!", nrecs_scanned, tsID+1, varname, param, level1, level2);
 
 	      if ( cdiInventoryMode == 1 )
 		return (CDI_EUFSTRUCT);
@@ -1940,7 +1383,7 @@ int gribapiScanTimestep(stream_t * streamptr)
 		  if ( memcmp(&datetime, &datetime0, sizeof(DateTime)) != 0 ) break;
 
 		  if ( CDI_Debug )
-                    gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, varname, paramstr, level1, level2);
+                    gribWarning("Parameter already exist, skipped!", nrecs_scanned, tsID+1, varname, param, level1, level2);
 
 		  continue;
 		}
@@ -1983,8 +1426,7 @@ int gribapiScanTimestep(stream_t * streamptr)
 
       if ( vrecID < nrecs )
 	{
-	  cdiParamToString(streamptr->tsteps[tsID].records[recID].param, paramstr, sizeof(paramstr));
-	  gribWarning("Paramameter not found!", nrecs_scanned, tsID+1, varname, paramstr,
+	  gribWarning("Paramameter not found!", nrecs_scanned, tsID+1, varname, streamptr->tsteps[tsID].records[recID].param,
                       streamptr->tsteps[tsID].records[recID].ilevel, streamptr->tsteps[tsID].records[recID].ilevel2);
 	  return (CDI_EUFSTRUCT);
 	}
@@ -2014,8 +1456,7 @@ int gribapiScanTimestep(stream_t * streamptr)
       streamptr->ntsteps = tsID;
     }
 
-  rstatus = (int)streamptr->ntsteps;
-  return (rstatus);
+  return (int)streamptr->ntsteps;
 }
 #endif
 
@@ -2029,7 +1470,7 @@ int gribapiDecode(unsigned char *gribbuffer, int gribsize, double *data, int gri
 {
   int status = 0;
   long lpar;
-  long editionNumber, numberOfPoints;
+  long numberOfPoints;
   size_t datasize, dummy, recsize;
   grib_handle *gh = NULL;
 
@@ -2051,8 +1492,6 @@ int gribapiDecode(unsigned char *gribbuffer, int gribsize, double *data, int gri
   gh = grib_handle_new_from_message(NULL, (void *) gribbuffer, recsize);
   GRIB_CHECK(my_grib_set_double(gh, "missingValue", missval), 0);
 
-  GRIB_CHECK(grib_get_long(gh, "editionNumber", &editionNumber), 0);
-
   /* get the size of the values array*/
   GRIB_CHECK(grib_get_size(gh, "values", &datasize), 0);
   GRIB_CHECK(grib_get_long(gh, "numberOfPoints", &numberOfPoints), 0);
@@ -3044,7 +2483,9 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
                 size_t len = CDI_UUID_SIZE;
                 zaxisInqUUID(zaxisID, uuid);
                 if (grib_set_bytes(gh, "uuidOfVGrid", uuid, &len) != 0)
-                  Warning("Can't write UUID!");
+                  {
+                    Warning("Can't write UUID!");
+                  }
                 GRIB_CHECK(my_grib_set_long(gh, "topLevel", (long) dlevel1), 0);
                 GRIB_CHECK(my_grib_set_long(gh, "bottomLevel", (long) dlevel2), 0);
               }
@@ -3063,7 +2504,9 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
                 size_t len = CDI_UUID_SIZE;
                 zaxisInqUUID(zaxisID, uuid);
                 if (grib_set_bytes(gh, "uuidOfVGrid", uuid, &len) != 0)
-                  Warning("Can't write UUID!");
+                  {
+                    Warning("Can't write UUID!");
+                  }
                 GRIB_CHECK(my_grib_set_double(gh, "level", level), 0);
               }
           }
diff --git a/src/stream_gribapi.h b/src/stream_gribapi.h
index b950b86d03d888cd4ec4ed0e15af1666b7c07514..6c136bd72e13da3c0818f93d2212d792c6fbf744 100644
--- a/src/stream_gribapi.h
+++ b/src/stream_gribapi.h
@@ -1,7 +1,9 @@
 #ifndef _STREAM_GRIBAPI_H
 #define _STREAM_GRIBAPI_H
 
+#ifndef  _CDI_INT_H
 #include "cdi_int.h"
+#endif
 
 int gribapiScanTimestep1(stream_t * streamptr);
 int gribapiScanTimestep2(stream_t * streamptr);
diff --git a/src/table.c b/src/table.c
index 72d0911f9fd9405feeb141c53c5045324fb140c0..bd7ec02db9867d63fcb4849a7fceb993965783a8 100644
--- a/src/table.c
+++ b/src/table.c
@@ -590,9 +590,9 @@ static void partabCheckID(int item)
     Error("item %d name undefined!", item);
 }
 
-char *tableInqNamePtr(int tableID)
+const char *tableInqNamePtr(int tableID)
 {
-  char *tablename = NULL;
+  const char *tablename = NULL;
 
   if ( CDI_Debug )
     Message("tableID = %d", tableID);
diff --git a/src/taxis.c b/src/taxis.c
index fb11e1817ba99aae3a66b841b8fcb2f4936f3c8e..f1ac7ed328fb8238a0baf38ff3da115018836d05 100644
--- a/src/taxis.c
+++ b/src/taxis.c
@@ -24,7 +24,7 @@ static int DefaultTimeType = TAXIS_ABSOLUTE;
 static int DefaultTimeUnit = TUNIT_HOUR;
 
 
-char *Timeunits[] = {
+const char *Timeunits[] = {
   "undefined",
   "seconds",
   "minutes",
@@ -105,10 +105,10 @@ dup_refcount_string(char *p)
 static int  TAXIS_Debug = 0;   /* If set to 1, debugging */
 
 
-char *tunitNamePtr(int unitID)
+const char *tunitNamePtr(int unitID)
 {
-  char *name;
-  int size = sizeof(Timeunits)/sizeof(char *);
+  const char *name;
+  int size = sizeof(Timeunits)/sizeof(*Timeunits);
 
   if ( unitID > 0 && unitID < size )
     name = Timeunits[unitID];
diff --git a/src/util.c b/src/util.c
index 1068477a5150a762b1dba21d2f54d0bc1f2197dc..8c33813f0b807ac80f3f6154fee3de96b72ce9f9 100644
--- a/src/util.c
+++ b/src/util.c
@@ -94,6 +94,61 @@ int str2uuid(const char *uuidstr, unsigned char *uuid)
   return iret;
 }
 
+//Returns a malloc'ed string that escapes all spaces and backslashes with backslashes.
+char* cdiEscapeSpaces(const char* string)
+{
+  //How much memory do we need?
+  size_t escapeCount = 0, length = 0;
+  for(const char* current = string; *current; current++)
+    {
+      if(strchr(" \\", *current)) escapeCount++;
+      length++;
+    }
+
+  char* result = malloc(length + escapeCount + 1);
+  if(!result) return NULL;
+
+  //Do the escaping.
+  for(size_t in = 0, out = 0; in < length;)
+    {
+      if(strchr(" \\", string[in])) result[out++] = '\\';
+      result[out++] = string[in++];
+    }
+  result[length + escapeCount] = 0;     //termination!
+  return result;
+}
+
+//input: a space terminated string that may contain escaped characters
+//output: a new zero terminated string with the escape characters removed
+//*outStringEnd points to the terminating character upon return.
+char* cdiUnescapeSpaces(const char* string, const char** outStringEnd)
+{
+  //How much memory do we need?
+  size_t escapeCount = 0, length = 0;
+  for(const char* current = string; *current && *current != ' '; current++)
+    {
+      if(*current == '\\')
+        {
+          current++, escapeCount++;
+          if(!current) return NULL;
+        }
+      length++;
+    }
+
+  char* result = malloc(length + 1);
+  if(!result) return NULL;
+
+  //Do the unescaping.
+  for(size_t in = 0, out = 0; out < length;)
+    {
+      if(string[in] == '\\') in++;
+      result[out++] = string[in++];
+    }
+  result[length] = 0;   //termination!
+  if(outStringEnd) *outStringEnd = &string[length + escapeCount];
+  return result;
+}
+
 #ifdef HAVE_DECL_UUID_GENERATE
 #include <sys/time.h>
 #include <uuid/uuid.h>
diff --git a/src/vlist.h b/src/vlist.h
index 79ed9df7d407205f3a230a4362a582a5fdced909..5a4ff73c910fae428a352eae59ba0cd3cc3a4d79 100644
--- a/src/vlist.h
+++ b/src/vlist.h
@@ -5,12 +5,14 @@
 #include "config.h"
 #endif
 
+#ifndef  _ERROR_H
 #include "error.h"
+#endif
 
 #include <stddef.h>  /* size_t */
 
 #ifndef _CDI_LIMITS_H
-#  include "cdi_limits.h"
+#include "cdi_limits.h"
 #endif
 
 #define VALIDMISS 1.e+303
@@ -150,6 +152,7 @@ vlist_t;
 
 
 vlist_t *vlist_to_pointer(int vlistID);
+void vlistCheckVarID(const char *caller, int vlistID, int varID);
 const char *vlistInqVarNamePtr(int vlistID, int varID);
 const char *vlistInqVarLongnamePtr(int vlistID, int varID);
 const char *vlistInqVarStdnamePtr(int vlistID, int varID);
diff --git a/src/vlist_var.c b/src/vlist_var.c
index 46a74e6e263b0d84f44a6e65c847bc14dec6ff3f..1217bc10f3333e64bfb52235ef1fa080cdd5e64a 100644
--- a/src/vlist_var.c
+++ b/src/vlist_var.c
@@ -14,6 +14,14 @@
 #include "namespace.h"
 #include "serialize.h"
 #include "error.h"
+#include "proprietarySystemWorkarounds.h"
+
+#if  defined  (HAVE_LIBGRIB_API)
+#  include "file.h"
+
+#  include <grib_api.h>
+#endif
+
 
 static
 void vlistvarInitEntry(int vlistID, int varID)
@@ -128,7 +136,6 @@ int vlistvarNewEntry(int vlistID)
   return (varID);
 }
 
-static
 void vlistCheckVarID(const char *caller, int vlistID, int varID)
 {
   vlist_t *vlistptr = vlist_to_pointer(vlistID);
@@ -501,6 +508,49 @@ void vlistInqVarName(int vlistID, int varID, char *name)
   return;
 }
 
+/*
+@Function vlistCopyVarName
+@Tatle    Get the name of a Variable in a safe way
+
+@Prototype char* vlistCopyVarName(int vlistId, int varId)
+@Parameter
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
+    @Item  varID    Variable identifier.
+
+@Return A pointer to a malloc'ed string. Must be cleaned up with free().
+
+@Description
+This is the buffer overflow immune version of vlistInqVarName().
+The memory for the returned string is allocated to fit the string via malloc().
+
+@EndFunction
+*/
+char* vlistCopyVarName(int vlistId, int varId)
+{
+  vlist_t* vlistptr = vlist_to_pointer(vlistId);
+  vlistCheckVarID(__func__, vlistId, varId);
+
+  //If a name is set in the variable description, use that.
+  const char* name = vlistptr->vars[varId].name;
+  if(name) return myStrDup(name);
+
+  //Otherwise we check if we should use the table of parameter descriptions.
+  int param = vlistptr->vars[varId].param;
+  int discipline, category, number;
+  cdiDecodeParam(param, &number, &category, &discipline);
+  if(discipline == 255)
+    {
+      int tableId = vlistptr->vars[varId].tableID;
+      if(( name = tableInqParNamePtr(tableId, number) )) return myStrDup(name);
+
+      //No luck, fall back to outputting a name of the format "var<num>".
+      return myAsprintf("var%d", number);
+    }
+
+  //Finally, we fall back to outputting a name of the format "param<num>.<cat>.<dis>".
+  return myAsprintf("param%d.%d.%d", number, category, discipline);
+}
+
 /*
 @Function  vlistInqVarLongname
 @Title     Get the longname of a Variable
@@ -1773,11 +1823,6 @@ void vlistDefVarDblKey(int vlistID, int varID, const char *name, double value)
 #endif
 }
 
-#if  defined  (HAVE_LIBGRIB_API)
-#  include "file.h"
-#  include "grib_api.h"
-#endif
-
 
 /* cdiClearAdditionalKeys: Clears the list of additional GRIB keys. */
 void cdiClearAdditionalKeys()
diff --git a/src/zaxis.c b/src/zaxis.c
index d46bf5e10bdfb78ee2f6c701ae1f0d9c52d734cd..641808bd2903235227756cd04e442fd894c926ef 100644
--- a/src/zaxis.c
+++ b/src/zaxis.c
@@ -105,6 +105,26 @@ const resOps zaxisOps = {
 
 static int  ZAXIS_Debug = 0;   /* If set to 1, debugging */
 
+void zaxisGetTypeDescription(int zaxisType, int* outPositive, const char** outName, const char** outLongName, const char** outStdName, const char** outUnit)
+{
+  if(zaxisType < 0 || zaxisType >= CDI_NumZaxistype)
+    {
+      if(outPositive) *outPositive = 0;
+      if(outName) *outName = NULL;
+      if(outLongName) *outLongName = NULL;
+      if(outStdName) *outStdName = NULL;
+      if(outUnit) *outUnit = NULL;
+    }
+  else
+    {
+      if(outPositive) *outPositive = ZaxistypeEntry[zaxisType].positive;
+      if(outName) *outName = ZaxistypeEntry[zaxisType].name;
+      if(outLongName) *outLongName = ZaxistypeEntry[zaxisType].longname;
+      if(outStdName) *outStdName = ZaxistypeEntry[zaxisType].stdname;
+      if(outUnit) *outUnit = ZaxistypeEntry[zaxisType].units;
+    }
+}
+
 static
 void zaxisDefaultValue(zaxis_t *zaxisptr)
 {
@@ -708,6 +728,7 @@ void zaxisDefUUID(int zaxisID, const unsigned char uuid[CDI_UUID_SIZE])
 @Prototype void zaxisInqUUID(int zaxisID, char *uuid)
 @Parameter
     @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
+    @Item uuid A user supplied buffer of at least 16 bytes.
 
 @Description
 The function @func{zaxisInqUUID} returns the UUID to a generalized Z-axis.
diff --git a/src/zaxis.h b/src/zaxis.h
index cc33867d5d0523d8e773e1af1f7330a6b8cb2e0c..7d975533d032bf6a182155c4c3a853842a09a0ae 100644
--- a/src/zaxis.h
+++ b/src/zaxis.h
@@ -1,9 +1,9 @@
 #ifndef _ZAXIS_H
 #define _ZAXIS_H
 
-#ifndef RESOURCE_HANDLE_H
-#include "resource_handle.h"
-#endif
+void zaxisGetTypeDescription(int zaxisType, int* outPositive, const char** outName, const char** outLongName, const char** outStdName, const char** outUnit);  //The returned const char* point to static storage. Don't free or modify them.
+
+int zaxisSize(void);
 
 unsigned cdiZaxisCount(void);
 
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 09a8687ca18b87b3e42bb2d6ca1a9279a754a9d7..f258bfd92a7ba69f5660e464c8441f0e4e5b0d88 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -34,7 +34,7 @@ test_resource_copy_LDADD = $(UUID_C_LIB) ../src/libcdiresunpack.la $(LDADD)
 test_resource_copy_mpi_SOURCES = test_resource_copy.c
 test_cdf_write_SOURCES = test_cdf_write.c
 test_cdf_read_SOURCES = test_cdf_read.c
-
+#
 AM_CFLAGS = $(PPM_CORE_CFLAGS) $(YAXT_CFLAGS) $(MPI_C_INCLUDE)
 if USE_MPI
 pio_write_LDADD = ../src/libcdipio.la $(UUID_C_LIB) $(MPI_C_LIB)
diff --git a/tests/Makefile.in b/tests/Makefile.in
index 8af6d8f236f38f4e130f42c26537767848816d29..2cd6deff2db08bb397e1e4c15dde6ea29ebb4694 100644
--- a/tests/Makefile.in
+++ b/tests/Makefile.in
@@ -518,6 +518,7 @@ test_resource_copy_LDADD = $(UUID_C_LIB) ../src/libcdiresunpack.la $(LDADD)
 test_resource_copy_mpi_SOURCES = test_resource_copy.c
 test_cdf_write_SOURCES = test_cdf_write.c
 test_cdf_read_SOURCES = test_cdf_read.c
+#
 AM_CFLAGS = $(PPM_CORE_CFLAGS) $(YAXT_CFLAGS) $(MPI_C_INCLUDE)
 @USE_MPI_FALSE@pio_write_LDADD = $(LDADD) $(UUID_C_LIB)
 @USE_MPI_TRUE@pio_write_LDADD = ../src/libcdipio.la $(UUID_C_LIB) $(MPI_C_LIB)