diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,5 @@
+#!/usr/bin/env runhaskell
+
+> import Distribution.Simple
+> main = defaultMain
+
diff --git a/cbits/H5E_inline.c b/cbits/H5E_inline.c
new file mode 100644
--- /dev/null
+++ b/cbits/H5E_inline.c
@@ -0,0 +1,182 @@
+#include <H5Epublic.h>
+#include <bindings.cmacros.h>
+
+BC_INLINE_(H5E_ERR_CLS,             hid_t)
+
+// TODO: these are auto-generated apparently - find out whether they change
+//       often enough that it's worth auto-generating the bindings as well
+BC_INLINE_(H5E_DATASET,             hid_t)
+BC_INLINE_(H5E_FUNC,                hid_t)
+BC_INLINE_(H5E_STORAGE,             hid_t)
+BC_INLINE_(H5E_FILE,                hid_t)
+BC_INLINE_(H5E_SOHM,                hid_t)
+BC_INLINE_(H5E_SYM,                 hid_t)
+#if H5_VERSION_GE(1,8,11)
+BC_INLINE_(H5E_PLUGIN,              hid_t)
+#endif /* H5_VERSION_GE */
+BC_INLINE_(H5E_VFL,                 hid_t)
+BC_INLINE_(H5E_INTERNAL,            hid_t)
+BC_INLINE_(H5E_BTREE,               hid_t)
+BC_INLINE_(H5E_REFERENCE,           hid_t)
+BC_INLINE_(H5E_DATASPACE,           hid_t)
+BC_INLINE_(H5E_RESOURCE,            hid_t)
+BC_INLINE_(H5E_PLIST,               hid_t)
+BC_INLINE_(H5E_LINK,                hid_t)
+BC_INLINE_(H5E_DATATYPE,            hid_t)
+BC_INLINE_(H5E_RS,                  hid_t)
+BC_INLINE_(H5E_HEAP,                hid_t)
+BC_INLINE_(H5E_OHDR,                hid_t)
+BC_INLINE_(H5E_ATOM,                hid_t)
+BC_INLINE_(H5E_ATTR,                hid_t)
+BC_INLINE_(H5E_NONE_MAJOR,          hid_t)
+BC_INLINE_(H5E_IO,                  hid_t)
+BC_INLINE_(H5E_SLIST,               hid_t)
+BC_INLINE_(H5E_EFL,                 hid_t)
+BC_INLINE_(H5E_TST,                 hid_t)
+BC_INLINE_(H5E_ARGS,                hid_t)
+BC_INLINE_(H5E_ERROR,               hid_t)
+BC_INLINE_(H5E_PLINE,               hid_t)
+BC_INLINE_(H5E_FSPACE,              hid_t)
+BC_INLINE_(H5E_CACHE,               hid_t)
+
+BC_INLINE_(H5E_SEEKERROR,           hid_t)
+BC_INLINE_(H5E_READERROR,           hid_t)
+BC_INLINE_(H5E_WRITEERROR,          hid_t)
+BC_INLINE_(H5E_CLOSEERROR,          hid_t)
+BC_INLINE_(H5E_OVERFLOW,            hid_t)
+BC_INLINE_(H5E_FCNTL,               hid_t)
+
+BC_INLINE_(H5E_NOSPACE,             hid_t)
+BC_INLINE_(H5E_CANTALLOC,           hid_t)
+BC_INLINE_(H5E_CANTCOPY,            hid_t)
+BC_INLINE_(H5E_CANTFREE,            hid_t)
+BC_INLINE_(H5E_ALREADYEXISTS,       hid_t)
+BC_INLINE_(H5E_CANTLOCK,            hid_t)
+BC_INLINE_(H5E_CANTUNLOCK,          hid_t)
+BC_INLINE_(H5E_CANTGC,              hid_t)
+BC_INLINE_(H5E_CANTGETSIZE,         hid_t)
+BC_INLINE_(H5E_OBJOPEN,             hid_t)
+
+BC_INLINE_(H5E_CANTRESTORE,         hid_t)
+BC_INLINE_(H5E_CANTCOMPUTE,         hid_t)
+BC_INLINE_(H5E_CANTEXTEND,          hid_t)
+BC_INLINE_(H5E_CANTATTACH,          hid_t)
+BC_INLINE_(H5E_CANTUPDATE,          hid_t)
+BC_INLINE_(H5E_CANTOPERATE,         hid_t)
+
+BC_INLINE_(H5E_CANTINIT,            hid_t)
+BC_INLINE_(H5E_ALREADYINIT,         hid_t)
+BC_INLINE_(H5E_CANTRELEASE,         hid_t)
+
+BC_INLINE_(H5E_CANTGET,             hid_t)
+BC_INLINE_(H5E_CANTSET,             hid_t)
+BC_INLINE_(H5E_DUPCLASS,            hid_t)
+
+#if H5_VERSION_GE(1,8,9)
+BC_INLINE_(H5E_SETDISALLOWED,       hid_t)
+#endif
+
+BC_INLINE_(H5E_CANTMERGE,           hid_t)
+BC_INLINE_(H5E_CANTREVIVE,          hid_t)
+BC_INLINE_(H5E_CANTSHRINK,          hid_t)
+
+BC_INLINE_(H5E_LINKCOUNT,           hid_t)
+BC_INLINE_(H5E_VERSION,             hid_t)
+BC_INLINE_(H5E_ALIGNMENT,           hid_t)
+BC_INLINE_(H5E_BADMESG,             hid_t)
+BC_INLINE_(H5E_CANTDELETE,          hid_t)
+BC_INLINE_(H5E_BADITER,             hid_t)
+BC_INLINE_(H5E_CANTPACK,            hid_t)
+BC_INLINE_(H5E_CANTRESET,           hid_t)
+BC_INLINE_(H5E_CANTRENAME,          hid_t)
+
+BC_INLINE_(H5E_SYSERRSTR,           hid_t)
+
+BC_INLINE_(H5E_NOFILTER,            hid_t)
+BC_INLINE_(H5E_CALLBACK,            hid_t)
+BC_INLINE_(H5E_CANAPPLY,            hid_t)
+BC_INLINE_(H5E_SETLOCAL,            hid_t)
+BC_INLINE_(H5E_NOENCODER,           hid_t)
+BC_INLINE_(H5E_CANTFILTER,          hid_t)
+
+BC_INLINE_(H5E_CANTOPENOBJ,         hid_t)
+BC_INLINE_(H5E_CANTCLOSEOBJ,        hid_t)
+BC_INLINE_(H5E_COMPLEN,             hid_t)
+BC_INLINE_(H5E_PATH,                hid_t)
+
+BC_INLINE_(H5E_NONE_MINOR,          hid_t)
+
+#if H5_VERSION_GE(1,8,11)
+BC_INLINE_(H5E_OPENERROR,           hid_t)
+#endif
+
+BC_INLINE_(H5E_FILEEXISTS,          hid_t)
+BC_INLINE_(H5E_FILEOPEN,            hid_t)
+BC_INLINE_(H5E_CANTCREATE,          hid_t)
+BC_INLINE_(H5E_CANTOPENFILE,        hid_t)
+BC_INLINE_(H5E_CANTCLOSEFILE,       hid_t)
+BC_INLINE_(H5E_NOTHDF5,             hid_t)
+BC_INLINE_(H5E_BADFILE,             hid_t)
+BC_INLINE_(H5E_TRUNCATED,           hid_t)
+BC_INLINE_(H5E_MOUNT,               hid_t)
+
+BC_INLINE_(H5E_BADATOM,             hid_t)
+BC_INLINE_(H5E_BADGROUP,            hid_t)
+BC_INLINE_(H5E_CANTREGISTER,        hid_t)
+BC_INLINE_(H5E_CANTINC,             hid_t)
+BC_INLINE_(H5E_CANTDEC,             hid_t)
+BC_INLINE_(H5E_NOIDS,               hid_t)
+
+BC_INLINE_(H5E_CANTFLUSH,           hid_t)
+BC_INLINE_(H5E_CANTSERIALIZE,       hid_t)
+BC_INLINE_(H5E_CANTLOAD,            hid_t)
+BC_INLINE_(H5E_PROTECT,             hid_t)
+BC_INLINE_(H5E_NOTCACHED,           hid_t)
+BC_INLINE_(H5E_SYSTEM,              hid_t)
+BC_INLINE_(H5E_CANTINS,             hid_t)
+BC_INLINE_(H5E_CANTPROTECT,         hid_t)
+BC_INLINE_(H5E_CANTUNPROTECT,       hid_t)
+BC_INLINE_(H5E_CANTPIN,             hid_t)
+BC_INLINE_(H5E_CANTUNPIN,           hid_t)
+BC_INLINE_(H5E_CANTMARKDIRTY,       hid_t)
+BC_INLINE_(H5E_CANTDIRTY,           hid_t)
+BC_INLINE_(H5E_CANTEXPUNGE,         hid_t)
+BC_INLINE_(H5E_CANTRESIZE,          hid_t)
+
+BC_INLINE_(H5E_TRAVERSE,            hid_t)
+BC_INLINE_(H5E_NLINKS,              hid_t)
+BC_INLINE_(H5E_NOTREGISTERED,       hid_t)
+BC_INLINE_(H5E_CANTMOVE,            hid_t)
+BC_INLINE_(H5E_CANTSORT,            hid_t)
+
+BC_INLINE_(H5E_MPI,                 hid_t)
+BC_INLINE_(H5E_MPIERRSTR,           hid_t)
+BC_INLINE_(H5E_CANTRECV,            hid_t)
+
+BC_INLINE_(H5E_CANTCLIP,            hid_t)
+BC_INLINE_(H5E_CANTCOUNT,           hid_t)
+BC_INLINE_(H5E_CANTSELECT,          hid_t)
+BC_INLINE_(H5E_CANTNEXT,            hid_t)
+BC_INLINE_(H5E_BADSELECT,           hid_t)
+BC_INLINE_(H5E_CANTCOMPARE,         hid_t)
+
+BC_INLINE_(H5E_UNINITIALIZED,       hid_t)
+BC_INLINE_(H5E_UNSUPPORTED,         hid_t)
+BC_INLINE_(H5E_BADTYPE,             hid_t)
+BC_INLINE_(H5E_BADRANGE,            hid_t)
+BC_INLINE_(H5E_BADVALUE,            hid_t)
+
+BC_INLINE_(H5E_NOTFOUND,            hid_t)
+BC_INLINE_(H5E_EXISTS,              hid_t)
+BC_INLINE_(H5E_CANTENCODE,          hid_t)
+BC_INLINE_(H5E_CANTDECODE,          hid_t)
+BC_INLINE_(H5E_CANTSPLIT,           hid_t)
+BC_INLINE_(H5E_CANTREDISTRIBUTE,    hid_t)
+BC_INLINE_(H5E_CANTSWAP,            hid_t)
+BC_INLINE_(H5E_CANTINSERT,          hid_t)
+BC_INLINE_(H5E_CANTLIST,            hid_t)
+BC_INLINE_(H5E_CANTMODIFY,          hid_t)
+BC_INLINE_(H5E_CANTREMOVE,          hid_t)
+
+BC_INLINE_(H5E_CANTCONVERT,         hid_t)
+BC_INLINE_(H5E_BADSIZE,             hid_t)
diff --git a/cbits/H5FD_inline.c b/cbits/H5FD_inline.c
new file mode 100644
--- /dev/null
+++ b/cbits/H5FD_inline.c
@@ -0,0 +1,14 @@
+#include <H5FDpublic.h>
+
+#include <string.h>
+
+#define MIN(a,b) (a < b ? a : b)
+#define BC_INLINE_ARRAY(name, t)                \
+    void inline_ ## name (t *b, size_t n) {   \
+        t a[] = name;                           \
+        memcpy(b, a, MIN(n, sizeof(a)));        \
+    }
+
+BC_INLINE_ARRAY(H5FD_FLMAP_SINGLE,      H5FD_mem_t)
+BC_INLINE_ARRAY(H5FD_FLMAP_DICHOTOMY,   H5FD_mem_t)
+BC_INLINE_ARRAY(H5FD_FLMAP_DEFAULT,     H5FD_mem_t)
diff --git a/cbits/H5FDmpi_inline.c b/cbits/H5FDmpi_inline.c
new file mode 100644
--- /dev/null
+++ b/cbits/H5FDmpi_inline.c
@@ -0,0 +1,12 @@
+#include <bindings.cmacros.h>
+#include <hdf5.h>
+
+// I would wrap this macro, but despite being in the public headers it uses
+// a macro internally that is not...
+// BC_INLINE1(IS_H5FD_MPI, hid_t *, int)
+
+#ifdef H5_HAVE_PARALLEL
+
+// BC_INLINE_(H5FD_mpi_native_g, char *)
+
+#endif /* H5_HAVE_PARALLEL */
diff --git a/cbits/H5G_inline.c b/cbits/H5G_inline.c
new file mode 100644
--- /dev/null
+++ b/cbits/H5G_inline.c
@@ -0,0 +1,8 @@
+#include <H5Gpublic.h>
+#include <bindings.cmacros.h>
+
+#ifndef H5_NO_DEPRECATED_SYMBOLS
+
+BC_INLINE1(H5G_USERTYPE, H5G_obj_t, H5G_obj_t)
+
+#endif /* H5_NO_DEPRECATED_SYMBOLS */
diff --git a/cbits/H5P_inline.c b/cbits/H5P_inline.c
new file mode 100644
--- /dev/null
+++ b/cbits/H5P_inline.c
@@ -0,0 +1,35 @@
+#include <H5Ppublic.h>
+#include <bindings.cmacros.h>
+
+BC_INLINE_(H5P_ROOT,                        hid_t)
+BC_INLINE_(H5P_OBJECT_CREATE,               hid_t)
+BC_INLINE_(H5P_FILE_CREATE,                 hid_t)
+BC_INLINE_(H5P_FILE_ACCESS,                 hid_t)
+BC_INLINE_(H5P_DATASET_CREATE,              hid_t)
+BC_INLINE_(H5P_DATASET_ACCESS,              hid_t)
+BC_INLINE_(H5P_DATASET_XFER,                hid_t)
+BC_INLINE_(H5P_FILE_MOUNT,                  hid_t)
+BC_INLINE_(H5P_GROUP_CREATE,                hid_t)
+BC_INLINE_(H5P_GROUP_ACCESS,                hid_t)
+BC_INLINE_(H5P_DATATYPE_CREATE,             hid_t)
+BC_INLINE_(H5P_DATATYPE_ACCESS,             hid_t)
+BC_INLINE_(H5P_STRING_CREATE,               hid_t)
+BC_INLINE_(H5P_ATTRIBUTE_CREATE,            hid_t)
+BC_INLINE_(H5P_OBJECT_COPY,                 hid_t)
+BC_INLINE_(H5P_LINK_CREATE,                 hid_t)
+BC_INLINE_(H5P_LINK_ACCESS,                 hid_t)
+
+BC_INLINE_(H5P_FILE_CREATE_DEFAULT,         hid_t)
+BC_INLINE_(H5P_FILE_ACCESS_DEFAULT,         hid_t)
+BC_INLINE_(H5P_DATASET_CREATE_DEFAULT,      hid_t)
+BC_INLINE_(H5P_DATASET_ACCESS_DEFAULT,      hid_t)
+BC_INLINE_(H5P_DATASET_XFER_DEFAULT,        hid_t)
+BC_INLINE_(H5P_FILE_MOUNT_DEFAULT,          hid_t)
+BC_INLINE_(H5P_GROUP_CREATE_DEFAULT,        hid_t)
+BC_INLINE_(H5P_GROUP_ACCESS_DEFAULT,        hid_t)
+BC_INLINE_(H5P_DATATYPE_CREATE_DEFAULT,     hid_t)
+BC_INLINE_(H5P_DATATYPE_ACCESS_DEFAULT,     hid_t)
+BC_INLINE_(H5P_ATTRIBUTE_CREATE_DEFAULT,    hid_t)
+BC_INLINE_(H5P_OBJECT_COPY_DEFAULT,         hid_t)
+BC_INLINE_(H5P_LINK_CREATE_DEFAULT,         hid_t)
+BC_INLINE_(H5P_LINK_ACCESS_DEFAULT,         hid_t)
diff --git a/cbits/H5T_inline.c b/cbits/H5T_inline.c
new file mode 100644
--- /dev/null
+++ b/cbits/H5T_inline.c
@@ -0,0 +1,101 @@
+#include <H5Tpublic.h>
+#include <bindings.cmacros.h>
+
+BC_INLINE_(H5T_IEEE_F32BE,      hid_t)
+BC_INLINE_(H5T_IEEE_F32LE,      hid_t)
+BC_INLINE_(H5T_IEEE_F64BE,      hid_t)
+BC_INLINE_(H5T_IEEE_F64LE,      hid_t)
+
+BC_INLINE_(H5T_STD_I8BE,        hid_t)
+BC_INLINE_(H5T_STD_I8LE,        hid_t)
+BC_INLINE_(H5T_STD_I16BE,       hid_t)
+BC_INLINE_(H5T_STD_I16LE,       hid_t)
+BC_INLINE_(H5T_STD_I32BE,       hid_t)
+BC_INLINE_(H5T_STD_I32LE,       hid_t)
+BC_INLINE_(H5T_STD_I64BE,       hid_t)
+BC_INLINE_(H5T_STD_I64LE,       hid_t)
+BC_INLINE_(H5T_STD_U8BE,        hid_t)
+BC_INLINE_(H5T_STD_U8LE,        hid_t)
+BC_INLINE_(H5T_STD_U16BE,       hid_t)
+BC_INLINE_(H5T_STD_U16LE,       hid_t)
+BC_INLINE_(H5T_STD_U32BE,       hid_t)
+BC_INLINE_(H5T_STD_U32LE,       hid_t)
+BC_INLINE_(H5T_STD_U64BE,       hid_t)
+BC_INLINE_(H5T_STD_U64LE,       hid_t)
+BC_INLINE_(H5T_STD_B8BE,        hid_t)
+BC_INLINE_(H5T_STD_B8LE,        hid_t)
+BC_INLINE_(H5T_STD_B16BE,       hid_t)
+BC_INLINE_(H5T_STD_B16LE,       hid_t)
+BC_INLINE_(H5T_STD_B32BE,       hid_t)
+BC_INLINE_(H5T_STD_B32LE,       hid_t)
+BC_INLINE_(H5T_STD_B64BE,       hid_t)
+BC_INLINE_(H5T_STD_B64LE,       hid_t)
+BC_INLINE_(H5T_STD_REF_OBJ,     hid_t)
+BC_INLINE_(H5T_STD_REF_DSETREG, hid_t)
+
+BC_INLINE_(H5T_UNIX_D32BE,      hid_t)
+BC_INLINE_(H5T_UNIX_D32LE,      hid_t)
+BC_INLINE_(H5T_UNIX_D64BE,      hid_t)
+BC_INLINE_(H5T_UNIX_D64LE,      hid_t)
+
+BC_INLINE_(H5T_C_S1,            hid_t)
+
+BC_INLINE_(H5T_FORTRAN_S1,      hid_t)
+
+BC_INLINE_(H5T_VAX_F32,         hid_t)
+BC_INLINE_(H5T_VAX_F64,         hid_t)
+
+BC_INLINE_(H5T_NATIVE_CHAR,     hid_t)
+BC_INLINE_(H5T_NATIVE_SCHAR,    hid_t)
+BC_INLINE_(H5T_NATIVE_UCHAR,    hid_t)
+BC_INLINE_(H5T_NATIVE_SHORT,    hid_t)
+BC_INLINE_(H5T_NATIVE_USHORT,   hid_t)
+BC_INLINE_(H5T_NATIVE_INT,      hid_t)
+BC_INLINE_(H5T_NATIVE_UINT,     hid_t)
+BC_INLINE_(H5T_NATIVE_LONG,     hid_t)
+BC_INLINE_(H5T_NATIVE_ULONG,    hid_t)
+BC_INLINE_(H5T_NATIVE_LLONG,    hid_t)
+BC_INLINE_(H5T_NATIVE_ULLONG,   hid_t)
+BC_INLINE_(H5T_NATIVE_FLOAT,    hid_t)
+BC_INLINE_(H5T_NATIVE_DOUBLE,   hid_t)
+#if H5_SIZEOF_LONG_DOUBLE !=0
+BC_INLINE_(H5T_NATIVE_LDOUBLE,  hid_t)
+#endif
+BC_INLINE_(H5T_NATIVE_B8,       hid_t)
+BC_INLINE_(H5T_NATIVE_B16,      hid_t)
+BC_INLINE_(H5T_NATIVE_B32,      hid_t)
+BC_INLINE_(H5T_NATIVE_B64,      hid_t)
+BC_INLINE_(H5T_NATIVE_OPAQUE,   hid_t)
+BC_INLINE_(H5T_NATIVE_HADDR,    hid_t)
+BC_INLINE_(H5T_NATIVE_HSIZE,    hid_t)
+BC_INLINE_(H5T_NATIVE_HSSIZE,   hid_t)
+BC_INLINE_(H5T_NATIVE_HERR,     hid_t)
+BC_INLINE_(H5T_NATIVE_HBOOL,    hid_t)
+
+BC_INLINE_(H5T_NATIVE_INT8,         hid_t)
+BC_INLINE_(H5T_NATIVE_UINT8,        hid_t)
+BC_INLINE_(H5T_NATIVE_INT_LEAST8,   hid_t)
+BC_INLINE_(H5T_NATIVE_UINT_LEAST8,  hid_t)
+BC_INLINE_(H5T_NATIVE_INT_FAST8,    hid_t)
+BC_INLINE_(H5T_NATIVE_UINT_FAST8,   hid_t)
+
+BC_INLINE_(H5T_NATIVE_INT16,        hid_t)
+BC_INLINE_(H5T_NATIVE_UINT16,       hid_t)
+BC_INLINE_(H5T_NATIVE_INT_LEAST16,  hid_t)
+BC_INLINE_(H5T_NATIVE_UINT_LEAST16, hid_t)
+BC_INLINE_(H5T_NATIVE_INT_FAST16,   hid_t)
+BC_INLINE_(H5T_NATIVE_UINT_FAST16,  hid_t)
+
+BC_INLINE_(H5T_NATIVE_INT32,        hid_t)
+BC_INLINE_(H5T_NATIVE_UINT32,       hid_t)
+BC_INLINE_(H5T_NATIVE_INT_LEAST32,  hid_t)
+BC_INLINE_(H5T_NATIVE_UINT_LEAST32, hid_t)
+BC_INLINE_(H5T_NATIVE_INT_FAST32,   hid_t)
+BC_INLINE_(H5T_NATIVE_UINT_FAST32,  hid_t)
+
+BC_INLINE_(H5T_NATIVE_INT64,        hid_t)
+BC_INLINE_(H5T_NATIVE_UINT64,       hid_t)
+BC_INLINE_(H5T_NATIVE_INT_LEAST64,  hid_t)
+BC_INLINE_(H5T_NATIVE_UINT_LEAST64, hid_t)
+BC_INLINE_(H5T_NATIVE_INT_FAST64,   hid_t)
+BC_INLINE_(H5T_NATIVE_UINT_FAST64,  hid_t)
diff --git a/cbits/H5_inline.c b/cbits/H5_inline.c
new file mode 100644
--- /dev/null
+++ b/cbits/H5_inline.c
@@ -0,0 +1,6 @@
+#include <H5public.h>
+#include <bindings.cmacros.h>
+
+herr_t inline_H5check() {
+    return H5check();
+}
diff --git a/hdf5.cabal b/hdf5.cabal
new file mode 100644
--- /dev/null
+++ b/hdf5.cabal
@@ -0,0 +1,149 @@
+name:                   hdf5
+version:                1.8.9
+stability:              provisional
+
+cabal-version:          >= 1.10
+build-type:             Simple
+
+extra-source-files: include/bindings.h
+                    include/mangle.h
+                    include/util.h
+
+author:                 James Cook <mokus@deepbondi.net>
+maintainer:             Picca Frédéric-Emmanuel <picca@synchrotron-soleil.fr>
+license:                PublicDomain
+homepage:               https://github.com/picca/hs-hdf5
+
+category:               Database
+synopsis:               Haskell interface to the HDF5 scientific data storage library.
+description:            This is a low-level but typesafe Haskell interface to the HDF5 library.  No pointers necessary.
+
+source-repository head
+  type: git
+  location: git://github.com/picca/hs-hdf5.git
+
+Flag useEmbededLibFFI
+  Description: Enable the embeded libffi
+  Default:     False
+
+Library
+  hs-source-dirs:       src
+  default-language:     Haskell2010
+  default-extensions:   GeneralizedNewtypeDeriving
+  default-extensions:   ForeignFunctionInterface
+
+  ghc-options:          -Wall
+  cc-options:           -Wno-format
+  exposed-modules:      Bindings.HDF5
+                      , Bindings.HDF5.Attribute
+                      , Bindings.HDF5.Raw
+                      , Bindings.HDF5.Core
+                      , Bindings.HDF5.Dataset
+                      , Bindings.HDF5.Dataspace
+                      , Bindings.HDF5.Datatype
+                      , Bindings.HDF5.Datatype.Internal
+                      , Bindings.HDF5.Error
+                      , Bindings.HDF5.ErrorCodes
+                      , Bindings.HDF5.File
+                      , Bindings.HDF5.Group
+                      , Bindings.HDF5.Link
+                      , Bindings.HDF5.Object
+                      , Bindings.HDF5.PropertyList
+                      , Bindings.HDF5.PropertyList.DAPL
+                      , Bindings.HDF5.PropertyList.DCPL
+                      , Bindings.HDF5.PropertyList.DXPL
+                      , Bindings.HDF5.PropertyList.FAPL
+                      , Bindings.HDF5.PropertyList.FCPL
+                      , Bindings.HDF5.PropertyList.FMPL
+                      , Bindings.HDF5.PropertyList.GAPL
+                      , Bindings.HDF5.PropertyList.GCPL
+                      , Bindings.HDF5.PropertyList.LAPL
+                      , Bindings.HDF5.PropertyList.LCPL
+                      , Bindings.HDF5.PropertyList.OCPL
+                      , Bindings.HDF5.PropertyList.OCPYPL
+                      , Bindings.HDF5.PropertyList.STRCPL
+                      , Bindings.HDF5.PropertyList.TAPL
+                      , Bindings.HDF5.PropertyList.TCPL
+
+                      , Bindings.HDF5.Core.HDFResultType
+                      , Bindings.HDF5.Core.HId
+                      , Bindings.HDF5.Raw.H5
+                      , Bindings.HDF5.Raw.H5A
+                      , Bindings.HDF5.Raw.H5AC
+                      , Bindings.HDF5.Raw.H5C
+                      , Bindings.HDF5.Raw.H5D
+                      , Bindings.HDF5.Raw.H5E
+                      , Bindings.HDF5.Raw.H5F
+                      , Bindings.HDF5.Raw.H5FD
+                      , Bindings.HDF5.Raw.H5FD.Core
+                      , Bindings.HDF5.Raw.H5FD.Family
+                      , Bindings.HDF5.Raw.H5FD.Log
+                      , Bindings.HDF5.Raw.H5FD.MPI
+                      , Bindings.HDF5.Raw.H5FD.Multi
+                      , Bindings.HDF5.Raw.H5FD.Sec2
+                      , Bindings.HDF5.Raw.H5FD.StdIO
+                      , Bindings.HDF5.Raw.H5FD.Direct
+                      , Bindings.HDF5.Raw.H5G
+                      , Bindings.HDF5.Raw.H5I
+                      , Bindings.HDF5.Raw.H5L
+                      , Bindings.HDF5.Raw.H5MM
+                      , Bindings.HDF5.Raw.H5O
+                      , Bindings.HDF5.Raw.H5P
+                      , Bindings.HDF5.Raw.H5R
+                      , Bindings.HDF5.Raw.H5S
+                      , Bindings.HDF5.Raw.H5T
+                      , Bindings.HDF5.Raw.H5Z
+                      , Bindings.HDF5.Raw.Util
+                      , Foreign.Ptr.Conventions
+
+  if flag(useEmbededLibFFI)
+    other-modules:      Foreign.LibFFI
+                      , Foreign.LibFFI.Base
+                      , Foreign.LibFFI.Types
+                      , Foreign.LibFFI.FFITypes
+                      , Foreign.LibFFI.Internal
+
+  else
+    build-depends:      libffi
+
+  c-sources:            cbits/H5_inline.c
+                      , cbits/H5E_inline.c
+                      , cbits/H5FD_inline.c
+                      , cbits/H5FD_inline.c
+                      , cbits/H5FDmpi_inline.c
+                      , cbits/H5G_inline.c
+                      , cbits/H5P_inline.c
+                      , cbits/H5T_inline.c
+
+  include-dirs:         include
+
+  build-depends:        base >= 3 && < 5
+                      , bytestring
+                      , tagged
+                      , vector
+                      , bindings-DSL
+                      , monad-control
+                      , lifted-base
+                      , primitive
+                      , transformers
+
+  pkgconfig-depends:    hdf5-serial, libffi
+
+
+test-suite hdf5-test
+  type:                exitcode-stdio-1.0
+  hs-source-dirs:      test
+  default-language:    Haskell2010
+  main-is:             Spec.hs
+  build-depends:       base
+                     , hspec
+                     , QuickCheck
+                     , temporary
+                     , hdf5
+                     , bytestring
+                     , exceptions
+                     , vector
+  other-modules:       Spec.Util
+                     , Spec.File
+                     , Spec.Group
+  ghc-options:         -Wall -threaded -rtsopts -with-rtsopts=-N
diff --git a/include/bindings.h b/include/bindings.h
new file mode 100644
--- /dev/null
+++ b/include/bindings.h
@@ -0,0 +1,69 @@
+#ifndef ___n_bindings_h__
+#define ___n_bindings_h__
+
+#include <util.h>
+
+#include <bindings.dsl.h>
+
+// Replace bindings-DSL naming scheme with our own
+#include <mangle.h>
+
+#undef bc_varid
+#undef bc_conid
+#undef bc_ptrid
+#undef bc_wrapper
+#undef bc_dynamic
+#define bc_varid(name)              hsc_mangle(varid,       name);
+#define bc_conid(name)              hsc_mangle(conid,       name);
+#define bc_ptrid(name)              hsc_mangle(ptrid,       name);
+#define bc_wrapper(name)            hsc_mangle(wrapper,     name);
+#define bc_dynamic(name)            hsc_mangle(dynamic,     name);
+
+#undef bc_fieldname
+#undef bc_unionupdate
+#undef bc_famaccess
+#define bc_fieldname(type,field)    bc_glue(mangle_fieldname(type),   field);
+#define bc_unionupdate(type,field)  bc_glue(mangle_unionupdate(type), field);
+#define bc_famaccess(type,field)    bc_glue(mangle_famaccess(type),   field);
+
+
+#define hsc_newtype(t,derive...)                                \
+    {                                                           \
+        printf("newtype ");                                     \
+        hsc_mangle_tycon(# t);                                  \
+        printf(" = ");                                          \
+        hsc_mangle_datacon(# t);                                \
+        printf(" ");                                            \
+        hsc_type(t);                                            \
+        { char *derives = # derive;                             \
+            printf(" deriving (Storable, Show%s%s)\n",                    \
+                strlen(derives) > 0 ? ", " : "",                \
+                derives);                                       \
+        }                                                       \
+    }
+
+#define hsc_newtype_const(t,c)      \
+    {                               \
+        hsc_mangle_ident(# c);      \
+        printf(" :: ");             \
+        hsc_mangle_tycon(# t);      \
+        printf("\n");               \
+        hsc_mangle_ident(# c);      \
+        printf(" = ");              \
+        hsc_mangle_datacon(# t);    \
+        printf(" (");               \
+        hsc_const(c);               \
+        printf(")\n");              \
+    }
+
+#define hsc_str(name)               \
+    {                               \
+        hsc_mangle_ident(# name);   \
+        printf(" :: String\n");     \
+        hsc_mangle_ident(# name);   \
+        printf(" = ");              \
+        hsc_const_str(name);        \
+        printf("\n");               \
+    }
+
+#endif /* ___n_bindings_h__ */
diff --git a/include/mangle.h b/include/mangle.h
new file mode 100644
--- /dev/null
+++ b/include/mangle.h
@@ -0,0 +1,116 @@
+#ifndef ___n_mangle_h__
+#define ___n_mangle_h__
+
+#include <util.h>
+
+static struct {
+    char *from, *to;
+} hardcoded_mangles[] = {
+    {"size_t",  "CSize"},
+    {"ssize_t", "CSSize"},
+    {"time_t",  "CTime"},
+    {"off_t",   "COff"},
+    {"hssize_t","HSSize_t"},
+    {NULL, NULL},
+};
+
+// Most type names are already uppercase, including all that have the "H5"
+// prefix.  That means we don't need to mess with figuring out the length
+// of the prefix.  Just check for a leading 'h' and, if present, uppercase
+// 2 chars instead of 1.
+char *uc_prefix(char *s) {
+    if (s[0] == '\0' || isupper(s[0]))
+        return s;
+
+    if (s[0] != 'h')
+        return ucn(s,1);
+
+    return ucn(s,2);
+}
+
+// the logic used in lc_prefix to identify the prefix.
+void skip_prefix(char *s, char **rest, unsigned *prefix_len) {
+    char    *r = s;
+    unsigned p = 0;
+    unsigned n = *prefix_len;
+
+    while ((p < n && *r != '\0' && isupper(*r)) || *r == '5') {
+        r++;
+        p++;
+    }
+
+    *rest = r;
+    *prefix_len = p;
+}
+
+// Lowercasing the prefix is a little trickier, for 2 reasons:
+// 1. the uppercase prefixes are not all the same length (eg., H5T and H5AC)
+// 2. they are terminated by an underscore in the case of all-caps macro names
+//    but not in the case of lowercase function names.  So sometimes we
+//    need to add an underscore* and other times we don't.
+//
+//   * because otherwise prefixes are potentially ambiguous after mangling;
+//     is 'h5a_create2' the mangling of 'H5Acreate2' or 'H5ACreate2'?
+//     Obviously a human can tell the difference, but a machine can't as
+//     easily.
+char *lc_prefix(char *s) {
+    char *rest;
+    unsigned prefix_len = 4;
+
+    if (s[0] == '\0' || islower(s[0]))
+        return s;
+
+    skip_prefix(s, &rest, &prefix_len);
+
+    {
+        char lc_pref[prefix_len+1];
+        int i;
+
+        for (i = 0; i < prefix_len; i++) {
+            lc_pref[i] = tolower(s[i]);
+        }
+
+        if (s[prefix_len] != '_') {
+            lc_pref[prefix_len] = '_';
+            prefix_len++;
+        }
+
+        return (concatn(lc_pref, prefix_len, rest, strlen(rest)));
+    }
+}
+
+#define mangle_tycon(name)                                          \
+    ({                                                              \
+        unsigned i;                                                 \
+        char *res = NULL;                                           \
+        for(i = 0; hardcoded_mangles[i].from != NULL; i++) {        \
+            if (strcmp(name, hardcoded_mangles[i].from) == 0) {     \
+                res = hardcoded_mangles[i].to;                      \
+                break;                                              \
+            }                                                       \
+        }                                                           \
+                                                                    \
+        if (res == NULL) res = uc_prefix(name);                     \
+        res;                                                        \
+    })
+
+#define mangle_datacon(name)        mangle_tycon(name)
+#define mangle_ident(name)          (lc_prefix(name))
+
+#define mangle_varid(name)          mangle_ident(name)
+#define mangle_fieldname(name)      mangle_varid(name)
+#define mangle_conid(name)          mangle_tycon(name)
+#define mangle_ptrid(name)          concat("p_", name)
+#define mangle_famaccess(name)      mangle_ptrid(name)
+#define mangle_unionupdate(name)    concat("u_", name)
+#define mangle_wrapper(name)        concat("mk_",name)
+#define mangle_dynamic(name)        concat("mK_",name)
+
+#define hsc_mangle(as,name)         printf("%s", mangle_ ## as(name));
+
+#define hsc_mangle_tycon(name)      hsc_mangle(tycon,   name)
+#define hsc_mangle_datacon(name)    hsc_mangle(datacon, name)
+#define hsc_mangle_ident(name)      hsc_mangle(ident,   name)
+
+
+#endif /* ___n_mangle_h__ */
diff --git a/include/util.h b/include/util.h
new file mode 100644
--- /dev/null
+++ b/include/util.h
@@ -0,0 +1,72 @@
+#ifndef ___n_util_h__
+#define ___n_util_h__
+
+#include <stdlib.h>
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#include <H5public.h>
+#include <string.h>
+
+// These version-check macros were introduced in HDF5 1.8.7
+#ifndef H5_VERSION_GE
+#define H5_VERSION_GE(a,b,c)                    \
+    ((H5_VERS_MAJOR > a) || (H5_VERS_MAJOR == a && ( \
+        H5_VERS_MINOR > b || (H5_VERS_MINOR == b && \
+            H5_VERS_RELEASE >= c))))
+#endif
+
+#ifndef H5_VERSION_LE
+#define H5_VERSION_LE(a,b,c)                     \
+    ((H5_VERS_MAJOR < a) || (H5_VERS_MAJOR == a && ( \
+        H5_VERS_MINOR < b || (H5_VERS_MINOR == b && \
+            H5_VERS_RELEASE <= c))))
+#endif
+
+#define signed(t)       ((t)(-1) < 0)
+#define floating(t)     ((t)(int)(t) 1.4 == (t) 1.4)
+#define nbitsof(t)      (sizeof(t) * 8)
+#define countof(x)      (sizeof(x) / sizeof((x)[0]))
+
+char *dupstr(char *s) {
+    // don't worry about freeing, this is a throw-away program
+    char *t = (char *) malloc(strlen(s) + 1);
+    strcpy(t,s);
+    return t;
+}
+
+char *mapstrn(char *s, unsigned n, int (*f)(int)) {
+    unsigned i;
+    char *t = dupstr(s);
+    
+    for (i = 0; i < n && t[i] != '\0'; i++) {
+        t[i] = f(t[i]);
+    }
+    
+    return t;
+}
+
+char *concatn(char *s1, unsigned n1, char *s2, unsigned n2) {
+    char *t = (char *) malloc(1 + n1 + n2);
+    strncpy(t,    s1, n1+1);
+    strncpy(t+n1, s2, n2+1);
+    t[n1+n2] = '\0';
+    return t;
+}
+
+char *concat(char *s1, char *s2) {
+    unsigned n1 = strlen(s1);
+    unsigned n2 = strlen(s2);
+    return concatn(s1,n1,s2,n2);
+}
+
+#define lcn(s,n)     mapstrn(s, n, &tolower)
+#define ucn(s,n)     mapstrn(s, n, &toupper)
+
+#endif /* ___n_util_h__ */
diff --git a/src/Bindings/HDF5.hs b/src/Bindings/HDF5.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5.hs
@@ -0,0 +1,28 @@
+module Bindings.HDF5
+    ( IndexType(..)
+    , IterOrder(..)
+    , IH_Info(..)
+    , module X
+    ) where
+
+import           Bindings.HDF5.Attribute           as X
+import           Bindings.HDF5.Core                as X
+import           Bindings.HDF5.Dataset             as X
+import           Bindings.HDF5.Dataspace           as X
+import           Bindings.HDF5.Datatype            as X
+import           Bindings.HDF5.File                as X
+import           Bindings.HDF5.Group               as X
+import           Bindings.HDF5.Link                as X
+import           Bindings.HDF5.Object              as X
+import           Bindings.HDF5.PropertyList        as X
+import           Bindings.HDF5.PropertyList.DAPL   as X
+import           Bindings.HDF5.PropertyList.DCPL   as X
+import           Bindings.HDF5.PropertyList.DXPL   as X
+import           Bindings.HDF5.PropertyList.FAPL   as X
+import           Bindings.HDF5.PropertyList.FCPL   as X
+import           Bindings.HDF5.PropertyList.FMPL   as X
+import           Bindings.HDF5.PropertyList.GAPL   as X
+import           Bindings.HDF5.PropertyList.OCPYPL as X
+import           Bindings.HDF5.PropertyList.STRCPL as X
+import           Bindings.HDF5.PropertyList.TAPL   as X
+import           Bindings.HDF5.PropertyList.TCPL   as X
diff --git a/src/Bindings/HDF5/Attribute.hs b/src/Bindings/HDF5/Attribute.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Attribute.hs
@@ -0,0 +1,202 @@
+{- |
+Typesafe wrappers around HDF5 functions from the H5A API.
+
+Feature coverage is as follows:
+
+  h5a_open
+  h5a_close
+  h5a_read
+
+-}
+module Bindings.HDF5.Attribute
+    ( Attribute
+    , openAttribute
+
+    , getAttributeType
+    , getAttributeInfo
+    , getAttributeSpace
+
+    , readAttribute
+    , readAttributeStringASCII
+
+    , doesAttributeExist
+    , closeAttribute
+
+    , iterateAttributes
+    , iterateAttributesByName
+    ) where
+
+
+import           Control.Exception               (SomeException, finally,
+                                                  throwIO, try)
+import qualified Data.ByteString                 as BS
+import           Data.IORef
+import qualified Data.Vector.Storable            as SV
+import           Foreign
+import           Foreign.C
+
+import           Bindings.HDF5.Core
+import           Bindings.HDF5.Dataspace
+import           Bindings.HDF5.Datatype
+import           Bindings.HDF5.Datatype.Internal
+import           Bindings.HDF5.Error
+import           Bindings.HDF5.Group
+import           Bindings.HDF5.Object
+import           Bindings.HDF5.PropertyList.LAPL
+import           Bindings.HDF5.Raw.H5
+import           Bindings.HDF5.Raw.H5A
+import           Bindings.HDF5.Raw.H5I
+import           Bindings.HDF5.Raw.H5O
+import           Bindings.HDF5.Raw.H5P
+import           Bindings.HDF5.Raw.Util
+import           Foreign.Ptr.Conventions
+
+-- * The Attribute type
+
+newtype Attribute = Attribute HId_t
+    deriving (Eq, HId, FromHId, HDFResultType)
+
+-- | Open an existing attribute
+
+openAttribute :: ObjectId -- ^ Parent location
+              -> BS.ByteString  -- ^ Attribute name
+              -> IO Attribute   -- ^ Resulting attribute
+openAttribute obj name =
+    Attribute <$> (withErrorCheck $
+                   BS.useAsCString name $ \cname ->
+                       h5a_open (hid obj) cname h5p_DEFAULT)
+
+getAttributeType :: Attribute -> IO Datatype
+getAttributeType (Attribute attr_id) =
+    Datatype <$> (withErrorCheck $
+                   h5a_get_type attr_id)
+
+-- | Close an Attribute
+
+closeAttribute :: Attribute -> IO ()
+closeAttribute (Attribute attr) =
+    withErrorCheck_ $
+        h5a_close attr
+
+getAttributeSpace :: Attribute -> IO Dataspace
+getAttributeSpace (Attribute attr_id) =
+    uncheckedFromHId
+    <$> withErrorCheck (h5a_get_space attr_id)
+
+-- |Read in data from an attribute
+--
+-- Parameters:
+--
+-- [@ attr_id  :: HId_t      @] Attribute to read
+--
+-- [@ dtype_id :: HId_t      @] Memory datatype of buffer
+--
+-- [@ buf      :: OutArray a @] Buffer for data to read
+--
+-- Returns non-negative on success / negative on failure
+--
+-- This function reads a complete attribute from disk.
+--
+-- > herr_t  H5Aread(hid_t attr_id, hid_t type_id, void *buf);
+
+readAttribute :: NativeType t =>
+                Attribute
+              -> IO (SV.Vector t)
+readAttribute attr@(Attribute attr_id) = do
+  space <- getAttributeSpace attr
+  n <- getSimpleDataspaceExtentNPoints space
+
+  withOutVector_ (fromIntegral n) $ \buf ->
+    withErrorCheck_ $
+      h5a_read attr_id (hdfTypeOf1 buf) buf
+
+-- | for now this method read only Bytestring this part is a bit fragile...
+-- | we should check thaht the attr type is compatible with the string type.
+-- | TODO fnd a better way to deal with all kind of attribute type...
+readAttributeStringASCII :: Attribute -> IO BS.ByteString
+readAttributeStringASCII attr@(Attribute attr_id) = do
+  space <- getAttributeSpace attr
+  n <- getSimpleDataspaceExtentNPoints space
+
+  atype <- getAttributeType attr
+  ts <- getTypeSize atype
+
+  let nbytes = fromIntegral n * fromIntegral ts
+  allocaBytes nbytes $ \buf -> do
+    withErrorCheck_ $ h5a_read attr_id (hid atype) (wrapPtr buf)
+    BS.packCStringLen (buf, nbytes)
+
+doesAttributeExist :: ObjectId -- ^ Parent location
+                   -> BS.ByteString  -- ^ Attribute name
+                   -> IO Bool   -- ^ Resulting attribute
+doesAttributeExist obj aname =
+  htriToBool $ BS.useAsCString aname $ \cname -> h5a_exists (hid obj) cname
+
+data AttributeInfo = AttributeInfo
+    { attributeCOrderValid :: Bool
+    , attributeCOrder      :: H5O_msg_crt_idx_t
+    , attributeCSet        :: CSet
+    , attributeDataSize    :: HSize
+    } deriving (Eq, Ord, Read, Show)
+
+readAttributeInfo :: H5A_info_t -> AttributeInfo
+readAttributeInfo i  = AttributeInfo
+    { attributeCOrderValid   = hboolToBool (h5a_info_t'corder_valid i)
+    , attributeCOrder        = h5a_info_t'corder i
+    , attributeCSet          = cSetFromCode (h5a_info_t'cset i)
+    , attributeDataSize      = HSize (h5a_info_t'data_size i)
+    }
+
+getAttributeInfo :: Attribute -> IO AttributeInfo
+getAttributeInfo (Attribute attr_id) =
+    fmap readAttributeInfo $
+        withOut_ $ \info ->
+            withErrorCheck_ $ h5a_get_info attr_id info
+
+foreign import ccall "wrapper" wrap_H5A_operator2_t
+    :: (HId_t -> CString -> In H5A_info_t -> InOut a -> IO HErr_t)
+    -> IO (FunPtr (HId_t -> CString -> In H5A_info_t -> InOut a -> IO HErr_t))
+
+with_operator2_t :: (Group -> BS.ByteString -> AttributeInfo -> IO HErr_t)
+     -> (H5A_operator2_t () -> InOut () -> IO HErr_t)
+     -> IO HErr_t
+with_operator2_t op f = do
+    exception1 <- newIORef Nothing :: IO (IORef (Maybe SomeException))
+
+    op1 <- wrap_H5A_operator2_t $ \grp name (In attribute) _opData -> do
+        name1 <- BS.packCString name
+        attribute1 <- peek attribute
+        result <- try (op (uncheckedFromHId grp) name1 (readAttributeInfo attribute1))
+        case result of
+            Left exc -> do
+                writeIORef exception1 (Just exc)
+                return maxBound
+            Right x -> return x
+
+    result <- f op1 (InOut nullPtr) `finally` freeHaskellFunPtr op1
+
+    if result == maxBound
+        then do
+            exception2 <- readIORef exception1
+            maybe (return result) throwIO exception2
+
+        else return result
+
+-- TODO : It would be nice if we didn't expose HErr_t in these callback functions.
+--        Decide whether we want Either or Exceptions.
+iterateAttributes :: ObjectId-> IndexType -> IterOrder -> Maybe HSize -> (Group -> BS.ByteString -> AttributeInfo -> IO HErr_t) -> IO HSize
+iterateAttributes obj indexType order startIndex op =
+    fmap HSize $
+        withInOut_ (maybe 0 hSize startIndex) $ \ioStartIndex ->
+            withErrorCheck_ $
+                with_operator2_t op $ \iop opData ->
+                    h5a_iterate2 (hid obj) (indexTypeCode indexType) (iterOrderCode order) ioStartIndex iop opData
+
+iterateAttributesByName :: ObjectId -> BS.ByteString -> IndexType -> IterOrder -> Maybe HSize -> Maybe LAPL -> (Group -> BS.ByteString -> AttributeInfo -> IO HErr_t) -> IO HSize
+iterateAttributesByName obj groupName indexType order startIndex lapl op =
+    fmap HSize $
+        withInOut_ (maybe 0 hSize startIndex) $ \ioStartIndex ->
+            withErrorCheck_ $
+                with_operator2_t op $ \iop opData ->
+                    BS.useAsCString groupName $ \cgroupName ->
+                        h5a_iterate_by_name (hid obj) cgroupName (indexTypeCode indexType) (iterOrderCode order) ioStartIndex iop opData (maybe h5p_DEFAULT hid lapl)
diff --git a/src/Bindings/HDF5/Core.hs b/src/Bindings/HDF5/Core.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Core.hs
@@ -0,0 +1,86 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module Bindings.HDF5.Core
+    ( module Bindings.HDF5.Core
+    , module Bindings.HDF5.Core.HId
+    , module Bindings.HDF5.Core.HDFResultType
+    ) where
+
+import Bindings.HDF5.Raw.H5
+
+import Bindings.HDF5.Core.HId
+import Bindings.HDF5.Core.HDFResultType
+
+import Data.Bits
+import Foreign.Storable
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+newtype HSize = HSize HSize_t
+    deriving (Eq, Ord, Enum, Bounded, Num, Real, Integral, Bits, Storable)
+
+hSize :: HSize -> HSize_t
+hSize (HSize s) = s
+
+instance Read HSize where
+    readsPrec p s =
+        [ (HSize (HSize_t n), rest)
+        | (n,rest) <- readsPrec p s
+        ]
+
+instance Show HSize where
+    showsPrec p (HSize (HSize_t n)) = showsPrec p n
+
+newtype HSSize = HSSize HSSize_t
+    deriving (Eq, Ord, Enum, Bounded, Num, Real, Integral, Bits, Storable)
+
+hSSize :: HSSize -> HSSize_t
+hSSize (HSSize s) = s
+
+instance Read HSSize where
+    readsPrec p s =
+        [ (HSSize (HSSize_t n), rest)
+        | (n,rest) <- readsPrec p s
+        ]
+
+instance Show HSSize where
+    showsPrec p (HSSize (HSSize_t n)) = showsPrec p n
+
+newtype HAddr = HAddr HAddr_t
+    deriving (Eq, Ord, Enum, Bounded, Num, Real, Integral, Bits, Storable)
+
+hAddr :: HAddr -> HAddr_t
+hAddr (HAddr a) = a
+
+instance Read HAddr where
+    readsPrec p s =
+        [ (HAddr (HAddr_t n), rest)
+        | (n, rest) <- readsPrec p s
+        ]
+
+instance Show HAddr where
+    showsPrec p (HAddr (HAddr_t n)) = showsPrec p n
+
+data IH_Info = IH_Info
+    { indexSize     :: !HSize
+    , heapSize      :: !HSize
+    } deriving (Eq, Ord, Read, Show)
+
+data IndexType
+    = ByName
+    | ByCreationOrder
+    deriving (Eq, Ord, Enum, Bounded, Read, Show)
+
+indexTypeCode :: IndexType -> H5_index_t
+indexTypeCode ByName            = h5_INDEX_NAME
+indexTypeCode ByCreationOrder   = h5_INDEX_CRT_ORDER
+
+data IterOrder
+    = Increasing
+    | Decreasing
+    | Native
+    deriving (Eq, Ord, Enum, Bounded, Read, Show)
+
+iterOrderCode :: IterOrder -> H5_iter_order_t
+iterOrderCode Increasing = h5_ITER_INC
+iterOrderCode Decreasing = h5_ITER_DEC
+iterOrderCode Native     = h5_ITER_NATIVE
diff --git a/src/Bindings/HDF5/Core/HDFResultType.hs b/src/Bindings/HDF5/Core/HDFResultType.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Core/HDFResultType.hs
@@ -0,0 +1,42 @@
+module Bindings.HDF5.Core.HDFResultType where
+
+import Bindings.HDF5.Raw
+
+-- |Types returned from HDF5 library functions which always signal failure
+-- the same way.
+class HDFResultType t where
+    isError :: t -> Bool
+
+instance HDFResultType HId_t where
+    isError = (< HId_t 0)
+
+instance HDFResultType HErr_t where
+    isError = (< 0)
+
+instance HDFResultType HTri_t where
+    isError (HTri_t x) = x < 0
+
+instance HDFResultType HAddr_t where
+    isError = (hADDR_UNDEF ==)
+
+instance HDFResultType H5T_order_t where
+    isError (H5T_order_t c) = c < 0
+
+instance HDFResultType H5T_pad_t where
+    isError (H5T_pad_t c) = c < 0
+
+instance HDFResultType H5T_str_t where
+    isError (H5T_str_t c) = c < 0
+
+instance HDFResultType H5_index_t where
+    isError (H5_index_t c) = c < 0
+
+instance HDFResultType H5_iter_order_t where
+    isError (H5_iter_order_t c) = c < 0
+
+instance HDFResultType H5I_type_t where
+    isError (H5I_type_t c) = c < 0
+
+instance HDFResultType H5T_norm_t where
+    isError (H5T_norm_t c) = c < 0
+
diff --git a/src/Bindings/HDF5/Core/HId.hs b/src/Bindings/HDF5/Core/HId.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Core/HId.hs
@@ -0,0 +1,27 @@
+-- |The HDF5 C type @hid_t@ is used to represent many, many different things.
+-- In this Haskell interface, it is always wrapped up in a newtype
+-- indicating its intent.  These newtypes all need to be convertible to
+-- and from 'HId_t' in order to actually use them with the raw bindings.
+-- This modules provides a standard interface for doing so.
+module Bindings.HDF5.Core.HId where
+
+import Bindings.HDF5.Raw.H5I
+
+-- |Types which can be converted to 'HId_t' (i.e., those which can be passed
+-- to HDF5 functions)
+class HId t where
+    hid         :: t -> HId_t
+
+-- |Types which can be converted from 'HId_t' (i.e., those which can be
+-- returned by HDF5 functions)
+class FromHId t where
+    uncheckedFromHId :: HId_t -> t
+
+instance HId HId_t where
+    hid = id
+
+instance FromHId HId_t where
+    uncheckedFromHId = id
+
+-- |HId types which can also serve as containers for other objects
+class HId t => Location t where
diff --git a/src/Bindings/HDF5/Dataset.hs b/src/Bindings/HDF5/Dataset.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Dataset.hs
@@ -0,0 +1,230 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module Bindings.HDF5.Dataset
+    ( Dataset
+    , createDataset
+    , createAnonymousDataset
+    , openDataset
+    , closeDataset
+
+    , getDatasetSpace
+    , SpaceStatus(..)
+    , getDatasetSpaceStatus
+    , getDatasetType
+
+    , getDatasetCreatePList
+    , getDatasetAccessPList
+
+    , getDatasetStorageSize
+    , getDatasetOffset
+
+    , readDataset
+    , readDatasetInto
+    , writeDataset
+
+    , setDatasetExtent
+
+    , fillSelection
+    ) where
+
+#if __GLASGOW_HASKELL__ < 710
+import Control.Applicative ((<$>))
+#endif
+
+import Bindings.HDF5.Core
+import Bindings.HDF5.Dataspace
+import Bindings.HDF5.Datatype.Internal
+import Bindings.HDF5.Error
+import Bindings.HDF5.Object
+import Bindings.HDF5.PropertyList.DAPL
+import Bindings.HDF5.PropertyList.DCPL
+import Bindings.HDF5.PropertyList.DXPL
+import Bindings.HDF5.PropertyList.LCPL
+import Bindings.HDF5.Raw.H5D
+import Bindings.HDF5.Raw.H5I
+import Bindings.HDF5.Raw.H5P
+import Bindings.HDF5.Raw.H5S
+import Control.Monad.ST (RealWorld)
+import qualified Data.ByteString as BS
+import qualified Data.Vector.Storable as SV
+import qualified Data.Vector.Storable.Mutable as SV.M
+import Foreign.Ptr.Conventions
+
+newtype Dataset = Dataset HId_t
+    deriving (Eq, HId, FromHId, HDFResultType)
+
+instance Object Dataset where
+    staticObjectType = Tagged (Just DatasetObj)
+
+createDataset :: Location loc
+    => loc -> BS.ByteString -> Datatype -> Dataspace -> Maybe LCPL -> Maybe DCPL -> Maybe DAPL -> IO Dataset
+createDataset loc_id name type_id space_id lcpl_id dcpl_id dapl_id =
+    fmap Dataset $
+        withErrorCheck $
+            BS.useAsCString name $ \cname ->
+                h5d_create2 (hid loc_id) cname (hid type_id) (hid space_id) (maybe h5p_DEFAULT hid lcpl_id) (maybe h5p_DEFAULT hid dcpl_id) (maybe h5p_DEFAULT hid dapl_id)
+
+createAnonymousDataset :: Location loc
+    => loc -> Datatype -> Dataspace -> Maybe DCPL -> Maybe DAPL -> IO Dataset
+createAnonymousDataset loc_id type_id space_id dcpl_id dapl_id =
+    fmap Dataset $
+        withErrorCheck $
+            h5d_create_anon (hid loc_id) (hid type_id) (hid space_id) (maybe h5p_DEFAULT hid dcpl_id) (maybe h5p_DEFAULT hid dapl_id)
+
+openDataset :: Location loc
+    => loc -> BS.ByteString -> Maybe DAPL -> IO Dataset
+openDataset loc_id name dapl_id =
+    fmap Dataset $
+        withErrorCheck $
+            BS.useAsCString name $ \cname ->
+                h5d_open2 (hid loc_id) cname (maybe h5p_DEFAULT hid dapl_id)
+
+closeDataset :: Dataset -> IO ()
+closeDataset (Dataset dset_id) =
+    withErrorCheck_ (h5d_close dset_id)
+
+getDatasetSpace :: Dataset -> IO Dataspace
+getDatasetSpace (Dataset dset_id) =
+    uncheckedFromHId
+    <$> withErrorCheck (h5d_get_space dset_id)
+
+data SpaceStatus
+    = NotAllocated
+    | Allocated
+    | PartAllocated
+    deriving (Eq, Ord, Read, Show, Enum, Bounded)
+
+spaceStatusFromCode :: H5D_space_status_t -> SpaceStatus
+spaceStatusFromCode c
+    | c == h5d_SPACE_STATUS_NOT_ALLOCATED   = NotAllocated
+    | c == h5d_SPACE_STATUS_ALLOCATED       = Allocated
+    | c == h5d_SPACE_STATUS_PART_ALLOCATED  = PartAllocated
+    | otherwise = error ("Unknown H5D_space_status_t " ++ show c)
+
+getDatasetSpaceStatus :: Dataset -> IO SpaceStatus
+getDatasetSpaceStatus (Dataset dset_id) =
+    fmap spaceStatusFromCode $
+        withOut_ $ \status ->
+            withErrorCheck (h5d_get_space_status dset_id status)
+
+getDatasetType :: Dataset -> IO Datatype
+getDatasetType (Dataset dset_id) =
+    fmap Datatype $
+        withErrorCheck $
+            h5d_get_type dset_id
+
+getDatasetCreatePList :: Dataset -> IO DCPL
+getDatasetCreatePList (Dataset dset_id) =
+    fmap uncheckedFromHId $
+        withErrorCheck $
+            h5d_get_create_plist dset_id
+
+getDatasetAccessPList :: Dataset -> IO DAPL
+getDatasetAccessPList (Dataset dset_id) =
+    fmap uncheckedFromHId $
+        withErrorCheck $
+            h5d_get_access_plist dset_id
+
+getDatasetStorageSize :: Dataset -> IO HSize
+getDatasetStorageSize (Dataset dset_id) =
+    HSize
+    <$> h5d_get_storage_size dset_id
+
+getDatasetOffset :: Dataset -> IO HAddr
+getDatasetOffset (Dataset dset_id) =
+    fmap HAddr $
+        withErrorCheck $
+            h5d_get_offset dset_id
+
+readDataset :: NativeType t =>
+    Dataset -> Maybe Dataspace -> Maybe DXPL -> IO (SV.Vector t)
+readDataset dset@(Dataset dset_id) file_space_id plist_id = do
+    effectiveSelection <- maybe (getDatasetSpace dset) return file_space_id
+    n <- getSimpleDataspaceExtentNPoints effectiveSelection
+
+    withOutVector_ (fromIntegral n) $ \buf ->
+        withErrorCheck_ $
+            h5d_read dset_id (hdfTypeOf1 buf) h5s_ALL (maybe h5s_ALL hid file_space_id) (maybe h5p_DEFAULT hid plist_id) buf
+
+readDatasetInto :: NativeType t =>
+    Dataset -> Maybe Dataspace -> Maybe Dataspace -> Maybe DXPL -> SV.MVector RealWorld t -> IO ()
+readDatasetInto dset@(Dataset dset_id) mem_space_id file_space_id plist_id vec = do
+    effectiveSelection <- maybe (getDatasetSpace dset) return mem_space_id
+    n <- getSimpleDataspaceExtentNPoints effectiveSelection
+
+    withOutMVector vec $ \vecSz buf ->
+        if fromIntegral n > vecSz
+            then fail "readDatasetInto: output vector is too small to contain selection"
+            else withErrorCheck_ $
+                    h5d_read dset_id (hdfTypeOf1 buf) (maybe h5s_ALL hid mem_space_id) (maybe h5s_ALL hid file_space_id) (maybe h5p_DEFAULT hid plist_id) buf
+
+writeDataset :: NativeType t =>
+    Dataset -> Maybe Dataspace -> Maybe Dataspace -> Maybe DXPL -> SV.Vector t -> IO ()
+writeDataset (Dataset dset_id) mem_space_id file_space_id plist_id buf =
+    withErrorCheck_ $
+        withInVector buf $ \ibuf ->
+            h5d_write dset_id (hdfTypeOf1 buf) (maybe h5s_ALL hid mem_space_id) (maybe h5s_ALL hid file_space_id) (maybe h5p_DEFAULT hid plist_id) ibuf
+
+-- foreign import ccall "wrapper" wrap_iterate_op
+--     :: (InOut a -> HId_t -> CUInt -> InArray HSize_t -> InOut b -> IO HErr_t)
+--     -> IO (H5D_operator_t a b)
+--
+-- TODO: figure out a good way to properly encapsulate the buffer so that
+-- out-of-bounds accesses are impossible.  Probably use a storable vector
+-- and check the bounds against the dataspace.
+-- Also check whether h5s_ALL is a valid dataspace; Actually I'm not sure how
+-- it could be, given that there is no information here about the size
+-- of the array apart from whatever is carried in the dataspace.
+-- iterateDatasetSelection :: NativeType t => InOutArray t -> Dataspace -> (InOut t -> [HSize] -> IO HErr_t) -> IO ()
+-- iterateDatasetSelection buf space_id op = do
+--     -- In order to marshall Haskell exceptions through the iterate operations,
+--     -- we use 'maxBound' as a "something might have happened" return value
+--     -- and pass a description of what that was via these IORefs.
+--     --
+--     -- The assertion mentioned here is that the 'type_id' argument to h5d_iterate
+--     -- is passed unchanged to the operator.  If that doesn't hold, then this
+--     -- function will need a more complicated type.
+--     assertionFailed <- newIORef False
+--     exception       <- newIORef Nothing :: IO (IORef (Maybe SomeException))
+--
+--     let bufType = hdfTypeOf1 buf
+--
+--     op <- wrap_iterate_op $ \elem type_id ndim (InArray point) _operator_data -> do
+--         point <- peekArray (fromIntegral ndim) point
+--         if type_id == bufType
+--             then do
+--                 result <- try (op elem (fmap HSize point))
+--                 case result of
+--                     Left exc -> do
+--                         writeIORef exception (Just exc)
+--                         return maxBound
+--                     Right x -> return x
+--             else do
+--                 writeIORef assertionFailed True
+--                 return maxBound
+--
+--     result <- withErrorCheck_
+--         (h5d_iterate buf bufType (hid space_id) op (InOut nullPtr)
+--         `finally` freeHaskellFunPtr op)
+--
+--     when (result == maxBound) $ do
+--         assertionFailed <- readIORef assertionFailed
+--         when assertionFailed (throwIO (AssertionFailed "iterateDatasetSelection: operator called with different type_id than h5d_iterate was called with!"))
+--         exception <- readIORef exception
+--         maybe (return result) throwIO exception
+--
+--     return result
+
+setDatasetExtent :: Dataset -> [HSize] -> IO ()
+setDatasetExtent (Dataset dset_id) sizes =
+    withErrorCheck_ $
+        withInList [sz | HSize sz <- sizes] $ \isizes ->
+            h5d_set_extent dset_id isizes
+
+-- Fill part of a vector with a value, using the geometry and selection of the given data space
+fillSelection :: (NativeType a, NativeType b) => a -> SV.MVector RealWorld b -> Dataspace -> IO ()
+fillSelection fill buf space =
+    withErrorCheck_ $
+        withIn fill $ \ifill ->
+            SV.M.unsafeWith buf $ \pbuf ->
+                h5d_fill ifill (hdfTypeOf1 ifill) (InOutArray pbuf) (hdfTypeOf1 buf) (hid space)
diff --git a/src/Bindings/HDF5/Dataspace.hs b/src/Bindings/HDF5/Dataspace.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Dataspace.hs
@@ -0,0 +1,372 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module Bindings.HDF5.Dataspace
+    ( Dataspace
+    , DataspaceClass(..)
+    , SelectionOperator(..)
+    , SelectionType(..)
+
+    , createDataspace
+    , createSimpleDataspace
+    , createExpandableDataspace
+
+    , copyDataspace
+
+    , closeDataspace
+
+    , encodeDataspace
+    , decodeDataspace
+
+    , getSimpleDataspaceExtentNPoints
+    , getSimpleDataspaceExtentNDims
+    , getSimpleDataspaceExtent
+
+    , isSimpleDataspace
+
+    , getDataspaceSelectionNPoints
+
+    , selectHyperslab
+    , selectElements
+
+    , getSimpleDataspaceExtentType
+
+    , setDataspaceExtentNone
+    , copyDataspaceExtent
+    , dataspaceExtentsEqual
+
+    , selectAll
+    , selectNone
+
+    , offsetSimpleDataspaceSelection
+
+    , selectionValid
+
+    , getHyperslabSelection
+    , getHyperslabSelectionNBlocks
+    , getHyperslabSelectionBlockList
+
+    , getElementSelection
+    , getElementSelectionNPoints
+    , getElementSelectionPointList
+
+    , getSelectionBounds
+
+    , getSelectionType
+    ) where
+
+import Bindings.HDF5.Core
+import Bindings.HDF5.Error
+import Bindings.HDF5.Object
+import Bindings.HDF5.Raw.H5I
+import Bindings.HDF5.Raw.H5S
+import Control.Exception (assert)
+import Control.Monad
+import qualified Data.ByteString as BS
+import qualified Data.ByteString.Unsafe as BS
+import Data.List
+import Data.Maybe
+import Data.Tagged
+import qualified Data.Vector as V
+import qualified Data.Vector.Storable as SV
+import Foreign
+import Foreign.C
+import Foreign.Ptr.Conventions
+
+newtype Dataspace = Dataspace HId_t
+    deriving (Eq, HId, FromHId, HDFResultType)
+
+instance Object Dataspace where
+    staticObjectType = Tagged (Just DataspaceObj)
+
+data DataspaceClass
+    = Scalar
+    | Simple
+    | Null
+    deriving (Eq, Ord, Enum, Bounded, Read, Show)
+
+rawDataspaceClass :: DataspaceClass -> H5S_class_t
+rawDataspaceClass Scalar = h5s_SCALAR
+rawDataspaceClass Simple = h5s_SIMPLE
+rawDataspaceClass Null   = h5s_NULL
+
+dataspaceClass :: H5S_class_t -> DataspaceClass
+dataspaceClass c
+    | c == h5s_SCALAR   = Scalar
+    | c == h5s_SIMPLE   = Simple
+    | c == h5s_NULL     = Null
+    | otherwise         = error ("unknown dataspace class: " ++ show c)
+
+createDataspace :: DataspaceClass -> IO Dataspace
+createDataspace cls =
+    fmap Dataspace $
+        withErrorCheck $
+            h5s_create (rawDataspaceClass cls)
+
+createSimpleDataspace :: [HSize] -> IO Dataspace
+createSimpleDataspace dims =
+    fmap Dataspace $
+        withErrorCheck $
+            withInList (map hSize dims) $ \idims ->
+                h5s_create_simple n idims (InArray nullPtr)
+    where n = genericLength dims
+
+createExpandableDataspace :: [(HSize, Maybe HSize)] -> IO Dataspace
+createExpandableDataspace dims =
+    fmap Dataspace $
+        withErrorCheck $
+            withInList (map hSize dimSizes) $ \idimSizes ->
+                withInList (map (maybe h5s_UNLIMITED hSize) dimLimits) $ \idimLimits ->
+                    h5s_create_simple n idimSizes idimLimits
+    where
+        n = genericLength dims
+        (dimSizes, dimLimits) = unzip dims
+
+copyDataspace :: Dataspace -> IO Dataspace
+copyDataspace (Dataspace space_id) =
+    fmap Dataspace $
+        withErrorCheck $
+            h5s_copy space_id
+
+closeDataspace :: Dataspace -> IO ()
+closeDataspace (Dataspace space_id) =
+    withErrorCheck_ $
+        h5s_close space_id
+
+encodeDataspace :: Dataspace -> IO BS.ByteString
+encodeDataspace (Dataspace space_id) =
+    withOutByteString $ \buf bufSz ->
+        withInOut_ bufSz $ \ioBufSz ->
+            withErrorCheck_ $
+                h5s_encode space_id buf ioBufSz
+
+decodeDataspace :: BS.ByteString -> IO Dataspace
+decodeDataspace bs = BS.unsafeUseAsCString bs $ \buf ->
+    fmap Dataspace $
+        withErrorCheck $
+            h5s_decode (InArray buf)
+
+getSimpleDataspaceExtentNPoints :: Dataspace -> IO HSize
+getSimpleDataspaceExtentNPoints (Dataspace space_id) =
+    fmap fromIntegral $
+        withErrorWhen (< 0) $
+            h5s_get_simple_extent_npoints space_id
+
+getSimpleDataspaceExtentNDims :: Dataspace -> IO CInt
+getSimpleDataspaceExtentNDims (Dataspace space_id) =
+    withErrorWhen (< 0) $
+        h5s_get_simple_extent_ndims space_id
+
+getSimpleDataspaceExtent :: Dataspace -> IO ([HSize], [Maybe HSize])
+getSimpleDataspaceExtent space@(Dataspace space_id) = do
+    n <- getSimpleDataspaceExtentNDims space
+
+    (dims, (maxDims, n')) <-
+        withOutList (fromIntegral n) $ \dims ->
+            withOutList (fromIntegral n) $ \maxDims ->
+                withErrorWhen (< 0) $
+                    h5s_get_simple_extent_dims space_id dims maxDims
+
+    assert (n==n') $ return
+        ( map HSize dims
+        , [ if d == h5s_UNLIMITED then Nothing else Just (HSize d) | d <- maxDims]
+        )
+
+isSimpleDataspace :: Dataspace -> IO Bool
+isSimpleDataspace (Dataspace space_id) =
+    htriToBool $
+        h5s_is_simple space_id
+
+getDataspaceSelectionNPoints :: Dataspace -> IO HSize
+getDataspaceSelectionNPoints (Dataspace space_id) =
+    fmap fromIntegral $
+        withErrorWhen (< 0) $
+            h5s_get_select_npoints space_id
+
+data SelectionOperator
+    = Set
+    | Or
+    | And
+    | Xor
+    | NotB
+    | NotA
+    | Append
+    | Prepend
+    deriving (Eq, Ord, Enum, Bounded, Read, Show)
+
+rawSelectionOperator :: SelectionOperator -> H5S_seloper_t
+rawSelectionOperator Set     = h5s_SELECT_SET
+rawSelectionOperator Or      = h5s_SELECT_OR
+rawSelectionOperator And     = h5s_SELECT_AND
+rawSelectionOperator Xor     = h5s_SELECT_XOR
+rawSelectionOperator NotB    = h5s_SELECT_NOTB
+rawSelectionOperator NotA    = h5s_SELECT_NOTA
+rawSelectionOperator Append  = h5s_SELECT_APPEND
+rawSelectionOperator Prepend = h5s_SELECT_PREPEND
+
+selectHyperslab :: Dataspace -> SelectionOperator -> [(HSize, Maybe HSize, HSize, Maybe HSize)] -> IO ()
+selectHyperslab space@(Dataspace space_id) oper hyperSlab = do
+    nDims <- getSimpleDataspaceExtentNDims space
+
+    when (length hyperSlab /= fromIntegral nDims)
+        (fail "selectHyperslab: the given hyperslab has the wrong number of dimensions for this dataspace")
+
+    withErrorCheck_ $
+        withInList' start $ \istart ->
+            maybe withNull withInList' stride $ \istride ->
+                withInList' count $ \icount ->
+                    maybe withNull withInList' block $ \iblock ->
+                        h5s_select_hyperslab space_id (rawSelectionOperator oper) istart istride icount iblock
+    where
+        (start, mbStrides, count, mbBlocks) = unzip4 hyperSlab
+        stride
+            | any isJust mbStrides  = Just (map (fromMaybe 1) mbStrides)
+            | otherwise             = Nothing
+        block
+            | any isJust mbBlocks  = Just (map (fromMaybe 1) mbBlocks)
+            | otherwise             = Nothing
+        withNull f = f (InArray nullPtr)
+        withInList' = withInList . map hSize
+
+selectElements :: Dataspace -> SelectionOperator -> V.Vector (SV.Vector HSize) -> IO ()
+selectElements space@(Dataspace space_id) oper elems = do
+    nDims <- getSimpleDataspaceExtentNDims space
+
+    let nElems = V.length elems
+        packed = SV.generate (nElems * fromIntegral nDims) $ \i ->
+            case i `divMod` nElems of
+                (dim, elt) -> elems V.! elt SV.! dim
+
+    withErrorCheck_ $
+        withInVector packed $ \ielems ->
+            h5s_select_elements space_id (rawSelectionOperator oper) (fromIntegral nElems) (castWrappedPtr ielems)
+
+-- TODO: determine whether to throw an exception or simply report it
+-- when the returned value is invalid.
+getSimpleDataspaceExtentType :: Dataspace -> IO DataspaceClass
+getSimpleDataspaceExtentType (Dataspace space_id) =
+    fmap dataspaceClass $
+        withErrorWhen (\(H5S_class_t c) -> c < 0) $
+            h5s_get_simple_extent_type space_id
+
+setDataspaceExtentNone :: Dataspace -> IO ()
+setDataspaceExtentNone (Dataspace space_id) =
+    withErrorCheck_ $
+        h5s_set_extent_none space_id
+
+copyDataspaceExtent :: Dataspace -> Dataspace -> IO ()
+copyDataspaceExtent (Dataspace dst) (Dataspace src) =
+    withErrorCheck_ $
+        h5s_extent_copy dst src
+
+dataspaceExtentsEqual :: Dataspace -> Dataspace -> IO Bool
+dataspaceExtentsEqual (Dataspace s1) (Dataspace s2) =
+    htriToBool $
+        h5s_extent_equal s1 s2
+
+selectAll :: Dataspace -> IO ()
+selectAll (Dataspace space_id) =
+    withErrorCheck_ $
+        h5s_select_all space_id
+
+selectNone :: Dataspace -> IO ()
+selectNone (Dataspace space_id) =
+    withErrorCheck_ $
+        h5s_select_none space_id
+
+offsetSimpleDataspaceSelection :: Dataspace -> SV.Vector HSSize -> IO ()
+offsetSimpleDataspaceSelection space@(Dataspace space_id) offsets = do
+    nDims <- getSimpleDataspaceExtentNDims space
+
+    when (fromIntegral nDims /= SV.length offsets)
+        (fail "offsetSimpleDataspaceSelection: offset vector's length must equal number dimensions in dataspace")
+
+    withErrorCheck_ $
+        withInVector offsets $ \ioffsets ->
+            h5s_offset_simple space_id (castWrappedPtr ioffsets)
+
+selectionValid :: Dataspace -> IO Bool
+selectionValid (Dataspace space_id) =
+    htriToBool $
+        h5s_select_valid space_id
+
+getHyperslabSelection :: Dataspace -> IO (V.Vector (SV.Vector HSize, SV.Vector HSize))
+getHyperslabSelection space = getHyperslabSelectionBlockList space 0 maxBound
+
+getHyperslabSelectionNBlocks :: Dataspace -> IO HSize
+getHyperslabSelectionNBlocks (Dataspace space_id) =
+    fmap fromIntegral $
+        withErrorWhen (< 0) $
+            h5s_get_select_hyper_nblocks space_id
+
+getHyperslabSelectionBlockList :: Dataspace -> HSize -> HSize -> IO (V.Vector (SV.Vector HSize, SV.Vector HSize))
+getHyperslabSelectionBlockList space@(Dataspace space_id) startBlock numBlocks = do
+    n <- getHyperslabSelectionNBlocks space
+    nDims <- getSimpleDataspaceExtentNDims space
+
+    let nBlks = min numBlocks (n - startBlock)
+        blkSize = 2 * fromIntegral nDims
+        numSizes = nBlks * blkSize
+
+
+    sizes <- withOutVector_ (fromIntegral numSizes) $ \buf ->
+        withErrorCheck_ $
+            h5s_get_select_hyper_blocklist space_id (hSize startBlock) (hSize nBlks) (castWrappedPtr buf)
+
+    let decodePt i = SV.slice i (fromIntegral nDims) sizes
+        decodeBlock i = (decodePt b, decodePt (b + fromIntegral nDims))
+            where b = i * fromIntegral blkSize
+    return $! V.generate (fromIntegral nBlks) decodeBlock
+
+getElementSelection :: Dataspace -> IO (V.Vector (SV.Vector HSize))
+getElementSelection space = getElementSelectionPointList space 0 maxBound
+
+getElementSelectionNPoints :: Dataspace -> IO HSize
+getElementSelectionNPoints (Dataspace space_id) =
+    fmap fromIntegral $
+        withErrorWhen (< 0) $
+            h5s_get_select_elem_npoints space_id
+
+getElementSelectionPointList :: Dataspace -> HSize -> HSize -> IO (V.Vector (SV.Vector HSize))
+getElementSelectionPointList space@(Dataspace space_id) startPoint numPoints = do
+    n <- getElementSelectionNPoints space
+    nDims <- getSimpleDataspaceExtentNDims space
+
+    let nPts = min numPoints (n - startPoint)
+        sz = nPts * fromIntegral nDims
+
+    rawPoints <- withOutVector_ (fromIntegral sz) $ \buf ->
+        withErrorCheck_ $
+            h5s_get_select_elem_pointlist space_id (hSize startPoint) (hSize nPts) (castWrappedPtr buf)
+
+    let unpackPt i = SV.generate (fromIntegral nDims) $ \j -> rawPoints SV.! (i + j * fromIntegral nPts)
+
+    return $! V.generate (fromIntegral nPts) unpackPt
+
+getSelectionBounds :: Dataspace -> IO [(HSize, HSize)]
+getSelectionBounds space@(Dataspace space_id) = do
+    n <- getSimpleDataspaceExtentNDims space
+
+    (start, end) <-
+        withOutList (fromIntegral n) $ \start ->
+            withOutList_ (fromIntegral n) $ \end ->
+                withErrorCheck_ $
+                    h5s_get_select_bounds space_id start end
+
+    return [(HSize s, HSize e) | (s,e) <- zip start end]
+
+data SelectionType
+    = Points
+    | Hyperslabs
+    deriving (Eq, Ord, Bounded, Enum, Read, Show)
+
+selectionType :: H5S_sel_type -> Maybe SelectionType
+selectionType c
+    | c == h5s_SEL_NONE         = Nothing
+    | c == h5s_SEL_POINTS       = Just Points
+    | c == h5s_SEL_HYPERSLABS   = Just Hyperslabs
+    | otherwise                 = error ("unknown h5s_SEL value" ++ show c)
+
+getSelectionType :: Dataspace -> IO (Maybe SelectionType)
+getSelectionType (Dataspace space_id) =
+    fmap selectionType $
+        withErrorWhen (\(H5S_sel_type c) -> c < 0) $
+            h5s_get_select_type space_id
diff --git a/src/Bindings/HDF5/Datatype.hs b/src/Bindings/HDF5/Datatype.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Datatype.hs
@@ -0,0 +1,424 @@
+module Bindings.HDF5.Datatype
+    ( Datatype
+    , Class(..)
+    , CSet(..)
+    , ByteOrder(..)
+    , Normalization(..)
+    , Pad(..)
+    , StringPad(..)
+
+    , NativeType(..)
+    , nativeTypeOf
+    , nativeTypeOf1
+
+    , module Bindings.HDF5.Datatype
+    ) where
+
+import Bindings.HDF5.Raw.H5P
+import Bindings.HDF5.Raw.H5T
+import Bindings.HDF5.Core
+import Bindings.HDF5.Error
+import Bindings.HDF5.PropertyList.LCPL
+import Bindings.HDF5.PropertyList.TAPL
+import Bindings.HDF5.PropertyList.TCPL
+import qualified Data.ByteString as BS
+import qualified Data.ByteString.Unsafe as BS
+import Data.List
+import Foreign
+import Foreign.C.Types
+import Foreign.Ptr.Conventions
+
+import Bindings.HDF5.Datatype.Internal
+
+-- ieeeF32be            = Datatype h5t_IEEE_F32BE
+-- ieeeF32le            = Datatype h5t_IEEE_F32LE
+-- ieeeF64be            = Datatype h5t_IEEE_F64BE
+-- ieeeF64le            = Datatype h5t_IEEE_F64LE
+-- stdI8be              = Datatype h5t_STD_I8BE
+-- stdI8le              = Datatype h5t_STD_I8LE
+-- stdI16be             = Datatype h5t_STD_I16BE
+-- stdI16le             = Datatype h5t_STD_I16LE
+-- stdI32be             = Datatype h5t_STD_I32BE
+-- stdI32le             = Datatype h5t_STD_I32LE
+-- stdI64be             = Datatype h5t_STD_I64BE
+-- stdI64le             = Datatype h5t_STD_I64LE
+-- stdU8be              = Datatype h5t_STD_U8BE
+-- stdU8le              = Datatype h5t_STD_U8LE
+-- stdU16be             = Datatype h5t_STD_U16BE
+-- stdU16le             = Datatype h5t_STD_U16LE
+-- stdU32be             = Datatype h5t_STD_U32BE
+-- stdU32le             = Datatype h5t_STD_U32LE
+-- stdU64be             = Datatype h5t_STD_U64BE
+-- stdU64le             = Datatype h5t_STD_U64LE
+-- stdB8be              = Datatype h5t_STD_B8BE
+-- stdB8le              = Datatype h5t_STD_B8LE
+-- stdB16be             = Datatype h5t_STD_B16BE
+-- stdB16le             = Datatype h5t_STD_B16LE
+-- stdB32be             = Datatype h5t_STD_B32BE
+-- stdB32le             = Datatype h5t_STD_B32LE
+-- stdB64be             = Datatype h5t_STD_B64BE
+-- stdB64le             = Datatype h5t_STD_B64LE
+-- stdRefObj            = Datatype h5t_STD_REF_OBJ
+-- stdRefDsetreg        = Datatype h5t_STD_REF_DSETREG
+-- unixD32be            = Datatype h5t_UNIX_D32BE
+-- unixD32le            = Datatype h5t_UNIX_D32LE
+-- unixD64be            = Datatype h5t_UNIX_D64BE
+-- unixD64le            = Datatype h5t_UNIX_D64LE
+-- cS1                  = Datatype h5t_C_S1
+-- fortranS1            = Datatype h5t_FORTRAN_S1
+-- intelI8              = Datatype h5t_INTEL_I8
+-- intelI16             = Datatype h5t_INTEL_I16
+-- intelI32             = Datatype h5t_INTEL_I32
+-- intelI64             = Datatype h5t_INTEL_I64
+-- intelU8              = Datatype h5t_INTEL_U8
+-- intelU16             = Datatype h5t_INTEL_U16
+-- intelU32             = Datatype h5t_INTEL_U32
+-- intelU64             = Datatype h5t_INTEL_U64
+-- intelB8              = Datatype h5t_INTEL_B8
+-- intelB16             = Datatype h5t_INTEL_B16
+-- intelB32             = Datatype h5t_INTEL_B32
+-- intelB64             = Datatype h5t_INTEL_B64
+-- intelF32             = Datatype h5t_INTEL_F32
+-- intelF64             = Datatype h5t_INTEL_F64
+-- alphaI8              = Datatype h5t_ALPHA_I8
+-- alphaI16             = Datatype h5t_ALPHA_I16
+-- alphaI32             = Datatype h5t_ALPHA_I32
+-- alphaI64             = Datatype h5t_ALPHA_I64
+-- alphaU8              = Datatype h5t_ALPHA_U8
+-- alphaU16             = Datatype h5t_ALPHA_U16
+-- alphaU32             = Datatype h5t_ALPHA_U32
+-- alphaU64             = Datatype h5t_ALPHA_U64
+-- alphaB8              = Datatype h5t_ALPHA_B8
+-- alphaB16             = Datatype h5t_ALPHA_B16
+-- alphaB32             = Datatype h5t_ALPHA_B32
+-- alphaB64             = Datatype h5t_ALPHA_B64
+-- alphaF32             = Datatype h5t_ALPHA_F32
+-- alphaF64             = Datatype h5t_ALPHA_F64
+-- mipsI8               = Datatype h5t_MIPS_I8
+-- mipsI16              = Datatype h5t_MIPS_I16
+-- mipsI32              = Datatype h5t_MIPS_I32
+-- mipsI64              = Datatype h5t_MIPS_I64
+-- mipsU8               = Datatype h5t_MIPS_U8
+-- mipsU16              = Datatype h5t_MIPS_U16
+-- mipsU32              = Datatype h5t_MIPS_U32
+-- mipsU64              = Datatype h5t_MIPS_U64
+-- mipsB8               = Datatype h5t_MIPS_B8
+-- mipsB16              = Datatype h5t_MIPS_B16
+-- mipsB32              = Datatype h5t_MIPS_B32
+-- mipsB64              = Datatype h5t_MIPS_B64
+-- mipsF32              = Datatype h5t_MIPS_F32
+-- mipsF64              = Datatype h5t_MIPS_F64
+-- vaxF32               = Datatype h5t_VAX_F32
+-- vaxF64               = Datatype h5t_VAX_F64
+
+-- * Operations defined on all datatypes
+
+createTypeID :: Class -> CSize -> IO Datatype
+createTypeID cls sz =
+    fmap Datatype $
+        withErrorCheck $
+            h5t_create (classCode cls) sz
+
+copyTypeID :: Datatype -> IO Datatype
+copyTypeID (Datatype t) =
+    fmap Datatype $
+        withErrorCheck $
+            h5t_copy t
+
+closeTypeID :: Datatype -> IO ()
+closeTypeID (Datatype t) =
+    withErrorCheck_ $
+        h5t_close t
+
+typeIDsEqual :: Datatype -> Datatype -> IO Bool
+typeIDsEqual (Datatype t1) (Datatype t2) =
+    htriToBool $
+        h5t_equal t1 t2
+
+lockTypeID :: Datatype -> IO ()
+lockTypeID (Datatype t) =
+    withErrorCheck_ $
+        h5t_lock t
+
+commitTypeID :: Location t => t -> BS.ByteString -> Datatype -> Maybe LCPL -> Maybe TCPL -> Maybe TAPL -> IO ()
+commitTypeID loc name typeId lcpl tcpl tapl =
+    withErrorCheck_ $
+        BS.useAsCString name $ \cname ->
+            h5t_commit2 (hid loc) cname (hid typeId) (maybe h5p_DEFAULT hid lcpl) (maybe h5p_DEFAULT hid tcpl) (maybe h5p_DEFAULT hid tapl)
+
+openTypeID :: Location t => t -> BS.ByteString -> Maybe TAPL -> IO Datatype
+openTypeID loc name tapl =
+    fmap Datatype $
+        BS.useAsCString name $ \cname ->
+            withErrorCheck $
+                h5t_open2 (hid loc) cname (maybe h5p_DEFAULT hid tapl)
+
+commitTypeIDAnonymously :: Location t => t -> Datatype -> Maybe TCPL -> Maybe TAPL -> IO ()
+commitTypeIDAnonymously loc typeId tcpl tapl =
+    withErrorCheck_ $
+        h5t_commit_anon (hid loc) (hid typeId) (maybe h5p_DEFAULT hid tcpl) (maybe h5p_DEFAULT hid tapl)
+
+getTypeCreationPList :: Datatype -> IO TCPL
+getTypeCreationPList (Datatype t) =
+    fmap uncheckedFromHId $
+        withErrorCheck $
+            h5t_get_create_plist t
+
+committedTypeID :: Datatype -> IO Bool
+committedTypeID (Datatype t) =
+    htriToBool $
+        h5t_committed t
+
+encodeTypeID :: Datatype -> IO BS.ByteString
+encodeTypeID (Datatype t) =
+    withOutByteString $ \buf bufSz ->
+        withInOut_ bufSz $ \ioBufSz ->
+            withErrorCheck_ $
+                h5t_encode t buf ioBufSz
+
+decodeTypeID :: BS.ByteString -> IO Datatype
+decodeTypeID bs =
+    fmap Datatype $
+        BS.unsafeUseAsCString bs $ \buf ->
+            h5t_decode (InArray buf)
+
+-- * Operations defined on compound datatypes
+
+insertCompoundTypeMember :: Datatype -> BS.ByteString -> CSize -> Datatype -> IO ()
+insertCompoundTypeMember (Datatype parent) name offset (Datatype member) =
+    withErrorCheck_ $
+        BS.useAsCString name $ \cname ->
+            h5t_insert parent cname offset member
+
+packCompoundType :: Datatype -> IO ()
+packCompoundType (Datatype t) =
+    withErrorCheck_ $
+        h5t_pack t
+
+-- * Operations defined on enumeration datatypes
+
+-- TODO: figure out good types for these
+-- createEnumType :: Datatype -> IO Datatype
+-- createEnumType (Datatype base) =
+--     fmap Datatype $
+--         withErrorCheck $
+--             h5t_enum_create base
+
+-- h5t_enum_insert
+-- h5t_enum_nameof
+-- h5t_enum_valueof
+
+-- * Operations defined on variable-length datatypes
+
+createVLenType :: Datatype -> IO Datatype
+createVLenType (Datatype base) =
+    fmap Datatype $
+        withErrorCheck $
+            h5t_vlen_create base
+
+-- * Operations defined on array datatypes
+
+createArrayType :: Datatype -> [HSize] -> IO Datatype
+createArrayType (Datatype base) dims =
+    fmap Datatype $
+        withInList (map hSize dims) $ \idims ->
+            withErrorCheck $
+                h5t_array_create2 base nDims idims
+    where nDims = genericLength dims
+
+getArrayTypeNDims :: Datatype -> IO CInt
+getArrayTypeNDims (Datatype t) =
+    withErrorWhen (< 0) $
+        h5t_get_array_ndims t
+
+getArrayTypeDims :: Datatype -> IO [HSize]
+getArrayTypeDims (Datatype t) = do
+    nDims <- getArrayTypeNDims (Datatype t)
+
+    fmap (map HSize . fst) $
+        withOutList' (fromIntegral nDims) $ \dims ->
+            fmap fromIntegral $
+                 withErrorWhen (< 0) $
+                    h5t_get_array_dims2 t dims
+
+
+-- * Operations defined on opaque datatypes
+
+setOpaqueTypeTag :: Datatype -> BS.ByteString -> IO ()
+setOpaqueTypeTag (Datatype t) tag =
+    withErrorCheck_ $
+        BS.useAsCString tag $ \ctag ->
+            h5t_set_tag t ctag
+
+getOpaqueTypeTag :: Datatype -> IO BS.ByteString
+getOpaqueTypeTag (Datatype t) = do
+    cstr <- withErrorWhen (nullPtr ==) $
+        h5t_get_tag t
+    BS.unsafePackMallocCString cstr
+
+-- * Querying property values
+
+getSuperType :: Datatype -> IO Datatype
+getSuperType (Datatype t) =
+    fmap Datatype $
+        withErrorCheck
+            $ h5t_get_super t
+
+getTypeClass :: Datatype -> IO Class
+getTypeClass (Datatype t) =
+    fmap classFromCode $
+        withErrorWhen (\(H5T_class_t c) -> c < 0) $
+            h5t_get_class t
+
+detectTypeClass :: Datatype -> Class -> IO Bool
+detectTypeClass (Datatype t) cls =
+    htriToBool $
+        h5t_detect_class t (classCode cls)
+
+getTypeSize :: Datatype -> IO CSize
+getTypeSize (Datatype t) =
+    withErrorWhen (<= 0) $
+        h5t_get_size t
+
+getByteOrder :: Datatype -> IO (Maybe ByteOrder)
+getByteOrder (Datatype t) =
+    fmap byteOrder $
+        withErrorCheck $
+            h5t_get_order t
+
+getTypePrecision :: Datatype -> IO CSize
+getTypePrecision (Datatype t) =
+    withErrorWhen (<= 0) $
+        h5t_get_precision t
+
+getTypeOffset :: Datatype -> IO CInt
+getTypeOffset (Datatype t) =
+    withErrorWhen (< 0) $
+        h5t_get_offset t
+
+getTypePad :: Datatype -> IO (Pad, Pad)
+getTypePad (Datatype t) = do
+    (msb, lsb) <-
+        withOut $ \msb ->
+            withOut_ $ \lsb ->
+                withErrorCheck $
+                    h5t_get_pad t msb lsb
+    return (padFromCode msb, padFromCode lsb)
+
+getFloatTypeFields :: Datatype -> IO (CSize, CSize, CSize, CSize, CSize)
+getFloatTypeFields (Datatype t) = do
+    (spos, (epos, (esize, (mpos, msize)))) <-
+        withOut $ \spos ->
+            withOut $ \epos ->
+                withOut $ \esize ->
+                    withOut $ \mpos ->
+                        withOut_ $ \msize ->
+                            withErrorCheck_ $
+                                h5t_get_fields t spos epos esize mpos msize
+    return (spos, epos, esize, mpos, msize)
+
+getFloatTypeEBias :: Datatype -> IO CSize
+getFloatTypeEBias (Datatype t) =
+    withErrorWhen (== 0) (h5t_get_ebias t)
+
+getFloatTypeNormalization :: Datatype -> IO (Maybe Normalization)
+getFloatTypeNormalization (Datatype t) =
+    fmap normalization $
+        withErrorCheck $
+            h5t_get_norm t
+
+getFloatTypeInternalPad :: Datatype -> IO Pad
+getFloatTypeInternalPad (Datatype t) =
+    fmap padFromCode $
+        withErrorCheck $
+            h5t_get_inpad t
+
+getStringPad :: Datatype -> IO StringPad
+getStringPad (Datatype t) =
+    fmap stringPadFromCode $
+        withErrorCheck $
+            h5t_get_strpad t
+
+-- type must be enum or compound
+getTypeNMembers :: Datatype -> IO CInt
+getTypeNMembers (Datatype t) =
+    withErrorWhen (< 0) $
+        h5t_get_nmembers t
+
+-- type must be enum or compound
+getMemberName :: Datatype -> CUInt -> IO BS.ByteString
+getMemberName (Datatype t) i = do
+    cstr <- withErrorWhen (== nullPtr) $
+        h5t_get_member_name t i
+    bs <- BS.packCString cstr
+    free cstr
+    return bs
+
+getMemberIndex :: Datatype -> BS.ByteString -> IO CInt
+getMemberIndex (Datatype t) bs =
+    withErrorWhen (< 0) $
+        BS.useAsCString bs $ \name ->
+            h5t_get_member_index t name
+
+-- TODO: implement these
+--  (figure out proper error check for this one, the docs are weird)
+-- getMemberOffset :: Datatype -> CUInt -> IO CSize
+-- getMemberOffset (Datatype t) i =
+--     withErrorWhen (< 0)
+
+-- getMemberClass
+-- getMemberType
+-- getMemberValue
+-- getCharSet
+-- isVariableString
+-- getNativeType
+
+-- * Setting property values
+
+setTypeSize :: Datatype -> CSize -> IO ()
+setTypeSize (Datatype t) sz =
+    withErrorCheck_ $
+        h5t_set_size t sz
+
+setByteOrder :: Datatype -> Maybe ByteOrder -> IO ()
+setByteOrder (Datatype t) order =
+    withErrorCheck_ $
+        h5t_set_order t (byteOrderCode order)
+
+setTypePrecision :: Datatype -> CSize -> IO ()
+setTypePrecision (Datatype t) prec =
+    withErrorCheck_ $
+        h5t_set_precision t prec
+
+setTypeOffset :: Datatype -> CSize -> IO ()
+setTypeOffset (Datatype t) offset =
+    withErrorCheck_ $
+        h5t_set_offset t offset
+
+setTypePad :: Datatype -> Pad -> Pad -> IO ()
+setTypePad (Datatype t) msb lsb =
+    withErrorCheck_ $
+        h5t_set_pad t (padCode msb) (padCode lsb)
+
+setFloatTypeFields :: Datatype -> CSize -> CSize -> CSize -> CSize -> CSize -> IO ()
+setFloatTypeFields (Datatype t) spos epos esize mpos msize =
+    withErrorCheck_ $
+        h5t_set_fields t spos epos esize mpos msize
+
+setFloatTypeEBias :: Datatype -> CSize -> IO ()
+setFloatTypeEBias (Datatype t) ebias =
+    withErrorCheck_ $
+        h5t_set_ebias t ebias
+
+-- TODO: implement these
+-- setFloatTypeNormalization ::
+-- setFloatTypeInternalPad ::
+-- setStringPad
+
+-- * Type conversion database
+
+-- registerTypeConversion
+-- unregisterTypeConversion
+-- findTypeConversion
+-- isCompilerConversion
+-- convertData
diff --git a/src/Bindings/HDF5/Datatype/Internal.hs b/src/Bindings/HDF5/Datatype/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Datatype/Internal.hs
@@ -0,0 +1,365 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE TemplateHaskell #-}
+module Bindings.HDF5.Datatype.Internal where
+
+import Data.Int
+import Data.Word
+import Foreign.C.Types
+
+import Bindings.HDF5.Core
+import Bindings.HDF5.Object
+import Bindings.HDF5.Raw
+import Data.Tagged
+import Foreign.Storable
+
+newtype Datatype = Datatype HId_t
+    deriving (Eq, HId, FromHId, HDFResultType)
+
+instance Object Datatype where
+    staticObjectType = Tagged (Just DatatypeObj)
+
+class Storable t => NativeType t where
+    nativeTypeId :: Tagged t Datatype
+
+-- nativeLdouble        = Datatype h5t_NATIVE_LDOUBLE
+-- nativeB8             = Datatype h5t_NATIVE_B8
+-- nativeB16            = Datatype h5t_NATIVE_B16
+-- nativeB32            = Datatype h5t_NATIVE_B32
+-- nativeB64            = Datatype h5t_NATIVE_B64
+-- nativeOpaque         = Datatype h5t_NATIVE_OPAQUE
+-- nativeIntLeast8      = Datatype h5t_NATIVE_INT_LEAST8
+-- nativeUintLeast8     = Datatype h5t_NATIVE_UINT_LEAST8
+-- nativeIntFast8       = Datatype h5t_NATIVE_INT_FAST8
+-- nativeUintFast8      = Datatype h5t_NATIVE_UINT_FAST8
+-- nativeIntLeast16     = Datatype h5t_NATIVE_INT_LEAST16
+-- nativeUintLeast16    = Datatype h5t_NATIVE_UINT_LEAST16
+-- nativeIntFast16      = Datatype h5t_NATIVE_INT_FAST16
+-- nativeUintFast16     = Datatype h5t_NATIVE_UINT_FAST16
+-- nativeIntLeast32     = Datatype h5t_NATIVE_INT_LEAST32
+-- nativeUintLeast32    = Datatype h5t_NATIVE_UINT_LEAST32
+-- nativeIntFast32      = Datatype h5t_NATIVE_INT_FAST32
+-- nativeUintFast32     = Datatype h5t_NATIVE_UINT_FAST32
+-- nativeIntLeast64     = Datatype h5t_NATIVE_INT_LEAST64
+-- nativeUintLeast64    = Datatype h5t_NATIVE_UINT_LEAST64
+-- nativeIntFast64      = Datatype h5t_NATIVE_INT_FAST64
+-- nativeUintFast64     = Datatype h5t_NATIVE_UINT_FAST64
+
+instance NativeType CChar where
+    nativeTypeId = Tagged (Datatype h5t_NATIVE_CHAR)
+
+instance NativeType CSChar where
+    nativeTypeId = Tagged (Datatype h5t_NATIVE_SCHAR)
+
+instance NativeType CUChar where
+    nativeTypeId = Tagged (Datatype h5t_NATIVE_UCHAR)
+
+instance NativeType CShort where
+    nativeTypeId = Tagged (Datatype h5t_NATIVE_SHORT)
+
+instance NativeType CUShort where
+    nativeTypeId = Tagged (Datatype h5t_NATIVE_USHORT)
+
+instance NativeType CInt where
+    nativeTypeId = Tagged (Datatype h5t_NATIVE_INT)
+
+instance NativeType CUInt where
+    nativeTypeId = Tagged (Datatype h5t_NATIVE_UINT)
+
+instance NativeType CLong where
+    nativeTypeId = Tagged (Datatype h5t_NATIVE_LONG)
+
+instance NativeType CULong where
+    nativeTypeId = Tagged (Datatype h5t_NATIVE_ULONG)
+
+instance NativeType CLLong where
+    nativeTypeId = Tagged (Datatype h5t_NATIVE_LLONG)
+
+instance NativeType CULLong where
+    nativeTypeId = Tagged (Datatype h5t_NATIVE_ULLONG)
+
+instance NativeType CFloat where
+    nativeTypeId = Tagged (Datatype h5t_NATIVE_FLOAT)
+
+instance NativeType CDouble where
+    nativeTypeId = Tagged (Datatype h5t_NATIVE_DOUBLE)
+
+instance NativeType HAddr where
+    nativeTypeId = Tagged (Datatype h5t_NATIVE_HADDR)
+
+instance NativeType HSize where
+    nativeTypeId = Tagged (Datatype h5t_NATIVE_HSIZE)
+
+instance NativeType HSSize where
+    nativeTypeId = Tagged (Datatype h5t_NATIVE_HSSIZE)
+
+instance NativeType HErr_t where
+    nativeTypeId = Tagged (Datatype h5t_NATIVE_HERR)
+
+instance NativeType HBool_t where
+    nativeTypeId = Tagged (Datatype h5t_NATIVE_HBOOL)
+
+instance NativeType Int8 where
+    nativeTypeId = Tagged (Datatype h5t_NATIVE_INT8)
+
+instance NativeType Int16 where
+    nativeTypeId = Tagged (Datatype h5t_NATIVE_INT16)
+
+instance NativeType Int32 where
+    nativeTypeId = Tagged (Datatype h5t_NATIVE_INT32)
+
+instance NativeType Int64 where
+    nativeTypeId = Tagged (Datatype h5t_NATIVE_INT64)
+
+instance NativeType Word8 where
+    nativeTypeId = Tagged (Datatype h5t_NATIVE_UINT8)
+
+instance NativeType Word16 where
+    nativeTypeId = Tagged (Datatype h5t_NATIVE_UINT16)
+
+instance NativeType Word32 where
+    nativeTypeId = Tagged (Datatype h5t_NATIVE_UINT32)
+
+instance NativeType Word64 where
+    nativeTypeId = Tagged (Datatype h5t_NATIVE_UINT64)
+
+if  isIEEE (0 :: Float)
+    && floatRadix  (0 :: Float) == 2
+    && floatDigits (0 :: Float) == 24
+    && floatRange  (0 :: Float) == (-125,128)
+    then [d| instance NativeType Float where nativeTypeId = Tagged (Datatype h5t_NATIVE_FLOAT) |]
+    else [d| |]
+
+if  isIEEE (0 :: Double)
+    && floatRadix  (0 :: Double) == 2
+    && floatDigits (0 :: Double) == 53
+    && floatRange  (0 :: Double) == (-1021,1024)
+    then [d| instance NativeType Double where nativeTypeId = Tagged (Datatype h5t_NATIVE_DOUBLE) |]
+    else [d| |]
+
+case sizeOf (0 :: Int) of
+    1   -> [d| instance NativeType Int where nativeTypeId = Tagged (Datatype h5t_NATIVE_INT8) |]
+    2   -> [d| instance NativeType Int where nativeTypeId = Tagged (Datatype h5t_NATIVE_INT16) |]
+    4   -> [d| instance NativeType Int where nativeTypeId = Tagged (Datatype h5t_NATIVE_INT32) |]
+    8   -> [d| instance NativeType Int where nativeTypeId = Tagged (Datatype h5t_NATIVE_INT64) |]
+    _   -> [d| |]
+
+case sizeOf (0 :: Word) of
+    1   -> [d| instance NativeType Word where nativeTypeId = Tagged (Datatype h5t_NATIVE_UINT8) |]
+    2   -> [d| instance NativeType Word where nativeTypeId = Tagged (Datatype h5t_NATIVE_UINT16) |]
+    4   -> [d| instance NativeType Word where nativeTypeId = Tagged (Datatype h5t_NATIVE_UINT32) |]
+    8   -> [d| instance NativeType Word where nativeTypeId = Tagged (Datatype h5t_NATIVE_UINT64) |]
+    _   -> [d| |]
+
+nativeTypeOf :: NativeType t => t -> Datatype
+nativeTypeOf it = untagAs it nativeTypeId
+    where
+        untagAs :: t -> Tagged t a -> a
+        untagAs _ = untag
+
+nativeTypeOf1 :: NativeType t => f t -> Datatype
+nativeTypeOf1 it = untagAs1 it nativeTypeId
+    where
+        untagAs1 :: f t -> Tagged t a -> a
+        untagAs1 _ = untag
+
+hdfTypeOf :: NativeType t => t -> HId_t
+hdfTypeOf = hid . nativeTypeOf
+
+hdfTypeOf1 :: NativeType t => f t -> HId_t
+hdfTypeOf1 = hid . nativeTypeOf1
+
+
+data Class
+    = Integer
+    | Float
+    | Time
+    | String
+    | BitField
+    | Opaque
+    | Compound
+    | Reference
+    | Enum
+    | VLen
+    | Array
+    deriving (Eq, Ord, Enum, Bounded, Read, Show)
+
+classCode :: Class -> H5T_class_t
+classCode Integer   = h5t_INTEGER
+classCode Float     = h5t_FLOAT
+classCode Time      = h5t_TIME
+classCode String    = h5t_STRING
+classCode BitField  = h5t_BITFIELD
+classCode Opaque    = h5t_OPAQUE
+classCode Compound  = h5t_COMPOUND
+classCode Reference = h5t_REFERENCE
+classCode Enum      = h5t_ENUM
+classCode VLen      = h5t_VLEN
+classCode Array     = h5t_ARRAY
+
+classFromCode :: H5T_class_t -> Class
+classFromCode c
+    | c == h5t_INTEGER      = Integer
+    | c == h5t_FLOAT        = Float
+    | c == h5t_TIME         = Time
+    | c == h5t_STRING       = String
+    | c == h5t_BITFIELD     = BitField
+    | c == h5t_OPAQUE       = Opaque
+    | c == h5t_COMPOUND     = Compound
+    | c == h5t_REFERENCE    = Reference
+    | c == h5t_ENUM         = Enum
+    | c == h5t_VLEN         = VLen
+    | c == h5t_ARRAY        = Array
+    | otherwise = error ("Unknown H5T_class_t " ++ show c)
+
+data CSet
+    = ASCII
+    | Reserved2
+    | Reserved3
+    | Reserved4
+    | Reserved5
+    | Reserved6
+    | Reserved7
+    | Reserved8
+    | Reserved9
+    | Reserved10
+    | Reserved11
+    | Reserved12
+    | Reserved13
+    | Reserved14
+    | Reserved15
+    | UTF8
+    deriving (Eq, Ord, Read, Show, Enum, Bounded)
+
+cSetCode :: CSet -> H5T_cset_t
+cSetCode ASCII          = h5t_CSET_ASCII
+cSetCode Reserved2      = h5t_CSET_RESERVED_2
+cSetCode Reserved3      = h5t_CSET_RESERVED_3
+cSetCode Reserved4      = h5t_CSET_RESERVED_4
+cSetCode Reserved5      = h5t_CSET_RESERVED_5
+cSetCode Reserved6      = h5t_CSET_RESERVED_6
+cSetCode Reserved7      = h5t_CSET_RESERVED_7
+cSetCode Reserved8      = h5t_CSET_RESERVED_8
+cSetCode Reserved9      = h5t_CSET_RESERVED_9
+cSetCode Reserved10     = h5t_CSET_RESERVED_10
+cSetCode Reserved11     = h5t_CSET_RESERVED_11
+cSetCode Reserved12     = h5t_CSET_RESERVED_12
+cSetCode Reserved13     = h5t_CSET_RESERVED_13
+cSetCode Reserved14     = h5t_CSET_RESERVED_14
+cSetCode Reserved15     = h5t_CSET_RESERVED_15
+cSetCode UTF8           = h5t_CSET_UTF8
+
+cSetFromCode :: H5T_cset_t -> CSet
+cSetFromCode c = case lookup c cSets of
+    Just cset -> cset
+    Nothing   -> error ("Unknown charset code: " ++ show c)
+    where cSets = [ (cSetCode x, x) | x <- [minBound .. maxBound]]
+
+data ByteOrder
+    = LE
+    | BE
+    | VAX
+    | Mixed
+    deriving (Eq, Ord, Bounded, Enum, Read, Show)
+
+byteOrderCode :: Maybe ByteOrder -> H5T_order_t
+byteOrderCode (Just LE)     = h5t_ORDER_LE
+byteOrderCode (Just BE)     = h5t_ORDER_BE
+byteOrderCode (Just VAX)    = h5t_ORDER_VAX
+byteOrderCode (Just Mixed)  = h5t_ORDER_MIXED
+byteOrderCode Nothing       = h5t_ORDER_NONE
+
+byteOrder :: H5T_order_t -> Maybe ByteOrder
+byteOrder c
+    | c == h5t_ORDER_LE     = Just LE
+    | c == h5t_ORDER_BE     = Just BE
+    | c == h5t_ORDER_VAX    = Just VAX
+    | c == h5t_ORDER_MIXED  = Just Mixed
+    | c == h5t_ORDER_NONE   = Nothing
+    | otherwise             = Nothing
+
+data Pad
+    = Zero
+    | One
+    | Background
+    deriving (Eq, Ord, Enum, Bounded, Read, Show)
+
+padCode     :: Pad -> H5T_pad_t
+padCode Zero        = h5t_PAD_ZERO
+padCode One         = h5t_PAD_ONE
+padCode Background  = h5t_PAD_BACKGROUND
+
+padFromCode :: H5T_pad_t -> Pad
+padFromCode c
+    | c == h5t_PAD_ZERO         = Zero
+    | c == h5t_PAD_ONE          = One
+    | c == h5t_PAD_BACKGROUND   = Background
+    | otherwise = error ("Unknown Pad code " ++ show c)
+
+data Normalization
+    = Implied
+    | MSBSet
+    deriving (Eq, Ord, Enum, Bounded, Read, Show)
+
+normalization :: H5T_norm_t -> Maybe Normalization
+normalization c
+    | c == h5t_NORM_IMPLIED = Just Implied
+    | c == h5t_NORM_MSBSET  = Just MSBSet
+    | c == h5t_NORM_NONE    = Nothing
+    | otherwise = error "Unknown H5T_norm_t value"
+
+data StringPad
+    = NullTerm
+    | NullPad
+    | SpacePad
+    | StringPad_Reserved3
+    | StringPad_Reserved4
+    | StringPad_Reserved5
+    | StringPad_Reserved6
+    | StringPad_Reserved7
+    | StringPad_Reserved8
+    | StringPad_Reserved9
+    | StringPad_Reserved10
+    | StringPad_Reserved11
+    | StringPad_Reserved12
+    | StringPad_Reserved13
+    | StringPad_Reserved14
+    | StringPad_Reserved15
+    deriving (Eq, Ord, Enum, Bounded, Read, Show)
+
+stringPadCode :: StringPad -> H5T_str_t
+stringPadCode NullTerm              = h5t_STR_NULLTERM
+stringPadCode NullPad               = h5t_STR_NULLPAD
+stringPadCode SpacePad              = h5t_STR_SPACEPAD
+stringPadCode StringPad_Reserved3   = h5t_STR_RESERVED_3
+stringPadCode StringPad_Reserved4   = h5t_STR_RESERVED_4
+stringPadCode StringPad_Reserved5   = h5t_STR_RESERVED_5
+stringPadCode StringPad_Reserved6   = h5t_STR_RESERVED_6
+stringPadCode StringPad_Reserved7   = h5t_STR_RESERVED_7
+stringPadCode StringPad_Reserved8   = h5t_STR_RESERVED_8
+stringPadCode StringPad_Reserved9   = h5t_STR_RESERVED_9
+stringPadCode StringPad_Reserved10  = h5t_STR_RESERVED_10
+stringPadCode StringPad_Reserved11  = h5t_STR_RESERVED_11
+stringPadCode StringPad_Reserved12  = h5t_STR_RESERVED_12
+stringPadCode StringPad_Reserved13  = h5t_STR_RESERVED_13
+stringPadCode StringPad_Reserved14  = h5t_STR_RESERVED_14
+stringPadCode StringPad_Reserved15  = h5t_STR_RESERVED_15
+
+stringPadFromCode :: H5T_str_t -> StringPad
+stringPadFromCode c
+    | c == h5t_STR_NULLTERM     = NullTerm
+    | c == h5t_STR_NULLPAD      = NullPad
+    | c == h5t_STR_SPACEPAD     = SpacePad
+    | c == h5t_STR_RESERVED_3   = StringPad_Reserved3
+    | c == h5t_STR_RESERVED_4   = StringPad_Reserved4
+    | c == h5t_STR_RESERVED_5   = StringPad_Reserved5
+    | c == h5t_STR_RESERVED_6   = StringPad_Reserved6
+    | c == h5t_STR_RESERVED_7   = StringPad_Reserved7
+    | c == h5t_STR_RESERVED_8   = StringPad_Reserved8
+    | c == h5t_STR_RESERVED_9   = StringPad_Reserved9
+    | c == h5t_STR_RESERVED_10  = StringPad_Reserved10
+    | c == h5t_STR_RESERVED_11  = StringPad_Reserved11
+    | c == h5t_STR_RESERVED_12  = StringPad_Reserved12
+    | c == h5t_STR_RESERVED_13  = StringPad_Reserved13
+    | c == h5t_STR_RESERVED_14  = StringPad_Reserved14
+    | c == h5t_STR_RESERVED_15  = StringPad_Reserved15
+    | otherwise = error ("Unknown StringPad code " ++ show c)
diff --git a/src/Bindings/HDF5/Error.hs b/src/Bindings/HDF5/Error.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Error.hs
@@ -0,0 +1,188 @@
+{-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module Bindings.HDF5.Error
+    ( ErrorClassID, hdfError
+    , HDF5Exception, errorStack, HDF5Error(..)
+    , HDFResultType(..)
+    , withErrorWhen, withErrorWhen_
+    , withErrorCheck, withErrorCheck_
+    , htriToBool
+    , registerErrorClass, unregisterErrorClass
+    , createMajorErrCode, releaseMajorErrCode
+    , createMinorErrCode, releaseMinorErrCode
+    , ErrorStack
+    , createErrorStack, closeErrorStack
+    , getCurrentErrorStack, setCurrentErrorStack,
+    ) where
+
+import Control.Monad
+import Control.Exception (throwIO, finally, Exception)
+import qualified Data.ByteString as BS
+import Data.IORef
+import Data.Typeable (Typeable)
+import Foreign.C
+import Foreign.Ptr
+import Foreign.Storable
+
+import Bindings.HDF5.Core
+import Bindings.HDF5.ErrorCodes
+import Bindings.HDF5.Raw.H5
+import Bindings.HDF5.Raw.H5E
+import Bindings.HDF5.Raw.H5I
+import Foreign.Ptr.Conventions
+
+newtype ErrorClassID = ErrorClassID HId_t
+    deriving (Eq, Ord, Typeable, HId, FromHId, HDFResultType)
+
+instance Show ErrorClassID where
+    showsPrec p cls@(ErrorClassID (HId_t h))
+        | cls == hdfError
+            = showString "hdfError"
+        | otherwise = showsPrec p h
+
+hdfError :: ErrorClassID
+hdfError = ErrorClassID h5e_ERR_CLS
+
+data HDF5Error = HDF5Error
+    { classId       :: !ErrorClassID
+    , majorNum      :: !(Maybe MajorErrCode)
+    , minorNum      :: !(Maybe MinorErrCode)
+    , line          :: !Integer
+    , funcName      :: !BS.ByteString
+    , fileName      :: !BS.ByteString
+    , description   :: !BS.ByteString
+    } deriving (Eq, Ord, Show, Typeable)
+
+readHDF5Error :: H5E_error2_t -> IO HDF5Error
+readHDF5Error err = do
+    func <- BS.packCString (h5e_error2_t'func_name err)
+    file <- BS.packCString (h5e_error2_t'file_name err)
+    desc <- BS.packCString (h5e_error2_t'desc err)
+
+    return HDF5Error
+        { classId       = ErrorClassID (h5e_error2_t'cls_id err)
+        , majorNum      = majorErrorFromCode (h5e_error2_t'maj_num err)
+        , minorNum      = minorErrorFromCode (h5e_error2_t'min_num err)
+        , line          = toInteger (h5e_error2_t'line err)
+        , funcName      = func
+        , fileName      = file
+        , description   = desc
+        }
+
+newtype HDF5Exception = HDF5Exception [HDF5Error]
+    deriving (Eq, Ord, Show, Typeable)
+instance Exception HDF5Exception
+
+errorStack :: HDF5Exception -> [HDF5Error]
+errorStack (HDF5Exception es) = es
+
+withErrorWhen :: (t -> Bool) -> IO t -> IO t
+withErrorWhen isError_ action = do
+    -- h5e_try does not alter the stack, just suspends the 'automatic' exception handler
+    result <- h5e_try action
+
+    if isError_ result
+        then do
+            stackId <- h5e_get_current_stack
+            errors  <- newIORef []
+
+            walk <- wrapStackWalk $ \_ (In err) _ -> do
+                err_desc <- readHDF5Error =<< peek err
+                modifyIORef errors (err_desc :)
+                return (HErr_t 0)
+
+            _ <- h5e_walk2 stackId h5e_WALK_DOWNWARD walk (InOut nullPtr)
+                `finally` do
+                    freeHaskellFunPtr walk
+                    h5e_close_stack stackId
+
+            errs <- readIORef errors
+            throwIO (HDF5Exception errs)
+        else return result
+
+withErrorWhen_ :: (t -> Bool) -> IO t -> IO ()
+withErrorWhen_ isErr action =
+    void $ withErrorWhen isErr action
+
+withErrorCheck :: HDFResultType t => IO t -> IO t
+withErrorCheck = withErrorWhen isError
+
+withErrorCheck_ :: HDFResultType t => IO t -> IO ()
+withErrorCheck_ = withErrorWhen_ isError
+
+htriToBool :: IO HTri_t -> IO Bool
+htriToBool = fmap toBool . withErrorCheck
+    where toBool (HTri_t x) = x > 0
+
+registerErrorClass :: BS.ByteString -> BS.ByteString -> BS.ByteString -> IO ErrorClassID
+registerErrorClass name libName version =
+    fmap ErrorClassID $
+        withErrorCheck $
+            BS.useAsCString name $ \cname ->
+                BS.useAsCString libName $ \clibName ->
+                    BS.useAsCString version $ \cversion ->
+                        h5e_register_class cname clibName cversion
+
+unregisterErrorClass :: ErrorClassID -> IO ()
+unregisterErrorClass (ErrorClassID h) =
+    withErrorCheck_ (h5e_unregister_class h)
+
+createMajorErrCode :: ErrorClassID -> BS.ByteString -> IO MajorErrCode
+createMajorErrCode (ErrorClassID cls) msg =
+    fmap UnknownMajor $
+        withErrorCheck $
+            BS.useAsCString msg $ \cmsg ->
+                h5e_create_msg cls h5e_MAJOR cmsg
+
+releaseMajorErrCode :: MajorErrCode -> IO ()
+releaseMajorErrCode (UnknownMajor code) =
+    withErrorCheck_ (h5e_close_msg code)
+
+releaseMajorErrCode otherErr = fail $ concat
+    [ "releaseMajorErrCode: "
+    , show otherErr
+    , " is a built-in error type, it's a bad idea to release it."
+    ]
+
+createMinorErrCode :: ErrorClassID -> BS.ByteString -> IO MinorErrCode
+createMinorErrCode (ErrorClassID cls) msg =
+    fmap UnknownMinor $
+        withErrorCheck $
+            BS.useAsCString msg $ \cmsg ->
+                h5e_create_msg cls h5e_MINOR cmsg
+
+releaseMinorErrCode :: MinorErrCode -> IO ()
+releaseMinorErrCode (UnknownMinor code) =
+    withErrorCheck_ (h5e_close_msg code)
+
+releaseMinorErrCode otherErr = fail $ concat
+    [ "releaseMinorErrCode: "
+    , show otherErr
+    , " is a built-in error type, it's a bad idea to release it."
+    ]
+
+newtype ErrorStack = ErrorStack HId_t
+    deriving (Eq, Ord, Show, HId, FromHId, HDFResultType)
+
+createErrorStack :: IO ErrorStack
+createErrorStack =
+    fmap ErrorStack
+        (withErrorCheck h5e_create_stack)
+
+getCurrentErrorStack :: IO ErrorStack
+getCurrentErrorStack =
+    fmap ErrorStack
+        (withErrorCheck h5e_get_current_stack)
+
+setCurrentErrorStack :: ErrorStack -> IO ()
+setCurrentErrorStack (ErrorStack h) =
+    withErrorCheck_ (h5e_set_current_stack h)
+
+closeErrorStack :: ErrorStack -> IO ()
+closeErrorStack (ErrorStack h) =
+    withErrorCheck_ (h5e_close_stack h)
+
+foreign import ccall "wrapper" wrapStackWalk
+    :: (CUInt -> In H5E_error2_t -> InOut a -> IO HErr_t)
+    -> IO (FunPtr (CUInt -> In H5E_error2_t -> InOut a -> IO HErr_t))
diff --git a/src/Bindings/HDF5/ErrorCodes.hs b/src/Bindings/HDF5/ErrorCodes.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/ErrorCodes.hs
@@ -0,0 +1,500 @@
+{-# LANGUAGE DeriveDataTypeable, FlexibleInstances #-}
+module Bindings.HDF5.ErrorCodes
+    ( MajorErrCode(..), majorErrorCode, majorErrorFromCode
+    , MinorErrCode(..), minorErrorCode, minorErrorFromCode
+
+    ) where
+import Data.Maybe
+
+import Bindings.HDF5.Raw.H5E
+import Bindings.HDF5.Raw.H5I
+import Data.Typeable (Typeable)
+import Foreign
+
+data MajorErrCode
+    -- |Dataset
+    = Dataset
+    -- |Function entry/exit
+    | Func
+    -- |Data storage
+    | Storage
+    -- |File accessability
+    | File
+    -- |Shared Object Header Messages
+    | SOHM
+    -- |Symbol table
+    | Sym
+    -- |Virtual File Layer
+    | VFL
+    -- |Internal error (too specific to document in detail)
+    | Internal
+    -- |B-Tree node
+    | BTree
+    -- |References
+    | Reference
+    -- |Dataspace
+    | Dataspace
+    -- |Resource unavailable
+    | Resource
+    -- |Property lists
+    | PList
+    -- |Links
+    | Link
+    -- |Datatype
+    | Datatype
+    -- |Reference Counted Strings
+    | RS
+    -- |Heap
+    | Heap
+    -- |Object header
+    | OHDR
+    -- |Object atom
+    | Atom
+    -- |Attribute
+    | Attr
+    -- |Low-level I/O
+    | IO
+    -- |Skip Lists
+    | SList
+    -- |External file list
+    | EFL
+    -- |Ternary Search Trees
+    | TST
+    -- |Invalid arguments to routine
+    | Args
+    -- |Error API
+    | Error
+    -- |Data filters
+    | PLine
+    -- |Free Space Manager
+    | FSpace
+    -- |Object cache
+    | Cache
+
+    -- |Unrecognized major error code
+    | UnknownMajor HId_t
+    deriving (Eq, Ord, Show, Typeable)
+
+rawMajorErrCodesInv :: [(HId_t, Maybe MajorErrCode)]
+rawMajorErrCodesInv = [(a,b) | (b,a) <- rawMajorErrCodes]
+
+rawMajorErrCodes :: [(Maybe MajorErrCode, HId_t)]
+rawMajorErrCodes =
+    [ (Nothing,         h5e_NONE_MAJOR)
+    , (Just Dataset,    h5e_DATASET)
+    , (Just Func,       h5e_FUNC)
+    , (Just Storage,    h5e_STORAGE)
+    , (Just File,       h5e_FILE)
+    , (Just SOHM,       h5e_SOHM)
+    , (Just Sym,        h5e_SYM)
+    , (Just VFL,        h5e_VFL)
+    , (Just Internal,   h5e_INTERNAL)
+    , (Just BTree,      h5e_BTREE)
+    , (Just Reference,  h5e_REFERENCE)
+    , (Just Dataspace,  h5e_DATASPACE)
+    , (Just Resource,   h5e_RESOURCE)
+    , (Just PList,      h5e_PLIST)
+    , (Just Link,       h5e_LINK)
+    , (Just Datatype,   h5e_DATATYPE)
+    , (Just RS,         h5e_RS)
+    , (Just Heap,       h5e_HEAP)
+    , (Just OHDR,       h5e_OHDR)
+    , (Just Atom,       h5e_ATOM)
+    , (Just Attr,       h5e_ATTR)
+    , (Just IO,         h5e_IO)
+    , (Just SList,      h5e_SLIST)
+    , (Just EFL,        h5e_EFL)
+    , (Just TST,        h5e_TST)
+    , (Just Args,       h5e_ARGS)
+    , (Just Error,      h5e_ERROR)
+    , (Just PLine,      h5e_PLINE)
+    , (Just FSpace,     h5e_FSPACE)
+    , (Just Cache,      h5e_CACHE)
+    ]
+
+majorErrorCode :: Maybe MajorErrCode -> Maybe HId_t
+majorErrorCode (Just (UnknownMajor code)) = Just code
+majorErrorCode err = lookup err rawMajorErrCodes
+
+majorErrorFromCode :: HId_t -> Maybe MajorErrCode
+majorErrorFromCode code =
+    fromMaybe (Just (UnknownMajor code))
+                  (lookup code rawMajorErrCodesInv)
+
+instance Storable (Maybe MajorErrCode) where
+    sizeOf    _ = sizeOf    (undefined :: HId_t)
+    alignment _ = alignment (undefined :: HId_t)
+
+    peek = fmap majorErrorFromCode . peek . castPtr
+    poke p err = case majorErrorCode err of
+        Nothing -> fail ("Unknown major error code: " ++ show err)
+        Just code -> poke (castPtr p) code
+
+data MinorErrCode
+    = SeekError
+    -- |Read failed
+    | ReadError
+    -- |Write failed
+    | WriteError
+    -- |Close failed
+    | CloseError
+    -- |Address overflowed
+    | Overflow
+    -- |File control (fcntl) failed
+    | FCNTL
+    -- |No space available for allocation
+    | NoSpace
+    -- |Can't allocate space
+    | CantAlloc
+    -- |Unable to copy object
+    | CantCopy
+    -- |Unable to free object
+    | CantFree
+    -- |Object already exists
+    | AlreadyExists
+    -- |Unable to lock object
+    | CantLock
+    -- |Unable to unlock object
+    | CantUnlock
+    -- |Unable to garbage collect
+    | CantGC
+    -- |Unable to compute size
+    | CantGetSize
+    -- |Object is already open
+    | ObjOpen
+    -- |Can't restore condition
+    | CantRestore
+    -- |Can't compute value
+    | CantCompute
+    -- |Can't extend heap's space
+    | CantExtend
+    -- |Can't attach object
+    | CantAttach
+    -- |Can't update object
+    | CantUpdate
+    -- |Can't operate on object
+    | CantOperate
+    -- |Unable to initialize object
+    | CantInit
+    -- |Object already initialized
+    | AlreadyInit
+    -- |Unable to release object
+    | CantRelease
+    -- |Can't get value
+    | CantGet
+    -- |Can't set value
+    | CantSet
+    -- |Duplicate class name in parent class
+    | DupClass
+    -- |Can't merge objects
+    | CantMerge
+    -- |Can't revive object
+    | CantRevive
+    -- |Can't shrink container
+    | CantShrink
+    -- |Bad object header link count
+    | LinkCount
+    -- |Wrong version number
+    | Version
+    -- |Alignment error
+    | Alignment
+    -- |Unrecognized message
+    | BadMesg
+    -- |Can't delete message
+    | CantDelete
+    -- |Iteration failed
+    | BadIter
+    -- |Can't pack messages
+    | CantPack
+    -- |Can't reset object
+    | CantReset
+    -- |Unable to rename object
+    | CantRename
+    -- |System error message
+    | SysErrStr
+    -- |Requested filter is not available
+    | NoFilter
+    -- |Callback failed
+    | Callback
+    -- |Error from filter 'can apply' callback
+    | CanApply
+    -- |Error from filter 'set local' callback
+    | SetLocal
+    -- |Filter present but encoding disabled
+    | NoEncoder
+    -- |Filter operation failed
+    | CantFilter
+    -- |Can't open object
+    | CantOpenObj
+    -- |Can't close object
+    | CantCloseObj
+    -- |Name component is too long
+    | CompLen
+    -- |Problem with path to object
+    | Path
+    -- |File already exists
+    | FileExists
+    -- |File already open
+    | FileOpen
+    -- |Unable to create file
+    | CantCreate
+    -- |Unable to open file
+    | CantOpenFile
+    -- |Unable to close file
+    | CantCloseFile
+    -- |Not an HDF5 file
+    | NotHDF5
+    -- |Bad file ID accessed
+    | BadFile
+    -- |File has been truncated
+    | Truncated
+    -- |File mount error
+    | Mount
+    -- |Unable to find atom information (already closed?)
+    | BadAtom
+    -- |Unable to find ID group information
+    | BadGroup
+    -- |Unable to register new atom
+    | CantRegister
+    -- |Unable to increment reference count
+    | CantInc
+    -- |Unable to decrement reference count
+    | CantDec
+    -- |Out of IDs for group
+    | NoIds
+    -- |Unable to flush data from cache
+    | CantFlush
+    -- |Unable to serialize data from cache
+    | CantSerialize
+    -- |Unable to load metadata into cache
+    | CantLoad
+    -- |Protected metadata error
+    | Protect
+    -- |Metadata not currently cached
+    | NotCached
+    -- |Internal error detected
+    | System
+    -- |Unable to insert metadata into cache
+    | CantIns
+    -- |Unable to protect metadata
+    | CantProtect
+    -- |Unable to unprotect metadata
+    | CanTUnprotect
+    -- |Unable to pin cache entry
+    | CantPin
+    -- |Unable to un-pin cache entry
+    | CantUnpin
+    -- |Unable to mark a pinned entry as dirty
+    | CantMarkDirty
+    -- |Unable to mark metadata as dirty
+    | CantDirty
+    -- |Unable to expunge a metadata cache entry
+    | CantExpunge
+    -- |Unable to resize a metadata cache entry
+    | CantResize
+    -- |Link traversal failure
+    | Traverse
+    -- |Too many soft links in path
+    | NLinks
+    -- |Link class not registered
+    | NotRegistered
+    -- |Can't move object
+    | CantMove
+    -- |Can't sort objects
+    | CantSort
+    -- |Some MPI function failed
+    | MPI
+    -- |MPI Error String
+    | MPIErrStr
+    -- |Can't receive data
+    | CantRecv
+    -- |Can't clip hyperslab region
+    | CantClip
+    -- |Can't count elements
+    | CantCount
+    -- |Can't select hyperslab
+    | CantSelect
+    -- |Can't move to next iterator location
+    | CantNext
+    -- |Invalid selection
+    | BadSelect
+    -- |Can't compare objects
+    | CantCompare
+    -- |Information is uinitialized
+    | Uninitialized
+    -- |Feature is unsupported
+    | Unsupported
+    -- |Inappropriate type
+    | BadType
+    -- |Out of range
+    | BadRange
+    -- |Bad value
+    | BadValue
+    -- |Object not found
+    | NotFound
+    -- |Object already exists
+    | Exists
+    -- |Unable to encode value
+    | CantEncode
+    -- |Unable to decode value
+    | CantDecode
+    -- |Unable to split node
+    | CantSplit
+    -- |Unable to redistribute records
+    | CantRedistribute
+    -- |Unable to swap records
+    | CantSwap
+    -- |Unable to insert object
+    | CantInsert
+    -- |Unable to list node
+    | CantList
+    -- |Unable to modify record
+    | CantModify
+    -- |Unable to remove object
+    | CantRemove
+    -- |Can't convert datatypes
+    | CantConvert
+    -- |Bad size for object
+    | BadSize
+
+    -- |Unrecognized minor error code
+    | UnknownMinor HId_t
+    deriving (Eq, Ord, Show, Typeable)
+
+rawMinorErrCodesInv :: [(HId_t, Maybe MinorErrCode)]
+rawMinorErrCodesInv = [(a,b) | (b,a) <- rawMinorErrCodes]
+rawMinorErrCodes :: [(Maybe MinorErrCode, HId_t)]
+rawMinorErrCodes =
+    [ (Nothing,                 h5e_NONE_MINOR)
+    , (Just SeekError,          h5e_SEEKERROR)
+    , (Just ReadError,          h5e_READERROR)
+    , (Just WriteError,         h5e_WRITEERROR)
+    , (Just CloseError,         h5e_CLOSEERROR)
+    , (Just Overflow,           h5e_OVERFLOW)
+    , (Just FCNTL,              h5e_FCNTL)
+    , (Just NoSpace,            h5e_NOSPACE)
+    , (Just CantAlloc,          h5e_CANTALLOC)
+    , (Just CantCopy,           h5e_CANTCOPY)
+    , (Just CantFree,           h5e_CANTFREE)
+    , (Just AlreadyExists,      h5e_ALREADYEXISTS)
+    , (Just CantLock,           h5e_CANTLOCK)
+    , (Just CantUnlock,         h5e_CANTUNLOCK)
+    , (Just CantGC,             h5e_CANTGC)
+    , (Just CantGetSize,        h5e_CANTGETSIZE)
+    , (Just ObjOpen,            h5e_OBJOPEN)
+    , (Just CantRestore,        h5e_CANTRESTORE)
+    , (Just CantCompute,        h5e_CANTCOMPUTE)
+    , (Just CantExtend,         h5e_CANTEXTEND)
+    , (Just CantAttach,         h5e_CANTATTACH)
+    , (Just CantUpdate,         h5e_CANTUPDATE)
+    , (Just CantOperate,        h5e_CANTOPERATE)
+    , (Just CantInit,           h5e_CANTINIT)
+    , (Just AlreadyInit,        h5e_ALREADYINIT)
+    , (Just CantRelease,        h5e_CANTRELEASE)
+    , (Just CantGet,            h5e_CANTGET)
+    , (Just CantSet,            h5e_CANTSET)
+    , (Just DupClass,           h5e_DUPCLASS)
+    , (Just CantMerge,          h5e_CANTMERGE)
+    , (Just CantRevive,         h5e_CANTREVIVE)
+    , (Just CantShrink,         h5e_CANTSHRINK)
+    , (Just LinkCount,          h5e_LINKCOUNT)
+    , (Just Version,            h5e_VERSION)
+    , (Just Alignment,          h5e_ALIGNMENT)
+    , (Just BadMesg,            h5e_BADMESG)
+    , (Just CantDelete,         h5e_CANTDELETE)
+    , (Just BadIter,            h5e_BADITER)
+    , (Just CantPack,           h5e_CANTPACK)
+    , (Just CantReset,          h5e_CANTRESET)
+    , (Just CantRename,         h5e_CANTRENAME)
+    , (Just SysErrStr,          h5e_SYSERRSTR)
+    , (Just NoFilter,           h5e_NOFILTER)
+    , (Just Callback,           h5e_CALLBACK)
+    , (Just CanApply,           h5e_CANAPPLY)
+    , (Just SetLocal,           h5e_SETLOCAL)
+    , (Just NoEncoder,          h5e_NOENCODER)
+    , (Just CantFilter,         h5e_CANTFILTER)
+    , (Just CantOpenObj,        h5e_CANTOPENOBJ)
+    , (Just CantCloseObj,       h5e_CANTCLOSEOBJ)
+    , (Just CompLen,            h5e_COMPLEN)
+    , (Just Path,               h5e_PATH)
+    , (Just FileExists,         h5e_FILEEXISTS)
+    , (Just FileOpen,           h5e_FILEOPEN)
+    , (Just CantCreate,         h5e_CANTCREATE)
+    , (Just CantOpenFile,       h5e_CANTOPENFILE)
+    , (Just CantCloseFile,      h5e_CANTCLOSEFILE)
+    , (Just NotHDF5,            h5e_NOTHDF5)
+    , (Just BadFile,            h5e_BADFILE)
+    , (Just Truncated,          h5e_TRUNCATED)
+    , (Just Mount,              h5e_MOUNT)
+    , (Just BadAtom,            h5e_BADATOM)
+    , (Just BadGroup,           h5e_BADGROUP)
+    , (Just CantRegister,       h5e_CANTREGISTER)
+    , (Just CantInc,            h5e_CANTINC)
+    , (Just CantDec,            h5e_CANTDEC)
+    , (Just NoIds,              h5e_NOIDS)
+    , (Just CantFlush,          h5e_CANTFLUSH)
+    , (Just CantSerialize,      h5e_CANTSERIALIZE)
+    , (Just CantLoad,           h5e_CANTLOAD)
+    , (Just Protect,            h5e_PROTECT)
+    , (Just NotCached,          h5e_NOTCACHED)
+    , (Just System,             h5e_SYSTEM)
+    , (Just CantIns,            h5e_CANTINS)
+    , (Just CantProtect,        h5e_CANTPROTECT)
+    , (Just CanTUnprotect,      h5e_CANTUNPROTECT)
+    , (Just CantPin,            h5e_CANTPIN)
+    , (Just CantUnpin,          h5e_CANTUNPIN)
+    , (Just CantMarkDirty,      h5e_CANTMARKDIRTY)
+    , (Just CantDirty,          h5e_CANTDIRTY)
+    , (Just CantExpunge,        h5e_CANTEXPUNGE)
+    , (Just CantResize,         h5e_CANTRESIZE)
+    , (Just Traverse,           h5e_TRAVERSE)
+    , (Just NLinks,             h5e_NLINKS)
+    , (Just NotRegistered,      h5e_NOTREGISTERED)
+    , (Just CantMove,           h5e_CANTMOVE)
+    , (Just CantSort,           h5e_CANTSORT)
+    , (Just MPI,                h5e_MPI)
+    , (Just MPIErrStr,          h5e_MPIERRSTR)
+    , (Just CantRecv,           h5e_CANTRECV)
+    , (Just CantClip,           h5e_CANTCLIP)
+    , (Just CantCount,          h5e_CANTCOUNT)
+    , (Just CantSelect,         h5e_CANTSELECT)
+    , (Just CantNext,           h5e_CANTNEXT)
+    , (Just BadSelect,          h5e_BADSELECT)
+    , (Just CantCompare,        h5e_CANTCOMPARE)
+    , (Just Uninitialized,      h5e_UNINITIALIZED)
+    , (Just Unsupported,        h5e_UNSUPPORTED)
+    , (Just BadType,            h5e_BADTYPE)
+    , (Just BadRange,           h5e_BADRANGE)
+    , (Just BadValue,           h5e_BADVALUE)
+    , (Just NotFound,           h5e_NOTFOUND)
+    , (Just Exists,             h5e_EXISTS)
+    , (Just CantEncode,         h5e_CANTENCODE)
+    , (Just CantDecode,         h5e_CANTDECODE)
+    , (Just CantSplit,          h5e_CANTSPLIT)
+    , (Just CantRedistribute,   h5e_CANTREDISTRIBUTE)
+    , (Just CantSwap,           h5e_CANTSWAP)
+    , (Just CantInsert,         h5e_CANTINSERT)
+    , (Just CantList,           h5e_CANTLIST)
+    , (Just CantModify,         h5e_CANTMODIFY)
+    , (Just CantRemove,         h5e_CANTREMOVE)
+    , (Just CantConvert,        h5e_CANTCONVERT)
+    , (Just BadSize,            h5e_BADSIZE)
+    ]
+
+minorErrorCode :: Maybe MinorErrCode -> Maybe HId_t
+minorErrorCode (Just (UnknownMinor code)) = Just code
+minorErrorCode err = lookup err rawMinorErrCodes
+
+minorErrorFromCode :: HId_t -> Maybe MinorErrCode
+minorErrorFromCode code =
+    fromMaybe (Just (UnknownMinor code))
+                  (lookup code rawMinorErrCodesInv)
+
+instance Storable (Maybe MinorErrCode) where
+    sizeOf    _ = sizeOf    (undefined :: HId_t)
+    alignment _ = alignment (undefined :: HId_t)
+
+    peek = fmap minorErrorFromCode . peek . castPtr
+    poke p err = case minorErrorCode err of
+        Nothing -> fail ("Unknown minor error code: " ++ show err)
+        Just code -> poke (castPtr p) code
diff --git a/src/Bindings/HDF5/File.hs b/src/Bindings/HDF5/File.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/File.hs
@@ -0,0 +1,284 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE FlexibleInstances #-}
+module Bindings.HDF5.File
+    ( AccFlags(..)
+    , ObjType(..)
+    , Scope(..)
+
+    , isHDF5
+
+    , File
+    , createFile
+    , openFile
+    , reopenFile
+    , flushFile
+    , closeFile
+
+    , mountFile
+    , unmountFile
+
+    , getFileSize
+    , getFileCreatePlist
+    , getFileAccessPlist
+
+    , FileInfo(..)
+    , getFileInfo
+    , getFileIntent
+    , getFileName
+    , getFileObjCount
+
+    , getOpenObjects
+    , getFileFreespace
+--    , get_mdc_config
+--    , get_mdc_hit_rate
+--    , get_mdc_size
+--    , clear_elink_file_cache
+--    , reset_mdc_hit_rate_stats
+--    , set_mdc_config
+    ) where
+
+import Bindings.HDF5.Core
+import Bindings.HDF5.Error
+import Bindings.HDF5.Object
+import Bindings.HDF5.PropertyList.FAPL
+import Bindings.HDF5.PropertyList.FCPL
+import Bindings.HDF5.PropertyList.FMPL
+import Bindings.HDF5.Raw.H5
+import Bindings.HDF5.Raw.H5F
+import Bindings.HDF5.Raw.H5I
+import Bindings.HDF5.Raw.H5P
+import Data.Bits
+import Data.Maybe
+import qualified Data.ByteString as BS
+import qualified Data.Vector.Storable as SV
+import Foreign.C
+import Foreign.Ptr
+import Foreign.Ptr.Conventions
+import Foreign.Storable
+
+-- TODO: determine whether all of these are valid for _both_ create and open.
+-- any that are not should be converted to Bool inputs to the corresponding function.
+-- It very well may be best to separate several of them out like that anyway.
+data AccFlags
+    = ReadOnly
+    | ReadWrite
+    | Truncate
+    | FailIfExists
+    | Debug
+    | Create
+    deriving (Eq, Ord, Enum, Bounded, Read, Show)
+
+accFlagToInt :: AccFlags -> CUInt
+accFlagToInt ReadOnly       = h5f_ACC_RDONLY
+accFlagToInt ReadWrite      = h5f_ACC_RDWR
+accFlagToInt Truncate       = h5f_ACC_TRUNC
+accFlagToInt FailIfExists   = h5f_ACC_EXCL
+accFlagToInt Debug          = h5f_ACC_DEBUG
+accFlagToInt Create         = h5f_ACC_CREAT
+
+accFlagsToInt :: [AccFlags] -> CUInt
+accFlagsToInt = foldl (.|.) 0 . map accFlagToInt
+
+intToAccFlags :: CUInt -> [AccFlags]
+intToAccFlags x =
+    [ f
+    | f <- [minBound .. maxBound]
+    , accFlagToInt f .&. x /= 0
+    ]
+
+instance Storable [AccFlags] where
+    sizeOf    _ = sizeOf (0 :: CUInt)
+    alignment _ = alignment (0 :: CUInt)
+    peek        = fmap intToAccFlags . peek . castPtr
+    poke p      = poke (castPtr p) . accFlagsToInt
+
+data ObjType
+    = Files
+    | Datasets
+    | Groups
+    | Datatypes
+    | Attrs
+    | All
+    deriving (Eq, Ord, Enum, Bounded, Read, Show)
+
+objTypeToInt :: ObjType -> CUInt
+objTypeToInt Files      = h5f_OBJ_FILE
+objTypeToInt Datasets   = h5f_OBJ_DATASET
+objTypeToInt Groups     = h5f_OBJ_GROUP
+objTypeToInt Datatypes  = h5f_OBJ_DATATYPE
+objTypeToInt Attrs      = h5f_OBJ_ATTR
+objTypeToInt All        = h5f_OBJ_ALL
+
+objTypesToInt :: [ObjType] -> CUInt
+objTypesToInt = foldl (.|.) 0 . map objTypeToInt
+
+intToObjTypes :: CUInt -> [ObjType]
+intToObjTypes x =
+    [ f
+    | f <- [minBound .. maxBound]
+    , objTypeToInt f .&. x /= 0
+    ]
+
+instance Storable [ObjType] where
+    sizeOf    _ = sizeOf (0 :: CUInt)
+    alignment _ = alignment (0 :: CUInt)
+    peek        = fmap intToObjTypes . peek . castPtr
+    poke p      = poke (castPtr p) . objTypesToInt
+
+data Scope
+    = Local
+    | Global
+    deriving (Eq, Ord, Enum, Bounded, Read, Show)
+
+scopeCode :: Scope -> H5F_scope_t
+scopeCode Local  = h5f_SCOPE_LOCAL
+scopeCode Global = h5f_SCOPE_GLOBAL
+
+data CloseDegree
+    = Weak
+    | Semi
+    | Strong
+    deriving (Eq, Ord, Enum, Bounded, Read, Show)
+
+rawCloseDegreesInv :: [(H5F_close_degree_t, Maybe CloseDegree)]
+rawCloseDegreesInv = [(a,b) | (b,a) <- rawCloseDegrees]
+rawCloseDegrees :: [(Maybe CloseDegree, H5F_close_degree_t)]
+rawCloseDegrees =
+    [ (Nothing,     h5f_CLOSE_DEFAULT)
+    , (Just Weak,   h5f_CLOSE_WEAK)
+    , (Just Semi,   h5f_CLOSE_SEMI)
+    , (Just Strong, h5f_CLOSE_STRONG)
+    ]
+
+closeDegreeFromCode :: H5F_close_degree_t -> Maybe CloseDegree
+closeDegreeFromCode c = fromMaybe Nothing (lookup c rawCloseDegreesInv)
+
+closeDegreeToCode :: Maybe CloseDegree -> H5F_close_degree_t
+closeDegreeToCode c =
+    fromMaybe (error ("closeDegreeToCode: unrecognized H5F_close_degree_t: " ++ show c))
+                  (lookup c rawCloseDegrees)
+
+instance Storable (Maybe CloseDegree) where
+    sizeOf _    = sizeOf    (undefined :: H5F_close_degree_t)
+    alignment _ = alignment (undefined :: H5F_close_degree_t)
+    peek        = fmap closeDegreeFromCode . peek . castPtr
+    poke p      = poke (castPtr p) . closeDegreeToCode
+
+isHDF5 :: BS.ByteString -> IO Bool
+isHDF5 filename = htriToBool (BS.useAsCString filename h5f_is_hdf5)
+
+newtype File = File HId_t
+    deriving (Eq, HId, FromHId, HDFResultType)
+
+instance Location File
+instance Object File where
+    staticObjectType = Tagged (Just FileObj)
+
+createFile :: BS.ByteString -> [AccFlags] -> Maybe FCPL -> Maybe FAPL -> IO File
+createFile filename flags create_plist access_plist =
+    fmap File $
+        withErrorCheck $
+            BS.useAsCString filename $ \cfilename ->
+                h5f_create cfilename (accFlagsToInt flags) (maybe h5p_DEFAULT hid create_plist) (maybe h5p_DEFAULT hid access_plist)
+
+openFile :: BS.ByteString -> [AccFlags] -> Maybe FAPL -> IO File
+openFile filename flags access_plist =
+    fmap File $
+        withErrorCheck $
+            BS.useAsCString filename $ \cfilename ->
+                h5f_open cfilename (accFlagsToInt flags) (maybe h5p_DEFAULT hid access_plist)
+
+reopenFile :: File -> IO File
+reopenFile (File file_id) =
+    fmap File $
+        withErrorCheck $
+            h5f_reopen file_id
+
+flushFile :: File -> Scope -> IO ()
+flushFile (File file_id) scope =
+    withErrorCheck_ $
+        h5f_flush file_id (scopeCode scope)
+
+closeFile :: File -> IO ()
+closeFile (File file_id) =
+    withErrorCheck_ (h5f_close file_id)
+
+mountFile :: Location loc => loc -> BS.ByteString -> File -> Maybe FMPL -> IO ()
+mountFile loc groupname (File file_id) mount_plist =
+    withErrorCheck_ $
+        BS.useAsCString groupname $ \cgroupname ->
+            h5f_mount (hid loc) cgroupname file_id (maybe h5p_DEFAULT hid mount_plist)
+
+unmountFile :: Location loc => loc -> BS.ByteString -> IO ()
+unmountFile loc groupname =
+    withErrorCheck_ $
+        BS.useAsCString groupname $ \cgroupname ->
+            h5f_unmount (hid loc) cgroupname
+
+getFileSize :: File -> IO HSize
+getFileSize (File file_id) =
+    fmap HSize $
+        withOut_ $ \sz ->
+            withErrorCheck $
+                h5f_get_filesize file_id sz
+
+getFileCreatePlist :: File -> IO FCPL
+getFileCreatePlist (File file_id) =
+    fmap uncheckedFromHId $
+        withErrorCheck $
+            h5f_get_create_plist file_id
+
+getFileAccessPlist :: File -> IO FAPL
+getFileAccessPlist (File file_id) =
+    fmap uncheckedFromHId $
+        withErrorCheck $
+            h5f_get_access_plist file_id
+
+data FileInfo = FileInfo
+    { superExtSize  :: !HSize
+    , sohmHdrSize   :: !HSize
+    , sohmMsgsInfo  :: !IH_Info
+    } deriving (Eq, Ord, Read, Show)
+
+readFileInfo :: H5F_info_t -> FileInfo
+readFileInfo (H5F_info_t a b (H5_ih_info_t c d)) = FileInfo (HSize a) (HSize b) (IH_Info (HSize c) (HSize d))
+
+getFileInfo :: Object obj => obj -> IO FileInfo
+getFileInfo obj =
+    fmap readFileInfo $
+        withOut_ $ \info ->
+            withErrorCheck $
+                h5f_get_info (hid obj) info
+
+getFileIntent :: File -> IO [AccFlags]
+getFileIntent (File file_id) =
+    fmap intToAccFlags $
+        withOut_ $ \intent ->
+            withErrorCheck_ $
+                h5f_get_intent file_id intent
+
+getFileName :: File -> IO BS.ByteString
+getFileName (File file_id) =
+    withOutByteString' $ \buf bufSz ->
+        withErrorWhen (< 0) $
+            h5f_get_name file_id buf bufSz
+
+getFileObjCount :: Maybe File -> Bool -> [ObjType] -> IO CSize
+getFileObjCount mbFile local objTypes =
+    fmap fromIntegral $
+        withErrorWhen (< 0) $
+            h5f_get_obj_count (maybe (HId_t h5f_OBJ_ALL) hid mbFile) (objTypesToInt objTypes .|. if local then 0 else h5f_OBJ_LOCAL)
+
+getOpenObjects :: Maybe File -> Bool -> [ObjType] -> IO (SV.Vector ObjectId)
+getOpenObjects mbFile local objTypes = do
+    n <- getFileObjCount mbFile local objTypes
+
+    withOutVector' (fromIntegral n) $ \objects ->
+        withErrorWhen (< 0) $
+            h5f_get_obj_ids (maybe (HId_t h5f_OBJ_ALL) hid mbFile) (objTypesToInt objTypes .|. if local then 0 else h5f_OBJ_LOCAL) n (castWrappedPtr objects)
+
+getFileFreespace :: File -> IO HSize
+getFileFreespace (File file_id) =
+    fmap fromIntegral $
+        withErrorWhen (< 0) $
+            h5f_get_freespace file_id
diff --git a/src/Bindings/HDF5/Group.hs b/src/Bindings/HDF5/Group.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Group.hs
@@ -0,0 +1,159 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{- |
+Typesafe wrappers around HDF5 functions from the H5G API.
+
+Feature coverage is as follows:
+
+  h5g_get_info                  	[  OK  ]
+  h5g_get_objname_by_idx        	[ FAIL ] (deprecated)
+  h5g_get_objinfo               	[ FAIL ] (deprecated)
+  h5g_iterate                   	[ FAIL ] (deprecated)
+  h5g_get_info_by_idx           	[ FAIL ]
+  h5g_link                      	[ FAIL ] (deprecated)
+  h5g_unlink                    	[ FAIL ] (deprecated)
+  h5g_get_objtype_by_idx        	[ FAIL ] (deprecated)
+  h5g_get_linkval               	[ FAIL ] (deprecated)
+  h5g_create_anon               	[  OK  ]
+  h5g_get_info_by_name          	[  OK  ]
+  h5g_get_num_objs              	[ FAIL ] (deprecated)
+  h5g_close                     	[  OK  ]
+  h5g_move                      	[ FAIL ] (deprecated)
+  h5g_open1                     	[ FAIL ] (deprecated)
+  h5g_open2                     	[  OK  ]
+  h5g_link2                     	[ FAIL ] (deprecated)
+  h5g_set_comment               	[ FAIL ] (deprecated)
+  h5g_get_comment               	[ FAIL ] (deprecated)
+  h5g_get_create_plist          	[ FAIL ]
+  h5g_move2                     	[ FAIL ] (deprecated)
+  h5g_create2                   	[  OK  ]
+  h5g_create1                   	[ FAIL ] (deprecated)
+
+
+-}
+module Bindings.HDF5.Group
+    ( Group
+
+    , createGroup
+    , createAnonymousGroup
+    , openGroup
+    , closeGroup
+
+    , GroupStorageType(..)
+    , GroupInfo(..)
+
+    , getGroupInfo
+    , getGroupInfoByName
+    ) where
+
+import Bindings.HDF5.Core
+import Bindings.HDF5.Error
+import Bindings.HDF5.Object
+import Bindings.HDF5.PropertyList.GAPL
+import Bindings.HDF5.PropertyList.GCPL
+import Bindings.HDF5.PropertyList.LCPL
+import Bindings.HDF5.Raw.H5G
+import Bindings.HDF5.Raw.H5I
+import Bindings.HDF5.Raw.H5P
+import Bindings.HDF5.Raw.Util
+import qualified Data.ByteString as BS
+import Data.Int
+import Foreign.Ptr.Conventions
+
+-- * The Group type
+
+newtype Group = Group HId_t
+    deriving (Eq, HId, FromHId, HDFResultType)
+
+instance Location Group
+instance Object Group where
+    staticObjectType = Tagged (Just GroupObj)
+
+-- * General group functions
+
+-- | Create a group given name, location and properties
+
+createGroup :: Location t =>
+               t                 -- ^ Parent location for the group
+               -> BS.ByteString  -- ^ Group name
+               -> Maybe LCPL     -- ^ Link creation properties
+               -> Maybe GCPL     -- ^ Group creation properties
+               -> Maybe GAPL     -- ^ Group access properties
+               -> IO Group       -- ^ Resulting group
+createGroup loc name lcpl gcpl gapl =
+    fmap Group $
+        withErrorCheck $
+            BS.useAsCString name $ \cname ->
+                h5g_create2 (hid loc) cname
+                    (maybe h5p_DEFAULT hid lcpl)
+                    (maybe h5p_DEFAULT hid gcpl)
+                    (maybe h5p_DEFAULT hid gapl)
+
+-- | Create an anonymous group without a name
+createAnonymousGroup :: Location t =>
+                        t              -- ^ Parent location for the group
+                        -> Maybe GCPL  -- ^ Group creation properties
+                        -> Maybe GAPL  -- ^ Group access properties
+                        -> IO Group    -- ^ Resulting group
+createAnonymousGroup loc gcpl gapl =
+    fmap Group $
+        withErrorCheck $
+            h5g_create_anon (hid loc) (maybe h5p_DEFAULT hid gcpl) (maybe h5p_DEFAULT hid gapl)
+
+-- | Open an existing group
+openGroup :: Location t =>
+             t                 -- ^ Parent location
+             -> BS.ByteString  -- ^ Group name
+             -> Maybe GAPL     -- ^ Group access properties
+             -> IO Group       -- ^ Resulting group
+openGroup loc name gapl =
+    fmap Group $
+        withErrorCheck $
+            BS.useAsCString name $ \cname ->
+                h5g_open2 (hid loc) cname (maybe h5p_DEFAULT hid gapl)
+
+-- | Close a group
+closeGroup :: Group -> IO ()
+closeGroup (Group grp) =
+    withErrorCheck_ $
+        h5g_close grp
+
+-- * Group metadata
+
+data GroupStorageType
+    = CompactStorage
+    | DenseStorage
+    | SymbolTableStorage
+    | UnknownStorage
+    deriving (Eq, Ord, Read, Show, Enum, Bounded)
+
+groupStorageTypeFromCode :: H5G_storage_type_t -> GroupStorageType
+groupStorageTypeFromCode c
+    | c == h5g_STORAGE_TYPE_COMPACT         = CompactStorage
+    | c == h5g_STORAGE_TYPE_DENSE           = DenseStorage
+    | c == h5g_STORAGE_TYPE_SYMBOL_TABLE    = SymbolTableStorage
+    | otherwise                             = UnknownStorage
+
+data GroupInfo = GroupInfo
+    { groupStorageType  :: !GroupStorageType
+    , groupNLinks       :: !HSize
+    , groupMaxCOrder    :: !Int64
+    , groupMounted      :: !Bool
+    } deriving (Eq, Ord, Read, Show)
+
+readGroupInfo :: H5G_info_t -> GroupInfo
+readGroupInfo (H5G_info_t a b c d) = GroupInfo (groupStorageTypeFromCode a) (HSize b) c (hboolToBool d)
+
+getGroupInfo :: Group -> IO GroupInfo
+getGroupInfo (Group group_id) =
+    fmap readGroupInfo $
+        withOut_ $ \info ->
+            withErrorCheck_ $
+                h5g_get_info group_id info
+
+getGroupInfoByName :: Location loc => loc -> BS.ByteString -> Maybe LAPL -> IO GroupInfo
+getGroupInfoByName loc name lapl =
+    fmap readGroupInfo $
+        withOut_ $ \info ->
+            BS.useAsCString name $ \cname ->
+                withErrorCheck_ $
+                    h5g_get_info_by_name (hid loc) cname info (maybe h5p_DEFAULT hid lapl)
diff --git a/src/Bindings/HDF5/Link.hs b/src/Bindings/HDF5/Link.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Link.hs
@@ -0,0 +1,258 @@
+{-# LANGUAGE ForeignFunctionInterface #-}
+{-
+
+  h5l_get_info_by_idx           	[ FAIL ]
+  h5l_iterate                   	[  OK  ]
+  h5l_register                  	[ FAIL ]
+  h5l_iterate_by_name           	[  OK  ]
+  h5l_unpack_elink_val          	[ FAIL ]
+  h5l_get_val_by_idx            	[ FAIL ]
+  h5l_create_external           	[  OK  ]
+  h5l_exists                    	[  OK  ]
+  h5l_move                      	[  OK  ]
+  h5l_create_ud                 	[ FAIL ]
+  h5l_create_hard               	[  OK  ]
+  h5l_is_registered             	[ FAIL ]
+  h5l_get_name_by_idx           	[  OK  ]
+  h5l_create_soft               	[  OK  ]
+  h5l_copy                      	[  OK  ]
+  h5l_get_val                   	[  OK  ]
+  h5l_visit                     	[  OK  ]
+  h5l_get_info                  	[  OK  ]
+  h5l_delete_by_idx             	[ FAIL ]
+  h5l_visit_by_name             	[  OK  ]
+  h5l_delete                    	[  OK  ]
+  h5l_unregister                	[ FAIL ]
+
+-}
+module Bindings.HDF5.Link
+    ( createHardLink
+    , createSoftLink
+    , createExternalLink
+
+    , getLinkNameByIdx
+
+    , doesLinkExist
+
+    , moveLink
+    , copyLink
+    , deleteLink
+
+    , LinkType(..)
+    , LinkInfo(..)
+    , getLinkInfo
+
+    , getSymLinkVal
+
+    , iterateLinks
+    , iterateLinksByName
+
+    , visitLinks
+    , visitLinksByName
+    ) where
+
+import           Bindings.HDF5.Core
+import           Bindings.HDF5.Datatype.Internal
+import           Bindings.HDF5.Error
+import           Bindings.HDF5.Group
+import           Bindings.HDF5.PropertyList.LAPL
+import           Bindings.HDF5.PropertyList.LCPL
+import           Bindings.HDF5.Raw.H5
+import           Bindings.HDF5.Raw.H5I
+import           Bindings.HDF5.Raw.H5L
+import           Bindings.HDF5.Raw.H5P
+import           Bindings.HDF5.Raw.Util
+import           Control.Exception               (SomeException, finally,
+                                                  throwIO, try)
+import qualified Data.ByteString                 as BS
+import           Data.IORef
+import           Foreign
+import           Foreign.C
+import           Foreign.Ptr.Conventions
+
+{-# ANN module "HLint: ignore Use camelCase" #-}
+
+createHardLink :: (Location src, Location dst) => src -> BS.ByteString -> dst -> BS.ByteString -> Maybe LCPL -> Maybe LAPL -> IO ()
+createHardLink src srcName dst dstName lcpl lapl =
+    withErrorCheck_ $
+        BS.useAsCString srcName $ \csrcName ->
+            BS.useAsCString dstName $ \cdstName ->
+                h5l_create_hard (hid src) csrcName (hid dst) cdstName
+                    (maybe h5p_DEFAULT hid lcpl)
+                    (maybe h5p_DEFAULT hid lapl)
+
+createSoftLink :: Location dst => BS.ByteString -> dst -> BS.ByteString -> Maybe LCPL -> Maybe LAPL -> IO ()
+createSoftLink srcName dst dstName lcpl lapl =
+    withErrorCheck_ $
+        BS.useAsCString srcName $ \csrcName ->
+            BS.useAsCString dstName $ \cdstName ->
+                h5l_create_soft csrcName (hid dst) cdstName
+                    (maybe h5p_DEFAULT hid lcpl)
+                    (maybe h5p_DEFAULT hid lapl)
+
+createExternalLink :: Location loc => BS.ByteString -> BS.ByteString -> loc -> BS.ByteString -> Maybe LCPL -> Maybe LAPL -> IO ()
+createExternalLink file obj loc name lcpl lapl =
+    withErrorCheck_ $
+        BS.useAsCString file $ \cfile ->
+            BS.useAsCString obj $ \cobj ->
+                BS.useAsCString name $ \cname ->
+                    h5l_create_external cfile cobj (hid loc) cname (maybe h5p_DEFAULT hid lcpl) (maybe h5p_DEFAULT hid lapl)
+
+getLinkNameByIdx :: Location loc =>  loc -> BS.ByteString -> IndexType -> IterOrder -> HSize -> Maybe LAPL -> IO BS.ByteString
+getLinkNameByIdx loc group indexType order idx lapl =
+  withOutByteString' $ \cname nameSize ->
+  BS.useAsCString group $ \cgroup ->
+  h5l_get_name_by_idx (hid loc) cgroup (indexTypeCode indexType) (iterOrderCode order) (hSize idx) cname nameSize (maybe h5p_DEFAULT hid lapl)
+
+doesLinkExist :: Location loc => loc -> BS.ByteString -> Maybe LAPL -> IO Bool
+doesLinkExist loc name lapl =
+    htriToBool $
+        BS.useAsCString name $ \cname ->
+            h5l_exists (hid loc) cname (maybe h5p_DEFAULT hid lapl)
+
+moveLink :: (Location src, Location dst) => src -> BS.ByteString -> dst -> BS.ByteString -> Maybe LCPL -> Maybe LAPL -> IO ()
+moveLink  src srcName dst dstName lcpl lapl =
+    withErrorCheck_ $
+        BS.useAsCString srcName $ \csrcName ->
+            BS.useAsCString dstName $ \cdstName ->
+                h5l_move (hid src) csrcName (hid dst) cdstName
+                    (maybe h5p_DEFAULT hid lcpl)
+                    (maybe h5p_DEFAULT hid lapl)
+
+copyLink :: (Location src, Location dst) => src -> BS.ByteString -> dst -> BS.ByteString -> Maybe LCPL -> Maybe LAPL -> IO ()
+copyLink  src srcName dst dstName lcpl lapl =
+    withErrorCheck_ $
+        BS.useAsCString srcName $ \csrcName ->
+            BS.useAsCString dstName $ \cdstName ->
+                h5l_copy (hid src) csrcName (hid dst) cdstName
+                    (maybe h5p_DEFAULT hid lcpl)
+                    (maybe h5p_DEFAULT hid lapl)
+
+deleteLink :: Location t => t -> BS.ByteString -> Maybe LAPL -> IO ()
+deleteLink loc name lapl =
+    withErrorCheck_ $
+        BS.useAsCString name $ \cname ->
+            h5l_delete (hid loc) cname (maybe h5p_DEFAULT hid lapl)
+
+data LinkType
+    = External
+    | Hard
+    | Soft
+    | OtherLinkType !H5L_type_t
+    deriving (Eq, Ord, Read, Show)
+
+linkTypeFromCode :: H5L_type_t -> LinkType
+linkTypeFromCode c
+    | c == h5l_TYPE_EXTERNAL    = External
+    | c == h5l_TYPE_HARD        = Hard
+    | c == h5l_TYPE_SOFT        = Soft
+    | c >= h5l_TYPE_UD_MIN      = OtherLinkType c
+    | otherwise                 = error ("Unknown link type: " ++ show c)
+
+
+data LinkInfo = LinkInfo
+    { linkType        :: LinkType
+    , linkCOrderValid :: Bool
+    , linkCOrder      :: Int64
+    , linkCSet        :: CSet
+    , linkAddress     :: HAddr
+    , linkValSize     :: CSize
+    } deriving (Eq, Ord, Read, Show)
+
+readLinkInfo :: H5L_info_t -> LinkInfo
+readLinkInfo i  = LinkInfo
+    { linkType          = linkTypeFromCode (h5l_info_t'type i)
+    , linkCOrderValid   = hboolToBool (h5l_info_t'corder_valid i)
+    , linkCOrder        = h5l_info_t'corder i
+    , linkCSet          = cSetFromCode (h5l_info_t'cset i)
+    , linkAddress       = HAddr (h5l_info_t'u'address i)
+    , linkValSize       = h5l_info_t'u'val_size i
+    }
+
+getLinkInfo :: Location loc => loc -> BS.ByteString -> Maybe LAPL -> IO LinkInfo
+getLinkInfo loc name lapl =
+    fmap readLinkInfo $
+        withOut_ $ \info ->
+            withErrorCheck_ $
+                BS.useAsCString name $ \cname ->
+                    h5l_get_info (hid loc) cname info (maybe h5p_DEFAULT hid lapl)
+
+getSymLinkVal :: Location loc => loc -> BS.ByteString -> Maybe LAPL -> IO BS.ByteString
+getSymLinkVal loc name mb_lapl =
+    BS.useAsCString name $ \cname -> do
+        let lapl = maybe h5p_DEFAULT hid mb_lapl
+        info <- withOut_ $ \info ->
+            withErrorCheck_ $
+                    h5l_get_info (hid loc) cname info lapl
+
+        let n = h5l_info_t'u'val_size info
+
+        buf <- mallocBytes (fromIntegral n)
+
+        withErrorCheck_ $
+            h5l_get_val (hid loc) cname (OutArray buf) n lapl
+        -- TODO: this will leak memory if an exception is thrown
+
+        BS.packCStringLen (buf, fromIntegral n)
+
+
+foreign import ccall "wrapper" wrap_H5L_iterate_t
+    :: (HId_t -> CString -> In H5L_info_t -> InOut a -> IO HErr_t)
+    -> IO (FunPtr (HId_t -> CString -> In H5L_info_t -> InOut a -> IO HErr_t))
+
+with_iterate_t :: (Group -> BS.ByteString -> LinkInfo -> IO HErr_t)
+     -> (H5L_iterate_t () -> InOut () -> IO HErr_t)
+     -> IO HErr_t
+with_iterate_t op f = do
+    exception1 <- newIORef Nothing :: IO (IORef (Maybe SomeException))
+
+    op1 <- wrap_H5L_iterate_t $ \grp name (In link) _opData -> do
+        name1 <- BS.packCString name
+        link1 <- peek link
+        result <- try (op (uncheckedFromHId grp) name1 (readLinkInfo link1))
+        case result of
+            Left exc -> do
+                writeIORef exception1 (Just exc)
+                return maxBound
+            Right x -> return x
+
+    result <- f op1 (InOut nullPtr) `finally` freeHaskellFunPtr op1
+
+    if result == maxBound
+        then do
+            exception2 <- readIORef exception1
+            maybe (return result) throwIO exception2
+
+        else return result
+
+-- TODO : It would be nice if we didn't expose HErr_t in these callback functions.
+--        Decide whether we want Either or Exceptions.
+iterateLinks :: Location t => t -> IndexType -> IterOrder -> Maybe HSize -> (Group -> BS.ByteString -> LinkInfo -> IO HErr_t) -> IO HSize
+iterateLinks loc indexType order startIndex op =
+    fmap HSize $
+        withInOut_ (maybe 0 hSize startIndex) $ \ioStartIndex ->
+            withErrorCheck_ $
+                with_iterate_t op $ \iop opData ->
+                    h5l_iterate (hid loc) (indexTypeCode indexType) (iterOrderCode order) ioStartIndex iop opData
+
+iterateLinksByName :: Location t => t -> BS.ByteString -> IndexType -> IterOrder -> Maybe HSize -> Maybe LAPL -> (Group -> BS.ByteString -> LinkInfo -> IO HErr_t) -> IO HSize
+iterateLinksByName loc groupName indexType order startIndex lapl op =
+    fmap HSize $
+        withInOut_ (maybe 0 hSize startIndex) $ \ioStartIndex ->
+            withErrorCheck_ $
+                with_iterate_t op $ \iop opData ->
+                    BS.useAsCString groupName $ \cgroupName ->
+                        h5l_iterate_by_name (hid loc) cgroupName (indexTypeCode indexType) (iterOrderCode order) ioStartIndex iop opData (maybe h5p_DEFAULT hid lapl)
+
+visitLinks :: Location t => t -> IndexType -> IterOrder -> (Group -> BS.ByteString -> LinkInfo -> IO HErr_t) -> IO ()
+visitLinks loc indexType order op =
+    withErrorCheck_ $
+        with_iterate_t op $ \iop opData ->
+            h5l_visit (hid loc) (indexTypeCode indexType) (iterOrderCode order) iop opData
+
+visitLinksByName :: Location t => t -> BS.ByteString -> IndexType -> IterOrder -> Maybe LAPL -> (Group -> BS.ByteString -> LinkInfo -> IO HErr_t) -> IO ()
+visitLinksByName loc groupName indexType order lapl op =
+    withErrorCheck_ $
+        with_iterate_t op $ \iop opData ->
+            BS.useAsCString groupName $ \cgroupName ->
+                h5l_visit_by_name (hid loc) cgroupName (indexTypeCode indexType) (iterOrderCode order) iop opData (maybe h5p_DEFAULT hid lapl)
diff --git a/src/Bindings/HDF5/Object.hs b/src/Bindings/HDF5/Object.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Object.hs
@@ -0,0 +1,132 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module Bindings.HDF5.Object
+    ( ObjectId
+    , Object(..)
+    , ObjectType(..)
+
+    , objectTypeOf
+    , objectTypeOf1
+
+    , uncheckedCastObject
+    , castObject
+
+    , openObject
+    , getObjectType
+
+    , linkObject
+    , closeObject
+    , copyObject
+
+    , doesObjectExist
+    ) where
+
+import Data.Maybe
+
+import Bindings.HDF5.Core
+import Bindings.HDF5.Error
+import Bindings.HDF5.PropertyList.LAPL
+import Bindings.HDF5.PropertyList.LCPL
+import Bindings.HDF5.PropertyList.OCPYPL
+import Bindings.HDF5.Raw.H5I
+import Bindings.HDF5.Raw.H5O
+import Bindings.HDF5.Raw.H5P
+import qualified Data.ByteString as BS
+import Foreign.Storable
+
+newtype ObjectId = ObjectId HId_t
+    deriving (Eq, HId, FromHId, HDFResultType, Storable)
+
+class (HId t, FromHId t) => Object t where
+    staticObjectType :: Tagged t (Maybe ObjectType)
+
+instance Object ObjectId where
+    staticObjectType = Tagged Nothing
+
+objectTypeOf :: Object t => t -> Maybe ObjectType
+objectTypeOf = f staticObjectType
+    where
+        f :: Tagged t a -> t -> a
+        f = const . unTagged
+
+objectTypeOf1 :: Object t => c t -> Maybe ObjectType
+objectTypeOf1 = f staticObjectType
+    where
+        f :: Tagged t a -> c t -> a
+        f = const . unTagged
+
+uncheckedCastObject :: (Object a, Object b) => a -> b
+uncheckedCastObject = uncheckedFromHId . hid
+
+castObject :: (Object src, Object dst) => src -> IO (Maybe dst)
+castObject = castTo staticObjectType
+    where
+        castTo :: (Object a, Object b) => Tagged b (Maybe ObjectType) -> a -> IO (Maybe b)
+        castTo (Tagged Nothing)        src = return (Just (uncheckedCastObject src)) -- cast to ObjectId always succeeds
+        castTo (Tagged (Just dstType)) src = do
+            srcType <- getObjectType src
+            return $! if srcType == dstType
+                then Just (uncheckedCastObject src)
+                else Nothing
+
+openObject :: Location loc => loc -> BS.ByteString -> Maybe LAPL -> IO ObjectId
+openObject loc name lapl =
+    fmap ObjectId $
+        BS.useAsCString name $ \cname ->
+            withErrorCheck $
+                h5o_open (hid loc) cname (maybe h5p_DEFAULT hid lapl)
+
+data ObjectType
+    = FileObj
+    | GroupObj
+    | DatatypeObj
+    | DataspaceObj
+    | DatasetObj
+    | AttrObj
+    deriving (Eq, Ord, Read, Show, Enum, Bounded)
+
+objectTypeCode :: ObjectType -> H5I_type_t
+objectTypeCode FileObj      = h5i_FILE
+objectTypeCode GroupObj     = h5i_GROUP
+objectTypeCode DatatypeObj  = h5i_DATATYPE
+objectTypeCode DataspaceObj = h5i_DATASPACE
+objectTypeCode DatasetObj   = h5i_DATASET
+objectTypeCode AttrObj      = h5i_ATTR
+
+objectTypeFromCode :: H5I_type_t -> ObjectType
+objectTypeFromCode c =
+    fromMaybe (error ("Unknown object type code: " ++ show c))
+                  (lookup c codes)
+        where
+          codes = [ (objectTypeCode x, x) | x <- [minBound .. maxBound]]
+
+getObjectType :: Object obj => obj -> IO ObjectType
+getObjectType obj =
+    fmap objectTypeFromCode $
+        withErrorCheck $
+            h5i_get_type (hid obj)
+
+linkObject :: (Object obj, Location loc) => obj -> loc -> BS.ByteString -> Maybe LCPL -> Maybe LAPL -> IO ()
+linkObject obj loc name lcpl lapl =
+    withErrorCheck_ $
+        BS.useAsCString name $ \cname ->
+            h5o_link (hid obj) (hid loc) cname (maybe h5p_DEFAULT hid lcpl) (maybe h5p_DEFAULT hid lapl)
+
+closeObject :: Object obj => obj -> IO ()
+closeObject obj =
+    withErrorCheck_ $
+        h5o_close (hid obj)
+
+copyObject :: (Location src, Location dst) => src -> BS.ByteString -> dst -> BS.ByteString -> Maybe OCPYPL -> Maybe LCPL -> IO ()
+copyObject src srcName dst dstName ocpypl lcpl =
+    withErrorCheck_ $
+        BS.useAsCString srcName $ \csrcName ->
+            BS.useAsCString dstName $ \cdstName ->
+                h5o_copy (hid src) csrcName (hid dst) cdstName
+                    (maybe h5p_DEFAULT hid ocpypl)
+                    (maybe h5p_DEFAULT hid lcpl)
+
+doesObjectExist :: Location loc => loc -> BS.ByteString -> Maybe LAPL -> IO Bool
+doesObjectExist loc name lapl =
+    htriToBool $
+        BS.useAsCString name $ \cname ->
+            h5o_exists_by_name (hid loc) cname (maybe h5p_DEFAULT hid lapl)
diff --git a/src/Bindings/HDF5/PropertyList.hs b/src/Bindings/HDF5/PropertyList.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/PropertyList.hs
@@ -0,0 +1,192 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module Bindings.HDF5.PropertyList
+    ( PropertyListClassID
+    , root
+    , objectCreate
+    , fileCreate
+    , fileAccess
+    , datasetCreate
+    , datasetAccess
+    , datasetXfer
+    , fileMount
+    , groupCreate
+    , groupAccess
+    , datatypeCreate
+    , datatypeAccess
+    , stringCreate
+    , attributeCreate
+    , objectCopy
+    , linkCreate
+    , linkAccess
+
+    , getClassName
+
+    , PropertyListID
+    , PropertyListOrClass
+    , PropertyList(..)
+    , Tagged(..)
+    , castPropertyList
+
+    , createPropertyList
+    , createPropertyListWithClass
+
+    , propertyExists
+    , getPropertySize
+    , getNProps
+
+    , getPropertyListClass
+    , getPropertyListClassParent
+
+    , propertyListsEqual
+
+    , propertyListIsA
+
+    , closePropertyListClass
+    , closePropertyList
+    ) where
+
+#if __GLASGOW_HASKELL__ < 710
+import Control.Applicative ((<$>))
+#endif
+
+import Bindings.HDF5.Raw.H5I
+import Bindings.HDF5.Raw.H5P
+import Bindings.HDF5.Core
+import Bindings.HDF5.Error
+
+import qualified Data.ByteString as BS
+import Data.Tagged
+import Foreign
+import Foreign.C
+import Foreign.Ptr.Conventions
+
+newtype PropertyListClassID = PropertyListClassID HId_t
+    deriving (Eq, HId, FromHId, HDFResultType)
+
+root, fileCreate, fileAccess, fileMount:: PropertyListClassID
+datasetCreate, datasetAccess, datasetXfer :: PropertyListClassID
+objectCreate, groupCreate, groupAccess :: PropertyListClassID
+datatypeCreate, datatypeAccess :: PropertyListClassID
+stringCreate, attributeCreate :: PropertyListClassID
+objectCopy, linkCreate, linkAccess :: PropertyListClassID
+
+root                = PropertyListClassID h5p_ROOT              -- no parent
+objectCreate        = PropertyListClassID h5p_OBJECT_CREATE     -- parent:  root
+fileCreate          = PropertyListClassID h5p_FILE_CREATE       -- parent:  groupCreate
+fileAccess          = PropertyListClassID h5p_FILE_ACCESS       -- parent:  root
+datasetCreate       = PropertyListClassID h5p_DATASET_CREATE    -- parent:  objectCreate
+datasetAccess       = PropertyListClassID h5p_DATASET_ACCESS    -- parent:  linkAccess
+datasetXfer         = PropertyListClassID h5p_DATASET_XFER      -- parent:  root
+fileMount           = PropertyListClassID h5p_FILE_MOUNT        -- parent:  root
+groupCreate         = PropertyListClassID h5p_GROUP_CREATE      -- parent:  objectCreate
+groupAccess         = PropertyListClassID h5p_GROUP_ACCESS      -- parent:  linkAccess
+datatypeCreate      = PropertyListClassID h5p_DATATYPE_CREATE   -- parent:  objectCreate
+datatypeAccess      = PropertyListClassID h5p_DATATYPE_ACCESS   -- parent:  linkAccess
+stringCreate        = PropertyListClassID h5p_STRING_CREATE     -- parent:  root
+attributeCreate     = PropertyListClassID h5p_ATTRIBUTE_CREATE  -- parent:  stringCreate
+objectCopy          = PropertyListClassID h5p_OBJECT_COPY       -- parent:  root
+linkCreate          = PropertyListClassID h5p_LINK_CREATE       -- parent:  stringCreate
+linkAccess          = PropertyListClassID h5p_LINK_ACCESS       -- parent:  root
+
+getClassName :: PropertyListClassID -> IO BS.ByteString
+getClassName (PropertyListClassID cls) = do
+    name <- withErrorWhen (nullPtr ==) $
+        h5p_get_class_name cls
+
+    nameStr <- BS.packCString name
+    free name
+
+    return nameStr
+
+newtype PropertyListID = PropertyListID HId_t
+    deriving (Eq, HId, FromHId, HDFResultType)
+
+class (HId t, FromHId t) => PropertyListOrClass t where
+class PropertyListOrClass t => PropertyList t where
+    staticPlistClass :: Tagged t PropertyListClassID
+
+instance PropertyListOrClass PropertyListID
+instance PropertyListOrClass PropertyListClassID
+
+instance PropertyList PropertyListID where
+    staticPlistClass = Tagged root
+
+uncheckedCastPlist :: (PropertyList a, PropertyList b) => a -> b
+uncheckedCastPlist = uncheckedFromHId . hid
+
+castPropertyList :: (PropertyList a, PropertyList b) => a -> IO (Maybe b)
+castPropertyList = castTo staticPlistClass
+    where
+        castTo :: (PropertyList a, PropertyList b)
+               => Tagged b PropertyListClassID -> a -> IO (Maybe b)
+        castTo (Tagged cls) plist = do
+            ok <- propertyListIsA plist cls
+            if ok
+                then return (Just . uncheckedCastPlist $ plist)
+                else return Nothing
+
+createPropertyList :: PropertyList t => IO t
+createPropertyList = create staticPlistClass
+    where
+        create :: PropertyList t => Tagged t PropertyListClassID -> IO t
+        create (Tagged cls)
+            = uncheckedCastPlist
+              <$> createPropertyListWithClass cls
+
+createPropertyListWithClass :: PropertyListClassID -> IO PropertyListID
+createPropertyListWithClass (PropertyListClassID cls) =
+    fmap PropertyListID $
+        withErrorCheck $
+            h5p_create cls
+
+propertyExists :: PropertyList t => t -> BS.ByteString -> IO Bool
+propertyExists plist name =
+    htriToBool $
+        BS.useAsCString name $ \cname ->
+            h5p_exist (hid plist) cname
+
+getPropertySize :: PropertyListOrClass t => t -> BS.ByteString -> IO CSize
+getPropertySize plist name =
+    withOut_ $ \sz ->
+        withErrorCheck_ $
+            BS.useAsCString name $ \cname ->
+                h5p_get_size (hid plist) cname sz
+
+getNProps :: PropertyListOrClass t => t -> IO CSize
+getNProps plist =
+    withOut_ $ \sz ->
+        withErrorCheck_ $
+            h5p_get_nprops (hid plist) sz
+
+getPropertyListClass :: PropertyList t => t -> IO PropertyListClassID
+getPropertyListClass plist =
+    fmap PropertyListClassID $
+        withErrorCheck $
+            h5p_get_class (hid plist)
+
+getPropertyListClassParent :: PropertyListClassID -> IO PropertyListClassID
+getPropertyListClassParent (PropertyListClassID cls) =
+    fmap PropertyListClassID $
+        withErrorCheck $
+            h5p_get_class_parent cls
+
+propertyListsEqual :: (PropertyListOrClass a, PropertyListOrClass b) => a -> b -> IO Bool
+propertyListsEqual pl1 pl2 =
+    htriToBool $
+        h5p_equal (hid pl1) (hid pl2)
+
+propertyListIsA :: PropertyList t => t -> PropertyListClassID -> IO Bool
+propertyListIsA plist (PropertyListClassID cls) =
+    htriToBool $
+        h5p_isa_class (hid plist) cls
+
+closePropertyListClass :: PropertyListClassID -> IO ()
+closePropertyListClass (PropertyListClassID cls) =
+    withErrorCheck_ $
+        h5p_close_class cls
+
+closePropertyList :: PropertyList t => t -> IO ()
+closePropertyList plist =
+    withErrorCheck_ $
+        h5p_close (hid plist)
diff --git a/src/Bindings/HDF5/PropertyList/DAPL.hs b/src/Bindings/HDF5/PropertyList/DAPL.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/PropertyList/DAPL.hs
@@ -0,0 +1,40 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module Bindings.HDF5.PropertyList.DAPL
+    ( module Bindings.HDF5.PropertyList.LAPL
+
+    , DAPL
+    , DatasetAccessPropertyList
+
+    , setChunkCache
+    , getChunkCache
+    ) where
+
+import Bindings.HDF5.Core
+import Bindings.HDF5.Error
+import Bindings.HDF5.PropertyList.LAPL
+import Bindings.HDF5.Raw.H5P
+import Foreign.C.Types
+import Foreign.Ptr.Conventions
+
+newtype DAPL = DAPL LAPL
+    deriving (Eq, HId, FromHId, HDFResultType, PropertyListOrClass, LinkAccessPropertyList)
+
+instance PropertyList DAPL where
+    staticPlistClass = Tagged datasetAccess
+
+class LinkAccessPropertyList t => DatasetAccessPropertyList t where
+instance DatasetAccessPropertyList DAPL
+
+setChunkCache :: DatasetAccessPropertyList dapl => dapl -> CSize -> CSize -> CDouble -> IO ()
+setChunkCache dapl rdccNSlots rdccNBytes rddcW0 =
+    withErrorCheck_ $
+        h5p_set_chunk_cache (hid dapl) rdccNSlots rdccNBytes rddcW0
+
+getChunkCache :: DatasetAccessPropertyList dapl => dapl -> IO (CSize, CSize, CDouble)
+getChunkCache dapl =
+    fmap (\(a,(b,c)) -> (a,b,c)) $
+        withOut $ \rdccNSlots ->
+            withOut $ \rdccNBytes ->
+                withOut_ $ \rddcW0 ->
+                    withErrorCheck_ $
+                        h5p_get_chunk_cache (hid dapl) rdccNSlots rdccNBytes rddcW0
diff --git a/src/Bindings/HDF5/PropertyList/DCPL.hs b/src/Bindings/HDF5/PropertyList/DCPL.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/PropertyList/DCPL.hs
@@ -0,0 +1,281 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module Bindings.HDF5.PropertyList.DCPL
+    ( module Bindings.HDF5.PropertyList.OCPL
+
+    , DCPL
+    , DatasetCreationPropertyList
+
+    , Layout(..)
+    , setLayout
+    , getLayout
+
+    , setChunk
+    , getChunk
+
+    , setExternal
+    , getExternalCount
+    , getExternalN
+    , getExternal
+
+    , setSZip
+
+    , setShuffle
+
+    , setNBit
+
+    , ScaleType(..)
+    , setScaleOffset
+
+    , setFillValue
+    , getFillValue
+    , FillValueDefaultType(..)
+    , fillValueDefined
+
+    , AllocTime(..)
+    , setAllocTime
+    , getAllocTime
+
+    , FillTime(..)
+    , setFillTime
+    , getFillTime
+    ) where
+
+import Bindings.HDF5.Core
+import Bindings.HDF5.Error
+import Bindings.HDF5.PropertyList
+import Bindings.HDF5.PropertyList.OCPL
+import Bindings.HDF5.Datatype.Internal
+import Bindings.HDF5.Raw.H5D
+import Bindings.HDF5.Raw.H5P
+import Bindings.HDF5.Raw.H5Z
+
+import qualified Data.ByteString as BS
+import qualified Data.ByteString.Unsafe as BS
+import Data.List
+import Foreign
+import Foreign.C
+import Foreign.Ptr.Conventions
+import System.Posix.Types
+
+newtype DCPL = DCPL OCPL
+    deriving (Eq, HId, FromHId, HDFResultType, PropertyListOrClass, ObjectCreationPropertyList)
+
+instance PropertyList DCPL where
+    staticPlistClass = Tagged datasetCreate
+
+class ObjectCreationPropertyList t => DatasetCreationPropertyList t where
+instance DatasetCreationPropertyList DCPL
+
+data Layout
+    = CompactLayout
+    | ContiguousLayout
+    | ChunkedLayout
+    deriving (Eq, Ord, Bounded, Enum, Read, Show)
+
+layoutCode :: Layout -> H5D_layout_t
+layoutCode CompactLayout      = h5d_COMPACT
+layoutCode ContiguousLayout   = h5d_CONTIGUOUS
+layoutCode ChunkedLayout      = h5d_CHUNKED
+
+layout :: H5D_layout_t -> Layout
+layout c
+    | c == h5d_COMPACT      = CompactLayout
+    | c == h5d_CONTIGUOUS   = ContiguousLayout
+    | c == h5d_CHUNKED      = ChunkedLayout
+    | otherwise = error ("unknown H5D_layout_t: " ++ show c)
+
+setLayout :: DatasetCreationPropertyList t => t -> Layout -> IO ()
+setLayout plist l =
+    withErrorCheck_ $
+        h5p_set_layout (hid plist) (layoutCode l)
+
+getLayout :: DatasetCreationPropertyList t => t -> IO Layout
+getLayout plist =
+    fmap layout $
+        withErrorWhen (\(H5D_layout_t c) -> c < 0) $
+            h5p_get_layout (hid plist)
+
+setChunk :: DatasetCreationPropertyList t => t -> [HSize] -> IO ()
+setChunk plist chunkSizes =
+    withErrorCheck_ $
+        withInList (map hSize chunkSizes) $ \cchunkSizes ->
+            h5p_set_chunk (hid plist) n cchunkSizes
+    where n = genericLength chunkSizes
+
+getChunk :: DatasetCreationPropertyList t => t -> IO [HSize]
+getChunk plist = do
+    n <- withErrorWhen (< 0) $
+        h5p_get_chunk (hid plist) 0 (OutArray nullPtr)
+
+    fmap (map HSize) $
+        withOutList_ (fromIntegral n) $ \buf ->
+            withErrorWhen_ (< 0) $
+                h5p_get_chunk (hid plist) n buf
+
+setExternal :: DatasetCreationPropertyList t => t -> BS.ByteString -> COff -> HSize -> IO ()
+setExternal plist name offset size =
+    withErrorCheck_ $
+        BS.useAsCString name $ \cname ->
+            h5p_set_external (hid plist) cname offset (hSize size)
+
+getExternalCount :: DatasetCreationPropertyList t => t -> IO CInt
+getExternalCount plist =
+    withErrorWhen (< 0) $
+        h5p_get_external_count (hid plist)
+
+getExternalN :: DatasetCreationPropertyList t => t -> CUInt -> CSize -> IO (BS.ByteString, COff, HSize)
+getExternalN plist idx name_size = do
+    let sz = fromIntegral name_size
+    name1 <- mallocBytes sz
+
+    (offset, size) <-
+        withOut $ \offset ->
+            withOut_ $ \size ->
+                withErrorCheck_ $
+                    h5p_get_external (hid plist) idx name_size (OutArray name1) offset size
+    -- TODO: this will leak memory if an exception is thrown
+
+    name2 <- BS.unsafePackCStringLen (name1, sz)
+    return (BS.takeWhile (0 /=) name2, offset, HSize size)
+
+getExternal :: DatasetCreationPropertyList t => t -> CUInt -> IO (BS.ByteString, COff, HSize)
+getExternal plist idx = loop 255
+    where
+        loop sz = do
+            result@(name, _, _) <- getExternalN plist idx sz
+            if BS.length name < fromIntegral sz
+                then return result
+                else do
+                    let sz' = 2*sz + 1
+                    if sz' > sz
+                        then loop sz'
+                        else fail "getExternal: name_size overflow, this is almost certainly a programming error in getExternal"
+
+setSZip :: DatasetCreationPropertyList t => t -> CUInt -> CUInt -> IO ()
+setSZip plist options_mask pixels_per_block =
+    withErrorCheck_ $
+        h5p_set_szip (hid plist) options_mask pixels_per_block
+
+setShuffle :: DatasetCreationPropertyList t => t -> IO ()
+setShuffle plist =
+    withErrorCheck_ $
+        h5p_set_shuffle (hid plist)
+
+setNBit :: DatasetCreationPropertyList t => t -> IO ()
+setNBit plist =
+    withErrorCheck_ $
+        h5p_set_nbit (hid plist)
+
+data ScaleType
+    = FloatDScale
+    | FloatEScale
+    | IntScale
+    deriving (Eq, Ord, Bounded, Enum, Read, Show)
+
+scaleTypeCode :: ScaleType -> H5Z_SO_scale_type_t
+scaleTypeCode FloatDScale = h5z_SO_FLOAT_DSCALE
+scaleTypeCode FloatEScale = h5z_SO_FLOAT_ESCALE
+scaleTypeCode IntScale    = h5z_SO_INT
+
+setScaleOffset :: DatasetCreationPropertyList t => t -> ScaleType -> CInt -> IO ()
+setScaleOffset plist scale_type scale_factor =
+    withErrorCheck_ $
+        h5p_set_scaleoffset (hid plist) (scaleTypeCode scale_type) scale_factor
+
+setFillValue :: (DatasetCreationPropertyList t, NativeType a) => t -> a -> IO ()
+setFillValue plist value =
+    withErrorCheck_ $
+        withIn value $ \ivalue ->
+            h5p_set_fill_value (hid plist) (hdfTypeOf1 ivalue) ivalue
+
+getFillValue :: (DatasetCreationPropertyList t, NativeType a) => t -> IO a
+getFillValue plist =
+    withOut_ $ \value ->
+        withErrorCheck_ $
+            h5p_get_fill_value (hid plist) (hdfTypeOf1 value) value
+
+data FillValueDefaultType
+    = Undefined
+    | DefaultFillValue
+    | UserDefined
+    deriving (Eq, Ord, Bounded, Enum, Read, Show)
+
+fillValueDefaultType :: H5D_fill_value_t -> FillValueDefaultType
+fillValueDefaultType c
+    | c == h5d_FILL_VALUE_UNDEFINED     = Undefined
+    | c == h5d_FILL_VALUE_DEFAULT       = DefaultFillValue
+    | c == h5d_FILL_VALUE_USER_DEFINED  = UserDefined
+    | c == h5d_FILL_VALUE_ERROR         = error "fillValueDefined: h5d_FILL_VALUE_ERROR"
+    | otherwise = error ("fillValueDefined: unknown H5D_fill_value_t " ++ show c)
+
+fillValueDefined :: DatasetCreationPropertyList t => t -> IO FillValueDefaultType
+fillValueDefined plist =
+    fmap fillValueDefaultType $
+        withOut_ $ \status ->
+            withErrorCheck_ $
+                h5p_fill_value_defined (hid plist) status
+
+data AllocTime
+    = DefaultAllocTime
+    | Early
+    | Late
+    | Incr -- ...emental?
+    deriving (Eq, Ord, Bounded, Enum, Read, Show)
+
+allocTimeCode :: AllocTime -> H5D_alloc_time_t
+allocTimeCode DefaultAllocTime  = h5d_ALLOC_TIME_DEFAULT
+allocTimeCode Early             = h5d_ALLOC_TIME_EARLY
+allocTimeCode Late              = h5d_ALLOC_TIME_LATE
+allocTimeCode Incr              = h5d_ALLOC_TIME_INCR
+
+allocTime :: H5D_alloc_time_t -> AllocTime
+allocTime c
+    | c == h5d_ALLOC_TIME_DEFAULT   = DefaultAllocTime
+    | c == h5d_ALLOC_TIME_EARLY     = Early
+    | c == h5d_ALLOC_TIME_LATE      = Late
+    | c == h5d_ALLOC_TIME_INCR      = Incr
+    | c == h5d_ALLOC_TIME_ERROR     = error "h5d_ALLOC_TIME_ERROR"
+    | otherwise = error ("unknown H5D_alloc_time_t " ++ show c)
+
+setAllocTime :: DatasetCreationPropertyList t => t -> AllocTime -> IO ()
+setAllocTime plist alloc_time =
+    withErrorCheck_ $
+        h5p_set_alloc_time (hid plist) (allocTimeCode alloc_time)
+
+getAllocTime :: DatasetCreationPropertyList t => t -> IO AllocTime
+getAllocTime plist =
+    fmap allocTime $
+        withOut_ $ \alloc_time ->
+            withErrorCheck_ $
+                h5p_get_alloc_time (hid plist) alloc_time
+
+data FillTime
+    = Alloc
+    | Never
+    | IfSet
+    deriving (Eq, Ord, Bounded, Enum, Read, Show)
+
+fillTimeCode :: FillTime -> H5D_fill_time_t
+fillTimeCode Alloc = h5d_FILL_TIME_ALLOC
+fillTimeCode Never = h5d_FILL_TIME_NEVER
+fillTimeCode IfSet = h5d_FILL_TIME_IFSET
+
+fillTime :: H5D_fill_time_t -> FillTime
+fillTime c
+    | c == h5d_FILL_TIME_ALLOC = Alloc
+    | c == h5d_FILL_TIME_NEVER = Never
+    | c == h5d_FILL_TIME_IFSET = IfSet
+    | otherwise = error "unknown h5d_FILL_TIME value"
+
+setFillTime :: DatasetCreationPropertyList t => t -> FillTime -> IO ()
+setFillTime plist fill_time =
+        withErrorCheck_ $
+            h5p_set_fill_time (hid plist) (fillTimeCode fill_time)
+
+getFillTime :: DatasetCreationPropertyList t => t -> IO FillTime
+getFillTime plist =
+    fmap fillTime $
+        withOut_ $ \fill_time ->
+            withErrorCheck_ $
+                h5p_get_fill_time (hid plist) fill_time
+
diff --git a/src/Bindings/HDF5/PropertyList/DXPL.hs b/src/Bindings/HDF5/PropertyList/DXPL.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/PropertyList/DXPL.hs
@@ -0,0 +1,21 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module Bindings.HDF5.PropertyList.DXPL
+    ( module Bindings.HDF5.PropertyList
+
+    , DXPL
+    , DatasetTransferPropertyList
+
+    ) where
+
+import Bindings.HDF5.Core
+import Bindings.HDF5.PropertyList
+
+class PropertyList t => DatasetTransferPropertyList t where
+newtype DXPL = DXPL PropertyListID
+    deriving (Eq, HId, FromHId, HDFResultType, PropertyListOrClass)
+instance PropertyList DXPL where
+    staticPlistClass = Tagged datasetXfer
+instance DatasetTransferPropertyList DXPL
+
+-- TODO: implement functions
+
diff --git a/src/Bindings/HDF5/PropertyList/FAPL.hs b/src/Bindings/HDF5/PropertyList/FAPL.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/PropertyList/FAPL.hs
@@ -0,0 +1,95 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module Bindings.HDF5.PropertyList.FAPL
+    ( module Bindings.HDF5.PropertyList
+
+    , FAPL
+    , FileAccessPropertyList
+
+    , setAlignment
+    , getAlignment
+
+    , setFamilyOffset
+    , getFamilyOffset
+
+    , setFCloseDegree
+    , getFCloseDegree
+    ) where
+
+import           Bindings.HDF5.Core
+import           Bindings.HDF5.Error
+import           Bindings.HDF5.PropertyList
+import           Bindings.HDF5.Raw.H5F
+import           Bindings.HDF5.Raw.H5P
+
+import           Control.Arrow              ((***))
+import           Foreign.Ptr.Conventions
+
+class PropertyList t => FileAccessPropertyList t where
+newtype FAPL = FAPL PropertyListID
+    deriving (Eq, HId, FromHId, HDFResultType, PropertyListOrClass)
+instance PropertyList FAPL where
+    staticPlistClass = Tagged fileAccess
+instance FileAccessPropertyList FAPL
+
+setAlignment :: FileAccessPropertyList fapl => fapl -> HSize -> HSize -> IO ()
+setAlignment fapl threshold alignment =
+    withErrorCheck_ $
+        h5p_set_alignment (hid fapl) (hSize threshold) (hSize alignment)
+
+getAlignment :: FileAccessPropertyList fapl => fapl -> IO (HSize, HSize)
+getAlignment fapl =
+    fmap (HSize *** HSize) $
+        withOut $ \threshold ->
+            withOut_ $ \alignment ->
+                withErrorCheck_ $
+                    h5p_get_alignment (hid fapl) threshold alignment
+
+
+-- TODO: implement these
+-- h5p_set_driver :: HId_t -> HId_t -> Ptr a -> IO HErr_t
+-- h5p_get_driver :: HId_t -> IO HId_t
+-- h5p_get_driver_info :: HId_t -> IO (Ptr a)
+
+setFamilyOffset :: FileAccessPropertyList fapl => fapl -> HSize -> IO ()
+setFamilyOffset fapl offset =
+    withErrorCheck_ $
+        h5p_set_family_offset (hid fapl) (hSize offset)
+
+getFamilyOffset :: FileAccessPropertyList fapl => fapl -> IO HSize
+getFamilyOffset fapl =
+    fmap HSize $
+        withOut_ $ \offset ->
+            withErrorCheck_ $
+                h5p_get_family_offset (hid fapl) offset
+
+setFCloseDegree :: FileAccessPropertyList fapl => fapl -> H5F_close_degree_t -> IO ()
+setFCloseDegree fapl degree =
+  withErrorCheck_ $
+  h5p_set_fclose_degree (hid fapl) degree
+
+getFCloseDegree :: FileAccessPropertyList fapl => fapl -> IO H5F_close_degree_t
+getFCloseDegree fapl =
+  withOut_ $ \degree ->
+    withErrorCheck_ $
+      h5p_get_fclose_degree (hid fapl) degree
+
+
+-- TODO: implement these
+-- h5p_set_multi_type :: HId_t -> H5FD_mem_t -> IO HErr_t
+-- h5p_get_multi_type :: HId_t -> Out H5FD_mem_t -> IO HErr_t
+-- h5p_set_cache :: HId_t -> CInt -> CSize -> CSize -> CDouble -> IO HErr_t
+-- h5p_get_cache :: HId_t -> Out CInt -> Out CSize -> Out CSize -> Out CDouble -> IO HErr_t
+-- h5p_set_mdc_config :: HId_t -> In H5AC_cache_config_t -> IO HErr_t
+-- h5p_get_mdc_config :: HId_t -> Out H5AC_cache_config_t -> IO HErr_t
+-- h5p_set_gc_references :: HId_t -> CUInt -> IO HErr_t
+-- h5p_get_gc_references :: HId_t -> Out CUInt -> IO HErr_t
+-- h5p_set_meta_block_size :: HId_t -> HSize_t -> IO HErr_t
+-- h5p_get_meta_block_size :: HId_t -> Out HSize_t -> IO HErr_t
+-- h5p_set_sieve_buf_size :: HId_t -> CSize -> IO HErr_t
+-- h5p_get_sieve_buf_size :: HId_t -> Out CSize -> IO HErr_t
+-- h5p_set_small_data_block_size :: HId_t -> HSize_t -> IO HErr_t
+-- h5p_get_small_data_block_size :: HId_t -> Out HSize_t -> IO HErr_t
+-- h5p_set_libver_bounds :: HId_t -> H5F_libver_t -> H5F_libver_t -> IO HErr_t
+-- h5p_get_libver_bounds :: HId_t -> Out H5F_libver_t -> Out H5F_libver_t -> IO HErr_t
+-- h5p_set_elink_file_cache_size :: HId_t -> CUInt -> IO HErr_t
+-- h5p_get_elink_file_cache_size :: HId_t -> Out CUInt -> IO HErr_t
diff --git a/src/Bindings/HDF5/PropertyList/FCPL.hs b/src/Bindings/HDF5/PropertyList/FCPL.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/PropertyList/FCPL.hs
@@ -0,0 +1,132 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module Bindings.HDF5.PropertyList.FCPL
+    ( module Bindings.HDF5.PropertyList.GCPL
+
+    , FCPL
+    , FileCreationPropertyList
+
+    , setUserblock
+    , getUserblock
+
+    , setSizes
+    , getSizes
+
+    , setSymK
+    , getSymK
+
+    , setIstoreK
+    , getIstoreK
+
+    , setSharedMesgNIndexes
+    , getSharedMesgNIndexes
+
+    , setSharedMesgIndex
+    , getSharedMesgIndex
+
+    , setSharedMesgPhaseChange
+    , getSharedMesgPhaseChange
+    ) where
+
+import Bindings.HDF5.Core
+import Bindings.HDF5.Error
+import Bindings.HDF5.PropertyList.GCPL
+import Bindings.HDF5.Raw.H5P
+import Data.Maybe
+import Foreign.C.Types
+import Foreign.Ptr.Conventions
+
+newtype FCPL = FCPL GCPL
+    deriving (Eq, HId, FromHId, HDFResultType, PropertyListOrClass, ObjectCreationPropertyList, GroupCreationPropertyList)
+
+instance PropertyList FCPL where
+    staticPlistClass = Tagged fileCreate
+
+class GroupCreationPropertyList t => FileCreationPropertyList t where
+instance FileCreationPropertyList FCPL
+
+-- TODO: figure out what the Out ptrs here represent.  Are they arrays?
+-- getVersion :: FileCreationPropertyList fcpl => fcpl -> ...
+
+setUserblock :: FileCreationPropertyList fcpl => fcpl -> HSize -> IO ()
+setUserblock fcpl sz =
+    withErrorCheck_ $
+        h5p_set_userblock (hid fcpl) (hSize sz)
+
+getUserblock :: FileCreationPropertyList fcpl => fcpl -> IO HSize
+getUserblock fcpl =
+    fmap HSize $
+        withOut_ $ \sz ->
+            withErrorCheck_ $
+                h5p_get_userblock (hid fcpl) sz
+
+setSizes :: FileCreationPropertyList fcpl => fcpl -> CSize -> CSize -> IO ()
+setSizes fcpl sizeof_addr sizeof_size =
+    withErrorCheck_ $
+        h5p_set_sizes (hid fcpl) sizeof_addr sizeof_size
+
+getSizes :: FileCreationPropertyList fcpl => fcpl -> IO (CSize, CSize)
+getSizes fcpl =
+    withOut $ \sizeof_addr ->
+        withOut_ $ \sizeof_size ->
+            withErrorCheck_ $
+                h5p_get_sizes (hid fcpl) sizeof_addr sizeof_size
+
+setSymK :: FileCreationPropertyList fcpl => fcpl -> Maybe CUInt -> Maybe CUInt -> IO ()
+setSymK fcpl mbIK mbLK =
+    withErrorCheck_ $
+        h5p_set_sym_k (hid fcpl) (fromMaybe 0 mbIK) (fromMaybe 0 mbLK)
+
+getSymK :: FileCreationPropertyList fcpl => fcpl -> IO (CUInt, CUInt)
+getSymK fcpl =
+    withOut $ \ik ->
+        withOut_ $ \lk ->
+            withErrorCheck_ $
+                h5p_get_sym_k (hid fcpl) ik lk
+
+setIstoreK :: FileCreationPropertyList fcpl => fcpl -> CUInt -> IO ()
+setIstoreK fcpl ik =
+    withErrorCheck_ $
+        h5p_set_istore_k (hid fcpl) ik
+
+getIstoreK :: FileCreationPropertyList fcpl => fcpl -> IO CUInt
+getIstoreK fcpl =
+    withOut_ $ \ik ->
+        withErrorCheck_ $
+            h5p_get_istore_k (hid fcpl) ik
+
+setSharedMesgNIndexes :: FileCreationPropertyList fcpl => fcpl -> CUInt -> IO ()
+setSharedMesgNIndexes fcpl nIndexes =
+    withErrorCheck_ $
+        h5p_set_shared_mesg_nindexes (hid fcpl) nIndexes
+
+getSharedMesgNIndexes :: FileCreationPropertyList fcpl => fcpl -> IO CUInt
+getSharedMesgNIndexes fcpl =
+    withOut_ $ \nIndexes ->
+        withErrorCheck_ $
+            h5p_get_shared_mesg_nindexes (hid fcpl) nIndexes
+
+-- TODO: figure out what, if any, constants apply for mesgTypeFlags
+setSharedMesgIndex :: FileCreationPropertyList fcpl => fcpl -> CUInt -> CUInt -> CUInt -> IO ()
+setSharedMesgIndex fcpl indexNum mesgTypeFlags minMesgSize =
+    withErrorCheck_ $
+        h5p_set_shared_mesg_index (hid fcpl) indexNum mesgTypeFlags minMesgSize
+
+getSharedMesgIndex :: FileCreationPropertyList fcpl => fcpl -> CUInt -> IO (CUInt, CUInt)
+getSharedMesgIndex fcpl indexNum =
+    withOut $ \mesgTypeFlags ->
+        withOut_ $ \minMesgSize ->
+            withErrorCheck_ $
+                h5p_get_shared_mesg_index (hid fcpl) indexNum mesgTypeFlags minMesgSize
+
+setSharedMesgPhaseChange :: FileCreationPropertyList fcpl => fcpl -> CUInt -> CUInt -> IO ()
+setSharedMesgPhaseChange fcpl maxList minBTree =
+    withErrorCheck_ $
+        h5p_set_shared_mesg_phase_change (hid fcpl) maxList minBTree
+
+getSharedMesgPhaseChange :: FileCreationPropertyList fcpl => fcpl -> IO (CUInt, CUInt)
+getSharedMesgPhaseChange fcpl =
+    withOut $ \maxList ->
+        withOut_ $ \minBTree ->
+            withErrorCheck_ $
+                h5p_get_shared_mesg_phase_change (hid fcpl) maxList minBTree
+
diff --git a/src/Bindings/HDF5/PropertyList/FMPL.hs b/src/Bindings/HDF5/PropertyList/FMPL.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/PropertyList/FMPL.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module Bindings.HDF5.PropertyList.FMPL
+    ( module Bindings.HDF5.PropertyList
+
+    , FMPL
+    , FileMountPropertyList
+    ) where
+
+import Bindings.HDF5.Core
+import Bindings.HDF5.PropertyList
+
+class PropertyList t => FileMountPropertyList t where
+newtype FMPL = FMPL PropertyListID
+    deriving (Eq, HId, FromHId, HDFResultType, PropertyListOrClass)
+instance PropertyList FMPL where
+    staticPlistClass = Tagged fileMount
+instance FileMountPropertyList FMPL
diff --git a/src/Bindings/HDF5/PropertyList/GAPL.hs b/src/Bindings/HDF5/PropertyList/GAPL.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/PropertyList/GAPL.hs
@@ -0,0 +1,21 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module Bindings.HDF5.PropertyList.GAPL
+    ( module Bindings.HDF5.PropertyList.LAPL
+
+    , GAPL
+    , GroupAccessPropertyList
+
+    ) where
+
+import Bindings.HDF5.Core
+import Bindings.HDF5.PropertyList.LAPL
+
+class LinkAccessPropertyList t => GroupAccessPropertyList t where
+newtype GAPL = GAPL LAPL
+    deriving (Eq, HId, FromHId, HDFResultType, PropertyListOrClass, LinkAccessPropertyList)
+instance PropertyList GAPL where
+    staticPlistClass = Tagged groupAccess
+instance GroupAccessPropertyList GAPL
+
+-- TODO: implement functions
+
diff --git a/src/Bindings/HDF5/PropertyList/GCPL.hs b/src/Bindings/HDF5/PropertyList/GCPL.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/PropertyList/GCPL.hs
@@ -0,0 +1,99 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module Bindings.HDF5.PropertyList.GCPL
+    ( module Bindings.HDF5.PropertyList.OCPL
+
+    , GCPL
+    , GroupCreationPropertyList
+
+    , setLocalHeapSizeHint
+    , getLocalHeapSizeHint
+
+    , setLinkPhaseChange
+    , getLinkPhaseChange
+
+    , getEstLinkInfo
+    , setEstLinkInfo
+
+    , CreationOrder(..)
+    , setLinkCreationOrder
+    , getLinkCreationOrder
+    ) where
+
+import Bindings.HDF5.Core
+import Bindings.HDF5.Error
+import Bindings.HDF5.PropertyList.OCPL
+import Bindings.HDF5.Raw.H5P
+import Foreign.C.Types
+import Foreign.Ptr.Conventions
+
+newtype GCPL = GCPL OCPL
+    deriving (Eq, HId, FromHId, HDFResultType, PropertyListOrClass, ObjectCreationPropertyList)
+
+instance PropertyList GCPL where
+    staticPlistClass = Tagged groupCreate
+
+class ObjectCreationPropertyList t => GroupCreationPropertyList t where
+instance GroupCreationPropertyList GCPL
+
+setLocalHeapSizeHint :: GroupCreationPropertyList gcpl => gcpl -> CSize -> IO ()
+setLocalHeapSizeHint gcpl sz =
+    withErrorCheck_ $
+        h5p_set_local_heap_size_hint (hid gcpl) sz
+
+getLocalHeapSizeHint :: GroupCreationPropertyList gcpl => gcpl -> IO CSize
+getLocalHeapSizeHint gcpl =
+    withOut_ $ \sz ->
+        withErrorCheck_ $
+            h5p_get_local_heap_size_hint (hid gcpl) sz
+
+setLinkPhaseChange :: GroupCreationPropertyList gcpl => gcpl -> CUInt -> CUInt -> IO ()
+setLinkPhaseChange gcpl maxCompact minDense =
+    withErrorCheck_ $
+        h5p_set_link_phase_change (hid gcpl) maxCompact minDense
+
+getLinkPhaseChange :: GroupCreationPropertyList gcpl => gcpl -> IO (CUInt, CUInt)
+getLinkPhaseChange gcpl =
+    withOut $ \maxCompact ->
+        withOut_ $ \minDense ->
+            withErrorCheck_ $
+                h5p_get_link_phase_change (hid gcpl) maxCompact minDense
+
+setEstLinkInfo :: GroupCreationPropertyList gcpl => gcpl -> CUInt -> CUInt -> IO ()
+setEstLinkInfo gcpl estNumEntries estNameLen =
+    withErrorCheck_ $
+        h5p_set_est_link_info (hid gcpl) estNumEntries estNameLen
+
+getEstLinkInfo :: GroupCreationPropertyList gcpl => gcpl -> IO (CUInt, CUInt)
+getEstLinkInfo gcpl =
+    withOut $ \estNumEntries ->
+        withOut_ $ \estNameLen ->
+            withErrorCheck_ $
+                h5p_get_est_link_info (hid gcpl) estNumEntries estNameLen
+
+data CreationOrder
+    = Tracked
+    | Indexed
+    deriving (Eq, Ord, Bounded, Enum, Read, Show)
+
+creationOrderCode :: Num a => CreationOrder -> a
+creationOrderCode Tracked = h5p_CRT_ORDER_TRACKED
+creationOrderCode Indexed = h5p_CRT_ORDER_INDEXED
+
+creationOrder :: (Eq a, Num a, Show a) => a -> CreationOrder
+creationOrder c
+    | c == h5p_CRT_ORDER_TRACKED    = Tracked
+    | c == h5p_CRT_ORDER_INDEXED    = Indexed
+    | otherwise = error ("Unknown CreationOrder code: " ++ show c)
+
+setLinkCreationOrder :: GroupCreationPropertyList gcpl => gcpl -> CreationOrder -> IO ()
+setLinkCreationOrder gcpl crtOrderFlags =
+    withErrorCheck_ $
+        h5p_set_link_creation_order (hid gcpl) (creationOrderCode crtOrderFlags)
+
+getLinkCreationOrder :: GroupCreationPropertyList gcpl => gcpl -> IO CreationOrder
+getLinkCreationOrder gcpl =
+    fmap creationOrder $
+        withOut_ $ \crtOrderFlags ->
+            withErrorCheck_ $
+             h5p_get_link_creation_order (hid gcpl) crtOrderFlags
+
diff --git a/src/Bindings/HDF5/PropertyList/LAPL.hs b/src/Bindings/HDF5/PropertyList/LAPL.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/PropertyList/LAPL.hs
@@ -0,0 +1,86 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module Bindings.HDF5.PropertyList.LAPL
+    ( module Bindings.HDF5.PropertyList
+
+    , LAPL
+    , LinkAccessPropertyList
+
+    , setNLinks
+    , getNLinks
+
+    , setELinkPrefix
+    , getELinkPrefix
+
+    , setELinkFAPL
+    , getELinkFAPL
+
+    , setELinkAccFlags
+    , getELinkAccFlags
+    ) where
+
+import Bindings.HDF5.Raw.H5P
+import Bindings.HDF5.Core
+import Bindings.HDF5.Error
+import Bindings.HDF5.PropertyList
+import Bindings.HDF5.PropertyList.FAPL
+
+import qualified Data.ByteString as BS
+import Foreign.Ptr.Conventions
+import Foreign.C.Types
+
+class PropertyList t => LinkAccessPropertyList t where
+newtype LAPL = LAPL PropertyListID
+    deriving (Eq, HId, FromHId, HDFResultType, PropertyListOrClass)
+instance PropertyList LAPL where
+    staticPlistClass = Tagged linkAccess
+instance LinkAccessPropertyList LAPL
+
+setNLinks :: LinkAccessPropertyList lapl => lapl -> CSize -> IO ()
+setNLinks lapl nLinks =
+    withErrorCheck_ $
+        h5p_set_nlinks (hid lapl) nLinks
+
+getNLinks :: LinkAccessPropertyList lapl => lapl -> IO CSize
+getNLinks lapl =
+    withOut_ $ \nLinks ->
+        withErrorCheck_ $
+            h5p_get_nlinks (hid lapl) nLinks
+
+setELinkPrefix :: LinkAccessPropertyList lapl => lapl -> BS.ByteString -> IO ()
+setELinkPrefix lapl prefix =
+    withErrorCheck_ $
+        BS.useAsCString prefix $ \cprefix ->
+            h5p_set_elink_prefix (hid lapl) cprefix
+
+getELinkPrefix :: LinkAccessPropertyList lapl => lapl -> IO BS.ByteString
+getELinkPrefix lapl =
+    withOutByteString $ \buf bufSz ->
+        withErrorWhen (< 0) $
+            h5p_get_elink_prefix (hid lapl) buf bufSz
+
+getELinkFAPL :: LinkAccessPropertyList lapl => lapl -> IO FAPL
+getELinkFAPL lapl =
+    fmap uncheckedFromHId $
+        withErrorCheck $
+            h5p_get_elink_fapl (hid lapl)
+
+setELinkFAPL :: LinkAccessPropertyList lapl => lapl -> FAPL -> IO ()
+setELinkFAPL lapl fapl =
+    withErrorCheck_ $
+        h5p_set_elink_fapl (hid lapl) (hid fapl)
+
+-- TODO: an enumeration type for these flags
+setELinkAccFlags :: LinkAccessPropertyList lapl => lapl -> CUInt -> IO ()
+setELinkAccFlags lapl flags =
+    withErrorCheck_ $
+        h5p_set_elink_acc_flags (hid lapl) flags
+
+getELinkAccFlags :: LinkAccessPropertyList lapl => lapl -> IO CUInt
+getELinkAccFlags lapl =
+    withOut_ $ \flags ->
+        withErrorCheck_ $
+            h5p_get_elink_acc_flags (hid lapl) flags
+
+-- type ELinkTraverse = BS.ByteString -> BS.ByteString -> BS.ByteString -> BS.ByteString -> Ptr CUInt -> FAPL -> IO ()
+-- h5p_set_elink_cb :: HId_t -> H5L_elink_traverse_t a -> Ptr a -> IO HErr_t
+-- h5p_get_elink_cb :: HId_t -> Out (H5L_elink_traverse_t a) -> Out (Ptr a) -> IO HErr_t
diff --git a/src/Bindings/HDF5/PropertyList/LCPL.hs b/src/Bindings/HDF5/PropertyList/LCPL.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/PropertyList/LCPL.hs
@@ -0,0 +1,21 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module Bindings.HDF5.PropertyList.LCPL
+    ( module Bindings.HDF5.PropertyList.STRCPL
+
+    , LCPL
+    , LinkCreationPropertyList
+
+    ) where
+
+import Bindings.HDF5.Core
+import Bindings.HDF5.PropertyList.STRCPL
+
+class StringCreationPropertyList t => LinkCreationPropertyList t where
+newtype LCPL = LCPL STRCPL
+    deriving (Eq, HId, FromHId, HDFResultType, PropertyListOrClass, StringCreationPropertyList)
+instance PropertyList LCPL where
+    staticPlistClass = Tagged linkCreate
+instance LinkCreationPropertyList LCPL
+
+-- TODO: implement functions
+
diff --git a/src/Bindings/HDF5/PropertyList/OCPL.hs b/src/Bindings/HDF5/PropertyList/OCPL.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/PropertyList/OCPL.hs
@@ -0,0 +1,132 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module Bindings.HDF5.PropertyList.OCPL
+    ( module Bindings.HDF5.PropertyList
+
+    , OCPL
+    , ObjectCreationPropertyList
+
+    , setAttrPhaseChange
+    , getAttrPhaseChange
+
+    , setAttrCreationOrder
+    , getAttrCreationOrder
+
+    , setObjTrackTimes
+    , getObjTrackTimes
+
+    , modifyFilter
+    , setFilter
+
+    , getNFilters
+
+    , allFiltersAvail
+
+    , removeFilter
+
+    , setDeflate
+
+    , setFletcher32
+    ) where
+
+import Bindings.HDF5.Raw.H5
+import Bindings.HDF5.Raw.H5P
+import Bindings.HDF5.Raw.H5Z
+import Bindings.HDF5.Core
+import Bindings.HDF5.Error
+import Bindings.HDF5.PropertyList
+
+import qualified Data.Vector.Storable as SV
+import Foreign.C
+import Foreign.Ptr.Conventions
+
+class PropertyList t => ObjectCreationPropertyList t where
+newtype OCPL = OCPL PropertyListID
+    deriving (Eq, HId, FromHId, HDFResultType, PropertyListOrClass)
+instance PropertyList OCPL where
+    staticPlistClass = Tagged objectCreate
+instance ObjectCreationPropertyList OCPL
+
+setAttrPhaseChange :: ObjectCreationPropertyList t => t -> CUInt -> CUInt -> IO ()
+setAttrPhaseChange plist max_compact min_dense =
+    withErrorCheck_ $
+        h5p_set_attr_phase_change (hid plist) max_compact min_dense
+
+getAttrPhaseChange :: ObjectCreationPropertyList t => t -> IO (CUInt, CUInt)
+getAttrPhaseChange plist =
+    withOut $ \max_compact ->
+        withOut_ $ \min_dense ->
+            withErrorCheck_ $
+                h5p_get_attr_phase_change (hid plist) max_compact min_dense
+
+setAttrCreationOrder :: ObjectCreationPropertyList t => t -> CUInt -> IO ()
+setAttrCreationOrder plist crt_order_flags =
+    withErrorCheck_ $
+        h5p_set_attr_creation_order (hid plist) crt_order_flags
+
+getAttrCreationOrder :: ObjectCreationPropertyList t => t -> IO CUInt
+getAttrCreationOrder plist =
+    withOut_ $ \crt_order_flags ->
+        withErrorCheck_ $
+            h5p_get_attr_creation_order (hid plist) crt_order_flags
+
+setObjTrackTimes :: ObjectCreationPropertyList t => t -> Bool -> IO ()
+setObjTrackTimes plist track_times =
+    withErrorCheck_ $
+        h5p_set_obj_track_times (hid plist) (HBool_t $ if track_times then 1 else 0)
+
+getObjTrackTimes :: ObjectCreationPropertyList t => t -> IO Bool
+getObjTrackTimes plist =
+    fmap (\(HBool_t x) -> x > 0) $
+        withOut_ $ \track_times ->
+            withErrorCheck_ $
+                h5p_get_obj_track_times (hid plist) track_times
+
+modifyFilter :: ObjectCreationPropertyList t => t -> H5Z_filter_t -> Bool -> SV.Vector CUInt -> IO ()
+modifyFilter plist filt optional cd_values =
+    withErrorCheck_ $
+        withInVector cd_values $ \ccd_values ->
+            h5p_modify_filter (hid plist) filt flags n_elmts ccd_values
+    where
+        flags
+            | optional  = h5z_FLAG_OPTIONAL
+            | otherwise = 0
+        n_elmts = fromIntegral (SV.length cd_values)
+
+setFilter :: ObjectCreationPropertyList t => t -> H5Z_filter_t -> Bool -> SV.Vector CUInt -> IO ()
+setFilter plist filt optional cd_values =
+    withErrorCheck_ $
+        withInVector cd_values $ \ccd_values ->
+            h5p_set_filter (hid plist) filt flags n_elmts ccd_values
+    where
+        flags
+            | optional  = h5z_FLAG_OPTIONAL
+            | otherwise = 0
+        n_elmts = fromIntegral (SV.length cd_values)
+
+getNFilters :: ObjectCreationPropertyList t => t -> IO CInt
+getNFilters plist =
+    withErrorWhen (< 0) $
+        h5p_get_nfilters (hid plist)
+
+-- getFilter :: ObjectCreationPropertyList t => t -> CUInt -> ...
+-- getFilterById
+
+allFiltersAvail :: ObjectCreationPropertyList t => t -> IO Bool
+allFiltersAvail plist =
+    htriToBool $
+        h5p_all_filters_avail (hid plist)
+
+removeFilter :: ObjectCreationPropertyList t => t -> H5Z_filter_t -> IO ()
+removeFilter plist filt =
+    withErrorCheck_ $
+        h5p_remove_filter (hid plist) filt
+
+setDeflate :: ObjectCreationPropertyList t => t -> CUInt -> IO ()
+setDeflate plist aggression =
+    withErrorCheck_ $
+        h5p_set_deflate (hid plist) aggression
+
+setFletcher32 :: ObjectCreationPropertyList t => t -> IO ()
+setFletcher32 plist =
+    withErrorCheck_ $
+        h5p_set_fletcher32 (hid plist)
diff --git a/src/Bindings/HDF5/PropertyList/OCPYPL.hs b/src/Bindings/HDF5/PropertyList/OCPYPL.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/PropertyList/OCPYPL.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module Bindings.HDF5.PropertyList.OCPYPL
+    ( module Bindings.HDF5.PropertyList
+
+    , OCPYPL
+    , ObjectCopyPropertyList
+    ) where
+
+import Bindings.HDF5.Core
+import Bindings.HDF5.PropertyList
+
+class PropertyList t => ObjectCopyPropertyList t where
+newtype OCPYPL = OCPYPL PropertyListID
+    deriving (Eq, HId, FromHId, HDFResultType, PropertyListOrClass)
+instance PropertyList OCPYPL where
+    staticPlistClass = Tagged objectCopy
+instance ObjectCopyPropertyList OCPYPL
diff --git a/src/Bindings/HDF5/PropertyList/STRCPL.hs b/src/Bindings/HDF5/PropertyList/STRCPL.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/PropertyList/STRCPL.hs
@@ -0,0 +1,21 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module Bindings.HDF5.PropertyList.STRCPL
+    ( module Bindings.HDF5.PropertyList
+
+    , STRCPL
+    , StringCreationPropertyList
+
+    ) where
+
+import Bindings.HDF5.Core
+import Bindings.HDF5.PropertyList
+
+class PropertyList t => StringCreationPropertyList t where
+newtype STRCPL = STRCPL PropertyListID
+    deriving (Eq, HId, FromHId, HDFResultType, PropertyListOrClass)
+instance PropertyList STRCPL where
+    staticPlistClass = Tagged stringCreate
+instance StringCreationPropertyList STRCPL
+
+-- TODO: implement functions
+
diff --git a/src/Bindings/HDF5/PropertyList/TAPL.hs b/src/Bindings/HDF5/PropertyList/TAPL.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/PropertyList/TAPL.hs
@@ -0,0 +1,21 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module Bindings.HDF5.PropertyList.TAPL
+    ( module Bindings.HDF5.PropertyList.LAPL
+
+    , TAPL
+    , DatatypeAccessPropertyList
+
+    ) where
+
+import Bindings.HDF5.Core
+import Bindings.HDF5.PropertyList.LAPL
+
+newtype TAPL = TAPL LAPL
+    deriving (Eq, HId, FromHId, HDFResultType, PropertyListOrClass, LinkAccessPropertyList)
+
+instance PropertyList TAPL where
+    staticPlistClass = Tagged datatypeAccess
+
+class LinkAccessPropertyList t => DatatypeAccessPropertyList t where
+instance DatatypeAccessPropertyList TAPL
+
diff --git a/src/Bindings/HDF5/PropertyList/TCPL.hs b/src/Bindings/HDF5/PropertyList/TCPL.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/PropertyList/TCPL.hs
@@ -0,0 +1,21 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module Bindings.HDF5.PropertyList.TCPL
+    ( module Bindings.HDF5.PropertyList.OCPL
+
+    , TCPL
+    , DatatypeCreationPropertyList
+
+    ) where
+
+import Bindings.HDF5.Core
+import Bindings.HDF5.PropertyList.OCPL
+
+newtype TCPL = TCPL OCPL
+    deriving (Eq, HId, FromHId, HDFResultType, PropertyListOrClass, ObjectCreationPropertyList)
+
+instance PropertyList TCPL where
+    staticPlistClass = Tagged datatypeCreate
+
+class ObjectCreationPropertyList t => DatatypeCreationPropertyList t where
+instance DatatypeCreationPropertyList TCPL
+
diff --git a/src/Bindings/HDF5/Raw.hs b/src/Bindings/HDF5/Raw.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw.hs
@@ -0,0 +1,32 @@
+{-# LANGUAGE CPP #-}
+module Bindings.HDF5.Raw (module X) where
+
+import Bindings.HDF5.Raw.H5 as X
+import Bindings.HDF5.Raw.H5A as X
+import Bindings.HDF5.Raw.H5AC as X
+import Bindings.HDF5.Raw.H5C as X
+import Bindings.HDF5.Raw.H5D as X
+import Bindings.HDF5.Raw.H5E as X
+import Bindings.HDF5.Raw.H5F as X
+import Bindings.HDF5.Raw.H5FD as X
+import Bindings.HDF5.Raw.H5FD.Core as X
+import Bindings.HDF5.Raw.H5FD.Family as X
+import Bindings.HDF5.Raw.H5FD.Log as X
+import Bindings.HDF5.Raw.H5FD.MPI as X
+import Bindings.HDF5.Raw.H5FD.Multi as X
+import Bindings.HDF5.Raw.H5FD.Sec2 as X
+import Bindings.HDF5.Raw.H5FD.StdIO as X
+#ifdef H5_HAVE_WINDOWS
+import Bindings.HDF5.Raw.H5FD.Windows as X
+#endif
+import Bindings.HDF5.Raw.H5FD.Direct as X
+import Bindings.HDF5.Raw.H5G as X
+import Bindings.HDF5.Raw.H5I as X
+import Bindings.HDF5.Raw.H5L as X
+import Bindings.HDF5.Raw.H5MM as X
+import Bindings.HDF5.Raw.H5O as X
+import Bindings.HDF5.Raw.H5P as X
+import Bindings.HDF5.Raw.H5R as X
+import Bindings.HDF5.Raw.H5S as X
+import Bindings.HDF5.Raw.H5T as X
+import Bindings.HDF5.Raw.H5Z as X
diff --git a/src/Bindings/HDF5/Raw/H5.hsc b/src/Bindings/HDF5/Raw/H5.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/H5.hsc
@@ -0,0 +1,281 @@
+module Bindings.HDF5.Raw.H5 where
+#include <bindings.h>
+#include <H5public.h>
+
+import Data.Bits
+import Data.Int
+import Data.Version
+import Data.Word
+import Foreign.C.Types
+import Foreign.Ptr
+import Foreign.Storable
+
+import Foreign.Ptr.Conventions
+
+-- *Version numbers
+
+-- |For major interface/format changes
+#num H5_VERS_MAJOR
+
+-- |For minor interface/format changes
+#num H5_VERS_MINOR
+
+-- |For tweaks, bug-fixes, or development
+#num H5_VERS_RELEASE
+
+-- |For pre-releases like snap0
+#str H5_VERS_SUBRELEASE
+
+-- |'h5_VERS_MAJOR', et al., wrapped up as a 'Version'
+vers :: Version
+vers = Version
+    [ h5_VERS_MAJOR
+    , h5_VERS_MINOR
+    , h5_VERS_RELEASE
+    ]
+    (filter (not.null) [ h5_VERS_SUBRELEASE ])
+
+-- |Full version string
+#str H5_VERS_INFO
+
+-- |Check that the HDF5 library that is linked with the current executable is
+-- the same version that these bindings were compiled against.  Returns 0 on
+-- success, calls abort() on failure.
+#cinline H5check, <herr_t>
+
+-- * Types and constants
+
+-- |Status return values.  Failed integer functions in HDF5 result almost
+-- always in a negative value (unsigned failing functions sometimes return
+-- zero for failure) while successfull return is non-negative (often zero).
+-- The negative failure value is most commonly -1, but don't bet on it.  The
+-- proper way to detect failure is something like:
+--
+-- @
+-- if((dset = H5Dopen2(file, name)) < 0)
+--    fprintf(stderr, "unable to open the requested dataset\n");
+-- @
+#newtype herr_t, Eq, Ord, Num, Real, Bits, Enum, Bounded, Integral
+
+-- |Boolean type.  Successful return values are zero (false) or positive
+-- (true). The typical true value is 1 but don't bet on it.  Boolean
+-- functions cannot fail.  Functions that return `htri_t' however return zero
+-- (false), positive (true), or negative (failure). The proper way to test
+-- for truth from a htri_t function is:
+--
+-- @
+--  if ((retval = H5Tcommitted(type))>0) {
+--    printf("data type is committed\n");
+--  } else if (!retval) {
+--    printf("data type is not committed\n");
+--  } else {
+--    printf("error determining whether data type is committed\n");
+--  }
+-- @
+#newtype hbool_t
+
+instance Eq HBool_t where
+    HBool_t x == HBool_t y
+        = (x /= 0) == (y /= 0)
+
+#newtype htri_t
+
+instance Eq HTri_t where
+    HTri_t x == HTri_t y
+        = compare x 0 == compare y 0
+
+-- |C signed size type.  This is a semi-standard POSIX type that isn't in
+-- the "Foreign.C.Types" module.  It is in "System.Posix.Types", but I'm not
+-- sure whether that module is available on all platforms.
+#newtype ssize_t, Eq, Ord, Num, Bits, Enum, Bounded, Real, Integral
+
+h5_SIZEOF_SSIZE_T :: CSize
+h5_SIZEOF_SSIZE_T = #const H5_SIZEOF_SSIZE_T
+
+#newtype hsize_t, Eq, Ord, Num, Bits, Enum, Bounded, Real, Integral
+#newtype hssize_t, Eq, Ord, Num, Bits, Enum, Bounded, Real, Integral
+
+h5_SIZEOF_HSIZE_T, h5_SIZEOF_HSSIZE_T :: CSize
+h5_SIZEOF_HSIZE_T  = #const H5_SIZEOF_HSIZE_T
+h5_SIZEOF_HSSIZE_T = #const H5_SIZEOF_HSSIZE_T
+
+#if H5_VERSION_GE(1,10,0)
+
+hSIZE_UNDEF :: HSize_t
+hSIZE_UNDEF = #const HSIZE_UNDEF
+
+#endif
+
+#newtype haddr_t, Eq, Ord, Num, Bits, Enum, Bounded, Real, Integral
+
+hADDR_UNDEF :: HAddr_t
+hADDR_UNDEF = HAddr_t (#const HADDR_UNDEF)
+
+h5_SIZEOF_HADDR_T :: CSize
+h5_SIZEOF_HADDR_T = #const H5_SIZEOF_HADDR_T
+
+#str H5_PRINTF_HADDR_FMT
+
+hADDR_MAX :: HAddr_t
+hADDR_MAX = HAddr_t (#const HADDR_MAX)
+
+-- |Common iteration orders
+#newtype H5_iter_order_t
+
+-- |Unknown order
+#newtype_const H5_iter_order_t, H5_ITER_UNKNOWN
+
+-- |Increasing order
+#newtype_const H5_iter_order_t, H5_ITER_INC
+
+-- |Decreasing order
+#newtype_const H5_iter_order_t, H5_ITER_DEC
+
+-- |No particular order, whatever is fastest
+#newtype_const H5_iter_order_t, H5_ITER_NATIVE
+
+-- |Number of iteration orders
+#num H5_ITER_N
+
+-- |Iteration callback return value indicating that iteration should stop
+-- and report an error.
+#newtype_const herr_t, H5_ITER_ERROR
+
+-- |Iteration callback return value indicating that iteration should continue.
+#newtype_const herr_t, H5_ITER_CONT
+
+-- |Iteration callback return value indicating that iteration should stop
+-- without error.
+--
+-- Actually, any postive value will cause the iterator to stop and pass back
+-- that positive value to the function that called the iterator
+#newtype_const herr_t, H5_ITER_STOP
+
+-- |The types of indices on links in groups/attributes on objects.
+-- Primarily used for \"\<do\> \<foo\> by index\" routines and for iterating over
+-- links in groups/attributes on objects.
+#newtype H5_index_t
+
+-- |Unknown index type
+#newtype_const H5_index_t, H5_INDEX_UNKNOWN
+
+-- |Index on names
+#newtype_const H5_index_t, H5_INDEX_NAME
+
+-- |Index on creation order
+#newtype_const H5_index_t, H5_INDEX_CRT_ORDER
+
+-- |Number of indices defined
+#num H5_INDEX_N
+
+-- |Storage info struct used by 'H5O_info_t' and 'H5F_info_t'
+#starttype H5_ih_info_t
+#field index_size , <hsize_t>
+#field heap_size  , <hsize_t>
+#stoptype
+
+-- *Functions in H5.c
+
+-- |Initialize the library.  This is normally called automatically, but if you
+-- find that an HDF5 library function is failing inexplicably, then try
+-- calling this function first.
+--
+-- Return: Non-negative on success/Negative on failure
+--
+-- > herr_t H5open(void);
+#ccall H5open                   , IO <herr_t>
+
+-- |Terminate the library and release all resources.
+--
+-- Return: Non-negative on success/Negative on failure
+--
+-- > herr_t H5close(void);
+#ccall H5close                  , IO <herr_t>
+
+-- |Indicates that the library is not to clean up after itself
+-- when the application exits by calling exit() or returning
+-- from main().  This function must be called before any other
+-- HDF5 function or constant is used or it will have no effect.
+--
+-- If this function is used then certain memory buffers will not
+-- be de-allocated nor will open files be flushed automatically.
+-- The application may still call H5close() explicitly to
+-- accomplish these things.
+--
+-- Return:  non-negative on success,
+--          negative if this function is called more than
+--          once or if it is called too late.
+--
+-- > herr_t H5dont_atexit(void);
+#ccall H5dont_atexit            , IO <herr_t>
+
+-- |Walks through all the garbage collection routines for the
+-- library, which are supposed to free any unused memory they have
+-- allocated.
+--
+-- These should probably be registered dynamicly in a linked list of
+-- functions to call, but there aren't that many right now, so we
+-- hard-wire them...
+--
+-- Return: non-negative on success, negative on failure
+--
+-- > herr_t H5garbage_collect(void);
+#ccall H5garbage_collect        , IO <herr_t>
+
+-- |Sets limits on the different kinds of free lists.  Setting a value
+-- of -1 for a limit means no limit of that type.  These limits are global
+-- for the entire library.  Each \"global\" limit only applies to free lists
+-- of that type, so if an application sets a limit of 1 MB on each of the
+-- global lists, up to 3 MB of total storage might be allocated (1MB on
+-- each of regular, array and block type lists).
+--
+-- The settings for block free lists are duplicated to factory free lists.
+-- Factory free list limits cannot be set independently currently.
+--
+-- Parameters:
+--
+-- [@ reg_global_lim :: CInt @]  The limit on all \"regular\" free list memory used
+--
+-- [@ reg_list_lim   :: CInt @]  The limit on memory used in each \"regular\" free list
+--
+-- [@ arr_global_lim :: CInt @]  The limit on all \"array\" free list memory used
+--
+-- [@ arr_list_lim   :: CInt @]  The limit on memory used in each \"array\" free list
+--
+-- [@ blk_global_lim :: CInt @]  The limit on all \"block\" free list memory used
+--
+-- [@ blk_list_lim   :: CInt @]  The limit on memory used in each \"block\" free list
+--
+-- Return: non-negative on success, negative on failure
+--
+-- > herr_t H5set_free_list_limits (int reg_global_lim, int reg_list_lim,
+-- >         int arr_global_lim, int arr_list_lim, int blk_global_lim,
+-- >         int blk_list_lim);
+#ccall H5set_free_list_limits   , CInt -> CInt -> CInt -> CInt -> CInt -> CInt -> IO <herr_t>
+
+-- |Returns the library version numbers through arguments. MAJNUM
+-- will be the major revision number of the library, MINNUM the
+-- minor revision number, and RELNUM the release revision number.
+--
+-- Note: When printing an HDF5 version number it should be printed as
+--
+-- > printf("%u.%u.%u", maj, min, rel)		or
+-- > printf("version %u.%u release %u", maj, min, rel)
+--
+-- Return:	Non-negative on success/Negative on failure
+--
+-- > herr_t H5get_libversion(unsigned *majnum, unsigned *minnum,
+-- >         unsigned *relnum);
+#ccall H5get_libversion         , Out CUInt -> Out CUInt -> Out CUInt -> IO <herr_t>
+
+-- |Purpose:	Verifies that the arguments match the version numbers
+-- compiled into the library.  This function is intended to be
+-- called from user to verify that the versions of header files
+-- compiled into the application match the version of the hdf5
+-- library.
+--
+-- Return: Success: 0, Failure: calls abort()
+--
+-- > herr_t H5check_version(unsigned majnum, unsigned minnum,
+-- >         unsigned relnum);
+#ccall H5check_version          , CUInt -> CUInt -> CUInt -> IO <herr_t>
diff --git a/src/Bindings/HDF5/Raw/H5A.hsc b/src/Bindings/HDF5/Raw/H5A.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/H5A.hsc
@@ -0,0 +1,639 @@
+module Bindings.HDF5.Raw.H5A where
+#include <bindings.h>
+#include <H5Apublic.h>
+
+import Foreign.C.String
+import Foreign.C.Types
+import Foreign.Ptr
+import Foreign.Storable
+
+import Bindings.HDF5.Raw.H5
+import Bindings.HDF5.Raw.H5I -- IDs
+import Bindings.HDF5.Raw.H5O -- Object Headers
+import Bindings.HDF5.Raw.H5T -- Datatypes
+import Foreign.Ptr.Conventions
+
+-- |Information struct for attribute (for 'h5a_get_info'/'h5a_get_info_by_idx')
+#starttype H5A_info_t
+-- |Indicate if creation order is valid
+#field corder_valid,    <hbool_t>
+-- |Creation order
+#field corder,          <H5O_msg_crt_idx_t>
+-- |Character set of attribute name
+#field cset,            <H5T_cset_t>
+-- |Size of raw data
+#field data_size,       <hsize_t>
+#stoptype
+
+
+-- | Typedef for 'h5a_iterate2' callbacks.
+--
+-- @
+--  typedef herr_t (*H5A_operator2_t)(hid_t location_id/*in*/,
+--     const char *attr_name/*in*/, const H5A_info_t *ainfo/*in*/, void *op_data/*in,out*/);
+-- @
+type H5A_operator2_t a = FunPtr (HId_t -> CString -> In H5A_info_t -> InOut a -> IO HErr_t)
+
+-- * Public function prototypes
+
+-- |Creates an attribute on an object
+--
+-- Parameters:
+--
+-- [@ loc_id    :: HId_t    @]  Object (dataset or group) to be attached to
+--
+-- [@ attr_name :: CString  @]  Name of attribute to locate and open
+--
+-- [@ type_id   :: HId_t    @]  ID of datatype for attribute
+--
+-- [@ space_id  :: HId_t    @]  ID of dataspace for attribute
+--
+-- [@ acpl_id   :: HId_t    @]  ID of creation property list (currently not used)
+--
+-- [@ aapl_id   :: HId_t    @]  Attribute access property list
+--
+-- Returns non-negative on success / negative on failure
+--
+-- This function creates an attribute which is attached to the object
+-- specified with 'loc_id'.  The name specified with 'attr_name' for
+-- each attribute for an object must be unique for that object.  The 'type_id'
+-- and 'space_id' are created with the H5T and H5S interfaces respectively.
+-- The 'aapl_id' property list is currently unused, but will be used in the
+-- future for optional attribute access properties.  The attribute ID returned
+-- from this function must be released with 'h5a_close' or resource leaks will
+-- develop.
+--
+-- > hid_t   H5Acreate2(hid_t loc_id, const char *attr_name, hid_t type_id,
+-- >     hid_t space_id, hid_t acpl_id, hid_t aapl_id);
+#ccall H5Acreate2, <hid_t> -> CString -> <hid_t> -> <hid_t> -> <hid_t> -> <hid_t> -> IO <hid_t>
+
+-- |Creates an attribute on an object
+--
+-- Parameters:
+--
+-- [@ loc_id    :: HId_t    @]  Object (dataset or group) to be attached to
+-- [@ obj_name  :: CString  @]  Name of object relative to location
+-- [@ attr_name :: CString  @]  Name of attribute to locate and open
+-- [@ type_id   :: HId_t    @]  ID of datatype for attribute
+-- [@ space_id  :: HId_t    @]  ID of dataspace for attribute
+-- [@ acpl_id   :: HId_t    @]  ID of creation property list (currently not used)
+-- [@ aapl_id   :: HId_t    @]  Attribute access property list
+-- [@ lapl_id   :: HId_t    @]  Link access property list
+--
+-- Returns non-negative on success / negative on failure
+--
+-- This function creates an attribute which is attached to the object
+-- specified with 'loc_id/obj_name'.  The name specified with 'attr_name' for
+-- each attribute for an object must be unique for that object.  The 'type_id'
+-- and 'space_id' are created with the H5T and H5S interfaces respectively.
+-- The 'aapl_id' property list is currently unused, but will be used in the
+-- future for optional attribute access properties.  The attribute ID returned
+-- from this function must be released with h5a_close or resource leaks will
+-- develop.
+--
+-- > hid_t   H5Acreate_by_name(hid_t loc_id, const char *obj_name, const char *attr_name,
+-- >     hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id, hid_t lapl_id);
+#ccall H5Acreate_by_name, <hid_t> -> CString -> CString -> <hid_t> -> <hid_t> -> <hid_t> -> <hid_t> -> <hid_t> -> IO <hid_t>
+
+-- |Opens an attribute for an object by looking up the attribute name
+--
+-- Parameters:
+--
+-- [@ loc_id    :: HId_t   @]   Object that attribute is attached to
+--
+-- [@ attr_name :: CString @]   Name of attribute to locate and open
+--
+-- [@ aapl_id   :: HId_t   @]   Attribute access property list
+--
+-- Returns ID of attribute on success, negative on failure
+--
+-- This function opens an existing attribute for access.  The attribute
+-- name specified is used to look up the corresponding attribute for the
+-- object.  The attribute ID returned from this function must be released with
+-- 'h5a_close' or resource leaks will develop.
+--
+-- > hid_t   H5Aopen(hid_t obj_id, const char *attr_name, hid_t aapl_id);
+#ccall H5Aopen, <hid_t> -> CString -> <hid_t> -> IO <hid_t>
+
+-- |Opens an attribute for an object by looking up the attribute name
+--
+-- Parameters:
+--
+-- [@ loc_id    :: HId_t   @]   Object that attribute is attached to
+--
+-- [@ obj_name  :: CString @]   Name of object relative to location
+--
+-- [@ attr_name :: CString @]   Name of attribute to locate and open
+--
+-- [@ aapl_id   :: HId_t   @]   Attribute access property list
+--
+-- [@ lapl_id   :: HId_t   @]   Link access property list
+--
+-- Returns ID of attribute on success, negative on failure
+--
+-- This function opens an existing attribute for access.  The attribute
+-- name specified is used to look up the corresponding attribute for the
+-- object.  The attribute ID returned from this function must be released with
+-- 'h5a_close' or resource leaks will develop.
+--
+-- > hid_t   H5Aopen_by_name(hid_t loc_id, const char *obj_name,
+-- >     const char *attr_name, hid_t aapl_id, hid_t lapl_id);
+#ccall H5Aopen_by_name, <hid_t> -> CString -> CString -> <hid_t> -> <hid_t> -> IO <hid_t>
+
+-- hid_t   H5Aopen_by_idx(hid_t loc_id, const char *obj_name,
+--     H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t aapl_id,
+--     hid_t lapl_id);
+#ccall H5Aopen_by_idx, <hid_t> -> CString -> <H5_index_t> -> <H5_iter_order_t> -> <hsize_t> -> <hid_t> -> <hid_t> -> IO <hid_t>
+
+-- TODO: Figure out how many elements elements 'buf' is expected to contain, and why
+-- |Write out data to an attribute
+--
+-- Parameters:
+--
+-- [@ attr_id  :: HId_t      @] Attribute to write
+--
+-- [@ dtype_id :: HId_t      @] Memory datatype of buffer
+--
+-- [@ buf      :: InArray a  @] Buffer of data to write
+--
+-- Returns non-negative on success / negative on failure
+--
+-- This function writes a complete attribute to disk.
+--
+-- > herr_t  H5Awrite(hid_t attr_id, hid_t type_id, const void *buf);
+#ccall H5Awrite, <hid_t> -> <hid_t> -> InArray a -> IO <herr_t>
+
+-- |Read in data from an attribute
+--
+-- Parameters:
+--
+-- [@ attr_id  :: HId_t      @] Attribute to read
+--
+-- [@ dtype_id :: HId_t      @] Memory datatype of buffer
+--
+-- [@ buf      :: OutArray a @] Buffer for data to read
+--
+-- Returns non-negative on success / negative on failure
+--
+-- This function reads a complete attribute from disk.
+--
+-- > herr_t  H5Aread(hid_t attr_id, hid_t type_id, void *buf);
+#ccall H5Aread, <hid_t> -> <hid_t> -> OutArray a -> IO <herr_t>
+
+-- |Close an attribute ID
+--
+-- Parameters:
+--
+-- [@ attr_id :: HId_t @]   Attribute to release access to
+--
+-- Returns non-negative on success / negative on failure
+--
+-- This function releases an attribute from use.  Further use of the
+-- attribute ID will result in undefined behavior.
+--
+-- > herr_t  H5Aclose(hid_t attr_id);
+#ccall H5Aclose, <hid_t> -> IO <herr_t>
+
+-- |Gets a copy of the dataspace for an attribute
+--
+-- Parameters:
+--
+-- [@ attr_id :: HId_t @]   Attribute to get dataspace of
+--
+-- Returns a dataspace ID on success, negative on failure
+--
+-- This function retrieves a copy of the dataspace for an attribute.
+-- The dataspace ID returned from this function must be released with
+-- 'h5s_close' or resource leaks will develop.
+--
+-- > hid_t   H5Aget_space(hid_t attr_id);
+#ccall H5Aget_space, <hid_t> -> IO <hid_t>
+
+-- |Gets a copy of the datatype for an attribute
+--
+-- Parameters:
+--
+-- [@ attr_id :: HId_t @]   Attribute to get datatype of
+--
+-- Returns a datatype ID on success, negative on failure
+--
+-- This function retrieves a copy of the datatype for an attribute.
+-- The datatype ID returned from this function must be released with
+-- 'h5t_close' or resource leaks will develop.
+--
+-- > hid_t   H5Aget_type(hid_t attr_id);
+#ccall H5Aget_type, <hid_t> -> IO <hid_t>
+
+-- |Gets a copy of the creation property list for an attribute
+--
+-- Parameters:
+--
+-- [@ attr_id :: HId_t @]   Attribute to get name of
+--
+-- This function returns the ID of a copy of the attribute's creation
+-- property list, or negative on failure. The resulting ID must be closed
+-- with 'h5p_close' or resource leaks will occur.
+--
+-- > hid_t   H5Aget_create_plist(hid_t attr_id);
+#ccall H5Aget_create_plist, <hid_t> -> IO <hid_t>
+
+-- TODO: check semantics of returned strings (null terminated and/or returns size?)
+-- |Gets a copy of the name for an attribute
+--
+-- Parameters:
+--
+-- [@ attr_id  :: HId_t          @] Attribute to get name of
+--
+-- [@ buf_size :: CSize          @] The size of the buffer to store the string in.
+--
+-- [@ buf      :: OutArray CChar @] Buffer to store name in
+--
+-- This function returns the length of the attribute's name (which may be
+-- longer than 'buf_size') on success or negative for failure.
+--
+-- This function retrieves the name of an attribute for an attribute ID.
+-- Up to 'buf_size' characters are stored in 'buf' followed by a '\0' string
+-- terminator.  If the name of the attribute is longer than 'buf_size'-1,
+-- the string terminator is stored in the last position of the buffer to
+-- properly terminate the string.
+--
+-- > ssize_t H5Aget_name(hid_t attr_id, size_t buf_size, char *buf);
+#ccall H5Aget_name, <hid_t> -> <size_t> -> OutArray CChar -> IO <ssize_t>
+
+-- |Retrieve name of an attribute, according to the order within an index.
+--
+-- Same pattern of behavior as 'h5i_get_name'
+--
+-- Returns non-negative length of name, with information in @name@ buffer
+-- on success / negative on failure
+--
+-- > ssize_t H5Aget_name_by_idx(hid_t loc_id, const char *obj_name,
+-- >     H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
+-- >     char *name /*out*/, size_t size, hid_t lapl_id);
+#ccall H5Aget_name_by_idx, <hid_t> -> CString -> <H5_index_t> -> <H5_iter_order_t> -> <hsize_t> -> OutArray CChar -> <size_t> -> <hid_t> -> IO <ssize_t>
+
+-- |Returns the amount of storage size that is allocated for this attribute.
+-- The return value may be zero if no data has been stored.
+--
+-- > hsize_t H5Aget_storage_size(hid_t attr_id);
+#ccall H5Aget_storage_size, <hid_t> -> IO <hsize_t>
+
+-- |Retrieve information about an attribute.
+--
+-- Returns non-negative on success / negative on failure
+--
+-- > herr_t  H5Aget_info(hid_t attr_id, H5A_info_t *ainfo /*out*/);
+#ccall H5Aget_info, <hid_t> -> Out <H5A_info_t> -> IO <herr_t>
+
+-- |Retrieve information about an attribute by name.
+--
+-- Returns non-negative on success / negative on failure
+--
+-- > herr_t  H5Aget_info_by_name(hid_t loc_id, const char *obj_name,
+-- >     const char *attr_name, H5A_info_t *ainfo /*out*/, hid_t lapl_id);
+#ccall H5Aget_info_by_name, <hid_t> -> CString -> CString -> Out H5A_info_t -> <hid_t> -> IO <herr_t>
+
+-- |Retrieve information about an attribute, according to the order within an index.
+--
+-- Returns non-negative on success / negative on failure
+--
+-- > herr_t  H5Aget_info_by_idx(hid_t loc_id, const char *obj_name,
+-- >     H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
+-- >     H5A_info_t *ainfo /*out*/, hid_t lapl_id);
+#ccall H5Aget_info_by_idx, <hid_t> -> CString -> <H5_index_t> -> <H5_iter_order_t> -> <hsize_t> -> Out <H5A_info_t> -> <hid_t> -> IO <herr_t>
+
+-- |Rename an attribute
+--
+-- Returns non-negative on success / negative on failure
+--
+-- > herr_t  H5Arename(hid_t loc_id, const char *old_name, const char *new_name);
+#ccall H5Arename, <hid_t> -> CString -> CString -> IO <herr_t>
+
+-- |Rename an attribute
+--
+-- Returns non-negative on success / negative on failure
+--
+-- > herr_t  H5Arename_by_name(hid_t loc_id, const char *obj_name,
+-- >     const char *old_attr_name, const char *new_attr_name, hid_t lapl_id);
+#ccall H5Arename_by_name, <hid_t> -> CString -> CString -> CString -> <hid_t> -> IO <herr_t>
+
+-- |Calls a user's function for each attribute on an object.
+--
+-- Parameters:
+--
+--  [@ loc_id :: HId_t          @]  Base location for object
+--
+--  [@ idx_type :: H5_index_t   @]  Type of index to use
+--
+--  [@ order :: H5_iter_order_t @]  Order to iterate over index
+--
+--  [@ idx :: InOut HSize_t     @]  Starting (IN) & Ending (OUT) attribute in index & order
+--
+--  [@ op :: H5A_operator2_t a  @]  User's function to pass each attribute to
+--
+--  [@ op_data :: InOut a       @]  User's data to pass through to iterator operator function
+--
+-- Returns a negative value if an error occurs, the return value of the
+-- last operator if it was non-zero (which can be a negative value), or zero
+-- if all attributes were processed.
+--
+-- This function interates over the attributes of dataset or group
+-- specified with 'loc_id' & 'obj_name'.  For each attribute of the object,
+-- the 'op_data' and some additional information (specified below) are passed
+-- to the 'op' function.  The iteration begins with the '*idx'
+-- object in the group and the next attribute to be processed by the operator
+-- is returned in '*idx'.
+--
+-- The operation receives the ID for the group or dataset being iterated
+-- over ('loc_id'), the name of the current attribute about the object
+-- ('attr_name'), the attribute's \"info\" struct ('ainfo') and the pointer to
+-- the operator data passed in to H5Aiterate2 ('op_data').  The return values
+-- from an operator are:
+--
+--  * Zero causes the iterator to continue, returning zero when all
+--    attributes have been processed.
+--
+--  * Positive causes the iterator to immediately return that positive
+--    value, indicating short-circuit success.  The iterator can be
+--    restarted at the next attribute.
+--
+--  * Negative causes the iterator to immediately return that value,
+--    indicating failure.  The iterator can be restarted at the next
+--    attribute.
+--
+-- > herr_t  H5Aiterate2(hid_t loc_id, H5_index_t idx_type,
+-- >     H5_iter_order_t order, hsize_t *idx, H5A_operator2_t op, void *op_data);
+#ccall H5Aiterate2, <hid_t> -> <H5_index_t> -> <H5_iter_order_t> -> InOut <hsize_t> -> H5A_operator2_t a -> InOut a -> IO <herr_t>
+
+-- |Calls a user's function for each attribute on an object
+--
+-- Parameters:
+--
+-- [@ loc_id   :: HId_t             @]  Base location for object
+--
+-- [@ obj_name :: CString           @]  Name of object relative to location
+--
+-- [@ idx_type :: H5_index_t        @]  Type of index to use
+--
+-- [@ order    :: H5_iter_order_t   @]  Order to iterate over index
+--
+-- [@ idx      :: InOut HSize_t     @]  Starting (IN) & Ending (OUT) attribute in index & order
+--
+-- [@ op       :: H5A_operator2_t a @]  H5A_operator2_t IN: User's function to pass each attribute to
+--
+-- [@ op_data  :: InOut a           @]  User's data to pass through to iterator operator function
+--
+-- [@ lapl_id  :: HId_t             @]  Link access property list
+--
+-- Returns a negative value if an error occurs, the return value of the
+-- last operator if it was non-zero (which can be a negative value), or zero
+-- if all attributes were processed.
+--
+-- This function interates over the attributes of dataset or group
+-- specified with 'loc_id' & 'obj_name'.  For each attribute of the object,
+-- the 'op_data' and some additional information (specified below) are passed
+-- to the 'op' function.  The iteration begins with the '*idx'
+-- object in the group and the next attribute to be processed by the operator
+-- is returned in '*idx'.
+--
+-- The operation receives the ID for the group or dataset being iterated
+-- over ('loc_id'), the name of the current attribute about the object
+-- ('attr_name'), the attribute's \"info\" struct ('ainfo') and the pointer to
+-- the operator data passed in to H5Aiterate_by_name ('op_data').  The return values
+-- from an operator are:
+--
+--  * Zero causes the iterator to continue, returning zero when all
+--    attributes have been processed.
+--
+--  * Positive causes the iterator to immediately return that positive
+--    value, indicating short-circuit success.  The iterator can be
+--    restarted at the next attribute.
+--
+--  * Negative causes the iterator to immediately return that value,
+--    indicating failure.  The iterator can be restarted at the next
+--    attribute.
+--
+-- > herr_t  H5Aiterate_by_name(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
+-- >     H5_iter_order_t order, hsize_t *idx, H5A_operator2_t op, void *op_data,
+-- >     hid_t lapd_id);
+#ccall H5Aiterate_by_name, <hid_t> -> CString -> <H5_index_t> -> <H5_iter_order_t> -> InOut <hsize_t> -> H5A_operator2_t a -> InOut a -> <hid_t> -> IO <herr_t>
+
+-- |Deletes an attribute from a location
+--
+-- Parameters:
+--
+-- [@ loc_id :: HId_t   @] Object (dataset or group) to have attribute deleted from
+--
+-- [@ name   :: CString @] Name of attribute to delete
+--
+-- Returns non-negative on success / negative on failure
+--
+-- This function removes the named attribute from a dataset or group.
+--
+-- > herr_t  H5Adelete(hid_t loc_id, const char *name);
+#ccall H5Adelete, <hid_t> -> CString -> IO <herr_t>
+
+-- |Deletes an attribute from a location
+--
+-- Parameters:
+--
+-- [@ loc_id    :: HId_t   @]   Object (dataset or group) to have attribute deleted from
+--
+-- [@ obj_name  :: CString @]   Name of object relative to location
+--
+-- [@ attr_name :: CString @]   Name of attribute to delete
+--
+-- [@ lapl_id   :: HId_t   @]   Link access property list
+--
+-- Returns non-negative on success / negative on failure
+--
+-- This function removes the named attribute from a dataset or group.
+--
+-- > herr_t  H5Adelete_by_name(hid_t loc_id, const char *obj_name,
+-- >     const char *attr_name, hid_t lapl_id);
+#ccall H5Adelete_by_name, <hid_t> -> CString -> CString -> <hid_t> -> IO <herr_t>
+
+-- |Deletes an attribute from a location, according to the order within an index
+--
+-- Parameters:
+--
+-- [@ loc_id   :: HId_t           @]    Base location for object
+--
+-- [@ obj_name :: CString         @]    Name of object relative to location
+--
+-- [@ idx_type :: H5_index_t      @]    Type of index to use
+--
+-- [@ order    :: H5_iter_order_t @]    Order to iterate over index
+--
+-- [@ n        :: HSize_t         @]    Offset within index
+--
+-- [@ lapl_id  :: HId_t           @]    Link access property list
+--
+-- Returns non-negative on success / negative on failure
+--
+-- This function removes an attribute from an object, using the 'idx_type'
+-- index to delete the 'n'th attribute in 'order' direction in the index.  The
+-- object is specified relative to the 'loc_id' with the 'obj_name' path.  To
+-- remove an attribute on the object specified by 'loc_id', pass in @"."@ for
+-- 'obj_name'.  The link access property list, 'lapl_id', controls aspects of
+-- the group hierarchy traversal when using the 'obj_name' to locate the final
+-- object to operate on.
+--
+-- > herr_t  H5Adelete_by_idx(hid_t loc_id, const char *obj_name,
+-- >     H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t lapl_id);
+#ccall H5Adelete_by_idx, <hid_t> -> CString -> <H5_index_t> -> <H5_iter_order_t> -> <hsize_t> -> <hid_t> -> IO <herr_t>
+
+-- |Checks if an attribute with a given name exists on an opened object.
+--
+-- > htri_t H5Aexists(hid_t obj_id, const char *attr_name);
+#ccall H5Aexists, <hid_t> -> CString -> IO <htri_t>
+
+-- |Checks if an attribute with a given name exists on an object.
+--
+-- > htri_t H5Aexists_by_name(hid_t obj_id, const char *obj_name,
+-- >     const char *attr_name, hid_t lapl_id);
+#ccall H5Aexists_by_name, <hid_t> -> CString -> CString -> <hid_t> -> IO <htri_t>
+
+#ifndef H5_NO_DEPRECATED_SYMBOLS
+-- |Typedef for 'h5a_iterate1' callbacks
+--
+-- > typedef herr_t (*H5A_operator1_t)(hid_t location_id/*in*/,
+-- >     const char *attr_name/*in*/, void *operator_data/*in,out*/);
+type H5A_operator1_t a = FunPtr (HId_t -> CString -> InOut a -> IO HErr_t)
+
+-- |Creates an attribute on an object
+--
+-- Parameters:
+--
+-- [@ loc_id   :: HId_t   @]    Object (dataset or group) to be attached to
+--
+-- [@ name     :: CString @]    Name of attribute to create
+--
+-- [@ type_id  :: HId_t   @]    ID of datatype for attribute
+--
+-- [@ space_id :: HId_t   @]    ID of dataspace for attribute
+--
+-- [@ plist_id :: HId_t   @]    ID of creation property list (currently not used)
+--
+-- Returns non-negative on success / negative on failure
+--
+-- This function creates an attribute which is attached to the object
+-- specified with 'location_id'.  The name specified with 'name' for each
+-- attribute for an object must be unique for that object.  The 'type_id'
+-- and 'space_id' are created with the H5T and H5S interfaces respectively.
+-- The attribute ID returned from this function must be released with
+-- 'h5a_close' or resource leaks will develop.
+--
+-- Note: Deprecated in favor of 'h5a_create2'
+--
+-- > hid_t   H5Acreate1(hid_t loc_id, const char *name, hid_t type_id,
+-- >     hid_t space_id, hid_t acpl_id);
+#ccall H5Acreate1, <hid_t> -> CString -> <hid_t> -> <hid_t> -> <hid_t> -> IO <hid_t>
+
+-- |Opens an attribute for an object by looking up the attribute name
+--
+-- Parameters:
+--
+-- [@ loc_id :: HId_t   @]  Object (dataset or group) to be attached to
+--
+-- [@ name   :: CString @]  Name of attribute to locate and open
+--
+-- Returns ID of attribute on success, negative on failure
+--
+-- This function opens an existing attribute for access.  The attribute
+-- name specified is used to look up the corresponding attribute for the
+-- object.  The attribute ID returned from this function must be released with
+-- H5Aclose or resource leaks will develop.
+--
+-- The location object may be either a group or a dataset, both of
+-- which may have any sort of attribute.
+--
+-- Note: Deprecated in favor of 'h5a_open'
+--
+-- > hid_t   H5Aopen_name(hid_t loc_id, const char *name);
+#ccall H5Aopen_name, <hid_t> -> CString -> IO <hid_t>
+
+-- |Opens the n'th attribute for an object
+--
+-- Parameters:
+--
+-- [@ loc_id :: HId_t @]   Object that attribute is attached to
+--
+-- [@ idx    :: CUInt @]   Index (0-based) attribute to open
+--
+-- Returns ID of attribute on success, negative on failure
+--
+-- This function opens an existing attribute for access.  The attribute
+-- index specified is used to look up the corresponding attribute for the
+-- object.  The attribute ID returned from this function must be released with
+-- 'h5a_close' or resource leaks will develop.
+--
+-- The location object may be either a group or a dataset, both of
+-- which may have any sort of attribute.
+--
+-- Note: Deprecated in favor of 'h5a_open_by_idx'
+--
+-- > hid_t   H5Aopen_idx(hid_t loc_id, unsigned idx);
+#ccall H5Aopen_idx, <hid_t> -> CUInt -> IO <hid_t>
+
+-- |Determines the number of attributes attached to an object
+--
+-- Parameters:
+--
+-- [@ loc_id :: HId_t @]    Object (dataset or group) to be queried
+--
+-- Returns number of attributes on success, negative on failure
+--
+-- This function returns the number of attributes attached to a dataset or
+-- group, 'location_id'.
+--
+-- Note: Deprecated in favor of 'h5o_get_info'
+--
+-- > int H5Aget_num_attrs(hid_t loc_id);
+#ccall H5Aget_num_attrs, <hid_t> -> IO CInt
+
+-- |Calls a user's function for each attribute on an object
+--
+-- Parameters:
+--
+-- [@ loc_id   :: HId_t             @]  Object (dataset or group) to be iterated over
+--
+-- [@ attr_num :: InOut CUInt       @]  Starting (IN) & Ending (OUT) attribute number
+--
+-- [@ op       :: H5A_operator1_t a @]  User's function to pass each attribute to
+--
+-- [@ op_data  :: InOut a           @]  User's data to pass through to iterator operator function
+--
+-- Returns a negative value if something is wrong, the return value of the
+-- last operator if it was non-zero, or zero if all attributes were processed.
+--
+-- This function interates over the attributes of dataset or group
+-- specified with 'loc_id'.  For each attribute of the object, the
+-- 'op_data' and some additional information (specified below) are passed
+-- to the 'op' function.  The iteration begins with the 'attr_num'
+-- object in the group and the next attribute to be processed by the operator
+-- is returned in 'attr_num'.
+--
+-- The operation receives the ID for the group or dataset being iterated
+-- over ('loc_id'), the name of the current attribute about the object
+-- ('attr_name') and the pointer to the operator data passed in to 'h5a_iterate1'
+-- ('op_data').  The return values from an operator are:
+--
+--  * Zero causes the iterator to continue, returning zero when all
+--    attributes have been processed.
+--
+--  * Positive causes the iterator to immediately return that positive
+--    value, indicating short-circuit success.  The iterator can be
+--    restarted at the next attribute.
+--
+--  * Negative causes the iterator to immediately return that value,
+--    indicating failure.  The iterator can be restarted at the next
+--    attribute.
+--
+-- Note: Deprecated in favor of 'h5a_iterate2'
+--
+-- > herr_t  H5Aiterate1(hid_t loc_id, unsigned *attr_num, H5A_operator1_t op,
+-- >     void *op_data);
+#ccall H5Aiterate1, <hid_t> -> InOut CUInt -> H5A_operator1_t a -> InOut a -> IO <herr_t>
+
+#endif /* H5_NO_DEPRECATED_SYMBOLS */
diff --git a/src/Bindings/HDF5/Raw/H5AC.hsc b/src/Bindings/HDF5/Raw/H5AC.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/H5AC.hsc
@@ -0,0 +1,416 @@
+module Bindings.HDF5.Raw.H5AC where
+#include <bindings.h>
+#include <H5ACpublic.h>
+
+import Foreign.C.Types
+import Foreign.Marshal.Array
+import Foreign.Ptr
+import Foreign.Storable
+
+import Bindings.HDF5.Raw.H5
+import Bindings.HDF5.Raw.H5C
+
+-- |'H5AC_cache_config_t' is a public structure intended for use in public APIs.
+-- At least in its initial incarnation, it is basicaly a copy of struct
+-- 'H5C_auto_size_ctl_t', minus the 'report_fcn' field, and plus the
+-- 'dirty_bytes_threshold' field.
+--
+-- The 'report_fcn' field is omitted, as including it would require us to
+-- make 'H5C_t' structure public.
+--
+-- The 'dirty_bytes_threshold' field does not appear in 'H5C_auto_size_ctl_t',
+-- as synchronization between caches on different processes is handled at
+-- the H5AC level, not at the level of H5C.  Note however that there is
+-- considerable interaction between this value and the other fields in this
+-- structure.
+--
+-- Similarly, the 'open_trace_file', 'close_trace_file', and 'trace_file_name'
+-- fields do not appear in 'H5C_auto_size_ctl_t', as most trace file
+-- issues are handled at the H5AC level.  The one exception is storage of
+-- the pointer to the trace file, which is handled by H5C.
+--
+-- The structure is in H5ACpublic.h as we may wish to allow different
+-- configuration options for metadata and raw data caches.
+--
+-- The fields of the structure are discussed individually below.
+--
+#starttype H5AC_cache_config_t
+
+-- |Integer field containing the version number of this version
+-- of the H5AC_cache_config_t structure.  Any instance of
+-- H5AC_cache_config_t passed to the cache must have a known
+-- version number, or an error will be flagged.
+#field version,                 CInt
+
+-- |Boolean field used to enable and disable the default
+-- reporting function.  This function is invoked every time the
+-- automatic cache resize code is run, and reports on its activities.
+--
+-- This is a debugging function, and should normally be turned off.
+#field rpt_fcn_enabled,         <hbool_t>
+
+-- |Boolean field indicating whether the trace_file_name
+-- field should be used to open a trace file for the cache.
+--
+-- The trace file is a debuging feature that allow the capture of
+-- top level metadata cache requests for purposes of debugging and/or
+-- optimization.  This field should normally be set to FALSE, as
+-- trace file collection imposes considerable overhead.
+--
+-- This field should only be set to TRUE when the trace_file_name
+-- contains the full path of the desired trace file, and either
+-- there is no open trace file on the cache, or the close_trace_file
+-- field is also TRUE.
+#field open_trace_file,         <hbool_t>
+
+-- |Boolean field indicating whether the current trace
+-- file (if any) should be closed.
+--
+-- See the above comments on the open_trace_file field.  This field
+-- should be set to FALSE unless there is an open trace file on the
+-- cache that you wish to close.
+#field close_trace_file,        <hbool_t>
+
+-- |Full path of the trace file to be opened if the 'open_trace_file' field is TRUE.
+--
+-- In the parallel case, an ascii representation of the mpi rank of
+-- the process will be appended to the file name to yield a unique
+-- trace file name for each process.
+--
+-- The length of the path must not exceed 'h5ac__MAX_TRACE_FILE_NAME_LEN'
+-- characters.
+#array_field trace_file_name,   CChar
+
+-- |Boolean field used to either report the current
+-- evictions enabled status of the cache, or to set the cache's
+-- evictions enabled status.
+--
+-- In general, the metadata cache should always be allowed to
+-- evict entries.  However, in some cases it is advantageous to
+-- disable evictions briefly, and thereby postpone metadata
+-- writes.  However, this must be done with care, as the cache
+-- can grow quickly.  If you do this, re-enable evictions as
+-- soon as possible and monitor cache size.
+--
+-- At present, evictions can only be disabled if automatic
+-- cache resizing is also disabled (that is, @( 'incr_mode' ==
+-- 'h5c_incr__off' ) && ( 'decr_mode' == 'h5c_decr__off' )@).  There
+-- is no logical reason why this should be so, but it simplifies
+-- implementation and testing, and I can't think of any reason
+-- why it would be desireable.  If you can think of one, I'll
+-- revisit the issue.
+#field evictions_enabled,       <hbool_t>
+
+-- |Boolean flag indicating whether the size of the
+-- initial size of the cache is to be set to the value given in
+-- the initial_size field.  If 'set_initial_size' is FALSE, the
+-- 'initial_size' field is ignored.
+#field set_initial_size,        <hbool_t>
+
+-- |If enabled, this field contain the size the cache is
+-- to be set to upon receipt of this structure.  Needless to say,
+-- 'initial_size' must lie in the closed interval @['min_size' .. 'max_size']@.
+#field initial_size,            <size_t>
+
+-- |double in the range 0 to 1 indicating the fraction
+-- of the cache that is to be kept clean.  This field is only used
+-- in parallel mode.  Typical values are 0.1 to 0.5.
+#field min_clean_fraction,      CDouble
+
+-- TODO: figure out where MIN_MAX_CACHE_SIZE and MAX_MAX_CACHE_SIZE come from.  They don't seem to be in any public headers
+-- |Maximum size to which the cache can be adjusted.  The
+-- supplied value must fall in the closed interval
+-- @['MIN_MAX_CACHE_SIZE' .. 'MAX_MAX_CACHE_SIZE']@.  Also, 'max_size' must
+-- be greater than or equal to 'min_size'.
+#field max_size,                <size_t>
+
+-- TODO: figure out where H5C__MIN_MAX_CACHE_SIZE and H5C__MAX_MAX_CACHE_SIZE come from.  They don't seem to be in any public headers
+-- |Minimum size to which the cache can be adjusted.  The
+-- supplied value must fall in the closed interval
+-- @['H5C__MIN_MAX_CACHE_SIZE' .. 'H5C__MAX_MAX_CACHE_SIZE']@.  Also, 'min_size'
+-- must be less than or equal to 'max_size'.
+#field min_size,                <size_t>
+
+-- TODO: figure out where H5C__MIN_AR_EPOCH_LENGTH and H5C__MAX_AR_EPOCH_LENGTH come from.  They don't seem to be in any public headers
+-- |Number of accesses on the cache over which to collect
+-- hit rate stats before running the automatic cache resize code,
+-- if it is enabled.
+--
+-- At the end of an epoch, we discard prior hit rate data and start
+-- collecting afresh.  The epoch_length must lie in the closed
+-- interval @['H5C__MIN_AR_EPOCH_LENGTH' .. 'H5C__MAX_AR_EPOCH_LENGTH']@.
+#field epoch_length,            CLong
+
+-- |Instance of the 'H5C_cache_incr_mode' enumerated type whose
+-- value indicates how we determine whether the cache size should be
+-- increased.  At present there are two possible values:
+--
+-- * 'h5c_incr__off':
+--         Don't attempt to increase the size of the cache
+--         automatically.
+--         When this increment mode is selected, the remaining fields
+--         in the cache size increase section ar ignored.
+--
+-- * 'h5c_incr__threshold':
+--         Attempt to increase the size of the cache
+--         whenever the average hit rate over the last epoch drops
+--         below the value supplied in the lower_hr_threshold
+--         field.
+--         Note that this attempt will fail if the cache is already
+--         at its maximum size, or if the cache is not already using
+--         all available space.
+--
+-- Note that you must set 'decr_mode' to 'h5c_incr__off' if you
+-- disable metadata cache entry evictions.
+#field incr_mode,               <H5C_cache_incr_mode>
+
+-- |Lower hit rate threshold.  If the increment mode
+-- ('incr_mode') is 'h5c_incr__threshold' and the hit rate drops below the
+-- value supplied in this field in an epoch, increment the cache size by
+-- 'size_increment'.  Note that cache size may not be incremented above
+-- 'max_size', and that the increment may be further restricted by the
+-- 'max_increment' field if it is enabled.
+--
+-- When enabled, this field must contain a value in the range [0.0, 1.0].
+-- Depending on the 'incr_mode' selected, it may also have to be less than
+-- 'upper_hr_threshold'.
+#field lower_hr_threshold,      CDouble
+
+-- |Double containing the multiplier used to derive the new
+-- cache size from the old if a cache size increment is triggered.
+-- The increment must be greater than 1.0, and should not exceed 2.0.
+--
+-- The new cache size is obtained my multiplying the current max cache
+-- size by the increment, and then clamping to max_size and to stay
+-- within the max_increment as necessary.
+#field increment,               CDouble
+
+-- |Boolean flag indicating whether the max_increment
+-- field should be used to limit the maximum cache size increment.
+#field apply_max_increment,     <hbool_t>
+
+-- |If enabled by the 'apply_max_increment' field described
+-- above, this field contains the maximum number of bytes by which the
+-- cache size can be increased in a single re-size.
+#field max_increment,           <size_t>
+
+-- |Instance of the 'H5C_cache_flash_incr_mode' enumerated
+-- type whose value indicates whether and by which algorithm we should
+-- make flash increases in the size of the cache to accomodate insertion
+-- of large entries and large increases in the size of a single entry.
+--
+-- The addition of the flash increment mode was occasioned by performance
+-- problems that appear when a local heap is increased to a size in excess
+-- of the current cache size.  While the existing re-size code dealt with
+-- this eventually, performance was very bad for the remainder of the
+-- epoch.
+--
+-- At present, there are two possible values for the 'flash_incr_mode':
+--
+-- * 'h5c_flash_incr__off':  Don't perform flash increases in the size of
+--         the cache.
+--
+-- * 'h5c_flash_incr__add_space':  Let @x@ be either the size of a newly
+--         newly inserted entry, or the number of bytes by which the
+--         size of an existing entry has been increased.
+--         If @x > flash_threshold * current max cache size@,
+--         increase the current maximum cache size by @x * flash_multiple@
+--         less any free space in the cache, and start a new epoch.  For
+--         now at least, pay no attention to the maximum increment.
+--
+-- In both of the above cases, the flash increment pays no attention to
+-- the maximum increment (at least in this first incarnation), but DOES
+-- stay within 'max_size'.
+--
+-- With a little thought, it should be obvious that the above flash
+-- cache size increase algorithm is not sufficient for all circumstances.
+-- For example, suppose the user round robins through
+-- @(1/flash_threshold) + 1@ groups, adding one data set to each on each
+-- pass.  Then all will increase in size at about the same time, requiring
+-- the max cache size to at least double to maintain acceptable
+-- performance, however the above flash increment algorithm will not be
+-- triggered.
+--
+-- Hopefully, the add space algorithms detailed above will be sufficient
+-- for the performance problems encountered to date.  However, we should
+-- expect to revisit the issue.
+#field flash_incr_mode,         <H5C_cache_flash_incr_mode>
+
+-- |Double containing the multiple described above in the
+-- 'h5c_flash_incr__add_space' section of the discussion of the
+-- 'flash_incr_mode' section.  This field is ignored unless 'flash_incr_mode'
+-- is 'h5c_flash_incr__add_space'.
+#field flash_multiple,          CDouble
+
+-- |Double containing the factor by which current max cache
+-- size is multiplied to obtain the size threshold for the 'add_space' flash
+-- increment algorithm.  The field is ignored unless 'flash_incr_mode' is
+-- 'h5c_flash_incr__add_space'.
+#field flash_threshold,         CDouble
+
+-- |Instance of the 'H5C_cache_decr_mode' enumerated type whose
+-- value indicates how we determine whether the cache size should be
+-- decreased.  At present there are four possibilities.
+--
+-- * 'h5c_decr__off':  Don't attempt to decrease the size of the cache
+--         automatically. When this increment mode is selected, the remaining
+--         fields in the cache size decrease section are ignored.
+--
+-- * 'h5c_decr__threshold': Attempt to decrease the size of the cache
+--         whenever the average hit rate over the last epoch rises
+--         above the value supplied in the upper_hr_threshold
+--         field.
+--
+-- * 'h5c_decr__age_out':  At the end of each epoch, search the cache for
+--         entries that have not been accessed for at least the number
+--         of epochs specified in the 'epochs_before_eviction' field, and
+--         evict these entries.  Conceptually, the maximum cache size
+--         is then decreased to match the new actual cache size.  However,
+--         this reduction may be modified by the 'min_size', the
+--         'max_decrement', and/or the 'empty_reserve'.
+--
+-- * 'h5c_decr__age_out_with_threshold':  Same as 'age_out', but we only
+--         attempt to reduce the cache size when the hit rate observed
+--         over the last epoch exceeds the value provided in the
+--         'upper_hr_threshold' field.
+--
+-- Note that you must set 'decr_mode' to 'h5c_decr__off' if you
+-- disable metadata cache entry evictions.
+#field decr_mode,               <H5C_cache_decr_mode>
+
+-- |Upper hit rate threshold.  The use of this field varies according to
+-- the current 'decr_mode':
+--
+-- * 'h5c_decr__off' or 'h5c_decr__age_out':  The value of this field is
+--         ignored.
+--
+-- * 'h5c_decr__threshold':  If the hit rate exceeds this threshold in any
+--         epoch, attempt to decrement the cache size by 'size_decrement'.
+--
+--         Note that cache size may not be decremented below 'min_size'.
+--
+--         Note also that if the 'upper_threshold' is 1.0, the cache size
+--         will never be reduced.
+--
+-- * 'h5c_decr__age_out_with_threshold':  If the hit rate exceeds this
+--         threshold in any epoch, attempt to reduce the cache size
+--         by evicting entries that have not been accessed for more
+--         than the specified number of epochs.
+#field upper_hr_threshold,      CDouble
+
+-- |This field is only used when the decr_mode is 'h5c_decr__threshold'.
+--
+-- The field is a double containing the multiplier used to derive the
+-- new cache size from the old if a cache size decrement is triggered.
+-- The decrement must be in the range 0.0 (in which case the cache will
+-- try to contract to its minimum size) to 1.0 (in which case the
+-- cache will never shrink).
+#field decrement,               CDouble
+
+-- |Boolean flag used to determine whether decrements
+-- in cache size are to be limited by the 'max_decrement' field.
+#field apply_max_decrement,     <hbool_t>
+
+-- |Maximum number of bytes by which the cache size can be
+-- decreased in a single re-size.  Note that decrements may also be
+-- restricted by the min_size of the cache, and (in age out modes) by
+-- the 'empty_reserve' field.
+#field max_decrement,           <size_t>
+
+-- TODO: figure out where H5C__MAX_EPOCH_MARKERS comes from
+-- |Integer field used in H5C_decr__age_out and
+-- 'h5c_decr__age_out_with_threshold' decrement modes.
+--
+-- This field contains the number of epochs an entry must remain
+-- unaccessed before it is evicted in an attempt to reduce the
+-- cache size.  If applicable, this field must lie in the range
+-- @[1 .. 'H5C__MAX_EPOCH_MARKERS']@.
+#field epochs_before_eviction,  CInt
+
+-- |Boolean field controlling whether the 'empty_reserve'
+-- field is to be used in computing the new cache size when the
+-- 'decr_mode' is 'h5c_decr__age_out' or 'h5c_decr__age_out_with_threshold'.
+#field apply_empty_reserve,     <hbool_t>
+
+-- |To avoid a constant racheting down of cache size by small
+-- amounts in the 'h5c_decr__age_out' and 'h5c_decr__age_out_with_threshold'
+-- modes, this field allows one to require that any cache size
+-- reductions leave the specified fraction of unused space in the cache.
+--
+-- The value of this field must be in the range [0.0, 1.0].  I would
+-- expect typical values to be in the range of 0.01 to 0.1.
+#field empty_reserve,           CDouble
+
+-- |Threshold of dirty byte creation used to
+-- synchronize updates between caches. (See above for outline and
+-- motivation.)
+--
+-- This value MUST be consistant across all processes accessing the
+-- file.  This field is ignored unless HDF5 has been compiled for
+-- parallel.
+#if H5_VERSION_GE(1,10,0)
+#field dirty_bytes_threshold,   <size_t>
+#else
+#field dirty_bytes_threshold,   CInt
+#endif
+
+#if H5_VERSION_GE(1,8,6)
+-- |Integer field containing a code indicating the
+-- desired metadata write strategy.  The valid values of this field
+-- are enumerated and discussed below:
+#field metadata_write_strategy, CInt
+#endif
+
+#stoptype
+
+#num H5AC__CURR_CACHE_CONFIG_VERSION
+#num H5AC__MAX_TRACE_FILE_NAME_LEN
+
+#if H5_VERSION_GE(1,8,6)
+
+-- |When 'metadata_write_strategy' is set to this value, only process
+-- zero is allowed to write dirty metadata to disk.  All other
+-- processes must retain dirty metadata until they are informed at
+-- a sync point that the dirty metadata in question has been written
+-- to disk.
+--
+-- When the sync point is reached (or when there is a user generated
+-- flush), process zero flushes sufficient entries to bring it into
+-- complience with its min clean size (or flushes all dirty entries in
+-- the case of a user generated flush), broad casts the list of
+-- entries just cleaned to all the other processes, and then exits
+-- the sync point.
+--
+-- Upon receipt of the broadcast, the other processes mark the indicated
+-- entries as clean, and leave the sync point as well.
+#num H5AC_METADATA_WRITE_STRATEGY__PROCESS_0_ONLY
+
+-- |In the distributed metadata write strategy, process zero still makes
+-- the decisions as to what entries should be flushed, but the actual
+-- flushes are distributed across the processes in the computation to
+-- the extent possible.
+--
+-- In this strategy, when a sync point is triggered (either by dirty
+-- metadata creation or manual flush), all processes enter a barrier.
+--
+-- On the other side of the barrier, process 0 constructs an ordered
+-- list of the entries to be flushed, and then broadcasts this list
+-- to the caches in all the processes.
+--
+-- All processes then scan the list of entries to be flushed, flushing
+-- some, and marking the rest as clean.  The algorithm for this purpose
+-- ensures that each entry in the list is flushed exactly once, and
+-- all are marked clean in each cache.
+--
+-- Note that in the case of a flush of the cache, no message passing
+-- is necessary, as all processes have the same list of dirty entries,
+-- and all of these entries must be flushed.  Thus in this case it is
+-- sufficient for each process to sort its list of dirty entries after
+-- leaving the initial barrier, and use this list as if it had been
+-- received from process zero.
+--
+-- To avoid possible messages from the past/future, all caches must
+-- wait until all caches are done before leaving the sync point.
+#num H5AC_METADATA_WRITE_STRATEGY__DISTRIBUTED
+
+#endif
diff --git a/src/Bindings/HDF5/Raw/H5C.hsc b/src/Bindings/HDF5/Raw/H5C.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/H5C.hsc
@@ -0,0 +1,24 @@
+module Bindings.HDF5.Raw.H5C where
+#include <bindings.h>
+#include <H5Cpublic.h>
+
+import Data.Word
+import Foreign.Storable
+
+#def typedef enum H5C_cache_incr_mode H5C_cache_incr_mode;
+#newtype H5C_cache_incr_mode, Eq
+#newtype_const H5C_cache_incr_mode, H5C_incr__off
+#newtype_const H5C_cache_incr_mode, H5C_incr__threshold
+
+#def typedef enum H5C_cache_flash_incr_mode H5C_cache_flash_incr_mode;
+#newtype H5C_cache_flash_incr_mode, Eq
+#newtype_const  H5C_cache_flash_incr_mode, H5C_flash_incr__off
+#newtype_const  H5C_cache_flash_incr_mode, H5C_flash_incr__add_space
+
+#def typedef enum H5C_cache_decr_mode H5C_cache_decr_mode;
+#newtype H5C_cache_decr_mode, Eq
+#newtype_const H5C_cache_decr_mode, H5C_decr__off
+#newtype_const H5C_cache_decr_mode, H5C_decr__threshold
+#newtype_const H5C_cache_decr_mode, H5C_decr__age_out
+#newtype_const H5C_cache_decr_mode, H5C_decr__age_out_with_threshold
+
diff --git a/src/Bindings/HDF5/Raw/H5D.hsc b/src/Bindings/HDF5/Raw/H5D.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/H5D.hsc
@@ -0,0 +1,585 @@
+#include <bindings.h>
+#include <H5Dpublic.h>
+
+module Bindings.HDF5.Raw.H5D where
+
+import Data.Int
+import Data.Word
+import Foreign.C.String
+import Foreign.C.Types
+import Foreign.Ptr
+import Foreign.Storable
+
+import Bindings.HDF5.Raw.H5
+import Bindings.HDF5.Raw.H5I
+import Foreign.Ptr.Conventions
+
+#if H5_VERSION_GE(1,8,3)
+
+#num H5D_CHUNK_CACHE_NSLOTS_DEFAULT
+#num H5D_CHUNK_CACHE_NBYTES_DEFAULT
+#num H5D_CHUNK_CACHE_W0_DEFAULT
+
+#endif
+
+#if H5_VERSION_GE(1,10,0)
+
+-- |Bit flags for the H5Pset_chunk_opts() and H5Pget_chunk_opts()
+#num H5D_CHUNK_DONT_FILTER_PARTIAL_CHUNKS
+
+#endif
+
+#if H5_VERSION_GE(1,8,11)
+
+-- |Property names for H5LTDdirect_chunk_write
+#str H5D_XFER_DIRECT_CHUNK_WRITE_FLAG_NAME
+#str H5D_XFER_DIRECT_CHUNK_WRITE_FILTERS_NAME
+#str H5D_XFER_DIRECT_CHUNK_WRITE_OFFSET_NAME
+#str H5D_XFER_DIRECT_CHUNK_WRITE_DATASIZE_NAME
+
+#endif
+
+-- |Values for the H5D_LAYOUT property
+#newtype H5D_layout_t, Eq
+
+#newtype_const H5D_layout_t, H5D_LAYOUT_ERROR
+
+-- |raw data is very small
+#newtype_const H5D_layout_t, H5D_COMPACT
+
+-- |the default
+#newtype_const H5D_layout_t, H5D_CONTIGUOUS
+
+-- |slow and fancy
+#newtype_const H5D_layout_t, H5D_CHUNKED
+
+#if H5_VERSION_GE(1,10,0)
+
+-- |actual data is stored in other datasets
+#newtype_const H5D_layout_t, H5D_VIRTUAL
+
+#endif
+
+#num H5D_NLAYOUTS
+
+#if H5_VERSION_GE(1,8,3)
+
+-- |Types of chunk index data structures
+#newtype H5D_chunk_index_t
+
+-- |v1 B-tree index
+#newtype_const H5D_chunk_index_t, H5D_CHUNK_BTREE
+
+#if H5_VERSION_GE(1,10,0)
+
+-- |v1 B-tree index (default)
+#newtype_const H5D_chunk_index_t, H5D_CHUNK_IDX_BTREE
+-- |Single Chunk index (cur dims[]=max dims[]=chunk dims[]; filtered & non-filtered)
+#newtype_const H5D_chunk_index_t, H5D_CHUNK_IDX_SINGLE
+-- |Implicit: No Index (H5D_ALLOC_TIME_EARLY, non-filtered, fixed dims)
+#newtype_const H5D_chunk_index_t, H5D_CHUNK_IDX_NONE
+-- |Fixed array (for 0 unlimited dims)
+#newtype_const H5D_chunk_index_t, H5D_CHUNK_IDX_FARRAY
+-- |Extensible array (for 1 unlimited dim)
+#newtype_const H5D_chunk_index_t, H5D_CHUNK_IDX_EARRAY
+-- |v2 B-tree index (for >1 unlimited dims)
+#newtype_const H5D_chunk_index_t, H5D_CHUNK_IDX_BT2
+
+#num H5D_CHUNK_IDX_NTYPES
+
+#endif
+
+#endif
+
+-- |Values for the space allocation time property
+#newtype H5D_alloc_time_t, Eq
+#newtype_const H5D_alloc_time_t, H5D_ALLOC_TIME_ERROR
+#newtype_const H5D_alloc_time_t, H5D_ALLOC_TIME_DEFAULT
+#newtype_const H5D_alloc_time_t, H5D_ALLOC_TIME_EARLY
+#newtype_const H5D_alloc_time_t, H5D_ALLOC_TIME_LATE
+#newtype_const H5D_alloc_time_t, H5D_ALLOC_TIME_INCR
+
+-- |Values for the status of space allocation
+#newtype H5D_space_status_t, Eq
+#newtype_const H5D_space_status_t, H5D_SPACE_STATUS_ERROR
+#newtype_const H5D_space_status_t, H5D_SPACE_STATUS_NOT_ALLOCATED
+#newtype_const H5D_space_status_t, H5D_SPACE_STATUS_PART_ALLOCATED
+#newtype_const H5D_space_status_t, H5D_SPACE_STATUS_ALLOCATED
+
+-- |Values for time of writing fill value property
+#newtype H5D_fill_time_t, Eq
+#newtype_const H5D_fill_time_t, H5D_FILL_TIME_ERROR
+#newtype_const H5D_fill_time_t, H5D_FILL_TIME_ALLOC
+#newtype_const H5D_fill_time_t, H5D_FILL_TIME_NEVER
+#newtype_const H5D_fill_time_t, H5D_FILL_TIME_IFSET
+
+-- |Values for fill value status
+#newtype H5D_fill_value_t, Eq
+#newtype_const H5D_fill_value_t, H5D_FILL_VALUE_ERROR
+#newtype_const H5D_fill_value_t, H5D_FILL_VALUE_UNDEFINED
+#newtype_const H5D_fill_value_t, H5D_FILL_VALUE_DEFAULT
+#newtype_const H5D_fill_value_t, H5D_FILL_VALUE_USER_DEFINED
+
+#if H5_VERSION_GE(1,10,0)
+
+-- | Values for VDS bounds option
+#newtype H5D_vds_view_t, Eq
+#newtype_const H5D_vds_view_t, H5D_VDS_ERROR
+#newtype_const H5D_vds_view_t, H5D_VDS_FIRST_MISSING
+#newtype_const H5D_vds_view_t, H5D_VDS_LAST_AVAILABLE
+
+-- |Callback for H5Pset_append_flush() in a dataset access property list
+-- > typedef herr_t (*H5D_append_cb_t)(hid_t dataset_id, hsize_t *cur_dims, void *op_data)
+type H5D_append_cb_t a = FunPtr (HId_t -> Out HSize_t -> InOut a -> IO HErr_t)
+
+#endif
+
+-- |Operator function type for 'h5d_iterate'
+--
+-- Parameters:
+--
+-- [@ elem          :: 'InOut' a           @]    Pointer to the element in memory containing the current point.
+--
+-- [@ type_id       :: 'HId_t'             @]    Datatype ID for the elements stored in ELEM.
+--
+-- [@ ndim          :: 'CUInt'             @]    Number of dimensions for POINT array
+--
+-- [@ point         :: 'InArray' 'HSize_t' @]    Array containing the location of the element within the original dataspace.
+--
+-- [@ operator_data :: 'InOut' b           @]    Pointer to any user-defined data associated with the operation.
+--
+-- Return Values:
+--
+--  * Zero causes the iterator to continue, returning zero when all
+--    elements have been processed.
+--
+--  * Positive causes the iterator to immediately return that positive
+--    value, indicating short-circuit success.  The iterator can be
+--    restarted at the next element.
+--
+--  * Negative causes the iterator to immediately return that value,
+--    indicating failure. The iterator can be restarted at the next
+--    element.
+--
+-- > typedef herr_t (*H5D_operator_t)(void *elem, hid_t type_id, unsigned ndim,
+-- > 				 const hsize_t *point, void *operator_data);
+type H5D_operator_t a b = FunPtr (InOut a -> HId_t -> CUInt -> InArray HSize_t -> InOut b -> IO HErr_t)
+
+#if H5_VERSION_GE(1,8,11)
+
+-- I don't see any documentation for these callback types in the HDF5 distribution
+-- (though I didn't look very hard, it might be there somewhere)
+
+-- Define the operator function pointer for H5Dscatter()
+--
+-- > typedef herr_t (*H5D_scatter_func_t)(void **src_buf/*out*/,
+-- >                                      size_t *src_buf_bytes_used/*out*/,
+-- >                                      void *op_data);
+type H5D_scatter_func_t a b = FunPtr (Out (Ptr a) -> Out CSize -> InOut b -> IO HErr_t)
+
+-- Define the operator function pointer for H5Dgather()
+--
+-- > typedef herr_t (*H5D_gather_func_t)(const void *dst_buf,
+-- >                                     size_t dst_buf_bytes_used, void *op_data);
+type H5D_gather_func_t a b = FunPtr (InArray a -> CSize -> InOut b -> IO HErr_t)
+
+#endif /* H5_VERSION_GE */
+
+-- |Creates a new dataset named 'name' at 'loc_id', opens the
+-- dataset for access, and associates with that dataset constant
+-- and initial persistent properties including the type of each
+-- datapoint as stored in the file ('type_id'), the size of the
+-- dataset ('space_id'), and other initial miscellaneous
+-- properties ('dcpl_id').
+--
+-- All arguments are copied into the dataset, so the caller is
+-- allowed to derive new types, data spaces, and creation
+-- parameters from the old ones and reuse them in calls to
+-- create other datasets.
+--
+-- On success, returns the object ID of the new dataset.  At this
+-- point, the dataset is ready to receive its raw data.  Attempting
+-- to read raw data from the dataset will probably return the fill
+-- value.  The dataset should be closed when the caller is no longer
+-- interested in it.
+--
+-- On failure, returns a negative value.
+--
+-- > hid_t H5Dcreate2(hid_t loc_id, const char *name, hid_t type_id,
+-- >     hid_t space_id, hid_t lcpl_id, hid_t dcpl_id, hid_t dapl_id);
+#ccall H5Dcreate2, <hid_t> -> CString -> <hid_t> -> <hid_t> -> <hid_t> -> <hid_t> -> <hid_t> -> IO <hid_t>
+
+-- |Creates a new dataset named 'name' at 'loc_id', opens the
+-- dataset for access, and associates with that dataset constant
+-- and initial persistent properties including the type of each
+-- datapoint as stored in the file ('type_id'), the size of the
+-- dataset ('space_id'), and other initial miscellaneous
+-- properties ('dcpl_id').
+--
+-- All arguments are copied into the dataset, so the caller is
+-- allowed to derive new types, data spaces, and creation
+-- parameters from the old ones and reuse them in calls to
+-- create other datasets.
+--
+-- The resulting ID should be linked into the file with
+-- 'h5o_link' or it will be deleted when closed.
+--
+-- On success returns the object ID of the new dataset.  At this
+-- point, the dataset is ready to receive its raw data.  Attempting
+-- to read raw data from the dataset will probably return the fill
+-- value.  The dataset should be linked into the group hierarchy before
+-- being closed or it will be deleted.  The dataset should be closed
+-- when the caller is no longer interested in it.
+--
+-- On failure, returns a negative value.
+--
+-- > hid_t H5Dcreate_anon(hid_t file_id, hid_t type_id, hid_t space_id,
+-- >     hid_t plist_id, hid_t dapl_id);
+#ccall H5Dcreate_anon, <hid_t> -> <hid_t> -> <hid_t> -> <hid_t> -> <hid_t> -> IO <hid_t>
+
+-- |Finds a dataset named 'name' at 'loc_id', opens it, and returns
+-- its ID.	 The dataset should be close when the caller is no
+-- longer interested in it.
+--
+-- Takes a dataset access property list
+--
+-- On success, returns a new dataset ID.
+-- On failure, returns a negative value.
+--
+-- > hid_t H5Dopen2(hid_t file_id, const char *name, hid_t dapl_id);
+#ccall H5Dopen2, <hid_t> -> CString -> <hid_t> -> IO <hid_t>
+
+-- |Closes access to a dataset ('dset_id') and releases
+-- resources used by it. It is illegal to subsequently use that
+-- same dataset ID in calls to other dataset functions.
+--
+-- Returns non-negative on success / negative on failure
+--
+-- > herr_t H5Dclose(hid_t dset_id);
+#ccall H5Dclose, <hid_t> -> IO <herr_t>
+
+-- |Returns a copy of the file data space for a dataset.
+--
+-- On success, returns a new ID for a copy of the data space.  The data
+-- space should be released by calling 'h5s_close'.
+--
+-- > hid_t H5Dget_space(hid_t dset_id);
+#ccall H5Dget_space, <hid_t> -> IO <hid_t>
+
+-- |Gets the status of data space allocation.
+--
+-- Returns non-negative on success / negative on failure
+--
+-- > herr_t H5Dget_space_status(hid_t dset_id, H5D_space_status_t *allocation);
+#ccall H5Dget_space_status, <hid_t> -> Out H5D_space_status_t -> IO <herr_t>
+
+-- |Gets a copy of the file datatype for a dataset.
+--
+-- On success, returns the ID for a copy of the datatype.  The data type
+-- should be released by calling 'h5t_close'.
+-- On failure, returns a negative value.
+--
+-- > hid_t H5Dget_type(hid_t dset_id);
+#ccall H5Dget_type, <hid_t> -> IO <hid_t>
+
+-- |Gets a copy of the dataset creation property list.
+--
+-- On success, returns the ID for a copy of the dataset creation
+-- property list.  The template should be released by calling 'h5p_close'.
+--
+-- > hid_t H5Dget_create_plist(hid_t dset_id);
+#ccall H5Dget_create_plist, <hid_t> -> IO <hid_t>
+
+#if H5_VERSION_GE(1,8,3)
+-- |Returns a copy of the dataset creation property list of the specified
+-- dataset.
+--
+-- The chunk cache parameters in the returned property lists will be
+-- those used by the dataset.  If the properties in the file access
+-- property list were used to determine the dataset's chunk cache
+-- configuration, then those properties will be present in the
+-- returned dataset access property list.  If the dataset does not
+-- use a chunked layout, then the chunk cache properties will be set
+-- to the default.  The chunk cache properties in the returned list
+-- are considered to be \"set\", and any use of this list will override
+-- the corresponding properties in the file's file access property
+-- list.
+--
+-- All link access properties in the returned list will be set to the
+-- default values.
+--
+-- On success, returns the ID for a copy of the dataset access
+-- property list.  The template should be released by calling 'h5p_close'.
+-- On failure, returns a negative value.
+--
+-- > hid_t H5Dget_access_plist(hid_t dset_id);
+#ccall H5Dget_access_plist, <hid_t> -> IO <hid_t>
+#endif
+
+-- |Returns the amount of storage that is required for the
+-- dataset. For chunked datasets this is the number of allocated
+-- chunks times the chunk size.
+--
+-- On success, returns the amount of storage space allocated for the
+-- dataset, not counting meta data. The return value may be zero if
+-- no data has been stored.
+--
+-- On failure, returns zero.
+--
+-- > hsize_t H5Dget_storage_size(hid_t dset_id);
+#ccall H5Dget_storage_size, <hid_t> -> IO <hsize_t>
+
+-- |Returns the address of dataset in file, or 'hADDR_UNDEF' on failure.
+--
+-- > haddr_t H5Dget_offset(hid_t dset_id);
+#ccall H5Dget_offset, <hid_t> -> IO <haddr_t>
+
+-- |Reads (part of) a data set from the file into application
+-- memory 'buf'. The part of the dataset to read is defined with
+-- 'mem_space_id' and 'file_space_id'. The data points are
+-- converted from their file type to the 'mem_type_id' specified.
+-- Additional miscellaneous data transfer properties can be
+-- passed to this function with the 'plist_id' argument.
+--
+-- The 'file_space_id' can be the constant 'h5s_ALL' which indicates
+-- that the entire file data space is to be referenced.
+--
+-- The 'mem_space_id' can be the constant 'h5s_ALL' in which case
+-- the memory data space is the same as the file data space
+-- defined when the dataset was created.
+--
+-- The number of elements in the memory data space must match
+-- the number of elements in the file data space.
+--
+-- The 'plist_id' can be the constant 'h5p_DEFAULT' in which
+-- case the default data transfer properties are used.
+--
+-- Returns non-negative on success / negative on failure.
+--
+-- > herr_t H5Dread(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
+-- >        hid_t file_space_id, hid_t plist_id, void *buf/*out*/);
+#ccall H5Dread, <hid_t> -> <hid_t> -> <hid_t> -> <hid_t> -> <hid_t> -> OutArray a -> IO <herr_t>
+
+-- |Writes (part of) a data set from application memory 'buf' to the
+-- file.  The part of the dataset to write is defined with the
+-- 'mem_space_id' and 'file_space_id' arguments. The data points
+-- are converted from their current type ('mem_type_id') to their
+-- file datatype.  Additional miscellaneous data transfer
+-- properties can be passed to this function with the
+-- 'plist_id' argument.
+--
+-- The 'file_space_id' can be the constant 'h5s_ALL' which indicates
+-- that the entire file data space is to be referenced.
+--
+-- The 'mem_space_id' can be the constant 'h5s_ALL' in which case
+-- the memory data space is the same as the file data space
+-- defined when the dataset was created.
+--
+-- The number of elements in the memory data space must match
+-- the number of elements in the file data space.
+--
+-- The 'plist_id' can be the constant 'h5p_DEFAULT' in which
+-- case the default data transfer properties are used.
+--
+-- Returns non-negative on success / negative on failure.
+--
+-- > herr_t H5Dwrite(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
+-- >        hid_t file_space_id, hid_t plist_id, const void *buf);
+#ccall H5Dwrite, <hid_t> -> <hid_t> -> <hid_t> -> <hid_t> -> <hid_t> -> InArray a -> IO <herr_t>
+
+-- TODO: verify that 'buf' is mutable
+-- |This routine iterates over all the elements selected in a memory
+-- buffer.  The callback function is called once for each element selected
+-- in the dataspace.  The selection in the dataspace is modified so
+-- that any elements already iterated over are removed from the selection
+-- if the iteration is interrupted (by the 'H5D_operator_t' function
+-- returning non-zero) in the \"middle\" of the iteration and may be
+-- re-started by the user where it left off.
+--
+-- NOTE: Until \"subtracting\" elements from a selection is implemented,
+--     the selection is not modified.
+--
+-- Parameters:
+--
+-- [@ buf           :: 'InOut' a            @]    Pointer to the buffer in memory containing the elements to iterate over.
+--
+-- [@ type_id       :: 'HId_t'              @]    Datatype ID for the elements stored in 'buf'.
+--
+-- [@ space_id      :: 'HId_t'              @]    Dataspace ID for 'buf', also contains the selection to iterate over.
+--
+-- [@ op            :: 'H5D_operator_t' a b @]    Function pointer to the routine to be called for each element in 'buf' iterated over.
+--
+-- [@ operator_data :: 'InOut' b            @]    Pointer to any user-defined data associated with the operation.
+--
+-- Returns the return value of the last operator if it was non-zero,
+-- or zero if all elements were processed. Otherwise returns a
+-- negative value.
+--
+-- > herr_t H5Diterate(void *buf, hid_t type_id, hid_t space_id,
+-- >        H5D_operator_t op, void *operator_data);
+#ccall H5Diterate, InOutArray a -> <hid_t> -> <hid_t> -> H5D_operator_t a b -> InOut b -> IO <herr_t>
+
+-- |Frees the buffers allocated for storing variable-length data
+-- in memory.  Only frees the VL data in the selection defined in the
+-- dataspace.  The dataset transfer property list is required to find the
+-- correct allocation/free methods for the VL data in the buffer.
+--
+-- Returns non-negative on success, negative on failure
+--
+-- > herr_t H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf);
+#ccall H5Dvlen_reclaim, <hid_t> -> <hid_t> -> <hid_t> -> Ptr a -> IO <herr_t>
+
+-- |This routine checks the number of bytes required to store the VL
+-- data from the dataset, using the 'space_id' for the selection in the
+-- dataset on disk and the 'type_id' for the memory representation of the
+-- VL data, in memory.  The 'size' value is modified according to how many
+-- bytes are required to store the VL data in memory.
+--
+-- This routine actually performs the read with a custom
+-- memory manager which basically just counts the bytes requested and
+-- uses a temporary memory buffer (through the H5FL API) to make certain
+-- enough space is available to perform the read.  Then the temporary
+-- buffer is released and the number of bytes allocated is returned.
+-- Kinda kludgy, but easier than the other method of trying to figure out
+-- the sizes without actually reading the data in... - QAK
+--
+-- Returns non-negative on success, negative on failure
+--
+-- > herr_t H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id, hsize_t *size);
+#ccall H5Dvlen_get_buf_size, <hid_t> -> <hid_t> -> <hid_t> -> Out <hsize_t> -> IO <herr_t>
+
+-- TODO: this explanation is incomprehensible.  Improve it.
+-- |Fill a selection in memory with a value.
+-- Use the selection in the dataspace to fill elements in a memory buffer.
+-- If "fill" parameter is NULL, uses all zeros as fill value
+--
+-- Parameters:
+--
+-- [@ fill         :: 'In' a    @]  Pointer to fill value to use
+-- [@ fill_type_id :: 'HId_t'   @]  Datatype of the fill value
+-- [@ buf          :: 'InOut' b @]  Memory buffer to fill selection within
+-- [@ buf_type_id  :: 'HId_t'   @]  Datatype of the elements in buffer
+-- [@ space_id     :: 'HId_t'   @]  Dataspace describing memory buffer & containing selection to use.
+--
+-- Returns non-negative on success / negative on failure.
+--
+-- > herr_t H5Dfill(const void *fill, hid_t fill_type, void *buf,
+-- >         hid_t buf_type, hid_t space);
+#ccall H5Dfill, In a -> <hid_t> -> InOutArray b -> <hid_t> -> <hid_t> -> IO <herr_t>
+
+-- |Modifies the dimensions of a dataset.  Can change to a smaller dimension.
+--
+-- Returns non-negative on success, negative on failure
+--
+-- > herr_t H5Dset_extent(hid_t dset_id, const hsize_t size[]);
+#ccall H5Dset_extent, <hid_t> -> InArray <hsize_t> -> IO <herr_t>
+
+#if H5_VERSION_GE(1,10,0)
+
+-- > H5_DLL herr_t H5Dflush(hid_t dset_id);
+#ccall H5Dflush, <hid_t> -> IO <herr_t>
+
+-- > H5_DLL herr_t H5Drefresh(hid_t dset_id);                                
+#ccall H5Drefresh, <hid_t> -> IO <herr_t>
+
+#endif
+
+#if H5_VERSION_GE(1,8,11)
+
+-- |Scatters data provided by the callback op to the
+-- destination buffer dst_buf, where the dimensions of
+-- dst_buf and the selection to be scattered to are specified
+-- by the dataspace dst_space_id.  The type of the data to be
+-- scattered is specified by type_id.
+--
+-- Returns non-negative on success, negative on failure
+--
+-- > herr_t H5Dscatter(H5D_scatter_func_t op, void *op_data, hid_t type_id,
+-- >     hid_t dst_space_id, void *dst_buf);
+#ccall H5Dscatter, H5D_scatter_func_t a b -> InOut b -> <hid_t> -> <hid_t> -> OutArray a -> IO <herr_t>
+
+-- |Gathers data provided from the source buffer src_buf to
+-- contiguous buffer dst_buf, then calls the callback op.
+-- The dimensions of src_buf and the selection to be gathered
+-- are specified by the dataspace src_space_id.  The type of
+-- the data to be gathered is specified by type_id.
+--
+-- Returns non-negative on success, negative on failure
+--
+-- > herr_t H5Dgather(hid_t src_space_id, const void *src_buf, hid_t type_id,
+-- >     size_t dst_buf_size, void *dst_buf, H5D_gather_func_t op, void *op_data);
+#ccall H5Dgather, <hid_t> -> InArray a -> <hid_t> -> <size_t> -> OutArray a -> H5D_gather_func_t a b -> InOut b -> IO <herr_t>
+
+#endif /* H5_VERSION_GE */
+
+-- |Prints various information about a dataset.  This function is not to be
+-- documented in the API at this time.
+--
+-- Returns non-negative on success, negative on failure
+--
+-- > herr_t H5Ddebug(hid_t dset_id);
+#ccall H5Ddebug, <hid_t> -> IO <herr_t>
+
+#if H5_VERSION_GE(1,10,0)
+
+-- |Internal API routines
+-- > H5_DLL herr_t H5Dformat_convert(hid_t dset_id);
+#ccall H5Dformat_convert, <hid_t> -> IO <herr_t>
+
+-- > H5_DLL herr_t H5Dget_chunk_index_type(hid_t did, H5D_chunk_index_t *idx_type);
+#ccall H5Dget_chunk_index_type, <hid_t> -> IO H5D_chunk_index_t
+
+#endif
+
+#ifndef H5_NO_DEPRECATED_SYMBOLS
+
+-- |Creates a new dataset named 'name' at 'loc_id', opens the
+-- dataset for access, and associates with that dataset constant
+-- and initial persistent properties including the type of each
+-- datapoint as stored in the file ('type_id'), the size of the
+-- dataset ('space_id'), and other initial miscellaneous
+-- properties ('dcpl_id').
+--
+-- All arguments are copied into the dataset, so the caller is
+-- allowed to derive new types, data spaces, and creation
+-- parameters from the old ones and reuse them in calls to
+-- create other datasets.
+--
+-- On success, returns the object ID of the new dataset.  At this
+-- point, the dataset is ready to receive its raw data.  Attempting
+-- to read raw data from the dataset will probably return the fill
+-- value.  The dataset should be closed when the caller is no longer
+-- interested in it.
+--
+-- On failure, returns a negative value.
+--
+-- Note:  Deprecated in favor of 'h5d_create2'
+--
+-- > hid_t H5Dcreate1(hid_t file_id, const char *name, hid_t type_id,
+-- >     hid_t space_id, hid_t dcpl_id);
+#ccall H5Dcreate1, <hid_t> -> CString -> <hid_t> -> <hid_t> -> <hid_t> -> IO <hid_t>
+
+-- |Finds a dataset named 'name' at 'loc_id', opens it, and returns
+-- its ID.  The dataset should be closed when the caller is no
+-- longer interested in it.
+--
+-- On success returns a new dataset ID.
+-- On failure, returns a negative value.
+--
+-- Note:  Deprecated in favor of 'h5d_open2'
+--
+-- > hid_t H5Dopen1(hid_t file_id, const char *name);
+#ccall H5Dopen1, <hid_t> -> CString -> IO <hid_t>
+
+-- |This function makes sure that the dataset is at least of size
+-- 'size'. The dimensionality of 'size' is the same as the data
+-- space of the dataset being changed.
+--
+-- Note:  Deprecated in favor of 'h5d_set_extent'
+--
+-- Returns non-negative on success / negative on failure
+--
+-- > herr_t H5Dextend(hid_t dset_id, const hsize_t size[]);
+#ccall H5Dextend, <hid_t> -> InArray <hsize_t> -> IO <herr_t>
+
+#endif /* H5_NO_DEPRECATED_SYMBOLS */
diff --git a/src/Bindings/HDF5/Raw/H5E.hsc b/src/Bindings/HDF5/Raw/H5E.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/H5E.hsc
@@ -0,0 +1,767 @@
+#include <bindings.h>
+#include <H5Epublic.h>
+
+module Bindings.HDF5.Raw.H5E where
+
+import Data.Int
+import Data.Word
+import Foreign.C.String
+import Foreign.C.Types
+import Foreign.Marshal.Alloc
+import Control.Monad
+import Foreign.Ptr
+import Foreign.Storable
+
+import Foreign.LibFFI
+
+import Bindings.HDF5.Raw.H5
+import Bindings.HDF5.Raw.H5I
+import Foreign.Ptr.Conventions
+
+-- |Value for the default error stack
+#newtype_const hid_t, H5E_DEFAULT
+
+-- |Different kinds of error information
+#newtype H5E_type_t
+#newtype_const H5E_type_t, H5E_MAJOR
+#newtype_const H5E_type_t, H5E_MINOR
+
+-- |Information about an error; element of error stack
+#starttype H5E_error2_t
+
+-- | class ID
+#field cls_id,       <hid_t>
+
+-- | major error ID
+#field maj_num,      <hid_t>
+
+-- | minor error number
+#field min_num,      <hid_t>
+
+-- | line in file where error occurs
+#field line,         CUInt
+
+-- | function in which error occurred
+#field func_name,    CString
+
+-- | file in which error occurred
+#field file_name,    CString
+
+-- | optional supplied description
+#field desc,         CString
+#stoptype
+
+-- |HDF5 error class
+#cinline H5E_ERR_CLS,           <hid_t>
+
+-- * Major error codes
+
+-- |Dataset
+#cinline H5E_DATASET,           <hid_t>
+
+-- |Function entry/exit
+#cinline H5E_FUNC,              <hid_t>
+
+-- |Data storage
+#cinline H5E_STORAGE,           <hid_t>
+
+-- |File accessibility
+#cinline H5E_FILE,              <hid_t>
+
+-- |Shared Object Header Messages
+#cinline H5E_SOHM,              <hid_t>
+
+-- |Symbol table
+#cinline H5E_SYM,               <hid_t>
+
+#if H5_VERSION_GE(1,8,11)
+
+-- |Plugin for dynamically loaded library
+#cinline H5E_PLUGIN,            <hid_t>
+
+#endif /* H5_VERSION_GE */
+
+-- |Virtual File Layer
+#cinline H5E_VFL,               <hid_t>
+
+-- |Internal error (too specific to document in detail)
+#cinline H5E_INTERNAL,          <hid_t>
+
+-- |B-Tree node
+#cinline H5E_BTREE,             <hid_t>
+
+-- |References
+#cinline H5E_REFERENCE,         <hid_t>
+
+-- |Dataspace
+#cinline H5E_DATASPACE,         <hid_t>
+
+-- |Resource unavailable
+#cinline H5E_RESOURCE,          <hid_t>
+
+-- |Property lists
+#cinline H5E_PLIST,             <hid_t>
+
+-- |Links
+#cinline H5E_LINK,              <hid_t>
+
+-- |Datatype
+#cinline H5E_DATATYPE,          <hid_t>
+
+-- |Reference Counted Strings
+#cinline H5E_RS,                <hid_t>
+
+-- |Heap
+#cinline H5E_HEAP,              <hid_t>
+
+-- |Object header
+#cinline H5E_OHDR,              <hid_t>
+
+-- |Object atom
+#cinline H5E_ATOM,              <hid_t>
+
+-- |Attribute
+#cinline H5E_ATTR,              <hid_t>
+
+-- |No error
+#cinline H5E_NONE_MAJOR,        <hid_t>
+
+-- |Low-level I/O
+#cinline H5E_IO,                <hid_t>
+
+-- |Skip Lists
+#cinline H5E_SLIST,             <hid_t>
+
+-- |External file list
+#cinline H5E_EFL,               <hid_t>
+
+-- |Ternary Search Trees
+#cinline H5E_TST,               <hid_t>
+
+-- |Invalid arguments to routine
+#cinline H5E_ARGS,              <hid_t>
+
+-- |Error API
+#cinline H5E_ERROR,             <hid_t>
+
+-- |Data filters
+#cinline H5E_PLINE,             <hid_t>
+
+-- |Free Space Manager
+#cinline H5E_FSPACE,            <hid_t>
+
+-- |Object cache
+#cinline H5E_CACHE,             <hid_t>
+
+-- * Minor error codes
+
+-- ** Generic low-level file I/O errors
+
+-- |Seek failed
+#cinline H5E_SEEKERROR,         <hid_t>
+
+-- |Read failed
+#cinline H5E_READERROR,         <hid_t>
+
+-- |Write failed
+#cinline H5E_WRITEERROR,        <hid_t>
+
+-- |Close failed
+#cinline H5E_CLOSEERROR,        <hid_t>
+
+-- |Address overflowed
+#cinline H5E_OVERFLOW,          <hid_t>
+
+-- |File control (fcntl) failed
+#cinline H5E_FCNTL,             <hid_t>
+
+-- ** Resource errors
+
+-- |No space available for allocation
+#cinline H5E_NOSPACE,           <hid_t>
+
+-- |Can't allocate space
+#cinline H5E_CANTALLOC,         <hid_t>
+
+-- |Unable to copy object
+#cinline H5E_CANTCOPY,          <hid_t>
+
+-- |Unable to free object
+#cinline H5E_CANTFREE,          <hid_t>
+
+-- |Object already exists
+#cinline H5E_ALREADYEXISTS,     <hid_t>
+
+-- |Unable to lock object
+#cinline H5E_CANTLOCK,          <hid_t>
+
+-- |Unable to unlock object
+#cinline H5E_CANTUNLOCK,        <hid_t>
+
+-- |Unable to garbage collect
+#cinline H5E_CANTGC,            <hid_t>
+
+-- |Unable to compute size
+#cinline H5E_CANTGETSIZE,       <hid_t>
+
+-- |Object is already open
+#cinline H5E_OBJOPEN,           <hid_t>
+
+-- ** Heap errors
+#cinline H5E_CANTRESTORE,       <hid_t>
+#cinline H5E_CANTCOMPUTE,       <hid_t>
+#cinline H5E_CANTEXTEND,        <hid_t>
+#cinline H5E_CANTATTACH,        <hid_t>
+#cinline H5E_CANTUPDATE,        <hid_t>
+#cinline H5E_CANTOPERATE,       <hid_t>
+
+-- ** Function entry/exit interface errors
+#cinline H5E_CANTINIT,          <hid_t>
+#cinline H5E_ALREADYINIT,       <hid_t>
+#cinline H5E_CANTRELEASE,       <hid_t>
+
+-- ** Property list errors
+#cinline H5E_CANTGET,           <hid_t>
+#cinline H5E_CANTSET,           <hid_t>
+#cinline H5E_DUPCLASS,          <hid_t>
+
+#if H5_VERSION_GE(1,8,9)
+#cinline H5E_SETDISALLOWED,     <hid_t>
+#endif
+
+-- ** Free space errors
+#cinline H5E_CANTMERGE,         <hid_t>
+#cinline H5E_CANTREVIVE,        <hid_t>
+#cinline H5E_CANTSHRINK,        <hid_t>
+
+-- ** Object header related errors
+#cinline H5E_LINKCOUNT,         <hid_t>
+#cinline H5E_VERSION,           <hid_t>
+#cinline H5E_ALIGNMENT,         <hid_t>
+#cinline H5E_BADMESG,           <hid_t>
+#cinline H5E_CANTDELETE,        <hid_t>
+#cinline H5E_BADITER,           <hid_t>
+#cinline H5E_CANTPACK,          <hid_t>
+#cinline H5E_CANTRESET,         <hid_t>
+#cinline H5E_CANTRENAME,        <hid_t>
+
+-- ** System level errors
+#cinline H5E_SYSERRSTR,         <hid_t>
+
+-- ** I/O pipeline errors
+#cinline H5E_NOFILTER,          <hid_t>
+#cinline H5E_CALLBACK,          <hid_t>
+#cinline H5E_CANAPPLY,          <hid_t>
+#cinline H5E_SETLOCAL,          <hid_t>
+#cinline H5E_NOENCODER,         <hid_t>
+#cinline H5E_CANTFILTER,        <hid_t>
+
+-- ** Group related errors
+#cinline H5E_CANTOPENOBJ,       <hid_t>
+#cinline H5E_CANTCLOSEOBJ,      <hid_t>
+#cinline H5E_COMPLEN,           <hid_t>
+#cinline H5E_PATH,              <hid_t>
+
+-- ** No error
+#cinline H5E_NONE_MINOR,        <hid_t>
+
+#if H5_VERSION_GE(1,8,11)
+
+-- ** Plugin errors
+#cinline H5E_OPENERROR,         <hid_t>
+
+#endif /* H5_VERSION_GE */
+
+-- ** File accessibility errors
+#cinline H5E_FILEEXISTS,        <hid_t>
+#cinline H5E_FILEOPEN,          <hid_t>
+#cinline H5E_CANTCREATE,        <hid_t>
+#cinline H5E_CANTOPENFILE,      <hid_t>
+#cinline H5E_CANTCLOSEFILE,     <hid_t>
+#cinline H5E_NOTHDF5,           <hid_t>
+#cinline H5E_BADFILE,           <hid_t>
+#cinline H5E_TRUNCATED,         <hid_t>
+#cinline H5E_MOUNT,             <hid_t>
+
+-- ** Object atom related errors
+#cinline H5E_BADATOM,           <hid_t>
+#cinline H5E_BADGROUP,          <hid_t>
+#cinline H5E_CANTREGISTER,      <hid_t>
+#cinline H5E_CANTINC,           <hid_t>
+#cinline H5E_CANTDEC,           <hid_t>
+#cinline H5E_NOIDS,             <hid_t>
+
+-- ** Cache related errors
+#cinline H5E_CANTFLUSH,         <hid_t>
+#cinline H5E_CANTSERIALIZE,     <hid_t>
+#cinline H5E_CANTLOAD,          <hid_t>
+#cinline H5E_PROTECT,           <hid_t>
+#cinline H5E_NOTCACHED,         <hid_t>
+#cinline H5E_SYSTEM,            <hid_t>
+#cinline H5E_CANTINS,           <hid_t>
+#cinline H5E_CANTPROTECT,       <hid_t>
+#cinline H5E_CANTUNPROTECT,     <hid_t>
+#cinline H5E_CANTPIN,           <hid_t>
+#cinline H5E_CANTUNPIN,         <hid_t>
+#cinline H5E_CANTMARKDIRTY,     <hid_t>
+#cinline H5E_CANTDIRTY,         <hid_t>
+#cinline H5E_CANTEXPUNGE,       <hid_t>
+#cinline H5E_CANTRESIZE,        <hid_t>
+
+-- ** Link related errors
+#cinline H5E_TRAVERSE,          <hid_t>
+#cinline H5E_NLINKS,            <hid_t>
+#cinline H5E_NOTREGISTERED,     <hid_t>
+#cinline H5E_CANTMOVE,          <hid_t>
+#cinline H5E_CANTSORT,          <hid_t>
+
+-- ** Parallel MPI errors
+#cinline H5E_MPI,               <hid_t>
+#cinline H5E_MPIERRSTR,         <hid_t>
+#cinline H5E_CANTRECV,          <hid_t>
+
+-- ** Dataspace errors
+#cinline H5E_CANTCLIP,          <hid_t>
+#cinline H5E_CANTCOUNT,         <hid_t>
+#cinline H5E_CANTSELECT,        <hid_t>
+#cinline H5E_CANTNEXT,          <hid_t>
+#cinline H5E_BADSELECT,         <hid_t>
+#cinline H5E_CANTCOMPARE,       <hid_t>
+
+-- ** Argument errors
+#cinline H5E_UNINITIALIZED,     <hid_t>
+#cinline H5E_UNSUPPORTED,       <hid_t>
+#cinline H5E_BADTYPE,           <hid_t>
+#cinline H5E_BADRANGE,          <hid_t>
+#cinline H5E_BADVALUE,          <hid_t>
+
+-- ** B-tree related errors
+#cinline H5E_NOTFOUND,          <hid_t>
+#cinline H5E_EXISTS,            <hid_t>
+#cinline H5E_CANTENCODE,        <hid_t>
+#cinline H5E_CANTDECODE,        <hid_t>
+#cinline H5E_CANTSPLIT,         <hid_t>
+#cinline H5E_CANTREDISTRIBUTE,  <hid_t>
+#cinline H5E_CANTSWAP,          <hid_t>
+#cinline H5E_CANTINSERT,        <hid_t>
+#cinline H5E_CANTLIST,          <hid_t>
+#cinline H5E_CANTMODIFY,        <hid_t>
+#cinline H5E_CANTREMOVE,        <hid_t>
+
+-- ** Datatype conversion errors
+#cinline H5E_CANTCONVERT,       <hid_t>
+#cinline H5E_BADSIZE,           <hid_t>
+
+newtype H5E_TRY_STATE
+    = H5E_TRY_STATE (Either (H5E_auto1_t ()) (H5E_auto2_t ()), InOut ())
+
+h5e_BEGIN_TRY :: IO H5E_TRY_STATE
+h5e_BEGIN_TRY = do
+    isV2 <- alloca $ \isV2 -> do
+        void $ h5e_auto_is_v2 h5e_DEFAULT (Out isV2)
+        peek isV2
+
+    alloca $ \cdata -> if isV2 /= 0
+        then alloca $ \func -> do
+            void $ h5e_get_auto2 h5e_DEFAULT (Out func) (Out cdata)
+            void $ h5e_set_auto2 h5e_DEFAULT nullFunPtr (InOut nullPtr)
+
+            func_ <- peek func
+            cdata_ <- peek cdata
+            return (H5E_TRY_STATE (Right func_, cdata_))
+        else alloca $ \func -> do
+            void $ h5e_get_auto1 (Out func) (Out cdata)
+            void $ h5e_set_auto1 nullFunPtr (InOut nullPtr)
+
+            func_ <- peek func
+            cdata_ <- peek cdata
+            return (H5E_TRY_STATE (Left func_, cdata_))
+
+h5e_END_TRY :: H5E_TRY_STATE -> IO HErr_t
+h5e_END_TRY (H5E_TRY_STATE (Right func, cdata)) = h5e_set_auto2 h5e_DEFAULT func cdata
+h5e_END_TRY (H5E_TRY_STATE (Left  func, cdata)) = h5e_set_auto1 func cdata
+
+-- |This is not a standard HDF5 function or macro, but rather a wrapper
+-- to the paired macros H5E_BEGIN_TRY and H5E_END_TRY, wrapping a simple action.
+h5e_try :: IO a -> IO a
+h5e_try action = do
+    tryState <- h5e_BEGIN_TRY
+    result <- action
+    void $ h5e_END_TRY tryState
+    return result
+
+-- TODO: wrap these up in an exported header file (something like "Bindings.HDF5.Raw.H5E.h") as macros for use in haskell code, or maybe as TH macros
+-- /*
+--  * Public API Convenience Macros for Error reporting - Documented
+--  */
+-- /* Use the Standard C __FILE__ & __LINE__ macros instead of typing them in */
+-- #define H5Epush_sim(func, cls, maj, min, str) H5Epush2(H5E_DEFAULT, __FILE__, func, __LINE__, cls, maj, min, str)
+--
+-- /*
+--  * Public API Convenience Macros for Error reporting - Undocumented
+--  */
+-- /* Use the Standard C __FILE__ & __LINE__ macros instead of typing them in */
+-- /*  And return after pushing error onto stack */
+-- #define H5Epush_ret(func, cls, maj, min, str, ret) {			      \
+--     H5Epush2(H5E_DEFAULT, __FILE__, func, __LINE__, cls, maj, min, str);      \
+--     return(ret);							      \
+-- }
+--
+-- /* Use the Standard C __FILE__ & __LINE__ macros instead of typing them in
+--  * And goto a label after pushing error onto stack.
+--  */
+-- #define H5Epush_goto(func, cls, maj, min, str, label) {			      \
+--     H5Epush2(H5E_DEFAULT, __FILE__, func, __LINE__, cls, maj, min, str);      \
+--     goto label;								      \
+-- }
+
+-- |Error stack traversal direction
+#newtype H5E_direction_t
+
+-- |begin deep, end at API function
+#newtype_const H5E_direction_t, H5E_WALK_UPWARD
+
+-- |begin at API function, end deep
+#newtype_const H5E_direction_t, H5E_WALK_DOWNWARD
+
+-- * Error stack traversal callback function types
+
+-- |Callback type for 'h5e_walk2'
+--
+-- > typedef herr_t (*H5E_walk2_t)(unsigned n, const H5E_error2_t *err_desc,
+-- >     void *client_data);
+type H5E_walk2_t a = FunPtr (CUInt -> In H5E_error2_t -> InOut a -> IO HErr_t)
+
+-- |Callback type for 'h5e_set_auto2'
+--
+-- > typedef herr_t (*H5E_auto2_t)(hid_t estack, void *client_data);
+type H5E_auto2_t a = FunPtr (HId_t -> InOut a -> IO HErr_t)
+
+-- * Public API functions
+
+-- |Registers an error class.
+--
+-- Returns non-negative value as class ID on success / negative on failure
+--
+-- > hid_t  H5Eregister_class(const char *cls_name, const char *lib_name,
+-- >     const char *version);
+#ccall H5Eregister_class, CString -> CString -> CString -> IO <hid_t>
+
+-- |Closes an error class.
+--
+-- Returns non-negative value on success / negative on failure
+--
+-- > herr_t H5Eunregister_class(hid_t class_id);
+#ccall H5Eunregister_class, <hid_t> -> IO <herr_t>
+
+-- |Closes a major or minor error.
+--
+-- Returns non-negative value on success / negative on failure
+--
+-- > herr_t H5Eclose_msg(hid_t err_id);
+#ccall H5Eclose_msg, <hid_t> -> IO <herr_t>
+
+-- |Creates a major or minor error, returns an ID.
+--
+-- Returns non-negative value on success / negative on failure
+--
+-- > hid_t  H5Ecreate_msg(hid_t cls, H5E_type_t msg_type, const char *msg);
+#ccall H5Ecreate_msg, <hid_t> -> H5E_type_t -> CString -> IO <hid_t>
+
+-- |Creates a new, empty, error stack.
+--
+-- Returns non-negative value as stack ID on success / negative on failure
+--
+-- > hid_t  H5Ecreate_stack(void);
+#ccall H5Ecreate_stack, IO <hid_t>
+
+-- |Registers current error stack, returns object handle for it, clears it.
+--
+-- Returns non-negative value as stack ID on success / negative on failure
+--
+-- > hid_t  H5Eget_current_stack(void);
+#ccall H5Eget_current_stack, IO <hid_t>
+
+-- |Closes an error stack.
+--
+-- Returns non-negative value on success / negative on failure
+--
+-- > herr_t H5Eclose_stack(hid_t stack_id);
+#ccall H5Eclose_stack, <hid_t> -> IO <herr_t>
+
+-- |Retrieves error class name.
+--
+-- Returns non-negative for name length if succeeds(zero means no name);
+-- otherwise returns negative value.
+--
+-- On successful return, 'name' will always be zero-terminated.
+--
+-- NB: The return value is the length of the name, not the length copied
+-- to the buffer.
+--
+-- > ssize_t H5Eget_class_name(hid_t class_id, char *name, size_t size);
+#ccall H5Eget_class_name, <hid_t> -> OutArray CChar -> <size_t> -> IO <ssize_t>
+
+-- |Replaces current stack with specified stack.  This closes the
+-- stack ID also.
+--
+-- Returns non-negative value on success / negative on failure
+--
+-- > herr_t H5Eset_current_stack(hid_t err_stack_id);
+#ccall H5Eset_current_stack, <hid_t> -> IO <herr_t>
+
+-- libffi to the rescue!  I have no idea how I'd wrap this without it, and there
+-- doesn't appear to be a non-deprecated non-private non-varargs equivalent.
+--
+-- |Pushes a new error record onto error stack for the current
+-- thread.  The error has major and minor IDs 'maj_id' and
+-- 'min_id', the name of a function where the error was detected,
+-- the name of the file where the error was detected, the
+-- line within that file, and an error description string.  The
+-- function name, file name, and error description strings must
+-- be statically allocated.
+--
+-- Returns non-negative on success/Negative on failure.
+--
+-- > herr_t H5Epush2(hid_t err_stack, const char *file, const char *func, unsigned line,
+-- >     hid_t cls_id, hid_t maj_id, hid_t min_id, const char *msg, ...);
+--
+-- (msg is a printf format string, the varargs are the format parameters)
+h5e_push2 :: HId_t -> CString -> CString -> CUInt -> HId_t -> HId_t -> HId_t -> CString -> [Arg] -> IO HErr_t
+h5e_push2 err_stack file func line cls_id maj_id min_id fmt [] =
+    h5e_push2_no_varargs err_stack file func line cls_id maj_id min_id fmt
+h5e_push2 (HId_t err_stack) file func line (HId_t cls_id) (HId_t maj_id) (HId_t min_id) fmt varargs =
+    callFFI p_H5Epush2 retHErr_t args
+    where
+        argHId_t = arg#type hid_t
+        retHErr_t = fmap HErr_t (ret#type herr_t)
+
+        args = argHId_t err_stack : argPtr file : argPtr func : argCUInt line
+             : argHId_t cls_id : argHId_t maj_id : argHId_t min_id : argPtr fmt
+             : varargs
+
+foreign import ccall "H5Epush2"
+    h5e_push2_no_varargs :: HId_t -> CString -> CString -> CUInt -> HId_t -> HId_t -> HId_t -> CString -> IO HErr_t
+foreign import ccall "&H5Epush2"
+    p_H5Epush2 :: FunPtr (HId_t -> CString -> CString -> CUInt -> HId_t -> HId_t -> HId_t -> CString -> IO HErr_t)
+
+-- |Deletes some error messages from the top of error stack.
+--
+-- Returns non-negative value on success / negative on failure
+--
+-- > herr_t H5Epop(hid_t err_stack, size_t count);
+#ccall H5Epop, <hid_t> -> <size_t> -> IO <herr_t>
+
+-- |Prints the error stack in some default way.  This is just a
+-- convenience function for 'h5e_walk' with a function that
+-- prints error messages.  Users are encouraged to write their
+-- own more specific error handlers.
+--
+-- Returns non-negative on success / negative on failure
+--
+-- > herr_t H5Eprint2(hid_t err_stack, FILE *stream);
+#ccall H5Eprint2, <hid_t> -> InOut CFile -> IO <herr_t>
+
+-- |Walks the error stack for the current thread and calls some
+-- function for each error along the way.
+--
+-- Returns non-negative on success / negative on failure
+--
+-- > herr_t H5Ewalk2(hid_t err_stack, H5E_direction_t direction, H5E_walk2_t func,
+-- >     void *client_data);
+#ccall H5Ewalk2, <hid_t> -> <H5E_direction_t> -> H5E_walk2_t a -> InOut a -> IO <herr_t>
+
+-- |Returns the current settings for the automatic error stack
+-- traversal function and its data for specific error stack.
+-- Either (or both) arguments may be null in which case the
+-- value is not returned.
+--
+-- Returns non-negative on success / negative on failure
+--
+-- > herr_t H5Eget_auto2(hid_t estack_id, H5E_auto2_t *func, void **client_data);
+--
+-- NB: the @a@ type here should be existentially quantified, not universally, but
+-- Haskell doesn't have a convenient way to say so in a foreign import.
+#ccall H5Eget_auto2, <hid_t> -> Out (H5E_auto2_t a) -> Out (InOut a) -> IO <herr_t>
+
+-- |Turns on or off automatic printing of errors for certain
+-- error stack.  When turned on (non-null 'func' pointer) any
+-- API function which returns an error indication will first
+-- call 'func' passing it 'client_data' as an argument.
+--
+-- The default values before this function is called are
+-- 'h5e_print2' with client data being the standard error stream,
+-- 'stderr'.
+--
+-- Automatic stack traversal is always in the 'h5e_WALK_DOWNWARD'
+-- direction.
+--
+-- > herr_t H5Eset_auto2(hid_t estack_id, H5E_auto2_t func, void *client_data);
+#ccall H5Eset_auto2, <hid_t> -> H5E_auto2_t a -> InOut a -> IO <herr_t>
+
+-- |Clears the error stack for the specified error stack.
+--
+-- Returns non-negative value on success / negative on failure
+--
+-- > herr_t H5Eclear2(hid_t err_stack);
+#ccall H5Eclear2, <hid_t> -> IO <herr_t>
+
+-- TODO: I think the type names mentioned here are wrong.  Sort them out.
+-- |Determines if the error auto reporting function for an
+-- error stack conforms to the 'H5E_auto_stack_t' typedef
+-- or the 'H5E_auto_t' typedef.  The 'is_stack' parameter is set
+-- to 1 for the first case and 0 for the latter case.
+--
+-- Returns non-negative on success / negative on failure
+--
+-- > herr_t H5Eauto_is_v2(hid_t err_stack, unsigned *is_stack);
+#ccall H5Eauto_is_v2, <hid_t> -> Out CUInt -> IO <herr_t>
+
+-- |Retrieves an error message.
+--
+-- Returns non-negative for message length if succeeds(zero means no message);
+-- otherwise returns negative value.
+--
+-- > ssize_t H5Eget_msg(hid_t msg_id, H5E_type_t *type, char *msg,
+-- >     size_t size);
+#ccall H5Eget_msg, <hid_t> -> Out <H5E_type_t> -> OutArray CChar -> <size_t> -> IO <ssize_t>
+
+-- |Retrieves the number of error message.
+--
+-- Returns non-negative value on success / negative on failure
+--
+-- > ssize_t H5Eget_num(hid_t error_stack_id);
+#ccall H5Eget_num, <hid_t> -> IO <ssize_t>
+
+#ifndef H5_NO_DEPRECATED_SYMBOLS
+
+-- * Deprecated symbols
+
+#newtype H5E_major_t, Eq
+#newtype H5E_minor_t, Eq
+
+-- | Information about an error element of error stack
+#starttype H5E_error1_t
+
+-- |major error number
+#field maj_num,    <H5E_major_t>
+
+-- |minor error number
+#field min_num,    <H5E_minor_t>
+
+-- |function in which error occurred
+#field func_name,  CString
+
+-- |file in which error occurred
+#field file_name,  CString
+
+-- |line in file where error occurs
+#field line,       CUInt
+
+-- |optional supplied description
+#field desc,       CString
+#stoptype
+
+
+-- | Callback type for 'h5e_walk1'
+--
+-- > typedef herr_t (*H5E_walk1_t)(int n, H5E_error1_t *err_desc, void *client_data);
+type H5E_walk1_t a = FunPtr (CInt -> In H5E_error1_t -> InOut a -> IO HErr_t)
+
+-- | Callback type for 'h5e_set_auto1'
+--
+-- > typedef herr_t (*H5E_auto1_t)(void *client_data);
+type H5E_auto1_t a = FunPtr (InOut a -> IO HErr_t)
+
+-- ** Function prototypes
+
+-- |This function is for backward compatbility.
+-- Clears the error stack for the specified error stack.
+--
+-- Returns non-negative on success / negative on failure
+--
+-- > herr_t H5Eclear1(void);
+#ccall H5Eclear1, IO <herr_t>
+
+-- |This function is for backward compatbility.
+-- Returns the current settings for the automatic error stack
+-- traversal function and its data for specific error stack.
+-- Either (or both) arguments may be null in which case the
+-- value is not returned.
+--
+-- Returns non-negative on success / negative on failure
+--
+-- > herr_t H5Eget_auto1(H5E_auto1_t *func, void **client_data);
+--
+-- NB: the @a@ type here should be existentially quantified, not universally, but
+-- Haskell doesn't have a convenient way to say so in a foreign import.
+#ccall H5Eget_auto1, Out (H5E_auto1_t a) -> Out (InOut a) -> IO <herr_t>
+
+-- |This function definition is for backward compatibility only.
+-- It doesn't have error stack and error class as parameters.
+-- The old definition of major and minor is casted as HID_T
+-- in H5Epublic.h
+--
+-- Returns non-negative on success / negative on failure
+--
+-- > herr_t H5Epush1(const char *file, const char *func, unsigned line,
+-- >     H5E_major_t maj, H5E_minor_t min, const char *str);
+#ccall H5Epush1, CString -> CString -> CUInt -> <H5E_major_t> -> <H5E_minor_t> -> CString -> IO <herr_t>
+
+-- |This function is for backward compatbility.
+-- Prints the error stack in some default way.  This is just a
+-- convenience function for 'h5e_walk1' with a function that
+-- prints error messages.  Users are encouraged to write there
+-- own more specific error handlers.
+--
+-- Returns non-negative on success / negative on failure
+--
+-- > herr_t H5Eprint1(FILE *stream);
+--
+-- NB: The first parameter is declared as 'InOut' to match 'H5E_auto1_t',
+-- but I'm quite sure it never modifies the passed value.
+#ccall H5Eprint1, InOut CFile -> IO <herr_t>
+
+-- |This function is for backward compatbility.
+-- Turns on or off automatic printing of errors for certain
+-- error stack.  When turned on (non-null 'func' pointer) any
+-- API function which returns an error indication will first
+-- call 'func' passing it 'client_data' as an argument.
+--
+-- The default values before this function is called are
+-- 'h5e_print1' with client data being the standard error stream,
+-- 'stderr'.
+--
+-- Automatic stack traversal is always in the 'h5e_WALK_DOWNWARD'
+-- direction.
+--
+-- Returns non-negative on success / negative on failure
+--
+-- > herr_t H5Eset_auto1(H5E_auto1_t func, void *client_data);
+#ccall H5Eset_auto1, H5E_auto1_t a -> InOut a -> IO <herr_t>
+
+-- |This function is for backward compatbility.
+-- Walks the error stack for the current thread and calls some
+-- function for each error along the way.
+--
+-- Returns non-negative on success / negative on failure
+--
+-- > herr_t H5Ewalk1(H5E_direction_t direction, H5E_walk1_t func,
+-- >     void *client_data);
+#ccall H5Ewalk1, H5E_direction_t -> H5E_walk1_t a -> InOut a -> IO <herr_t>
+
+-- |Retrieves a major error message.
+--
+-- Returns message if succeeds, otherwise returns NULL.
+--
+-- > char *H5Eget_major(H5E_major_t maj);
+#ccall H5Eget_major, <H5E_major_t> -> IO CString
+
+-- |Retrieves a minor error message.
+--
+-- Returns message if succeeds, otherwise returns NULL.
+--
+-- > char *H5Eget_minor(H5E_minor_t min);
+#ccall H5Eget_minor, <H5E_minor_t> -> IO CString
+
+#endif /* H5_NO_DEPRECATED_SYMBOLS */
diff --git a/src/Bindings/HDF5/Raw/H5F.hsc b/src/Bindings/HDF5/Raw/H5F.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/H5F.hsc
@@ -0,0 +1,724 @@
+#include <bindings.h>
+#include <H5Fpublic.h>
+
+module Bindings.HDF5.Raw.H5F where
+
+import Data.Int
+import Data.Word
+import Foreign.C.String
+import Foreign.C.Types
+import Foreign.Ptr
+import Foreign.Storable
+
+import Bindings.HDF5.Raw.H5
+import Bindings.HDF5.Raw.H5AC
+import Bindings.HDF5.Raw.H5I
+
+import Foreign.Ptr.Conventions
+
+-- * Types and constants
+
+-- ** Flags for 'h5f_create' and 'h5f_open'
+-- These are the bits that can be passed to the 'flags' argument of
+-- H5Fcreate() and H5Fopen(). Use the bit-wise OR operator (|) to combine
+-- them as needed.  As a side effect, they call H5check_version() to make sure
+-- that the application is compiled with a version of the hdf5 header files
+-- which are compatible with the library to which the application is linked.
+-- We're assuming that these constants are used rather early in the hdf5
+-- session.
+
+-- |absence of rdwr => rd-only
+#num H5F_ACC_RDONLY
+
+-- |open for read and write
+#num H5F_ACC_RDWR
+
+-- |overwrite existing files
+#num H5F_ACC_TRUNC
+
+-- |fail if file already exists
+#num H5F_ACC_EXCL
+
+-- |print debug info
+#num H5F_ACC_DEBUG
+
+-- |create non-existing files
+#num H5F_ACC_CREAT
+
+#if H5_VERSION_GE(1,10,0)
+
+-- |indicate that this file is open for writing in a
+-- single-writer/multi-reader (SWMR) scenario.  Note that the
+-- process(es) opening the file for reading must open the file with
+-- RDONLY access, and use the special "SWMR_READ" access flag.
+#num H5F_ACC_SWMR_WRITE
+
+-- |indicate that this file is open for reading in a
+-- single-writer/multi-reader (SWMR) scenario.  Note that the
+-- process(es) opening the file for SWMR reading must also open the
+-- file with the RDONLY flag.  */
+#num H5F_ACC_SWMR_READ
+
+#endif
+
+#if H5_VERSION_GE(1,8,3)
+
+-- |Value passed to 'h5p_set_elink_acc_flags' to cause flags to be taken from the
+-- parent file.
+#num H5F_ACC_DEFAULT
+
+#endif
+
+-- ** Flags for 'h5f_get_obj_count' and 'h5f_get_obj_ids' calls
+
+-- |File objects
+#num H5F_OBJ_FILE
+
+-- |Dataset objects
+#num H5F_OBJ_DATASET
+
+-- |Group objects
+#num H5F_OBJ_GROUP
+
+-- |Named datatype objects
+#num H5F_OBJ_DATATYPE
+
+-- |Attribute objects
+#num H5F_OBJ_ATTR
+
+#num H5F_OBJ_ALL
+
+-- |Restrict search to objects opened through current file ID
+#num H5F_OBJ_LOCAL
+
+#newtype_const hsize_t, H5F_FAMILY_DEFAULT
+
+#ifdef H5_HAVE_PARALLEL
+
+-- |Use this constant string as the MPI_Info key to set 'h5f_mpio' debug flags.
+-- To turn on 'h5f_mpio' debug flags, set the MPI_Info value with this key to
+-- have the value of a string consisting of the characters that turn on the
+-- desired flags.
+#str H5F_MPIO_DEBUG_KEY
+
+#endif /* H5_HAVE_PARALLEL */
+
+-- |The difference between a single file and a set of mounted files
+#newtype H5F_scope_t
+
+-- |specified file handle only
+#newtype_const H5F_scope_t, H5F_SCOPE_LOCAL
+
+-- |entire virtual file
+#newtype_const H5F_scope_t, H5F_SCOPE_GLOBAL
+
+-- |Unlimited file size for 'h5p_set_external'
+#newtype_const hsize_t, H5F_UNLIMITED
+
+-- |How does file close behave?
+#newtype H5F_close_degree_t, Eq
+
+-- |Use the degree pre-defined by underlining VFL
+#newtype_const H5F_close_degree_t, H5F_CLOSE_DEFAULT
+
+-- |file closes only after all opened objects are closed
+#newtype_const H5F_close_degree_t, H5F_CLOSE_WEAK
+
+-- |if no opened objects, file is close; otherwise, file close fails
+#newtype_const H5F_close_degree_t, H5F_CLOSE_SEMI
+
+-- |if there are opened objects, close them first, then close file
+#newtype_const H5F_close_degree_t, H5F_CLOSE_STRONG
+
+
+#if H5_VERSION_GE(1,10,0)
+
+-- |Current "global" information about file
+-- (just size info currently)
+#starttype H5F_info2_t
+
+-- |Superblock version
+#field super.version,  CUInt
+
+-- |Superblock size
+#field super.super_size, <hsize_t>
+
+
+-- |Superblock extension size
+#field super.super_ext_size, <hsize_t>
+
+-- |Version # of file free space management
+#field free.version, CUInt
+
+-- |Free space manager metadata size
+#field free.meta_size, <hsize_t>
+
+-- |Amount of free space in the file
+#field free.tot_space, <hsize_t>
+
+-- |Version # of shared object header info
+#field sohm.version, CUInt
+
+-- |Shared object header message header size
+#field sohm.hdr_size, <hsize_t>
+
+-- |Shared object header message index & heap size
+#field sohm.msgs_info, <H5_ih_info_t>
+
+#stoptype
+
+#endif
+ 
+#if H5_VERSION_GE(1,8,4)
+
+-- |Types of allocation requests. The values larger than 'h5fd_MEM_DEFAULT'
+-- should not change other than adding new types to the end. These numbers
+-- might appear in files.
+#newtype H5F_mem_t, Eq
+-- |Data should not appear in the free list.
+-- Must be negative.
+#newtype_const H5F_mem_t, H5FD_MEM_NOLIST
+-- |Value not yet set.  Can also be the
+-- datatype set in a larger allocation
+-- that will be suballocated by the library.
+-- Must be zero.
+#newtype_const H5F_mem_t, H5FD_MEM_DEFAULT
+-- |Superblock data
+#newtype_const H5F_mem_t, H5FD_MEM_SUPER
+-- |B-tree data
+#newtype_const H5F_mem_t, H5FD_MEM_BTREE
+-- |Raw data (content of datasets, etc.)
+#newtype_const H5F_mem_t, H5FD_MEM_DRAW
+-- |Global heap data
+#newtype_const H5F_mem_t, H5FD_MEM_GHEAP
+-- |Local heap data
+#newtype_const H5F_mem_t, H5FD_MEM_LHEAP
+-- |Object header data
+#newtype_const H5F_mem_t, H5FD_MEM_OHDR
+-- |Sentinel value - must be last
+#num H5FD_MEM_NTYPES
+
+#endif
+
+#if H5_VERSION_GE(1,10,0)
+
+-- |Free space section information
+#starttype H5F_sect_info_t
+
+-- |Address of free space section
+#field addr, <haddr_t>
+
+-- |Size of free space section
+#field size, <hsize_t>
+
+#stoptype
+
+#endif
+ 
+-- |Library's file format versions
+#newtype H5F_libver_t
+
+-- |Use the earliest possible format for storing objects
+#newtype_const H5F_libver_t, H5F_LIBVER_EARLIEST
+
+-- |Use the latest possible format available for storing objects
+#newtype_const H5F_libver_t, H5F_LIBVER_LATEST
+
+#if H5_VERSION_GE(1,8,6) && H5_VERSION_LE(1,8,16)
+
+-- |Use version 1.8 format for storing objects
+#newtype_const H5F_libver_t, H5F_LIBVER_18
+
+#endif
+
+#if H5_VERSION_GE(1,10,0)
+
+-- |File space handling strategy
+#newtype H5F_file_space_type_t, Eq
+
+-- |Default (or current) free space strategy setting
+#newtype_const H5F_file_space_type_t, H5F_FILE_SPACE_DEFAULT
+
+-- |Persistent free space managers, aggregators, virtual file driver
+#newtype_const H5F_file_space_type_t, H5F_FILE_SPACE_ALL_PERSIST
+
+-- |Non-persistent free space managers, aggregators, virtual file driver
+-- This is the library default
+#newtype_const H5F_file_space_type_t, H5F_FILE_SPACE_ALL
+
+-- |Aggregators, Virtual file driver
+#newtype_const H5F_file_space_type_t, H5F_FILE_SPACE_AGGR_VFD
+
+-- |Virtual file driver
+#newtype_const H5F_file_space_type_t, H5F_FILE_SPACE_VFD
+
+#num H5F_FILE_SPACE_NTYPES
+
+-- | Data structure to report the collection of read retries for metadata items with checksum
+-- Used by public routine H5Fget_metadata_read_retry_info()
+-- TODO check the retries static array
+#num H5F_NUM_METADATA_READ_RETRY_TYPES
+
+#starttype H5F_retry_info_t
+#field nbins, CUInt
+#field retries, Ptr Word32
+#stoptype 
+
+-- |Callback for H5Pset_object_flush_cb() in a file access property list
+-- > typedef herr_t (*H5F_flush_cb_t)(hid_t object_id, void *udata);
+
+type H5F_flush_cb_t a = FunPtr (HId_t -> InOut a -> IO HErr_t)
+
+#endif
+
+
+-- * Public functions
+
+-- |Check the file signature to detect an HDF5 file.
+--
+-- [Bugs:] This function is not robust: it only uses the default file
+--         driver when attempting to open the file when in fact it
+--         should use all known file drivers.
+--
+-- > htri_t H5Fis_hdf5(const char *filename);
+#ccall H5Fis_hdf5, CString -> IO <htri_t>
+
+-- |This is the primary function for creating HDF5 files. The
+-- 'flags' parameter determines whether an existing file will be
+-- overwritten or not.  All newly created files are opened for
+-- both reading and writing.  All flags may be combined with the
+-- bit-wise OR operator (@ .|. @ from "Data.Bits") to change the
+-- behavior of the file create call.
+--
+-- The more complex behaviors of a file's creation and access
+-- are controlled through the file-creation and file-access
+-- property lists.  The value of 'h5p_DEFAULT' for a template
+-- value indicates that the library should use the default
+-- values for the appropriate template.
+--
+-- See also: "Bindings.HDF5.Raw.H5F" for the list of supported flags.
+-- "Bindings.HDF5.Raw.H5P" for the list of file creation and file
+-- access properties.
+--
+-- On success, returns a file ID.  On failure, returns a negative value.
+--
+-- > hid_t  H5Fcreate(const char *filename, unsigned flags,
+-- >        hid_t create_plist, hid_t access_plist);
+#ccall H5Fcreate, CString -> CUInt -> <hid_t> -> <hid_t> -> IO <hid_t>
+
+-- |This is the primary function for accessing existing HDF5
+-- files.  The 'flags' argument determines whether writing to an
+-- existing file will be allowed or not.  All flags may be
+-- combined with the bit-wise OR operator (@ .|. @ from "Data.Bits")
+-- to change the behavior of the file open call.  The more complex
+-- behaviors of a file's access are controlled through the file-access
+-- property list.
+--
+-- See Also: "Bindings.HDF5.Raw.H5F" for a list of possible values for 'flags'.
+--
+-- On success, returns a file ID.  On failure, returns a negative value.
+--
+-- > hid_t  H5Fopen(const char *filename, unsigned flags,
+-- >        hid_t access_plist);
+#ccall H5Fopen, CString -> CUInt -> <hid_t> -> IO <hid_t>
+
+-- |Reopen a file.  The new file handle which is returned points
+-- to the same file as the specified file handle.  Both handles
+-- share caches and other information.  The only difference
+-- between the handles is that the new handle is not mounted
+-- anywhere and no files are mounted on it.
+--
+-- On success, returns a file ID.  On failure, returns a negative value.
+--
+-- > hid_t  H5Freopen(hid_t file_id);
+#ccall H5Freopen, <hid_t> -> IO <hid_t>
+
+-- |Flushes all outstanding buffers of a file to disk but does
+-- not remove them from the cache.  The 'object_id' can be a file,
+-- dataset, group, attribute, or named data type.
+--
+-- Returns non-negative on success / negative on failure
+--
+-- > herr_t H5Fflush(hid_t object_id, H5F_scope_t scope);
+#ccall H5Fflush, <hid_t> -> <H5F_scope_t> -> IO <herr_t>
+
+-- |This function closes the file specified by 'file_id' by
+-- flushing all data to storage, and terminating access to the
+-- file through 'file_id'.  If objects (e.g., datasets, groups,
+-- etc.) are open in the file then the underlying storage is not
+-- closed until those objects are closed; however, all data for
+-- the file and the open objects is flushed.
+--
+-- Returns non-negative on success / negative on failure
+--
+-- > herr_t H5Fclose(hid_t file_id);
+#ccall H5Fclose, <hid_t> -> IO <herr_t>
+
+-- |Get an atom for a copy of the file-creation property list for
+-- this file. This function returns an atom with a copy of the
+-- properties used to create a file.
+--
+-- On success, returns a template ID.
+-- On failure, returns a negative value.
+--
+-- > hid_t  H5Fget_create_plist(hid_t file_id);
+#ccall H5Fget_create_plist, <hid_t> -> IO <hid_t>
+
+-- |Returns a copy of the file access property list of the
+-- specified file.
+--
+-- NOTE: If you are going to overwrite information in the copied
+-- property list that was previously opened and assigned to the
+-- property list, then you must close it before overwriting the values.
+--
+-- On success, returns an Object ID for a copy of the file access
+-- property list.  On failure, returns a negative value.
+--
+-- > hid_t  H5Fget_access_plist(hid_t file_id);
+#ccall H5Fget_access_plist, <hid_t> -> IO <hid_t>
+
+-- |Public API to retrieve the file's 'intent' flags passed
+-- during 'h5f_open'.
+--
+-- Returns non-negative on success / negative on failure
+--
+-- > herr_t H5Fget_intent(hid_t file_id, unsigned * intent);
+#ccall H5Fget_intent, <hid_t> -> Out CUInt -> IO <herr_t>
+
+-- |Returns the number of opened object IDs (files, datasets, groups
+-- and datatypes) in the same file.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > ssize_t H5Fget_obj_count(hid_t file_id, unsigned types);
+#ccall H5Fget_obj_count, <hid_t> -> CUInt -> IO <ssize_t>
+
+-- |Returns a list of opened object IDs.
+--
+-- Returns non-negative on success, negative on failure
+--
+-- > ssize_t H5Fget_obj_ids(hid_t file_id, unsigned types, size_t max_objs, hid_t *obj_id_list);
+#ccall H5Fget_obj_ids, <hid_t> -> CUInt -> <size_t> -> OutArray <hid_t> -> IO <ssize_t>
+
+-- |Returns a pointer to the file handle of the low-level file driver.
+--
+-- Returns non-negative on success, negative on failure
+--
+-- > herr_t H5Fget_vfd_handle(hid_t file_id, hid_t fapl, void **file_handle);
+#ccall H5Fget_vfd_handle, <hid_t> -> <hid_t> -> Out (Ptr CFile) -> IO <herr_t>
+
+-- |Mount file 'child_id' onto the group specified by 'loc_id' and
+-- 'name' using mount properties 'plist_id'.
+--
+-- Returns non-negative on success, negative on failure
+--
+-- > herr_t H5Fmount(hid_t loc, const char *name, hid_t child, hid_t plist);
+#ccall H5Fmount, <hid_t> -> CString -> <hid_t> -> <hid_t> -> IO <herr_t>
+
+-- |Given a mount point, dissassociate the mount point's file
+-- from the file mounted there.  Do not close either file.
+--
+-- The mount point can either be the group in the parent or the
+-- root group of the mounted file (both groups have the same
+-- name).  If the mount point was opened before the mount then
+-- it's the group in the parent, but if it was opened after the
+-- mount then it's the root group of the child.
+--
+-- Returns non-negative on success, negative on failure
+--
+-- > herr_t H5Funmount(hid_t loc, const char *name);
+#ccall H5Funmount, <hid_t> -> CString -> IO <herr_t>
+
+-- |Retrieves the amount of free space in the file.
+-- Returns a negative value on failure.
+--
+-- hssize_t H5Fget_freespace(hid_t file_id);
+#ccall H5Fget_freespace, <hid_t> -> IO <hssize_t>
+
+-- |Retrieves the file size of the HDF5 file. This function
+-- is called after an existing file is opened in order
+-- to learn the true size of the underlying file.
+--
+-- Returns non-negative on success, negative on failure
+--
+-- > herr_t H5Fget_filesize(hid_t file_id, hsize_t *size);
+#ccall H5Fget_filesize, <hid_t> -> Out <hsize_t> -> IO <herr_t>
+
+#if H5_VERSION_GE(1,8,9)
+
+-- |If a buffer is provided (via the buf_ptr argument) and is
+-- big enough (size in buf_len argument), load *buf_ptr with
+-- an image of the open file whose ID is provided in the
+-- file_id parameter, and return the number of bytes copied
+-- to the buffer.
+--
+-- If the buffer exists, but is too small to contain an image
+-- of the indicated file, return a negative number.
+--
+-- Finally, if no buffer is provided, return the size of the
+-- buffer needed.  This value is simply the eoa of the target
+-- file.
+--
+-- Note that any user block is skipped.
+--
+-- Also note that the function may not be used on files
+-- opened with either the split/multi file driver or the
+-- family file driver.
+--
+-- In the former case, the sparse address space makes the
+-- get file image operation impractical, due to the size of
+-- the image typically required.
+--
+-- In the case of the family file driver, the problem is
+-- the driver message in the super block, which will prevent
+-- the image being opened with any driver other than the
+-- family file driver -- which negates the purpose of the
+-- operation.  This can be fixed, but no resources for
+-- this now.
+--
+-- Return:      Success:        Bytes copied / number of bytes needed.
+--              Failure:        negative value
+--
+-- > ssize_t H5Fget_file_image(hid_t file_id, void * buf_ptr, size_t buf_len);
+#ccall H5Fget_file_image, <hid_t> -> InArray a -> <size_t> -> IO <ssize_t>
+
+#endif
+
+-- |Retrieves the current automatic cache resize configuration
+-- from the metadata cache, and return it in 'config_ptr'.
+--
+-- Note that the 'version' field of 'config_ptr' must be correctly
+-- filled in by the caller.  This allows us to adapt for
+-- obsolete versions of the structure.
+--
+-- Returns non-negative on success, negative on failure
+--
+-- > herr_t H5Fget_mdc_config(hid_t file_id,
+-- >        H5AC_cache_config_t * config_ptr);
+#ccall H5Fget_mdc_config, <hid_t> -> Out <H5AC_cache_config_t> -> IO <herr_t>
+
+-- |Sets the current metadata cache automatic resize
+-- configuration, using the contents of the instance of
+-- 'H5AC_cache_config_t' pointed to by 'config_ptr'.
+--
+-- Returns non-negative on success, negative on failure
+--
+-- > herr_t H5Fset_mdc_config(hid_t file_id,
+-- >        H5AC_cache_config_t * config_ptr);
+#ccall H5Fset_mdc_config, <hid_t> -> In <H5AC_cache_config_t> -> IO <herr_t>
+
+-- |Retrieves the current hit rate from the metadata cache.
+-- This rate is the overall hit rate since the last time
+-- the hit rate statistics were reset either manually or
+-- automatically.
+--
+-- Returns non-negative on success, negative on failure
+--
+-- > herr_t H5Fget_mdc_hit_rate(hid_t file_id, double * hit_rate_ptr);
+#ccall H5Fget_mdc_hit_rate, <hid_t> -> Out CDouble -> IO <herr_t>
+
+-- |Retrieves the maximum size, minimum clean size, current
+-- size, and current number of entries from the metadata
+-- cache associated with the specified file.  If any of
+-- the ptr parameters are NULL, the associated datum is
+-- not returned.
+--
+-- Returns non-negative on success, negative on failure
+--
+-- > herr_t H5Fget_mdc_size(hid_t file_id,
+-- >        size_t * max_size_ptr,
+-- >        size_t * min_clean_size_ptr,
+-- >        size_t * cur_size_ptr,
+-- >        int * cur_num_entries_ptr);
+#ccall H5Fget_mdc_size, <hid_t> -> Out <size_t> -> Out <size_t> -> Out <size_t> -> Out CInt -> IO <herr_t>
+
+-- |Reset the hit rate statistic whose current value can
+-- be obtained via the 'h5f_get_mdc_hit_rate' call.  Note
+-- that this statistic will also be reset once per epoch
+-- by the automatic cache resize code if it is enabled.
+--
+-- It is probably a bad idea to call this function unless
+-- you are controlling cache size from your program instead
+-- of using our cache size control code.
+--
+-- Returns non-negative on success, negative on failure
+--
+-- > herr_t H5Freset_mdc_hit_rate_stats(hid_t file_id);
+#ccall H5Freset_mdc_hit_rate_stats, <hid_t> -> IO <herr_t>
+
+-- |Gets the name of the file to which object OBJ_ID belongs.
+-- If 'name' is non-NULL then write up to 'size' bytes into that
+-- buffer and always return the length of the entry name.
+-- Otherwise 'size' is ignored and the function does not store the name,
+-- just returning the number of characters required to store the name.
+-- If an error occurs then the buffer pointed to by 'name' (NULL or non-NULL)
+-- is unchanged and the function returns a negative value.
+--
+-- Note:  This routine returns the name that was used to open the file,
+-- not the actual name after resolving symlinks, etc.
+--
+-- Returns the length of the file name (_not_ the length of the data
+-- copied into the output buffer) on success, or a negative value on failure.
+--
+-- > ssize_t H5Fget_name(hid_t obj_id, char *name, size_t size);
+#ccall H5Fget_name, <hid_t> -> OutArray CChar -> <size_t> -> IO <ssize_t>
+
+-- |#. Get storage size for superblock extension if there is one
+--
+--  #. Get the amount of btree and heap storage for entries in the SOHM table if there is one.
+--
+--  #. Consider success when there is no superblock extension and/or SOHM table
+--
+-- Returns non-negative on success, negative on failure
+--
+#if H5_VERSION_GE(1,10,0)
+
+-- > herr_t H5Fget_info2(hid_t obj_id, H5F_info2_t *bh_info);
+#ccall H5Fget_info2, <hid_t> -> Out H5F_info2_t -> IO <herr_t>
+
+-- > herr_t H5Fget_metadata_read_retry_info(hid_t file_id, H5F_retry_info_t *info);
+#ccall H5Fget_metadata_read_retry_info, <hid_t> -> Out H5F_retry_info_t -> IO <herr_t>
+
+-- > herr_t H5Fstart_swmr_write(hid_t file_id);
+#ccall H5Fstart_swmr_write, <hid_t> -> IO <herr_t>
+
+-- > ssize_t H5Fget_free_sections(hid_t file_id, H5F_mem_t type,
+-- >    size_t nsects, H5F_sect_info_t *sect_info/*out*/);
+#ccall H5Fget_free_sections, <hid_t> -> <H5F_mem_t> -> <size_t> -> Out H5F_sect_info_t -> IO <ssize_t>
+
+#endif
+
+#if H5_VERSION_GE(1,8,7)
+-- |Releases the external file cache associated with the
+-- provided file, potentially closing any cached files
+-- unless they are held open from somewhere else.
+--
+-- Returns non-negative on success, negative on failure
+--
+-- > herr_t H5Fclear_elink_file_cache(hid_t file_id);
+#ccall H5Fclear_elink_file_cache, <hid_t> -> IO <herr_t>
+#endif
+
+#if H5_VERSION_GE(1,10,0)
+
+-- > herr_t H5Fstart_mdc_logging(hid_t file_id);
+#ccall H5Fstart_mdc_logging, <hid_t> -> IO <herr_t>
+
+-- > herr_t H5Fstop_mdc_logging(hid_t file_id);
+#ccall H5Fstop_mdc_logging, <hid_t> -> IO <herr_t>
+
+-- > herr_t H5Fget_mdc_logging_status(hid_t file_id,
+-- >                                  /*OUT*/ hbool_t *is_enabled,
+-- >                                  /*OUT*/ hbool_t *is_currently_logging);
+#ccall H5Fget_mdc_logging_status, <hid_t> -> Out hbool_t -> Out hbool_t -> IO <herr_t>
+
+-- > herr_t H5Fformat_convert(hid_t fid);
+#ccall H5Fformat_convert, <hid_t> -> IO <herr_t>
+
+-- > herr_t H5Fget_info1(hid_t obj_id, H5F_info1_t *bh_info);
+#ccall H5Fget_info1, <hid_t> -> Out H5F_info1_t -> IO <herr_t>
+
+#endif
+
+#if H5_VERSION_GE(1,8,9) && H5_HAVE_PARALLEL
+
+-- |Sets the atomicity mode
+--
+-- Returns non-negative on success, negative on failure
+-- > herr_t H5Fset_mpi_atomicity(hid_t file_id, hbool_t flag);
+#ccall H5Fset_mpi_atomicity, <hid_t> -> <hbool_t> -> IO <herr_t>
+
+-- |Returns the atomicity mode
+--
+-- Returns non-negative on success, negative on failure
+-- > herr_t H5Fget_mpi_atomicity(hid_t file_id, hbool_t *flag);
+#ccall H5Fget_mpi_atomicity, <hid_t> -> Out <hbool_t> -> IO <herr_t>
+
+#endif
+
+
+#if H5_VERSION_GE(1,10,0) && !H5_NO_DEPRECATED_SYMBOLS
+
+-- |Current "global" information about file
+-- (just size info currently)
+#starttype H5F_info1_t
+
+-- |Superblock extension size
+#field super_ext_size,  <hsize_t>
+
+-- |Shared object header message header size
+#field sohm.hdr_size,   <hsize_t>
+
+-- |Shared object header message index & heap size
+#field sohm.msgs_info,  <H5_ih_info_t>
+#stoptype
+
+#endif
+
+#if (H5_VERSION_GE(1,10,0) && (H5Fget_info_vers == 1)) || H5_VERSION_LE(1,8,18)
+
+-- |Current "global" information about file
+-- (just size info currently)
+#starttype H5F_info_t
+
+-- |Superblock extension size
+#field super_ext_size,  <hsize_t>
+
+-- |Shared object header message header size
+#field sohm.hdr_size,   <hsize_t>
+
+-- |Shared object header message index & heap size
+#field sohm.msgs_info,  <H5_ih_info_t>
+ 
+#stoptype
+
+#else
+
+-- |Current "global" information about file
+-- (just size info currently)
+#starttype H5F_info_t
+
+-- |Superblock version
+#field super.version,  CUInt
+
+-- |Superblock size
+#field super.super_size, <hsize_t>
+
+-- |Superblock extension size
+#field super.super_ext_size, <hsize_t>
+
+-- |Version # of file free space management
+#field free.version, CUInt
+
+-- |Free space manager metadata size
+#field free.meta_size, <hsize_t>
+
+-- |Amount of free space in the file
+#field free.tot_space, <hsize_t>
+
+-- |Version # of shared object header info
+#field sohm.version, CUInt
+
+-- |Shared object header message header size
+#field sohm.hdr_size, <hsize_t>
+
+-- |Shared object header message index & heap size
+#field sohm.msgs_info, <H5_ih_info_t>
+
+#stoptype
+
+#endif
+
+
+#if H5_VERSION_GE(1,8,10)
+#if (H5Fget_info_vers == 1)
+foreign import ccall unsafe "H5Fget_info1" h5f_get_info
+#else
+foreign import ccall unsafe "H5Fget_info2" h5f_get_info
+#endif
+#else
+foreign import ccall unsafe "H5Fget_info" h5f_get_info
+#endif
+  :: HId_t -> Out H5F_info_t -> IO HErr_t
+
+
diff --git a/src/Bindings/HDF5/Raw/H5FD.hsc b/src/Bindings/HDF5/Raw/H5FD.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/H5FD.hsc
@@ -0,0 +1,658 @@
+#include <bindings.h>
+#include <H5FDpublic.h>
+
+-- |The Virtual File Layer as described in documentation.
+-- This is the greatest common denominator for all types of
+-- storage access whether a file, memory, network, etc. This
+-- layer usually just dispatches the request to an actual
+-- file driver layer.
+module Bindings.HDF5.Raw.H5FD where
+
+import Data.Word
+import Foreign.Ptr
+import Foreign.C.String
+import Foreign.C.Types
+import Foreign.Marshal.Array
+import Foreign.Storable
+
+import Bindings.HDF5.Raw.H5
+import Bindings.HDF5.Raw.H5F
+import Bindings.HDF5.Raw.H5I
+import Foreign.Ptr.Conventions
+
+-- |Default VFL driver value
+#newtype_const hid_t, H5FD_VFD_DEFAULT
+
+#if H5_VERSION_GE(1,8,4)
+
+-- |Types of allocation requests: see "Bindings.HDF5.Raw.H5F"
+type H5FD_mem_t = H5F_mem_t
+
+#else
+
+#newtype H5FD_mem_t, Eq
+
+#newtype_const H5FD_mem_t, H5FD_MEM_NOLIST
+#newtype_const H5FD_mem_t, H5FD_MEM_DEFAULT
+
+#if H5_VERSION_LE(1,8,9)
+#newtype_const H5FD_mem_t, H5FD_MEM_SUPER
+#endif
+
+#newtype_const H5FD_mem_t, H5FD_MEM_BTREE
+#newtype_const H5FD_mem_t, H5FD_MEM_DRAW
+#newtype_const H5FD_mem_t, H5FD_MEM_GHEAP
+#newtype_const H5FD_mem_t, H5FD_MEM_LHEAP
+#newtype_const H5FD_mem_t, H5FD_MEM_OHDR
+
+#endif
+
+-- |Map "fractal heap" header blocks to 'ohdr' type file memory, since its
+-- a fair amount of work to add a new kind of file memory and they are similar
+-- enough to object headers and probably too minor to deserve their own type.
+#if H5_VERSION_GE(1,8,4)
+#newtype_const H5F_mem_t, H5FD_MEM_FHEAP_HDR
+#else
+#newtype_const H5FD_mem_t, H5FD_MEM_FHEAP_HDR
+#endif
+
+-- |Map "fractal heap" indirect blocks to 'ohdr' type file memory, since they
+-- are similar to fractal heap header blocks.
+#if H5_VERSION_GE(1,8,4)
+#newtype_const H5F_mem_t, H5FD_MEM_FHEAP_IBLOCK
+#else
+#newtype_const H5FD_mem_t, H5FD_MEM_FHEAP_IBLOCK
+#endif
+
+-- |Map "fractal heap" direct blocks to 'lheap' type file memory, since they
+-- will be replacing local heaps.
+#if H5_VERSION_GE(1,8,4)
+#newtype_const H5F_mem_t, H5FD_MEM_FHEAP_DBLOCK
+#else
+#newtype_const H5FD_mem_t, H5FD_MEM_FHEAP_DBLOCK
+#endif
+
+-- |Map "fractal heap" 'huge' objects to 'draw' type file memory, since they
+-- represent large objects that are directly stored in the file.
+#if H5_VERSION_GE(1,8,4)
+#newtype_const H5F_mem_t, H5FD_MEM_FHEAP_HUGE_OBJ
+#else
+#newtype_const H5FD_mem_t, H5FD_MEM_FHEAP_HUGE_OBJ
+#endif
+
+-- |Map "free space" header blocks to 'ohdr' type file memory, since its
+-- a fair amount of work to add a new kind of file memory and they are similar
+-- enough to object headers and probably too minor to deserve their own type.
+#if H5_VERSION_GE(1,8,4)
+#newtype_const H5F_mem_t, H5FD_MEM_FSPACE_HDR
+#else
+#newtype_const H5FD_mem_t, H5FD_MEM_FSPACE_HDR
+#endif
+
+-- |Map "free space" serialized sections to 'lheap' type file memory, since they
+-- are similar enough to local heap info.
+#if H5_VERSION_GE(1,8,4)
+#newtype_const H5F_mem_t, H5FD_MEM_FSPACE_SINFO
+#else
+#newtype_const H5FD_mem_t, H5FD_MEM_FSPACE_SINFO
+#endif
+
+-- |Map "shared object header message" master table to 'ohdr' type file memory,
+-- since its a fair amount of work to add a new kind of file memory and they are
+-- similar enough to object headers and probably too minor to deserve their own
+-- type.
+#if H5_VERSION_GE(1,8,4)
+#newtype_const H5F_mem_t, H5FD_MEM_SOHM_TABLE
+#else
+#newtype_const H5FD_mem_t, H5FD_MEM_SOHM_TABLE
+#endif
+
+-- |Map "shared object header message" indices to 'btree' type file memory,
+-- since they are similar enough to B-tree nodes.
+#if H5_VERSION_GE(1,8,4)
+#newtype_const H5F_mem_t, H5FD_MEM_SOHM_INDEX
+#else
+#newtype_const H5FD_mem_t, H5FD_MEM_SOHM_INDEX
+#endif
+
+#if H5_VERSION_GE(1,10,0)
+-- |Map "extensible array" header blocks to 'ohdr' type file memory, since its
+-- a fair amount of work to add a new kind of file memory and they are similar
+-- enough to object headers and probably too minor to deserve their own type.
+--
+-- Map "extensible array" index blocks to 'ohdr' type file memory, since they
+-- are similar to extensible array header blocks.
+--
+-- Map "extensible array" super blocks to 'btree' type file memory, since they
+-- are similar enough to B-tree nodes.
+--
+-- Map "extensible array" data blocks & pages to 'lheap' type file memory, since
+-- they are similar enough to local heap info.
+
+#newtype_const H5F_mem_t, H5FD_MEM_EARRAY_HDR
+#newtype_const H5F_mem_t, H5FD_MEM_EARRAY_IBLOCK
+#newtype_const H5F_mem_t, H5FD_MEM_EARRAY_SBLOCK
+#newtype_const H5F_mem_t, H5FD_MEM_EARRAY_DBLOCK
+#newtype_const H5F_mem_t, H5FD_MEM_EARRAY_DBLK_PAGE
+
+-- |Map "fixed array" header blocks to 'ohdr' type file memory, since its
+-- a fair amount of work to add a new kind of file memory and they are similar
+-- enough to object headers and probably too minor to deserve their own type.
+--
+-- Map "fixed array" data blocks & pages to 'lheap' type file memory, since
+-- they are similar enough to local heap info.
+
+
+#newtype_const H5F_mem_t, H5FD_MEM_FARRAY_HDR
+#newtype_const H5F_mem_t, H5FD_MEM_FARRAY_DBLOCK
+#newtype_const H5F_mem_t, H5FD_MEM_FARRAY_DBLK_PAGE
+
+#endif
+
+-- Array initializers: pass a buffer and the size of that buffer (in bytes)
+-- and it will be filled as prescribed by the corresponding array-literal macro.
+--
+-- TODO: create statically-allocated constant versions of these?
+-- TODO: explain more in haddock docs about how to use these
+
+-- |Initialize a free-list map which maps all types of allocation requests
+-- to a single free list.  This is useful for drivers that don't really care
+-- about keeping different requests segregated in the underlying file and which
+-- want to make most efficient reuse of freed memory.  The use of the
+-- 'h5fd_MEM_SUPER' free list is arbitrary.
+#cinline H5FD_FLMAP_SINGLE,    OutArray <H5FD_mem_t> -> <size_t> -> IO ()
+
+-- |A free-list map which segregates requests into \"raw\" or \"meta\" data
+-- pools.
+#cinline H5FD_FLMAP_DICHOTOMY, OutArray <H5FD_mem_t> -> <size_t> -> IO ()
+
+-- |The default free list map which causes each request type to use its own
+-- free-list.
+#cinline H5FD_FLMAP_DEFAULT,   OutArray <H5FD_mem_t> -> <size_t> -> IO ()
+
+-- |Defining 'h5fd_FEAT_AGGREGATE_METADATA' for a VFL driver means that
+-- the library will attempt to allocate a larger block for metadata and
+-- then sub-allocate each metadata request from that larger block.
+#num H5FD_FEAT_AGGREGATE_METADATA
+
+-- |Defining 'h5fd_FEAT_ACCUMULATE_METADATA' for a VFL driver means that
+-- the library will attempt to cache metadata as it is written to the file
+-- and build up a larger block of metadata to eventually pass to the VFL
+-- 'write' routine.
+--
+-- Distinguish between updating the metadata accumulator on writes
+-- ('h5fd_FEAT_ACCUMULATE_METADATA_WRITE') and reads
+-- ('h5fd_FEAT_ACCUMULATE_METADATA_READ').  This is particularly (perhaps
+-- only, even) important for MPI-I/O where we guarantee that writes are
+-- collective, but reads may not be.  If we were to allow the metadata
+-- accumulator to be written during a read operation, the application would
+-- hang.
+#num H5FD_FEAT_ACCUMULATE_METADATA
+#num H5FD_FEAT_ACCUMULATE_METADATA_WRITE
+#num H5FD_FEAT_ACCUMULATE_METADATA_READ
+
+-- |Defining 'h5fd_FEAT_DATA_SIEVE' for a VFL driver means that
+-- the library will attempt to cache raw data as it is read from/written to
+-- a file in a "data seive" buffer.  See Rajeev Thakur's papers:
+--
+--  * <http://www.mcs.anl.gov/~thakur/papers/romio-coll.ps.gz>
+--
+--  * <http://www.mcs.anl.gov/~thakur/papers/mpio-high-perf.ps.gz>
+#num H5FD_FEAT_DATA_SIEVE
+
+-- |Defining 'h5fd_FEAT_AGGREGATE_SMALLDATA' for a VFL driver means that
+-- the library will attempt to allocate a larger block for \"small\" raw data
+-- and then sub-allocate \"small\" raw data requests from that larger block.
+#num H5FD_FEAT_AGGREGATE_SMALLDATA
+
+#if H5_VERSION_GE(1,8,4)
+
+-- |Defining 'h5fd_FEAT_IGNORE_DRVRINFO' for a VFL driver means that
+-- the library will ignore the driver info that is encoded in the file
+-- for the VFL driver.  (This will cause the driver info to be eliminated
+-- from the file when it is flushed/closed, if the file is opened R/W).
+#num H5FD_FEAT_IGNORE_DRVRINFO
+
+#if H5_VERSION_LE(1,8,16)
+-- |Defining 'h5fd_FEAT_DIRTY_SBLK_LOAD' for a VFL driver means that
+-- the library will mark the superblock dirty when the file is opened
+-- R/W.  This will cause the driver info to be re-encoded when the file
+-- is flushed/closed.
+#num H5FD_FEAT_DIRTY_SBLK_LOAD
+
+#endif
+
+#endif
+
+#if H5_VERSION_GE(1,8,5)
+
+-- |Defining 'h5fd_FEAT_POSIX_COMPAT_HANDLE' for a VFL driver means that
+-- the handle for the VFD (returned with the 'get_handle' callback) is
+-- of type 'int' and is compatible with POSIX I/O calls.
+#num H5FD_FEAT_POSIX_COMPAT_HANDLE
+
+#endif
+
+#if H5_VERSION_GE(1,8,9)
+
+-- |Defining 'H5FD_FEAT_ALLOW_FILE_IMAGE' for a VFL driver means that
+-- the driver is able to use a file image in the fapl as the initial
+-- contents of a file.
+#num H5FD_FEAT_ALLOW_FILE_IMAGE
+
+-- |Defining 'H5FD_FEAT_CAN_USE_FILE_IMAGE_CALLBACKS' for a VFL driver
+-- means that the driver is able to use callbacks to make a copy of the
+-- image to store in memory.
+#num H5FD_FEAT_CAN_USE_FILE_IMAGE_CALLBACKS
+
+#endif
+
+#if H5_VERSION_GE(1,10,0)
+
+-- |Defining 'H5FD_FEAT_SUPPORTS_SWMR_IO' for a VFL driver means that the
+-- driver supports the single-writer/multiple-readers I/O pattern.
+
+#num H5FD_FEAT_SUPPORTS_SWMR_IO
+
+#endif
+
+-- |Class information for each file driver
+#starttype H5FD_class_t
+#field name,            CString
+#field maxaddr,         <haddr_t>
+#field fc_degree,       <H5F_close_degree_t>
+#if H5_VERSION_GE(1,10,0)
+#field terminate,       FunPtr (IO <herr_t>)
+#endif
+#field sb_size,         FunPtr (In H5FD_t -> IO <hsize_t>)
+#field sb_encode,       FunPtr (In H5FD_t -> OutArray CChar -> Out CUChar -> IO <herr_t>)
+#field sb_decode,       FunPtr (In H5FD_t -> CString -> In CUChar -> IO <herr_t>)
+#field fapl_size,       <size_t>
+#field fapl_get,        FunPtr (In H5FD_t -> IO (Ptr ()))
+#field fapl_copy,       FunPtr (Ptr () -> IO (Ptr ()))
+#field fapl_free,       FunPtr (Ptr () -> IO <herr_t>)
+#field dxpl_size,       <size_t>
+#field dxpl_copy,       FunPtr (Ptr () -> IO (Ptr ()))
+#field dxpl_free,       FunPtr (Ptr () -> IO <herr_t>)
+#field open,            FunPtr (CString -> CUInt -> <hid_t> -> <haddr_t> -> IO (Ptr <H5FD_t>))
+#field close,           FunPtr (In <H5FD_t> -> IO <herr_t>)
+#field cmp,             FunPtr (In <H5FD_t> -> In <H5FD_t> -> IO CInt)
+#field query,           FunPtr (In <H5FD_t> -> Ptr CULong -> IO <herr_t>)
+
+#if H5_VERSION_GE(1,8,2)
+#field get_type_map,    FunPtr (In <H5FD_t> -> Out <H5FD_mem_t> -> IO <herr_t>)
+#endif
+
+#field alloc,           FunPtr (In <H5FD_t> -> <H5FD_mem_t> -> <hid_t> -> <hsize_t> -> IO <haddr_t>)
+#field free,            FunPtr (In <H5FD_t> -> <H5FD_mem_t> -> <hid_t> -> <haddr_t> -> <hsize_t> -> IO <herr_t>)
+#field get_eoa,         FunPtr (In <H5FD_t> -> <H5FD_mem_t> -> IO <haddr_t>)
+#field set_eoa,         FunPtr (In <H5FD_t> -> <H5FD_mem_t> -> <haddr_t>)
+
+#if H5_VERSION_GE(1,10,0)
+#field get_eof,         FunPtr (In <H5FD_t> -> <H5FD_mem_t> -> IO <haddr_t>)
+#else
+#field get_eof,         FunPtr (In <H5FD_t> -> IO <haddr_t>)
+#endif
+
+#field get_handle,      FunPtr (In <H5FD_t> -> <hid_t> -> Out (Ptr ()) -> IO <herr_t>)
+#field read,            FunPtr (In <H5FD_t> -> <H5FD_mem_t> -> <hid_t> -> <haddr_t> -> <size_t> -> OutArray () -> IO <herr_t>)
+#field write,           FunPtr (In <H5FD_t> -> <H5FD_mem_t> -> <hid_t> -> <haddr_t> -> <size_t> -> InArray  () -> IO <herr_t>)
+#field flush,           FunPtr (In <H5FD_t> -> <hid_t> -> CUInt -> IO <herr_t>)
+
+#if H5_VERSION_GE(1,8,2)
+#field truncate,        FunPtr (In <H5FD_t> -> <hid_t> -> <hbool_t> -> IO <herr_t>)
+#endif
+
+#if H5_VERSION_GE(1,10,0)
+#field lock,            FunPtr (In <H5FD_t> -> <hbool_t> -> IO <herr_t>)
+#field unlock,          FunPtr (In <H5FD_t> -> IO <herr_t>)
+#else
+#field lock,            FunPtr (In <H5FD_t> -> Ptr CUChar -> CUInt -> <hbool_t> -> IO <herr_t>)
+#field unlock,          FunPtr (In <H5FD_t> -> Ptr CUChar -> <hbool_t> -> IO <herr_t>)
+#endif
+
+#array_field fl_map,    <H5FD_mem_t>
+#stoptype
+
+
+-- |A free list is a singly-linked list of address/size pairs.
+#starttype H5FD_free_t
+#field addr,    <haddr_t>
+#field size,    <hsize_t>
+#field next,    Ptr <H5FD_free_t>
+#stoptype
+
+
+-- |The main datatype for each driver. Public fields common to all drivers
+-- are declared here and the driver appends private fields in memory.
+#starttype H5FD_t
+
+-- |driver ID for this file
+#field driver_id,       <hid_t>
+
+-- |constant class info
+#field cls,             Ptr <H5FD_class_t>
+
+-- |File 'serial' number
+#field fileno,          CULong
+
+-- |VFL Driver feature Flags
+#field feature_flags,   CULong
+
+-- |For this file, overrides class
+#field maxaddr,         <haddr_t>
+
+#if H5_VERSION_GE(1,8,2)
+-- |Base address for HDF5 data w/in file
+#field base_addr,       <haddr_t>
+#endif
+
+#if H5_VERSION_GE(1,10,0) && H5_VERSION_LE(1,10,1)
+-- |Whether the file is open for SWMR read access
+-- Information from file open flags, for SWMR access
+#field swmr_read, <hbool_t>
+#endif
+
+-- Space allocation management fields
+
+-- |Threshold for alignment
+#field threshold,       <hsize_t>
+-- |Allocation alignment
+#field alignment,       <hsize_t>
+#stoptype
+
+#if H5_VERSION_GE(1,8,9)
+
+-- |enum for the source of file image callbacks
+#newtype H5FD_file_image_op_t
+
+#newtype_const H5FD_file_image_op_t, H5FD_FILE_IMAGE_OP_NO_OP
+#newtype_const H5FD_file_image_op_t, H5FD_FILE_IMAGE_OP_PROPERTY_LIST_SET
+#newtype_const H5FD_file_image_op_t, H5FD_FILE_IMAGE_OP_PROPERTY_LIST_COPY
+#newtype_const H5FD_file_image_op_t, H5FD_FILE_IMAGE_OP_PROPERTY_LIST_GET
+#newtype_const H5FD_file_image_op_t, H5FD_FILE_IMAGE_OP_PROPERTY_LIST_CLOSE
+#newtype_const H5FD_file_image_op_t, H5FD_FILE_IMAGE_OP_FILE_OPEN
+#newtype_const H5FD_file_image_op_t, H5FD_FILE_IMAGE_OP_FILE_RESIZE
+#newtype_const H5FD_file_image_op_t, H5FD_FILE_IMAGE_OP_FILE_CLOSE
+
+-- |TODO: wrap this.  not tackling it now, because there are a lot of
+-- pointer types to pin down.
+data H5FD_file_image_callbacks_t = H5FD_file_image_callbacks_t
+
+-- /* Define structure to hold file image callbacks */
+-- typedef struct {
+--     void   *(*image_malloc)(size_t size, H5FD_file_image_op_t file_image_op,
+--                             void *udata);
+--     void   *(*image_memcpy)(void *dest, const void *src, size_t size,
+--                             H5FD_file_image_op_t file_image_op, void *udata);
+--     void   *(*image_realloc)(void *ptr, size_t size,
+--                             H5FD_file_image_op_t file_image_op, void *udata);
+--     herr_t  (*image_free)(void *ptr, H5FD_file_image_op_t file_image_op,
+--                           void *udata);
+--     void   *(*udata_copy)(void *udata);
+--     herr_t  (*udata_free)(void *udata);
+--     void *udata;
+-- } H5FD_file_image_callbacks_t;
+
+#endif
+
+-- |Registers a new file driver as a member of the virtual file
+-- driver class.  Certain fields of the class struct are
+-- required and that is checked here so it doesn't have to be
+-- checked every time the field is accessed.
+--
+-- On success, returns a file driver ID which is good until the
+-- library is closed or the driver is unregistered.
+-- On failure, returns a negative value.
+--
+-- > hid_t H5FDregister(const H5FD_class_t *cls);
+#ccall H5FDregister, In <H5FD_class_t> -> IO <hid_t>
+
+-- |Removes a driver ID from the library. This in no way affects
+-- file access property lists which have been defined to use
+-- this driver or files which are already opened under this
+-- driver.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5FDunregister(hid_t driver_id);
+#ccall H5FDunregister, <hid_t> -> IO <herr_t>
+
+-- |Opens a file named 'name' for the type(s) of access described
+-- by the bit vector 'flags' according to a file access property
+-- list 'fapl_id' (which may be the constant 'h5p_DEFAULT'). The
+-- file should expect to handle format addresses in the range [0,
+-- 'maxaddr'] (if 'maxaddr' is 'hADDR_UNDEF' then the caller
+-- doesn't care about the address range).
+--
+-- Possible values for the 'flags' bits are:
+--
+-- ['h5f_ACC_RDWR']
+--  Open the file for read and write access. If
+--  this bit is not set then open the file for
+--  read only access. It is permissible to open a
+--  file for read and write access when only read
+--  access is requested by the library (the
+--  library will never attempt to write to a file
+--  which it opened with only read access).
+--
+-- ['h5f_ACC_CREAT']
+--  Create the file if it doesn't already exist.
+--  However, see 'h5f_ACC_EXCL' below.
+--
+-- ['h5f_ACC_TRUNC']
+--  Truncate the file if it already exists. This
+--  is equivalent to deleting the file and then
+--  creating a new empty file.
+--
+-- ['h5f_ACC_EXCL']
+--  When used with 'h5f_ACC_CREAT', if the file
+--  already exists then the open should fail.
+--  Note that this is unsupported/broken with
+--  some file drivers (e.g., sec2 across nfs) and
+--  will contain a race condition when used to
+--  perform file locking.
+--
+-- The 'maxaddr' is the maximum address which will be requested by
+-- the library during an allocation operation. Usually this is
+-- the same value as the 'maxaddr' field of the class structure,
+-- but it can be smaller if the driver is being used under some
+-- other driver.
+--
+-- Note that when the driver 'open' callback gets control that
+-- the public part of the file struct (the 'H5FD_t' part) will be
+-- incomplete and will be filled in after that callback returns.
+--
+-- On success, returns a pointer to a new file driver struct.
+-- On failure, returns 'nullPtr'.
+--
+-- > H5FD_t *H5FDopen(const char *name, unsigned flags, hid_t fapl_id,
+-- >        haddr_t maxaddr);
+#ccall H5FDopen, CString -> CUInt -> <hid_t> -> <haddr_t> -> IO (Ptr <H5FD_t>)
+
+-- |Closes the file by calling the driver 'close' callback, which
+-- should free all driver-private data and free the file struct.
+-- Note that the public part of the file struct (the 'H5FD_t' part)
+-- will be all zero during the driver close callback like during
+-- the 'open' callback.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5FDclose(H5FD_t *file);
+#ccall H5FDclose, In <H5FD_t> -> IO <herr_t>
+
+-- |Compare the keys of two files using the file driver callback
+-- if the files belong to the same driver, otherwise sort the
+-- files by driver class pointer value.
+--
+-- Returns an integer greater than, less than, or equal to zero,
+-- indicating the corresponding ordering.
+--
+-- Must never fail. If both file handles are invalid then they
+-- compare equal. If one file handle is invalid then it compares
+-- less than the other.  If both files belong to the same driver
+-- and the driver doesn't provide a comparison callback then the
+-- file pointers themselves are compared.
+--
+-- > int H5FDcmp(const H5FD_t *f1, const H5FD_t *f2);
+#ccall H5FDcmp, In <H5FD_t> -> In <H5FD_t> -> IO CInt
+
+-- |Query a VFL driver for its feature flags. (listed in
+-- "Bindings.HDF5.Raw.H5FD")
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > int H5FDquery(const H5FD_t *f, unsigned long *flags);
+#ccall H5FDquery, In <H5FD_t> -> Out CULong -> IO CInt
+
+-- |Allocates 'size' bytes of memory from the 'file'. The memory will
+-- be used according to the allocation class 'type'. First we try
+-- to satisfy the request from one of the free lists, according
+-- to the free list map provided by the driver. The free list
+-- array has one entry for each request type and the value of
+-- that array element can be one of four possibilities:
+--
+-- * It can be the constant 'h5fd_MEM_DEFAULT' (or zero) which
+--   indicates that the identity mapping is used. In other
+--   words, the request type maps to its own free list.
+--
+-- * It can be the request type itself, which has the same
+--   effect as the 'h5fd_MEM_DEFAULT' value above.
+--
+-- * It can be the ID for another request type, which
+--   indicates that the free list for the specified type
+--   should be used instead.
+--
+-- * It can be the constant 'h5fd_MEM_NOLIST' which means that
+--   no free list should be used for this type of request.
+--
+-- If the request cannot be satisfied from a free list then
+-- either the driver's 'alloc' callback is invoked (if one was
+-- supplied) or the end-of-address marker is extended. The
+-- 'alloc' callback is always called with the same arguments as
+-- the 'h5fd_alloc'.
+--
+-- Returns the format address of the new file memory, or the
+-- undefined address 'hADDR_UNDEF' on failure.
+--
+-- > haddr_t H5FDalloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size);
+#ccall H5FDalloc, In <H5FD_t> -> <H5FD_mem_t> -> <hid_t> -> <hsize_t> -> IO <haddr_t>
+
+-- |Frees format addresses starting with 'addr' and continuing for
+-- 'size' bytes in the file 'file'. The type of space being freed is
+-- specified by 'type', which is mapped to a free list as
+-- described for the 'h5fd_alloc' function above.  If the request
+-- doesn't map to a free list then either the application 'free'
+-- callback is invoked (if defined) or the memory is leaked.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5FDfree(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id,
+-- >                        haddr_t addr, hsize_t size);
+#ccall H5FDfree, In <H5FD_t> -> <H5FD_mem_t> -> <hid_t> -> <haddr_t> -> <hsize_t> -> IO <herr_t>
+
+-- |Returns the address of the first byte after the last
+-- allocated memory in the file, or 'hADDR_UNDEF' on failure.
+--
+-- > haddr_t H5FDget_eoa(H5FD_t *file, H5FD_mem_t type);
+#ccall H5FDget_eoa, In <H5FD_t> -> <H5FD_mem_t> -> IO <haddr_t>
+
+-- |Set the end-of-address marker for the file. The 'addr' is the
+-- address of the first byte past the last allocated byte of the
+-- file. This function is called from two places:
+--
+--  1. It is called after an existing file is opened in order to
+--     \"allocate\" enough space to read the superblock and then
+--     to \"allocate\" the entire hdf5 file based on the contents
+--     of the superblock.
+--
+--  2. It is called during file memory allocation if the
+--     allocation request cannot be satisfied from the free list
+--     and the driver didn't supply an allocation callback.
+--
+-- Returns non-negative on success, or negative on failure.  If the
+-- operation fails, it will do so with no side-effects.
+--
+-- > herr_t H5FDset_eoa(H5FD_t *file, H5FD_mem_t type, haddr_t eoa);
+#ccall H5FDset_eoa, In <H5FD_t> -> <H5FD_mem_t> -> <haddr_t> -> IO <herr_t>
+
+-- |Returns the end-of-file address, which is the greater of the
+-- end-of-format address and the actual EOF marker. This
+-- function is called after an existing file is opened in order
+-- for the library to learn the true size of the underlying file
+-- and to determine whether the hdf5 data has been truncated.
+--
+-- It is also used when a file is first opened to learn whether
+-- the file is empty or not.
+--
+-- It is permissible for the driver to return the maximum address
+-- for the file size if the file is not empty.
+--
+-- On failure, returns 'hADDR_UNDEF'
+--
+#if H5_VERSION_GE(1,10,0)
+-- > haddr_t H5FDget_eof(H5FD_t *file, H5FD_mem_t type);
+#ccall H5FDget_eof, In <H5FD_t> -> <H5FD_mem_t> -> IO <haddr_t>
+#else
+-- > haddr_t H5FDget_eof(H5FD_t *file);
+#ccall H5FDget_eof, In <H5FD_t> -> IO <haddr_t>
+#endif
+
+-- |Returns a pointer to the file handle of low-level virtual
+-- file driver.
+--
+-- returns non-negative on success, negative otherwise.
+--
+-- > herr_t H5FDget_vfd_handle(H5FD_t *file, hid_t fapl, void**file_handle);
+#ccall H5FDget_vfd_handle, In <H5FD_t> -> <hid_t> -> Out (Ptr a) -> IO <herr_t>
+
+-- |Reads 'size' bytes from 'file' beginning at address 'addr'
+-- according to the data transfer property list 'dxpl_id' (which may
+-- be the constant 'h5p_DEFAULT'). The result is written into the
+-- buffer 'buf'.
+--
+-- Returns non-negative on success.  The read result is written into
+-- the 'buf' buffer which should be allocated by the caller.
+--
+-- On failure, returns a negative value and the contents of 'buf'
+-- is undefined.
+--
+-- > herr_t H5FDread(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id,
+-- >        haddr_t addr, size_t size, void *buf/*out*/);
+#ccall H5FDread, In <H5FD_t> -> <H5FD_mem_t> -> <hid_t> -> <haddr_t> -> <size_t> -> OutArray a -> IO <herr_t>
+
+-- |Writes 'size' bytes to 'file' beginning at address 'addr' according
+-- to the data transfer property list 'dxpl_id' (which may be the
+-- constant 'h5p_DEFAULT'). The bytes to be written come from the
+-- buffer 'buf'.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5FDwrite(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id,
+-- >        haddr_t addr, size_t size, const void *buf);
+#ccall H5FDwrite, In <H5FD_t> -> <H5FD_mem_t> -> <hid_t> -> <haddr_t> -> <size_t> -> InArray a -> IO <herr_t>
+
+-- |Notify driver to flush all cached data.  If the driver has no
+-- flush method then nothing happens.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5FDflush(H5FD_t *file, hid_t dxpl_id, unsigned closing);
+#ccall H5FDflush, In <H5FD_t> -> <hid_t> -> CUInt -> IO <herr_t>
+
+#if H5_VERSION_GE(1,8,2)
+-- |Notify driver to truncate the file back to the allocated size.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5FDtruncate(H5FD_t *file, hid_t dxpl_id, hbool_t closing);
+#ccall H5FDtruncate, In <H5FD_t> -> <hid_t> -> <hbool_t> -> IO <herr_t>
+#endif
+
+#if H5_VERSION_GE(1,10,0)
+-- > herr_t H5FDlock(H5FD_t *file, hbool_t rw);
+#ccall H5FDlock, In <H5FD_t> -> <hbool_t> -> IO <herr_t>
+
+-- > herr_t H5FDunlock(H5FD_t *file);
+#ccall H5FDunlock, In <H5FD_t> -> IO <herr_t>
+#endif
diff --git a/src/Bindings/HDF5/Raw/H5FD/Core.hsc b/src/Bindings/HDF5/Raw/H5FD/Core.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/H5FD/Core.hsc
@@ -0,0 +1,48 @@
+#include <bindings.h>
+#include <hdf5.h>
+
+-- |A driver which stores the HDF5 data in main memory using
+-- only the HDF5 public API. This driver is useful for fast
+-- access to small, temporary hdf5 files.
+module Bindings.HDF5.Raw.H5FD.Core where
+
+import Foreign.C.Types
+import Foreign.Ptr
+import System.IO.Unsafe (unsafePerformIO)
+
+import Bindings.HDF5.Raw.H5
+import Bindings.HDF5.Raw.H5I
+
+import Foreign.Ptr.Conventions
+
+#mangle_ident "H5FD_CORE"
+  :: HId_t
+#mangle_ident "H5FD_CORE"
+    = unsafePerformIO (#mangle_ident "H5FD_core_init")
+
+-- |Initialize this driver by registering the driver with the library.
+--
+-- > hid_t H5FD_core_init(void);x
+#ccall H5FD_core_init, IO <hid_t>
+
+#if H5_VERSION_LE(1,8,18)
+-- |Shut down the VFD.
+--
+-- > void H5FD_core_term(void);
+#ccall H5FD_core_term, IO ()
+#endif
+
+-- |Modify the file access property list to use the H5FD_CORE
+-- driver.  The 'increment' specifies how much to grow the memory
+-- each time we need more.
+--
+-- > herr_t H5Pset_fapl_core(hid_t fapl_id, size_t increment,
+-- >        hbool_t backing_store);
+#ccall H5Pset_fapl_core, <hid_t> -> <size_t> -> <hbool_t> -> IO <herr_t>
+
+-- |Queries properties set by the H5Pset_fapl_core() function.
+--
+-- > herr_t H5Pget_fapl_core(hid_t fapl_id, size_t *increment/*out*/,
+-- >        hbool_t *backing_store/*out*/);
+#ccall H5Pget_fapl_core, <hid_t> -> Out <size_t> -> Out <hbool_t> -> IO <herr_t>
+
diff --git a/src/Bindings/HDF5/Raw/H5FD/Direct.hsc b/src/Bindings/HDF5/Raw/H5FD/Direct.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/H5FD/Direct.hsc
@@ -0,0 +1,56 @@
+#include <bindings.h>
+#include <hdf5.h>
+
+-- |The Direct I/O file driver forces the data to be written to
+-- the file directly without being copied into system kernel
+-- buffer.  The main system supporting this feature is Linux.
+module Bindings.HDF5.Raw.H5FD.Direct where
+
+import Bindings.HDF5.Raw.H5I
+
+#mangle_ident "H5FD_DIRECT"
+  :: HId_t
+#mangle_ident "H5FD_DIRECT"
+#ifdef H5_HAVE_DIRECT
+    = unsafePerformIO (#mangle_ident "H5FD_direct_init")
+#else
+    = (#mangle_datacon "hid_t") (-1)
+#endif /* H5_HAVE_DIRECT */
+
+#ifdef H5_HAVE_DIRECT
+
+-- |Default value for memory boundary.  This can be changed via 'h5p_set_fapl_direct'.
+#num MBOUNDARY_DEF
+
+-- |Default value for file block size.  This can be changed via 'h5p_set_fapl_direct'.
+#num FBSIZE_DEF
+
+-- |Default value for maximal copy buffer size.  This can be changed via 'h5p_set_fapl_direct'.
+#num CBSIZE_DEF
+
+-- |Initialize this driver by registering the driver with the library.
+--
+-- > hid_t H5FD_direct_init(void);
+#ccall H5FD_direct_init, IO <hid_t>
+
+-- |Shut down the VFD.
+--
+-- > void H5FD_direct_term(void);
+#ccall H5FD_direct_term, IO ()
+
+-- TODO: evaluate the claim that "There are no driver-specific properties."  It appears to be patently false.
+-- |Modify the file access property list to use the H5FD_DIRECT
+-- driver.  There are no driver-specific properties.
+--
+-- > herr_t H5Pset_fapl_direct(hid_t fapl_id, size_t alignment, size_t block_size,
+-- >        size_t cbuf_size);
+#ccall H5Pset_fapl_direct, <hid_t> -> <size_t> -> <size_t> -> <size_t> -> IO <herr_t>
+
+-- |Returns information about the direct file access property
+-- list though the function arguments.
+--
+-- > herr_t H5Pget_fapl_direct(hid_t fapl_id, size_t *boundary/*out*/,
+-- >        size_t *block_size/*out*/, size_t *cbuf_size/*out*/);
+#ccall H5Pget_fapl_direct, <hid_t> -> Out <size_t> -> Out <size_t> -> Out <size_t> -> IO <herr_t>
+
+#endif /* H5_HAVE_DIRECT */
diff --git a/src/Bindings/HDF5/Raw/H5FD/Family.hsc b/src/Bindings/HDF5/Raw/H5FD/Family.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/H5FD/Family.hsc
@@ -0,0 +1,61 @@
+#include <bindings.h>
+#include <hdf5.h>
+
+-- |Implements a family of files that acts as a single hdf5
+-- file.  The purpose is to be able to split a huge file on a
+-- 64-bit platform, transfer all the <2GB members to a 32-bit
+-- platform, and then access the entire huge file on the 32-bit
+-- platform.
+--
+-- All family members are logically the same size although their
+-- physical sizes may vary.  The logical member size is
+-- determined by looking at the physical size of the first member
+-- when the file is opened.  When creating a file family, the
+-- first member is created with a predefined physical size
+-- (actually, this happens when the file family is flushed, and
+-- can be quite time consuming on file systems that don't
+-- implement holes, like nfs).
+module Bindings.HDF5.Raw.H5FD.Family where
+
+import System.IO.Unsafe (unsafePerformIO)
+
+import Foreign.Ptr
+
+import Bindings.HDF5.Raw.H5
+import Bindings.HDF5.Raw.H5I
+import Foreign.Ptr.Conventions
+
+#mangle_ident "H5FD_FAMILY"
+  :: HId_t
+#mangle_ident "H5FD_FAMILY"
+    = unsafePerformIO (#mangle_ident "H5FD_family_init")
+
+-- |Initialize this driver by registering the driver with the library.
+--
+-- > hid_t H5FD_family_init(void);
+#ccall H5FD_family_init, IO <hid_t>
+
+#if H5_VERSION_LE(1,8,18)
+-- |Shut down the VFD.
+--
+-- > void H5FD_family_term(void);
+#ccall H5FD_family_term, IO ()
+#endif
+
+-- |Sets the file access property list 'fapl_id' to use the family
+-- driver. The 'memb_size' is the size in bytes of each file
+-- member (used only when creating a new file) and the
+-- 'memb_fapl_id' is a file access property list to be used for
+-- each family member.
+--
+-- > herr_t H5Pset_fapl_family(hid_t fapl_id, hsize_t memb_size,
+-- >        hid_t memb_fapl_id);
+#ccall H5Pset_fapl_family, <hid_t> -> <hsize_t> -> <hid_t> -> IO <herr_t>
+
+-- |Returns information about the family file access property
+-- list though the function arguments.
+--
+-- > herr_t H5Pget_fapl_family(hid_t fapl_id, hsize_t *memb_size/*out*/,
+-- >        hid_t *memb_fapl_id/*out*/);
+#ccall H5Pget_fapl_family, <hid_t> -> Out <hsize_t> -> Out <hid_t> -> IO <herr_t>
+
diff --git a/src/Bindings/HDF5/Raw/H5FD/Log.hsc b/src/Bindings/HDF5/Raw/H5FD/Log.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/H5FD/Log.hsc
@@ -0,0 +1,80 @@
+#include <bindings.h>
+#include <hdf5.h>
+
+-- |The POSIX unbuffered file driver using only the HDF5 public
+-- API and with a few optimizations: the lseek() call is made
+-- only when the current file position is unknown or needs to be
+-- changed based on previous I/O through this driver (don't mix
+-- I/O from this driver with I/O from other parts of the
+-- application to the same file).
+--     With custom modifications...
+module Bindings.HDF5.Raw.H5FD.Log where
+
+import Foreign.C.String
+import Foreign.C.Types
+import Foreign.Ptr
+import System.IO.Unsafe (unsafePerformIO)
+
+import Bindings.HDF5.Raw.H5
+import Bindings.HDF5.Raw.H5I
+
+#mangle_ident "H5FD_LOG"
+  :: HId_t
+#mangle_ident "H5FD_LOG"
+    = unsafePerformIO (#mangle_ident "H5FD_log_init")
+
+-- * Flags for 'h5p_set_fapl_log'
+
+-- ** Flags for tracking where reads/writes/seeks occur
+#num H5FD_LOG_LOC_READ
+#num H5FD_LOG_LOC_WRITE
+#num H5FD_LOG_LOC_SEEK
+#num H5FD_LOG_LOC_IO
+
+-- ** Flags for tracking number of times each byte is read/written
+#num H5FD_LOG_FILE_READ
+#num H5FD_LOG_FILE_WRITE
+#num H5FD_LOG_FILE_IO
+
+-- ** Flag for tracking "flavor" (type) of information stored at each byte */
+#num H5FD_LOG_FLAVOR
+
+-- ** Flags for tracking total number of reads/writes/seeks */
+#num H5FD_LOG_NUM_READ
+#num H5FD_LOG_NUM_WRITE
+#num H5FD_LOG_NUM_SEEK
+#num H5FD_LOG_NUM_IO
+
+-- ** Flags for tracking time spent in open/read/write/seek/close */
+#num H5FD_LOG_TIME_OPEN
+#num H5FD_LOG_TIME_READ
+#num H5FD_LOG_TIME_WRITE
+#num H5FD_LOG_TIME_SEEK
+#num H5FD_LOG_TIME_CLOSE
+#num H5FD_LOG_TIME_IO
+
+-- ** Flag for tracking allocation of space in file */
+#num H5FD_LOG_ALLOC
+#num H5FD_LOG_ALL
+
+-- * Functions
+
+-- |Initialize this driver by registering the driver with the library.
+--
+-- > hid_t H5FD_log_init(void);
+#ccall H5FD_log_init, IO <hid_t>
+
+#if H5_VERSION_LE(1,8,18)
+-- |Shut down the VFD.
+--
+-- > void H5FD_log_term(void);
+#ccall H5FD_log_term, IO ()
+#endif
+
+-- TODO: evaluate the claim that "There are no driver-specific properties."  It appears to be patently false.
+-- |Modify the file access property list to use the H5FD_LOG
+-- driver.  There are no driver-specific properties.
+--
+-- > herr_t H5Pset_fapl_log(hid_t fapl_id, const char *logfile, unsigned flags, size_t buf_size);
+#ccall H5Pset_fapl_log, <hid_t> -> CString -> CUInt -> <size_t> -> IO <herr_t>
+
diff --git a/src/Bindings/HDF5/Raw/H5FD/MPI.hsc b/src/Bindings/HDF5/Raw/H5FD/MPI.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/H5FD/MPI.hsc
@@ -0,0 +1,109 @@
+#include <bindings.h>
+#include <hdf5.h>
+#include <H5FDmpi.h>
+#include "H5FDmpio.h"
+-- #include "H5FDmpiposix.h" : Not compatible with latest brew hdf
+
+module Bindings.HDF5.Raw.H5FD.MPI where
+
+import Data.Word
+import Foreign.Storable
+
+-- TODO: Haddock docs.  This is a low priority right now because I don't even have an MPI library installed anywhere.
+
+#num H5D_ONE_LINK_CHUNK_IO_THRESHOLD
+#num H5D_MULTI_CHUNK_IO_COL_THRESHOLD
+
+#newtype H5FD_mpio_xfer_t
+#newtype_const H5FD_mpio_xfer_t, H5FD_MPIO_INDEPENDENT
+#newtype_const H5FD_mpio_xfer_t, H5FD_MPIO_COLLECTIVE
+
+#newtype H5FD_mpio_chunk_opt_t
+#newtype_const H5FD_mpio_chunk_opt_t, H5FD_MPIO_CHUNK_DEFAULT
+#newtype_const H5FD_mpio_chunk_opt_t, H5FD_MPIO_CHUNK_ONE_IO
+#newtype_const H5FD_mpio_chunk_opt_t, H5FD_MPIO_CHUNK_MULTI_IO
+
+#newtype H5FD_mpio_collective_opt_t
+#newtype_const H5FD_mpio_collective_opt_t, H5FD_MPIO_COLLECTIVE_IO
+#newtype_const H5FD_mpio_collective_opt_t, H5FD_MPIO_INDIVIDUAL_IO
+
+#if H5_VERSION_LE(1,8,10)
+
+#ifdef H5_HAVE_PARALLEL
+
+#starttype H5FD_class_mpi_t
+#field super, <H5FD_class_t>
+#field get_rank, FunPtr (In <H5FD_t> -> IO CInt) int
+#field get_size, FunPtr (In <H5FD_t> -> IO CInt) int
+#field get_comm, FunPtr (In <H5FD_t> -> IO <MPI_Comm>)
+#stoptype
+
+#endif /* H5_HAVE_PARALLEL */
+
+-- I would wrap this macro, but despite being in the public headers it uses
+-- a macro internally that is not...
+-- #cinline IS_H5FD_MPI, In <hid_t> -> IO CInt
+
+#ifdef H5_HAVE_PARALLEL
+
+#str H5FD_MPI_XFER_MEM_MPI_TYPE_NAME
+
+#str H5FD_MPI_XFER_FILE_MPI_TYPE_NAME
+
+#cinline H5FD_mpi_native_g, CString
+
+-- haddr_t H5FD_mpi_MPIOff_to_haddr(MPI_Offset mpi_off);
+#ccall H5FD_mpi_MPIOff_to_haddr, <MPI_Offset> -> IO <haddr_t>
+
+-- herr_t H5FD_mpi_haddr_to_MPIOff(haddr_t addr, MPI_Offset *mpi_off/*out*/);
+#ccall H5FD_mpi_haddr_to_MPIOff, <haddr_t> -> Out <MPI_Offset> -> IO <herr_t>
+
+-- herr_t H5FD_mpi_comm_info_dup(MPI_Comm comm, MPI_Info info,
+-- 				MPI_Comm *comm_new, MPI_Info *info_new);
+#ccall H5FD_mpi_comm_info_dup, <MPI_Comm> -> <MPI_Info> -> Out <MPI_Comm> -> Out <MPI_Info> -> IO <herr_t>
+
+-- herr_t H5FD_mpi_comm_info_free(MPI_Comm *comm, MPI_Info *info);
+#ccall H5FD_mpi_comm_info_free, In <MPI_Comm> -> In <MPI_Info> -> IO <herr_t>
+
+
+#ifdef NOT_YET
+
+-- herr_t H5FD_mpio_wait_for_left_neighbor(H5FD_t *file);
+#ccall H5FD_mpio_wait_for_left_neighbor, In <H5FD_t> -> IO <herr_t>
+
+-- herr_t H5FD_mpio_signal_right_neighbor(H5FD_t *file);
+#ccall H5FD_mpio_signal_right_neighbor, In <H5FD_t> -> IO <herr_t>
+
+#endif /* NOT_YET */
+
+#if H5_VERSION_GE(1,8,10)
+
+-- herr_t H5FD_mpi_setup_collective(hid_t dxpl_id, MPI_Datatype *btype,
+--     MPI_Datatype *ftype);
+#ccall H5FD_mpi_setup_collective, <hid_t> -> Ptr <MPI_Datatype> -> Ptr <MPI_Datatype> -> IO <herr_t>
+
+#else
+
+-- herr_t H5FD_mpi_setup_collective(hid_t dxpl_id, MPI_Datatype btype,
+--     MPI_Datatype ftype);
+#ccall H5FD_mpi_setup_collective, <hid_t> -> <MPI_Datatype> -> <MPI_Datatype> -> IO <herr_t>
+
+-- herr_t H5FD_mpi_teardown_collective(hid_t dxpl_id);
+#ccall H5FD_mpi_teardown_collective, <hid_t> -> IO <herr_t>
+
+#endif
+
+
+-- /* Driver specific methods */
+-- int H5FD_mpi_get_rank(const H5FD_t *file);
+#ccall H5FD_mpi_get_rank, In <H5FD_t> -> IO CInt
+
+-- int H5FD_mpi_get_size(const H5FD_t *file);
+#ccall H5FD_mpi_get_size, In <H5FD_t> -> IO CInt
+
+-- MPI_Comm H5FD_mpi_get_comm(const H5FD_t *_file);
+#ccall H5FD_mpi_get_comm, In <H5FD_t> -> IO <MPI_Comm>
+
+#endif /* H5_HAVE_PARALLEL */
+
+#endif /* H5_VERSION_LE */
diff --git a/src/Bindings/HDF5/Raw/H5FD/Multi.hsc b/src/Bindings/HDF5/Raw/H5FD/Multi.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/H5FD/Multi.hsc
@@ -0,0 +1,163 @@
+#include <bindings.h>
+#include <hdf5.h>
+
+-- |H5FDmulti Implements a file driver which dispatches I/O requests to
+-- other file drivers depending on the purpose of the address
+-- region being accessed. For instance, all meta-data could be
+-- placed in one file while all raw data goes to some other file.
+module Bindings.HDF5.Raw.H5FD.Multi where
+
+import Foreign.C.String
+import Foreign.Ptr
+import System.IO.Unsafe (unsafePerformIO)
+
+import Bindings.HDF5.Raw.H5
+import Bindings.HDF5.Raw.H5I
+import Bindings.HDF5.Raw.H5FD
+import Foreign.Ptr.Conventions
+
+#mangle_ident "H5FD_MULTI"
+  :: HId_t
+#mangle_ident "H5FD_MULTI"
+    = unsafePerformIO (#mangle_ident "H5FD_multi_init")
+
+-- |Initialize this driver by registering the driver with the library.
+--
+-- On success, returns the driver ID for the multi driver.  On failure,
+-- returns a negative value.
+--
+-- > hid_t H5FD_multi_init(void);
+#ccall H5FD_multi_init, IO <hid_t>
+
+#if H5_VERSION_LE(1,8,18)
+-- Shut down the VFD
+--
+-- > void H5FD_multi_term(void);
+#ccall H5FD_multi_term, IO ()
+#endif
+
+-- TODO: find out whether input arrays need to be static... Probably not, since H5Pget_fapl_multi copies them out.
+-- |Sets the file access property list 'fapl_id' to use the multi
+-- driver. The 'memb_map' array maps memory usage types to other
+-- memory usage types and is the mechanism which allows the
+-- caller to specify how many files are created. The array
+-- contains 'h5fd_MEM_NTYPES' entries which are either the value
+-- 'h5fd_MEM_DEFAULT' or a memory usage type and the number of
+-- unique values determines the number of files which are
+-- opened.  For each memory usage type which will be associated
+-- with a file the 'memb_fapl' array should have a property list
+-- and the 'memb_name' array should be a name generator (a
+-- printf-style format with a %s which will be replaced with the
+-- name passed to 'h5fd_open', usually from 'h5f_create' or
+-- 'h5f_open').
+--
+-- If 'relax' is set then opening an existing file for read-only
+-- access will not fail if some file members are missing.  This
+-- allows a file to be accessed in a limited sense if just the
+-- meta data is available.
+--
+-- Default values for each of the optional arguments are:
+--
+-- ['memb_map']
+--      The default member map has the value
+--      'h5fd_MEM_DEFAULT' for each element.
+--
+-- ['memb_fapl']
+--      The value 'h5p_DEFAULT' for each element.
+--
+-- ['memb_name']
+--      The string \"%s-X.h5\" where \"X\" is one of the
+--         letters \"s\" ('h5fd_MEM_SUPER'),
+--         \"b\" ('h5fd_MEM_BTREE'), \"r\" ('h5fd_MEM_DRAW'),
+--         \"g\" ('h5fd_MEM_GHEAP'), \"l\" ('h5fd_MEM_LHEAP'),
+--         \"o\" ('h5fd_MEM_OHDR').
+--
+-- ['memb_addr']
+--      The value 'hADDR_UNDEF' for each element.
+--
+--
+-- Example: To set up a multi file access property list which partitions
+-- data into meta and raw files each being 1/2 of the address
+-- space one would say (TODO: translate to Haskell):
+--
+-- > H5FD_mem_t mt, memb_map[H5FD_MEM_NTYPES];
+-- > hid_t memb_fapl[H5FD_MEM_NTYPES];
+-- > const char *memb[H5FD_MEM_NTYPES];
+-- > haddr_t memb_addr[H5FD_MEM_NTYPES];
+-- >
+-- > // The mapping...
+-- > for (mt=0; mt<H5FD_MEM_NTYPES; mt++) {
+-- >     memb_map[mt] = H5FD_MEM_SUPER;
+-- > }
+-- > memb_map[H5FD_MEM_DRAW] = H5FD_MEM_DRAW;
+-- >
+-- > // Member information
+-- > memb_fapl[H5FD_MEM_SUPER] = H5P_DEFAULT;
+-- > memb_name[H5FD_MEM_SUPER] = "%s.meta";
+-- > memb_addr[H5FD_MEM_SUPER] = 0;
+-- >
+-- > memb_fapl[H5FD_MEM_DRAW] = H5P_DEFAULT;
+-- > memb_name[H5FD_MEM_DRAW] = "%s.raw";
+-- > memb_addr[H5FD_MEM_DRAW] = HADDR_MAX/2;
+-- >
+-- > hid_t fapl = H5Pcreate(H5P_FILE_ACCESS);
+-- > H5Pset_fapl_multi(fapl, memb_map, memb_fapl,
+-- >                   memb_name, memb_addr, TRUE);
+--
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_fapl_multi(hid_t fapl_id, const H5FD_mem_t *memb_map,
+-- >        const hid_t *memb_fapl, const char * const *memb_name,
+-- >        const haddr_t *memb_addr, hbool_t relax);
+#ccall H5Pset_fapl_multi, <hid_t> -> InArray <H5FD_mem_t> -> InArray <hid_t> -> InArray CString -> InArray <haddr_t> -> <hbool_t> -> IO <herr_t>
+
+-- |Returns information about the multi file access property
+-- list though the function arguments which are the same as for
+-- 'h5p_set_fapl_multi' above.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_fapl_multi(hid_t fapl_id, H5FD_mem_t *memb_map/*out*/,
+-- >        hid_t *memb_fapl/*out*/, char **memb_name/*out*/,
+-- >        haddr_t *memb_addr/*out*/, hbool_t *relax/*out*/);
+#ccall H5Pget_fapl_multi, <hid_t> -> OutArray <H5FD_mem_t> -> OutArray <hid_t> -> OutArray CString -> OutArray <haddr_t> -> Out <hbool_t> -> IO <herr_t>
+
+#if H5_VERSION_LE(1,8,10)
+
+-- TODO: investigate and elaborate.  Does this use the same array size and format as H5Pset_fapl_multi?
+-- |Set the data transfer property list 'dxpl_id' to use the multi
+-- driver with the specified data transfer properties for each
+-- memory usage type in the array 'memb_dxpl' (after the usage map is
+-- applied).
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_dxpl_multi(hid_t dxpl_id, const hid_t *memb_dxpl);
+#ccall H5Pset_dxpl_multi, <hid_t> -> InArray <hid_t> -> IO <herr_t>
+
+-- Purpose:	Returns information which was set with 'h5p_set_dxpl_multi' above.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_dxpl_multi(hid_t dxpl_id, hid_t *memb_dxpl/*out*/);
+#ccall H5Pget_dxpl_multi, <hid_t> -> OutArray <hid_t> -> IO <herr_t>
+
+#endif /* H5_VERSION_LE */
+
+-- |Compatability function. Makes the multi driver act like the
+-- old split driver which stored meta data in one file and raw
+-- data in another file.
+--
+-- If the raw or meta extension string contains a \"%s\", it will
+-- be substituted by the filename given for 'h5f_open' or 'h5f_create'.
+-- If no %s is found, one is inserted at the beginning.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_fapl_split(hid_t fapl, const char *meta_ext,
+-- >        hid_t meta_plist_id, const char *raw_ext,
+-- >        hid_t raw_plist_id);
+#ccall H5Pset_fapl_split, <hid_t> -> CString -> <hid_t> -> CString -> <hid_t> -> IO <herr_t>
+
+
diff --git a/src/Bindings/HDF5/Raw/H5FD/Sec2.hsc b/src/Bindings/HDF5/Raw/H5FD/Sec2.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/H5FD/Sec2.hsc
@@ -0,0 +1,40 @@
+#include <bindings.h>
+#include <hdf5.h>
+
+-- |The POSIX unbuffered file driver using only the HDF5 public
+-- API and with a few optimizations: the lseek() call is made
+-- only when the current file position is unknown or needs to be
+-- changed based on previous I/O through this driver (don't mix
+-- I/O from this driver with I/O from other parts of the
+-- application to the same file).
+module Bindings.HDF5.Raw.H5FD.Sec2 where
+
+import Foreign.Ptr
+import System.IO.Unsafe (unsafePerformIO)
+
+import Bindings.HDF5.Raw.H5
+import Bindings.HDF5.Raw.H5I
+
+#mangle_ident "H5FD_SEC2"
+  :: HId_t
+#mangle_ident "H5FD_SEC2"
+    = unsafePerformIO (#mangle_ident "H5FD_sec2_init")
+
+-- |Initialize this driver by registering the driver with the library.
+--
+-- > hid_t H5FD_sec2_init(void);
+#ccall H5FD_sec2_init, IO <hid_t>
+
+#if H5_VERSION_LE(1,8,18)
+-- |Shut down the VFD.
+--
+-- > void H5FD_sec2_term(void);
+#ccall H5FD_sec2_term, IO ()
+#endif
+ 
+-- |Modify the file access property list to use the H5FD_SEC2
+-- driver.  There are no driver-specific properties.
+--
+-- > herr_t H5Pset_fapl_sec2(hid_t fapl_id);
+#ccall H5Pset_fapl_sec2, <hid_t> -> IO <herr_t>
+
diff --git a/src/Bindings/HDF5/Raw/H5FD/StdIO.hsc b/src/Bindings/HDF5/Raw/H5FD/StdIO.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/H5FD/StdIO.hsc
@@ -0,0 +1,36 @@
+#include <bindings.h>
+#include <hdf5.h>
+
+module Bindings.HDF5.Raw.H5FD.StdIO where
+
+import Foreign.Ptr
+import System.IO.Unsafe (unsafePerformIO)
+
+import Bindings.HDF5.Raw.H5
+import Bindings.HDF5.Raw.H5I
+
+#mangle_ident "H5FD_STDIO"
+  :: HId_t
+#mangle_ident "H5FD_STDIO"
+    = unsafePerformIO (#mangle_ident "H5FD_stdio_init")
+
+-- |Initialize this driver by registering the driver with the library.
+--
+-- > hid_t H5FD_stdio_init(void);
+#ccall H5FD_stdio_init, IO <hid_t>
+
+#if H5_VERSION_LE(1,8,18)
+
+-- |Shut down the VFD.
+--
+-- > void H5FD_stdio_term(void);
+#ccall H5FD_stdio_term, IO ()
+
+#endif
+
+-- |Modify the file access property list to use the H5FD_STDIO
+-- driver.  There are no driver-specific properties.
+--
+-- herr_t H5Pset_fapl_stdio(hid_t fapl_id);
+#ccall H5Pset_fapl_stdio, <hid_t> -> IO <herr_t>
+
diff --git a/src/Bindings/HDF5/Raw/H5G.hsc b/src/Bindings/HDF5/Raw/H5G.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/H5G.hsc
@@ -0,0 +1,422 @@
+#include <bindings.h>
+#include <H5Gpublic.h>
+
+module Bindings.HDF5.Raw.H5G where
+
+import Data.Int
+import Foreign.C.String
+import Foreign.C.Types
+import Foreign.Marshal.Array
+import Foreign.Ptr
+import Foreign.Storable
+
+import Bindings.HDF5.Raw.H5
+import Bindings.HDF5.Raw.H5I
+import Bindings.HDF5.Raw.H5L
+import Bindings.HDF5.Raw.H5O
+import Foreign.Ptr.Conventions
+
+-- |Types of link storage for groups
+#newtype H5G_storage_type_t, Eq, Ord, Read
+
+-- |Unknown link storage type
+#newtype_const H5G_storage_type_t, H5G_STORAGE_TYPE_UNKNOWN
+
+-- |Links in group are stored with a \"symbol table\"
+-- (this is sometimes called \"old-style\" groups)
+#newtype_const H5G_storage_type_t, H5G_STORAGE_TYPE_SYMBOL_TABLE
+
+-- |Links are stored in object header
+#newtype_const H5G_storage_type_t, H5G_STORAGE_TYPE_COMPACT
+
+-- |Links are stored in fractal heap & indexed with v2 B-tree
+#newtype_const H5G_storage_type_t, H5G_STORAGE_TYPE_DENSE
+
+-- |Information struct for group (for 'h5g_get_info' / 'h5g_get_info_by_name' / 'h5g_get_info_by_idx')
+#starttype H5G_info_t
+
+-- |Type of storage for links in group
+#field storage_type,    <H5G_storage_type_t>
+
+-- |Number of links in group
+#field nlinks,          <hsize_t>
+
+-- |Current max. creation order value for group
+#field max_corder,      Int64
+
+#if H5_VERSION_GE(1,8,2)
+-- |Whether group has a file mounted on it
+#field mounted,         <hbool_t>
+#endif
+
+#stoptype
+
+
+-- |Creates a new group relative to 'loc_id', giving it the
+-- specified creation property list 'gcpl_id' and access
+-- property list 'gapl_id'.  The link to the new group is
+-- created with the 'lcpl_id'.
+--
+-- Parameters:
+--
+-- [@ loc_id  :: 'HId_t'   @]   File or group identifier
+--
+-- [@ name    :: 'CString' @]   Absolute or relative name of the new group
+--
+-- [@ lcpl_id :: 'HId_t'   @]   Property list for link creation
+--
+-- [@ gcpl_id :: 'HId_t'   @]   Property list for group creation
+--
+-- [@ gapl_id :: 'HId_t'   @]   Property list for group access
+--
+-- On success, returns the object ID of a new, empty group open for
+-- writing.  Call 'h5g_close' when finished with the group.
+-- Returns a negative value on failure.
+--
+-- > hid_t H5Gcreate2(hid_t loc_id, const char *name, hid_t lcpl_id,
+-- >     hid_t gcpl_id, hid_t gapl_id);
+#ccall H5Gcreate2, <hid_t> -> CString -> <hid_t> -> <hid_t> -> <hid_t> -> IO <hid_t>
+
+-- |Creates a new group relative to 'loc_id', giving it the
+-- specified creation property list 'gcpl_id' and access
+-- property list 'gapl_id'.
+--
+-- The resulting ID should be linked into the file with
+-- 'h5o_link' or it will be deleted when closed.
+--
+-- Given the default setting, 'h5g_create_anon' followed by
+-- 'h5o_link' will have the same function as 'h5g_create2'.
+--
+-- Parameters:
+--
+-- [@ loc_id  :: 'HId_t'   @] File or group identifier
+--
+-- [@ name    :: 'CString' @] Absolute or relative name of the new group
+--
+-- [@ gcpl_id :: 'HId_t'   @] Property list for group creation
+--
+-- [@ gapl_id :: 'HId_t'   @] Property list for group access
+--
+-- Example:  To create missing groups \"A\" and \"B01\" along the given path
+-- \"/A/B01/grp\" (TODO: translate to Haskell):
+--
+-- > hid_t create_id = H5Pcreate(H5P_GROUP_CREATE);
+-- > int   status = H5Pset_create_intermediate_group(create_id, TRUE);
+-- > hid_t gid = H5Gcreate_anon(file_id, "/A/B01/grp", create_id, H5P_DEFAULT);
+--
+-- On success, returns the object ID of a new, empty group open for
+-- writing.  Call 'h5g_close' when finished with the group.
+-- On failure, returns a negative value.
+--
+-- > hid_t H5Gcreate_anon(hid_t loc_id, hid_t gcpl_id, hid_t gapl_id);
+#ccall H5Gcreate_anon, <hid_t> -> <hid_t> -> <hid_t> -> IO <hid_t>
+
+-- |Opens an existing group for modification.  When finished,
+-- call 'h5g_close' to close it and release resources.
+--
+-- This function allows the user the pass in a Group Access
+-- Property List, which 'h5g_open1' does not.
+--
+-- On success, returns the object ID of the group.
+-- On failure, returns a negative value.
+--
+-- > hid_t H5Gopen2(hid_t loc_id, const char *name, hid_t gapl_id);
+#ccall H5Gopen2, <hid_t> -> CString -> <hid_t> -> IO <hid_t>
+
+-- |Returns a copy of the group creation property list.
+--
+-- On success, returns the ID for a copy of the group creation
+-- property list.  The property list ID should be released by
+-- calling 'h5p_close'.
+--
+-- > hid_t H5Gget_create_plist(hid_t group_id);
+#ccall H5Gget_create_plist, <hid_t> -> IO <hid_t>
+
+-- |Retrieve information about a group.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Gget_info(hid_t loc_id, H5G_info_t *ginfo);
+#ccall H5Gget_info, <hid_t> -> Out <H5G_info_t> -> IO <herr_t>
+
+-- |Retrieve information about a group.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Gget_info_by_name(hid_t loc_id, const char *name, H5G_info_t *ginfo,
+-- >     hid_t lapl_id);
+#ccall H5Gget_info_by_name, <hid_t> -> CString -> Out <H5G_info_t> -> <hid_t> -> IO <herr_t>
+
+-- |Retrieve information about a group, according to the order of an index.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Gget_info_by_idx(hid_t loc_id, const char *group_name,
+-- >     H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5G_info_t *ginfo,
+-- >     hid_t lapl_id);
+#ccall H5Gget_info_by_idx, <hid_t> -> CString -> <H5_index_t> -> <H5_iter_order_t> -> <hsize_t> -> Out <H5G_info_t> -> <hid_t> -> IO <herr_t>
+
+-- |Closes the specified group.  The group ID will no longer be
+-- valid for accessing the group.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Gclose(hid_t group_id);
+#ccall H5Gclose, <hid_t> -> IO <herr_t>
+
+#if H5_VERSION_GE(1,10,0)
+-- > herr_t H5Gflush(hid_t group_id);
+#ccall H5Gflush, <hid_t> -> IO <herr_t>
+-- > herr_t H5Grefresh(hid_t group_id);
+#ccall H5Grefresh, <hid_t> -> IO <herr_t>
+#endif
+
+#ifndef H5_NO_DEPRECATED_SYMBOLS
+
+#num H5G_SAME_LOC
+#newtype_const H5L_type_t, H5G_LINK_ERROR
+#newtype_const H5L_type_t, H5G_LINK_HARD
+#newtype_const H5L_type_t, H5G_LINK_SOFT
+type H5G_link_t = H5L_type_t
+
+-- /* Macros for types of objects in a group (see H5G_obj_t definition) */
+#num H5G_NTYPES
+#num H5G_NLIBTYPES
+#num H5G_NUSERTYPES
+#cinline H5G_USERTYPE, <H5G_obj_t> -> <H5G_obj_t>
+
+-- |An object has a certain type. The first few numbers are reserved for use
+-- internally by HDF5. Users may add their own types with higher values.  The
+-- values are never stored in the file - they only exist while an application
+-- is running.  An object may satisfy the 'isa' function for more than one type.
+#newtype H5G_obj_t, Eq
+
+-- |Unknown object type
+#newtype_const H5G_obj_t, H5G_UNKNOWN
+
+-- |Object is a group
+#newtype_const H5G_obj_t, H5G_GROUP
+
+-- |Object is a dataset
+#newtype_const H5G_obj_t, H5G_DATASET
+
+-- |Object is a named data type
+#newtype_const H5G_obj_t, H5G_TYPE
+
+-- |Object is a symbolic link
+#newtype_const H5G_obj_t, H5G_LINK
+
+-- |Object is a user-defined link
+#newtype_const H5G_obj_t, H5G_UDLINK
+
+-- |Reserved for future use
+#newtype_const H5G_obj_t, H5G_RESERVED_5
+
+-- |Reserved for future use
+#newtype_const H5G_obj_t, H5G_RESERVED_6
+
+-- |Reserved for future use
+#newtype_const H5G_obj_t, H5G_RESERVED_7
+
+-- |Type of 'h5g_iterate' operator
+--
+-- > typedef herr_t (*H5G_iterate_t)(hid_t group, const char *name, void *op_data);
+type H5G_iterate_t a = FunPtr (HId_t -> CString -> InOut a -> IO HErr_t)
+
+-- |Information about an object
+#starttype H5G_stat_t
+
+-- |file number
+#array_field fileno,    CULong
+
+-- |object number
+#array_field objno,     CULong
+
+-- |number of hard links to object
+#field nlink,           CUInt
+
+-- |basic object type
+#field type,            <H5G_obj_t>
+
+-- |modification time
+#field mtime,           <time_t>
+
+-- |symbolic link value length
+#field linklen,         <size_t>
+
+-- |Object header information
+#field ohdr,            <H5O_stat_t>
+#stoptype
+
+
+-- |Creates a new group relative to 'loc_id' and gives it the
+-- specified 'name'.  The group is opened for write access
+-- and it's object ID is returned.
+--
+-- The optional 'size_hint' specifies how much file space to
+-- reserve to store the names that will appear in this
+-- group. If a non-positive value is supplied for the 'size_hint'
+-- then a default size is chosen.
+--
+-- Note:  Deprecated in favor of 'h5g_create2'
+--
+-- On success, returns the object ID of a new, empty group open for
+-- writing.  Call 'h5g_close' when finished with the group.
+-- On failure, returns a negative value.
+--
+-- > hid_t H5Gcreate1(hid_t loc_id, const char *name, size_t size_hint);
+#ccall H5Gcreate1, <hid_t> -> CString -> <size_t> -> IO <hid_t>
+
+-- |Opens an existing group for modification.  When finished,
+-- call 'h5g_close' to close it and release resources.
+--
+-- Note:  Deprecated in favor of 'h5g_open2'
+--
+-- On success, returns the Object ID of the group.
+-- On failure, returns a negative value.
+--
+-- > hid_t H5Gopen1(hid_t loc_id, const char *name);
+#ccall H5Gopen1, <hid_t> -> CString -> IO <hid_t>
+
+-- |Creates a link between two existing objects.  The new
+-- APIs to do this are 'h5l_create_hard' and 'h5l_create_soft'.
+--
+-- > herr_t H5Glink(hid_t cur_loc_id, H5G_link_t type, const char *cur_name,
+-- >     const char *new_name);
+#ccall H5Glink, <hid_t> -> <H5G_link_t> -> CString -> CString -> IO <herr_t>
+
+-- |Creates a link between two existing objects.  The new
+-- APIs to do this are 'h5l_create_hard' and 'h5l_create_soft'.
+--
+-- herr_t H5Glink2(hid_t cur_loc_id, const char *cur_name, H5G_link_t type,
+--     hid_t new_loc_id, const char *new_name);
+#ccall H5Glink2, <hid_t> -> CString -> <H5G_link_t> -> <hid_t> -> CString -> IO <herr_t>
+
+-- |Moves and renames a link.  The new API to do this is 'h5l_move'.
+--
+-- > herr_t H5Gmove(hid_t src_loc_id, const char *src_name,
+-- >     const char *dst_name);
+#ccall H5Gmove, <hid_t> -> CString -> CString -> IO <herr_t>
+
+-- |Moves and renames a link.  The new API to do this is 'h5l_move'.
+--
+-- > herr_t H5Gmove2(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id,
+-- >     const char *dst_name);
+#ccall H5Gmove2, <hid_t> -> CString -> <hid_t> -> CString -> IO <herr_t>
+
+-- |Removes a link.  The new API is 'h5l_delete' / 'h5l_delete_by_idx'.
+--
+-- > herr_t H5Gunlink(hid_t loc_id, const char *name);
+#ccall H5Gunlink, <hid_t> -> CString -> IO <herr_t>
+
+-- |Retrieve's a soft link's data.  The new API is 'h5l_get_val' / 'h5l_get_val_by_idx'.
+--
+-- > herr_t H5Gget_linkval(hid_t loc_id, const char *name, size_t size,
+-- >     char *buf/*out*/);
+#ccall H5Gget_linkval, <hid_t> -> CString -> <size_t> -> OutArray a -> IO <herr_t>
+
+-- |Gives the specified object a comment.  The 'comment' string
+-- should be a null terminated string.  An object can have only
+-- one comment at a time.  Passing 'nullPtr' for the 'comment' argument
+-- will remove the comment property from the object.
+--
+-- Note:  Deprecated in favor of 'h5o_set_comment' / 'h5o_set_comment_by_name'
+--
+-- Returns non-negative on success / negative on failure
+--
+-- > herr_t H5Gset_comment(hid_t loc_id, const char *name, const char *comment);
+#ccall H5Gset_comment, <hid_t> -> CString -> CString -> IO <herr_t>
+
+-- |Return at most 'bufsize' characters of the comment for the
+-- specified object.  If 'bufsize' is large enough to hold the
+-- entire comment then the comment string will be null
+-- terminated, otherwise it will not.  If the object does not
+-- have a comment value then no bytes are copied to the BUF
+-- buffer.
+--
+-- Note:  Deprecated in favor of 'h5o_get_comment' / 'h5o_get_comment_by_name'
+--
+-- On success, returns the number of characters in the comment counting
+-- the null terminator.  The value returned may be larger than the 'bufsize'
+-- argument.
+--
+-- > int H5Gget_comment(hid_t loc_id, const char *name, size_t bufsize,
+-- >     char *buf);
+#ccall H5Gget_comment, <hid_t> -> CString -> <size_t> -> OutArray CChar -> IO CInt
+
+-- |Iterates over the entries of a group.  The 'loc_id' and 'name'
+-- identify the group over which to iterate and 'idx' indicates
+-- where to start iterating (zero means at the beginning).	 The
+-- 'operator' is called for each member and the iteration
+-- continues until the operator returns non-zero or all members
+-- are processed. The operator is passed a group ID for the
+-- group being iterated, a member name, and 'op_data' for each
+-- member.
+--
+-- Note:	Deprecated in favor of 'h5l_iterate'
+--
+-- Returns the return value of the first operator that
+-- returns non-zero, or zero if all members were
+-- processed with no operator returning non-zero.
+--
+-- Returns negative if something goes wrong within the
+-- library, or the negative value returned by one
+-- of the operators.
+--
+-- > herr_t H5Giterate(hid_t loc_id, const char *name, int *idx,
+-- >         H5G_iterate_t op, void *op_data);
+#ccall H5Giterate, <hid_t> -> CString -> InOut CInt -> H5G_iterate_t a -> InOut a -> IO <herr_t>
+
+-- |Returns the number of objects in the group.  It iterates
+-- all B-tree leaves and sum up total number of group members.
+--
+-- Note:  Deprecated in favor of 'h5g_get_info'
+--
+-- Returns non-negative on success, negative on failure
+--
+-- > herr_t H5Gget_num_objs(hid_t loc_id, hsize_t *num_objs);
+#ccall H5Gget_num_objs, <hid_t> -> Out <hsize_t> -> IO <herr_t>
+
+-- |Returns information about an object.  If 'follow_link' is
+-- non-zero then all symbolic links are followed; otherwise all
+-- links except the last component of the name are followed.
+--
+-- Note:  Deprecated in favor of 'h5l_get_info' / 'h5o_get_info'
+--
+-- Returns non-negative on success, with the fields of 'statbuf' (if
+-- non-null) initialized. Negative on failure.
+--
+-- > herr_t H5Gget_objinfo(hid_t loc_id, const char *name,
+-- >     hbool_t follow_link, H5G_stat_t *statbuf/*out*/);
+#ccall H5Gget_objinfo, <hid_t> -> CString -> <hbool_t> -> Out <H5G_stat_t> -> IO <herr_t>
+
+-- |Returns the name of objects in the group by giving index.
+-- If 'name' is non-NULL then write up to 'size' bytes into that
+-- buffer and always return the length of the entry name.
+-- Otherwise 'size' is ignored and the function does not store the name,
+-- just returning the number of characters required to store the name.
+-- If an error occurs then the buffer pointed to by 'name' (NULL or non-NULL)
+-- is unchanged and the function returns a negative value.
+-- If a zero is returned for the name's length, then there is no name
+-- associated with the ID.
+--
+-- Note:  Deprecated in favor of 'h5l_get_name_by_idx'
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > ssize_t H5Gget_objname_by_idx(hid_t loc_id, hsize_t idx, char* name,
+-- >     size_t size);
+#ccall H5Gget_objname_by_idx, <hid_t> -> <hsize_t> -> OutArray CChar -> <size_t> -> IO <ssize_t>
+
+-- |Returns the type of objects in the group by giving index.
+--
+-- Note:  Deprecated in favor of 'h5l_get_info' / 'h5o_get_info'
+--
+-- Returns 'h5g_GROUP', 'h5g_DATASET', or 'h5g_TYPE' on success, or
+-- 'h5g_UNKNOWN' on failure.
+--
+-- > H5G_obj_t H5Gget_objtype_by_idx(hid_t loc_id, hsize_t idx);
+#ccall H5Gget_objtype_by_idx, <hid_t> -> <hsize_t> -> IO <H5G_obj_t>
+
+
+#endif /* H5_NO_DEPRECATED_SYMBOLS */
diff --git a/src/Bindings/HDF5/Raw/H5I.hsc b/src/Bindings/HDF5/Raw/H5I.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/H5I.hsc
@@ -0,0 +1,292 @@
+#include <bindings.h>
+#include <H5Apublic.h>
+
+module Bindings.HDF5.Raw.H5I where
+
+import Data.Bits
+import Data.Char
+import Data.Int
+import Foreign.C.Types
+import Foreign.Ptr
+import Foreign.Storable
+
+import Bindings.HDF5.Raw.H5
+import Foreign.Ptr.Conventions
+
+-- |Library type values
+#newtype H5I_type_t, Eq
+
+-- |uninitialized type
+#newtype_const H5I_type_t, H5I_UNINIT
+
+-- |invalid Type
+#newtype_const H5I_type_t, H5I_BADID
+
+-- |type ID for File objects
+#newtype_const H5I_type_t, H5I_FILE
+
+-- |type ID for Group objects
+#newtype_const H5I_type_t, H5I_GROUP
+
+-- |type ID for Datatype objects
+#newtype_const H5I_type_t, H5I_DATATYPE
+
+-- |type ID for Dataspace objects
+#newtype_const H5I_type_t, H5I_DATASPACE
+
+-- |type ID for Dataset objects
+#newtype_const H5I_type_t, H5I_DATASET
+
+-- |type ID for Attribute objects
+#newtype_const H5I_type_t, H5I_ATTR
+
+-- |type ID for Reference objects
+#newtype_const H5I_type_t, H5I_REFERENCE
+
+-- |type ID for virtual file layer
+#newtype_const H5I_type_t, H5I_VFL
+
+-- |type ID for generic property list classes
+#newtype_const H5I_type_t, H5I_GENPROP_CLS
+
+-- |type ID for generic property lists
+#newtype_const H5I_type_t, H5I_GENPROP_LST
+
+-- |type ID for error classes
+#newtype_const H5I_type_t, H5I_ERROR_CLASS
+
+-- |type ID for error messages
+#newtype_const H5I_type_t, H5I_ERROR_MSG
+
+-- |type ID for error stacks
+#newtype_const H5I_type_t, H5I_ERROR_STACK
+
+-- |number of library types
+#num H5I_NTYPES
+
+-- TODO: I think HId_t should be parameterised over the element type and
+-- possibly also dimensionality of the dataset
+-- |Type of atoms to return to users
+#if H5_VERSION_GE(1,10,0)
+
+newtype HId_t = HId_t Int64 deriving (Storable, Eq, Ord)
+
+#else
+
+newtype HId_t = HId_t Int32 deriving (Storable, Eq, Ord)
+
+#endif
+
+instance Show HId_t where
+    showsPrec p (HId_t x) = showParen (p>10)
+        ( showString "HId_t 0x"
+        . showString
+            [ intToDigit (fromIntegral digit)
+            | place <- [finiteBitSize x - 4, finiteBitSize x - 8 .. 0]
+            , let mask = 0xf `shiftL` place
+            , let digit = ((x .&. mask) `shiftR` place) .&. 0xf
+            ]
+        )
+#if !MIN_VERSION_base(4,7,0)
+      where
+        finiteBitSize = bitSize
+#endif
+
+h5_SIZEOF_HID_T :: CSize
+h5_SIZEOF_HID_T = #const H5_SIZEOF_HID_T
+
+-- |An invalid object ID. This is also negative for error return.
+#newtype_const hid_t, H5I_INVALID_HID
+
+-- |Function for freeing objects. This function will be called with an object
+-- ID type number and a pointer to the object. The function should free the
+-- object and return non-negative to indicate that the object
+-- can be removed from the ID type. If the function returns negative
+-- (failure) then the object will remain in the ID type.
+type H5I_free_t        a = FunPtr (In a -> IO HErr_t)
+
+-- |Type of the function to compare objects & keys
+type H5I_search_func_t a = FunPtr (In a -> HId_t -> In a -> IO CInt)
+
+-- |Registers an 'object' in a 'type' and returns an ID for it.
+-- This routine does _not_ check for unique-ness of the objects,
+-- if you register an object twice, you will get two different
+-- IDs for it.  This routine does make certain that each ID in a
+-- type is unique.  IDs are created by getting a unique number
+-- for the type the ID is in and incorporating the type into
+-- the ID which is returned to the user.
+--
+-- Return:	Success:	New object id.
+--  	Failure:	Negative
+--
+-- > hid_t H5Iregister(H5I_type_t type, const void *object);
+#ccall H5Iregister , <H5I_type_t> -> In a -> IO <hid_t>
+
+-- |Find an object pointer for the specified ID, verifying that
+-- it is in a particular type.
+--
+-- On success, returns a non-null object pointer associated with the
+-- specified ID.
+-- On failure, returns NULL.
+--
+-- > void *H5Iobject_verify(hid_t id, H5I_type_t id_type);
+#ccall H5Iobject_verify , <hid_t> -> <H5I_type_t> -> IO (Ptr a)
+
+-- |Removes the specified ID from its type, first checking that the
+-- type of the ID and the type type are the same.
+--
+-- On success, returns a pointer to the object that was removed, the
+-- same pointer which would have been found by calling 'h5i_object'.
+-- On failure, returns NULL.
+--
+-- > void *H5Iremove_verify(hid_t id, H5I_type_t id_type);
+#ccall H5Iremove_verify , <hid_t> -> <H5I_type_t> -> IO (Ptr a)
+
+-- |Retrieves the number of references outstanding for a type.
+-- Returns negative on failure.
+--
+-- > H5I_type_t H5Iget_type(hid_t id);
+#ccall H5Iget_type , <hid_t> -> IO <H5I_type_t>
+
+-- |Obtains the file ID given an object ID.  User has to close this ID.
+-- Returns a negative value on failure.
+--
+-- > hid_t H5Iget_file_id(hid_t id);
+#ccall H5Iget_file_id , <hid_t> -> IO <hid_t>
+
+-- |Gets a name of an object from its ID.
+--
+-- If 'name' is non-NULL then write up to 'size' bytes into that
+-- buffer and always return the length of the entry name.
+-- Otherwise 'size' is ignored and the function does not store the name,
+-- just returning the number of characters required to store the name.
+-- If an error occurs then the buffer pointed to by 'name' (NULL or non-NULL)
+-- is unchanged and the function returns a negative value.
+-- If a zero is returned for the name's length, then there is no name
+-- associated with the ID.
+--
+-- > ssize_t H5Iget_name(hid_t id, char *name/*out*/, size_t size);
+#ccall H5Iget_name, <hid_t> -> OutArray CChar -> <size_t> -> IO <ssize_t>
+
+-- |Increments the number of references outstanding for an ID.
+--
+-- On success, returns the new reference count.  On failure, returns
+-- a negative value.
+--
+-- > int H5Iinc_ref(hid_t id);
+#ccall H5Iinc_ref, <hid_t> -> IO CInt
+
+-- |Decrements the number of references outstanding for an ID.
+-- If the reference count for an ID reaches zero, the object
+-- will be closed.
+--
+-- On success, returns the new reference count.  On failure, returns
+-- a negative value.
+--
+-- > int H5Idec_ref(hid_t id);
+#ccall H5Idec_ref, <hid_t> -> IO CInt
+
+-- |Retrieves the number of references outstanding for an ID.
+-- Returns a negative value on failure.
+--
+-- > int H5Iget_ref(hid_t id);
+#ccall H5Iget_ref, <hid_t> -> IO CInt
+
+-- |Creates a new type of ID's to give out.  A specific number
+-- ('reserved') of type entries may be reserved to enable \"constant\"
+-- values to be handed out which are valid IDs in the type, but which
+-- do not map to any data structures and are not allocated dynamically
+-- later.  'hash_size' is the minimum hash table size to use for the
+-- type.  'free_func' is called with an object pointer when the object
+-- is removed from the type.
+--
+-- On success, returns the type ID of the new type.
+-- On failure, returns 'h5i_BADID'.
+--
+-- > H5I_type_t H5Iregister_type(size_t hash_size, unsigned reserved, H5I_free_t free_func);
+#ccall H5Iregister_type, <size_t> -> CUInt -> <H5I_free_t> a -> IO <H5I_type_t>
+
+-- |Removes all objects from the type, calling the free
+-- function for each object regardless of the reference count.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Iclear_type(H5I_type_t type, hbool_t force);
+#ccall H5Iclear_type, <H5I_type_t> -> <hbool_t> -> IO <herr_t>
+
+-- |Destroys a type along with all atoms in that type
+-- regardless of their reference counts. Destroying IDs
+-- involves calling the free-func for each ID's object and
+-- then adding the ID struct to the ID free list.
+--
+-- Returns zero on success, negative on failure.
+--
+-- herr_t H5Idestroy_type(H5I_type_t type);
+#ccall H5Idestroy_type, <H5I_type_t> -> IO <herr_t>
+
+-- |Increments the number of references outstanding for an ID type.
+--
+-- On success, returns the new reference count.  On failure, returns
+-- a negative value.
+--
+-- > int H5Iinc_type_ref(H5I_type_t type);
+#ccall H5Iinc_type_ref, <H5I_type_t> -> IO CInt
+
+-- |Decrements the reference count on an entire type of IDs.
+-- If the type reference count becomes zero then the type is
+-- destroyed along with all atoms in that type regardless of
+-- their reference counts.  Destroying IDs involves calling
+-- the free-func for each ID's object and then adding the ID
+-- struct to the ID free list.
+--
+-- Returns the number of references to the type on success; a
+-- return value of 0 means that the type will have to be
+-- re-initialized before it can be used again (and should probably
+-- be set to H5I_UNINIT).
+--
+-- > int H5Idec_type_ref(H5I_type_t type);
+#ccall H5Idec_type_ref, <H5I_type_t> -> IO CInt
+
+-- |Retrieves the number of references outstanding for a type.
+-- Returns a negative value on failure.
+--
+-- > int H5Iget_type_ref(H5I_type_t type);
+#ccall H5Iget_type_ref, <H5I_type_t> -> IO CInt
+
+-- |Apply function 'func' to each member of type 'type' and return a
+-- pointer to the first object for which 'func' returns non-zero.
+-- The 'func' should take a pointer to the object and the 'key' as
+-- arguments and return non-zero to terminate the search (zero
+-- to continue).
+--
+-- Limitation:  Currently there is no way to start searching from where a
+-- previous search left off.
+--
+-- Returns the first object in the type for which 'func' returns
+-- non-zero.  Returns NULL if 'func' returned zero for every object in
+-- the type.
+--
+-- > void *H5Isearch(H5I_type_t type, H5I_search_func_t func, void *key);
+#ccall H5Isearch, <H5I_type_t> -> <H5I_search_func_t> a -> In a -> IO (Ptr a)
+
+-- |Returns the number of members in a type.  The public interface
+-- throws an error if the supplied type does not exist.  This is
+-- different than the private interface, which will just return 0.
+--
+-- Returns zero on success, negative on failure.
+--
+-- > herr_t H5Inmembers(H5I_type_t type, hsize_t *num_members);
+#ccall H5Inmembers, <H5I_type_t> -> Out <hsize_t> -> IO <herr_t>
+
+-- |Check whether the given type is currently registered with the library.
+--
+-- > htri_t H5Itype_exists(H5I_type_t type);
+#ccall H5Itype_exists, <H5I_type_t> -> IO <htri_t>
+
+#if H5_VERSION_GE(1,8,3)
+-- |Check if the given id is valid.  An id is valid if it is in
+-- use and has an application reference count of at least 1.
+--
+-- > htri_t H5Iis_valid(hid_t id);
+#ccall H5Iis_valid, <hid_t> -> IO <htri_t>
+#endif
diff --git a/src/Bindings/HDF5/Raw/H5L.hsc b/src/Bindings/HDF5/Raw/H5L.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/H5L.hsc
@@ -0,0 +1,482 @@
+#include <bindings.h>
+#include <H5Lpublic.h>
+
+module Bindings.HDF5.Raw.H5L where
+
+import Data.Int
+import Data.Word
+import Foreign.C.String
+import Foreign.C.Types
+import Foreign.Marshal.Alloc
+import Foreign.Ptr
+import Foreign.Storable
+
+import Bindings.HDF5.Raw.H5
+import Bindings.HDF5.Raw.H5I
+import Bindings.HDF5.Raw.H5T
+import Foreign.Ptr.Conventions
+
+-- |Maximum length of a link's name
+-- (encoded in a 32-bit unsigned integer)
+h5l_MAX_LINK_NAME_LEN :: Word32
+h5l_MAX_LINK_NAME_LEN = #const H5L_MAX_LINK_NAME_LEN
+
+-- |Macro to indicate operation occurs on same location
+#newtype_const hid_t, H5L_SAME_LOC
+
+-- |Current version of the H5L_class_t struct
+#num H5L_LINK_CLASS_T_VERS
+
+-- |Link class types.
+--
+-- Values less than 64 are reserved for the HDF5 library's internal use.
+-- Values 64 to 255 are for "user-defined" link class types; these types are
+-- defined by HDF5 but their behavior can be overridden by users.
+-- Users who want to create new classes of links should contact the HDF5
+-- development team at <mailto:hdfhelp@ncsa.uiuc.edu>.
+--
+-- These values can never change because they appear in HDF5 files.
+#newtype H5L_type_t, Eq, Ord, Read
+
+-- |Invalid link type id
+#newtype_const H5L_type_t, H5L_TYPE_ERROR
+
+-- |Hard link id
+#newtype_const H5L_type_t, H5L_TYPE_HARD
+
+-- |Soft link id
+#newtype_const H5L_type_t, H5L_TYPE_SOFT
+
+-- |External link id
+#newtype_const H5L_type_t, H5L_TYPE_EXTERNAL
+
+-- |Maximum link type id
+#newtype_const H5L_type_t, H5L_TYPE_MAX
+
+-- |Maximum value link value for \"built-in\" link types
+#newtype_const H5L_type_t, H5L_TYPE_BUILTIN_MAX
+
+-- |Link ids at or above this value are \"user-defined\" link types.
+#newtype_const H5L_type_t, H5L_TYPE_UD_MIN
+
+-- |Information struct for link (for 'h5l_get_info' / 'h5l_get_info_by_idx')
+#starttype H5L_info_t
+
+-- |Type of link
+#field type,                <H5L_type_t>
+
+-- |Indicate if creation order is valid
+#field corder_valid,        <hbool_t>
+
+-- |Creation order
+#field corder,              Int64
+
+-- |Character set of link name
+#field cset,                <H5T_cset_t>
+
+-- |Address hard link points to
+#union_field u.address,     <haddr_t>
+
+-- |Size of a soft link or UD link value
+#union_field u.val_size,    <size_t>
+#stoptype
+
+
+-- /* The H5L_class_t struct can be used to override the behavior of a
+--  * "user-defined" link class. Users should populate the struct with callback
+--  * functions defined below.
+--  */
+
+-- * Callback prototypes for user-defined links
+
+-- |Link creation callback
+--
+-- > typedef herr_t (*H5L_create_func_t)(const char *link_name, hid_t loc_group,
+-- >     const void *lnkdata, size_t lnkdata_size, hid_t lcpl_id);
+type H5L_create_func_t a = FunPtr (CString -> HId_t -> Ptr a -> CSize -> HId_t -> IO HErr_t)
+
+-- |Callback for when the link is moved
+--
+-- > typedef herr_t (*H5L_move_func_t)(const char *new_name, hid_t new_loc,
+-- >     const void *lnkdata, size_t lnkdata_size);
+type H5L_move_func_t a = FunPtr (CString -> HId_t -> Ptr a -> CSize -> IO HErr_t)
+
+-- |Callback for when the link is copied
+--
+-- > typedef herr_t (*H5L_copy_func_t)(const char *new_name, hid_t new_loc,
+-- >     const void *lnkdata, size_t lnkdata_size);
+type H5L_copy_func_t a = FunPtr (CString -> HId_t -> Ptr a -> CSize -> IO HErr_t)
+
+-- |Callback during link traversal
+--
+-- > typedef herr_t (*H5L_traverse_func_t)(const char *link_name, hid_t cur_group,
+-- >     const void *lnkdata, size_t lnkdata_size, hid_t lapl_id);
+type H5L_traverse_func_t a = FunPtr (CString -> HId_t -> Ptr a -> CSize -> HId_t -> IO HErr_t)
+
+-- |Callback for when the link is deleted
+--
+-- > typedef herr_t (*H5L_delete_func_t)(const char *link_name, hid_t file,
+-- >     const void *lnkdata, size_t lnkdata_size);
+type H5L_delete_func_t a = FunPtr (CString -> HId_t -> Ptr a -> CSize -> IO HErr_t)
+
+-- |Callback for querying the link
+--
+-- Returns the size of the buffer needed
+--
+-- > typedef ssize_t (*H5L_query_func_t)(const char *link_name, const void *lnkdata,
+-- >     size_t lnkdata_size, void *buf /*out*/, size_t buf_size);
+type H5L_query_func_t a b = FunPtr (CString -> Ptr a -> CSize -> Out b -> CSize -> IO CSSize)
+
+-- |User-defined link types
+#starttype H5L_class_t
+
+-- |Version number of this struct
+#field version,     CInt
+
+-- |Link type ID
+#field id,          <H5L_type_t>
+
+-- |Comment for debugging
+#field comment,     CString
+
+-- |Callback during link creation
+#field create_func, H5L_create_func_t ()
+
+-- |Callback after moving link
+#field move_func,   H5L_move_func_t ()
+
+-- |Callback after copying link
+#field copy_func,   H5L_copy_func_t ()
+
+-- |Callback during link traversal
+#field trav_func,   H5L_traverse_func_t ()
+
+-- |Callback for link deletion
+#field del_func,    H5L_delete_func_t ()
+
+-- |Callback for queries
+#field query_func,  H5L_query_func_t () ()
+#stoptype
+
+
+-- |Prototype for 'h5l_iterate' / 'h5l_iterate_by_name' operator
+--
+-- > typedef herr_t (*H5L_iterate_t)(hid_t group, const char *name, const H5L_info_t *info,
+-- >     void *op_data);
+type H5L_iterate_t a = FunPtr (HId_t -> CString -> In H5L_info_t -> InOut a -> IO HErr_t)
+
+-- |Callback for external link traversal
+--
+-- > typedef herr_t (*H5L_elink_traverse_t)(const char *parent_file_name,
+-- >     const char *parent_group_name, const char *child_file_name,
+-- >     const char *child_object_name, unsigned *acc_flags, hid_t fapl_id,
+-- >     void *op_data);
+type H5L_elink_traverse_t a = FunPtr (CString
+    -> CString -> CString
+    -> CString -> Ptr CUInt -> HId_t
+    -> Ptr a -> IO HErr_t)
+
+-- |Renames an object within an HDF5 file and moves it to a new
+-- group.  The original name 'src' is unlinked from the group graph
+-- and then inserted with the new name 'dst' (which can specify a
+-- new path for the object) as an atomic operation. The names
+-- are interpreted relative to 'src_loc_id' and
+-- 'dst_loc_id', which are either file IDs or group ID.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Lmove(hid_t src_loc, const char *src_name, hid_t dst_loc,
+-- >     const char *dst_name, hid_t lcpl_id, hid_t lapl_id);
+#ccall H5Lmove, <hid_t> -> CString -> <hid_t> -> CString -> <hid_t> -> <hid_t> -> IO <herr_t>
+
+-- |Creates an identical copy of a link with the same creation
+-- time and target.  The new link can have a different name
+-- and be in a different location than the original.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Lcopy(hid_t src_loc, const char *src_name, hid_t dst_loc,
+-- >     const char *dst_name, hid_t lcpl_id, hid_t lapl_id);
+#ccall H5Lcopy, <hid_t> -> CString -> <hid_t> -> CString -> <hid_t> -> <hid_t> -> IO <herr_t>
+
+-- |Creates a hard link from 'new_name' to 'cur_name'.
+--
+-- 'cur_name' must name an existing object.  'cur_name' and
+-- 'new_name' are interpreted relative to 'cur_loc_id' and
+-- 'new_loc_id', which are either file IDs or group IDs.
+--
+-- Returns non-negative on success, negative on failure
+--
+-- > herr_t H5Lcreate_hard(hid_t cur_loc, const char *cur_name,
+-- >     hid_t dst_loc, const char *dst_name, hid_t lcpl_id, hid_t lapl_id);
+#ccall H5Lcreate_hard, <hid_t> -> CString -> <hid_t> -> CString -> <hid_t> -> <hid_t> -> IO <herr_t>
+
+-- |Creates a soft link from 'link_name' to 'link_target'.
+--
+-- 'link_target' can be anything and is interpreted at lookup
+-- time relative to the group which contains the final component
+-- of 'link_name'.  For instance, if 'link_target' is \"./foo\" and
+-- 'link_name' is \"./x/y/bar\" and a request is made for \"./x/y/bar\"
+-- then the actual object looked up is \"./x/y/./foo\".
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Lcreate_soft(const char *link_target, hid_t link_loc_id,
+-- >     const char *link_name, hid_t lcpl_id, hid_t lapl_id);
+#ccall H5Lcreate_soft, CString -> <hid_t> -> CString -> <hid_t> -> <hid_t> -> IO <herr_t>
+
+-- |Removes the specified 'name' from the group graph and
+-- decrements the link count for the object to which 'name'
+-- points.  If the link count reaches zero then all file-space
+-- associated with the object will be reclaimed (but if the
+-- object is open, then the reclamation of the file space is
+-- delayed until all handles to the object are closed).
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Ldelete(hid_t loc_id, const char *name, hid_t lapl_id);
+#ccall H5Ldelete, <hid_t> -> CString -> <hid_t> -> IO <herr_t>
+
+-- |Removes the specified link from the group graph and
+-- decrements the link count for the object to which it
+-- points, according to the order within an index.
+--
+-- If the link count reaches zero then all file-space
+-- associated with the object will be reclaimed (but if the
+-- object is open, then the reclamation of the file space is
+-- delayed until all handles to the object are closed).
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Ldelete_by_idx(hid_t loc_id, const char *group_name,
+-- >     H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t lapl_id);
+#ccall H5Ldelete_by_idx, <hid_t> -> CString -> <H5_index_t> -> <H5_iter_order_t> -> <hsize_t> -> <hid_t> -> IO <herr_t>
+
+-- |Returns the link value of a link whose name is 'name'.  For
+-- symbolic links, this is the path to which the link points,
+-- including the null terminator.  For user-defined links, it
+-- is the link buffer.
+--
+-- At most 'size' bytes are copied to the 'buf' result buffer.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Lget_val(hid_t loc_id, const char *name, void *buf/*out*/,
+-- >     size_t size, hid_t lapl_id);
+#ccall H5Lget_val, <hid_t> -> CString -> OutArray a -> <size_t> -> <hid_t> -> IO <herr_t>
+
+-- |Returns the link value of a link, according to the order of
+-- an index.  For symbolic links, this is the path to which the
+-- link points, including the null terminator.  For user-defined
+-- links, it is the link buffer.
+--
+-- At most 'size' bytes are copied to the 'buf' result buffer.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Lget_val_by_idx(hid_t loc_id, const char *group_name,
+-- >     H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
+-- >     void *buf/*out*/, size_t size, hid_t lapl_id);
+#ccall H5Lget_val_by_idx, <hid_t> -> CString -> <H5_index_t> -> <H5_iter_order_t> -> <hsize_t> -> OutArray a -> CSize -> <hid_t> -> IO <herr_t>
+
+-- |Checks if a link of a given name exists in a group
+--
+-- > htri_t H5Lexists(hid_t loc_id, const char *name, hid_t lapl_id);
+#ccall H5Lexists, <hid_t> -> CString -> <hid_t> -> IO <htri_t>
+
+-- |Gets metadata for a link.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Lget_info(hid_t loc_id, const char *name,
+-- >     H5L_info_t *linfo /*out*/, hid_t lapl_id);
+#ccall H5Lget_info, <hid_t> -> CString -> Out <H5L_info_t> -> <hid_t> -> IO <herr_t>
+
+-- |Gets metadata for a link, according to the order within an index.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Lget_info_by_idx(hid_t loc_id, const char *group_name,
+-- >     H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
+-- >     H5L_info_t *linfo /*out*/, hid_t lapl_id);
+#ccall H5Lget_info_by_idx, <hid_t> -> CString -> <H5_index_t> -> <H5_iter_order_t> -> <hsize_t> -> Out <H5L_info_t> -> <hid_t> -> IO <herr_t>
+
+-- |Gets name for a link, according to the order within an index.
+--
+-- Same pattern of behavior as 'h5i_get_name'.
+--
+-- On success, returns non-negative length of name, with information
+-- in 'name' buffer
+-- On failure,returns a negative value.
+--
+-- > ssize_t H5Lget_name_by_idx(hid_t loc_id, const char *group_name,
+-- >     H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
+-- >     char *name /*out*/, size_t size, hid_t lapl_id);
+#ccall H5Lget_name_by_idx, <hid_t> -> CString -> <H5_index_t> -> <H5_iter_order_t> -> <hsize_t> -> OutArray CChar -> <ssize_t> -> <hid_t> -> IO <ssize_t>
+
+-- |Iterates over links in a group, with user callback routine,
+-- according to the order within an index.
+--
+-- Same pattern of behavior as 'h5g_iterate'.
+--
+-- Returns the return value of the first operator that returns non-zero,
+-- or zero if all members were processed with no operator returning non-zero.
+--
+-- Returns negative if something goes wrong within the library, or the
+-- negative value returned by one of the operators.
+--
+-- > herr_t H5Literate(hid_t grp_id, H5_index_t idx_type,
+-- >     H5_iter_order_t order, hsize_t *idx, H5L_iterate_t op, void *op_data);
+#ccall H5Literate, <hid_t> -> <H5_index_t> -> <H5_iter_order_t> -> InOut <hsize_t> -> H5L_iterate_t a -> InOut a -> IO <herr_t>
+
+-- |Iterates over links in a group, with user callback routine,
+-- according to the order within an index.
+--
+-- Same pattern of behavior as 'h5g_iterate'.
+--
+-- Returns the return value of the first operator that returns non-zero,
+-- or zero if all members were processed with no operator returning non-zero.
+--
+-- Returns negative if something goes wrong within the library, or the
+-- negative value returned by one of the operators.
+--
+-- > herr_t H5Literate_by_name(hid_t loc_id, const char *group_name,
+-- >     H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx,
+-- >     H5L_iterate_t op, void *op_data, hid_t lapl_id);
+#ccall H5Literate_by_name, <hid_t> -> CString -> <H5_index_t> -> <H5_iter_order_t> -> InOut <hsize_t> -> H5L_iterate_t a -> InOut a -> <hid_t> -> IO <herr_t>
+
+-- |Recursively visit all the links in a group and all
+-- the groups that are linked to from that group.  Links within
+-- each group are visited according to the order within the
+-- specified index (unless the specified index does not exist for
+-- a particular group, then the \"name\" index is used).
+--
+-- NOTE: Each _link_ reachable from the initial group will only be
+-- visited once.  However, because an object may be reached from
+-- more than one link, the visitation may call the application's
+-- callback with more than one link that points to a particular
+-- _object_.
+--
+-- Returns the return value of the first operator that
+-- returns non-zero, or zero if all members were
+-- processed with no operator returning non-zero.
+--
+-- Returns negative if something goes wrong within the
+-- library, or the negative value returned by one
+-- of the operators.
+--
+-- > herr_t H5Lvisit(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order,
+-- >     H5L_iterate_t op, void *op_data);
+#ccall H5Lvisit, <hid_t> -> <H5_index_t> -> <H5_iter_order_t> -> H5L_iterate_t a -> InOut a -> IO <herr_t>
+
+-- |Recursively visit all the links in a group and all
+-- the groups that are linked to from that group.  Links within
+-- each group are visited according to the order within the
+-- specified index (unless the specified index does not exist for
+-- a particular group, then the \"name\" index is used).
+--
+-- NOTE: Each _link_ reachable from the initial group will only be
+-- visited once.  However, because an object may be reached from
+-- more than one link, the visitation may call the application's
+-- callback with more than one link that points to a particular
+-- _object_.
+--
+-- Returns the return value of the first operator that
+-- returns non-zero, or zero if all members were
+-- processed with no operator returning non-zero.
+--
+-- Returns negative if something goes wrong within the
+-- library, or the negative value returned by one
+-- of the operators.
+--
+-- > herr_t H5Lvisit_by_name(hid_t loc_id, const char *group_name,
+-- >     H5_index_t idx_type, H5_iter_order_t order, H5L_iterate_t op,
+-- >     void *op_data, hid_t lapl_id);
+#ccall H5Lvisit_by_name, <hid_t> -> CString -> <H5_index_t> -> <H5_iter_order_t> -> H5L_iterate_t a -> InOut a -> <hid_t> -> IO <herr_t>
+
+-- |Creates a user-defined link of type 'link_type' named 'link_name'
+-- with user-specified data 'udata'.
+--
+-- The format of the information pointed to by 'udata' is
+-- defined by the user. 'udata_size' holds the size of this buffer.
+--
+-- 'link_name' is interpreted relative to 'link_loc_id'.
+--
+-- The property list specified by 'lcpl_id' holds properties used
+-- to create the link.
+--
+-- The link class of the new link must already be registered
+-- with the library.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Lcreate_ud(hid_t link_loc_id, const char *link_name,
+-- >     H5L_type_t link_type, const void *udata, size_t udata_size, hid_t lcpl_id,
+-- >     hid_t lapl_id);
+#ccall H5Lcreate_ud, <hid_t> -> CString -> <H5L_type_t> -> In a -> <size_t> -> <hid_t> -> <hid_t> -> IO <herr_t>
+
+-- |Registers a class of user-defined links, or changes the
+-- behavior of an existing class.
+--
+-- The link class passed in will override any existing link
+-- class for the specified link class ID. It must at least
+-- include a 'H5L_class_t' version (which should be
+-- 'h5l_LINK_CLASS_T_VERS'), a link class ID, and a traversal
+-- function.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Lregister(const H5L_class_t *cls);
+#ccall H5Lregister, In <H5L_class_t> -> IO <herr_t>
+
+-- |Unregisters a class of user-defined links, preventing them
+-- from being traversed, queried, moved, etc.
+--
+-- A link class can be re-registered using 'h5l_register'.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Lunregister(H5L_type_t id);
+#ccall H5Lunregister, <H5L_type_t> -> IO <herr_t>
+
+-- |Tests whether a user-defined link class has been registered
+-- or not.
+--
+-- > htri_t H5Lis_registered(H5L_type_t id);
+#ccall H5Lis_registered, <H5L_type_t> -> IO <htri_t>
+
+-- |Given a buffer holding the \"link value\" from an external link,
+-- gets pointers to the information within the link value buffer.
+--
+-- External link link values contain some flags and
+-- two NULL-terminated strings, one after the other.
+--
+-- The 'flags' value will be filled in and 'filename' and
+-- 'obj_path' will be set to pointers within 'ext_linkval' (unless
+-- any of these values is NULL).
+--
+-- Using this function on strings that aren't external link
+-- 'udata' buffers can result in segmentation faults.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Lunpack_elink_val(const void *ext_linkval/*in*/, size_t link_size,
+-- >    unsigned *flags, const char **filename/*out*/, const char **obj_path /*out*/);
+#ccall H5Lunpack_elink_val, InArray a -> <size_t> -> Out CUInt -> Out (Ptr CChar) -> Out (Ptr CChar) -> IO <herr_t>
+
+-- |Creates an external link from 'link_name' to 'obj_name'.
+--
+-- External links are links to objects in other HDF5 files.  They
+-- are allowed to \"dangle\" like soft links internal to a file.
+-- 'file_name' is the name of the file that 'obj_name' is is contained
+-- within.  If 'obj_name' is given as a relative path name, the
+-- path will be relative to the root group of 'file_name'.
+-- 'link_name' is interpreted relative to 'link_loc_id', which is
+-- either a file ID or a group ID.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Lcreate_external(const char *file_name, const char *obj_name,
+-- >     hid_t link_loc_id, const char *link_name, hid_t lcpl_id, hid_t lapl_id);
+#ccall H5Lcreate_external, CString -> CString -> <hid_t> -> CString -> <hid_t> -> <hid_t> -> IO <herr_t>
+
diff --git a/src/Bindings/HDF5/Raw/H5MM.hsc b/src/Bindings/HDF5/Raw/H5MM.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/H5MM.hsc
@@ -0,0 +1,10 @@
+#include <bindings.h>
+#include <H5MMpublic.h>
+
+module Bindings.HDF5.Raw.H5MM where
+
+import Foreign.C.Types
+import Foreign.Ptr
+
+type H5MM_allocate_t info mem = FunPtr (CSize -> Ptr info -> IO (Ptr mem))
+type H5MM_free_t     info mem = FunPtr (Ptr mem -> Ptr info -> IO ())
diff --git a/src/Bindings/HDF5/Raw/H5O.hsc b/src/Bindings/HDF5/Raw/H5O.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/H5O.hsc
@@ -0,0 +1,641 @@
+#include <bindings.h>
+#include <H5Apublic.h>
+
+module Bindings.HDF5.Raw.H5O where
+
+import Data.Int
+import Data.Word
+import Foreign.C.String
+import Foreign.C.Types
+import Foreign.Ptr
+import Foreign.Storable
+
+import Bindings.HDF5.Raw.H5     -- Generic Functions
+import Bindings.HDF5.Raw.H5I    -- IDs
+import Foreign.Ptr.Conventions
+
+-- * Constants
+
+-- ** Flags for object copy ('h5o_copy')
+
+-- |Copy only immediate members
+#num H5O_COPY_SHALLOW_HIERARCHY_FLAG
+
+-- |Expand soft links into new objects
+#num H5O_COPY_EXPAND_SOFT_LINK_FLAG
+
+-- |Expand external links into new objects
+#num H5O_COPY_EXPAND_EXT_LINK_FLAG
+
+-- |Copy objects that are pointed by references
+#num H5O_COPY_EXPAND_REFERENCE_FLAG
+
+-- |Copy object without copying attributes
+#num H5O_COPY_WITHOUT_ATTR_FLAG
+
+-- |Copy NULL messages (empty space)
+#num H5O_COPY_PRESERVE_NULL_FLAG
+
+#if H5_VERSION_GE(1,8,9)
+
+-- |Merge committed datatypes in dest file
+#num H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG
+
+#endif
+
+-- |All object copying flags (for internal checking)
+#num H5O_COPY_ALL
+
+-- ** Flags for shared message indexes
+-- Pass these flags in using the mesg_type_flags parameter in
+-- H5P_set_shared_mesg_index.
+
+
+-- | No shared messages
+#num H5O_SHMESG_NONE_FLAG
+
+-- | Simple Dataspace Message
+#num H5O_SHMESG_SDSPACE_FLAG
+
+-- | Datatype Message
+#num H5O_SHMESG_DTYPE_FLAG
+
+-- | Fill Value Message
+#num H5O_SHMESG_FILL_FLAG
+
+-- | Filter pipeline message
+#num H5O_SHMESG_PLINE_FLAG
+
+-- | Attribute Message
+#num H5O_SHMESG_ATTR_FLAG
+
+#num H5O_SHMESG_ALL_FLAG
+
+-- ** Object header status flag definitions
+
+-- |2-bit field indicating # of bytes to store the size of chunk 0's data
+#num H5O_HDR_CHUNK0_SIZE
+
+-- |Attribute creation order is tracked
+#num H5O_HDR_ATTR_CRT_ORDER_TRACKED
+
+-- |Attribute creation order has index
+#num H5O_HDR_ATTR_CRT_ORDER_INDEXED
+
+-- |Non-default attribute storage phase change values stored
+#num H5O_HDR_ATTR_STORE_PHASE_CHANGE
+
+-- |Store access, modification, change & birth times for object
+#num H5O_HDR_STORE_TIMES
+
+#num H5O_HDR_ALL_FLAGS
+
+-- ** Maximum shared message values
+
+#num H5O_SHMESG_MAX_NINDEXES
+#num H5O_SHMESG_MAX_LIST_SIZE
+
+-- * Types
+
+-- |Types of objects in file
+#newtype H5O_type_t, Eq
+
+-- |Unknown object type
+#newtype_const H5O_type_t, H5O_TYPE_UNKNOWN
+
+-- |Object is a group
+#newtype_const H5O_type_t, H5O_TYPE_GROUP
+
+-- |Object is a dataset
+#newtype_const H5O_type_t, H5O_TYPE_DATASET
+
+-- |Object is a named data type
+#newtype_const H5O_type_t, H5O_TYPE_NAMED_DATATYPE
+
+-- |Number of different object types
+#num H5O_TYPE_NTYPES
+
+#if H5_VERSION_GE(1,8,4)
+
+-- |Information struct for object header metadata
+-- (for 'h5o_get_info'/ 'h5o_get_info_by_name' / 'h5o_get_info_by_idx')
+#starttype H5O_hdr_info_t
+
+-- |Version number of header format in file
+#field version,         CUInt
+
+-- |Number of object header messages
+#field nmesgs,          CUInt
+
+-- |Number of object header chunks
+#field nchunks,         CUInt
+
+-- |Object header status flags
+#field flags,           CUInt
+
+-- |Total space for storing object header in file
+#field space.total,     <hsize_t>
+
+-- |Space within header for object header metadata information
+#field space.meta,      <hsize_t>
+
+-- |Space within header for actual message information
+#field space.mesg,      <hsize_t>
+
+-- |Free space within object header
+#field space.free,      <hsize_t>
+
+-- |Flags to indicate presence of message type in header
+#field mesg.present,    Word64
+
+-- |Flags to indicate message type is shared in header
+#field mesg.shared,     Word64
+
+#stoptype
+
+#endif
+
+-- |Information struct for object
+-- (for 'h5o_get_info'/ 'h5o_get_info_by_name' / 'h5o_get_info_by_idx')
+#starttype H5O_info_t
+
+-- |File number that object is located in
+#field fileno,          CULong
+
+-- |Object address in file
+#field addr,            <haddr_t>
+
+-- |Basic object type (group, dataset, etc.)
+#field type,            <H5O_type_t>
+
+-- |Reference count of object
+#field rc,              CUInt
+
+-- |Access time
+#field atime,           <time_t>
+
+-- |Modification time
+#field mtime,           <time_t>
+
+-- |Change time
+#field ctime,           <time_t>
+
+-- |Birth time
+#field btime,           <time_t>
+
+-- |# of attributes attached to object
+#field num_attrs,       <hsize_t>
+
+#if H5_VERSION_GE(1,8,4)
+
+-- |Object header information
+#field hdr,             <H5O_hdr_info_t>
+
+#else
+
+-- |Version number of header format in file
+#field hdr.version,      CUInt
+
+-- |Number of object header messages
+#field hdr.nmesgs,       CUInt
+
+-- |Number of object header chunks
+#field hdr.nchunks,      CUInt
+
+-- |Object header status flags
+#field hdr.flags,        CUInt
+
+-- |Total space for storing object header in file
+#field hdr.space.total,  <hsize_t>
+
+-- |Space within header for object header metadata information
+#field hdr.space.meta,   <hsize_t>
+
+-- |Space within header for actual message information
+#field hdr.space.mesg,   <hsize_t>
+
+-- |Free space within object header
+#field hdr.space.free,   <hsize_t>
+
+-- |Flags to indicate presence of message type in header
+#field hdr.mesg.present, Word64
+
+-- |Flags to indicate message type is shared in header
+#field hdr.mesg.shared,  Word64
+
+#endif
+
+-- |v1/v2 B-tree & local/fractal heap for groups, B-tree for chunked datasets
+#field meta_size.obj,   <H5_ih_info_t>
+
+-- |v2 B-tree & heap for attributes
+#field meta_size.attr,  <H5_ih_info_t>
+
+#stoptype
+
+
+-- |Typedef for message creation indexes
+#newtype H5O_msg_crt_idx_t, Eq, Ord, Read
+
+-- |Prototype for 'h5o_visit' / 'h5o_visit_by_name' operator
+type H5O_iterate_t a = FunPtr (HId_t -> CString -> In H5O_info_t -> InOut a -> IO HErr_t)
+
+#newtype H5O_mcdt_search_ret_t
+
+-- |Abort H5Ocopy
+#newtype_const H5O_mcdt_search_ret_t, H5O_MCDT_SEARCH_ERROR
+
+-- |Continue the global search of all committed datatypes in the destination file
+#newtype_const H5O_mcdt_search_ret_t, H5O_MCDT_SEARCH_CONT
+
+-- |Stop the search, but continue copying.  The committed datatype will be copied but not merged.
+#newtype_const H5O_mcdt_search_ret_t, H5O_MCDT_SEARCH_STOP
+
+-- |Callback to invoke when completing the search for a matching committed datatype from the committed dtype list
+--
+-- > typedef H5O_mcdt_search_ret_t (*H5O_mcdt_search_cb_t)(void *op_data);
+type H5O_mcdt_search_cb_t a = FunPtr (InOut a -> IO H5O_mcdt_search_ret_t)
+
+-- * Functions
+
+-- |Opens an object within an HDF5 file.
+--
+-- This function opens an object in the same way that 'h5g_open2',
+-- 'h5t_open2', and 'h5d_open2' do. However, 'h5o_open' doesn't require
+-- the type of object to be known beforehand. This can be
+-- useful in user-defined links, for instance, when only a
+-- path is known.
+--
+-- The opened object should be closed again with 'h5o_close'
+-- or 'h5g_close', 'h5t_close', or 'h5d_close'.
+--
+-- On success, returns an open object identifier
+-- On failure, returns a negative value.
+--
+-- > hid_t H5Oopen(hid_t loc_id, const char *name, hid_t lapl_id);
+#ccall H5Oopen, <hid_t> -> CString -> <hid_t> -> IO <hid_t>
+
+-- |Warning! This function is EXTREMELY DANGEROUS!
+--
+-- Improper use can lead to FILE CORRUPTION, INACCESSIBLE DATA,
+-- and other VERY BAD THINGS!
+--
+-- This function opens an object using its address within the
+-- HDF5 file, similar to an HDF5 hard link. The open object
+-- is identical to an object opened with 'h5o_open' and should
+-- be closed with 'h5o_close' or a type-specific closing
+-- function (such as 'h5g_close').
+--
+-- This function is very dangerous if called on an invalid
+-- address. For this reason, 'h5o_incr_refcount' should be
+-- used to prevent HDF5 from deleting any object that is
+-- referenced by address (e.g. by a user-defined link).
+-- 'h5o_decr_refcount' should be used when the object is
+-- no longer being referenced by address (e.g. when the UD link
+-- is deleted).
+--
+-- The address of the HDF5 file on disk has no effect on
+-- 'h5o_open_by_addr', nor does the use of any unusual file
+-- drivers. The \"address\" is really the offset within the
+-- HDF5 file, and HDF5's file drivers will transparently
+-- map this to an address on disk for the filesystem.
+--
+-- On success, returns an open object identifier
+-- On failure, returns a negative value.
+--
+-- > hid_t H5Oopen_by_addr(hid_t loc_id, haddr_t addr);
+#ccall H5Oopen_by_addr, <hid_t> -> <haddr_t> -> IO <hid_t>
+
+-- |Opens an object within an HDF5 file, according to the offset
+-- within an index.
+--
+-- This function opens an object in the same way that 'h5g_open',
+-- 'h5t_open', and 'h5d_open' do. However, 'h5o_open' doesn't require
+-- the type of object to be known beforehand. This can be
+-- useful in user-defined links, for instance, when only a
+-- path is known.
+--
+-- The opened object should be closed again with 'h5o_close'
+-- or 'h5g_close', 'h5t_close', or 'h5d_close'.
+--
+-- On success, returns an open object identifier
+-- On failure, returns a negative value.
+--
+-- > hid_t H5Oopen_by_idx(hid_t loc_id, const char *group_name,
+-- >     H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t lapl_id);
+#ccall H5Oopen_by_idx, <hid_t> -> CString -> <H5_index_t> -> <H5_iter_order_t> -> <hsize_t> -> <hid_t> -> IO <hid_t>
+
+#if H5_VERSION_GE(1,8,5)
+
+-- |Determine if a linked-to object exists
+--
+-- > htri_t H5Oexists_by_name(hid_t loc_id, const char *name, hid_t lapl_id);
+#ccall H5Oexists_by_name, <hid_t> -> CString -> <hid_t> -> IO <htri_t>
+
+#endif
+
+-- |Retrieve information about an object.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Oget_info(hid_t loc_id, H5O_info_t *oinfo);
+#ccall H5Oget_info, <hid_t> -> Out <H5O_info_t> -> IO <herr_t>
+
+-- |Retrieve information about an object.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Oget_info_by_name(hid_t loc_id, const char *name, H5O_info_t *oinfo,
+-- >     hid_t lapl_id);
+#ccall H5Oget_info_by_name, <hid_t> -> CString -> Out <H5O_info_t> -> <hid_t> -> IO <herr_t>
+
+-- |Retrieve information about an object, according to the order
+-- of an index.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Oget_info_by_idx(hid_t loc_id, const char *group_name,
+-- >     H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5O_info_t *oinfo,
+-- >     hid_t lapl_id);
+#ccall H5Oget_info_by_idx, <hid_t> -> CString -> <H5_index_t> -> <H5_iter_order_t> -> <hsize_t> -> Out <H5O_info_t> -> <hid_t> -> IO <herr_t>
+
+-- |Creates a hard link from 'new_name' to the object specified
+-- by 'obj_id' using properties defined in the Link Creation
+-- Property List 'lcpl'.
+--
+-- This function should be used to link objects that have just
+-- been created.
+--
+-- 'new_name' is interpreted relative to 'new_loc_id', which
+-- is either a file ID or a group ID.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Olink(hid_t obj_id, hid_t new_loc_id, const char *new_name,
+-- >     hid_t lcpl_id, hid_t lapl_id);
+#ccall H5Olink, <hid_t> -> <hid_t> -> CString -> <hid_t> -> <hid_t> -> IO <herr_t>
+
+-- |Warning! This function is EXTREMELY DANGEROUS!
+-- Improper use can lead to FILE CORRUPTION, INACCESSIBLE DATA,
+-- and other VERY BAD THINGS!
+--
+-- This function increments the \"hard link\" reference count
+-- for an object. It should be used when a user-defined link
+-- that references an object by address is created. When the
+-- link is deleted, 'h5o_decr_refcount' should be used.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Oincr_refcount(hid_t object_id);
+#ccall H5Oincr_refcount, <hid_t> -> IO <herr_t>
+
+-- |Warning! This function is EXTREMELY DANGEROUS!
+-- Improper use can lead to FILE CORRUPTION, INACCESSIBLE DATA,
+-- and other VERY BAD THINGS!
+--
+-- This function decrements the \"hard link\" reference count
+-- for an object. It should be used when user-defined links
+-- that reference an object by address are deleted, and only
+-- after 'h5o_incr_refcount' has already been used.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Odecr_refcount(hid_t object_id);
+#ccall H5Odecr_refcount, <hid_t> -> IO <herr_t>
+
+-- |Copy an object (group or dataset) to destination location
+-- within a file or cross files. 'plist_id' is a property list
+-- which is used to pass user options and properties to the
+-- copy. The name, 'dst_name', must not already be taken by some
+-- other object in the destination group.
+--
+-- 'h5o_copy' will fail if the name of the destination object
+--     exists in the destination group.  For example,
+--     @H5Ocopy(fid_src, \"/dset\", fid_dst, \"/dset\", ...)@
+--     will fail if \"/dset\" exists in the destination file
+--
+-- OPTIONS THAT HAVE BEEN IMPLEMENTED:
+--
+--     ['h5o_COPY_SHALLOW_HIERARCHY_FLAG']
+--         If this flag is specified, only immediate members of
+--         the group are copied. Otherwise (default), it will
+--         recursively copy all objects below the group
+--
+--     ['h5o_COPY_EXPAND_SOFT_LINK_FLAG']
+--         If this flag is specified, it will copy the objects
+--         pointed by the soft links. Otherwise (default), it
+--         will copy the soft link as they are
+--
+--     ['h5o_COPY_WITHOUT_ATTR_FLAG']
+--         If this flag is specified, it will copy object without
+--         copying attributes. Otherwise (default), it will
+--         copy object along with all its attributes
+--
+--     ['h5o_COPY_EXPAND_REFERENCE_FLAG']
+--         1. Copy object between two different files:
+--             When this flag is specified, it will copy objects that
+--             are pointed by the references and update the values of
+--             references in the destination file.  Otherwise (default)
+--             the values of references in the destination will set to
+--             zero
+--             The current implementation does not handle references
+--             inside of other datatype structure. For example, if
+--             a member of compound datatype is reference, H5Ocopy()
+--             will copy that field as it is. It will not set the
+--             value to zero as default is used nor copy the object
+--             pointed by that field the flag is set
+--         2. Copy object within the same file:
+--             This flag does not have any effect to the 'h5o_copy'.
+--             Datasets or attributes of references are copied as they
+--             are, i.e. values of references of the destination object
+--             are the same as the values of the source object
+--
+-- OPTIONS THAT MAY APPLY TO COPY IN THE FUTURE:
+--
+--     ['h5o_COPY_EXPAND_EXT_LINK_FLAG']
+--         If this flag is specified, it will expand the external links
+--         into new objects, Otherwise (default), it will keep external
+--         links as they are (default)
+--
+-- PROPERTIES THAT MAY APPLY TO COPY IN FUTURE:
+--
+--   * Change data layout such as chunk size
+--
+--   * Add filter such as data compression.
+--
+--   * Add an attribute to the copied object(s) that say the date/time
+--     for the copy or other information about the source file.
+--
+-- The intermediate group creation property should be passed in
+-- using the lcpl instead of the ocpypl.
+--
+-- Parameters:
+--
+-- [@ src_loc_id :: HId_t   @]  Source file or group identifier.
+--
+-- [@ src_name   :: CString @]  Name of the source object to be copied
+--
+-- [@ dst_loc_id :: HId_t   @]  Destination file or group identifier
+--
+-- [@ dst_name   :: CString @]  Name of the destination object
+--
+-- [@ ocpypl_id  :: HId_t   @]  Properties which apply to the copy
+--
+-- [@ lcpl_id    :: HId_t   @]  Properties which apply to the new hard link
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Ocopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id,
+-- >     const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id);
+#ccall H5Ocopy, <hid_t> -> CString -> <hid_t> -> CString -> <hid_t> -> <hid_t> -> IO <herr_t>
+
+-- |Gives the specified object a comment.  The 'comment' string
+-- should be a null terminated string.  An object can have only
+-- one comment at a time.  Passing NULL for the 'comment' argument
+-- will remove the comment property from the object.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Oset_comment(hid_t obj_id, const char *comment);
+#ccall H5Oset_comment, <hid_t> -> CString -> IO <herr_t>
+
+-- |Gives the specified object a comment.  The 'comment' string
+-- should be a null terminated string.  An object can have only
+-- one comment at a time.  Passing NULL for the 'comment' argument
+-- will remove the comment property from the object.
+--
+-- Note:  Deprecated in favor of using attributes on objects.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Oset_comment_by_name(hid_t loc_id, const char *name,
+-- >     const char *comment, hid_t lapl_id);
+#ccall H5Oset_comment_by_name, <hid_t> -> CString -> CString -> <hid_t> -> IO <herr_t>
+
+-- |Retrieve comment for an object.
+--
+-- On success, returns the number of bytes in the comment including the
+-- null terminator, or zero if the object has no comment.  On failure
+-- returns a negative value.
+--
+-- > ssize_t H5Oget_comment(hid_t obj_id, char *comment, size_t bufsize);
+#ccall H5Oget_comment, <hid_t> -> OutArray CChar -> <size_t> -> IO <ssize_t>
+
+-- |Retrieve comment for an object.
+--
+-- On success, returns the number of bytes in the comment including the
+-- null terminator, or zero if the object has no comment.  On failure
+-- returns a negative value.
+--
+-- > ssize_t H5Oget_comment_by_name(hid_t loc_id, const char *name,
+-- >     char *comment, size_t bufsize, hid_t lapl_id);
+#ccall H5Oget_comment_by_name, <hid_t> -> CString -> OutArray CChar -> <size_t> -> <hid_t> -> IO <ssize_t>
+
+-- |Recursively visit an object and all the objects reachable
+-- from it.  If the starting object is a group, all the objects
+-- linked to from that group will be visited.  Links within
+-- each group are visited according to the order within the
+-- specified index (unless the specified index does not exist for
+-- a particular group, then the "name" index is used).
+--
+-- NOTE: Soft links and user-defined links are ignored during
+-- this operation.
+--
+-- NOTE: Each _object_ reachable from the initial group will only
+-- be visited once.  If multiple hard links point to the same
+-- object, the first link to the object's path (according to the
+-- iteration index and iteration order given) will be used to in
+-- the callback about the object.
+--
+-- On success, returns the return value of the first operator that
+-- returns non-zero, or zero if all members were processed with no
+-- operator returning non-zero.
+--
+-- Returns negative if something goes wrong within the library, or
+-- the negative value returned by one of the operators.
+--
+-- > herr_t H5Ovisit(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order,
+-- >     H5O_iterate_t op, void *op_data);
+#ccall H5Ovisit, <hid_t> -> <H5_index_t> -> <H5_iter_order_t> -> H5O_iterate_t a -> InOut a -> IO <herr_t>
+
+-- |Recursively visit an object and all the objects reachable
+-- from it.  If the starting object is a group, all the objects
+-- linked to from that group will be visited.  Links within
+-- each group are visited according to the order within the
+-- specified index (unless the specified index does not exist for
+-- a particular group, then the "name" index is used).
+--
+-- NOTE: Soft links and user-defined links are ignored during
+-- this operation.
+--
+-- NOTE: Each _object_ reachable from the initial group will only
+-- be visited once.  If multiple hard links point to the same
+-- object, the first link to the object's path (according to the
+-- iteration index and iteration order given) will be used to in
+-- the callback about the object.
+--
+-- On success, returns the return value of the first operator that
+-- returns non-zero, or zero if all members were processed with no
+-- operator returning non-zero.
+--
+-- Returns negative if something goes wrong within the library, or
+-- the negative value returned by one of the operators.
+--
+-- > herr_t H5Ovisit_by_name(hid_t loc_id, const char *obj_name,
+-- >     H5_index_t idx_type, H5_iter_order_t order, H5O_iterate_t op,
+-- >     void *op_data, hid_t lapl_id);
+#ccall H5Ovisit_by_name, <hid_t> -> CString -> <H5_index_t> -> <H5_iter_order_t> -> H5O_iterate_t a -> InOut a -> <hid_t> -> IO <herr_t>
+
+-- |Close an open file object.
+--
+-- This is the companion to 'h5o_open'. It is used to close any
+-- open object in an HDF5 file (but not IDs are that not file
+-- objects, such as property lists and dataspaces). It has
+-- the same effect as calling 'h5g_close', 'h5d_close', or 'h5t_close'.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Oclose(hid_t object_id);
+#ccall H5Oclose, <hid_t> -> IO <herr_t>
+
+#if H5_VERSION_GE(1,10,0)
+
+-- > herr_t H5Oflush(hid_t obj_id);
+#ccall H5Oflush, <hid_t> -> IO <herr_t>
+
+-- > herr_t H5Orefresh(hid_t oid);
+#ccall H5Orefresh, <hid_t> -> IO <herr_t>
+
+-- > herr_t H5Odisable_mdc_flushes(hid_t object_id);
+#ccall H5Odisable_mdc_flushes, <hid_t> -> IO <herr_t>
+
+-- > herr_t H5Oenable_mdc_flushes(hid_t object_id);
+#ccall H5Oenable_mdc_flushes, <hid_t> -> IO <herr_t>
+
+-- > herr_t H5Oare_mdc_flushes_disabled(hid_t object_id, hbool_t *are_disabled);
+#ccall H5Oare_mdc_flushes_disabled, <hid_t> -> Out hbool_t -> IO <herr_t>
+
+#endif
+
+#ifndef H5_NO_DEPRECATED_SYMBOLS
+
+-- * Deprecated types
+
+-- |A struct that's part of the 'h5g_stat_t' routine (deprecated)
+#starttype H5O_stat_t
+
+-- |Total size of object header in file
+#field size,    <hsize_t>
+
+-- |Free space within object header
+#field free,    <hsize_t>
+
+-- |Number of object header messages
+#field nmesgs,  CUInt
+
+-- |Number of object header chunks
+#field nchunks, CUInt
+
+#stoptype
+
+#endif /* H5_NO_DEPRECATED_SYMBOLS */
diff --git a/src/Bindings/HDF5/Raw/H5P.hsc b/src/Bindings/HDF5/Raw/H5P.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/H5P.hsc
@@ -0,0 +1,2554 @@
+#include <bindings.h>
+#include <H5Ppublic.h>
+
+module Bindings.HDF5.Raw.H5P where
+
+import Data.Word
+import Foreign.C.String
+import Foreign.C.Types
+import Foreign.Ptr
+import Foreign.Storable
+import System.Posix.Types (COff(..))
+
+import Bindings.HDF5.Raw.H5
+import Bindings.HDF5.Raw.H5AC
+import Bindings.HDF5.Raw.H5D
+import Bindings.HDF5.Raw.H5F
+import Bindings.HDF5.Raw.H5FD
+import Bindings.HDF5.Raw.H5I
+import Bindings.HDF5.Raw.H5L
+import Bindings.HDF5.Raw.H5MM
+import Bindings.HDF5.Raw.H5O
+import Bindings.HDF5.Raw.H5T
+import Bindings.HDF5.Raw.H5Z
+import Foreign.Ptr.Conventions
+
+#cinline H5P_ROOT,                          <hid_t>
+#cinline H5P_OBJECT_CREATE,                 <hid_t>
+#cinline H5P_FILE_CREATE,                   <hid_t>
+#cinline H5P_FILE_ACCESS,                   <hid_t>
+#cinline H5P_DATASET_CREATE,                <hid_t>
+#cinline H5P_DATASET_ACCESS,                <hid_t>
+#cinline H5P_DATASET_XFER,                  <hid_t>
+#cinline H5P_FILE_MOUNT,                    <hid_t>
+#cinline H5P_GROUP_CREATE,                  <hid_t>
+#cinline H5P_GROUP_ACCESS,                  <hid_t>
+#cinline H5P_DATATYPE_CREATE,               <hid_t>
+#cinline H5P_DATATYPE_ACCESS,               <hid_t>
+#cinline H5P_STRING_CREATE,                 <hid_t>
+#cinline H5P_ATTRIBUTE_CREATE,              <hid_t>
+#cinline H5P_OBJECT_COPY,                   <hid_t>
+#cinline H5P_LINK_CREATE,                   <hid_t>
+#cinline H5P_LINK_ACCESS,                   <hid_t>
+
+#cinline H5P_FILE_CREATE_DEFAULT,           <hid_t>
+#cinline H5P_FILE_ACCESS_DEFAULT,           <hid_t>
+#cinline H5P_DATASET_CREATE_DEFAULT,        <hid_t>
+#cinline H5P_DATASET_ACCESS_DEFAULT,        <hid_t>
+#cinline H5P_DATASET_XFER_DEFAULT,          <hid_t>
+#cinline H5P_FILE_MOUNT_DEFAULT,            <hid_t>
+#cinline H5P_GROUP_CREATE_DEFAULT,          <hid_t>
+#cinline H5P_GROUP_ACCESS_DEFAULT,          <hid_t>
+
+#cinline H5P_DATATYPE_CREATE_DEFAULT,       <hid_t>
+#cinline H5P_DATATYPE_ACCESS_DEFAULT,       <hid_t>
+#cinline H5P_ATTRIBUTE_CREATE_DEFAULT,      <hid_t>
+#cinline H5P_OBJECT_COPY_DEFAULT,           <hid_t>
+#cinline H5P_LINK_CREATE_DEFAULT,           <hid_t>
+#cinline H5P_LINK_ACCESS_DEFAULT,           <hid_t>
+
+#if !H5_VERSION_GE(1,8,18)
+#cinline H5P_ATTRIBUTE_ACCESS,              <hid_t>
+#cinline H5P_ATTRIBUTE_ACCESS_DEFAULT,      <hid_t>
+#endif
+
+-- |Default value for all property list classes
+#newtype_const hid_t, H5P_DEFAULT
+
+#num H5P_CRT_ORDER_TRACKED
+#num H5P_CRT_ORDER_INDEXED
+
+
+-- /* Define property list class callback function pointer types */
+
+-- |
+-- > typedef herr_t (*H5P_cls_create_func_t)(hid_t prop_id, void *create_data);
+type H5P_cls_create_func_t a = FunPtr (HId_t -> Ptr a -> IO HErr_t)
+
+-- |
+-- > typedef herr_t (*H5P_cls_copy_func_t)(hid_t new_prop_id, hid_t old_prop_id,
+-- >                                       void *copy_data);
+type H5P_cls_copy_func_t a = FunPtr (HId_t -> HId_t -> Ptr a -> IO HErr_t)
+
+-- |
+-- > typedef herr_t (*H5P_cls_close_func_t)(hid_t prop_id, void *close_data);
+type H5P_cls_close_func_t a = FunPtr (HId_t -> Ptr a -> IO HErr_t)
+
+-- |Parameters:
+--
+-- [@ prop_id       :: 'HId_t'        @]  The ID of the property list being created.
+--
+-- [@ name          :: 'CString'      @]  The name of the property being modified.
+--
+-- [@ size          :: 'CSize'        @]  The size of the property value
+--
+-- [@ initial_value :: 'InOut' a      @]  The initial value for the property being created. (The 'default' value passed to 'h5p_register2')
+--
+-- > typedef herr_t (*H5P_prp_create_func_t)(hid_t prop_id, const char *name,
+-- >         size_t size, void *initial_value);
+type H5P_prp_create_func_t a = FunPtr (CString -> CSize -> InOut a -> IO HErr_t)
+
+-- |Parameters:
+--
+-- [@ prop_id   :: 'HId_t'   @] The ID of the property list being modified.
+--
+-- [@ name      :: 'CString' @] The name of the property being modified.
+--
+-- [@ size      :: 'CSize'   @] The size of the property value
+--
+-- [@ new_value :: 'InOut' a @] The value being set for the property.
+--
+-- The 'set' routine may modify the value to be set and those changes will be
+-- stored as the value of the property.  If the 'set' routine returns a
+-- negative value, the new property value is not copied into the property and
+-- the property list set routine returns an error value.
+
+-- > typedef herr_t (*H5P_prp_set_func_t)(hid_t prop_id, const char *name,
+-- >     size_t size, void *value);
+type H5P_prp_set_func_t    a = FunPtr (HId_t -> CString -> CSize -> InOut a -> IO HErr_t)
+
+-- |Parameters:
+--
+-- [@ prop_id :: 'HId_t'   @] The ID of the property list being queried.
+--
+-- [@ name    :: 'CString' @] The name of the property being queried.
+--
+-- [@ size    :: 'CSize'   @] The size of the property value
+--
+-- [@ value   :: 'InOut' a @] The value being retrieved for the property.
+--
+-- The 'get' routine may modify the value to be retrieved and those changes
+-- will be returned to the calling function.  If the 'get' routine returns a
+-- negative value, the property value is returned and the property list get
+-- routine returns an error value.
+--
+-- > typedef herr_t (*H5P_prp_get_func_t)(hid_t prop_id, const char *name,
+-- >     size_t size, void *value);
+type H5P_prp_get_func_t    a = FunPtr (HId_t -> CString -> CSize -> InOut a -> IO HErr_t)
+
+#if H5_VERSION_GE(1,10,0)
+
+-- > typedef herr_t (*H5P_prp_encode_func_t)(const void *value, void **buf, size_t *size);
+type H5P_prp_encode_func_t a b = FunPtr (In a -> Out b -> Out CSize)
+
+-- > typedef herr_t (*H5P_prp_decode_func_t)(const void **buf, void *value);
+type H5P_prp_decode_func_t a b = FunPtr (In a -> Out b)
+
+#endif
+
+-- |Parameters:
+--
+-- [@ prop_id :: 'HId_t'   @] The ID of the property list the property is deleted from.
+-- [@ name    :: 'CString' @] The name of the property being deleted.
+-- [@ size    :: 'CSize'   @] The size of the property value
+-- [@ value   :: 'InOut' a @] The value of the property being deleted.
+--
+-- The 'delete' routine may modify the value passed in, but the value is not
+-- used by the library when the 'delete' routine returns.  If the
+-- 'delete' routine returns a negative value, the property list deletion
+-- routine returns an error value but the property is still deleted.
+--
+-- > typedef herr_t (*H5P_prp_del_func_t)(hid_t prop_id, const char *name,
+-- >     size_t size, void *value);
+type H5P_prp_delete_func_t a = FunPtr (HId_t -> CString -> CSize -> InOut a -> IO HErr_t)
+
+-- |Parameters:
+--
+-- [@ name  :: 'CString' @] The name of the property being copied.
+--
+-- [@ size  :: 'CSize'   @] The size of the property value
+--
+-- [@ value :: 'InOut' a @] The value of the property being copied.
+--
+-- The 'copy' routine may modify the value to be copied and those changes will be
+-- stored as the value of the property.  If the 'copy' routine returns a
+-- negative value, the new property value is not copied into the property and
+-- the property list copy routine returns an error value.
+--
+-- > typedef herr_t (*H5P_prp_copy_func_t)(const char *name, size_t size,
+-- >     void *value);
+type H5P_prp_copy_func_t   a = FunPtr (CString -> CSize -> InOut a -> IO HErr_t)
+
+-- |Parameters:
+--
+-- [@ value1 :: 'In' a  @]    The value of the first property being compared.
+--
+-- [@ value2 :: 'In' a  @]    The value of the second property being compared.
+--
+-- [@ size   :: 'CSize' @]    The size of the property value
+--
+-- The 'compare' routine may not modify the values to be compared.  The
+-- 'compare' routine should return a positive value if 'value1' is greater than
+-- 'value2', a negative value if 'value2' is greater than 'value1' and zero if
+-- 'value1' and 'value2' are equal.
+--
+-- > typedef int (*H5P_prp_compare_func_t)( void *value1, void *value2,
+-- >     size_t size);
+type H5P_prp_compare_func_t a = FunPtr (In a -> In a -> CSize -> IO CInt)
+
+-- |Parameters:
+--
+-- [@ name  :: 'CString' @] The name of the property being closed.
+--
+-- [@ size  :: 'CSize'   @] The size of the property value
+--
+-- [@ value :: 'In' a    @] The value of the property being closed.
+--
+-- > typedef herr_t (*H5P_prp_close_func_t)(const char *name, size_t size,
+-- >     void *value);
+type H5P_prp_close_func_t a = FunPtr (CString -> CSize -> InOut a -> IO HErr_t)
+
+-- |Type of operator callback for 'h5p_iterate'.
+--
+-- The operation receives the property list or class identifier for the object
+-- being iterated over, 'id', the name of the current property within the object,
+-- 'name', and the pointer to the operator data passed in to H5Piterate, 'iter_data'.
+--
+-- The return values from an operator are:
+--
+-- * Zero causes the iterator to continue, returning zero when all properties
+--   have been processed.
+--
+-- * Positive causes the iterator to immediately return that positive value,
+--   indicating short-circuit success. The iterator can be restarted at the
+--   index of the next property.
+--
+-- * Negative causes the iterator to immediately return that value, indicating
+--   failure. The iterator can be restarted at the index of the next
+--   property.
+--
+-- > typedef herr_t (*H5P_iterate_t)(hid_t id, const char *name, void *iter_data);
+type H5P_iterate_t a = FunPtr (HId_t -> CString -> InOut a -> IO HErr_t)
+
+#if H5_VERSION_GE(1,8,8)
+
+-- |Actual IO mode property
+#newtype H5D_mpio_actual_chunk_opt_mode_t
+
+-- |The default value, H5D_MPIO_NO_CHUNK_OPTIMIZATION, is used for all I/O
+-- operations that do not use chunk optimizations, including non-collective
+-- I/O and contiguous collective I/O.
+#newtype_const H5D_mpio_actual_chunk_opt_mode_t, H5D_MPIO_NO_CHUNK_OPTIMIZATION
+#newtype_const H5D_mpio_actual_chunk_opt_mode_t, H5D_MPIO_LINK_CHUNK
+#newtype_const H5D_mpio_actual_chunk_opt_mode_t, H5D_MPIO_MULTI_CHUNK
+
+#if H5_VERSION_LE(1,8,10)
+#newtype_const H5D_mpio_actual_chunk_opt_mode_t, H5D_MPIO_MULTI_CHUNK_NO_OPT
+#endif
+
+-- |The following four values are conveniently defined as a bit field so that
+-- we can switch from the default to indpendent or collective and then to
+-- mixed without having to check the original value.
+#newtype H5D_mpio_actual_io_mode_t
+
+-- |NO_COLLECTIVE means that either collective I/O wasn't requested or that
+-- no I/O took place.
+#newtype_const H5D_mpio_actual_io_mode_t, H5D_MPIO_NO_COLLECTIVE
+
+-- |CHUNK_INDEPENDENT means that collective I/O was requested, but the
+-- chunk optimization scheme chose independent I/O for each chunk.
+#newtype_const H5D_mpio_actual_io_mode_t, H5D_MPIO_CHUNK_INDEPENDENT
+#newtype_const H5D_mpio_actual_io_mode_t, H5D_MPIO_CHUNK_COLLECTIVE
+#newtype_const H5D_mpio_actual_io_mode_t, H5D_MPIO_CHUNK_MIXED
+
+-- |The contiguous case is separate from the bit field.
+#newtype_const H5D_mpio_actual_io_mode_t, H5D_MPIO_CONTIGUOUS_COLLECTIVE
+
+#endif
+
+#if H5_VERSION_GE(1,8,10)
+
+-- | Broken collective IO property
+#newtype H5D_mpio_no_collective_cause_t
+
+#newtype_const H5D_mpio_no_collective_cause_t, H5D_MPIO_COLLECTIVE
+#newtype_const H5D_mpio_no_collective_cause_t, H5D_MPIO_SET_INDEPENDENT
+#newtype_const H5D_mpio_no_collective_cause_t, H5D_MPIO_DATATYPE_CONVERSION
+#newtype_const H5D_mpio_no_collective_cause_t, H5D_MPIO_DATA_TRANSFORMS
+#newtype_const H5D_mpio_no_collective_cause_t, H5D_MPIO_NOT_SIMPLE_OR_SCALAR_DATASPACES
+#newtype_const H5D_mpio_no_collective_cause_t, H5D_MPIO_NOT_CONTIGUOUS_OR_CHUNKED_DATASET
+
+#if H5_VERSION_GE(1,10,2)
+#newtype_const H5D_mpio_no_collective_cause_t, H5D_MPIO_NO_COLLECTIVE_MAX_CAUSE
+#else
+#newtype_const H5D_mpio_no_collective_cause_t, H5D_MPIO_FILTERS
+#endif
+
+#endif
+
+-- /*********************/
+-- /* Public Prototypes */
+-- /*********************/
+
+-- /* Generic property list routines */
+
+
+-- |Create a new property list class.  Allocates memory and attaches
+-- a class to the property list class hierarchy.
+--
+-- Parameters
+--
+-- [@ parent      :: 'HId_t'                   @] Property list class ID of parent class
+--
+-- [@ name        :: 'CString'                 @] Name of class we are creating
+--
+-- [@ cls_create  :: 'H5P_cls_create_func_t' a @] The callback function to call when each property list in this class is created.
+--
+-- [@ create_data :: 'InOut' a                 @] Pointer to user data to pass along to class creation callback.
+--
+-- [@ cls_copy    :: 'H5P_cls_copy_func_t' b   @] The callback function to call when each property list in this class is copied.
+--
+-- [@ copy_data   :: 'InOut' b                 @] Pointer to user data to pass along to class copy callback.
+--
+-- [@ cls_close   :: 'H5P_cls_close_func_t' c  @] The callback function to call when each property list in this class is closed.
+--
+-- [@ close_data  :: 'InOut' c                 @] Pointer to user data to pass along to class close callback.
+--
+-- Returns a valid property list class ID on success, NULL on failure.
+--
+-- > hid_t H5Pcreate_class(hid_t parent, const char *name,
+-- >     H5P_cls_create_func_t cls_create, void *create_data,
+-- >     H5P_cls_copy_func_t cls_copy, void *copy_data,
+-- >     H5P_cls_close_func_t cls_close, void *close_data);
+#ccall H5Pcreate_class, <hid_t> -> CString -> H5P_cls_create_func_t a -> Ptr a -> H5P_cls_copy_func_t b -> Ptr b -> H5P_cls_close_func_t c -> Ptr c -> IO <hid_t>
+
+-- |This routine retrieves the name of a generic property list class.
+-- The pointer to the name must be 'free'd by the user for successful calls.
+--
+-- Parameters
+--
+-- [@ pclass_id :: 'HId_t' @]   Property class to query
+--
+-- On success, returns a pointer to a malloc'ed string containing the class name
+-- On failure, returns NULL.
+--
+-- > char *H5Pget_class_name(hid_t pclass_id);
+#ccall H5Pget_class_name, <hid_t> -> IO CString
+
+-- |Routine to create a new property list of a property list class.
+--
+-- Creates a property list of a given class.  If a 'create' callback
+-- exists for the property list class, it is called before the
+-- property list is passed back to the user.  If 'create' callbacks exist for
+-- any individual properties in the property list, they are called before the
+-- class 'create' callback.
+--
+-- Parameters:
+--
+-- [@ cls_id :: 'HId_t' @]  Property list class create list from
+--
+-- Returns a valid property list ID on success, a negative value on failure.
+--
+-- > hid_t H5Pcreate(hid_t cls_id);
+#ccall H5Pcreate, <hid_t> -> IO <hid_t>
+
+-- |Routine to register a new property in a property list class.
+--
+-- Registers a new property with a property list class.  The property will
+-- exist in all property list objects of that class after this routine is
+-- finished.  The name of the property must not already exist.  The default
+-- property value must be provided and all new property lists created with this
+-- property will have the property value set to the default provided.  Any of
+-- the callback routines may be set to NULL if they are not needed.
+--
+-- Zero-sized properties are allowed and do not store any data in the
+-- property list.  These may be used as flags to indicate the presence or
+-- absence of a particular piece of information.  The 'default' pointer for a
+-- zero-sized property may be set to NULL.  The property 'create' & 'close'
+-- callbacks are called for zero-sized properties, but the 'set' and 'get'
+-- callbacks are never called.
+--
+-- The 'create' callback is called when a new property list with this
+-- property is being created.  'H5P_prp_create_func_t' is defined as:
+--
+-- The 'create' routine may modify the value to be set and those changes will
+-- be stored as the initial value of the property.  If the 'create' routine
+-- returns a negative value, the new property value is not copied into the
+-- property and the property list creation routine returns an error value.
+--
+-- The 'set' callback is called before a new value is copied into the
+-- property.  The 'set' routine may modify the value to be set and those
+-- changes will be stored as the value of the property.  If the 'set' routine
+-- returns a negative value, the new property value is not copied into the
+-- property and the property list set routine returns an error value.
+--
+-- The 'get' callback is called before a value is retrieved from the
+-- property.  The 'get' routine may modify the value to be retrieved and
+-- those changes will be returned to the calling function.  If the 'get'
+-- routine returns a negative value, the property value is returned and
+-- the property list get routine returns an error value.
+--
+-- The 'delete' callback is called when a property is deleted from a
+-- property list.  The 'delete' routine may modify the value passed in,
+-- but the value is not used by the library when the 'delete' routine
+-- returns.  If the 'delete' routine returns a negative value, the
+-- property list deletion routine returns an error value but the property
+-- is still deleted.
+--
+-- The 'copy' callback is called when a property list with this property
+-- is copied.  The 'copy' routine may modify the value to be copied and
+-- those changes will be stored as the value of the property.  If the
+-- 'copy' routine returns a negative value, the new property value is not
+-- copied into the property and the property list copy routine returns an
+-- error value.
+--
+-- The 'compare' callback is called when a property list with this property
+-- is compared to another property list.  The 'compare' routine may not
+-- modify the values to be compared.  The 'compare' routine should return
+-- a positive value if 'value1' is greater than 'value2', a negative value
+-- if 'value2' is greater than 'value1' and zero if 'value1' and 'value2'
+-- are equal.
+--
+-- The 'close' callback is called when a property list with this property
+-- is being destroyed.  The 'close' routine may modify the value passed in,
+-- but the value is not used by the library when the 'close' routine returns.
+-- If the 'close' routine returns a negative value, the property list close
+-- routine returns an error value but the property list is still closed.
+--
+-- Parameters:
+--
+-- [@ class       :: HId_t                      @]        IN: Property list class to close
+--
+-- [@ name        :: CString                    @]        IN: Name of property to register
+--
+-- [@ size        :: CSize                      @]        IN: Size of property in bytes
+--
+-- [@ def_value   :: In a                       @]        IN: Pointer to buffer containing default value for property in newly created property lists
+--
+-- [@ prp_create  :: H5P_prp_create_func_t a    @]        IN: Function pointer to property creation callback
+--
+-- [@ prp_set     :: H5P_prp_set_func_t a       @]        IN: Function pointer to property set callback
+--
+-- [@ prp_get     :: H5P_prp_get_func_t a       @]        IN: Function pointer to property get callback
+--
+-- [@ prp_delete  :: H5P_prp_delete_func_t a    @]        IN: Function pointer to property delete callback
+--
+-- [@ prp_copy    :: H5P_prp_copy_func_t a      @]        IN: Function pointer to property copy callback
+--
+-- [@ prp_cmp     :: H5P_prp_compare_func_t a   @]        IN: Function pointer to property compare callback
+--
+-- [@ prp_close   :: H5P_prp_close_func_t a     @]        IN: Function pointer to property close callback
+--
+-- Returns non-negative on success, negative on failure.
+--
+--  COMMENTS, BUGS, ASSUMPTIONS:
+--
+-- The 'set' callback function may be useful to range check the value being
+-- set for the property or may perform some tranformation/translation of the
+-- value set.  The 'get' callback would then [probably] reverse the
+-- transformation, etc.  A single 'get' or 'set' callback could handle
+-- multiple properties by performing different actions based on the property
+-- name or other properties in the property list.
+--
+-- I would like to say \"the property list is not closed\" when a 'close'
+-- routine fails, but I don't think that's possible due to other properties in
+-- the list being successfully closed & removed from the property list.  I
+-- suppose that it would be possible to just remove the properties which have
+-- successful 'close' callbacks, but I'm not happy with the ramifications
+-- of a mangled, un-closable property list hanging around...  Any comments? -QAK
+--
+-- > herr_t H5Pregister2(hid_t cls_id, const char *name, size_t size,
+-- >     void *def_value, H5P_prp_create_func_t prp_create,
+-- >     H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get,
+-- >     H5P_prp_delete_func_t prp_del, H5P_prp_copy_func_t prp_copy,
+-- >     H5P_prp_compare_func_t prp_cmp, H5P_prp_close_func_t prp_close);
+#ccall H5Pregister2, <hid_t> -> CString -> <size_t> -> In a -> H5P_prp_create_func_t a -> H5P_prp_set_func_t a -> H5P_prp_get_func_t a -> H5P_prp_delete_func_t a -> H5P_prp_copy_func_t a -> H5P_prp_compare_func_t a -> H5P_prp_close_func_t a -> IO <herr_t>
+
+-- |Routine to insert a new property in a property list.
+--
+-- Inserts a temporary property into a property list.  The property will
+-- exist only in this property list object.  The name of the property must not
+-- already exist.  The value must be provided unless the property is zero-
+-- sized.  Any of the callback routines may be set to NULL if they are not
+-- needed.
+--
+-- Zero-sized properties are allowed and do not store any data in the
+-- property list.  These may be used as flags to indicate the presence or
+-- absence of a particular piece of information.  The 'value' pointer for a
+-- zero-sized property may be set to NULL.  The property 'close' callback is
+-- called for zero-sized properties, but the 'set' and 'get' callbacks are
+-- never called.
+--
+-- There is no 'create' callback routine for temporary property list
+-- objects, the initial value is assumed to have any necessary setup already
+-- performed on it.
+-- Aside from that, the callbacks are the same as for 'h5p_register'.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pinsert2(hid_t plist_id, const char *name, size_t size,
+-- >     void *value, H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get,
+-- >     H5P_prp_delete_func_t prp_delete, H5P_prp_copy_func_t prp_copy,
+-- >     H5P_prp_compare_func_t prp_cmp, H5P_prp_close_func_t prp_close);
+#ccall H5Pinsert2, <hid_t> -> CString -> CSize -> In a -> H5P_prp_set_func_t a -> H5P_prp_get_func_t a -> H5P_prp_delete_func_t a -> H5P_prp_copy_func_t a -> H5P_prp_compare_func_t a -> H5P_prp_close_func_t a -> IO <herr_t>
+
+-- |Routine to set a property's value in a property list.
+--
+-- Sets a new value for a property in a property list.  The property name
+-- must exist or this routine will fail.  If there is a 'set' callback routine
+-- registered for this property, the 'value' will be passed to that routine and
+-- any changes to the 'value' will be used when setting the property value.
+-- The information pointed at by the 'value' pointer (possibly modified by the
+-- 'set' callback) is copied into the property list value and may be changed
+-- by the application making the H5Pset call without affecting the property
+-- value.
+--
+-- If the 'set' callback routine returns an error, the property value will
+-- not be modified.  This routine may not be called for zero-sized properties
+-- and will return an error in that case.
+--
+-- Parameters:
+--
+-- [@ plist_id :: 'HId_t'   @]    Property list to find property in
+--
+-- [@ name     :: 'CString' @]    Name of property to set
+--
+-- [@ value    :: 'In' a    @]    Pointer to the value for the property
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset(hid_t plist_id, const char *name, void *value);
+#ccall H5Pset, <hid_t> -> CString -> In a -> IO <herr_t>
+
+-- |Routine to query the existence of a property in a property object.
+--
+-- Parameters:
+--
+-- [@ id   :: 'HId_t'   @]    Property object ID to check
+--
+-- [@ name :: 'CString' @]    Name of property to check for
+--
+-- > htri_t H5Pexist(hid_t plist_id, const char *name);
+#ccall H5Pexist, <hid_t> -> CString -> IO <htri_t>
+
+#if H5_VERSION_GE(1,10,0)
+
+-- > herr_t H5Pencode(hid_t plist_id, void *buf, size_t *nalloc);
+#ccall H5Pencode, <hid_t> ->  In a -> Out <size_t> -> IO <herr_t>
+
+-- > H5_DLL hid_t  H5Pdecode(const void *buf);
+#ccall H5Pdecode, In a -> IO <hid_t>
+
+#endif
+
+-- |Routine to query the size of a property in a property list or class.
+--
+-- This routine retrieves the size of a property's value in bytes.  Zero-
+-- sized properties are allowed and return a value of 0.  This function works
+-- for both property lists and classes.
+--
+-- Parameters:
+--
+-- [@ id   :: 'HId_t'       @]  ID of property list or class to check
+--
+-- [@ name :: 'CString'     @]  Name of property to query
+--
+-- [@ size :: 'Out' 'CSize' @]  Size of property
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_size(hid_t id, const char *name, size_t *size);
+#ccall H5Pget_size, <hid_t> -> CString -> Out <size_t> -> IO <herr_t>
+
+-- |Routine to query the size of a property in a property list or class.
+--
+-- This routine retrieves the number of properties in a property list or
+-- class.  If a property class ID is given, the number of registered properties
+-- in the class is returned in 'nprops'.  If a property list ID is given, the
+-- current number of properties in the list is returned in 'nprops'.
+--
+-- Parameters:
+--
+-- [@ id     'HId_t'       @]   ID of Property list or class to check
+--
+-- [@ nprops 'Out' 'CSize' @]   Number of properties in the property object
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_nprops(hid_t id, size_t *nprops);
+#ccall H5Pget_nprops, <hid_t> -> Out <size_t> -> IO <herr_t>
+
+-- |Routine to query the name of a generic property list class
+--
+-- This routine retrieves the name of a generic property list class.
+-- The pointer to the name must be free'd by the user for successful calls.
+--
+-- Parameters:
+--
+-- [@ pclass_id :: 'HId_t' @] Property class to query
+--
+-- Returns a pointer to a malloc'ed string containing the class name, or
+-- NULL on failure.
+--
+-- > hid_t H5Pget_class(hid_t plist_id);
+#ccall H5Pget_class, <hid_t> -> IO <hid_t>
+
+-- |This routine retrieves an ID for the parent class of a property class.
+--
+-- Parameters:
+--
+-- [@ pclass_id :: 'HId_t' @] Property class to query
+--
+-- Returns the ID of the parent class object or NULL on failure.
+--
+-- > hid_t H5Pget_class_parent(hid_t pclass_id);
+#ccall H5Pget_class_parent, <hid_t> -> IO <hid_t>
+
+-- |Routine to query the value of a property in a property list.
+--
+-- Retrieves a copy of the value for a property in a property list.  The
+-- property name must exist or this routine will fail.  If there is a
+-- 'get' callback routine registered for this property, the copy of the
+-- value of the property will first be passed to that routine and any changes
+-- to the copy of the value will be used when returning the property value
+-- from this routine.
+--
+-- If the 'get' callback routine returns an error, 'value' will not be
+-- modified and this routine will return an error.  This routine may not be
+-- called for zero-sized properties.
+--
+-- Parameters:
+--
+-- [@ plist_id :: 'HId_t'   @]  Property list to check
+--
+-- [@ name     :: 'CString' @]  Name of property to query
+--
+-- [@ value    :: 'Out' a   @]  Pointer to the buffer for the property value
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget(hid_t plist_id, const char *name, void * value);
+#ccall H5Pget, <hid_t> -> CString -> Out a -> IO <herr_t>
+
+-- |Determines whether two property lists or two property classes are equal.
+--
+-- Parameters:
+--
+-- [@ id1 :: 'HId_t' @] Property list or class ID to compare
+--
+-- [@ id2 :: 'HId_t' @] Property list or class ID to compare
+--
+-- > htri_t H5Pequal(hid_t id1, hid_t id2);
+#ccall H5Pequal, <hid_t> -> <hid_t> -> IO <htri_t>
+
+-- |This routine queries whether a property list is a member of the property
+-- list class.
+--
+-- Parameters:
+--
+-- [@ plist_id  :: 'HId_t' @] Property list to query
+--
+-- [@ pclass_id :: 'HId_t' @] Property class to query
+--
+-- > htri_t H5Pisa_class(hid_t plist_id, hid_t pclass_id);
+#ccall H5Pisa_class, <hid_t> -> <hid_t> -> IO <htri_t>
+
+-- |This routine iterates over the properties in the property object specified
+-- with ID.  The properties in both property lists and classes may be iterated
+-- over with this function.  For each property in the object, the 'iter_data' and
+-- some additional information, specified below, are passed to the 'iter_func'
+-- function.  The iteration begins with the 'idx' property in the object and the
+-- next element to be processed by the operator is returned in 'idx'.  If 'idx' is
+-- NULL, then the iterator starts at the first property; since no stopping point
+-- is returned in this case, the iterator cannot be restarted if one of the calls
+-- to its operator returns non-zero.  The 'idx' value is 0-based (ie. to start at
+-- the "first" property, the 'idx' value should be 0).
+--
+-- 'h5p_iterate' assumes that the properties in the object identified by ID remains
+-- unchanged through the iteration.  If the membership changes during the
+-- iteration, the function's behavior is undefined.
+--
+-- Parameters:
+--
+-- [@ id        :: 'HId_t'           @] ID of property object to iterate over
+--
+-- [@ idx       :: 'InOut' 'CInt'    @] Index of the property to begin with
+--
+-- [@ iter_func :: 'H5P_iterate_t' a @] Function pointer to function to be called with each property iterated over.
+--
+-- [@ iter_data :: 'InOut' a         @] Pointer to iteration data from user
+--
+-- Returns the return value of the last call to 'iter_func' if it was
+-- non-zero, or zero if all properties have been processed.  Returns a
+-- negative value on failure.
+--
+-- > int H5Piterate(hid_t id, int *idx, H5P_iterate_t iter_func,
+-- >             void *iter_data);
+#ccall H5Piterate, <hid_t> -> InOut CInt -> H5P_iterate_t a -> InOut a -> IO CInt
+
+-- |Copies a property from one property list or class to another.
+--
+-- If a property is copied from one class to another, all the property
+-- information will be first deleted from the destination class and then the
+-- property information will be copied from the source class into the
+-- destination class.
+--
+-- If a property is copied from one list to another, the property will be
+-- first deleted from the destination list (generating a call to the 'close'
+-- callback for the property, if one exists) and then the property is copied
+-- from the source list to the destination list (generating a call to the
+-- 'copy' callback for the property, if one exists).
+--
+-- If the property does not exist in the destination class or list, this call
+-- is equivalent to calling H5Pregister2 or H5Pinsert2 (for a class or list, as
+-- appropriate) and the 'create' callback will be called in the case of the
+-- property being copied into a list (if such a callback exists for the
+-- property).
+--
+-- Parameters:
+--
+-- [@ dst_id :: 'HId_t'   @]    ID of destination property list or class
+--
+-- [@ src_id :: 'HId_t'   @]    ID of source property list or class
+--
+-- [@ name   :: 'CString' @]    Name of property to copy
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pcopy_prop(hid_t dst_id, hid_t src_id, const char *name);
+#ccall H5Pcopy_prop, <hid_t> -> <hid_t> -> CString -> IO <herr_t>
+
+-- |Removes a property from a property list.  Both properties which were
+-- in existance when the property list was created (i.e. properties registered
+-- with 'h5p_register2') and properties added to the list after it was created
+-- (i.e. added with 'h5p_insert2') may be removed from a property list.
+-- Properties do not need to be removed a property list before the list itself
+-- is closed, they will be released automatically when 'h5p_close' is called.
+-- The 'close' callback for this property is called before the property is
+-- release, if the callback exists.
+--
+-- Parameters:
+--
+-- [@ plist_id :: 'HId_t'   @]  Property list to modify
+--
+-- [@ name     :: 'CString' @]  Name of property to remove
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Premove(hid_t plist_id, const char *name);
+#ccall H5Premove, <hid_t> -> CString -> IO <herr_t>
+
+-- |Removes a property from a property list class.  Future property lists
+-- created of that class will not contain this property.  Existing property
+-- lists containing this property are not affected.
+--
+-- Parameters:
+-- [@ pclass_id :: 'HId_t'   @] Property list class to modify
+-- [@ name      :: 'CString' @] Name of property to remove
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Punregister(hid_t pclass_id, const char *name);
+#ccall H5Punregister, <hid_t> -> CString -> IO <herr_t>
+
+-- |Release memory and de-attach a class from the property list class hierarchy.
+--
+-- Parameters:
+--
+-- [@ cls_id :: 'HId_t' @]  Property list class ID to class
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pclose_class(hid_t plist_id);
+#ccall H5Pclose_class, <hid_t> -> IO <herr_t>
+
+-- |Closes a property list.  If a 'close' callback exists for the property
+-- list class, it is called before the property list is destroyed.  If 'close'
+-- callbacks exist for any individual properties in the property list, they are
+-- called after the class 'close' callback.
+--
+-- Parameters:
+-- [@ plist_id :: 'HId_t' @]    Property list to close
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pclose(hid_t plist_id);
+#ccall H5Pclose, <hid_t> -> IO <herr_t>
+
+-- |Copy a property list or class and return the ID.  This routine calls the
+-- class 'copy' callback after any property 'copy' callbacks are called
+-- (assuming all property 'copy' callbacks return successfully).
+--
+-- Parameters:
+--     hid_t id;           IN: Property list or class ID to copy
+--
+-- Returns a valid (non-negative) property list ID on success, negative on failure.
+--
+-- > hid_t H5Pcopy(hid_t plist_id);
+#ccall H5Pcopy, <hid_t> -> IO <hid_t>
+
+-- * Object creation property list (OCPL) routines
+
+-- |Sets the cutoff values for indexes storing attributes
+-- in object headers for this file.  If more than 'max_compact'
+-- attributes are in an object header, the attributes will be
+-- moved to a heap and indexed with a B-tree.
+--
+-- Likewise, an object header containing fewer than 'min_dense'
+-- attributes will be converted back to storing the attributes
+-- directly in the object header.
+--
+-- If the 'max_compact' is zero then attributes for this object will
+-- never be stored in the object header but will be always be
+-- stored in a heap.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_attr_phase_change(hid_t plist_id, unsigned max_compact, unsigned min_dense);
+#ccall H5Pset_attr_phase_change, <hid_t> -> CUInt -> CUInt -> IO <herr_t>
+
+-- |Gets the phase change values for attribute storage
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_attr_phase_change(hid_t plist_id, unsigned *max_compact, unsigned *min_dense);
+#ccall H5Pget_attr_phase_change, <hid_t> -> Out CUInt -> Out CUInt -> IO <herr_t>
+
+-- |Set the flags for creation order of attributes on an object
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_attr_creation_order(hid_t plist_id, unsigned crt_order_flags);
+#ccall H5Pset_attr_creation_order, <hid_t> -> CUInt -> IO <herr_t>
+
+-- |Returns the flags indicating creation order is tracked/indexed
+-- for attributes on an object.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_attr_creation_order(hid_t plist_id, unsigned *crt_order_flags);
+#ccall H5Pget_attr_creation_order, <hid_t> -> Out CUInt -> IO <herr_t>
+
+-- |Set whether the birth, access, modification & change times for
+-- an object are stored.
+--
+-- Birth time is the time the object was created.  Access time is
+-- the last time that metadata or raw data was read from this
+-- object.  Modification time is the last time the data for
+-- this object was changed (either writing raw data to a dataset
+-- or inserting/modifying/deleting a link in a group).  Change
+-- time is the last time the metadata for this object was written
+-- (adding/modifying/deleting an attribute on an object, extending
+-- the size of a dataset, etc).
+--
+-- If these times are not tracked, they will be reported as
+-- 12:00 AM UDT, Jan. 1, 1970 (i.e. 0 seconds past the UNIX
+-- epoch) when queried.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_obj_track_times(hid_t plist_id, hbool_t track_times);
+#ccall H5Pset_obj_track_times, <hid_t> -> <hbool_t> -> IO <herr_t>
+
+-- |Returns whether times are tracked for an object.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_obj_track_times(hid_t plist_id, hbool_t *track_times);
+#ccall H5Pget_obj_track_times, <hid_t> -> Out <hbool_t> -> IO <herr_t>
+
+-- |Modifies the specified 'filter' in the transient or permanent
+-- output filter pipeline depending on whether 'plist' is a dataset
+-- creation or dataset transfer property list.  The 'flags' argument
+-- specifies certain general properties of the filter and is
+-- documented below.  The 'cd_values' is an array of 'cd_nelmts'
+-- integers which are auxiliary data for the filter.  The integer
+-- values will be stored in the dataset object header as part of
+-- the filter information.
+--
+-- The 'flags' argument is a bit vector of the following fields:
+--
+-- ['h5z_FLAG_OPTIONAL']
+-- If this bit is set then the filter is optional.  If the
+-- filter fails during an 'h5d_write' operation then the filter
+-- is just excluded from the pipeline for the chunk for which it
+-- failed; the filter will not participate in the pipeline
+-- during an 'h5d_read' of the chunk.  If this bit is clear and
+-- the filter fails then the entire I/O operation fails.
+-- If this bit is set but encoding is disabled for a filter,
+-- attempting to write will generate an error.
+--
+-- Note:  This function currently supports only the permanent filter
+-- pipeline.  That is, 'plist_id' must be a dataset creation
+-- property list.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pmodify_filter(hid_t plist_id, H5Z_filter_t filter,
+-- >         unsigned int flags, size_t cd_nelmts,
+-- >         const unsigned int cd_values[/*cd_nelmts*/]);
+#ccall H5Pmodify_filter, <hid_t> -> <H5Z_filter_t> -> CUInt -> <size_t> -> InArray CUInt -> IO <herr_t>
+
+-- |Adds the specified 'filter' and corresponding properties to the
+-- end of the data or link output filter pipeline
+-- depending on whether 'plist' is a dataset creation or group
+-- creation property list.  The 'flags' argument specifies certain
+-- general properties of the filter and is documented below.
+-- The 'cd_values' is an array of 'cd_nelmts' integers which are
+-- auxiliary data for the filter.  The integer vlues will be
+-- stored in the dataset object header as part of the filter
+-- information.
+--
+-- The 'flags' argument is a bit vector of the following fields:
+--
+-- ['h5z_FLAG_OPTIONAL']
+-- If this bit is set then the filter is optional.  If the
+-- filter fails during an 'h5d_write' operation then the filter
+-- is just excluded from the pipeline for the chunk for which it
+-- failed; the filter will not participate in the pipeline
+-- during an 'h5d_read' of the chunk.  If this bit is clear and
+-- the filter fails then the entire I/O operation fails.
+-- If this bit is set but encoding is disabled for a filter,
+-- attempting to write will generate an error.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_filter(hid_t plist_id, H5Z_filter_t filter,
+-- >         unsigned int flags, size_t cd_nelmts,
+-- >         const unsigned int c_values[]);
+#ccall H5Pset_filter, <hid_t> -> <H5Z_filter_t> -> CUInt -> <size_t> -> InArray CUInt -> IO <herr_t>
+
+-- |Returns the number of filters in the data or link
+-- pipeline depending on whether 'plist_id' is a dataset creation
+-- or group creation property list.  In each pipeline the
+-- filters are numbered from zero through N-1 where N is the
+-- value returned by this function.  During output to the file
+-- the filters of a pipeline are applied in increasing order
+-- (the inverse is true for input).
+--
+-- Returns the number of filters or negative on failure.
+--
+-- > int H5Pget_nfilters(hid_t plist_id);
+#ccall H5Pget_nfilters, <hid_t> -> IO CInt
+
+-- |This is the query counterpart of 'h5p_set_filter' and returns
+-- information about a particular filter number in a permanent
+-- or transient pipeline depending on whether 'plist_id' is a
+-- dataset creation or transfer property list.  On input,
+-- 'cd_nelmts' indicates the number of entries in the 'cd_values'
+-- array allocated by the caller while on exit it contains the
+-- number of values defined by the filter.  'filter_config' is a bit
+-- field contaning encode/decode flags from "Bindings.HDF5.Raw.H5Z".  The
+-- 'idx' should be a value between zero and N-1 as described for
+-- 'h5p_get_nfilters' and the function will return failure if the
+-- filter number is out of range.
+--
+-- Returns the filter identification number or 'h5z_FILTER_ERROR' on
+-- failure (which is negative).
+--
+-- > H5Z_filter_t H5Pget_filter2(hid_t plist_id, unsigned filter,
+-- >        unsigned int *flags/*out*/,
+-- >        size_t *cd_nelmts/*out*/,
+-- >        unsigned cd_values[]/*out*/,
+-- >        size_t namelen, char name[],
+-- >        unsigned *filter_config /*out*/);
+#ccall H5Pget_filter2, <hid_t> -> CUInt -> Out CUInt -> Out <size_t> -> OutArray CUInt -> <size_t> -> OutArray CChar -> Out CUInt -> IO <H5Z_filter_t>
+
+-- |This is an additional query counterpart of 'h5p_set_filter' and
+-- returns information about a particular filter in a permanent
+-- or transient pipeline depending on whether 'plist_id' is a
+-- dataset creation or transfer property list.  On input,
+-- 'cd_nelmts' indicates the number of entries in the 'cd_values'
+-- array allocated by the caller while on exit it contains the
+-- number of values defined by the filter.  'filter_config' is a bit
+-- field contaning encode/decode flags from "Bindings.HDF5.Raw.H5Z".  The
+-- ID should be the filter ID to retrieve the parameters for.  If the
+-- filter is not set for the property list, an error will be returned.
+--
+-- Returns the number of filters or negative on failure.
+--
+-- > herr_t H5Pget_filter_by_id2(hid_t plist_id, H5Z_filter_t id,
+-- >        unsigned int *flags/*out*/, size_t *cd_nelmts/*out*/,
+-- >        unsigned cd_values[]/*out*/, size_t namelen, char name[]/*out*/,
+-- >        unsigned *filter_config/*out*/);
+#ccall H5Pget_filter_by_id2, <hid_t> -> <H5Z_filter_t> -> Out CUInt -> Out CSize -> OutArray CUInt -> CSize -> OutArray CChar -> Out CUInt -> IO <herr_t>
+
+-- |This is a query routine to verify that all the filters set
+-- in the dataset creation property list are available currently.
+--
+-- > htri_t H5Pall_filters_avail(hid_t plist_id);
+#ccall H5Pall_filters_avail, <hid_t> -> IO <htri_t>
+
+-- |Deletes a filter from the dataset creation property list;
+-- deletes all filters if 'filter' is 'h5z_FILTER_NONE'
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Premove_filter(hid_t plist_id, H5Z_filter_t filter);
+#ccall H5Premove_filter, <hid_t> -> <H5Z_filter_t> -> IO <herr_t>
+
+-- |Sets the compression method for a dataset or group link
+-- filter pipeline (depending on whether 'plist_id' is a dataset
+-- creation or group creation property list) to 'h5z_FILTER_DEFLATE'
+-- and the compression level to 'level' which should be a value
+-- between zero and nine, inclusive.  Lower compression levels
+-- are faster but result in less compression.  This is the same
+-- algorithm as used by the GNU gzip program.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_deflate(hid_t plist_id, unsigned aggression);
+#ccall H5Pset_deflate, <hid_t> -> CUInt -> IO <herr_t>
+
+-- |Sets Fletcher32 checksum of EDC for a dataset creation
+-- property list or group creation property list.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_fletcher32(hid_t plist_id);
+#ccall H5Pset_fletcher32, <hid_t> -> IO <herr_t>
+
+
+-- * File creation property list (FCPL) routines
+
+-- |Retrieves version information for various parts of a file.
+--
+-- Any (or even all) of the output arguments can be null
+-- pointers.
+--
+-- Parameters:
+--
+-- [@ plist_id :: 'HId_t'       @]  The file creation property list ID
+--
+-- [@ boot	   :: 'Out' 'CUInt' @]  The file super block.
+--
+-- [@ freelist :: 'Out' 'CUInt' @]  The global free list.
+--
+-- [@ stab	   :: 'Out' 'CUInt' @]  The root symbol table entry.
+--
+-- [@ shhdr    :: 'Out' 'CUInt' @]  Shared object headers.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_version(hid_t plist_id, unsigned *boot/*out*/,
+-- >          unsigned *freelist/*out*/, unsigned *stab/*out*/,
+-- >          unsigned *shhdr/*out*/);
+#ccall H5Pget_version, <hid_t> -> Out CUInt -> Out CUInt -> Out CUInt -> Out CUInt -> IO <herr_t>
+
+-- |Sets the userblock size field of a file creation property list.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_userblock(hid_t plist_id, hsize_t size);
+#ccall H5Pset_userblock, <hid_t> -> <hsize_t> -> IO <herr_t>
+
+-- |Queries the size of a user block in a file creation property list.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_userblock(hid_t plist_id, hsize_t *size);
+#ccall H5Pget_userblock, <hid_t> -> Out <hsize_t> -> IO <herr_t>
+
+-- |Sets file size-of addresses and sizes.  'plist_id' should be a
+-- file creation property list.  A value of zero causes the
+-- property to not change.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_sizes(hid_t plist_id, size_t sizeof_addr,
+-- >        size_t sizeof_size);
+#ccall H5Pset_sizes, <hid_t> -> <size_t> -> <size_t> -> IO <herr_t>
+
+-- |Returns the size of address and size quantities stored in a
+-- file according to a file creation property list.  Either (or
+-- even both) 'sizeof_addr' and 'sizeof_size' may be null pointers.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_sizes(hid_t plist_id, size_t *sizeof_addr/*out*/,
+-- >        size_t *sizeof_size/*out*/);
+#ccall H5Pget_sizes, <hid_t> -> Out <size_t> -> Out <size_t> -> IO <herr_t>
+
+-- |IK is one half the rank of a tree that stores a symbol
+-- table for a group.  Internal nodes of the symbol table are on
+-- average 75% full.  That is, the average rank of the tree is
+-- 1.5 times the value of IK.
+--
+-- LK is one half of the number of symbols that can be stored in
+-- a symbol table node.  A symbol table node is the leaf of a
+-- symbol table tree which is used to store a group.  When
+-- symbols are inserted randomly into a group, the group's
+-- symbol table nodes are 75% full on average.  That is, they
+-- contain 1.5 times the number of symbols specified by LK.
+--
+-- Either (or even both) of IK and LK can be zero in which case
+-- that value is left unchanged.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_sym_k(hid_t plist_id, unsigned ik, unsigned lk);
+#ccall H5Pset_sym_k, <hid_t> -> CUInt -> CUInt -> IO <herr_t>
+
+-- |Retrieves the symbol table B-tree 1/2 rank (IK) and the
+-- symbol table leaf node 1/2 size (LK).  See 'h5p_set_sym_k' for
+-- details. Either (or even both) IK and LK may be null
+-- pointers.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_sym_k(hid_t plist_id, unsigned *ik/*out*/, unsigned *lk/*out*/);
+#ccall H5Pget_sym_k, <hid_t> -> Out CUInt -> Out CUInt -> IO <herr_t>
+
+-- |IK is one half the rank of a tree that stores chunked raw
+-- data.  On average, such a tree will be 75% full, or have an
+-- average rank of 1.5 times the value of IK.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_istore_k(hid_t plist_id, unsigned ik);
+#ccall H5Pset_istore_k, <hid_t> -> CUInt -> IO <herr_t>
+
+-- |Queries the 1/2 rank of an indexed storage B-tree.  See
+-- 'h5p_set_istore_k' for details.  The argument IK may be the
+-- null pointer.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_istore_k(hid_t plist_id, unsigned *ik/*out*/);
+#ccall H5Pget_istore_k, <hid_t> -> Out CUInt -> IO <herr_t>
+
+-- |Set the number of Shared Object Header Message (SOHM)
+-- indexes specified in this property list.  If this is
+-- zero then shared object header messages are disabled
+-- for this file.
+--
+-- These indexes can then be configured with
+-- H5Pset_shared_mesg_index.  'h5p_set_shared_mesg_phase_chage'
+-- also controls settings for all indexes.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_shared_mesg_nindexes(hid_t plist_id, unsigned nindexes);
+#ccall H5Pset_shared_mesg_nindexes, <hid_t> -> CUInt -> IO <herr_t>
+
+-- |Get the number of Shared Object Header Message (SOHM)
+-- indexes specified in this property list.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_shared_mesg_nindexes(hid_t plist_id, unsigned *nindexes);
+#ccall H5Pget_shared_mesg_nindexes, <hid_t> -> Out CUInt -> IO <herr_t>
+
+-- |Configure a given shared message index.  Sets the types of
+-- message that should be stored in this index and the minimum
+-- size of a message in the index.
+--
+-- 'index_num' is zero-indexed (in a file with three indexes,
+-- they are numbered 0, 1, and 2).
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_shared_mesg_index(hid_t plist_id, unsigned index_num, unsigned mesg_type_flags, unsigned min_mesg_size);
+#ccall H5Pset_shared_mesg_index, <hid_t> -> CUInt -> CUInt -> CUInt -> IO <herr_t>
+
+-- |Get information about a given shared message index.  Gets
+-- the types of message that are stored in the index and the
+-- minimum size of a message in the index.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_shared_mesg_index(hid_t plist_id, unsigned index_num, unsigned *mesg_type_flags, unsigned *min_mesg_size);
+#ccall H5Pget_shared_mesg_index, <hid_t> -> CUInt -> Out CUInt -> Out CUInt -> IO <herr_t>
+
+-- |Sets the cutoff values for indexes storing shared object
+-- header messages in this file.  If more than 'max_list'
+-- messages are in an index, that index will become a B-tree.
+-- Likewise, a B-tree index containing fewer than 'min_btree'
+-- messages will be converted to a list.
+--
+-- If the 'max_list' is zero then SOHM indexes in this file will
+-- never be lists but will be created as B-trees.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_shared_mesg_phase_change(hid_t plist_id, unsigned max_list, unsigned min_btree);
+#ccall H5Pset_shared_mesg_phase_change, <hid_t> -> CUInt -> CUInt -> IO <herr_t>
+
+-- |Gets the maximum size of a SOHM list index before it becomes
+-- a B-tree.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_shared_mesg_phase_change(hid_t plist_id, unsigned *max_list, unsigned *min_btree);
+#ccall H5Pget_shared_mesg_phase_change, <hid_t> -> Out CUInt -> Out CUInt -> IO <herr_t>
+
+#if H5_VERSION_GE(1,10,0)
+
+-- > H5_DLL herr_t H5Pset_file_space(hid_t plist_id, H5F_file_space_type_t strategy, hsize_t threshold);
+#ccall H5Pset_file_space, <hid_t> -> H5F_file_space_type_t -> <hsize_t> -> IO <herr_t>
+
+-- > H5_DLL herr_t H5Pget_file_space(hid_t plist_id, H5F_file_space_type_t *strategy, hsize_t *threshold);
+#ccall H5Pget_file_space, <hid_t> -> Out H5F_file_space_type_t -> Out <hsize_t> -> IO <herr_t>
+
+#endif
+
+-- * File access property list (FAPL) routines
+
+-- |Sets the alignment properties of a file access property list
+-- so that any file object >= 'threshold' bytes will be aligned on
+-- an address which is a multiple of 'alignment'.  The addresses
+-- are relative to the end of the user block; the alignment is
+-- calculated by subtracting the user block size from the
+-- absolute file address and then adjusting the address to be a
+-- multiple of 'alignment'.
+--
+-- Default values for 'threshold' and 'alignment' are one, implying
+-- no alignment.  Generally the default values will result in
+-- the best performance for single-process access to the file.
+-- For MPI-IO and other parallel systems, choose an alignment
+-- which is a multiple of the disk block size.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_alignment(hid_t fapl_id, hsize_t threshold,
+-- >     hsize_t alignment);
+#ccall H5Pset_alignment, <hid_t> -> <hsize_t> -> <hsize_t> -> IO <herr_t>
+
+-- |Returns the current settings for alignment properties from a
+-- file access property list.  The 'threshold' and/or 'alignment'
+-- pointers may be null pointers.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_alignment(hid_t fapl_id, hsize_t *threshold/*out*/,
+-- >     hsize_t *alignment/*out*/);
+#ccall H5Pget_alignment, <hid_t> -> Out <hsize_t> -> Out <hsize_t> -> IO <herr_t>
+
+-- |Set the file driver ('driver_id') for a file access or data
+-- transfer property list ('plist_id') and supply an optional
+-- struct containing the driver-specific properites
+-- ('driver_info').  The driver properties will be copied into the
+-- property list and the reference count on the driver will be
+-- incremented, allowing the caller to close the driver ID but
+-- still use the property list.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_driver(hid_t plist_id, hid_t driver_id,
+-- >         const void *driver_info);
+#ccall H5Pset_driver, <hid_t> -> <hid_t> -> In a -> IO <herr_t>
+
+-- |Return the ID of the low-level file driver.  'plist_id' should
+-- be a file access property list or data transfer propert list.
+--
+-- Returns a low-level driver ID which is the same ID
+-- used when the driver was set for the property
+-- list. The driver ID is only valid as long as
+-- the file driver remains registered.
+--
+-- Returns a negative value on failure.
+--
+-- > hid_t H5Pget_driver(hid_t plist_id);
+#ccall H5Pget_driver, <hid_t> -> IO <hid_t>
+
+-- |Returns a pointer directly to the file driver-specific
+-- information of a file access or data transfer property list.
+--
+-- On success, returns a pointer to *uncopied* driver specific data
+-- structure if any.
+--
+-- On failure, returns NULL. Null is also returned if the driver has
+-- not registered any driver-specific properties although no error is
+-- pushed on the stack in this case.
+--
+-- > void *H5Pget_driver_info(hid_t plist_id);
+#ccall H5Pget_driver_info, <hid_t> -> IO (Ptr a)
+
+-- |Set offset for family driver.  This file access property
+-- list will be passed to H5Fget_vfd_handle or 'h5fd_get_vfd_handle'
+-- to retrieve VFD file handle.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_family_offset(hid_t fapl_id, hsize_t offset);
+#ccall H5Pset_family_offset, <hid_t> -> <hsize_t> -> IO <herr_t>
+
+-- |Get offset for family driver.  This file access property
+-- list will be passed to H5Fget_vfd_handle or 'h5fd_get_vfd_handle'
+-- to retrieve VFD file handle.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_family_offset(hid_t fapl_id, hsize_t *offset);
+#ccall H5Pget_family_offset, <hid_t> -> Out <hsize_t> -> IO <herr_t>
+
+-- |Set data type for multi driver.  This file access property
+-- list will be passed to 'h5f_get_vfd_handle' or 'h5fd_get_vfd_handle'
+-- to retrieve VFD file handle.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_multi_type(hid_t fapl_id, H5FD_mem_t type);
+#ccall H5Pset_multi_type, <hid_t> -> <H5FD_mem_t> -> IO <herr_t>
+
+-- |Get data type for multi driver.  This file access property
+-- list will be passed to H5Fget_vfd_handle or 'h5fd_get_vfd_handle'
+-- to retrieve VFD file handle.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_multi_type(hid_t fapl_id, H5FD_mem_t *type);
+#ccall H5Pget_multi_type, <hid_t> -> Out <H5FD_mem_t> -> IO <herr_t>
+
+-- |Set the number of objects in the meta data cache and the
+-- maximum number of chunks and bytes in the raw data chunk
+-- cache.
+--
+-- The 'rdcc_w0' value should be between 0 and 1 inclusive and
+-- indicates how much chunks that have been fully read or fully
+-- written are favored for preemption.  A value of zero means
+-- fully read or written chunks are treated no differently than
+-- other chunks (the preemption is strictly LRU) while a value
+-- of one means fully read chunks are always preempted before
+-- other chunks.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_cache(hid_t plist_id, int mdc_nelmts,
+-- >        size_t rdcc_nslots, size_t rdcc_nbytes,
+-- >        double rdcc_w0);
+#ccall H5Pset_cache, <hid_t> -> CInt -> <size_t> -> <size_t> -> CDouble -> IO <herr_t>
+
+-- |Retrieves the maximum possible number of elements in the meta
+-- data cache and the maximum possible number of elements and
+-- bytes and the 'rdcc_w0' value in the raw data chunk cache.  Any
+-- (or all) arguments may be null pointers in which case the
+-- corresponding datum is not returned.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_cache(hid_t plist_id,
+-- >        int *mdc_nelmts, /* out */
+-- >        size_t *rdcc_nslots/*out*/,
+-- >        size_t *rdcc_nbytes/*out*/, double *rdcc_w0);
+#ccall H5Pget_cache, <hid_t> -> Out CInt -> Out <size_t> -> Out <size_t> -> Out CDouble -> IO <herr_t>
+
+-- |Set the initial metadata cache resize configuration in the
+-- target FAPL.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_mdc_config(hid_t    plist_id,
+-- >        H5AC_cache_config_t * config_ptr);
+#ccall H5Pset_mdc_config, <hid_t> -> In <H5AC_cache_config_t> -> IO <herr_t>
+
+-- |Retrieve the metadata cache initial resize configuration
+-- from the target FAPL.
+--
+-- Observe that the function will fail if 'config_ptr' is
+-- NULL, or if 'config_ptr'->'version' specifies an unknown
+-- version of 'H5AC_cache_config_t'.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_mdc_config(hid_t     plist_id,
+-- >        H5AC_cache_config_t * config_ptr);	/* out */
+#ccall H5Pget_mdc_config, <hid_t> -> Out <H5AC_cache_config_t> -> IO <herr_t>
+
+-- |Sets the flag for garbage collecting references for the file.
+-- Dataset region references (and other reference types
+-- probably) use space in the file heap.  If garbage collection
+-- is on and the user passes in an uninitialized value in a
+-- reference structure, the heap might get corrupted.  When
+-- garbage collection is off however and the user re-uses a
+-- reference, the previous heap block will be orphaned and not
+-- returned to the free heap space.  When garbage collection is
+-- on, the user must initialize the reference structures to 0 or
+-- risk heap corruption.
+--
+-- Default value for garbage collecting references is off, just
+-- to be on the safe side.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_gc_references(hid_t fapl_id, unsigned gc_ref);
+#ccall H5Pset_gc_references, <hid_t> -> CUInt -> IO <herr_t>
+
+-- |Returns the current setting for the garbage collection
+-- references property from a file access property list.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_gc_references(hid_t fapl_id, unsigned *gc_ref/*out*/);
+#ccall H5Pget_gc_references, <hid_t> -> Out CUInt -> IO <herr_t>
+
+-- |Sets the degree for the file close behavior.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_fclose_degree(hid_t fapl_id, H5F_close_degree_t degree);
+#ccall H5Pset_fclose_degree, <hid_t> -> <H5F_close_degree_t> -> IO <herr_t>
+
+-- |Gets the degree for the file close behavior.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_fclose_degree(hid_t fapl_id, H5F_close_degree_t *degree);
+#ccall H5Pget_fclose_degree, <hid_t> -> Out <H5F_close_degree_t> -> IO <herr_t>
+
+-- |Sets the minimum size of metadata block allocations when
+-- the 'h5fd_FEAT_AGGREGATE_METADATA' is set by a VFL driver.
+-- Each \"raw\" metadata block is allocated to be this size and then
+-- specific pieces of metadata (object headers, local heaps, B-trees, etc)
+-- are sub-allocated from this block.
+--
+-- The default value is set to 2048 (bytes), indicating that metadata
+-- will be attempted to be bunched together in (at least) 2K blocks in
+-- the file.  Setting the value to 0 with this API function will
+-- turn off the metadata aggregation, even if the VFL driver attempts to
+-- use that strategy.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_meta_block_size(hid_t fapl_id, hsize_t size);
+#ccall H5Pset_meta_block_size, <hid_t> -> <hsize_t> -> IO <herr_t>
+
+-- |Returns the current settings for the metadata block allocation
+-- property from a file access property list.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_meta_block_size(hid_t fapl_id, hsize_t *size/*out*/);
+#ccall H5Pget_meta_block_size, <hid_t> -> Out <hsize_t> -> IO <herr_t>
+
+-- |Sets the maximum size of the data seive buffer used for file
+-- drivers which are capable of using data sieving.  The data sieve
+-- buffer is used when performing I/O on datasets in the file.  Using a
+-- buffer which is large anough to hold several pieces of the dataset
+-- being read in for hyperslab selections boosts performance by quite a
+-- bit.
+--
+-- The default value is set to 64KB, indicating that file I/O for raw data
+-- reads and writes will occur in at least 64KB blocks.
+-- Setting the value to 0 with this API function will turn off the
+-- data sieving, even if the VFL driver attempts to use that strategy.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_sieve_buf_size(hid_t fapl_id, size_t size);
+#ccall H5Pset_sieve_buf_size, <hid_t> -> <size_t> -> IO <herr_t>
+
+-- |Returns the current settings for the data sieve buffer size
+-- property from a file access property list.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_sieve_buf_size(hid_t fapl_id, size_t *size/*out*/);
+#ccall H5Pget_sieve_buf_size, <hid_t> -> Out <size_t> -> IO <herr_t>
+
+-- |Sets the minimum size of \"small\" raw data block allocations
+-- when the 'h5fd_FEAT_AGGREGATE_SMALLDATA' is set by a VFL driver.
+-- Each \"small\" raw data block is allocated to be this size and then
+-- pieces of raw data which are small enough to fit are sub-allocated from
+-- this block.
+--
+-- The default value is set to 2048 (bytes), indicating that raw data
+-- smaller than this value will be attempted to be bunched together in (at
+-- least) 2K blocks in the file.  Setting the value to 0 with this API
+-- function will turn off the \"small\" raw data aggregation, even if the
+-- VFL driver attempts to use that strategy.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_small_data_block_size(hid_t fapl_id, hsize_t size);
+#ccall H5Pset_small_data_block_size, <hid_t> -> <hsize_t> -> IO <herr_t>
+
+-- |Returns the current settings for the \"small\" raw data block
+-- allocation property from a file access property list.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_small_data_block_size(hid_t fapl_id, hsize_t *size/*out*/);
+#ccall H5Pget_small_data_block_size, <hid_t> -> Out <hsize_t> -> IO <herr_t>
+
+-- |Indicates which versions of the file format the library should
+-- use when creating objects.  'low' is the earliest version of the HDF5
+-- library that is guaranteed to be able to access the objects created
+-- (the format of some objects in an HDF5 file may not have changed between
+-- versions of the HDF5 library, possibly allowing earlier versions of the
+-- HDF5 library to access those objects) and 'high' is the latest version
+-- of the library required to access the objects created (later versions
+-- of the HDF5 library will also be able to access those objects).
+--
+-- 'low' is used to require that objects use a more modern format and 'high'
+-- is used to restrict objects from using a more modern format.
+--
+-- The special values of 'h5f_FORMAT_EARLIEST' and 'h5f_FORMAT_LATEST' can be
+-- used in the following manner:  Setting 'low' and 'high' to 'h5f_FORMAT_LATEST'
+-- will produce files whose objects use the latest version of the file
+-- format available in the current HDF5 library for each object created.
+-- Setting 'low' and 'high' to 'h5f_FORMAT_EARLIEST' will produce files that that
+-- always require the use of the earliest version of the file format for
+-- each object created. [NOTE!  'low'='high'='h5f_FORMAT_EARLIEST' is not
+-- implemented as of version 1.8.0 and setting 'low' and 'high' to
+-- 'h5f_FORMAT_EARLIEST' will produce an error currently].
+--
+-- Currently, the only two valid combinations for this routine are:
+-- 'low' = 'h5f_FORMAT_EARLIEST' and 'high' = 'h5f_FORMAT_LATEST' (the default
+-- setting, which creates objects with the ealiest version possible for
+-- each object, but no upper limit on the version allowed to be created if
+-- a newer version of an object's format is required to support a feature
+-- requested with an HDF5 library API routine), and 'low' = 'h5f_FORMAT_LATEST'
+-- and 'high' = 'h5f_FORMAT_LATEST' (which is described above).
+--
+-- The 'low' and 'high' values set with this routine at imposed with each
+-- HDF5 library API call that creates objects in the file.  API calls that
+-- would violate the 'low' or 'high' format bound will fail.
+--
+-- Setting the 'low' and 'high' values will not affect reading / writing existing
+-- objects, only the creation of new objects.
+--
+-- Note:  Eventually we want to add more values to the 'H5F_libver_t'
+-- enumerated type that indicate library release values where the file
+-- format was changed (like 'h5f_FORMAT_1_2_0' for the file format changes
+-- in the 1.2.x release branch and possily even 'h5f_FORMAT_1_4_2' for
+-- a change mid-way through the 1.4.x release branch, etc).
+--
+-- Adding more values will allow applications to make settings like the
+-- following:
+--
+-- ['low' = 'h5f_FORMAT_EARLIEST', 'high' = 'h5f_FORMAT_1_2_0']
+--      Create objects with the earliest possible format and don't allow
+--      any objects to be created that require a library version greater
+--      than 1.2.x (This is the \"make certain that \<application\> linked
+--      with v1.2.x of the library can read the file produced\" use case)
+--
+-- ['low' = 'h5f_FORMAT_1_4_2', 'high' = 'h5f_FORMAT_LATEST']
+--      Create objects with at least the version of their format that
+--      the 1.4.2 library uses and allow any later version of the object's
+--      format necessary to represent features used.
+--      (This is the \"make certain to take advantage of \<new feature\>
+--      in the file format\" use case (maybe \<new feature\> is smaller
+--      or scales better than an ealier version, which would otherwise
+--      be used))
+--
+-- ['low' = 'h5f_FORMAT_1_2_0', 'high' = 'h5f_FORMAT_1_6_0']
+--      Creates objects with at least the version of their format that
+--      the 1.2.x library uses and don't allow any objects to be created
+--      that require a library version greater than 1.6.x.
+--      (Not certain of a particular use case for these settings,
+--      although its probably just the logical combination of the
+--      previous two; it just falls out as possible/logical (if it turns
+--      out to be hard to implement in some way, we can always disallow
+--      it))
+--
+-- Note #2:  We talked about whether to include enum values for only library
+-- versions where the format changed and decided it would be less confusing
+-- for application developers if we include enum values for _all_ library
+-- releases and then map down to the previous actual library release which
+-- had a format change.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_libver_bounds(hid_t plist_id, H5F_libver_t low,
+-- >     H5F_libver_t high);
+#ccall H5Pset_libver_bounds, <hid_t> -> <H5F_libver_t> -> <H5F_libver_t> -> IO <herr_t>
+
+-- |Returns the current settings for the library version format bounds
+-- from a file access property list.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_libver_bounds(hid_t plist_id, H5F_libver_t *low,
+-- >     H5F_libver_t *high);
+#ccall H5Pget_libver_bounds, <hid_t> -> Out H5F_libver_t -> Out H5F_libver_t -> IO <herr_t>
+
+#if H5_VERSION_GE(1,8,7)
+
+-- |Sets the number of files opened through external links
+-- from the file associated with this fapl to be held open
+-- in that file's external file cache.  When the maximum
+-- number of files is reached, the least recently used file
+-- is closed (unless it is opened from somewhere else).
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_elink_file_cache_size(hid_t plist_id, unsigned efc_size);
+#ccall H5Pset_elink_file_cache_size, <hid_t> -> CUInt -> IO <herr_t>
+
+-- |Gets the number of files opened through external links
+-- from the file associated with this fapl to be held open
+-- in that file's external file cache.  When the maximum
+-- number of files is reached, the least recently used file
+-- is closed (unless it is opened from somewhere else).
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_elink_file_cache_size(hid_t plist_id, unsigned *efc_size);
+#ccall H5Pget_elink_file_cache_size, <hid_t> -> Out CUInt -> IO <herr_t>
+
+#endif
+
+#if H5_VERSION_GE(1,8,9)
+
+-- |Sets the initial file image. Some file drivers can initialize
+-- the starting data in a file from a buffer.
+--
+-- Returns non-negative on success, negative on failure
+--
+-- > herr_t H5Pset_file_image(hid_t fapl_id, void *buf_ptr, size_t buf_len);
+#ccall H5Pset_file_image, <hid_t> -> Ptr a -> <size_t> -> IO <herr_t>
+
+-- |If the file image exists and buf_ptr_ptr is not NULL,
+-- allocate a buffer of the correct size, copy the image into
+-- the new buffer, and return the buffer to the caller in
+-- *buf_ptr_ptr.  Do this using the file image callbacks
+-- if defined.
+--
+-- NB: It is the responsibility of the caller to free the
+-- buffer whose address is returned in *buf_ptr_ptr.  Do
+-- this using free if the file image callbacks are not
+-- defined, or with whatever method is appropriate if
+-- the callbacks are defined.
+--
+-- If buf_ptr_ptr is not NULL, and no image exists, set
+-- *buf_ptr_ptr to NULL.
+--
+-- If buf_len_ptr is not NULL, set *buf_len_ptr equal
+-- to the length of the file image if it exists, and
+-- to 0 if it does not.
+--
+-- Returns non-negative on success, negative on failure
+--
+-- > herr_t H5Pget_file_image(hid_t fapl_id, void **buf_ptr_ptr, size_t *buf_len_ptr);
+#ccall H5Pget_file_image, <hid_t> -> Ptr (Ptr a) -> <size_t> -> IO <herr_t>
+
+-- |Sets the callbacks for file images. Some file drivers allow
+-- the use of user-defined callbacks for allocating, freeing and
+-- copying the drivers internal buffer, potentially allowing a
+-- clever user to do optimizations such as avoiding large mallocs
+-- and memcpys or to perform detailed logging.
+--
+-- Returns non-negative on success, negative on failure
+--
+-- > herr_t H5Pset_file_image_callbacks(hid_t fapl_id,
+-- >    H5FD_file_image_callbacks_t *callbacks_ptr);
+#ccall H5Pset_file_image_callbacks, <hid_t> -> In H5FD_file_image_callbacks_t -> IO <herr_t>
+
+-- |Sets the callbacks for file images. Some file drivers allow
+-- the use of user-defined callbacks for allocating, freeing and
+-- copying the drivers internal buffer, potentially allowing a
+-- clever user to do optimizations such as avoiding large mallocs
+--
+-- Returns non-negative on success, negative on failure
+--
+-- > herr_t H5Pget_file_image_callbacks(hid_t fapl_id,
+-- >    H5FD_file_image_callbacks_t *callbacks_ptr);
+#ccall H5Pget_file_image_callbacks, <hid_t> -> Out H5FD_file_image_callbacks_t -> IO <herr_t>
+
+#endif
+
+#if H5_VERSION_GE(1,10,0)
+
+-- > herr_t H5Pset_metadata_read_attempts(hid_t plist_id, unsigned attempts);
+#ccall H5Pget_metadata_read_attempts, <hid_t> -> Out CUInt -> IO <herr_t>
+-- > herr_t H5Pset_object_flush_cb(hid_t plist_id, H5F_flush_cb_t func, void *udata);
+#ccall H5Pset_object_flush_cb , <hid_t> -> H5F_flush_cb_t a -> Out a -> IO <herr_t>
+-- > herr_t H5Pget_object_flush_cb(hid_t plist_id, H5F_flush_cb_t *func, void **udata);
+#ccall H5Pget_object_flush_cb, <hid_t> -> H5F_flush_cb_t a -> Out (Out a) -> IO <herr_t>
+-- > herr_t H5Pset_mdc_log_options(hid_t plist_id, hbool_t is_enabled, const char *location, hbool_t start_on_access);
+#ccall H5Pset_mdc_log_options, <hid_t> -> <hbool_t> -> CString -> <hbool_t> -> IO <herr_t>
+-- > herr_t H5Pget_mdc_log_options(hid_t plist_id, hbool_t *is_enabled, char *location, size_t *location_size, hbool_t *start_on_access);
+#ccall H5Pget_mdc_log_options, <hid_t> -> Out <hbool_t> -> Out CString -> Out <size_t> -> Out <hbool_t> -> IO <herr_t>
+
+#ifdef H5_HAVE_PARALLEL
+-- > herr_t H5Pset_coll_metadata_read(hid_t plist_id, hbool_t is_collective);
+#ccall H5Pset_all_coll_metadata_ops, <hid_t> -> <hbool_t> -> IO <herr_t>
+-- > herr_t H5Pget_coll_metadata_read(hid_t plist_id, hbool_t *is_collective);
+#ccall H5Pget_all_coll_metadata_ops, <hid_t> -> Out <hbool_t> -> IO <herr_t>
+-- > herr_t H5Pset_coll_metadata_write(hid_t plist_id, hbool_t is_collective);
+#ccall H5Pset_coll_metadata_write, <hid_t> -> <hbool_t> -> IO <herr_t>
+-- > herr_t H5Pget_coll_metadata_write(hid_t plist_id, hbool_t *is_collective);
+#ccall H5Pget_coll_metadata_write, <hid_t> -> Out <hbool_t> -> IO <herr_t>
+#endif /* H5_HAVE_PARALLEL */
+
+#endif
+
+-- * Dataset creation property list (DCPL) routines
+
+-- |Sets the layout of raw data in the file.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_layout(hid_t plist_id, H5D_layout_t layout);
+#ccall H5Pset_layout, <hid_t> -> <H5D_layout_t> -> IO <herr_t>
+
+-- |Retrieves layout type of a dataset creation property list.
+--
+-- Returns the layout type on success, negative on failure.
+--
+-- > H5D_layout_t H5Pget_layout(hid_t plist_id);
+#ccall H5Pget_layout, <hid_t> -> IO <H5D_layout_t>
+
+-- |Sets the number of dimensions and the size of each chunk to
+-- the values specified.  The dimensionality of the chunk should
+-- match the dimensionality of the dataspace.
+--
+-- As a side effect, the layout method is changed to
+-- 'h5d_CHUNKED'.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_chunk(hid_t plist_id, int ndims, const hsize_t dim[/*ndims*/]);
+#ccall H5Pset_chunk, <hid_t> -> CInt -> InArray <hsize_t> -> IO <herr_t>
+
+-- |Retrieves the chunk size of chunked layout.  The chunk
+-- dimensionality is returned and the chunk size in each
+-- dimension is returned through the DIM argument.  At most
+-- 'max_ndims' elements of 'dim' will be initialized.
+--
+-- Returns a negative value on failure.
+--
+-- > int H5Pget_chunk(hid_t plist_id, int max_ndims, hsize_t dim[]/*out*/);
+#ccall H5Pget_chunk, <hid_t> -> CInt -> OutArray <hsize_t> -> IO CInt
+
+#if H5_VERSION_GE(1,10,0)
+-- > herr_t H5Pset_virtual(hid_t dcpl_id, hid_t vspace_id,
+-- >     const char *src_file_name, const char *src_dset_name, hid_t src_space_id);
+#ccall H5Pset_virtual, <hid_t> -> <hid_t> -> CString -> CString -> <hid_t> -> IO <herr_t>
+-- > herr_t H5Pget_virtual_count(hid_t dcpl_id, size_t *count/*out*/);
+#ccall H5Pget_virtual_count, <hid_t> -> Out <size_t> -> IO <herr_t>
+-- > hid_t H5Pget_virtual_vspace(hid_t dcpl_id, size_t index);
+#ccall H5Pget_virtual_vspace, <hid_t> -> <size_t> -> IO <hid_t>
+-- > hid_t H5Pget_virtual_srcspace(hid_t dcpl_id, size_t index);
+#ccall H5Pget_virtual_srcspace, <hid_t> -> <size_t> -> IO <hid_t>
+-- > ssize_t H5Pget_virtual_filename(hid_t dcpl_id, size_t index,
+-- >     char *name/*out*/, size_t size);
+#ccall H5Pget_virtual_filename, <hid_t> -> <size_t> -> Out CString -> <size_t> -> IO <ssize_t>
+-- > ssize_t H5Pget_virtual_dsetname(hid_t dcpl_id, size_t index,
+-- >     char *name/*out*/, size_t size);
+#ccall H5Pget_virtual_dsetname, <hid_t> -> <size_t> -> Out CString -> <size_t> -> IO <ssize_t>
+
+#endif
+
+-- |Adds an external file to the list of external files. 'plist_id'
+-- should be an object ID for a dataset creation property list.
+-- 'name' is the name of an external file, 'offset' is the location
+-- where the data starts in that file, and 'size' is the number of
+-- bytes reserved in the file for the data.
+--
+-- If a dataset is split across multiple files then the files
+-- should be defined in order. The total size of the dataset is
+-- the sum of the 'size' arguments for all the external files.  If
+-- the total size is larger than the size of a dataset then the
+-- dataset can be extended (provided the dataspace also allows
+-- the extending).
+--
+-- > herr_t H5Pset_external(hid_t plist_id, const char *name, off_t offset,
+-- >           hsize_t size);
+#ccall H5Pset_external, <hid_t> -> CString -> <off_t> -> <hsize_t> -> IO <herr_t>
+
+#if H5_VERSION_GE(1,10,0)
+
+-- > herr_t H5Pset_chunk_opts(hid_t plist_id, unsigned opts);
+#ccall H5Pset_chunk_opts, <hid_t> -> CUInt -> IO <herr_t>
+-- > herr_t H5Pget_chunk_opts(hid_t plist_id, unsigned *opts);
+#ccall H5Pget_chunk_opts, <hid_t> -> Out CUInt -> IO <herr_t>
+
+#endif
+
+-- |Returns the number of external files for this dataset, or negative
+-- on failure.
+--
+-- > int H5Pget_external_count(hid_t plist_id);
+#ccall H5Pget_external_count, <hid_t> -> IO CInt
+
+-- |Returns information about an external file.  External files
+-- are numbered from zero to N-1 where N is the value returned
+-- by 'h5p_get_external_count'.  At most 'name_size' characters are
+-- copied into the 'name' array.  If the external file name is
+-- longer than 'name_size' with the null terminator, then the
+-- return value is not null terminated (similar to strncpy()).
+--
+-- If 'name_size' is zero or 'name' is the null pointer then the
+-- external file name is not returned.  If 'offset' or 'size' are
+-- null pointers then the corresponding information is not
+-- returned.
+--
+-- See Also:  'h5p_set_external'
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_external(hid_t plist_id, unsigned idx, size_t name_size,
+-- >           char *name/*out*/, off_t *offset/*out*/,
+-- >           hsize_t *size/*out*/);
+#ccall H5Pget_external, <hid_t> -> CUInt -> <size_t> -> OutArray CChar -> Out <off_t> -> Out <hsize_t> -> IO <herr_t>
+
+-- |Sets the compression method for a permanent or transient
+-- filter pipeline (depending on whether 'plist_id' is a dataset
+-- creation or transfer property list) to 'h5z_FILTER_SZIP'.
+-- Szip is a special compression package that is said to be good
+-- for scientific data.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_szip(hid_t plist_id, unsigned options_mask, unsigned pixels_per_block);
+#ccall H5Pset_szip, <hid_t> -> CUInt -> CUInt -> IO <herr_t>
+
+-- |Sets the shuffling method for a permanent
+-- filter to 'h5z_FILTER_SHUFFLE'
+-- and bytes of the datatype of the array to be shuffled
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_shuffle(hid_t plist_id);
+#ccall H5Pset_shuffle, <hid_t> -> IO <herr_t>
+
+-- |Sets nbit filter for a dataset creation property list
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_nbit(hid_t plist_id);
+#ccall H5Pset_nbit, <hid_t> -> IO <herr_t>
+
+-- |Sets scaleoffset filter for a dataset creation property list
+-- and user-supplied parameters
+--
+-- Parameters:
+--
+-- [@ scale_factor :: 'CInt' @]
+--   For integer datatypes, this parameter will be
+--   minimum-bits, if this value is set to 0,
+--   scaleoffset filter will calculate the minimum-bits.
+--   For floating-point datatype,
+--   For variable-minimum-bits method, this will be
+--   the decimal precision of the filter,
+--   For fixed-minimum-bits method, this will be
+--   the minimum-bit of the filter.
+--
+-- [@ scale_type :: 'H5Z_SO_scale_type_t' @]
+--  0 for floating-point variable-minimum-bits,
+--  1 for floating-point fixed-minimum-bits,
+--  other values, for integer datatype
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_scaleoffset(hid_t plist_id, H5Z_SO_scale_type_t scale_type, int scale_factor);
+#ccall H5Pset_scaleoffset, <hid_t> -> <H5Z_SO_scale_type_t> -> CInt -> IO <herr_t>
+
+-- |Set the fill value for a dataset creation property list. The
+-- 'value' is interpretted as being of type 'type', which need not
+-- be the same type as the dataset but the library must be able
+-- to convert 'value' to the dataset type when the dataset is
+-- created.  If 'value' is NULL, it will be interpreted as
+-- undefining fill value.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_fill_value(hid_t plist_id, hid_t type_id,
+-- >      const void *value);
+#ccall H5Pset_fill_value, <hid_t> -> <hid_t> -> In a -> IO <herr_t>
+
+-- |Queries the fill value property of a dataset creation
+-- property list.  The fill value is returned through the 'value'
+-- pointer and the memory is allocated by the caller.  The fill
+-- value will be converted from its current datatype to the
+-- specified 'type'.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_fill_value(hid_t plist_id, hid_t type_id,
+-- >      void *value/*out*/);
+#ccall H5Pget_fill_value, <hid_t> -> <hid_t> -> Out a -> IO <herr_t>
+
+-- |Check if fill value is defined.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pfill_value_defined(hid_t plist, H5D_fill_value_t *status);
+#ccall H5Pfill_value_defined, <hid_t> -> Out <H5D_fill_value_t> -> IO <herr_t>
+
+-- |Set space allocation time for dataset during creation.
+-- Valid values are 'h5d_ALLOC_TIME_DEFAULT', 'h5d_ALLOC_TIME_EARLY',
+-- 'h5d_ALLOC_TIME_LATE', 'h5d_ALLOC_TIME_INCR'
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_alloc_time(hid_t plist_id, H5D_alloc_time_t
+-- >    alloc_time);
+#ccall H5Pset_alloc_time, <hid_t> -> <H5D_alloc_time_t> -> IO <herr_t>
+
+-- |Get space allocation time for dataset creation.
+-- Valid values are 'h5d_ALLOC_TIME_DEFAULT', 'h5d_ALLOC_TIME_EARLY',
+-- 'h5d_ALLOC_TIME_LATE', 'h5d_ALLOC_TIME_INCR'
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_alloc_time(hid_t plist_id, H5D_alloc_time_t
+-- >    *alloc_time/*out*/);
+#ccall H5Pget_alloc_time, <hid_t> -> Out H5D_alloc_time_t -> IO <herr_t>
+
+-- |Set fill value writing time for dataset.  Valid values are
+-- 'h5d_FILL_TIME_ALLOC' and 'h5d_FILL_TIME_NEVER'.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_fill_time(hid_t plist_id, H5D_fill_time_t fill_time);
+#ccall H5Pset_fill_time, <hid_t> -> <H5D_fill_time_t> -> IO <herr_t>
+
+-- |Get fill value writing time.  Valid values are 'h5d_NEVER'
+-- and 'h5d_ALLOC'.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_fill_time(hid_t plist_id, H5D_fill_time_t
+-- >    *fill_time/*out*/);
+#ccall H5Pget_fill_time, <hid_t> -> Out <H5D_fill_time_t> -> IO <herr_t>
+
+
+#if H5_VERSION_GE(1,8,3)
+
+-- * Dataset access property list (DAPL) routines
+
+-- |Set the number of objects in the meta data cache and the
+-- maximum number of chunks and bytes in the raw data chunk cache.
+-- Once set, these values will override the values in the file access
+-- property list.  Each of these values can be individually unset
+-- (or not set at all) by passing the macros:
+-- 'h5d_CHUNK_CACHE_NCHUNKS_DEFAULT',
+-- 'h5d_CHUNK_CACHE_NSLOTS_DEFAULT', and/or
+-- 'h5d_CHUNK_CACHE_W0_DEFAULT'
+-- as appropriate.
+--
+-- The 'rdcc_w0' value should be between 0 and 1 inclusive and
+-- indicates how much chunks that have been fully read or fully
+-- written are favored for preemption.  A value of zero means
+-- fully read or written chunks are treated no differently than
+-- other chunks (the preemption is strictly LRU) while a value
+-- of one means fully read chunks are always preempted before
+-- other chunks.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_chunk_cache(hid_t dapl_id, size_t rdcc_nslots,
+-- >        size_t rdcc_nbytes, double rdcc_w0);
+#ccall H5Pset_chunk_cache, <hid_t> -> <size_t> -> <size_t> -> CDouble -> IO <herr_t>
+
+-- |Retrieves the maximum possible number of elements in the meta
+-- data cache and the maximum possible number of elements and
+-- bytes and the 'rdcc_w0' value in the raw data chunk cache.  Any
+-- (or all) arguments may be null pointers in which case the
+-- corresponding datum is not returned.  If these properties have
+-- not been set on this property list, the default values for a
+-- file access property list are returned.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_chunk_cache(hid_t dapl_id,
+-- >        size_t *rdcc_nslots/*out*/,
+-- >        size_t *rdcc_nbytes/*out*/,
+-- >        double *rdcc_w0/*out*/);
+#ccall H5Pget_chunk_cache, <hid_t> -> Out <size_t> -> Out <size_t> -> Out CDouble -> IO <herr_t>
+
+#endif
+
+#if H5_VERSION_GE(1,10,0)
+
+-- > +H5_DLL herr_t H5Pset_virtual_view(hid_t plist_id, H5D_vds_view_t view);
+#ccall H5Pset_virtual_view, <hid_t> -> H5D_vds_view_t -> IO <herr_t>
+-- > +H5_DLL herr_t H5Pget_virtual_view(hid_t plist_id, H5D_vds_view_t *view);
+#ccall H5Pget_virtual_view, <hid_t> -> Out H5D_vds_view_t -> IO <herr_t>
+-- > +H5_DLL herr_t H5Pset_virtual_printf_gap(hid_t plist_id, hsize_t gap_size);
+#ccall H5Pset_virtual_printf_gap, <hid_t> ->  <hsize_t> -> IO <herr_t>
+-- > +H5_DLL herr_t H5Pget_virtual_printf_gap(hid_t plist_id, hsize_t *gap_size);
+#ccall H5Pget_virtual_printf_gap, <hid_t> -> Out <hsize_t> -> IO <herr_t>
+-- > +H5_DLL herr_t H5Pset_append_flush(hid_t plist_id, unsigned ndims,
+-- > +    const hsize_t boundary[], H5D_append_cb_t func, void *udata);
+#ccall H5Pset_append_flush, <hid_t> -> CUInt -> In <hsize_t> -> H5D_append_cb_t a -> In a -> IO <herr_t>
+-- > +H5_DLL herr_t H5Pget_append_flush(hid_t plist_id, unsigned dims,
+-- > +    hsize_t boundary[], H5D_append_cb_t *func, void **udata);
+#ccall H5Pget_append_flush, <hid_t> -> CUInt -> In <hsize_t> -> H5D_append_cb_t a -> Out (Out a) -> IO <herr_t>
+-- > herr_t H5Pset_efile_prefix(hid_t dapl_id, const char* prefix);
+#ccall H5Pset_efile_prefix, <hid_t> -> CString -> IO <herr_t>
+-- > ssize_t H5Pget_efile_prefix(hid_t dapl_id, char* prefix /*out*/, size_t size);
+#ccall H5Pget_efile_prefix, <hid_t> -> Out CString -> <size_t> -> IO <ssize_t>
+
+#endif
+
+-- * Dataset xfer property list (DXPL) routines
+
+-- |Sets data transform expression.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_data_transform(hid_t plist_id, const char* expression);
+#ccall H5Pset_data_transform, <hid_t> -> CString -> IO <herr_t>
+
+-- |Gets data transform expression.
+--
+-- If 'expression' is non-NULL then write up to 'size' bytes into that
+-- buffer and always return the length of the transform name.
+-- Otherwise 'size' is ignored and the function does not store the expression,
+-- just returning the number of characters required to store the expression.
+-- If an error occurs then the buffer pointed to by 'expression' (NULL or non-NULL)
+-- is unchanged and the function returns a negative value.
+-- If a zero is returned for the name's length, then there is no name
+-- associated with the ID.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > ssize_t H5Pget_data_transform(hid_t plist_id, char* expression /*out*/, size_t size);
+#ccall H5Pget_data_transform, <hid_t> -> OutArray CChar -> <size_t> -> IO <ssize_t>
+
+-- |Given a dataset transfer property list, set the maximum size
+-- for the type conversion buffer and background buffer and
+-- optionally supply pointers to application-allocated buffers.
+-- If the buffer size is smaller than the entire amount of data
+-- being transfered between application and file, and a type
+-- conversion buffer or background buffer is required then
+-- strip mining will be used.
+--
+-- If 'tconv' and/or 'bkg' are null pointers then buffers will be
+-- allocated and freed during the data transfer.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_buffer(hid_t plist_id, size_t size, void *tconv,
+-- >         void *bkg);
+#ccall H5Pset_buffer, <hid_t> -> <size_t> -> Ptr a -> Ptr b -> IO <herr_t>
+
+-- |Reads values previously set with 'h5p_set_buffer'.
+--
+-- Returns buffer size on success, 0 on failure.
+--
+-- > size_t H5Pget_buffer(hid_t plist_id, void **tconv/*out*/,
+-- >         void **bkg/*out*/);
+#ccall H5Pget_buffer, <hid_t> -> Out (Ptr a) -> Out (Ptr b) -> IO <size_t>
+
+-- |When reading or writing compound data types and the
+-- destination is partially initialized and the read/write is
+-- intended to initialize the other members, one must set this
+-- property to TRUE.  Otherwise the I/O pipeline treats the
+-- destination datapoints as completely uninitialized.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_preserve(hid_t plist_id, hbool_t status);
+#ccall H5Pset_preserve, <hid_t> -> <hbool_t> -> IO <herr_t>
+
+-- |The inverse of 'h5p_set_preserve'
+--
+-- Returns TRUE or FALSE (C macros) on success, negative on failure.
+--
+-- > int H5Pget_preserve(hid_t plist_id);
+#ccall H5Pget_preserve, <hid_t> -> IO CInt
+
+-- |Enable or disable error-detecting for a dataset reading
+-- process.  This error-detecting algorithm is whichever
+-- user chooses earlier.  This function cannot control
+-- writing process.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_edc_check(hid_t plist_id, H5Z_EDC_t check);
+#ccall H5Pset_edc_check, <hid_t> -> <H5Z_EDC_t> -> IO <herr_t>
+
+-- |
+-- > H5Z_EDC_t H5Pget_edc_check(hid_t plist_id);
+#ccall H5Pget_edc_check, <hid_t> -> IO <H5Z_EDC_t>
+
+-- |Sets user's callback function for dataset transfer property
+-- list.  This callback function defines what user wants to do
+-- if certain filter fails.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_filter_callback(hid_t plist_id, H5Z_filter_func_t func,
+-- >                                      void* op_data);
+#ccall H5Pset_filter_callback, <hid_t> -> H5Z_filter_func_t a b -> InOut b -> IO <herr_t>
+
+-- |Sets B-tree split ratios for a dataset transfer property
+-- list. The split ratios determine what percent of children go
+-- in the first node when a node splits.  The 'left' ratio is
+-- used when the splitting node is the left-most node at its
+-- level in the tree; the 'right' ratio is when the splitting node
+-- is the right-most node at its level; and the 'middle' ratio for
+-- all other cases.  A node which is the only node at its level
+-- in the tree uses the 'right' ratio when it splits.  All ratios
+-- are real numbers between 0 and 1, inclusive.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_btree_ratios(hid_t plist_id, double left, double middle,
+-- >        double right);
+#ccall H5Pset_btree_ratios, <hid_t> -> CDouble -> CDouble -> CDouble -> IO <herr_t>
+
+-- |Queries B-tree split ratios.  See H5Pset_btree_ratios().
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_btree_ratios(hid_t plist_id, double *left/*out*/,
+-- >        double *middle/*out*/,
+-- >        double *right/*out*/);
+#ccall H5Pget_btree_ratios, <hid_t> -> Out CDouble -> Out CDouble -> Out CDouble -> IO <herr_t>
+
+-- |Sets the memory allocate/free pair for VL datatypes.  The
+-- allocation routine is called when data is read into a new
+-- array and the free routine is called when 'h5d_vlen_reclaim' is
+-- called.  The 'alloc_info' and 'free_info' are user parameters
+-- which are passed to the allocation and freeing functions
+-- respectively.  To reset the allocate/free functions to the
+-- default setting of using the system's malloc/free functions,
+-- call this routine with 'alloc_func' and 'free_func' set to NULL.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_vlen_mem_manager(hid_t plist_id,
+-- >        H5MM_allocate_t alloc_func,
+-- >        void *alloc_info, H5MM_free_t free_func,
+-- >        void *free_info);
+#ccall H5Pset_vlen_mem_manager, <hid_t> -> H5MM_allocate_t allocInfo mem -> Ptr allocInfo -> H5MM_free_t freeInfo mem -> Ptr freeInfo -> IO <herr_t>
+
+-- |The inverse of 'h5p_set_vlen_mem_manager'
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_vlen_mem_manager(hid_t plist_id,
+-- >        H5MM_allocate_t *alloc_func,
+-- >        void **alloc_info,
+-- >        H5MM_free_t *free_func,
+-- >        void **free_info);
+#ccall H5Pget_vlen_mem_manager, <hid_t> -> Out (H5MM_allocate_t allocInfo mem) -> Out (Ptr allocInfo) -> Out (H5MM_free_t freeInfo mem) -> Out (Ptr freeInfo) -> IO <herr_t>
+
+-- |Given a dataset transfer property list, set the number of
+-- \"I/O vectors\" (offset and length pairs) which are to be
+-- accumulated in memory before being issued to the lower levels
+-- of the library for reading or writing the actual data.
+-- Increasing the number should give better performance, but use
+-- more memory during hyperslab I/O.  The vector size must be
+-- greater than 1.
+--
+-- The default is to use 1024 vectors for I/O during hyperslab
+-- reading/writing.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_hyper_vector_size(hid_t fapl_id, size_t size);
+#ccall H5Pset_hyper_vector_size, <hid_t> -> <size_t> -> IO <herr_t>
+
+-- |Reads values previously set with 'h5p_set_hyper_vector_size'.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_hyper_vector_size(hid_t fapl_id, size_t *size/*out*/);
+#ccall H5Pget_hyper_vector_size, <hid_t> -> Out <size_t> -> IO <herr_t>
+
+-- |Sets user's callback function for dataset transfer property
+-- list.  This callback function defines what user wants to do
+-- if there's exception during datatype conversion.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_type_conv_cb(hid_t dxpl_id, H5T_conv_except_func_t op, void* operate_data);
+#ccall H5Pset_type_conv_cb, <hid_t> -> H5T_conv_except_func_t a b -> InOut b -> IO <herr_t>
+
+-- |Gets callback function for dataset transfer property
+-- list.  This callback function defines what user wants to do
+-- if there's exception during datatype conversion.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_type_conv_cb(hid_t dxpl_id, H5T_conv_except_func_t *op, void** operate_data);
+#ccall H5Pget_type_conv_cb, <hid_t> -> Out (H5T_conv_except_func_t a b) -> Out (InOut b) -> IO <herr_t>
+
+#ifdef H5_HAVE_PARALLEL
+
+#if H5_VERSION_GE(1,8,8)
+
+-- TODO: docs
+-- > herr_t H5Pget_mpio_actual_chunk_opt_mode(hid_t plist_id, H5D_mpio_actual_chunk_opt_mode_t *actual_chunk_opt_mode);
+#ccall H5Pget_mpio_actual_chunk_opt_mode, <hid_t> -> Out H5D_mpio_actual_chunk_opt_mode_t -> IO <herr_t>
+
+-- > herr_t H5Pget_mpio_actual_io_mode(hid_t plist_id, H5D_mpio_actual_io_mode_t *actual_io_mode);
+#ccall H5Pget_mpio_actual_io_mode, <hid_t> -> Out H5D_mpio_actual_io_mode_t -> IO <herr_t>
+
+#endif
+
+#if H5_VERSION_GE(1,8,10)
+
+-- TODO: ensure ptr sizes match and change Word32 to H5D_mpio_no_collective_cause_t
+-- > herr_t H5Pget_mpio_no_collective_cause(hid_t plist_id, uint32_t *local_no_collective_cause, uint32_t *global_no_collective_cause);
+#ccall H5Pget_mpio_no_collective_cause, <hid_t> -> Out Word32 -> Out Word32 -> IO <herr_t>
+
+#endif
+
+#endif /* H5_HAVE_PARALLEL */
+
+-- * Link creation property list (LCPL) routines
+
+-- |Set 'crt_intmd_group' so that 'h5l_create_*', 'h5o_link', etc.
+-- will create missing groups along the given path \"name\".
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_create_intermediate_group(hid_t plist_id, unsigned crt_intmd);
+#ccall H5Pset_create_intermediate_group, <hid_t> -> CUInt -> IO <herr_t>
+
+-- |Returns the 'crt_intmd_group', which is set to create missing
+-- groups during 'h5o_link', etc.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_create_intermediate_group(hid_t plist_id, unsigned *crt_intmd /*out*/);
+#ccall H5Pget_create_intermediate_group, <hid_t> -> Out CUInt -> IO <herr_t>
+
+-- * Group creation property list (GCPL) routines
+
+-- |Set the \"size hint\" for creating local heaps for a group.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_local_heap_size_hint(hid_t plist_id, size_t size_hint);
+#ccall H5Pset_local_heap_size_hint, <hid_t> -> <size_t> -> IO <herr_t>
+
+-- |Returns the local heap size hint, which is used for creating groups
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_local_heap_size_hint(hid_t plist_id, size_t *size_hint /*out*/);
+#ccall H5Pget_local_heap_size_hint, <hid_t> -> Out <size_t> -> IO <herr_t>
+
+-- |Set the maximum # of links to store \"compactly\" and the
+-- minimum # of links to store \"densely\".  (These should
+-- overlap).
+--
+-- Currently both of these must be updated at the same time.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_link_phase_change(hid_t plist_id, unsigned max_compact, unsigned min_dense);
+#ccall H5Pset_link_phase_change, <hid_t> -> CUInt -> CUInt -> IO <herr_t>
+
+-- |Returns the max. # of compact links & the min. # of dense
+-- links, which are used for storing groups
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_link_phase_change(hid_t plist_id, unsigned *max_compact /*out*/, unsigned *min_dense /*out*/);
+#ccall H5Pget_link_phase_change, <hid_t> -> Out CUInt -> Out CUInt -> IO <herr_t>
+
+-- |Set the estimates for the number of entries and length of each
+-- entry name in a group.
+--
+-- Currently both of these must be updated at the same time.
+--
+-- 'est_num_entries' applies only when the number of entries is less
+-- than the 'max_compact' # of entries (from 'h5p_set_link_phase_change').
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_est_link_info(hid_t plist_id, unsigned est_num_entries, unsigned est_name_len);
+#ccall H5Pset_est_link_info, <hid_t> -> CUInt -> CUInt -> IO <herr_t>
+
+-- |Returns the est. # of links in a group & the est. length of
+-- the name of each link.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_est_link_info(hid_t plist_id, unsigned *est_num_entries /* out */, unsigned *est_name_len /* out */);
+#ccall H5Pget_est_link_info, <hid_t> -> Out CUInt -> Out CUInt -> IO <herr_t>
+
+-- |Set the flags for creation order of links in a group
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_link_creation_order(hid_t plist_id, unsigned crt_order_flags);
+#ccall H5Pset_link_creation_order, <hid_t> -> CUInt -> IO <herr_t>
+
+-- |Returns the flag indicating that creation order is tracked
+-- for links in a group.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_link_creation_order(hid_t plist_id, unsigned *crt_order_flags /* out */);
+#ccall H5Pget_link_creation_order, <hid_t> -> Out CUInt -> IO <herr_t>
+
+-- * String creation property list (STRCPL) routines
+
+-- |Sets the character encoding of the string.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_char_encoding(hid_t plist_id, H5T_cset_t encoding);
+#ccall H5Pset_char_encoding, <hid_t> -> <H5T_cset_t> -> IO <herr_t>
+
+-- |Gets the character encoding of the string.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_char_encoding(hid_t plist_id, H5T_cset_t *encoding /*out*/);
+#ccall H5Pget_char_encoding, <hid_t> -> Out <H5T_cset_t> -> IO <herr_t>
+
+
+-- * Link access property list (LAPL) routines
+
+-- |Set the number of soft or UD link traversals allowed before
+-- the library assumes it has found a cycle and aborts the
+-- traversal.
+--
+-- The limit on soft or UD link traversals is designed to
+-- terminate link traversal if one or more links form a cycle.
+-- However, users may have a file with a legitimate path
+-- formed of a large number of soft or user-defined links.
+-- This property can be used to allow traversal of as many
+-- links as desired.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_nlinks(hid_t plist_id, size_t nlinks);
+#ccall H5Pset_nlinks, <hid_t> -> <size_t> -> IO <herr_t>
+
+-- |Gets the number of soft or user-defined links that can be
+-- traversed before a failure occurs.
+--
+-- Retrieves the current setting for the nlinks property on
+-- the given property list.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_nlinks(hid_t plist_id, size_t *nlinks);
+#ccall H5Pget_nlinks, <hid_t> -> Out <size_t> -> IO <herr_t>
+
+-- |Set a prefix to be applied to the path of any external links
+-- traversed.  The prefix is appended to the filename stored
+-- in the external link.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_elink_prefix(hid_t plist_id, const char *prefix);
+#ccall H5Pset_elink_prefix, <hid_t> -> CString -> IO <herr_t>
+
+-- |Gets the prefix to be applied to any external link
+-- traversals made using this property list.
+--
+-- If the pointer is not NULL, it points to a user-allocated
+-- buffer.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > ssize_t H5Pget_elink_prefix(hid_t plist_id, char *prefix, size_t size);
+#ccall H5Pget_elink_prefix, <hid_t> -> OutArray CChar -> <size_t> -> IO <ssize_t>
+
+#if H5_VERSION_GE(1,8,2)
+
+-- |Gets the file access property list identifier that is
+-- set for link access property.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > hid_t H5Pget_elink_fapl(hid_t lapl_id);
+#ccall H5Pget_elink_fapl, <hid_t> -> IO <hid_t>
+
+-- |Sets the file access property list for link access
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_elink_fapl(hid_t lapl_id, hid_t fapl_id);
+#ccall H5Pset_elink_fapl, <hid_t> -> <hid_t> -> IO <herr_t>
+
+#endif
+
+#if H5_VERSION_GE(1,8,3)
+
+-- |Sets the file access flags to be used when traversing an
+-- external link.  This should be either 'h5f_ACC_RDONLY' or
+-- 'h5f_ACC_RDWR', or 'h5f_ACC_DEFAULT' to unset the value.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_elink_acc_flags(hid_t lapl_id, unsigned flags);
+#ccall H5Pset_elink_acc_flags, <hid_t> -> CUInt -> IO <herr_t>
+
+-- |Gets the file access flags to be used when traversing an
+-- external link.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_elink_acc_flags(hid_t lapl_id, unsigned *flags);
+#ccall H5Pget_elink_acc_flags, <hid_t> -> Out CUInt -> IO <herr_t>
+
+-- |Sets the file access flags to be used when traversing an
+-- external link.  This should be either 'h5f_ACC_RDONLY' or
+-- 'h5f_ACC_RDWR'.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_elink_cb(hid_t lapl_id, H5L_elink_traverse_t func, void *op_data);
+#ccall H5Pset_elink_cb, <hid_t> -> H5L_elink_traverse_t a -> Ptr a -> IO <herr_t>
+
+-- |Gets the file access flags to be used when traversing an
+-- external link.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_elink_cb(hid_t lapl_id, H5L_elink_traverse_t *func, void **op_data);
+#ccall H5Pget_elink_cb, <hid_t> -> Out (H5L_elink_traverse_t a) -> Out (Ptr a) -> IO <herr_t>
+
+#endif
+
+-- * Object copy property list (OCPYPL) routines
+
+-- |Set properties when copying an object (group, dataset, and datatype)
+-- from one location to another
+--
+-- Parameters:
+--
+-- [@ plist_id   :: 'HId_t' @]  Property list to copy object
+--
+-- [@ cpy_option :: 'CUInt' @]  Options to copy object
+--
+-- Possible values for 'cpy_option' include:
+--
+--  ['h5o_COPY_SHALLOW_HIERARCHY_FLAG'] Copy only immediate members
+--
+--  ['h5o_COPY_EXPAND_SOFT_LINK_FLAG' ] Expand soft links into new objects/
+--
+--  ['h5o_COPY_EXPAND_EXT_LINK_FLAG'  ] Expand external links into new objects
+--
+--  ['h5o_COPY_EXPAND_REFERENCE_FLAG' ] Copy objects that are pointed by references
+--
+--  ['h5o_COPY_WITHOUT_ATTR_FLAG'     ] Copy object without copying attributes
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_copy_object(hid_t plist_id, unsigned crt_intmd);
+#ccall H5Pset_copy_object, <hid_t> -> CUInt -> IO <herr_t>
+
+-- |Returns the cpy_option, which is set for 'h5o_copy' for copying objects
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_copy_object(hid_t plist_id, unsigned *crt_intmd /*out*/);
+#ccall H5Pget_copy_object, <hid_t> -> Out CUInt -> IO <herr_t>
+
+#if H5_VERSION_GE(1,8,9)
+
+-- TODO: finish
+
+-- |Adds path to the list of paths to search first in the
+-- target file when merging committed datatypes during H5Ocopy
+-- (i.e. when using the H5O_COPY_MERGE_COMMITTED_DTYPE_FLAG flag
+-- as set by H5Pset_copy_object).  If the source named
+-- dataype is not found in the list of paths created by this
+-- function, the entire file will be searched.
+--
+-- Usage:       H5Padd_merge_committed_dtype_path(plist_id, path)
+--              hid_t plist_id;                 IN: Property list to copy object
+--              const char *path;               IN: Path to add to list
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Padd_merge_committed_dtype_path(hid_t plist_id, const char *path);
+#ccall H5Padd_merge_committed_dtype_path, <hid_t> -> CString -> IO <herr_t>
+
+-- |Frees and clears the list of paths created by
+-- H5Padd_merge_committed_dtype_path.  A new list may then be
+-- created by calling H5Padd_merge_committed_dtype_path again.
+--
+-- Usage:       H5Pfree_merge_committed_dtype_paths(plist_id)
+--              hid_t plist_id;                 IN: Property list to copy object
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pfree_merge_committed_dtype_paths(hid_t plist_id);
+#ccall H5Pfree_merge_committed_dtype_paths, <hid_t> -> IO <herr_t>
+
+-- |Set the callback function when a matching committed datatype is not found
+-- from the list of paths stored in the object copy property list.
+-- H5Ocopy will invoke this callback before searching all committed datatypes
+-- at destination.
+--
+-- Usage:       H5Pset_mcdt_search_cb(plist_id, H5O_mcdt_search_cb_t func, void *op_data)
+--              hid_t plist_id;                 IN: Property list to copy object
+--              H5O_mcdt_search_cb_t func;      IN: The callback function
+--              void *op_data;              IN: The user data
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pset_mcdt_search_cb(hid_t plist_id, H5O_mcdt_search_cb_t func, void *op_data);
+#ccall H5Pset_mcdt_search_cb, <hid_t> -> H5O_mcdt_search_cb_t a -> InOut a -> IO <herr_t>
+
+-- |Retrieves the callback function and user data from the specified
+-- object copy property list.
+--
+-- Usage:       H5Pget_mcdt_search_cb(plist_id, H5O_mcdt_search_cb_t *func, void **op_data)
+--              hid_t plist_id;                 IN: Property list to copy object
+--      H5O_mcdt_search_cb_t *func; OUT: The callback function
+--      void **op_data;         OUT: The user data
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Pget_mcdt_search_cb(hid_t plist_id, H5O_mcdt_search_cb_t *func, void **op_data);
+#ccall H5Pget_mcdt_search_cb, <hid_t> -> Out (H5O_mcdt_search_cb_t a) -> Out (InOut a) -> IO <herr_t>
+
+#endif
+
+#ifndef H5_NO_DEPRECATED_SYMBOLS
+
+-- * Deprecated Constants
+
+-- |We renamed the "root" of the property list class hierarchy
+h5p_NO_CLASS :: HId_t
+h5p_NO_CLASS = h5p_ROOT
+
+-- * Deprecated Functions
+
+-- | Old version of 'h5p_register2'.
+--
+-- > herr_t H5Pregister1(hid_t cls_id, const char *name, size_t size,
+-- >     void *def_value, H5P_prp_create_func_t prp_create,
+-- >     H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get,
+-- >     H5P_prp_delete_func_t prp_del, H5P_prp_copy_func_t prp_copy,
+-- >     H5P_prp_close_func_t prp_close);
+#ccall H5Pregister1, <hid_t> -> CString -> <size_t> -> Ptr a -> H5P_prp_create_func_t a -> H5P_prp_set_func_t a -> H5P_prp_get_func_t a -> H5P_prp_delete_func_t a -> H5P_prp_copy_func_t a -> H5P_prp_close_func_t a -> IO <herr_t>
+
+-- |Old version of 'h5p_insert2'.
+--
+-- > herr_t H5Pinsert1(hid_t plist_id, const char *name, size_t size,
+-- >     void *value, H5P_prp_set_func_t prp_set, H5P_prp_get_func_t prp_get,
+-- >     H5P_prp_delete_func_t prp_delete, H5P_prp_copy_func_t prp_copy,
+-- >     H5P_prp_close_func_t prp_close);
+#ccall H5Pinsert1, <hid_t> -> CString -> <size_t> -> In a -> H5P_prp_set_func_t a -> H5P_prp_get_func_t a -> H5P_prp_delete_func_t a -> H5P_prp_copy_func_t a -> H5P_prp_close_func_t a -> IO <herr_t>
+
+-- |This is the query counterpart of 'h5p_set_filter' and returns
+-- information about a particular filter number in a permanent
+-- or transient pipeline depending on whether 'plist_id' is a
+-- dataset creation or transfer property list.  On input,
+-- 'cd_nelmts' indicates the number of entries in the 'cd_values'
+-- array allocated by the caller while on exit it contains the
+-- number of values defined by the filter.  The 'idx'
+-- should be a value between zero and N-1 as described for
+-- 'h5p_get_nfilters' and the function will return failure if the
+-- filter number is out of range.
+--
+-- > H5Z_filter_t H5Pget_filter1(hid_t plist_id, unsigned filter,
+-- >     unsigned int *flags/*out*/, size_t *cd_nelmts/*out*/,
+-- >     unsigned cd_values[]/*out*/, size_t namelen, char name[]);
+#ccall H5Pget_filter1, <hid_t> -> CUInt -> Out CUInt -> Out <size_t> -> OutArray CUInt -> <size_t> -> Out CChar -> IO <H5Z_filter_t>
+
+-- |This is an additional query counterpart of 'h5p_set_filter' and
+-- returns information about a particular filter in a permanent
+-- or transient pipeline depending on whether 'plist_id' is a
+-- dataset creation or transfer property list.  On input,
+-- 'cd_nelmts' indicates the number of entries in the 'cd_values'
+-- array allocated by the caller while on exit it contains the
+-- number of values defined by the filter.  The ID
+-- should be the filter ID to retrieve the parameters for.  If the
+-- filter is not set for the property list, an error will be returned.
+--
+-- > herr_t H5Pget_filter_by_id1(hid_t plist_id, H5Z_filter_t id,
+-- >     unsigned int *flags/*out*/, size_t *cd_nelmts/*out*/,
+-- >     unsigned cd_values[]/*out*/, size_t namelen, char name[]/*out*/);
+#ccall H5Pget_filter_by_id1, <hid_t> -> <H5Z_filter_t> -> Out CUInt -> Out <size_t> -> OutArray CUInt -> <size_t> -> OutArray CChar -> IO <herr_t>
+
+#endif /* H5_NO_DEPRECATED_SYMBOLS */
diff --git a/src/Bindings/HDF5/Raw/H5R.hsc b/src/Bindings/HDF5/Raw/H5R.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/H5R.hsc
@@ -0,0 +1,183 @@
+#include <bindings.h>
+#include <H5Rpublic.h>
+
+module Bindings.HDF5.Raw.H5R where
+
+import Data.ByteString
+import Data.Int
+import Data.Word
+import Foreign.C.String
+import Foreign.C.Types
+import Foreign.Ptr
+import Foreign.Storable
+
+import Bindings.HDF5.Raw.H5
+import Bindings.HDF5.Raw.H5G
+import Bindings.HDF5.Raw.H5I
+import Bindings.HDF5.Raw.H5O
+
+
+import Foreign.Ptr.Conventions
+
+-- |Reference types allowed
+#newtype H5R_type_t
+
+-- |invalid Reference Type
+#newtype_const H5R_type_t, H5R_BADTYPE
+
+-- |Object reference
+#newtype_const H5R_type_t, H5R_OBJECT
+
+-- |Dataset Region Reference
+#newtype_const H5R_type_t, H5R_DATASET_REGION
+
+-- |Number of reference types
+#num H5R_MAXTYPE
+
+#mangle_ident "H5R_OBJ_REF_BUF_SIZE"
+  :: CSize
+#mangle_ident "H5R_OBJ_REF_BUF_SIZE"
+    = #const H5R_OBJ_REF_BUF_SIZE
+
+#newtype hobj_ref_t
+
+#mangle_ident "H5R_DSET_REG_REF_BUF_SIZE"
+  :: CSize
+#mangle_ident "H5R_DSET_REG_REF_BUF_SIZE"
+    = #const H5R_DSET_REG_REF_BUF_SIZE
+
+-- |Buffer to store heap ID and index
+--
+-- > typedef unsigned char hdset_reg_ref_t[H5R_DSET_REG_REF_BUF_SIZE];
+newtype #mangle_tycon   "hdset_reg_ref_t"
+    =   #mangle_datacon "hdset_reg_ref_t"
+    ByteString
+
+
+-- |Creates a particular type of reference specified with 'ref_type', in the
+-- space pointed to by 'ref'.  The 'loc_id' and 'name' are used to locate the object
+-- pointed to and the 'space_id' is used to choose the region pointed to (for
+-- Dataset Region references).
+--
+-- Parameters:
+--
+-- [@ ref      :: 'Out' a      @] Reference created
+--
+-- [@ loc_id   :: 'HId_t'      @] Location ID used to locate object pointed to
+--
+-- [@ name     :: 'CString'    @] Name of object at location LOC_ID of object pointed to
+--
+-- [@ ref_type :: 'H5R_type_t' @] Type of reference to create
+--
+-- [@ space_id :: 'HId_t'      @] Dataspace ID with selection, used for Dataset Region references.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Rcreate(void *ref, hid_t loc_id, const char *name,
+-- >        H5R_type_t ref_type, hid_t space_id);
+#ccall H5Rcreate, Out a -> <hid_t> -> CString -> <H5R_type_t> -> <hid_t> -> IO <herr_t>
+
+-- |Opens the HDF5 object referenced.  Given a reference to some object,
+-- open that object and return an ID for that object.
+--
+-- Parameters:
+--
+-- [@ id       :: 'HId_t'      @]   Dataset reference object is in or location ID of object that the dataset is located within.
+--
+-- [@ ref_type :: 'H5R_type_t' @]   Type of reference to create
+--
+-- [@ ref      :: 'In' a       @]   Reference to open.
+--
+-- Returns a valid ID on success, negative on failure
+--
+-- > hid_t H5Rdereference(hid_t dataset, H5R_type_t ref_type, const void *ref);
+#if H5_VERSION_GE(1,10,0)
+#ccall H5Rdereference1, <hid_t> -> <H5R_type_t> -> In a -> IO <hid_t>
+-- > hid_t H5Rdereference2(hid_t obj_id, hid_t oapl_id, H5R_type_t ref_type, const void *ref);
+#ccall H5Rdereference2,  <hid_t> -> <hid_t> -> <H5R_type_t> -> In a -> IO <hid_t>
+#else
+#ccall H5Rdereference, <hid_t> -> <H5R_type_t> -> In a -> IO <hid_t>
+#endif
+
+-- |Retrieves a dataspace with the region pointed to selected.
+-- Given a reference to some object, creates a copy of the dataset pointed
+-- to's dataspace and defines a selection in the copy which is the region
+-- pointed to.
+--
+-- Parameters:
+--
+-- [@ id       :: 'HId_t'      @]   Dataset reference object is in or location ID of object that the dataset is located within.
+--
+-- [@ ref_type :: 'H5R_type_t' @]   Type of reference to get region of
+--
+-- [@ ref      :: 'In' a       @]   Reference to open.
+--
+-- Returns a valid ID on success, negative on failure.
+--
+-- > hid_t H5Rget_region(hid_t dataset, H5R_type_t ref_type, const void *ref);
+#ccall H5Rget_region, <hid_t> -> <H5R_type_t> -> In a -> IO <hid_t>
+
+-- |Given a reference to some object, this function retrieves the type of
+-- object pointed to.
+--
+-- Parameters:
+--
+-- [@ id       :: 'HId_t'            @] Dataset reference object is in or location ID of object that the dataset is located within.
+--
+-- [@ ref_type :: 'H5R_type_t'       @] Type of reference to query
+--
+-- [@ ref      :: 'In' a             @] Reference to query.
+--
+-- [@ obj_type :: 'Out' 'H5O_type_t' @] Type of object reference points to
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Rget_obj_type2(hid_t id, H5R_type_t ref_type, const void *_ref,
+-- >     H5O_type_t *obj_type);
+#ccall H5Rget_obj_type2, <hid_t> -> <H5R_type_t> -> In a -> Out <H5O_type_t> -> IO <herr_t>
+
+-- |Given a reference to some object, determine a path to the object
+-- referenced in the file.
+--
+-- Note:  This may not be the only path to that object.
+--
+-- Parameters:
+--
+-- [@ loc_id   :: 'HId_t'       @]  Dataset reference object is in or location ID of object that the dataset is located within.
+--
+-- [@ ref_type :: 'H5R_type_t'  @]  Type of reference
+--
+-- [@ ref      :: 'In' a        @]  Reference to query.
+--
+-- [@ name     :: 'Out' 'CChar' @]  Buffer to place name of object referenced
+--
+-- [@ size     :: 'CSize'       @]  Size of name buffer
+--
+-- Returns non-negative length of the path on success, Negative on failure
+--
+-- > ssize_t H5Rget_name(hid_t loc_id, H5R_type_t ref_type, const void *ref,
+-- >     char *name/*out*/, size_t size);
+#ccall H5Rget_name, <hid_t> -> <H5R_type_t> -> In a -> OutArray CChar -> <size_t> -> IO <ssize_t>
+
+
+#ifndef H5_NO_DEPRECATED_SYMBOLS
+
+-- |Retrieves the type of object that an object reference points to
+-- Given a reference to some object, this function returns the type of object
+-- pointed to.
+--
+-- Parameters:
+--
+-- [@ id       :: 'HId_t'      @]   Dataset reference object is in or location ID of object that the dataset is located within.
+--
+-- [@ ref_type :: 'H5R_type_t' @]   Type of reference to query
+--
+-- [@ ref      :: 'In' a       @]   Reference to query.
+--
+-- On success, returns an object type defined in "Bindings.HDF5.Raw.H5G"
+-- On failure, returns 'h5g_UNKNOWN'
+--
+-- > H5G_obj_t H5Rget_obj_type1(hid_t id, H5R_type_t ref_type, const void *_ref);
+#ccall H5Rget_obj_type1, <hid_t> -> <H5R_type_t> -> In a -> IO <H5G_obj_t>
+
+#endif /* H5_NO_DEPRECATED_SYMBOLS */
diff --git a/src/Bindings/HDF5/Raw/H5S.hsc b/src/Bindings/HDF5/Raw/H5S.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/H5S.hsc
@@ -0,0 +1,536 @@
+#include <bindings.h>
+#include <H5Spublic.h>
+
+module Bindings.HDF5.Raw.H5S where
+
+import Data.Int
+import Foreign.C.Types
+import Foreign.Ptr
+import Foreign.Storable
+
+import Bindings.HDF5.Raw.H5
+import Bindings.HDF5.Raw.H5I
+import Foreign.Ptr.Conventions
+
+#newtype_const hid_t, H5S_ALL
+#num H5S_UNLIMITED
+
+-- |Maximum number of dimensions
+#num H5S_MAX_RANK
+
+-- |Different types of dataspaces
+#newtype H5S_class_t, Eq
+
+-- |error
+#newtype_const H5S_class_t, H5S_NO_CLASS
+
+-- |scalar variable
+#newtype_const H5S_class_t, H5S_SCALAR
+
+-- |simple data space
+#newtype_const H5S_class_t, H5S_SIMPLE
+
+-- |null data space
+#newtype_const H5S_class_t, H5S_NULL
+
+-- |Different ways of combining selections
+#newtype H5S_seloper_t
+
+-- |error
+#newtype_const H5S_seloper_t, H5S_SELECT_NOOP
+
+-- |Select "set" operation
+#newtype_const H5S_seloper_t, H5S_SELECT_SET
+
+-- |Binary "or" operation for hyperslabs
+-- (add new selection to existing selection)
+-- Original region:  AAAAAAAAAA
+-- New region:             BBBBBBBBBB
+-- A or B:           CCCCCCCCCCCCCCCC
+#newtype_const H5S_seloper_t, H5S_SELECT_OR
+
+-- |Binary "and" operation for hyperslabs
+-- (only leave overlapped regions in selection)
+-- Original region:  AAAAAAAAAA
+-- New region:             BBBBBBBBBB
+-- A and B:                CCCC
+#newtype_const H5S_seloper_t, H5S_SELECT_AND
+
+-- |Binary "xor" operation for hyperslabs
+-- (only leave non-overlapped regions in selection)
+-- Original region:  AAAAAAAAAA
+-- New region:             BBBBBBBBBB
+-- A xor B:          CCCCCC    CCCCCC
+#newtype_const H5S_seloper_t, H5S_SELECT_XOR
+
+-- |Binary "not" operation for hyperslabs
+-- (only leave non-overlapped regions in original selection)
+-- Original region:  AAAAAAAAAA
+-- New region:             BBBBBBBBBB
+-- A not B:          CCCCCC
+#newtype_const H5S_seloper_t, H5S_SELECT_NOTB
+
+-- |Binary "not" operation for hyperslabs
+-- (only leave non-overlapped regions in new selection)
+-- Original region:  AAAAAAAAAA
+-- New region:             BBBBBBBBBB
+-- B not A:                    CCCCCC
+#newtype_const H5S_seloper_t, H5S_SELECT_NOTA
+
+-- |Append elements to end of point selection
+#newtype_const H5S_seloper_t, H5S_SELECT_APPEND
+
+-- |Prepend elements to beginning of point selection
+#newtype_const H5S_seloper_t, H5S_SELECT_PREPEND
+
+-- |Invalid upper bound on selection operations
+#newtype_const H5S_seloper_t, H5S_SELECT_INVALID
+
+-- |Enumerated type for the type of selection
+#newtype H5S_sel_type, Eq
+
+-- |Error
+#newtype_const H5S_sel_type, H5S_SEL_ERROR
+
+-- |Nothing selected
+#newtype_const H5S_sel_type, H5S_SEL_NONE
+
+-- |Sequence of points selected
+#newtype_const H5S_sel_type, H5S_SEL_POINTS
+
+-- |"New-style" hyperslab selection defined
+#newtype_const H5S_sel_type, H5S_SEL_HYPERSLABS
+
+-- |Entire extent selected
+#newtype_const H5S_sel_type, H5S_SEL_ALL
+
+-- |Number of selection types
+#num H5S_SEL_N
+
+-- |Creates a new dataspace of a given type.  The extent & selection are
+-- undefined
+--
+-- Parameters:
+--
+-- [@ type :: 'H5S_type_t' @]   Dataspace type to create
+--
+-- Returns valid dataspace ID on success, negative on failure
+--
+-- > hid_t H5Screate(H5S_class_t type);
+#ccall H5Screate, <H5S_class_t> -> IO <hid_t>
+
+-- |Creates a new simple dataspace object and opens it for
+-- access. The 'dims' argument is the size of the simple dataset
+-- and the 'maxdims' argument is the upper limit on the size of
+-- the dataset.  'maxdims' may be the null pointer in which case
+-- the upper limit is the same as 'dims'.  If an element of
+-- 'maxdims' is 'h5s_UNLIMITED' then the corresponding dimension is
+-- unlimited, otherwise no element of 'maxdims' should be smaller
+-- than the corresponding element of 'dims'.
+--
+-- On success, returns the ID for the new simple dataspace object.
+-- Returns negative on failure.
+--
+-- > hid_t H5Screate_simple(int rank, const hsize_t dims[],
+-- >        const hsize_t maxdims[]);
+#ccall H5Screate_simple, CInt -> InArray <hsize_t> -> InArray <hsize_t> -> IO <hid_t>
+
+-- |Determines if a simple dataspace's extent has been set (e.g.,
+-- by 'h5s_set_extent_simple').  Helps avoid write errors.
+--
+-- Returns TRUE (C macro) if dataspace has extent set, FALSE (C macro)
+-- if dataspace's extent is uninitialized.
+--
+-- > herr_t H5Sset_extent_simple(hid_t space_id, int rank,
+-- >        const hsize_t dims[],
+-- >        const hsize_t max[]);
+#ccall H5Sset_extent_simple, <hid_t> -> CInt -> InArray <hsize_t> -> InArray <hsize_t> -> IO <herr_t>
+
+-- |Copies a dataspace.
+--
+-- On success, returns the ID of the new dataspace.  Returns negative on
+-- failure.
+--
+-- > hid_t H5Scopy(hid_t space_id);
+#ccall H5Scopy, <hid_t> -> IO <hid_t>
+
+-- |Release access to a dataspace object.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Sclose(hid_t space_id);
+#ccall H5Sclose, <hid_t> -> IO <herr_t>
+
+-- |Given a dataspace ID, converts the object description
+-- (including selection) into binary in a buffer.
+--
+-- 'nalloc' is the size of the buffer on input, the size of the encoded
+-- data on output.  If the buffer is not big enough, no data is written
+-- to it (but nalloc is still updated with the size needed).
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Sencode(hid_t obj_id, void *buf, size_t *nalloc);
+#ccall H5Sencode, <hid_t> -> OutArray CChar -> InOut <size_t> -> IO <herr_t>
+
+-- |Decode a binary object description of dataspace and
+-- return a new object handle.
+--
+-- On success, returns the ID of the new dataspace.  Returns negative on
+-- failure.
+--
+-- > hid_t H5Sdecode(const void *buf);
+#ccall H5Sdecode, InArray CChar -> IO <hid_t>
+
+-- |Determines how many data points a dataset extent has.
+--
+-- On success, returns the number of data points in the dataset.  On
+-- failure, returns a negative value.
+--
+-- > hssize_t H5Sget_simple_extent_npoints(hid_t space_id);
+#ccall H5Sget_simple_extent_npoints, <hid_t> -> IO <hssize_t>
+
+-- |Determines the dimensionality of a dataspace.
+--
+-- On success, returns the number of dimensions in the dataset.  On
+-- failure, returns a negative value.
+--
+-- > int H5Sget_simple_extent_ndims(hid_t space_id);
+#ccall H5Sget_simple_extent_ndims, <hid_t> -> IO CInt
+
+-- |Returns the size and maximum sizes in each dimension of
+-- a dataspace DS through	the DIMS and MAXDIMS arguments.
+--
+-- Returns the number of dimensions, the same value as returned
+-- by 'h5s_get_simple_extent_ndims', or a negative value on failure..
+--
+-- > int H5Sget_simple_extent_dims(hid_t space_id, hsize_t dims[],
+-- >        hsize_t maxdims[]);
+#ccall H5Sget_simple_extent_dims, <hid_t> -> OutArray <hsize_t> -> OutArray <hsize_t> -> IO CInt
+
+-- |Check if a dataspace is simple
+--
+-- Parameters:
+--
+-- [@ space_id :: 'HId_t' @]    ID of dataspace object to query
+--
+-- > htri_t H5Sis_simple(hid_t space_id);
+#ccall H5Sis_simple, <hid_t> -> IO <htri_t>
+
+-- |Returns the number of elements in current selection for dataspace.
+--
+-- Parameters:
+-- [@ dsid :: 'HId_t' @]    Dataspace ID of selection to query
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > hssize_t H5Sget_select_npoints(hid_t spaceid);
+#ccall H5Sget_select_npoints, <hid_t> -> IO <hssize_t>
+
+-- |Combines a hyperslab selection with the current selection for a dataspace.
+-- If the current selection is not a hyperslab, it is freed and the hyperslab
+-- parameters passed in are combined with the 'h5s_SEL_ALL' hyperslab (ie. a
+-- selection composing the entire current extent).  If 'stride' or 'block' is
+-- NULL, they are assumed to be set to all '1'.
+--
+-- Parameters:
+--
+-- [@ dsid   :: 'HId_t'                   @]  Dataspace ID of selection to modify
+--
+-- [@ op     :: 'H5S_seloper_t'           @]  Operation to perform on current selection
+--
+-- [@ start  :: 'InArray' 'HSize_t'       @]  Offset of start of hyperslab
+--
+-- [@ stride :: 'InArray' 'HSize_t'       @]  Hyperslab stride
+--
+-- [@ count  :: 'InArray' 'HSize_t'       @]  Number of blocks included in hyperslab
+--
+-- [@ block  :: 'InArray' 'HSize_t'       @]  Size of block in hyperslab
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Sselect_hyperslab(hid_t space_id, H5S_seloper_t op,
+-- >        const hsize_t start[],
+-- >        const hsize_t _stride[],
+-- >        const hsize_t count[],
+-- >        const hsize_t _block[]);
+#ccall H5Sselect_hyperslab, <hid_t> -> <H5S_seloper_t> -> InArray <hsize_t> -> InArray <hsize_t> -> InArray <hsize_t> -> InArray <hsize_t> -> IO <herr_t>
+
+
+#ifdef NEW_HYPERSLAB_API
+
+-- |Specify a hyperslab to combine with the current hyperslab selection and
+-- return a new dataspace with the combined selection as the selection in the
+-- new dataspace.
+--
+-- Combines a hyperslab selection with the current selection for a dataspace,
+-- creating a new dataspace to return the generated selection.
+-- If the current selection is not a hyperslab, it is freed and the hyperslab
+-- parameters passed in are combined with the H5S_SEL_ALL hyperslab (ie. a
+-- selection composing the entire current extent).  If STRIDE or BLOCK is
+-- NULL, they are assumed to be set to all '1'.
+--
+-- Parameters:
+--
+-- [@ dsid   :: 'HId_t'             @]  Dataspace ID of selection to use
+--
+-- [@ op     :: 'H5S_seloper_t'     @]  Operation to perform on current selection
+--
+-- [@ start  :: 'InArray' 'HSize_t' @]  Offset of start of hyperslab
+--
+-- [@ stride :: 'InArray' 'HSize_t' @]  Hyperslab stride
+--
+-- [@ count  :: 'InArray' 'HSize_t' @]  Number of blocks included in hyperslab
+--
+-- [@ block  :: 'InArray' 'HSize_t' @]  Size of block in hyperslab
+--
+-- Returns dataspace ID on success, negative on failure
+--
+-- > hid_t H5Scombine_hyperslab(hid_t space_id, H5S_seloper_t op,
+-- >        const hsize_t start[],
+-- >        const hsize_t _stride[],
+-- >        const hsize_t count[],
+-- >        const hsize_t _block[]);
+#ccall H5Scombine_hyperslab, <hid_t> -> <H5S_seloper_t> -> InArray <hsize_t> -> InArray <hsize_t> -> InArray <hsize_t> -> InArray <hsize_t> -> IO <hid_t>
+
+-- |Refine an existing hyperslab selection with an operation, using a second
+-- hyperslab.  The first selection is modified to contain the result of
+-- 'space1' operated on by 'space2'.
+--
+-- Parameters:
+--
+-- [@ space1 :: 'HId_t'         @]  First Dataspace ID
+--
+-- [@ op     :: 'H5S_seloper_t' @]  Selection operation
+--
+-- [@ space2 :: 'HId_t'         @]  Second Dataspace ID
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Sselect_select(hid_t space1_id, H5S_seloper_t op,
+-- >        hid_t space2_id);
+#ccall H5Sselect_select, <hid_t> -> <H5S_seloper_t> -> <hid_t> -> IO <herr_t>
+
+-- |Combine two existing hyperslab selections with an operation, returning
+-- a new dataspace with the resulting selection.  The dataspace extent from
+-- space1 is copied for the dataspace extent of the newly created dataspace.
+--
+-- Parameters:
+--
+-- [@ space1 :: 'HId_t'         @]   First Dataspace ID
+--
+-- [@ op     :: 'H5S_seloper_t' @]   Selection operation
+--
+-- [@ space2 :: 'HId_t'         @]   Second Dataspace ID
+--
+-- Returns dataspace ID on success, negative on failure
+--
+-- > hid_t H5Scombine_select(hid_t space1_id, H5S_seloper_t op,
+-- >        hid_t space2_id);
+#ccall H5Scombine_select, <hid_t> -> <H5S_seloper_t> -> <hid_t> -> IO <hid_t>
+
+#endif /* NEW_HYPERSLAB_API */
+
+-- |This function selects array elements to be included in the selection for
+-- the dataspace.  The 'coord' array is a 2-D array of size \<dataspace rank\>
+-- by 'num_elem' (ie. a list of coordinates in the dataspace).  The order of
+-- the element coordinates in the 'coord' array specifies the order that the
+-- array elements are iterated through when I/O is performed.  Duplicate
+-- coordinates are not checked for.  The selection operator, 'op', determines
+-- how the new selection is to be combined with the existing selection for
+-- the dataspace.  Currently, only 'h5s_SELECT_SET' is supported, which replaces
+-- the existing selection with the one defined in this call.  When operators
+-- other than 'h5s_SELECT_SET' are used to combine a new selection with an
+-- existing selection, the selection ordering is reset to 'C' array ordering.
+--
+-- Parameters:
+--
+-- [@ dsid     :: 'HId_t'             @]    Dataspace ID of selection to modify
+--
+-- [@ op       :: 'H5S_seloper_t'     @]    Operation to perform on current selection
+--
+-- [@ num_elem :: 'CSize'             @]    Number of elements in COORD array.
+--
+-- [@ coord    :: 'InArray' 'HSize_t' @]    The location of each element selected
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Sselect_elements(hid_t space_id, H5S_seloper_t op,
+-- >     size_t num_elem, const hsize_t *coord);
+#ccall H5Sselect_elements, <hid_t> -> <H5S_seloper_t> -> <size_t> -> InArray <hsize_t> -> IO <herr_t>
+
+-- |Retrieves the type of extent for a dataspace object
+--
+-- Returns the class of the dataspace object on success, 'n5s_NO_CLASS'
+-- on failure.
+--
+-- > H5S_class_t H5Sget_simple_extent_type(hid_t space_id);
+#ccall H5Sget_simple_extent_type, <hid_t> -> IO <H5S_class_t>
+
+-- |Resets the extent of a dataspace back to \"none\"
+--
+-- This function resets the type of a dataspace back to \"none\" with no
+-- extent information stored for the dataspace.
+--
+-- > herr_t H5Sset_extent_none(hid_t space_id);
+#ccall H5Sset_extent_none, <hid_t> -> IO <herr_t>
+
+-- |
+-- > herr_t H5Sextent_copy(hid_t dst_id,hid_t src_id);
+#ccall H5Sextent_copy, <hid_t> -> <hid_t> -> IO <herr_t>
+
+-- |Determines if two dataspace extents are equal.
+--
+-- > htri_t H5Sextent_equal(hid_t sid1, hid_t sid2);
+#ccall H5Sextent_equal, <hid_t> -> <hid_t> -> IO <htri_t>
+
+-- |This function selects the entire extent for a dataspace.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Sselect_all(hid_t spaceid);
+#ccall H5Sselect_all, <hid_t> -> IO <herr_t>
+
+-- |This function de-selects the entire extent for a dataspace.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Sselect_none(hid_t spaceid);
+#ccall H5Sselect_none, <hid_t> -> IO <herr_t>
+
+-- |Changes the offset of a selection within a simple dataspace extent
+--
+-- Parameters:
+--
+-- [@ space_id :: 'HId_t'              @]   Dataspace object to reset
+--
+-- [@ offset   :: 'InArray' 'HSsize_t' @]   Offset to position the selection at
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Soffset_simple(hid_t space_id, const hssize_t *offset);
+#ccall H5Soffset_simple, <hid_t> -> InArray <hssize_t> -> IO <herr_t>
+
+-- |Check whether the selection fits within the extent, with the current
+-- offset defined.
+--
+-- Determines if the current selection at the current offet fits within the
+-- extent for the dataspace.
+--
+-- > htri_t H5Sselect_valid(hid_t spaceid);
+#ccall H5Sselect_valid, <hid_t> -> IO <htri_t>
+
+#if H5_VERSION_GE(1,10,0)
+
+-- > htri_t H5Sis_regular_hyperslab(hid_t spaceid);
+#ccall H5Sis_regular_hyperslab, <hid_t> -> IO <htri_t>
+-- > htri_t H5Sget_regular_hyperslab(hid_t spaceid, hsize_t start[],
+-- >     hsize_t stride[], hsize_t count[], hsize_t block[]);
+#ccall H5Sget_regular_hyperslab, <hid_t> -> InArray <hsize_t> -> InArray <hsize_t> -> InArray <hsize_t> -> InArray <hsize_t> -> IO <htri_t>
+
+#endif
+
+-- |Get the number of hyperslab blocks in current hyperslab selection
+--
+-- Returns negative on failure
+--
+-- > hssize_t H5Sget_select_hyper_nblocks(hid_t spaceid);
+#ccall H5Sget_select_hyper_nblocks, <hid_t> -> IO <hssize_t>
+
+-- |Get the number of points in current element selection
+--
+-- Returns negative on failure
+--
+-- > hssize_t H5Sget_select_elem_npoints(hid_t spaceid);
+#ccall H5Sget_select_elem_npoints, <hid_t> -> IO <hssize_t>
+
+-- |Puts a list of the hyperslab blocks into the user's buffer.  The blocks
+-- start with the 'startblock'th block in the list of blocks and put
+-- 'numblocks' number of blocks into the user's buffer (or until the end of
+-- the list of blocks, whichever happen first)
+--
+-- The block coordinates have the same dimensionality (rank) as the
+-- dataspace they are located within.  The list of blocks is formatted as
+-- follows: \<\"start\" coordinate\> immediately followed by \<\"opposite\"
+-- corner coordinate\>, followed by the next \"start\" and \"opposite\"
+-- coordinate, etc.  until all the block information requested has been
+-- put into the user's buffer.
+--
+-- No guarantee of any order of the blocks is implied.
+--
+-- Parameters:
+--
+-- [@ dsid       :: 'HId_t'               @]    Dataspace ID of selection to query
+--
+-- [@ startblock :: 'HSsize_t'            @]    Hyperslab block to start with
+--
+-- [@ numblocks  :: 'HSsize_t'            @]    Number of hyperslab blocks to get
+--
+-- [@ buf        :: 'OutArray' 'HSsize_t' @]    List of hyperslab blocks selected
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Sget_select_hyper_blocklist(hid_t spaceid, hsize_t startblock,
+-- >     hsize_t numblocks, hsize_t buf[/*numblocks*/]);
+#ccall H5Sget_select_hyper_blocklist, <hid_t> -> <hsize_t> -> <hsize_t> -> OutArray <hsize_t> -> IO <herr_t>
+
+-- |Puts a list of the element points into the user's buffer.  The points
+-- start with the 'startpoint'th block in the list of points and put
+-- 'numpoints' number of points into the user's buffer (or until the end of
+-- the list of points, whichever happen first)
+--
+-- The point coordinates have the same dimensionality (rank) as the
+-- dataspace they are located within.  The list of points is formatted as
+-- follows: <coordinate> followed by the next coordinate, etc. until all the
+-- point information in the selection have been put into the user's buffer.
+--
+-- The points are returned in the order they will be interated through
+-- when a selection is read/written from/to disk.
+--
+-- Parameters:
+--
+-- [@ dsid       :: 'HId_t'   @]    Dataspace ID of selection to query
+--
+-- [@ startpoint :: 'HSize_t' @]    Element point to start with
+--
+-- [@ numpoints  :: 'HSize_t' @]    Number of element points to get
+--
+-- [@ buf        :: 'HSize_t' @]    List of element points selected
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Sget_select_elem_pointlist(hid_t spaceid, hsize_t startpoint,
+-- >     hsize_t numpoints, hsize_t buf[/*numpoints*/]);
+#ccall H5Sget_select_elem_pointlist, <hid_t> -> <hsize_t> -> <hsize_t> -> OutArray <hsize_t> -> IO <herr_t>
+
+-- |Retrieves the bounding box containing the current selection and places
+-- it into the user's buffers.  The start and end buffers must be large
+-- enough to hold the dataspace rank number of coordinates.  The bounding box
+-- exactly contains the selection, ie. if a 2-D element selection is currently
+-- defined with the following points: (4,5), (6,8) (10,7), the bounding box
+-- with be (4, 5), (10, 8).  Calling this function on a \"none\" selection
+-- returns fail.
+--
+-- The bounding box calculations _does_ include the current offset of the
+-- selection within the dataspace extent.
+--
+-- Parameters:
+--
+-- [@ dsid  :: 'HId_t'              @]  Dataspace ID of selection to query
+--
+-- [@ start :: 'OutArray' 'HSize_t' @]  Starting coordinate of bounding box
+--
+-- [@ end   :: 'OutArray' 'HSize_t' @]  Opposite coordinate of bounding box
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- Weird warning in source: This routine participates in the
+-- \"Inlining C function pointers\" pattern, don't call it directly,
+-- use the appropriate macro defined in H5Sprivate.h.
+--
+-- > herr_t H5Sget_select_bounds(hid_t spaceid, hsize_t start[],
+-- >     hsize_t end[]);
+#ccall H5Sget_select_bounds, <hid_t> -> OutArray <hsize_t> -> OutArray <hsize_t> -> IO <herr_t>
+
+-- H5S_sel_type H5Sget_select_type(hid_t spaceid);
+#ccall H5Sget_select_type, <hid_t> -> IO <H5S_sel_type>
diff --git a/src/Bindings/HDF5/Raw/H5T.hsc b/src/Bindings/HDF5/Raw/H5T.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/H5T.hsc
@@ -0,0 +1,1357 @@
+#include <bindings.h>
+
+#include <H5Tpublic.h>
+
+module Bindings.HDF5.Raw.H5T where
+
+import Data.Int
+import Data.Word
+import Foreign.C.String
+import Foreign.C.Types
+import Foreign.Ptr
+import Foreign.Storable
+
+import Bindings.HDF5.Raw.H5
+import Bindings.HDF5.Raw.H5I
+import Foreign.Ptr.Conventions
+
+-- |These are the various classes of datatypes
+--
+-- If this goes over 16 types (0-15), the file format will need to change)
+#newtype H5T_class_t, Eq
+
+-- |error
+#newtype_const H5T_class_t, H5T_NO_CLASS
+
+-- |integer types
+#newtype_const H5T_class_t, H5T_INTEGER
+
+-- |floating-point types
+#newtype_const H5T_class_t, H5T_FLOAT
+
+-- |date and time types
+#newtype_const H5T_class_t, H5T_TIME
+
+-- |character string types
+#newtype_const H5T_class_t, H5T_STRING
+
+-- |bit field types
+#newtype_const H5T_class_t, H5T_BITFIELD
+
+-- |opaque types
+#newtype_const H5T_class_t, H5T_OPAQUE
+
+-- |compound types
+#newtype_const H5T_class_t, H5T_COMPOUND
+
+-- |reference types
+#newtype_const H5T_class_t, H5T_REFERENCE
+
+-- |enumeration types
+#newtype_const H5T_class_t, H5T_ENUM
+
+-- |Variable-Length types
+#newtype_const H5T_class_t, H5T_VLEN
+
+-- |Array types
+#newtype_const H5T_class_t, H5T_ARRAY
+
+-- |The number of basic datatypes
+#num H5T_NCLASSES
+
+-- |Byte orders
+#newtype H5T_order_t, Eq
+
+-- |error
+#newtype_const H5T_order_t, H5T_ORDER_ERROR
+
+-- |little endian
+#newtype_const H5T_order_t, H5T_ORDER_LE
+
+-- |bit endian
+#newtype_const H5T_order_t, H5T_ORDER_BE
+
+-- |VAX mixed endian
+#newtype_const H5T_order_t, H5T_ORDER_VAX
+
+#if H5_VERSION_GE(1,8,6)
+-- |Compound type with mixed member orders
+#newtype_const H5T_order_t, H5T_ORDER_MIXED
+#endif
+
+-- |no particular order (strings, bits,..)
+#newtype_const H5T_order_t, H5T_ORDER_NONE
+
+-- |Types of integer sign schemes
+#newtype H5T_sign_t, Eq
+
+-- |error
+#newtype_const H5T_sign_t, H5T_SGN_ERROR
+
+-- |this is an unsigned type
+#newtype_const H5T_sign_t, H5T_SGN_NONE
+
+-- |two's complement
+#newtype_const H5T_sign_t, H5T_SGN_2
+
+-- |The number of recognized integer sign schemes
+#num H5T_NSGN
+
+-- |Floating-point normalization schemes
+#newtype H5T_norm_t, Eq
+
+-- |error
+#newtype_const H5T_norm_t, H5T_NORM_ERROR
+
+-- |msb of mantissa isn't stored, always 1
+#newtype_const H5T_norm_t, H5T_NORM_IMPLIED
+
+-- |msb of mantissa is always 1
+#newtype_const H5T_norm_t, H5T_NORM_MSBSET
+
+-- |not normalized
+#newtype_const H5T_norm_t, H5T_NORM_NONE
+
+-- |Character set to use for text strings.  Do not change these values since
+-- they appear in HDF5 files!
+#newtype H5T_cset_t, Eq, Ord, Read
+
+-- |error
+#newtype_const H5T_cset_t, H5T_CSET_ERROR
+
+-- |US ASCII
+#newtype_const H5T_cset_t, H5T_CSET_ASCII
+
+-- |UTF-8 Unicode encoding
+#newtype_const H5T_cset_t, H5T_CSET_UTF8
+
+-- |reserved for later use
+#newtype_const H5T_cset_t, H5T_CSET_RESERVED_2
+
+-- |reserved for later use
+#newtype_const H5T_cset_t, H5T_CSET_RESERVED_3
+
+-- |reserved for later use
+#newtype_const H5T_cset_t, H5T_CSET_RESERVED_4
+
+-- |reserved for later use
+#newtype_const H5T_cset_t, H5T_CSET_RESERVED_5
+
+-- |reserved for later use
+#newtype_const H5T_cset_t, H5T_CSET_RESERVED_6
+
+-- |reserved for later use
+#newtype_const H5T_cset_t, H5T_CSET_RESERVED_7
+
+-- |reserved for later use
+#newtype_const H5T_cset_t, H5T_CSET_RESERVED_8
+
+-- |reserved for later use
+#newtype_const H5T_cset_t, H5T_CSET_RESERVED_9
+
+-- |reserved for later use
+#newtype_const H5T_cset_t, H5T_CSET_RESERVED_10
+
+-- |reserved for later use
+#newtype_const H5T_cset_t, H5T_CSET_RESERVED_11
+
+-- |reserved for later use
+#newtype_const H5T_cset_t, H5T_CSET_RESERVED_12
+
+-- |reserved for later use
+#newtype_const H5T_cset_t, H5T_CSET_RESERVED_13
+
+-- |reserved for later use
+#newtype_const H5T_cset_t, H5T_CSET_RESERVED_14
+
+-- |reserved for later use
+#newtype_const H5T_cset_t, H5T_CSET_RESERVED_15
+
+-- |Number of character sets actually defined
+#num H5T_NCSET
+
+-- |Type of padding to use in character strings.  Do not change these values
+-- since they appear in HDF5 files!
+#newtype H5T_str_t, Eq
+
+-- |error
+#newtype_const H5T_str_t, H5T_STR_ERROR
+
+-- |null terminate like in C
+#newtype_const H5T_str_t, H5T_STR_NULLTERM
+
+-- |pad with nulls
+#newtype_const H5T_str_t, H5T_STR_NULLPAD
+
+-- |pad with spaces like in Fortran
+#newtype_const H5T_str_t, H5T_STR_SPACEPAD
+
+-- |reserved for later use
+#newtype_const H5T_str_t, H5T_STR_RESERVED_3
+
+-- |reserved for later use
+#newtype_const H5T_str_t, H5T_STR_RESERVED_4
+
+-- |reserved for later use
+#newtype_const H5T_str_t, H5T_STR_RESERVED_5
+
+-- |reserved for later use
+#newtype_const H5T_str_t, H5T_STR_RESERVED_6
+
+-- |reserved for later use
+#newtype_const H5T_str_t, H5T_STR_RESERVED_7
+
+-- |reserved for later use
+#newtype_const H5T_str_t, H5T_STR_RESERVED_8
+
+-- |reserved for later use
+#newtype_const H5T_str_t, H5T_STR_RESERVED_9
+
+-- |reserved for later use
+#newtype_const H5T_str_t, H5T_STR_RESERVED_10
+
+-- |reserved for later use
+#newtype_const H5T_str_t, H5T_STR_RESERVED_11
+
+-- |reserved for later use
+#newtype_const H5T_str_t, H5T_STR_RESERVED_12
+
+-- |reserved for later use
+#newtype_const H5T_str_t, H5T_STR_RESERVED_13
+
+-- |reserved for later use
+#newtype_const H5T_str_t, H5T_STR_RESERVED_14
+
+-- |reserved for later use
+#newtype_const H5T_str_t, H5T_STR_RESERVED_15
+
+-- |num 'H5T_str_t' types actually defined
+#num H5T_NSTR
+
+-- |Type of padding to use in other atomic types
+#newtype H5T_pad_t, Eq
+
+-- |error
+#newtype_const H5T_pad_t, H5T_PAD_ERROR
+
+-- |always set to zero
+#newtype_const H5T_pad_t, H5T_PAD_ZERO
+
+-- |always set to one
+#newtype_const H5T_pad_t, H5T_PAD_ONE
+
+-- |set to background value
+#newtype_const H5T_pad_t, H5T_PAD_BACKGROUND
+
+-- |Number of valid 'H5T_pad_t' values.
+#num H5T_NPAD
+
+-- |Commands sent to conversion functions
+#newtype H5T_cmd_t, Eq
+
+-- |query and/or initialize private data
+#newtype_const H5T_cmd_t, H5T_CONV_INIT
+
+-- |convert data from source to dest datatype
+#newtype_const H5T_cmd_t, H5T_CONV_CONV
+
+-- |function is being removed from path
+#newtype_const H5T_cmd_t, H5T_CONV_FREE
+
+-- |How is the 'bkg' buffer used by the conversion function?
+#newtype H5T_bkg_t, Eq
+
+-- |background buffer is not needed, send NULL
+#newtype_const H5T_bkg_t, H5T_BKG_NO
+
+-- |bkg buffer used as temp storage only
+#newtype_const H5T_bkg_t, H5T_BKG_TEMP
+
+-- |init bkg buf with data before conversion
+#newtype_const H5T_bkg_t, H5T_BKG_YES
+
+-- |Type conversion client data
+data H5T_cdata_t a = H5T_cdata_t {
+
+    -- |what should the conversion function do?
+    h5t_cdata_t'command   :: H5T_cmd_t,
+
+    -- |is the background buffer needed?
+    h5t_cdata_t'need_bkg  :: H5T_bkg_t,
+
+    -- |recalculate private data
+    h5t_cdata_t'recalc    :: HBool_t,
+
+    -- |private data
+    h5t_cdata_t'priv      :: Ptr a}
+
+    deriving (Eq,Show)
+
+instance Storable (H5T_cdata_t a) where
+  sizeOf _ = #size H5T_cdata_t
+  alignment = sizeOf
+  peek p = do
+    v0 <- #{peek H5T_cdata_t, command}  p
+    v1 <- #{peek H5T_cdata_t, need_bkg} p
+    v2 <- #{peek H5T_cdata_t, recalc}   p
+    v3 <- #{peek H5T_cdata_t, priv}     p
+    return $ H5T_cdata_t v0 v1 v2 v3
+  poke p (H5T_cdata_t v0 v1 v2 v3) = do
+    #{poke H5T_cdata_t, command}  p v0
+    #{poke H5T_cdata_t, need_bkg} p v1
+    #{poke H5T_cdata_t, recalc}   p v2
+    #{poke H5T_cdata_t, priv}     p v3
+    return ()
+
+-- |Conversion function persistence
+#newtype H5T_pers_t
+
+-- |wild card
+#newtype_const H5T_pers_t, H5T_PERS_DONTCARE
+
+-- |hard conversion function
+#newtype_const H5T_pers_t, H5T_PERS_HARD
+
+-- |soft conversion function
+#newtype_const H5T_pers_t, H5T_PERS_SOFT
+
+-- |The order to retrieve atomic native datatype
+#newtype H5T_direction_t
+
+-- |default direction is inscendent
+#newtype_const H5T_direction_t, H5T_DIR_DEFAULT
+
+-- |in inscendent order
+#newtype_const H5T_direction_t, H5T_DIR_ASCEND
+
+-- |in descendent order
+#newtype_const H5T_direction_t, H5T_DIR_DESCEND
+
+-- |The exception type passed into the conversion callback function
+#newtype H5T_conv_except_t
+
+-- |source value is greater than destination's range
+#newtype_const H5T_conv_except_t, H5T_CONV_EXCEPT_RANGE_HI
+
+-- |source value is less than destination's range
+#newtype_const H5T_conv_except_t, H5T_CONV_EXCEPT_RANGE_LOW
+
+-- |source value loses precision in destination
+#newtype_const H5T_conv_except_t, H5T_CONV_EXCEPT_PRECISION
+
+-- |source value is truncated in destination
+#newtype_const H5T_conv_except_t, H5T_CONV_EXCEPT_TRUNCATE
+
+-- |source value is positive infinity(floating number)
+#newtype_const H5T_conv_except_t, H5T_CONV_EXCEPT_PINF
+
+-- |source value is negative infinity(floating number)
+#newtype_const H5T_conv_except_t, H5T_CONV_EXCEPT_NINF
+
+-- |source value is NaN(floating number)
+#newtype_const H5T_conv_except_t, H5T_CONV_EXCEPT_NAN
+
+-- |The return value from conversion callback function 'h5t_conv_except_func_t'
+#newtype H5T_conv_ret_t
+
+-- |abort conversion
+#newtype_const H5T_conv_ret_t, H5T_CONV_ABORT
+
+-- |callback function failed to handle the exception
+#newtype_const H5T_conv_ret_t, H5T_CONV_UNHANDLED
+
+-- |callback function handled the exception successfully
+#newtype_const H5T_conv_ret_t, H5T_CONV_HANDLED
+
+-- |Variable Length Datatype struct in memory
+-- (This is only used for VL sequences, not VL strings, which are stored in char *'s)
+#starttype hvl_t
+
+-- |Length of VL data (in base type units)
+#field len, CSize
+
+-- |Pointer to VL data
+#field p, Ptr ()
+
+#stoptype
+
+-- |Indicate that a string is variable length (null-terminated in C, instead of fixed length)
+h5t_VARIABLE :: CSize
+h5t_VARIABLE = #const H5T_VARIABLE
+
+-- |Maximum length of an opaque tag.
+#num H5T_OPAQUE_TAG_MAX
+
+-- TODO: find documentation for this type.
+type H5T_conv_t a b conversionData = FunPtr
+    (HId_t -> HId_t -> Ptr (H5T_cdata_t conversionData)
+    -> CSize -> CSize -> CSize -> InOutArray a -> InArray b -> HId_t
+    -> IO HErr_t)
+
+-- |Exception handler.  If an exception like overflow happens during conversion,
+-- this function is called if it's registered through 'h5p_set_type_conv_cb'.
+type H5T_conv_except_func_t a userData = FunPtr
+    (H5T_conv_except_t -> HId_t -> HId_t -> In a -> In a -> InOut userData
+    -> IO H5T_conv_ret_t)
+
+-- * Constants identifying data types
+
+-- ** The IEEE floating point types in various byte orders.
+
+#cinline H5T_IEEE_F32BE,        <hid_t>
+#cinline H5T_IEEE_F32LE,        <hid_t>
+#cinline H5T_IEEE_F64BE,        <hid_t>
+#cinline H5T_IEEE_F64LE,        <hid_t>
+
+-- ** \"Standard\" Types
+-- These are \"standard\" types.  For instance, signed (2's complement) and
+-- unsigned integers of various sizes and byte orders.
+
+#cinline H5T_STD_I8BE,          <hid_t>
+#cinline H5T_STD_I8LE,          <hid_t>
+#cinline H5T_STD_I16BE,         <hid_t>
+#cinline H5T_STD_I16LE,         <hid_t>
+#cinline H5T_STD_I32BE,         <hid_t>
+#cinline H5T_STD_I32LE,         <hid_t>
+#cinline H5T_STD_I64BE,         <hid_t>
+#cinline H5T_STD_I64LE,         <hid_t>
+#cinline H5T_STD_U8BE,          <hid_t>
+#cinline H5T_STD_U8LE,          <hid_t>
+#cinline H5T_STD_U16BE,         <hid_t>
+#cinline H5T_STD_U16LE,         <hid_t>
+#cinline H5T_STD_U32BE,         <hid_t>
+#cinline H5T_STD_U32LE,         <hid_t>
+#cinline H5T_STD_U64BE,         <hid_t>
+#cinline H5T_STD_U64LE,         <hid_t>
+#cinline H5T_STD_B8BE,          <hid_t>
+#cinline H5T_STD_B8LE,          <hid_t>
+#cinline H5T_STD_B16BE,         <hid_t>
+#cinline H5T_STD_B16LE,         <hid_t>
+#cinline H5T_STD_B32BE,         <hid_t>
+#cinline H5T_STD_B32LE,         <hid_t>
+#cinline H5T_STD_B64BE,         <hid_t>
+#cinline H5T_STD_B64LE,         <hid_t>
+#cinline H5T_STD_REF_OBJ,       <hid_t>
+#cinline H5T_STD_REF_DSETREG,   <hid_t>
+
+-- ** Types which are particular to Unix.
+
+#cinline H5T_UNIX_D32BE,        <hid_t>
+#cinline H5T_UNIX_D32LE,        <hid_t>
+#cinline H5T_UNIX_D64BE,        <hid_t>
+#cinline H5T_UNIX_D64LE,        <hid_t>
+
+-- **  Types particular to the C language.
+-- String types use \"bytes\" instead of \"bits\" as their size.
+
+#cinline H5T_C_S1,              <hid_t>
+
+-- ** Types particular to Fortran.
+
+#cinline H5T_FORTRAN_S1,        <hid_t>
+
+-- ** Types for Intel CPUs.
+-- They are little endian with IEEE floating point.
+h5t_INTEL_I8, h5t_INTEL_I16, h5t_INTEL_I32, h5t_INTEL_I64 :: HId_t
+h5t_INTEL_U8, h5t_INTEL_U16, h5t_INTEL_U32, h5t_INTEL_U64 :: HId_t
+h5t_INTEL_B8, h5t_INTEL_B16, h5t_INTEL_B32, h5t_INTEL_B64 :: HId_t
+h5t_INTEL_F32, h5t_INTEL_F64 :: HId_t
+
+h5t_INTEL_I8  = h5t_STD_I8LE
+h5t_INTEL_I16 = h5t_STD_I16LE
+h5t_INTEL_I32 = h5t_STD_I32LE
+h5t_INTEL_I64 = h5t_STD_I64LE
+h5t_INTEL_U8  = h5t_STD_U8LE
+h5t_INTEL_U16 = h5t_STD_U16LE
+h5t_INTEL_U32 = h5t_STD_U32LE
+h5t_INTEL_U64 = h5t_STD_U64LE
+h5t_INTEL_B8  = h5t_STD_B8LE
+h5t_INTEL_B16 = h5t_STD_B16LE
+h5t_INTEL_B32 = h5t_STD_B32LE
+h5t_INTEL_B64 = h5t_STD_B64LE
+h5t_INTEL_F32 = h5t_IEEE_F32LE
+h5t_INTEL_F64 = h5t_IEEE_F64LE
+
+-- ** Types for Alpha CPUs.
+-- They are little endian with IEEE floating point.
+
+h5t_ALPHA_I8, h5t_ALPHA_I16, h5t_ALPHA_I32, h5t_ALPHA_I64 :: HId_t
+h5t_ALPHA_U8, h5t_ALPHA_U16, h5t_ALPHA_U32, h5t_ALPHA_U64 :: HId_t
+h5t_ALPHA_B8, h5t_ALPHA_B16, h5t_ALPHA_B32, h5t_ALPHA_B64 :: HId_t
+h5t_ALPHA_F32, h5t_ALPHA_F64 :: HId_t
+
+h5t_ALPHA_I8  = h5t_STD_I8LE
+h5t_ALPHA_I16 = h5t_STD_I16LE
+h5t_ALPHA_I32 = h5t_STD_I32LE
+h5t_ALPHA_I64 = h5t_STD_I64LE
+h5t_ALPHA_U8  = h5t_STD_U8LE
+h5t_ALPHA_U16 = h5t_STD_U16LE
+h5t_ALPHA_U32 = h5t_STD_U32LE
+h5t_ALPHA_U64 = h5t_STD_U64LE
+h5t_ALPHA_B8  = h5t_STD_B8LE
+h5t_ALPHA_B16 = h5t_STD_B16LE
+h5t_ALPHA_B32 = h5t_STD_B32LE
+h5t_ALPHA_B64 = h5t_STD_B64LE
+h5t_ALPHA_F32 = h5t_IEEE_F32LE
+h5t_ALPHA_F64 = h5t_IEEE_F64LE
+
+-- ** Types for MIPS CPUs.
+-- They are big endian with IEEE floating point.
+
+h5t_MIPS_I8, h5t_MIPS_I16, h5t_MIPS_I32, h5t_MIPS_I64 :: HId_t
+h5t_MIPS_U8, h5t_MIPS_U16, h5t_MIPS_U32, h5t_MIPS_U64 :: HId_t
+h5t_MIPS_B8, h5t_MIPS_B16, h5t_MIPS_B32, h5t_MIPS_B64 :: HId_t
+h5t_MIPS_F32, h5t_MIPS_F64 :: HId_t
+
+h5t_MIPS_I8  = h5t_STD_I8BE
+h5t_MIPS_I16 = h5t_STD_I16BE
+h5t_MIPS_I32 = h5t_STD_I32BE
+h5t_MIPS_I64 = h5t_STD_I64BE
+h5t_MIPS_U8  = h5t_STD_U8BE
+h5t_MIPS_U16 = h5t_STD_U16BE
+h5t_MIPS_U32 = h5t_STD_U32BE
+h5t_MIPS_U64 = h5t_STD_U64BE
+h5t_MIPS_B8  = h5t_STD_B8BE
+h5t_MIPS_B16 = h5t_STD_B16BE
+h5t_MIPS_B32 = h5t_STD_B32BE
+h5t_MIPS_B64 = h5t_STD_B64BE
+h5t_MIPS_F32 = h5t_IEEE_F32BE
+h5t_MIPS_F64 = h5t_IEEE_F64BE
+
+-- ** VAX floating point types (i.e. in VAX byte order)
+
+#cinline H5T_VAX_F32,           <hid_t>
+#cinline H5T_VAX_F64,           <hid_t>
+
+-- ** Predefined native types.
+-- These are the types detected by 'h5_detect' and they violate the naming
+-- scheme a little.  Instead of a class name, precision and byte order as
+-- the last component, they have a C-like type name.
+-- If the type begins with 'U' then it is the unsigned version of the
+-- integer type; other integer types are signed.  The type LLONG corresponds
+-- to C's 'long long' and LDOUBLE is 'long double' (these types might be the
+-- same as 'LONG' and 'DOUBLE' respectively).
+
+#cinline H5T_NATIVE_CHAR,       <hid_t>
+#cinline H5T_NATIVE_SCHAR,      <hid_t>
+#cinline H5T_NATIVE_UCHAR,      <hid_t>
+#cinline H5T_NATIVE_SHORT,      <hid_t>
+#cinline H5T_NATIVE_USHORT,     <hid_t>
+#cinline H5T_NATIVE_INT,        <hid_t>
+#cinline H5T_NATIVE_UINT,       <hid_t>
+#cinline H5T_NATIVE_LONG,       <hid_t>
+#cinline H5T_NATIVE_ULONG,      <hid_t>
+#cinline H5T_NATIVE_LLONG,      <hid_t>
+#cinline H5T_NATIVE_ULLONG,     <hid_t>
+#cinline H5T_NATIVE_FLOAT,      <hid_t>
+#cinline H5T_NATIVE_DOUBLE,     <hid_t>
+#if H5_SIZEOF_LONG_DOUBLE !=0
+#cinline H5T_NATIVE_LDOUBLE,    <hid_t>
+#endif
+#cinline H5T_NATIVE_B8,         <hid_t>
+#cinline H5T_NATIVE_B16,        <hid_t>
+#cinline H5T_NATIVE_B32,        <hid_t>
+#cinline H5T_NATIVE_B64,        <hid_t>
+#cinline H5T_NATIVE_OPAQUE,     <hid_t>
+#cinline H5T_NATIVE_HADDR,      <hid_t>
+#cinline H5T_NATIVE_HSIZE,      <hid_t>
+#cinline H5T_NATIVE_HSSIZE,     <hid_t>
+#cinline H5T_NATIVE_HERR,       <hid_t>
+#cinline H5T_NATIVE_HBOOL,      <hid_t>
+
+-- ** C9x integer types
+
+#cinline H5T_NATIVE_INT8,           <hid_t>
+#cinline H5T_NATIVE_UINT8,          <hid_t>
+#cinline H5T_NATIVE_INT_LEAST8,     <hid_t>
+#cinline H5T_NATIVE_UINT_LEAST8,    <hid_t>
+#cinline H5T_NATIVE_INT_FAST8,      <hid_t>
+#cinline H5T_NATIVE_UINT_FAST8,     <hid_t>
+
+#cinline H5T_NATIVE_INT16,          <hid_t>
+#cinline H5T_NATIVE_UINT16,         <hid_t>
+#cinline H5T_NATIVE_INT_LEAST16,    <hid_t>
+#cinline H5T_NATIVE_UINT_LEAST16,   <hid_t>
+#cinline H5T_NATIVE_INT_FAST16,     <hid_t>
+#cinline H5T_NATIVE_UINT_FAST16,    <hid_t>
+
+#cinline H5T_NATIVE_INT32,          <hid_t>
+#cinline H5T_NATIVE_UINT32,         <hid_t>
+#cinline H5T_NATIVE_INT_LEAST32,    <hid_t>
+#cinline H5T_NATIVE_UINT_LEAST32,   <hid_t>
+#cinline H5T_NATIVE_INT_FAST32,     <hid_t>
+#cinline H5T_NATIVE_UINT_FAST32,    <hid_t>
+
+#cinline H5T_NATIVE_INT64,          <hid_t>
+#cinline H5T_NATIVE_UINT64,         <hid_t>
+#cinline H5T_NATIVE_INT_LEAST64,    <hid_t>
+#cinline H5T_NATIVE_UINT_LEAST64,   <hid_t>
+#cinline H5T_NATIVE_INT_FAST64,     <hid_t>
+#cinline H5T_NATIVE_UINT_FAST64,    <hid_t>
+
+-- * Operations defined on all datatypes
+
+-- |Create a new type and initialize it to reasonable values.
+-- The type is a member of type class 'type' and is 'size' bytes.
+--
+-- On success, returns a new type identifier.  On failure, returns
+-- a negative value.
+--
+-- > hid_t H5Tcreate(H5T_class_t type, size_t size);
+#ccall H5Tcreate, H5T_class_t -> <size_t> -> IO <hid_t>
+
+-- |Copies a datatype.  The resulting datatype is not locked.
+-- The datatype should be closed when no longer needed by
+-- calling 'h5t_close'.
+--
+-- Returns the ID of a new datatype on success, negative on failure.
+--
+-- > hid_t H5Tcopy(hid_t type_id);
+#ccall H5Tcopy, <hid_t> -> IO <hid_t>
+
+-- |Frees a datatype and all associated memory.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Tclose(hid_t type_id);
+#ccall H5Tclose, <hid_t> -> IO <herr_t>
+
+-- |Determines if two datatypes are equal.
+--
+-- > htri_t H5Tequal(hid_t type1_id, hid_t type2_id);
+#ccall H5Tequal, <hid_t> -> <hid_t> -> IO <htri_t>
+
+-- |Locks a type, making it read only and non-destructable.  This
+-- is normally done by the library for predefined datatypes so
+-- the application doesn't inadvertently change or delete a
+-- predefined type.
+--
+-- Once a datatype is locked it can never be unlocked unless
+-- the entire library is closed.
+--
+-- It is illegal to lock a named datatype since we must allow named
+-- types to be closed (to release file resources) but locking a type
+-- prevents that.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Tlock(hid_t type_id);
+#ccall H5Tlock, <hid_t> -> IO <herr_t>
+
+-- |Save a transient datatype to a file and turn the type handle
+-- into a \"named\", immutable type.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Tcommit2(hid_t loc_id, const char *name, hid_t type_id,
+-- >     hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id);
+#ccall H5Tcommit2, <hid_t> -> CString -> <hid_t> -> <hid_t> -> <hid_t> -> <hid_t> -> IO <herr_t>
+
+-- |Opens a named datatype using a Datatype Access Property
+--     List.
+--
+-- Returns the object ID of the named datatype on success, negative
+-- on failure.
+--
+-- > hid_t H5Topen2(hid_t loc_id, const char *name, hid_t tapl_id);
+#ccall H5Topen2, <hid_t> -> CString -> <hid_t> -> IO <hid_t>
+
+-- |Save a transient datatype to a file and turn the type handle
+-- into a \"named\", immutable type.
+--
+-- The resulting ID should be linked into the file with
+-- 'h5o_link' or it will be deleted when closed.
+--
+-- Note:  Datatype access property list is unused currently, but is
+-- checked for sanity anyway.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Tcommit_anon(hid_t loc_id, hid_t type_id, hid_t tcpl_id, hid_t tapl_id);
+#ccall H5Tcommit_anon, <hid_t> -> <hid_t> -> <hid_t> -> <hid_t> -> IO <herr_t>
+
+-- |Returns a copy of the datatype creation property list, or negative on
+-- failure.  The property list ID should be released by calling 'h5p_close'.
+--
+-- > hid_t H5Tget_create_plist(hid_t type_id);
+#ccall H5Tget_create_plist, <hid_t> -> IO <hid_t>
+
+-- |Determines if a datatype is committed or not.
+--
+-- > htri_t H5Tcommitted(hid_t type_id);
+#ccall H5Tcommitted, <hid_t> -> IO <htri_t>
+
+-- |Given a datatype ID, converts the object description into
+-- binary in a buffer.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Tencode(hid_t obj_id, void *buf, size_t *nalloc);
+#ccall H5Tencode, <hid_t> -> OutArray a -> InOut <size_t> -> IO <herr_t>
+
+-- |Decode a binary object description and return a new object handle,
+-- or negative on failure.
+--
+-- > hid_t H5Tdecode(const void *buf);
+#ccall H5Tdecode, InArray a -> IO <hid_t>
+
+#if H5_VERSION_GE(1,10,0)
+
+-- > herr_t H5Tflush(hid_t type_id);
+#ccall H5Tflush, <hid_t> -> IO <herr_t>
+-- > herr_t H5Trefresh(hid_t type_id);
+#ccall H5Trefresh, <hid_t> -> IO <herr_t>
+
+#endif
+
+-- * Operations defined on compound datatypes
+
+-- |Adds another member to the compound datatype 'parent_id'.  The
+-- new member has a 'name' which must be unique within the
+-- compound datatype. The 'offset' argument defines the start of
+-- the member in an instance of the compound datatype, and
+-- 'member_id' is the type of the new member.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Tinsert(hid_t parent_id, const char *name, size_t offset,
+-- >        hid_t member_id);
+#ccall H5Tinsert, <hid_t> -> CString -> <size_t> -> <hid_t> -> IO <herr_t>
+
+-- |Recursively removes padding from within a compound datatype
+-- to make it more efficient (space-wise) to store that data.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Tpack(hid_t type_id);
+#ccall H5Tpack, <hid_t> -> IO <herr_t>
+
+-- * Operations defined on enumeration datatypes
+
+-- |Create a new enumeration data type based on the specified
+-- 'type', which must be an integer type.
+--
+-- Returns the ID of a new enumeration data type on success, negative
+-- on failure.
+--
+-- > hid_t H5Tenum_create(hid_t base_id);
+#ccall H5Tenum_create, <hid_t> -> IO <hid_t>
+
+-- |Insert a new enumeration data type member into an enumeration
+-- type.  'type' is the enumeration type, 'name' is the name of the
+-- new member, and 'value' points to the value of the new member.
+-- The 'name' and 'value' must both be unique within the 'type'. 'value'
+-- points to data which is of the data type defined when the
+-- enumeration type was created.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Tenum_insert(hid_t type, const char *name, const void *value);
+#ccall H5Tenum_insert, <hid_t> -> CString -> In a -> IO <herr_t>
+
+-- |Finds the symbol name that corresponds to the specified 'value'
+-- of an enumeration data type 'type'. At most 'size' characters of
+-- the symbol name are copied into the 'name' buffer. If the
+-- entire symbol anem and null terminator do not fit in the 'name'
+-- buffer then as many characters as possible are copied (not
+-- null terminated) and the function fails.
+--
+-- Returns non-negative on success, negative on failure.  On failure,
+-- the first character of 'name' is set to null if 'size' allows it.
+--
+-- WARNING: the above 2 paragraphs contradict each other about what happens
+-- on failure.  This is because the documentation in the source does.  If
+-- I read the source correctly, this is because there are some failures which
+-- have one behavior and some which have the other.  Therefore, I would
+-- probably not rely on either behavior.
+--
+-- > herr_t H5Tenum_nameof(hid_t type, const void *value, char *name/*out*/,
+-- >        size_t size);
+#ccall H5Tenum_nameof, <hid_t> -> In a -> OutArray CChar -> <size_t> -> IO <herr_t>
+
+-- |Finds the value that corresponds to the specified 'name' of an
+-- enumeration 'type'. The 'value' argument should be at least as
+-- large as the value of @'h5t_get_size' type@ in order to hold the
+-- result.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Tenum_valueof(hid_t type, const char *name,
+-- >        void *value/*out*/);
+#ccall H5Tenum_valueof, <hid_t> -> CString -> Out a -> IO <herr_t>
+
+-- * Operations defined on variable-length datatypes
+
+-- |Create a new variable-length datatype based on the specified 'base_type'.
+--
+-- Returns the ID of a new VL datatype on success, negative on failure.
+--
+-- > hid_t H5Tvlen_create(hid_t base_id);
+#ccall H5Tvlen_create, <hid_t> -> IO <hid_t>
+
+-- * Operations defined on array datatypes
+
+-- |Create a new array datatype based on the specified 'base_type'.
+-- The type is an array with 'ndims' dimensionality and the size of the
+-- array is 'dims'. The total member size should be relatively small.
+-- Array datatypes are currently limited to 'h5s_max_rank' number of
+-- dimensions and must have the number of dimensions set greater than
+-- 0. (i.e. 0 > 'ndims' <= 'h5s_MAX_RANK')  All dimensions sizes must be
+-- greater than 0 also.
+--
+-- Returns the ID of a new array datatype on success, negative on failure.
+--
+-- > hid_t H5Tarray_create2(hid_t base_id, unsigned ndims,
+-- >        const hsize_t dim[/* ndims */]);
+#ccall H5Tarray_create2, <hid_t> -> CUInt -> InArray <hsize_t> -> IO <hid_t>
+
+-- |Returns the number of dimensions of an array datatype, or negative on
+-- failure.
+--
+-- > int H5Tget_array_ndims(hid_t type_id);
+#ccall H5Tget_array_ndims, <hid_t> -> IO CInt
+
+-- |Query the sizes of dimensions for an array datatype.
+--
+-- Returns the number of dimensions of the array type on success or
+-- negative on failure.
+--
+-- > int H5Tget_array_dims2(hid_t type_id, hsize_t dims[]);
+#ccall H5Tget_array_dims2, <hid_t> -> OutArray <hsize_t> -> IO CInt
+
+-- * Operations defined on opaque datatypes
+
+-- |Tag an opaque datatype with a unique ASCII identifier.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Tset_tag(hid_t type, const char *tag);
+#ccall H5Tset_tag, <hid_t> -> CString -> IO <herr_t>
+
+-- |Get the tag associated with an opaque datatype.
+--
+-- Returns a pointer to a 'malloc'ed string.  The caller should 'free' the
+-- string.
+--
+-- > char *H5Tget_tag(hid_t type);
+#ccall H5Tget_tag, <hid_t> -> IO CString
+
+-- * Querying property values
+
+-- |Returns the type from which 'type' is derived. In the case of
+-- an enumeration type the return value is an integer type.
+--
+-- Returns the type ID for the base datatype on success, or negative on
+-- failure.
+--
+-- > hid_t H5Tget_super(hid_t type);
+#ccall H5Tget_super, <hid_t> -> IO <hid_t>
+
+-- |Returns the datatype class identifier for datatype 'type_id'.
+--
+-- Returns one of the non-negative datatype class constants on success
+-- or 'h5t_NO_CLASS' (which is negative) on failure.
+--
+-- > H5T_class_t H5Tget_class(hid_t type_id);
+#ccall H5Tget_class, <hid_t> -> IO <H5T_class_t>
+
+-- |Check whether a datatype contains (or is) a certain type of
+-- datatype.
+--
+-- > htri_t H5Tdetect_class(hid_t type_id, H5T_class_t cls);
+#ccall H5Tdetect_class, <hid_t> -> <H5T_class_t> -> IO <htri_t>
+
+-- |Determines the total size of a datatype in bytes.
+--
+-- Returns the size of an instance of the datatype (in bytes) on
+-- success or 0 on failure (valid datatypes are never zero size).
+--
+-- > size_t H5Tget_size(hid_t type_id);
+#ccall H5Tget_size, <hid_t> -> IO <size_t>
+
+-- |Returns the byte order of a datatype on success, or 'h5t_ORDER_ERROR'
+-- (which is negative) on failure.
+--
+-- If the type is compound and its members have mixed orders, this function
+-- returns 'h5t_ORDER_MIXED'.
+--
+-- > H5T_order_t H5Tget_order(hid_t type_id);
+#ccall H5Tget_order, <hid_t> -> IO H5T_order_t
+
+-- |Gets the precision of a datatype.  The precision is
+-- the number of significant bits which, unless padding is
+-- present, is 8 times larger than the value returned by
+-- 'h5t_get_size'.
+--
+-- Returns 0 on failure (all atomic types have at least one
+-- significant bit)
+--
+-- > size_t H5Tget_precision(hid_t type_id);
+#ccall H5Tget_precision, <hid_t> -> IO <size_t>
+
+-- |Retrieves the bit offset of the first significant bit.  The
+-- signficant bits of an atomic datum can be offset from the
+-- beginning of the memory for that datum by an amount of
+-- padding. The 'offset' property specifies the number of bits
+-- of padding that appear to the \"right of\" the value.  That is,
+-- if we have a 32-bit datum with 16-bits of precision having
+-- the value 0x1122 then it will be layed out in memory as (from
+-- small byte address toward larger byte addresses):
+--
+-- >     Big      Big       Little   Little
+-- >     Endian   Endian    Endian   Endian
+-- >     offset=0 offset=16 offset=0 offset=16
+-- >
+-- > 0:  [ pad]   [0x11]    [0x22]   [ pad]
+-- > 1:  [ pad]   [0x22]    [0x11]   [ pad]
+-- > 2:  [0x11]   [ pad]    [ pad]   [0x22]
+-- > 3:  [0x22]   [ pad]    [ pad]   [0x11]
+--
+-- Returns the offset on success or negative on failure.
+--
+-- > int H5Tget_offset(hid_t type_id);
+#ccall H5Tget_offset, <hid_t> -> IO CInt
+
+-- |Gets the least significant pad type and the most significant
+-- pad type and returns their values through the LSB and MSB
+-- arguments, either of which may be the null pointer.
+--
+-- Returns non-negative on success or negative on failure.
+--
+-- > herr_t H5Tget_pad(hid_t type_id, H5T_pad_t *lsb/*out*/,
+-- >        H5T_pad_t *msb/*out*/);
+#ccall H5Tget_pad, <hid_t> -> Out <H5T_pad_t> -> Out <H5T_pad_t> -> IO <herr_t>
+
+-- |Returns the sign type for an integer type or 'h5t_SGN_ERROR' (a negative
+-- value) on failure.
+--
+-- > H5T_sign_t H5Tget_sign(hid_t type_id);
+#ccall H5Tget_sign, <hid_t> -> IO <H5T_sign_t>
+
+-- |Returns information about the locations of the various bit
+-- fields of a floating point datatype.  The field positions
+-- are bit positions in the significant region of the datatype.
+-- Bits are numbered with the least significant bit number zero.
+--
+-- Any (or even all) of the arguments can be null pointers.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Tget_fields(hid_t type_id, size_t *spos/*out*/,
+-- >        size_t *epos/*out*/, size_t *esize/*out*/,
+-- >        size_t *mpos/*out*/, size_t *msize/*out*/);
+#ccall H5Tget_fields, <hid_t> -> Out <size_t> -> Out <size_t> -> Out <size_t> -> Out <size_t> -> Out <size_t> -> IO <herr_t>
+
+-- |Returns the exponent bias of a floating-point type, or 0 on failure.
+--
+-- > size_t H5Tget_ebias(hid_t type_id);
+#ccall H5Tget_ebias, <hid_t> -> IO <size_t>
+
+-- |Returns the mantisssa normalization of a floating-point data type,
+-- or 'h5t_NORM_ERROR' (a negative value) on failure.
+--
+-- > H5T_norm_t H5Tget_norm(hid_t type_id);
+#ccall H5Tget_norm, <hid_t> -> IO <H5T_norm_t>
+
+-- |If any internal bits of a floating point type are unused
+-- (that is, those significant bits which are not part of the
+-- sign, exponent, or mantissa) then they will be filled
+-- according to the value of this property.
+--
+-- > H5T_pad_t H5Tget_inpad(hid_t type_id);
+#ccall H5Tget_inpad, <hid_t> -> IO <H5T_pad_t>
+
+-- |The method used to store character strings differs with the
+-- programming language: C usually null terminates strings while
+-- Fortran left-justifies and space-pads strings.  This property
+-- defines the storage mechanism for the string.
+--
+-- Returns the character set of a string type on success, or
+-- 'h5t_STR_ERROR' (a negative value) on failure.
+--
+-- > H5T_str_t H5Tget_strpad(hid_t type_id);
+#ccall H5Tget_strpad, <hid_t> -> IO <H5T_str_t>
+
+-- |Determines how many members 'type_id' has.  The type must be
+-- either a compound datatype or an enumeration datatype.
+--
+-- Returns the number of members defined in the datatype on success, or
+-- negative on failure.
+--
+-- > int H5Tget_nmembers(hid_t type_id);
+#ccall H5Tget_nmembers, <hid_t> -> IO CInt
+
+-- |Returns the name of a member of a compound or enumeration
+-- datatype.  Members are stored in no particular order with
+-- numbers 0 through N-1 where N is the value returned by
+-- 'h5t_get_nmembers'.
+--
+-- Returns a pointer to a string allocated with 'malloc', or NULL on
+-- failure.  The caller is responsible for 'free'ing the string.
+--
+-- > char *H5Tget_member_name(hid_t type_id, unsigned membno);
+#ccall H5Tget_member_name, <hid_t> -> CUInt -> IO CString
+
+-- |Returns the index of a member in a compound or enumeration
+-- datatype by given name.  Members are stored in no particular
+-- order with numbers 0 through N-1 where N is the value
+-- returned by 'h5t_get_nmembers'.
+--
+-- Returns the index of the member on success, or negative on
+-- failure.
+--
+-- > int H5Tget_member_index(hid_t type_id, const char *name);
+#ccall H5Tget_member_index, <hid_t> -> CString -> IO CInt
+
+-- |Returns the byte offset of the beginning of a member with
+-- respect to the beginning of the compound datatype datum.
+--
+-- Returns the byte offset on success, or zero on failure.
+-- Zero is a valid offset, but this function will fail only
+-- if a call to 'h5t_get_member_dims' fails with the same
+-- arguments.
+--
+-- > size_t H5Tget_member_offset(hid_t type_id, unsigned membno);
+#ccall H5Tget_member_offset, <hid_t> -> CUInt -> IO <size_t>
+
+-- |Returns the datatype class of a member of a compound datatype.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > H5T_class_t H5Tget_member_class(hid_t type_id, unsigned membno);
+#ccall H5Tget_member_class, <hid_t> -> CUInt -> IO <H5T_class_t>
+
+-- |Returns a copy of the datatype of the specified member, or negative
+-- on failure.  The caller should invoke 'h5t_close' to release resources
+-- associated with the type.
+--
+-- > hid_t H5Tget_member_type(hid_t type_id, unsigned membno);
+#ccall H5Tget_member_type, <hid_t> -> CUInt -> IO <hid_t>
+
+-- |Return the value for an enumeration data type member.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Tget_member_value(hid_t type_id, unsigned membno, void *value/*out*/);
+#ccall H5Tget_member_value, <hid_t> -> CUInt -> Out a -> IO <herr_t>
+
+-- |HDF5 is able to distinguish between character sets of
+-- different nationalities and to convert between them to the
+-- extent possible.
+--
+-- Returns the character set of a string type on success, or
+-- 'h5t_CSET_ERROR' (a negative value) on failure.
+--
+-- > H5T_cset_t H5Tget_cset(hid_t type_id);
+#ccall H5Tget_cset, <hid_t> -> IO <H5T_cset_t>
+
+-- |Check whether a datatype is a variable-length string
+--
+-- > htri_t H5Tis_variable_str(hid_t type_id);
+#ccall H5Tis_variable_str, <hid_t> -> IO <htri_t>
+
+-- |High-level API to return the native type of a datatype.
+-- The native type is chosen by matching the size and class of
+-- querried datatype from the following native premitive
+-- datatypes:
+--
+--  'h5t_NATIVE_CHAR'         'h5t_NATIVE_UCHAR'
+--  'h5t_NATIVE_SHORT'        'h5t_NATIVE_USHORT'
+--  'h5t_NATIVE_INT'          'h5t_NATIVE_UINT'
+--  'h5t_NATIVE_LONG'         'h5t_NATIVE_ULONG'
+--  'h5t_NATIVE_LLONG'        'h5t_NATIVE_ULLONG'
+--
+--  'H5T_NATIVE_FLOAT'
+--  'H5T_NATIVE_DOUBLE'
+--  'H5T_NATIVE_LDOUBLE'
+--
+-- Compound, array, enum, and VL types all choose among these
+-- types for theire members.  Time, Bifield, Opaque, Reference
+-- types are only copy out.
+--
+-- Returns the native data type if successful, negative otherwise.
+--
+-- > hid_t H5Tget_native_type(hid_t type_id, H5T_direction_t direction);
+#ccall H5Tget_native_type, <hid_t> -> <H5T_direction_t> -> IO <hid_t>
+
+-- * Setting property values
+
+-- |Sets the total size in bytes for a datatype (this operation
+-- is not permitted on reference datatypes).  If the size is
+-- decreased so that the significant bits of the datatype
+-- extend beyond the edge of the new size, then the 'offset'
+-- property is decreased toward zero.  If the 'offset' becomes
+-- zero and the significant bits of the datatype still hang
+-- over the edge of the new size, then the number of significant
+-- bits is decreased.
+--
+-- Adjusting the size of an 'h5t_STRING' automatically sets the
+-- precision to @8*size@.
+--
+-- All datatypes have a positive size.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Tset_size(hid_t type_id, size_t size);
+#ccall H5Tset_size, <hid_t> -> <size_t> -> IO <herr_t>
+
+-- |Sets the byte order for a datatype.
+--
+-- Notes:  There are some restrictions on this operation:
+--
+--  1. For enum type, members shouldn't be defined yet.
+--
+--  2. 'h5t_ORDER_NONE' only works for reference and fixed-length
+--     string.
+--
+--  3. For opaque type, the order will be ignored.
+--
+--  4. For compound type, all restrictions above apply to the
+--     members.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Tset_order(hid_t type_id, H5T_order_t order);
+#ccall H5Tset_order, <hid_t> -> <H5T_order_t> -> IO <herr_t>
+
+-- |Sets the precision of a datatype.  The precision is
+-- the number of significant bits which, unless padding is
+-- present, is 8 times larger than the value returned by
+-- 'h5t_get_size'.
+--
+-- If the precision is increased then the offset is decreased
+-- and then the size is increased to insure that significant
+-- bits do not \"hang over\" the edge of the datatype.
+--
+-- The precision property of strings is read-only.
+--
+-- When decreasing the precision of a floating point type, set
+-- the locations and sizes of the sign, mantissa, and exponent
+-- fields first.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Tset_precision(hid_t type_id, size_t prec);
+#ccall H5Tset_precision, <hid_t> -> <size_t> -> IO <herr_t>
+
+-- |Sets the bit offset of the first significant bit.  The
+-- signficant bits of an atomic datum can be offset from the
+-- beginning of the memory for that datum by an amount of
+-- padding. The `offset' property specifies the number of bits
+-- of padding that appear to the "right of" the value.  That is,
+-- if we have a 32-bit datum with 16-bits of precision having
+-- the value 0x1122 then it will be layed out in memory as (from
+-- small byte address toward larger byte addresses):
+--
+-- >     Big      Big       Little   Little
+-- >     Endian   Endian    Endian   Endian
+-- >     offset=0 offset=16 offset=0 offset=16
+-- >
+-- > 0:  [ pad]   [0x11]    [0x22]   [ pad]
+-- > 1:  [ pad]   [0x22]    [0x11]   [ pad]
+-- > 2:  [0x11]   [ pad]    [ pad]   [0x22]
+-- > 3:  [0x22]   [ pad]    [ pad]   [0x11]
+--
+-- If the offset is incremented then the total size is
+-- incremented also if necessary to prevent significant bits of
+-- the value from hanging over the edge of the data type.
+--
+-- The offset of an 'h5t_STRING' cannot be set to anything but
+-- zero.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Tset_offset(hid_t type_id, size_t offset);
+#ccall H5Tset_offset, <hid_t> -> <size_t> -> IO <herr_t>
+
+-- |Sets the LSB and MSB pad types.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Tset_pad(hid_t type_id, H5T_pad_t lsb, H5T_pad_t msb);
+#ccall H5Tset_pad, <hid_t> -> <H5T_pad_t> -> <H5T_pad_t> -> IO <herr_t>
+
+-- |Sets the sign property for an integer.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Tset_sign(hid_t type_id, H5T_sign_t sign);
+#ccall H5Tset_sign, <hid_t> -> <H5T_sign_t> -> IO <herr_t>
+
+-- |Sets the locations and sizes of the various floating point
+-- bit fields.  The field positions are bit positions in the
+-- significant region of the datatype.  Bits are numbered with
+-- the least significant bit number zero.
+--
+-- Fields are not allowed to extend beyond the number of bits of
+-- precision, nor are they allowed to overlap with one another.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Tset_fields(hid_t type_id, size_t spos, size_t epos,
+-- >        size_t esize, size_t mpos, size_t msize);
+#ccall H5Tset_fields, <hid_t> -> <size_t> -> <size_t> -> <size_t> -> <size_t> -> <size_t> -> IO <herr_t>
+
+-- |Sets the exponent bias of a floating-point type.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Tset_ebias(hid_t type_id, size_t ebias);
+#ccall H5Tset_ebias, <hid_t> -> <size_t> -> IO <herr_t>
+
+-- |Sets the mantissa normalization method for a floating point
+-- datatype.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Tset_norm(hid_t type_id, H5T_norm_t norm);
+#ccall H5Tset_norm, <hid_t> -> <H5T_norm_t> -> IO <herr_t>
+
+-- |If any internal bits of a floating point type are unused
+-- (that is, those significant bits which are not part of the
+-- sign, exponent, or mantissa) then they will be filled
+-- according to the value of this property.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Tset_inpad(hid_t type_id, H5T_pad_t pad);
+#ccall H5Tset_inpad, <hid_t> -> <H5T_pad_t> -> IO <herr_t>
+
+-- |HDF5 is able to distinguish between character sets of
+-- different nationalities and to convert between them to the
+-- extent possible.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Tset_cset(hid_t type_id, H5T_cset_t cset);
+#ccall H5Tset_cset, <hid_t> -> <H5T_cset_t> -> IO <herr_t>
+
+-- |The method used to store character strings differs with the
+-- programming language: C usually null terminates strings while
+-- Fortran left-justifies and space-pads strings.  This property
+-- defines the storage mechanism for the string.
+--
+-- When converting from a long string to a short string if the
+-- short string is 'h5t_STR_NULLPAD' or 'h5t_STR_SPACEPAD' then the
+-- string is simply truncated; otherwise if the short string is
+-- 'h5t_STR_NULLTERM' it will be truncated and a null terminator
+-- is appended.
+--
+-- When converting from a short string to a long string, the
+-- long string is padded on the end by appending nulls or
+-- spaces.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Tset_strpad(hid_t type_id, H5T_str_t strpad);
+#ccall H5Tset_strpad, <hid_t> -> <H5T_str_t> -> IO <herr_t>
+
+-- * Type conversion database
+
+-- |Register a hard or soft conversion function for a data type
+-- conversion path.  The path is specified by the source and
+-- destination data types 'src_id' and 'dst_id' (for soft functions
+-- only the class of these types is important).  If 'func' is a
+-- hard function then it replaces any previous path; if it's a
+-- soft function then it replaces all existing paths to which it
+-- applies and is used for any new path to which it applies as
+-- long as that path doesn't have a hard function.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Tregister(H5T_pers_t pers, const char *name, hid_t src_id,
+-- >        hid_t dst_id, H5T_conv_t func);
+#ccall H5Tregister, <H5T_pers_t> -> CString -> <hid_t> -> <hid_t> -> H5T_conv_t a b c -> IO <herr_t>
+
+-- |Removes conversion paths that match the specified criteria.
+-- All arguments are optional. Missing arguments are wild cards.
+-- The special no-op path cannot be removed.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Tunregister(H5T_pers_t pers, const char *name, hid_t src_id,
+-- >        hid_t dst_id, H5T_conv_t func);
+#ccall H5Tunregister, <H5T_pers_t> -> CString -> <hid_t> -> <hid_t> -> H5T_conv_t a b c -> IO <herr_t>
+
+-- TODO: check docs on this funtion and figure out what its type should be
+-- |Finds a conversion function that can handle a conversion from
+-- type 'src_id' to type 'dst_id'.  The 'pcdata' argument is a pointer
+-- to a pointer to type conversion data which was created and
+-- initialized by the type conversion function of this path
+-- when the conversion function was installed on the path.
+--
+-- > H5T_convT H5Tfind(hid_t src_id, hid_t dst_id, H5T_cdata_t **pcdata);
+#ccall H5Tfind, <hid_t> -> <hid_t> -> Out (Ptr (H5T_cdata_t c)) -> IO (H5T_conv_t a b c)
+
+-- |Finds out whether the library's conversion function from
+-- type 'src_id' to type 'dst_id' is a compiler (hard) conversion.
+-- A hard conversion uses compiler's casting; a soft conversion
+-- uses the library's own conversion function.
+--
+-- > htri_t H5Tcompiler_conv(hid_t src_id, hid_t dst_id);
+#ccall H5Tcompiler_conv, <hid_t> -> <hid_t> -> IO <htri_t>
+
+-- |Convert 'nelmts' elements from type 'src_id' to type 'dst_id'.  The
+-- source elements are packed in 'buf' and on return the
+-- destination will be packed in 'buf'.  That is, the conversion
+-- is performed in place.  The optional background buffer is an
+-- array of 'nelmts' values of destination type which are merged
+-- with the converted values to fill in cracks (for instance,
+-- 'background' might be an array of structs with the 'a' and 'b'
+-- fields already initialized and the conversion of BUF supplies
+-- the 'c' and 'd' field values).  The 'plist_id' a dataset transfer
+-- property list which is passed to the conversion functions.  (It's
+-- currently only used to pass along the VL datatype custom allocation
+-- information -QAK 7/1/99)
+--
+-- > herr_t H5Tconvert(hid_t src_id, hid_t dst_id, size_t nelmts,
+-- >        void *buf, void *background, hid_t plist_id);
+#ccall H5Tconvert, <hid_t> -> <hid_t> -> <size_t> -> InOutArray a -> InArray b -> <hid_t> -> IO <herr_t>
+
+#ifndef H5_NO_DEPRECATED_SYMBOLS
+
+-- * Symbols defined for compatibility with previous versions of the HDF5 API.
+--
+-- Use of these symbols is deprecated.
+
+-- |Save a transient datatype to a file and turn the type handle
+-- into a named, immutable type.
+--
+-- Note:  Deprecated in favor of 'h5t_commit2'
+--
+-- > herr_t H5Tcommit1(hid_t loc_id, const char *name, hid_t type_id);
+#ccall H5Tcommit1, <hid_t> -> CString -> <hid_t> -> IO <herr_t>
+
+-- |Opens a named datatype.
+--
+-- Deprecated in favor of 'h5t_open2'.
+--
+-- > hid_t H5Topen1(hid_t loc_id, const char *name);
+#ccall H5Topen1, <hid_t> -> CString -> IO <hid_t>
+
+-- |Create a new array datatype based on the specified 'base_type'.
+-- The type is an array with 'ndims' dimensionality and the size of the
+-- array is 'dims'. The total member size should be relatively small.
+-- Array datatypes are currently limited to 'h5s_MAX_RANK' number of
+-- dimensions and must have the number of dimensions set greater than
+-- 0. (i.e. @0 > ndims <= 'h5s_MAX_RANK'@)  All dimensions sizes must
+-- be greater than 0 also.
+--
+-- Returns the ID of a new array datatype on success, negative on
+-- failure.
+--
+-- > hid_t H5Tarray_create1(hid_t base_id, int ndims,
+-- >        const hsize_t dim[/* ndims */],
+-- >        const int perm[/* ndims */]);
+#ccall H5Tarray_create1, <hid_t> -> CInt -> InArray <hsize_t> -> InArray CInt -> IO <hid_t>
+
+-- |Query the sizes of dimensions for an array datatype.
+--
+-- Returns the number of dimensions of the array type on success,
+-- negative on failure.
+--
+-- > int H5Tget_array_dims1(hid_t type_id, hsize_t dims[], int perm[]);
+#ccall H5Tget_array_dims1, <hid_t> -> OutArray <hsize_t> -> OutArray CInt -> IO CInt
+
+--
+#endif /* H5_NO_DEPRECATED_SYMBOLS */
diff --git a/src/Bindings/HDF5/Raw/H5Z.hsc b/src/Bindings/HDF5/Raw/H5Z.hsc
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/H5Z.hsc
@@ -0,0 +1,293 @@
+#include <bindings.h>
+#include <H5Ipublic.h>
+#include <H5Zpublic.h>
+
+module Bindings.HDF5.Raw.H5Z where
+
+import Data.Int
+import Data.Word
+import Foreign.C.String
+import Foreign.C.Types
+import Foreign.Ptr
+import Foreign.Storable
+
+import Bindings.HDF5.Raw.H5
+import Bindings.HDF5.Raw.H5I
+import Foreign.Ptr.Conventions
+
+-- |Filter identifiers.  Values 0 through 255 are for filters defined by the
+-- HDF5 library.  Values 256 through 511 are available for testing new
+-- filters.  Subsequent values should be obtained from the HDF5 development
+-- team at <mailto:hdf5dev@ncsa.uiuc.edu>.  These values will never change
+-- because they appear in the HDF5 files.
+#newtype H5Z_filter_t, Eq
+
+-- |no filter
+#newtype_const H5Z_filter_t, H5Z_FILTER_ERROR
+
+-- |reserved indefinitely
+#newtype_const H5Z_filter_t, H5Z_FILTER_NONE
+
+-- |deflation like gzip
+#newtype_const H5Z_filter_t, H5Z_FILTER_DEFLATE
+
+-- |shuffle the data
+#newtype_const H5Z_filter_t, H5Z_FILTER_SHUFFLE
+
+-- |fletcher32 checksum of EDC
+#newtype_const H5Z_filter_t, H5Z_FILTER_FLETCHER32
+
+-- |szip compression
+#newtype_const H5Z_filter_t, H5Z_FILTER_SZIP
+
+-- |nbit compression
+#newtype_const H5Z_filter_t, H5Z_FILTER_NBIT
+
+-- |scale+offset compression
+#newtype_const H5Z_filter_t, H5Z_FILTER_SCALEOFFSET
+
+-- |filter ids below this value are reserved for library use
+#newtype_const H5Z_filter_t, H5Z_FILTER_RESERVED
+
+-- |maximum filter id
+#newtype_const H5Z_filter_t, H5Z_FILTER_MAX
+
+-- |Symbol to remove all filters in 'h5p_remove_filter'
+#newtype_const H5Z_filter_t, H5Z_FILTER_ALL
+
+-- |Maximum number of filters allowed in a pipeline
+-- (should probably be allowed to be an unlimited amount, but
+-- currently each filter uses a bit in a 32-bit field, so the
+-- format would have to be changed to accomodate that)
+#num H5Z_MAX_NFILTERS
+
+-- ** Flags for filter definition (stored)
+
+-- |definition flag mask
+#num H5Z_FLAG_DEFMASK
+
+-- |filter is mandatory
+#num H5Z_FLAG_MANDATORY
+
+-- |filter is optional
+#num H5Z_FLAG_OPTIONAL
+
+-- ** Additional flags for filter invocation (not stored
+
+-- |invocation flag mask
+#num H5Z_FLAG_INVMASK
+
+-- |reverse direction; read
+#num H5Z_FLAG_REVERSE
+
+-- |skip EDC filters for read
+#num H5Z_FLAG_SKIP_EDC
+
+-- ** Special parameters for szip compression
+-- [These are aliases for the similar definitions in szlib.h, which we can't
+-- include directly due to the duplication of various symbols with the zlib.h
+-- header file]
+#num H5_SZIP_ALLOW_K13_OPTION_MASK
+#num H5_SZIP_CHIP_OPTION_MASK
+#num H5_SZIP_EC_OPTION_MASK
+#num H5_SZIP_NN_OPTION_MASK
+#num H5_SZIP_MAX_PIXELS_PER_BLOCK
+
+-- ** Macros for the shuffle filter
+
+-- |Number of parameters that users can set
+#num H5Z_SHUFFLE_USER_NPARMS
+
+-- |Total number of parameters for filter
+#num H5Z_SHUFFLE_TOTAL_NPARMS
+
+-- ** Macros for the szip filter
+
+-- |Number of parameters that users can set
+#num H5Z_SZIP_USER_NPARMS
+
+-- |Total number of parameters for filter
+#num H5Z_SZIP_TOTAL_NPARMS
+
+-- |\"User\" parameter for option mask
+#num H5Z_SZIP_PARM_MASK
+
+-- |\"User\" parameter for pixels-per-block
+#num H5Z_SZIP_PARM_PPB
+
+-- |\"Local\" parameter for bits-per-pixel
+#num H5Z_SZIP_PARM_BPP
+
+-- |\"Local\" parameter for pixels-per-scanline
+#num H5Z_SZIP_PARM_PPS
+
+-- ** Macros for the nbit filter
+
+-- |Number of parameters that users can set
+#num H5Z_NBIT_USER_NPARMS
+
+-- ** Macros for the scale offset filter
+
+-- |Number of parameters that users can set
+#num H5Z_SCALEOFFSET_USER_NPARMS
+
+-- ** Special parameters for ScaleOffset filter
+#num H5Z_SO_INT_MINBITS_DEFAULT
+#newtype H5Z_SO_scale_type_t
+#newtype_const H5Z_SO_scale_type_t, H5Z_SO_FLOAT_DSCALE
+#newtype_const H5Z_SO_scale_type_t, H5Z_SO_FLOAT_ESCALE
+#newtype_const H5Z_SO_scale_type_t, H5Z_SO_INT
+
+-- |Current version of the H5Z_class_t struct
+#num H5Z_CLASS_T_VERS
+
+-- |Values to decide if EDC is enabled for reading data
+#newtype H5Z_EDC_t
+#newtype_const H5Z_EDC_t, H5Z_ERROR_EDC
+#newtype_const H5Z_EDC_t, H5Z_DISABLE_EDC
+#newtype_const H5Z_EDC_t, H5Z_ENABLE_EDC
+#newtype_const H5Z_EDC_t, H5Z_NO_EDC
+
+-- ** Bit flags for H5Zget_filter_info
+#num H5Z_FILTER_CONFIG_ENCODE_ENABLED
+#num H5Z_FILTER_CONFIG_DECODE_ENABLED
+
+-- |Return values for filter callback function
+#newtype H5Z_cb_return_t
+
+#newtype_const H5Z_cb_return_t, H5Z_CB_ERROR
+
+-- |I/O should fail if filter fails.
+#newtype_const H5Z_cb_return_t, H5Z_CB_FAIL
+
+-- |I/O continues if filter fails.
+#newtype_const H5Z_cb_return_t, H5Z_CB_CONT
+
+#newtype_const H5Z_cb_return_t, H5Z_CB_NO
+
+-- |Filter callback function definition
+--
+-- > typedef H5Z_cb_return_t (*H5Z_filter_func_t)(H5Z_filter_t filter, void* buf,
+-- >        size_t buf_size, void* op_data);
+type H5Z_filter_func_t a b = FunPtr (H5Z_filter_t -> InOutArray a -> CSize -> InOut b -> IO H5Z_cb_return_t)
+
+-- |Before a dataset gets created, the \"can_apply\" callbacks for any filters used
+-- in the dataset creation property list are called
+-- with the dataset's dataset creation property list, the dataset's datatype and
+-- a dataspace describing a chunk (for chunked dataset storage).
+--
+-- The \"can_apply\" callback must determine if the combination of the dataset
+-- creation property list setting, the datatype and the dataspace represent a
+-- valid combination to apply this filter to.  For example, some cases of
+-- invalid combinations may involve the filter not operating correctly on
+-- certain datatypes (or certain datatype sizes), or certain sizes of the chunk
+-- dataspace.
+--
+-- The \"can_apply\" callback can be the NULL pointer, in which case, the library
+-- will assume that it can apply to any combination of dataset creation
+-- property list values, datatypes and dataspaces.
+--
+-- The \"can_apply\" callback returns positive a valid combination, zero for an
+-- invalid combination and negative for an error.
+--
+-- > typedef htri_t (*H5Z_can_apply_func_t)(hid_t dcpl_id, hid_t type_id, hid_t space_id);
+#callback H5Z_can_apply_func_t, <hid_t> -> <hid_t> -> <hid_t> -> IO <htri_t>
+
+-- |After the \"can_apply\" callbacks are checked for new datasets, the \"set_local\"
+-- callbacks for any filters used in the dataset creation property list are
+-- called.  These callbacks receive the dataset's private copy of the dataset
+-- creation property list passed in to H5Dcreate (i.e. not the actual property
+-- list passed in to H5Dcreate) and the datatype ID passed in to H5Dcreate
+-- (which is not copied and should not be modified) and a dataspace describing
+-- the chunk (for chunked dataset storage) (which should also not be modified).
+--
+-- The \"set_local\" callback must set any parameters that are specific to this
+-- dataset, based on the combination of the dataset creation property list
+-- values, the datatype and the dataspace.  For example, some filters perform
+-- different actions based on different datatypes (or datatype sizes) or
+-- different number of dimensions or dataspace sizes.
+--
+-- The \"set_local\" callback can be the NULL pointer, in which case, the library
+-- will assume that there are no dataset-specific settings for this filter.
+--
+-- The \"set_local\" callback must return non-negative on success and negative
+-- for an error.
+--
+-- > typedef herr_t (*H5Z_set_local_func_t)(hid_t dcpl_id, hid_t type_id, hid_t space_id);
+#callback H5Z_set_local_func_t, <hid_t> -> <hid_t> -> <hid_t> -> IO <herr_t>
+
+-- |A filter gets definition flags and invocation flags (defined above), the
+-- client data array and size defined when the filter was added to the
+-- pipeline, the size in bytes of the data on which to operate, and pointers
+-- to a buffer and its allocated size.
+--
+-- The filter should store the result in the supplied buffer if possible,
+-- otherwise it can allocate a new buffer, freeing the original.  The
+-- allocated size of the new buffer should be returned through the 'buf_size'
+-- pointer and the new buffer through the BUF pointer.
+--
+-- The return value from the filter is the number of bytes in the output
+-- buffer.  If an error occurs then the function should return zero and leave
+-- all pointer arguments unchanged.
+--
+-- > typedef size_t (*H5Z_func_t)(unsigned int flags, size_t cd_nelmts,
+-- >        const unsigned int cd_values[], size_t nbytes,
+-- >        size_t *buf_size, void **buf);
+type H5Z_func_t a = FunPtr (CUInt -> CSize -> InArray CUInt -> CSize -> InOut CSize -> InOut (Ptr a) -> IO CSize)
+
+-- | The filter table maps filter identification numbers to structs that
+-- contain a pointers to the filter function and timing statistics.
+#starttype H5Z_class2_t
+
+-- | Version number of the H5Z_class_t struct
+#field version, CInt
+
+-- | Filter ID number
+#field id, <H5Z_filter_t>
+
+-- | Does this filter have an encoder?
+#field encoder_present, CUInt
+
+-- | Does this filter have a decoder?
+#field decoder_present, CUInt
+
+-- | Comment for debugging
+#field name, CString
+
+-- | The \"can apply\" callback for a filter
+#field can_apply, <H5Z_can_apply_func_t>
+
+-- | The \"set local\" callback for a filter
+#field set_local, <H5Z_set_local_func_t>
+
+-- | The actual filter function
+#field filter, H5Z_func_t ()
+
+#stoptype
+
+-- |This function registers a new filter.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Zregister(const void *cls);
+#ccall H5Zregister, In <H5Z_class2_t> -> IO <herr_t>
+
+-- |This function unregisters a filter.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Zunregister(H5Z_filter_t id);
+#ccall H5Zunregister, <H5Z_filter_t> -> IO <herr_t>
+
+-- |Check if a filter is available
+--
+-- > htri_t H5Zfilter_avail(H5Z_filter_t id);
+#ccall H5Zfilter_avail, <H5Z_filter_t> -> IO <htri_t>
+
+-- |Gets information about a pipeline data filter and stores it
+-- in 'filter_config_flags'.
+--
+-- Returns non-negative on success, negative on failure.
+--
+-- > herr_t H5Zget_filter_info(H5Z_filter_t filter, unsigned int *filter_config_flags);
+#ccall H5Zget_filter_info, <H5Z_filter_t> -> Out CUInt -> IO <herr_t>
diff --git a/src/Bindings/HDF5/Raw/Util.hs b/src/Bindings/HDF5/Raw/Util.hs
new file mode 100644
--- /dev/null
+++ b/src/Bindings/HDF5/Raw/Util.hs
@@ -0,0 +1,16 @@
+module Bindings.HDF5.Raw.Util where
+
+import Bindings.HDF5.Raw
+
+hboolToBool :: HBool_t -> Bool
+hboolToBool (HBool_t n) = n /= 0
+
+boolToHBool :: Bool -> HBool_t
+boolToHBool True  = HBool_t 1
+boolToHBool False = HBool_t 0
+
+test_htri_t :: HTri_t -> Maybe Bool
+test_htri_t (HTri_t n) = case compare n 0 of
+    LT -> Nothing
+    EQ -> Just False
+    GT -> Just True
diff --git a/src/Foreign/LibFFI.hs b/src/Foreign/LibFFI.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/LibFFI.hs
@@ -0,0 +1,28 @@
+{- |
+This is the only module that normal users should need to import.
+
+As an example, allocate 1GB of memory, zero it, and crash:
+
+@
+import System.Posix.DynamicLinker
+import Foreign.Ptr
+import Foreign.LibFFI
+
+main = do
+    malloc <- dlsym Default \"malloc\"
+    memset <- dlsym Default \"memset\"
+    p <- callFFI malloc (retPtr retVoid) [argCSize (2^30)]
+    callFFI memset (retPtr retVoid) [argPtr p, argCInt 0, argCSize (2^30)]
+    callFFI memset (retPtr retVoid) [argPtr nullPtr, argCInt 0, argCSize 1]
+@
+-}
+module Foreign.LibFFI
+    (Arg
+    ,RetType
+    ,callFFI
+    ,withRetType
+    ,module Foreign.LibFFI.Types
+    ) where
+
+import Foreign.LibFFI.Base
+import Foreign.LibFFI.Types
diff --git a/src/Foreign/LibFFI/Base.hs b/src/Foreign/LibFFI/Base.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/LibFFI/Base.hs
@@ -0,0 +1,65 @@
+{- | This module defines the basic libffi machinery. You will need this to create support for new ffi types. -}
+module Foreign.LibFFI.Base where
+
+import           Control.Monad
+import           Data.List
+
+import           Foreign.Marshal
+import           Foreign.Ptr
+import           Foreign.Storable
+
+import           Foreign.LibFFI.FFITypes
+import           Foreign.LibFFI.Internal
+
+newtype Arg = Arg { unArg :: IO (Ptr CType, Ptr CValue, IO ()) }
+
+customPointerArg :: (a -> IO (Ptr b)) -> (Ptr b -> IO ()) -> a -> Arg
+customPointerArg newA freeA a = Arg $ do
+    p <- newA a
+    pp <- new p
+    return (ffi_type_pointer, castPtr pp, free pp >> freeA p)
+
+mkStorableArg :: Storable a => Ptr CType -> a -> Arg
+mkStorableArg cType a = Arg $ do
+    p <- malloc
+    poke p a
+    return (cType, castPtr p, free p)
+
+data RetType a = RetType (Ptr CType) ((Ptr CValue -> IO ()) -> IO a)
+
+instance Functor RetType where
+    fmap f  = withRetType (return . f)
+
+withRetType :: (a -> IO b) -> RetType a -> RetType b
+withRetType f (RetType cType withPoke)
+            = RetType cType (withPoke >=> f)
+
+mkStorableRetType :: Storable a => Ptr CType -> RetType a
+mkStorableRetType cType
+            = RetType cType
+                (\write -> alloca $ \ptr -> write (castPtr ptr) >> peek ptr)
+
+newStorableStructArgRet :: Storable a => [Ptr CType] -> IO (a -> Arg, RetType a, IO ())
+newStorableStructArgRet cTypes = do
+    (cType, freeit) <- newStructCType cTypes
+    return (mkStorableArg cType, mkStorableRetType cType, freeit)
+
+newStructCType  :: [Ptr CType] -> IO (Ptr CType, IO ())
+newStructCType cTypes = do
+    ffi_type <- mallocBytes sizeOf_ffi_type
+    elements <- newArray0 nullPtr cTypes
+    init_ffi_type ffi_type elements
+    return (ffi_type, free ffi_type >> free elements)
+
+callFFI :: FunPtr a -> RetType b -> [Arg] -> IO b
+callFFI funPtr (RetType cRetType withRet) args
+    = allocaBytes sizeOf_cif $ \cif -> do
+        (cTypes, cValues, frees) <- unzip3 `liftM` mapM unArg args
+        withArray cTypes $ \cTypesPtr -> do
+            status <- ffi_prep_cif cif ffi_default_abi (genericLength args) cRetType cTypesPtr
+            unless (status == ffi_ok) $
+                error "callFFI: ffi_prep_cif failed"
+            withArray cValues $ \cValuesPtr -> do
+                ret <- withRet (\cRet -> ffi_call cif funPtr cRet cValuesPtr)
+                sequence_ frees
+                return ret
diff --git a/src/Foreign/LibFFI/FFITypes.hs b/src/Foreign/LibFFI/FFITypes.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/LibFFI/FFITypes.hs
@@ -0,0 +1,83 @@
+{-# LANGUAGE ForeignFunctionInterface #-}
+{- | The pointers exported and used by the C libffi describing basic ffi types. -}
+module Foreign.LibFFI.FFITypes where
+
+import           Foreign.C.Types
+import           Foreign.Ptr
+import           Foreign.Storable
+
+import           Foreign.LibFFI.Internal
+
+foreign import ccall unsafe "&" ffi_type_void :: Ptr CType
+foreign import ccall unsafe "&" ffi_type_sint8 :: Ptr CType
+foreign import ccall unsafe "&" ffi_type_uint8 :: Ptr CType
+foreign import ccall unsafe "&" ffi_type_uint16 :: Ptr CType
+foreign import ccall unsafe "&" ffi_type_sint16 :: Ptr CType
+foreign import ccall unsafe "&" ffi_type_uint32 :: Ptr CType
+foreign import ccall unsafe "&" ffi_type_sint32 :: Ptr CType
+foreign import ccall unsafe "&" ffi_type_uint64 :: Ptr CType
+foreign import ccall unsafe "&" ffi_type_sint64 :: Ptr CType
+foreign import ccall unsafe "&" ffi_type_float  :: Ptr CType
+foreign import ccall unsafe "&" ffi_type_double :: Ptr CType
+foreign import ccall unsafe "&" ffi_type_pointer :: Ptr CType
+
+ffi_type_uchar  :: Ptr CType
+ffi_type_uchar  = ffi_type_uint8
+
+ffi_type_schar  :: Ptr CType
+ffi_type_schar  = ffi_type_sint8
+
+ffi_type_wchar  :: Ptr CType
+ffi_type_wchar  = case sizeOf (undefined :: CWchar) of
+                    2 -> ffi_type_sint16
+                    4 -> ffi_type_sint32
+                    8 -> ffi_type_sint64
+                    _ -> error "ffi_type_wchar of unsupported size"
+
+ffi_type_size   :: Ptr CType
+ffi_type_size   = case sizeOf (undefined :: CSize) of
+                    4 -> ffi_type_uint32
+                    8 -> ffi_type_uint64
+                    _ -> error "ffi_type_size of unsupported size"
+
+ffi_type_time   :: Ptr CType
+ffi_type_time   = case sizeOf (undefined :: CTime) of
+                    4 -> ffi_type_sint32
+                    8 -> ffi_type_sint64
+                    _ -> error "ffi_type_time of unsupported size"
+
+ffi_type_uint   :: Ptr CType
+ffi_type_uint   = case sizeOf (undefined :: CUInt) of
+                    4 -> ffi_type_uint32
+                    8 -> ffi_type_uint64
+                    _ -> error "ffi_type_uint of unsupported size"
+
+ffi_type_sint   :: Ptr CType
+ffi_type_sint   = case sizeOf (undefined :: CInt) of
+                    4 -> ffi_type_sint32
+                    8 -> ffi_type_sint64
+                    _ -> error "ffi_type_sint of unsupported size"
+
+ffi_type_ulong  :: Ptr CType
+ffi_type_ulong  = case sizeOf (undefined :: CULong) of
+                    4 -> ffi_type_uint32
+                    8 -> ffi_type_uint64
+                    _ -> error "ffi_type_ulong of unsupported size"
+
+ffi_type_slong  :: Ptr CType
+ffi_type_slong  = case sizeOf (undefined :: CLong) of
+                    4 -> ffi_type_sint32
+                    8 -> ffi_type_sint64
+                    _ -> error "ffi_type_slong of unsupported size"
+
+ffi_type_hs_int :: Ptr CType
+ffi_type_hs_int = case sizeOf (undefined :: Int) of
+                    4 -> ffi_type_sint32
+                    8 -> ffi_type_sint64
+                    _ -> error "ffi_type_hs_int: unsupported sizeOf (_ :: Int)"
+
+ffi_type_hs_word :: Ptr CType
+ffi_type_hs_word = case sizeOf (undefined :: Word) of
+                    4   -> ffi_type_uint32
+                    8   -> ffi_type_uint64
+                    _   -> error "ffi_type_hs_word: unsupported sizeOf (_ :: Word)"
diff --git a/src/Foreign/LibFFI/Internal.hsc b/src/Foreign/LibFFI/Internal.hsc
new file mode 100644
--- /dev/null
+++ b/src/Foreign/LibFFI/Internal.hsc
@@ -0,0 +1,42 @@
+{-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-}
+{- | The internals of the C library libffi -}
+module Foreign.LibFFI.Internal where
+
+#include <ffi.h>
+
+import Data.Word
+import Foreign.C.Types
+import Foreign.Ptr
+import Foreign.Storable
+
+data CValue
+data CType
+data CIF
+
+type C_ffi_status   = (#type ffi_status)
+type C_ffi_abi      = (#type ffi_abi)
+
+ffi_default_abi :: C_ffi_abi
+ffi_default_abi = #const FFI_DEFAULT_ABI
+
+ffi_ok          :: C_ffi_status
+ffi_ok          = #const FFI_OK
+
+sizeOf_cif :: Int
+sizeOf_cif = #size ffi_cif
+
+sizeOf_ffi_type :: Int
+sizeOf_ffi_type = #size ffi_type
+
+init_ffi_type   :: Ptr CType -> Ptr (Ptr CType) -> IO ()
+init_ffi_type cType cTypes = do
+    (#poke ffi_type, size) cType (0 :: CSize)
+    (#poke ffi_type, alignment) cType (0 :: CUShort)
+    (#poke ffi_type, type) cType ((#const FFI_TYPE_STRUCT) :: CUShort)
+    (#poke ffi_type, elements) cType cTypes
+
+foreign import ccall safe ffi_prep_cif
+    :: Ptr CIF -> C_ffi_abi -> CUInt -> Ptr CType -> Ptr (Ptr CType) -> IO C_ffi_status
+
+foreign import ccall safe ffi_call
+    :: Ptr CIF -> FunPtr a -> Ptr CValue -> Ptr (Ptr CValue) -> IO ()
diff --git a/src/Foreign/LibFFI/Types.hs b/src/Foreign/LibFFI/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/LibFFI/Types.hs
@@ -0,0 +1,223 @@
+-- | Arguments and return types
+module Foreign.LibFFI.Types (
+    -- * Arguments
+    -- ** Integral types
+    argCInt,
+    argCUInt,
+    argCLong,
+    argCULong,
+    argInt,
+    argInt8,
+    argInt16,
+    argInt32,
+    argInt64,
+    argWord,
+    argWord8,
+    argWord16,
+    argWord32,
+    argWord64,
+    -- ** Floating point types
+    argCFloat,
+    argCDouble,
+    -- ** Various other C types
+    argCSize,
+    argCTime,
+    argCChar,
+    argCUChar,
+    argCWchar,
+    argPtr,
+    argFunPtr,
+    -- ** Strings
+    argString,
+    argByteString,
+    argConstByteString,
+    -- * Return types
+    -- ** Integral types
+    retVoid,
+    retCInt,
+    retCUInt,
+    retCLong,
+    retCULong,
+    retInt,
+    retInt8,
+    retInt16,
+    retInt32,
+    retInt64,
+    retWord,
+    retWord8,
+    retWord16,
+    retWord32,
+    retWord64,
+    -- ** Floating point types
+    retCFloat,
+    retCDouble,
+    -- ** Various other C types
+    retCSize,
+    retCTime,
+    retCChar,
+    retCUChar,
+    retCWchar,
+    retPtr,
+    retFunPtr,
+    -- ** Strings
+    retCString,
+    retString,
+    retByteString,
+    retMallocByteString
+    ) where
+
+import           Data.Int
+import           Data.Word
+
+import qualified Data.ByteString         as BS
+import qualified Data.ByteString.Unsafe  as BSU
+import           Foreign.C.String
+import           Foreign.C.Types
+import           Foreign.Marshal
+import           Foreign.Ptr
+
+import           Foreign.LibFFI.Base
+import           Foreign.LibFFI.FFITypes
+
+argCInt     :: CInt -> Arg
+argCInt     = mkStorableArg ffi_type_sint
+argCUInt    :: CUInt -> Arg
+argCUInt    = mkStorableArg ffi_type_uint
+argCLong    :: CLong -> Arg
+argCLong    = mkStorableArg ffi_type_slong
+argCULong   :: CULong -> Arg
+argCULong   = mkStorableArg ffi_type_ulong
+
+-- | Note that on e.g. x86_64, Int \/= CInt
+argInt      :: Int -> Arg
+argInt      = mkStorableArg ffi_type_hs_int
+argInt8     :: Int8 -> Arg
+argInt8     = mkStorableArg ffi_type_sint8
+argInt16    :: Int16 -> Arg
+argInt16    = mkStorableArg ffi_type_sint16
+argInt32    :: Int32 -> Arg
+argInt32    = mkStorableArg ffi_type_sint32
+argInt64    :: Int64 -> Arg
+argInt64    = mkStorableArg ffi_type_sint64
+
+argWord     :: Word -> Arg
+argWord     = mkStorableArg ffi_type_hs_word
+argWord8    :: Word8 -> Arg
+argWord8    = mkStorableArg ffi_type_uint8
+argWord16   :: Word16 -> Arg
+argWord16   = mkStorableArg ffi_type_uint16
+argWord32   :: Word32 -> Arg
+argWord32   = mkStorableArg ffi_type_uint32
+argWord64   :: Word64 -> Arg
+argWord64   = mkStorableArg ffi_type_uint64
+
+argCFloat   :: CFloat -> Arg
+argCFloat   = mkStorableArg ffi_type_float
+argCDouble  :: CDouble -> Arg
+argCDouble  = mkStorableArg ffi_type_double
+
+argCSize    :: CSize -> Arg
+argCSize    = mkStorableArg ffi_type_size
+argCTime    :: CTime -> Arg
+argCTime    = mkStorableArg ffi_type_size
+
+argCChar    :: CChar -> Arg
+argCChar    = mkStorableArg ffi_type_schar
+argCUChar   :: CUChar -> Arg
+argCUChar   = mkStorableArg ffi_type_uchar
+
+argCWchar   :: CWchar -> Arg
+argCWchar   = mkStorableArg ffi_type_schar
+
+argPtr      :: Ptr a -> Arg
+argPtr      = mkStorableArg ffi_type_pointer
+
+argFunPtr   :: FunPtr a -> Arg
+argFunPtr   = mkStorableArg ffi_type_pointer
+
+{- | The string argument is passed to C as a char * pointer, which is freed afterwards.
+     The argument should not contain zero-bytes. -}
+argString   :: String -> Arg
+argString   = customPointerArg newCString free
+
+-- | Like argString, but for ByteString's.
+argByteString  :: BS.ByteString -> Arg
+argByteString  = customPointerArg (flip BS.useAsCString return) (const $ return ())
+
+-- | Like argByteString, but changing the string from C breaks referential transparency.
+argConstByteString  :: BS.ByteString -> Arg
+argConstByteString  = customPointerArg (flip BSU.unsafeUseAsCString return) (const $ return ())
+
+retVoid     :: RetType ()
+retVoid     = RetType ffi_type_void (\write -> write nullPtr >> return ())
+
+retCInt     :: RetType CInt
+retCInt     = mkStorableRetType ffi_type_sint
+retCUInt    :: RetType CUInt
+retCUInt    = mkStorableRetType ffi_type_uint
+retCLong    :: RetType CLong
+retCLong    = mkStorableRetType ffi_type_slong
+retCULong   :: RetType CULong
+retCULong   = mkStorableRetType ffi_type_ulong
+
+retInt      :: RetType Int
+retInt      = mkStorableRetType ffi_type_hs_int
+retInt8     :: RetType Int8
+retInt8     = mkStorableRetType ffi_type_sint8
+retInt16    :: RetType Int16
+retInt16    = mkStorableRetType ffi_type_sint16
+retInt32    :: RetType Int32
+retInt32    = mkStorableRetType ffi_type_sint32
+retInt64    :: RetType Int64
+retInt64    = mkStorableRetType ffi_type_sint64
+
+retWord     :: RetType Word
+retWord     = mkStorableRetType ffi_type_hs_word
+retWord8    :: RetType Word8
+retWord8    = mkStorableRetType ffi_type_uint8
+retWord16   :: RetType Word16
+retWord16   = mkStorableRetType ffi_type_uint16
+retWord32   :: RetType Word32
+retWord32   = mkStorableRetType ffi_type_uint32
+retWord64   :: RetType Word64
+retWord64   = mkStorableRetType ffi_type_uint64
+
+retCFloat   :: RetType CFloat
+retCFloat   = mkStorableRetType ffi_type_float
+retCDouble  :: RetType CDouble
+retCDouble  = mkStorableRetType ffi_type_double
+
+retCSize    :: RetType CSize
+retCSize    = mkStorableRetType ffi_type_size
+retCTime    :: RetType CTime
+retCTime    = mkStorableRetType ffi_type_time
+
+retCChar    :: RetType CChar
+retCChar    = mkStorableRetType ffi_type_schar
+retCUChar   :: RetType CUChar
+retCUChar   = mkStorableRetType ffi_type_uchar
+
+retCWchar   :: RetType CWchar
+retCWchar   = mkStorableRetType ffi_type_schar
+
+retFunPtr   :: RetType a -> RetType (FunPtr a)
+retFunPtr _ = mkStorableRetType ffi_type_pointer
+
+retPtr      :: RetType a -> RetType (Ptr a)
+retPtr _    = mkStorableRetType ffi_type_pointer
+
+retCString          :: RetType CString
+retCString          = retPtr retCChar
+
+{- | Peek a String out of the returned char *. The char * is not freed. -}
+retString           :: RetType String
+retString           = withRetType peekCString (retPtr retCChar)
+
+{- | Like retString, but for ByteString's -}
+retByteString       :: RetType BS.ByteString
+retByteString       = withRetType BS.packCString (retPtr retCChar)
+
+{- | Make a ByteString out of the returned char *.
+     The char * will be free(3)ed when the ByteString is garbage collected. -}
+retMallocByteString :: RetType BS.ByteString
+retMallocByteString = withRetType BSU.unsafePackMallocCString (retPtr retCChar)
diff --git a/src/Foreign/Ptr/Conventions.hs b/src/Foreign/Ptr/Conventions.hs
new file mode 100644
--- /dev/null
+++ b/src/Foreign/Ptr/Conventions.hs
@@ -0,0 +1,224 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving, FlexibleContexts #-}
+-- |various common data-passing conventions
+module Foreign.Ptr.Conventions where
+
+-- TODO: make these all exception-safe
+-- TODO: reverse order of 'out' returns
+-- TODO: bytestring versions?  versions allocating by byte but using vectors?
+import Foreign.C.Types
+import Foreign.Marshal
+import Foreign.Ptr
+import Foreign.ForeignPtr
+import Foreign.Storable
+
+import Control.Monad.IO.Class
+import Control.Monad.Trans.Control
+import Control.Exception.Lifted
+
+import qualified Data.ByteString as BS
+import qualified Data.Vector.Storable as SV
+import qualified Data.Vector.Storable.Mutable as SVM
+
+class WrappedPtr p where
+    wrapPtr         :: Ptr a -> p a
+    unwrapPtr       :: p a -> Ptr a
+    nullWrappedPtr  :: p a
+    nullWrappedPtr = wrapPtr nullPtr
+    castWrappedPtr  :: p a -> p b
+    castWrappedPtr = wrapPtr . castPtr . unwrapPtr
+
+instance WrappedPtr Foreign.Ptr.Ptr where
+    wrapPtr         = id
+    unwrapPtr       = id
+    nullWrappedPtr  = nullPtr
+    castWrappedPtr  = castPtr
+
+-- * Input pointers
+
+-- |In by-ref parameter; memory is allocated and freed by caller
+newtype In       a = In       (Ptr a) deriving (Eq, Ord, Show, Storable, WrappedPtr)
+
+-- |In by-ref array; memory is allocated and freed by caller
+newtype InArray  a = InArray  (Ptr a) deriving (Eq, Ord, Show, Storable, WrappedPtr)
+
+withIn :: (Storable a, MonadBaseControl IO m) => a -> (In a -> m b) -> m b
+withIn x f = liftBaseOp (with x) (f . In)
+
+withInList :: (Storable a, MonadBaseControl IO m) => [a] -> (InArray a -> m b) -> m b
+withInList xs f = liftBaseOp (withArray xs) (f . InArray)
+
+withInVector :: (Storable a, MonadBaseControl IO m) => SV.Vector a -> (InArray a -> m b) -> m b
+withInVector vec f = liftBaseOp (SV.unsafeWith vec) (f . InArray)
+
+withInMVector :: (Storable a, MonadBaseControl IO m) => SVM.IOVector a -> (InArray a -> m b) -> m b
+withInMVector vec f = liftBaseOp (SVM.unsafeWith vec) (f . InArray)
+
+-- * Output pointers
+
+-- |Out by-ref parameter; memory is allocated and freed by caller
+newtype Out      a = Out      (Ptr a) deriving (Eq, Ord, Show, Storable, WrappedPtr)
+
+-- |Out by-ref array; length is specified by caller, memory is allocated
+-- and freed by caller
+newtype OutArray a = OutArray (Ptr a) deriving (Eq, Ord, Show, Storable, WrappedPtr)
+
+withOut :: (Storable a, MonadBaseControl IO m, MonadIO m) => (Out a -> m b) -> m (a,b)
+withOut f = liftBaseOp alloca $ \p -> do
+    b <- f (Out p)
+    a <- liftIO (peek p)
+    return (a,b)
+
+withMaybeOut :: (Storable a, MonadBaseControl IO m, MonadIO m) => (Out a -> m Bool) -> m (Maybe a)
+withMaybeOut f = liftBaseOp alloca $ \p -> do
+    success <- f (Out p)
+    if success
+        then do
+            a <- liftIO (peek p)
+            return (Just a)
+        else return Nothing
+
+withOut_ :: (Storable a, MonadBaseControl IO m, MonadIO m) => (Out a -> m b) -> m a
+withOut_ f = liftBaseOp alloca $ \p -> do
+    _ <- f (Out p)
+    liftIO (peek p)
+
+withOutMVector :: (Storable a, MonadBaseControl IO m) => SVM.IOVector a -> (Int -> OutArray a -> m b) -> m b
+withOutMVector vec f =
+    liftBaseOp (SVM.unsafeWith vec) (f (SVM.length vec) . OutArray)
+
+withOutVector :: (Storable a, MonadBaseControl IO m, MonadIO m) => Int -> (OutArray a -> m b) -> m (SV.Vector a, b)
+withOutVector n f = do
+    p <- liftIO (mallocForeignPtrArray n)
+    b <- liftBaseOp (withForeignPtr p) (f . OutArray)
+    return (SV.unsafeFromForeignPtr p 0 n, b)
+
+
+-- NOTE: withOutVector_ and withOutVector' don't typecheck unless you specify the monad type as IO
+
+withOutVector_ :: (Storable a) => Int -> (OutArray a -> IO b) -> IO (SV.Vector a)
+withOutVector_ n f = do
+    p <- liftIO (mallocForeignPtrArray n)
+    _ <- liftBaseOp (withForeignPtr p) (f . OutArray)
+    return (SV.unsafeFromForeignPtr p 0 n)
+
+withOutVector' :: (Storable a, Integral b) => Int -> (OutArray a -> IO b) -> IO (SV.Vector a)
+withOutVector' sz f = do
+    p <- liftIO (mallocForeignPtrArray sz)
+    n <- liftBaseOp (withForeignPtr p) (f . OutArray)
+    return (SV.unsafeFromForeignPtr p 0 (fromIntegral n))
+
+withOutList :: (Storable a, MonadIO m) => Int -> (OutArray a -> m b) -> m ([a],b)
+withOutList n f = do
+    p <- liftIO (mallocArray n)
+    b <- f (OutArray p)
+    a <- liftIO (peekArray n p)
+    liftIO (free p)
+    return (a, b)
+
+withOutList_ :: (Storable a, MonadIO m) => Int -> (OutArray a -> m b) -> m [a]
+withOutList_ n f = do
+    p <- liftIO (mallocArray n)
+    _ <- f (OutArray p)
+    a <- liftIO (peekArray n p)
+    liftIO (free p)
+    return a
+
+withOutList' :: (Storable a, MonadIO m) => Int -> (OutArray a -> m Int) -> m ([a], Int)
+withOutList' sz f = do
+    p <- liftIO (mallocArray sz)
+    n <- f (OutArray p)
+    a <- liftIO (peekArray n p)
+    liftIO (free p)
+    return (a, n)
+
+-- | @withOutList0 zero n f@: allocate an array large enough to hold @n@ elements,
+-- plus one extra spot for a terminator.  Calls @f@ with that buffer, which is
+-- expected to fill it with up to @n@ elements, followed by @zero@.  The
+-- elements are then read out into a list.
+withOutList0 :: (Storable a, Eq a, MonadIO m) => a -> Int -> (OutArray a -> m b) -> m ([a], b)
+withOutList0 zero n f = do
+    p <- liftIO (mallocArray0 n)
+    b <- f (OutArray p)
+    a <- liftIO (peekArray0 zero p)
+    liftIO (free p)
+    return (a, b)
+
+-- |Get a 'BS.ByteString' from a function using the common \"buffer and size in,
+-- bytes written out\" convention.
+--
+-- Calls the function twice; once with a null pointer to discover the length
+-- needed and once more to actually read out the string.
+withOutByteString :: (MonadBaseControl IO m, MonadIO m, Integral a, Integral b) => (OutArray CChar -> a -> m b) -> m BS.ByteString
+withOutByteString f = do
+    bufSz <- f nullWrappedPtr 0
+
+    bracket (liftIO (mallocBytes (fromIntegral bufSz))) (liftIO . free) $ \buf -> do
+        sz <- f (OutArray buf) (fromIntegral bufSz)
+
+        liftIO (BS.packCStringLen (buf, fromIntegral sz))
+
+-- | Variant of withOutByteString which expects the discovered length to be one byte less than
+--   the required buffer size.  As required for H5Fget_name
+withOutByteString' :: (MonadBaseControl IO m, MonadIO m, Integral a, Integral b) => (OutArray CChar -> a -> m b) -> m BS.ByteString
+withOutByteString' f = do
+    bufSz <- f nullWrappedPtr 0
+    -- bufSz should be 1 minus the length of the buffer which needs allocating
+    let bufSz' = bufSz + 1
+
+    bracket (liftIO (mallocBytes (fromIntegral bufSz'))) (liftIO . free) $ \buf -> do
+        sz <- f (OutArray buf) (fromIntegral bufSz')
+
+        liftIO (BS.packCStringLen (buf, fromIntegral sz))
+
+
+-- * Bidirectional pointers
+
+-- |In-out parameter.  Memory is allocated and freed by caller.
+newtype InOut    a = InOut    (Ptr a) deriving (Eq, Ord, Show, Storable, WrappedPtr)
+
+newtype InOutArray a = InOutArray (Ptr a) deriving (Eq, Ord, Show, Storable, WrappedPtr)
+
+withInOut :: (Storable a, MonadBaseControl IO m, MonadIO m) => a -> (InOut a -> m b) -> m (a,b)
+withInOut a f = liftBaseOp alloca $ \p -> do
+    liftIO (poke p a)
+    b <- f (InOut p)
+    a_ <- liftIO (peek p)
+    return (a_,b)
+
+withInOut_ :: (Storable a, MonadBaseControl IO m, MonadIO m) => a -> (InOut a -> m b) -> m a
+withInOut_ a f = liftBaseOp alloca $ \p -> do
+    liftIO (poke p a)
+    _ <- f (InOut p)
+    liftIO (peek p)
+
+withInOutList :: (Storable a, MonadIO m) => Int -> [a] -> (InOutArray a -> m (Int, b)) -> m ([a], b)
+withInOutList sz xs f = do
+    p <- liftIO (mallocArray sz)
+    liftIO $ sequence_
+        [ pokeElemOff p i x
+        | (i,x) <- zip [0..] (take sz xs)
+        ]
+
+    (n, y) <- f (InOutArray p)
+
+    xs' <- liftIO $ sequence
+        [ peekElemOff p i
+        | i <- [0..n-1]
+        ]
+
+    return (xs', y)
+
+withInOutList_ :: (Storable a, MonadIO m) => Int -> [a] -> (InOutArray a -> m Int) -> m [a]
+withInOutList_ sz xs f = do
+    p <- liftIO (mallocArray sz)
+    liftIO $ sequence_
+        [ pokeElemOff p i x
+        | (i,x) <- zip [0..] (take sz xs)
+        ]
+
+    n <- f (InOutArray p)
+
+    liftIO $ sequence
+        [ peekElemOff p i
+        | i <- [0..n-1]
+        ]
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,8 @@
+import           Spec.File  (describeFile)
+import           Spec.Group (describeGroup)
+import           Test.Hspec
+
+main :: IO ()
+main = hspec $ do
+  describe "File interface" describeFile
+  describe "Group interface" describeGroup
diff --git a/test/Spec/File.hs b/test/Spec/File.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec/File.hs
@@ -0,0 +1,65 @@
+{-# LANGUAGE CPP #-}
+module Spec.File ( describeFile ) where
+
+import Test.Hspec
+-- import Test.QuickCheck
+
+import qualified Data.ByteString.Char8 as BS
+import qualified Bindings.HDF5.File as F
+import qualified Data.Vector.Storable as SV
+
+import Spec.Util
+
+-- | Describe the H5F File interface
+describeFile :: Spec
+describeFile = do
+  it "isHDF5 returns True for the test file" $ do
+    isHdf5 <- withTestFile $ \path file -> do
+      -- Flish file to disk
+      F.flushFile file F.Global
+      -- Return whether it is a valid HDF5 file
+      F.isHDF5 (BS.pack path)
+    isHdf5 `shouldBe` True
+
+  it "getFileName reports correct filename" $ do
+    (fn, path) <- withTestFile $ \path file -> do
+      fn <- F.getFileName file
+      return (fn, BS.pack path)
+    fn `shouldBe` path
+
+    {- TODO : create a group and mount it there so we can test something about it
+    it "Allows mounting of one file in another" $ do
+      x <- withTestFile $ \path file1 -> let callback file2 = do
+                                               F.mountFile file1 (BS.pack "/") file2 Nothing
+                                               return 42
+                                         in withTestFile' callback
+      x `shouldBe` 42
+    -}
+
+
+  it "global object count is zero initially" $ do
+    count <- F.getFileObjCount Nothing True [F.All]
+    count `shouldBe` 0
+
+  around withTestFile' $ do
+    it "test file has one file" $ \file -> do
+      count <- F.getFileObjCount (Just file) True [F.Files]
+      count `shouldBe` 1
+
+    it "test file has no groups" $ \file -> do
+      count <- F.getFileObjCount (Just file) True [F.Groups]
+      count `shouldBe` 0
+
+    it "test file has no datasets" $ \file -> do
+      count <- F.getFileObjCount (Just file) True [F.Datasets]
+      count `shouldBe` 0
+
+    it "test file has 1 open object" $ \file -> do
+      vec <- F.getOpenObjects (Just file)True [F.All]
+      SV.length vec `shouldBe` 1
+
+#if MIN_VERSION_hspec(2,2,5)
+    xit "test file has no free space" $ \file -> do
+      size <- F.getFileFreespace file
+      size `shouldBe` 0  -- with hdf5 1.10.4 it returns 1248
+#endif
diff --git a/test/Spec/Group.hs b/test/Spec/Group.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec/Group.hs
@@ -0,0 +1,23 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Spec.Group ( describeGroup ) where
+
+import           Test.Hspec
+
+import           Bindings.HDF5.Core    (IndexType (..), IterOrder (..), hid)
+import qualified Bindings.HDF5.Group   as G
+import qualified Bindings.HDF5.Link    as L
+import qualified Bindings.HDF5.Object  as OB
+import qualified Data.ByteString.Char8 as BS
+
+import           Spec.Util
+
+-- | Describe the H5G Group interface
+describeGroup :: Spec
+describeGroup = do
+  around (withGroup "group1") $ do
+    it "can create group at top-level" $ \file -> do
+      name <- L.getLinkNameByIdx file "/" ByName Increasing 0 Nothing
+      name `shouldBe` "group1"
+
+  -- TODO : test lookup non-existent group
diff --git a/test/Spec/Util.hs b/test/Spec/Util.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec/Util.hs
@@ -0,0 +1,34 @@
+module Spec.Util
+  ( withTestFile
+  , withTestFile'
+  , withGroup
+  ) where
+
+import           Control.Exception     (bracket)
+import           System.IO
+import           System.IO.Temp
+
+import qualified Bindings.HDF5.File    as F
+import qualified Bindings.HDF5.Group   as G
+import qualified Data.ByteString.Char8 as BS
+
+-- TODO : Use H5FD_CORE driver to avoid writing files : will require high-level wrapper for H5Pset_fapl_core
+
+-- | Call a handle with a temporary HDF5 file
+withTestFile :: (FilePath -> F.File -> IO a) -> IO a
+withTestFile callback = withSystemTempFile "hs-hdf5.hdf" callback2 where
+  callback2 path handle = bracket aquire release run where
+    aquire = do
+      hClose handle
+      F.createFile (BS.pack path) [F.Truncate] Nothing Nothing
+    run file = do callback path file
+    release file = do F.closeFile file
+
+withTestFile' :: (F.File -> IO a) -> IO a
+withTestFile' callback = withTestFile (\path file -> callback file)
+
+withGroup :: BS.ByteString -> (F.File -> IO a) -> IO a
+withGroup name f = withTestFile' $ \file -> do
+  group <- G.createGroup file name Nothing Nothing Nothing
+  G.closeGroup group
+  f file
