diff --git a/pymolfile/libpymolfile/AUTHORS b/pymolfile/libpymolfile-old/AUTHORS
similarity index 100%
rename from pymolfile/libpymolfile/AUTHORS
rename to pymolfile/libpymolfile-old/AUTHORS
diff --git a/pymolfile/libpymolfile/COPYING b/pymolfile/libpymolfile-old/COPYING
similarity index 100%
rename from pymolfile/libpymolfile/COPYING
rename to pymolfile/libpymolfile-old/COPYING
diff --git a/pymolfile/libpymolfile/README b/pymolfile/libpymolfile-old/README
similarity index 100%
rename from pymolfile/libpymolfile/README
rename to pymolfile/libpymolfile-old/README
diff --git a/pymolfile/libpymolfile-old/__init__.py b/pymolfile/libpymolfile-old/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..584c3db77a365e537797219d8d866cef43fdd84e
--- /dev/null
+++ b/pymolfile/libpymolfile-old/__init__.py
@@ -0,0 +1,7 @@
+
+# Stand-alone python bindings for libvmdmolfile
+# Copyright (c) 2017 Berk Onat <b.onat@warwick.ac.uk>
+# Published under the GNU GENERAL PUBLIC LICENSE Version 2 (or higher)
+"""Stand-alone vmdmolfile library.
+
+"""
diff --git a/pymolfile/libpymolfile-old/f77_molfile.c b/pymolfile/libpymolfile-old/f77_molfile.c
new file mode 100644
index 0000000000000000000000000000000000000000..1bb6aee33f8e61628d32f88fa160be5f8813234f
--- /dev/null
+++ b/pymolfile/libpymolfile-old/f77_molfile.c
@@ -0,0 +1,363 @@
+
+/* 
+ * molfile fortran interface
+ * $Id: f77_molfile.c,v 1.1 2006/03/10 22:48:49 johns Exp $
+ * (c) 2006 Axel Kohlmeyer <akohlmey@cmm.chem.upenn.edu>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "molfile_plugin.h"
+#include "libmolfile_plugin.h"
+#include "vmdplugin.h"
+
+#define F77TESTME 1
+
+/* fortran name mangling */ 
+#if defined(_F77_NO_UNDERSCORE)
+#define FNAME(n) n
+#elif defined(_F77_F2C_UNDERSCORE)
+#define FNAME(n) n ## __
+#else
+#define FNAME(n) n ## _
+#endif
+
+/* interface typedef magic */
+typedef int int4;
+
+struct molfile_f77_handle 
+{
+    void  *handle;
+    const char *fname;
+    const char *ftype;
+    molfile_plugin_t *plugin;
+};
+typedef struct molfile_f77_handle f77_fd;
+
+/* plugin list */
+#ifndef MAXPLUGINS
+#define MAXPLUGINS 200
+#endif
+static int numplugins=0;
+static molfile_plugin_t *plugin_list[MAXPLUGINS];
+
+/* we maintain a static list of assigned handles */
+#ifndef MAXHADNLES
+#define MAXHANDLES 200
+#endif
+static int4 numhandles=0;
+static f77_fd handle_list[MAXHANDLES];
+
+/* helper functions */
+/* helper function to copy fortran style (a la sun fortran) strings into
+ * valid c style strings. just using the string pointers will not work,
+ * since the strings are NOT zero terminated.
+ *
+ * WARNING: do not forget to free(2) them later, 
+ * or you'll have a memory leak!
+ */
+static char *f77strdup(const char *s,const int sz)
+{
+    char *r;
+
+    r = (char *)malloc(sz + 1);
+    r = (char *)memcpy(r, s, sz);
+    r[sz] = '\0';
+    return r;
+}
+
+/* trim off whitespace at the end of a string */
+static void f77trim(char *s,const int sz)
+{
+    int i;
+
+    i=1;
+    while( (i++ < sz) && isspace(s[sz-i]) ) {
+        s[sz-i] ='\0';
+    }
+}
+
+/* get the filename extension */
+static const char *f77getfnext(const char *s)
+{
+    int i,len;
+
+    len = strlen(s);
+    for (i=len; i>=0; --i) {
+        if(s[i] == '.') {
+            return &s[i+1];
+        }
+    }
+    return NULL;
+}
+
+/* check validity of plugins and register them. */
+static int f77register(void *ptr, vmdplugin_t *plugin) {
+
+    if (!plugin->type || !plugin->name || !plugin->author) {
+        fprintf(stderr," skipping plugin with incomplete header\n");
+        return -1;
+    }
+
+#if F77TESTME    
+    fprintf(stderr, " trying to register plugin #%d: %s,  type:    %s/%d\n"
+            " written by: %s\n\n", numplugins+1, plugin->name, 
+            plugin->type, plugin->abiversion, plugin->author);
+#endif
+
+    if (plugin->abiversion != vmdplugin_ABIVERSION) {
+        fprintf(stderr, " skipping plugin with incompatible ABI:%d/%d\n",
+                plugin->abiversion, vmdplugin_ABIVERSION);
+        return -2;
+    }
+
+    if (0 != strncmp(plugin->type, "mol file", 8)) {
+        fprintf(stderr, " skipping plugin of incompatible type:%s\n",
+                plugin->type);
+        return -3;
+    }
+
+    if (numplugins < MAXPLUGINS) {
+        plugin_list[numplugins] = (molfile_plugin_t *) plugin;
+        ++numplugins;
+        return 0;
+    }
+    
+    fprintf(stderr, " too many plugins: %d. increase MAXPLUGINS, "
+            "recompile, and try again.\n", numplugins);
+    
+    return -4;
+}
+
+
+/* the official fortran API */
+
+/* register all available plugins and clear handles. */
+void FNAME(f77_molfile_init)(void) 
+{
+    int i;
+    
+    MOLFILE_INIT_ALL;
+
+    for (i=0; i<MAXHANDLES; ++i) {
+        handle_list[i].handle = NULL;
+    }
+
+    MOLFILE_REGISTER_ALL(NULL,f77register);
+
+    /* 
+     * FIXME: check all plugins and make 
+     * sure the babel plugin(s) are last.
+     */
+}
+
+/* unregister all available plugins */
+void FNAME(f77_molfile_finish)(void) 
+{
+#if 0
+    int i;
+
+    /* FIXME: add code to close and nullify all open handles */
+    for (i=0; i<MAXHANDLES; ++i) {
+        handle_list[i] = NULL;
+    }
+#endif
+
+    MOLFILE_FINI_ALL;
+}
+
+
+/* open a file and provide file descriptor */
+void FNAME(f77_molfile_open_read)(int4 *handle, int4 *natoms,
+                        const char *infile, const char *intype, 
+                        const int len_if, const int len_it)
+{
+    char *fname, *ftype;
+    molfile_plugin_t *plugin;
+    int i;
+    
+    if (numhandles >= MAXHANDLES) {
+        fprintf(stderr, "too many molfile f77 handles.\n");
+        *handle = -666;
+        return;
+    }
+
+    fname = f77strdup(infile, len_if);
+    f77trim(fname,len_if);
+    
+    ftype = f77strdup(intype, len_it);
+    f77trim(ftype,len_it);
+            
+    fprintf(stderr, " %s: trying for: %s/%d, %s/%d\n", 
+            __FUNCTION__, fname, len_if, ftype, len_it);
+
+    plugin = NULL;
+    /* determine plugin type automatically */
+    if(0 == strncmp(intype, "auto", 4)) {
+        const char *fext;
+        
+        fext = f77getfnext(fname);
+        if (fext == NULL) {
+            fprintf(stderr, " could not determine file name extension "
+                    "for automatic plugin guess\n");
+            *handle = -111;
+            return;
+        }
+#if F77TESTME
+        fprintf(stderr, " filename extension: %s\n", fext);
+#endif
+
+        for (i=0; (i<numplugins) && plugin==NULL; ++i) {
+#if F77TESTME
+            fprintf(stderr, " tying filename extension: %s\n",
+                    plugin_list[i]->filename_extension);
+#endif
+            if (0 == strcmp(plugin_list[i]->filename_extension, fext)) {
+                fprintf(stderr, " using plugin: %s\n", 
+                        plugin_list[i]->prettyname);
+                
+                plugin = plugin_list[i];
+            }
+        }
+        if (plugin == NULL) {
+            fprintf(stderr, " could not determine matching plugin type"
+                    "from file name extension\n");
+            *handle = -222;
+            return;
+        }
+    } else {
+        
+        for (i=0; (i<numplugins) && (plugin==NULL); ++i) {
+#if F77TESTME
+            fprintf(stderr, " tying plugin type: %s\n",
+                    plugin_list[i]->name);
+#endif
+            if (0 == strcmp(plugin_list[i]->name, ftype)) {
+                fprintf(stderr, " using plugin: %s\n", 
+                        plugin_list[i]->prettyname);
+                plugin = plugin_list[i];
+            }
+        }
+        if (plugin == NULL) {
+            fprintf(stderr, " could not find plugin for type %s\n",ftype);
+            *handle = -333;
+            return;
+        }
+    }
+    
+    if(plugin == NULL) { /* this should not happen, but... */
+        fprintf(stderr, " no plugin found.\n");
+        *handle = -444;
+        return;
+    }
+    
+    /* build handle */
+    ++numhandles;
+    for (i=0; i<numhandles; ++i) {
+        if(handle_list[i].plugin == NULL) {
+            *handle = i;
+            handle_list[i].fname=fname;
+            handle_list[i].ftype=plugin->name;
+            handle_list[i].plugin=plugin;
+        }
+    }
+
+    /* open file for reading and detect number of atoms */
+    *natoms=MOLFILE_NUMATOMS_UNKNOWN;
+    handle_list[*handle].handle= 
+        plugin->open_file_read(fname,plugin->name,natoms);
+    if(handle_list[*handle].handle == NULL) {
+        fprintf(stderr, " open of %s-plugin for file %s failed\n",
+                plugin->type, fname);
+        --numhandles;
+        handle_list[*handle].plugin=NULL;
+        *handle=-777;
+        return;
+    }
+    
+    return;
+}
+
+/* read next time step */
+void FNAME(f77_molfile_read_next)(int4 *handle, int4 *natoms, float *xyz, 
+                             float *box, int4 *status)
+{
+    molfile_plugin_t *plugin;
+    molfile_timestep_t step;
+    int retval;
+
+    /* do some sanity checks on the handle */
+    if((*handle < 0) || (*handle >= MAXHANDLES)) {
+        fprintf(stderr, " %s: illegal handle: %d\n",
+                __FUNCTION__, *handle);
+        *status = 0;
+        return;
+    }
+
+    plugin = handle_list[*handle].plugin;
+    if(plugin==NULL) {
+        fprintf(stderr, " %s: inactive handle: %d\n",
+                __FUNCTION__, *handle);
+        *status = 0;
+        return;
+    }
+
+    /* skip or read the timestep as demanded */
+    if(status == 0) {
+        retval = plugin->read_next_timestep(handle_list[*handle].handle,
+                                             *natoms, NULL);
+    } else {
+        step.coords = xyz;
+        retval = plugin->read_next_timestep(handle_list[*handle].handle,
+                                             *natoms, &step);
+    }
+
+    /* copy the box parameters */
+    if (retval == MOLFILE_SUCCESS) {
+        *status = 1;
+        box[0]=step.A;
+        box[1]=step.B;
+        box[2]=step.C;
+        box[3]=step.alpha;
+        box[4]=step.beta;
+        box[5]=step.gamma;
+    } else {
+        *status = 0;
+    }
+}
+            
+/* close a read file descriptor */
+void FNAME(f77_molfile_close_read)(int4 *handle)
+{
+    molfile_plugin_t *plugin;
+    
+    /* do some sanity checks on the handle */
+    if((*handle < 0) || (*handle >= MAXHANDLES)) {
+        fprintf(stderr, " %s: illegal handle: %d\n",
+                __FUNCTION__, *handle);
+        *handle = -111;
+        return;
+    }
+
+    plugin = handle_list[*handle].plugin;
+    if(plugin==NULL) {
+        fprintf(stderr, " %s: inactive handle: %d\n",
+                __FUNCTION__, *handle);
+        *handle = -222;
+        return;
+    }
+
+#if F77TESTME
+    fprintf(stderr, " %s: trying to close handle %d"
+            " for file %s\n", __FUNCTION__, *handle, 
+            handle_list[*handle].fname);
+#endif
+
+    plugin->close_file_read(handle_list[*handle].handle);
+    --numhandles;
+    handle_list[*handle].plugin=NULL;
+    *handle=-1;
+}
diff --git a/pymolfile/libpymolfile-old/libvmdmolfile.i b/pymolfile/libpymolfile-old/libvmdmolfile.i
new file mode 100644
index 0000000000000000000000000000000000000000..5bc26bba13286284a3c168a6d2394d526c215668
--- /dev/null
+++ b/pymolfile/libpymolfile-old/libvmdmolfile.i
@@ -0,0 +1,665 @@
+/* -*- C -*-  (not really, but good for syntax highlighting) */
+/* SWIG interface for libvmdmolfile of VMD molfile_plugins
+   Copyright (c) 2017 Berk Onat <b.onat@warwick.ac.uk>
+   Published under the GNU GENERAL PUBLIC LICENSE Version 2 (or higher)
+
+   swig -python -outdir MDAnalysis/coordinates/xdrfile src/xdrfile/libxdrfile2.i
+*/
+%define DOCSTRING
+"
+:Author:  Berk Onat <b.onat@warwick.ac.uk>
+:Year:    2017
+:Licence: GNU GENERAL PUBLIC LICENSE Version 2 (or higher)
+
+
+The Gromacs XTC/TRR library :mod:`libxdrfile2`
+==============================================
+
+:mod:`libxdrfile2`, a derivative of the Gromacs_ `libxdrfile library`_, provides an
+interface to some high-level functions for XTC/TRR trajectory handling.
+Only functions required for reading and processing whole trajectories are exposed at
+the moment; low-level routines to read individual numbers are not provided. In
+addition, :mod:`libxdrfile2` exposes functions to allow fast frame indexing and XDR
+file seeking.
+
+The functions querying the numbers of atoms in a trajectory frame
+(:func:`read_xtc_natoms` and :func:`read_trr_natoms`) open a file themselves and
+only require the file name.
+
+All other functions operate on a *XDRFILE* object, which is a special file
+handle for xdr files.  Any xdr-based trajectory file (XTC or TRR format) always
+has to be opened with :func:`xdrfile_open`. When done, close the trajectory
+with :func:`xdrfile_close`.
+
+The functions fill or read existing arrays of coordinates; they never allocate
+these arrays themselves. Hence they need to be setup outside libxdrfile2 as
+numpy arrays. The exception to these are the indexing ones functions that take
+care of array allocation and transference to a garbage-collectable memory object.
+
+
+.. _Gromacs: http://www.gromacs.org
+.. _libxdrfile library: http://www.gromacs.org/Developer_Zone/Programming_Guide/XTC_Library
+
+.. versionchanged:: 0.8.0
+   :mod:`libxdrfile2` is now used instead of :mod:`libxdrfile`. :mod:`libxdrfile2` is
+   based on :mod:`libxdrfile` but has xdr seeking and indexing capabilities.
+   Unlike :mod:`libxdrfile` before it, :mod:`libxdrfile2` is distributed under the GNU
+   GENERAL PUBLIC LICENSE, version 2 (or higher).
+
+
+Example: Reading from a XTC
+---------------------------
+
+In the example we read coordinate frames from an existing XTC trajectory::
+
+  import numpy as np
+  from libxdrfile2 import xdrfile_open, xdrfile_close, read_xtc_natoms, read_xtc, DIM, exdrOK
+  xtc = 'md.xtc'
+
+  # get number of atoms
+  natoms = read_xtc_natoms(xtc)
+
+  # allocate coordinate array of the right size and type
+  # (the type float32 is crucial to match the underlying C-code!!)
+  x = np.zeros((natoms, DIM), dtype=np.float32)
+  # allocate unit cell box
+  box = np.zeros((DIM, DIM), dtype=np.float32)
+
+  # open file
+  XTC = xdrfile_open(xtc, 'r')
+
+  # loop through file until return status signifies end or a problem
+  # (it should become exdrENDOFFILE on the last iteration)
+  status = exdrOK
+  while status == exdrOK:
+     status,step,time,prec = read_xtc(XTC, box, x)
+     # do something with x
+     centre = x.mean(axis=0)
+     print 'Centre of geometry at %(time)g ps: %(centre)r' % vars()
+
+  # finally close file
+  xdrfile_close(XTC)
+
+Note that only the *contents* of the coordinate and unitcell arrays *x* and
+*box* change.
+
+
+Functions and constants
+-----------------------
+
+The module defines a number of constants such as :data:`DIM` or the
+`Status symbols`_.
+
+.. data:: DIM
+
+          The number of cartesian dimensions for which the underlying C-code
+          was compiled; this is most certainly 3.
+
+
+Status symbols
+~~~~~~~~~~~~~~
+
+A number of symbols are exported; they all start with the letters
+``exdr``. Important ones are:
+
+.. data:: exdrOK
+
+          Success of xdr file read/write operation.
+
+.. data:: exdrCLOSE
+
+          xdr file is closed
+
+.. data:: exdrENDOFFILE
+
+          end of file was reached (response of :func:`read_xtc` and
+          :func:`read_trr` after the last read frame)
+
+.. data:: exdrFILENOTFOUND
+
+          :func:`xdrfile_open` cannot find the requested file
+
+Other symbols that are used internally are:
+
+.. data:: exdrHEADER
+
+          header
+
+.. data:: exdrSTRING
+
+          string
+
+.. data:: exdrDOUBLE
+
+          double precision floating point number
+
+.. data:: exdrINT
+
+          integer
+
+.. data:: exdrFLOAT
+
+          floating point number
+
+.. data:: exdrUINT
+
+          unsigned integer
+
+.. data:: exdr3DX
+
+          compressed 3D coordinates
+
+.. data:: exdrMAGIC
+
+          magic number
+
+.. data:: exdrNOMEM
+
+          not enough memory to allocate space for a XDR data structure.
+
+Opening and closing of XDR files
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Two low-level functions are used to obtain a *XDRFILE* object (a file handle)
+to access xdr files such as XTC or TRR trajectories.
+
+.. function:: xdrfile_open(path, mode) -> XDRFILE
+
+              Open *path* and returns a *XDRFILE* handle that is required by other
+              functions.
+
+              :Arguments:
+		  *path*
+		     file name
+		  *mode*
+		     'r' for reading and 'w' for writing
+	      :Returns: *XDRFILE* handle
+
+.. function:: xdrfile_close(XDRFILE) -> status
+
+              Close the xdrfile pointed to by *XDRFILE*.
+
+              .. Warning:: Closing an already closed file will lead to a
+                           crash with a double-free pointer error.
+
+XTC functions
+~~~~~~~~~~~~~
+
+The XTC trajectory format is a lossy compression format that only stores
+coordinates. Compression level is determined by the *precision* argument to the
+:func:`write_xtc` function. Coordinates (Gromacs_ uses nm natively) are
+multiplied by *precision* and truncated to the integer part. A typical value is
+1000.0, which gives an accuracy of 1/100 of an Angstroem.
+
+The advantage of XTC over TRR is its significantly reduced size.
+
+
+.. function:: read_xtc_natoms(fn) -> natoms
+
+              Read the number of atoms *natoms* from a xtc file *fn*.
+
+              :Arguments:
+                *fn*
+                   file name of an xtc file
+
+              :Raises: :exc:`IOError` if the supplied filed is not a XTC
+                       or if it is not readable.
+
+.. function:: read_xtc_numframes(fn) -> (numframes, offsets)
+
+              Read through the whole trajectory headers to obtain the total number of frames.
+              The process is speeded up by reading frame headers for the amount of data in the frame,
+              and then skipping directly to the next header. An array of frame offsets is also
+              returned, which can later be used to seek direcly to arbitrary frames in the trajectory.
+
+              :Arguments:
+                *fn*
+                   file name of an xtc file
+
+              :Returns:
+                a tuple containing:
+                  *numframes*
+                     an int with the total frame count in the trajectory
+                  *offsets*
+                     a numpy array of int64 recording the starting byte offset of each frame
+
+              :Raises: :exc:`IOError` if the supplied filed is not a XTC
+                       or if it is not readable.
+
+.. function:: read_xtc(XDRFILE, box, x) -> (status, step, time, precision)
+
+              Read the next frame from the opened xtc trajectory into *x*.
+
+              :Arguments:
+                *XDRFILE*
+                   open *XDRFILE* object
+                *box*
+                   pre-allocated numpy ``array((DIM,DIM),dtype=numpy.float32)`` which
+                   is filled with the unit cell box vectors
+                *x*
+                   pre-allocated numpy ``array((natoms, DIM),dtype=numpy.float32)``
+                   which is updated with the coordinates from the frame
+
+              :Returns:
+                a tuple containing:
+                  *status*
+                     integer status (0 = exdrOK), see `Status symbols`_ for other
+                     values)
+                  *step*
+                     simulation step
+                  *time*
+                     simulation time in ps
+                  *precision*
+                     precision of the lossy xtc format (typically 1000.0)
+
+.. function:: write_xtc(XDRFILE, step, time, box, x, prec) -> status
+
+              Write the next frame *x* to the opened xtc trajectory.
+
+              :Arguments:
+                *XDRFILE*
+                   open *XDRFILE* object (writable)
+                *step*
+                   simulation step
+                *time*
+                   time step in ps
+                *box*
+                   numpy ``array((DIM,DIM),dtype=numpy.float32)`` which contains
+                   the unit cell box vectors
+                *x*
+                   numpy ``array((natoms, DIM),dtype=nump.float32)``
+                   which contains the coordinates from the frame
+                *precision*
+                   precision of the lossy xtc format (typically 1000.0)
+
+              :Returns: *status*, integer status (0 = OK), see the ``libxdrfile2.exdr*``
+                        constants under `Status symbols`_ for other values)
+
+TRR functions
+~~~~~~~~~~~~~
+
+TRR is the Gromacs_ native full-feature trajectory storage format. It can contain position
+coordinates, velocities and forces, and the lambda value for free energy perturbation
+calculations. Velocities and forces are optional in the sense that they can be all zero.
+
+.. function:: read_trr_natoms(fn) -> natoms
+
+              Read the number of atoms *natoms* from a trr file *fn*.
+
+              :Arguments:
+                *fn*
+                   file name of a trr file
+
+              :Raises: :exc:`IOError` if the supplied filed is not a TRR
+                       or if it is not readable.
+
+.. function:: read_trr_numframes(fn) -> (numframes, offsets)
+
+              Read through the whole trajectory headers to obtain the total number of frames.
+              The process is speeded up by reading frame headers for the amount of data in the frame,
+              and then skipping directly to the next header. An array of frame offsets is also
+              returned, which can later be used to seek direcly to arbitrary frames in the trajectory.
+
+              :Arguments:
+                *fn*
+                   file name of an xtc file
+
+              :Returns:
+                a tuple containing:
+                  *numframes*
+                     an int with the total frame count in the trajectory
+                  *offsets*
+                     a numpy array of int64 recording the starting byte offset of each frame
+
+              :Raises: :exc:`IOError` if the supplied filed is not a TRR or if it is not readable.
+
+.. function:: read_trr(XDRFILE, box, x, v, f) -> (status, step, time, lambda)
+
+              Read the next frame from the opened trr trajectory into *x*, *v*, and *f*.
+
+              :Arguments:
+                *XDRFILE*
+                   open *XDRFILE* object
+                *box*
+                   pre-allocated numpy ``array((DIM,DIM),dtype=numpy.float32)`` which
+                   is filled with the unit cell box vectors
+                *x*
+                   pre-allocated numpy ``array((natoms, DIM),dtype=nump.float32)``
+                   which is updated with the **coordinates** from the frame
+                *v*
+                   pre-allocated numpy ``array((natoms, DIM),dtype=nump.float32)``
+                   which is updated with the **velocities** from the frame
+                *f*
+                   pre-allocated numpy ``array((natoms, DIM),dtype=nump.float32)``
+                   which is updated with the **forces** from the frame
+
+              :Returns:
+                a tuple containing:
+                  *status*
+                     integer status (0 = exdrOK), see the ``libxdrfile2.exdr*`` constants
+                     under `Status symbols`_ for other values)
+                  *step*
+                     simulation step
+                  *time*
+                     simulation time in ps
+                  *lambda*
+                     current lambda value (only interesting for free energy perturbation)
+                  *has_x*
+                     boolean indicating whether coordinates were read from the TRR
+                  *has_v*
+                     boolean indicating whether velocities were read from the TRR
+                  *has_f*
+                     boolean indicating whether forces were read from the TRR
+
+.. function:: write_trr(XDRFILE, step, time, lambda, box, x, v, f) -> status
+
+              Write the next frame to the opened trr trajectory.
+
+              :Arguments:
+                *XDRFILE*
+                   open *XDRFILE* object (writable)
+                *step*
+                   simulation step
+                *time*
+                   time step in ps
+                *lambda*
+                   free energy lambda value (typically 0.0)
+                *box*
+                   numpy ``array((DIM,DIM),dtype=numpy.float32)`` which contains
+                   the unit cell box vectors
+                *x*
+                   numpy ``array((natoms, DIM),dtype=nump.float32)``
+                   which contains the **coordinates** from the frame
+                *v*
+                   numpy ``array((natoms, DIM),dtype=nump.float32)``
+                   which contains the **velocities** from the frame
+                *f*
+                   numpy ``array((natoms, DIM),dtype=nump.float32)``
+                   which contains the **forces** from the frame
+
+              .. versionchanged:: 0.8.0
+                   either one of *x*, *v*, or *f* can now be set as a natom,0-DIM
+                   numpy ``array((natom, 0),dtype=nump.float32)``. This will cause the
+                   corresponding property to be skipped when writing to file.
+
+              :Returns: *status*, integer status (0 = OK), see the ``libxdrfile2.exdr*``
+                        constants under `Status symbols`_ for other values)
+
+"
+%enddef
+
+%module(docstring=DOCSTRING) libvmdmolfile
+
+
+%{
+/* Python SWIG interface to molfile_plugin of VMD version 1.9.3
+   Copyright (c) 2017 Berk Onat <b.onat@warwick.ac.uk>
+   Published under the GNU LESSER GENERAL PUBLIC LICENSE Version 3 (or higher)
+ */
+#define SWIG_FILE_WITH_INIT
+#include <stdio.h>
+#include "molfile_plugin.h"
+%}
+
+%include "numpy.i"
+
+%init %{
+import_array();
+%}
+
+
+/* 
+
+   I am only wrapping 'high level' functions and modify call
+   signatures so that one does not need anything like pointers from
+   python.
+*/
+
+
+/* status codes */
+enum { exdrOK, exdrHEADER, exdrSTRING, exdrDOUBLE,
+       exdrINT, exdrFLOAT, exdrUINT, exdr3DX, exdrCLOSE, exdrMAGIC,
+       exdrNOMEM, exdrENDOFFILE, exdrFILENOTFOUND, exdrNR };
+
+/* These com from stdio.h, for file seeking. Gives all the flexibility to _fseek(). */
+enum { SEEK_SET, SEEK_CUR, SEEK_END };
+
+/* open/close xdr files */
+%feature("autodoc", "0") xdrfile_open;
+extern XDRFILE* xdrfile_open(const char *path, const char *mode);
+
+%feature("autodoc", "0") xdrfile_close;
+extern int xdrfile_close(XDRFILE *fp);
+
+
+/* from xdrfile_xtc.c */
+/* This function returns the number of atoms in the xtc file in *natoms
+     extern int read_xtc_natoms(char *fn,int *natoms);
+   ... but the wrapped function returns natoms as the python return value
+*/
+%feature("autodoc", "0") my_read_xtc_natoms;
+%rename (read_xtc_natoms) my_read_xtc_natoms;
+%exception my_read_xtc_natoms {
+  $action
+  if (PyErr_Occurred()) SWIG_fail;
+}
+%inline %{
+  int my_read_xtc_natoms(char *fn) {
+    int natoms;
+    int status;
+    status = read_xtc_natoms(fn, &natoms);
+    if (status != exdrOK) {
+      PyErr_Format(PyExc_IOError, "[%d] Error reading natoms from xtc '%s'", status, fn);
+      return 0;
+    }
+    return natoms;
+  }
+%}
+
+%feature("autodoc", "0") my_read_xtc_numframes;
+%rename (read_xtc_numframes) my_read_xtc_numframes;
+%exception my_read_xtc_numframes {
+  $action
+  if (PyErr_Occurred()) SWIG_fail;
+}
+%inline %{
+PyObject * my_read_xtc_numframes(char *fn) {
+    int numframes, status;
+    int64_t *offsets[1];
+    PyObject *npoffsets = NULL;
+    status = read_xtc_numframes(fn, &numframes, offsets);
+    if (status != exdrOK) {
+      PyErr_Format(PyExc_IOError, "[%d] Error reading numframes by seeking through xtc '%s'", status, fn);
+      return 0;
+    }
+    npy_intp nfrms[1] = { numframes };
+    npoffsets = PyArray_SimpleNewFromData(1, nfrms, NPY_INT64, *offsets);
+    if (npoffsets==NULL)
+    {
+      free(*offsets);
+      Py_XDECREF(npoffsets);
+      PyErr_Format(PyExc_IOError, "Error copying frame index into Python.");
+      return 0;
+    }
+    /* From http://web.archive.org/web/20130304224839/http://blog.enthought.com/python/numpy/simplified-creation-of-numpy-arrays-from-pre-allocated-memory/ */
+    PyArray_BASE(npoffsets) = PyCObject_FromVoidPtr(*offsets, free);
+    PyObject *tuple = PyTuple_New(2);
+    PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong((long)numframes));
+    PyTuple_SET_ITEM(tuple, 1, npoffsets);
+    return tuple;
+  }
+%}
+
+
+/* This function returns the number of atoms in the trr file in *natoms
+     extern int read_trr_natoms(char *fn,int *natoms);
+ ... but the wrapped function returns natoms as the python return value
+*/
+%feature("autodoc", "0") my_read_trr_natoms;
+%rename (read_trr_natoms) my_read_trr_natoms;
+%exception my_read_trr_natoms {
+  $action
+  if (PyErr_Occurred()) SWIG_fail;
+}
+%inline %{
+  int my_read_trr_natoms(char *fn) {
+    int natoms;
+    int status;
+    status = read_trr_natoms(fn, &natoms);
+    if (status != exdrOK) {
+      PyErr_Format(PyExc_IOError, "[%d] Error reading natoms from trr '%s'", status, fn);
+      return 0;
+    }
+    return natoms;
+  }
+%}
+
+
+%feature("autodoc", "0") my_read_trr_numframes;
+%rename (read_trr_numframes) my_read_trr_numframes;
+%exception my_read_trr_numframes {
+  $action
+  if (PyErr_Occurred()) SWIG_fail;
+}
+%inline %{
+PyObject * my_read_trr_numframes(char *fn) {
+    int numframes, status;
+    int64_t *offsets[1];
+    PyObject *npoffsets = NULL;
+    status = read_trr_numframes(fn, &numframes, offsets);
+    if (status != exdrOK) {
+      PyErr_Format(PyExc_IOError, "[%d] Error reading numframes by seeking through trr '%s'", status, fn);
+      return 0;
+    }
+    npy_intp nfrms[1] = { numframes };
+    npoffsets = PyArray_SimpleNewFromData(1, nfrms, NPY_INT64, *offsets);
+    if (npoffsets==NULL)
+    {
+      free(*offsets);
+      Py_XDECREF(npoffsets);
+      PyErr_Format(PyExc_IOError, "Error copying frame index into Python.");
+      return 0;
+    }
+    /* From http://web.archive.org/web/20130304224839/http://blog.enthought.com/python/numpy/simplified-creation-of-numpy-arrays-from-pre-allocated-memory/ */
+    PyArray_BASE(npoffsets) = PyCObject_FromVoidPtr(*offsets, free);
+    PyObject *tuple = PyTuple_New(2);
+    PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong((long)numframes));
+    PyTuple_SET_ITEM(tuple, 1, npoffsets);
+    return tuple;
+  }
+%}
+
+
+
+#define DIM 3
+typedef float matrix[DIM][DIM];
+typedef float rvec[DIM];
+
+
+/* Reading from xdr files */
+
+%apply (float INPLACE_ARRAY2[ANY][ANY]) {(matrix box)}
+%apply (int DIM1, int DIM2, float* INPLACE_ARRAY2) {(int natoms,  int _DIM,  float *x),
+                                                    (int vnatoms, int v_DIM, float *v),
+                                                    (int fnatoms, int f_DIM, float *f)}
+
+/* Read one frame of an open xtc file */
+/*
+extern int read_xtc(XDRFILE *xd,int natoms,int *step,float *time,
+ 		    matrix box,rvec *x,float *prec);
+*/
+%feature("autodoc", "read_xtc(XDRFILE, box, x) -> (status, step, time, precision)") my_read_xtc;
+%rename (read_xtc) my_read_xtc;
+%inline %{
+PyObject * my_read_xtc(XDRFILE *xd, matrix box, int natoms, int _DIM, float *x) {
+  /* _DIM = 3 always, need to reorder for numpy.i SWIG */
+  int status, step;
+  float time, prec;
+  PyObject *tuple = PyTuple_New(4);
+  status = read_xtc(xd, natoms, &step, &time, box, (rvec *)x, &prec);
+  PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong((long)status));
+  PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong((long)step));
+  PyTuple_SET_ITEM(tuple, 2, PyFloat_FromDouble((double)time));
+  PyTuple_SET_ITEM(tuple, 3, PyFloat_FromDouble((double)prec));
+  return tuple; // return  (status, step, time, prec)
+}
+%}
+
+%feature("autodoc", "read_trr(XDRFILE, box, x, v, f) -> (status, step, time, lambda)") my_read_trr;
+%rename (read_trr) my_read_trr;
+%inline %{
+PyObject * my_read_trr(XDRFILE *xd, matrix box,
+		int natoms,  int _DIM,  float *x,
+		int vnatoms, int v_DIM, float *v,
+		int fnatoms, int f_DIM, float *f) {
+  /* _DIM = 3 always, need to reorder for numpy.i SWIG */
+  int status, step, has_prop=0;
+  float time, lmbda;
+  PyObject *tuple = PyTuple_New(7);
+  status = read_trr(xd, natoms, &step, &time, &lmbda, box, (rvec *)x, (rvec *)v, (rvec *)f, &has_prop);
+  PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong((long)status));
+  PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong((long)step));
+  PyTuple_SET_ITEM(tuple, 2, PyFloat_FromDouble((double)time));
+  PyTuple_SET_ITEM(tuple, 3, PyFloat_FromDouble((double)lmbda));
+  PyTuple_SET_ITEM(tuple, 4, PyBool_FromLong((long)(has_prop & HASX)));
+  PyTuple_SET_ITEM(tuple, 5, PyBool_FromLong((long)(has_prop & HASV)));
+  PyTuple_SET_ITEM(tuple, 6, PyBool_FromLong((long)(has_prop & HASF)));
+  return tuple; // return  (status, step, time, lmbda, has_x, has_v, has_f)
+}
+%}
+
+%clear (matrix box);
+%clear (int natoms,  int _DIM,  float *x);
+%clear (int vnatoms, int v_DIM, float *v);
+%clear (int fnatoms, int f_DIM, float *f);
+
+
+/* Writing of xdr files */
+
+%apply (float IN_ARRAY2[ANY][ANY]) {(matrix box)}
+%apply (int DIM1, int DIM2, float* IN_ARRAY2) {(int natoms,  int _DIM,  float *x),
+                                               (int vnatoms, int v_DIM, float *v),
+                                               (int fnatoms, int f_DIM, float *f)}
+
+/* Write a frame to xtc file */
+/*
+extern int write_xtc(XDRFILE *xd, int natoms,int step,float time,
+		     matrix box,rvec *x,float prec);
+*/
+%feature("autodoc", "write_xtc(XDRFILE, step, time, box, x, prec) -> status") my_write_xtc;
+%rename (write_xtc) my_write_xtc;
+%inline %{
+int my_write_xtc(XDRFILE *xd, int step, float time,
+                 matrix box, int natoms, int _DIM, float *x, float prec) {
+  /* _DIM = 3 always, need to reorder for numpy.i SWIG */
+  return write_xtc(xd, natoms, step, time, box, (rvec *)x, prec);
+}
+%}
+
+%feature("autodoc", "write_trr(XDRFILE, step, time, lambda, box, x, v, f) -> status") my_write_trr;
+%rename (write_trr) my_write_trr;
+%inline %{
+int my_write_trr(XDRFILE *xd, int step, float time, float lmbda, matrix box,
+                 int natoms,  int _DIM,  float *x,
+                 int vnatoms, int v_DIM, float *v,
+                 int fnatoms, int f_DIM, float *f) {
+  /* Preparing for the case of empty arrays - NULL pointers tell the library to skip this property. */
+  if (_DIM == 0) x = NULL;
+  if (v_DIM == 0) v = NULL;
+  if (f_DIM == 0) f = NULL;
+  return write_trr(xd, natoms, step, time, lmbda, box, (rvec *)x, (rvec *)v, (rvec *)f);
+}
+%}
+
+%feature("autodoc", "0") xdr_seek;
+extern int xdr_seek(XDRFILE *xd, long long pos, int whence);
+
+%feature("autodoc", "0") xdr_tell;
+extern long long xdr_tell(XDRFILE *xd);
+
+%clear (matrix box);
+%clear (int natoms,  int _DIM,  float *x);
+%clear (int vnatoms, int v_DIM, float *v);
+%clear (int fnatoms, int f_DIM, float *f);
+
+
diff --git a/pymolfile/libpymolfile-old/libvmdmolfile.py b/pymolfile/libpymolfile-old/libvmdmolfile.py
new file mode 100644
index 0000000000000000000000000000000000000000..87a2c6692427936a46427739df076f2582fc4fef
--- /dev/null
+++ b/pymolfile/libpymolfile-old/libvmdmolfile.py
@@ -0,0 +1,487 @@
+# This file was automatically generated by SWIG (http://www.swig.org).
+# Version 2.0.11
+#
+# Do not make changes to this file unless you know what you are doing--modify
+# the SWIG interface file instead.
+
+
+
+
+"""
+
+:Author:  Oliver Beckstein <orbeckst@gmail.com>
+:Author:  Manuel Melo <manuel.nuno.melo@gmail.com>
+:Year:    2014
+:Licence: GNU GENERAL PUBLIC LICENSE Version 2 (or higher)
+
+
+The Gromacs XTC/TRR library :mod:`libxdrfile2`
+==============================================
+
+:mod:`libxdrfile2`, a derivative of the Gromacs_ `libxdrfile library`_, provides an
+interface to some high-level functions for XTC/TRR trajectory handling.
+Only functions required for reading and processing whole trajectories are exposed at
+the moment; low-level routines to read individual numbers are not provided. In
+addition, :mod:`libxdrfile2` exposes functions to allow fast frame indexing and XDR
+file seeking.
+
+The functions querying the numbers of atoms in a trajectory frame
+(:func:`read_xtc_natoms` and :func:`read_trr_natoms`) open a file themselves and
+only require the file name.
+
+All other functions operate on a *XDRFILE* object, which is a special file
+handle for xdr files.  Any xdr-based trajectory file (XTC or TRR format) always
+has to be opened with :func:`xdrfile_open`. When done, close the trajectory
+with :func:`xdrfile_close`.
+
+The functions fill or read existing arrays of coordinates; they never allocate
+these arrays themselves. Hence they need to be setup outside libxdrfile2 as
+numpy arrays. The exception to these are the indexing ones functions that take
+care of array allocation and transference to a garbage-collectable memory object.
+
+
+.. _Gromacs: http://www.gromacs.org
+.. _libxdrfile library: http://www.gromacs.org/Developer_Zone/Programming_Guide/XTC_Library
+
+.. versionchanged:: 0.8.0
+   :mod:`libxdrfile2` is now used instead of :mod:`libxdrfile`. :mod:`libxdrfile2` is
+   based on :mod:`libxdrfile` but has xdr seeking and indexing capabilities.
+   Unlike :mod:`libxdrfile` before it, :mod:`libxdrfile2` is distributed under the GNU
+   GENERAL PUBLIC LICENSE, version 2 (or higher).
+
+
+Example: Reading from a XTC
+---------------------------
+
+In the example we read coordinate frames from an existing XTC trajectory::
+
+  import numpy as np
+  from libxdrfile2 import xdrfile_open, xdrfile_close, read_xtc_natoms, read_xtc, DIM, exdrOK
+  xtc = 'md.xtc'
+
+  # get number of atoms
+  natoms = read_xtc_natoms(xtc)
+
+  # allocate coordinate array of the right size and type
+  # (the type float32 is crucial to match the underlying C-code!!)
+  x = np.zeros((natoms, DIM), dtype=np.float32)
+  # allocate unit cell box
+  box = np.zeros((DIM, DIM), dtype=np.float32)
+
+  # open file
+  XTC = xdrfile_open(xtc, 'r')
+
+  # loop through file until return status signifies end or a problem
+  # (it should become exdrENDOFFILE on the last iteration)
+  status = exdrOK
+  while status == exdrOK:
+     status,step,time,prec = read_xtc(XTC, box, x)
+     # do something with x
+     centre = x.mean(axis=0)
+     print 'Centre of geometry at %(time)g ps: %(centre)r' % vars()
+
+  # finally close file
+  xdrfile_close(XTC)
+
+Note that only the *contents* of the coordinate and unitcell arrays *x* and
+*box* change.
+
+
+Functions and constants
+-----------------------
+
+The module defines a number of constants such as :data:`DIM` or the
+`Status symbols`_.
+
+.. data:: DIM
+
+          The number of cartesian dimensions for which the underlying C-code
+          was compiled; this is most certainly 3.
+
+
+Status symbols
+~~~~~~~~~~~~~~
+
+A number of symbols are exported; they all start with the letters
+``exdr``. Important ones are listed here:
+
+.. data:: exdrOK
+
+          Success of xdr file read/write operation.
+
+.. data:: exdrCLOSE
+
+          xdr file is closed
+
+.. data:: exdrENDOFFILE
+
+          end of file was reached (response of :func:`read_xtc` and
+          :func:`read_trr` after the last read frame)
+
+.. data:: exdrFILENOTFOUND
+
+          :func:`xdrfile_open` cannot find the requested file
+
+
+Opening and closing of XDR files
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Two low-level functions are used to obtain a *XDRFILE* object (a file handle)
+to access xdr files such as XTC or TRR trajectories.
+
+.. function:: xdrfile_open(path, mode) -> XDRFILE
+
+              Open *path* and returns a *XDRFILE* handle that is required by other
+              functions.
+
+              :Arguments:
+		  *path*
+		     file name
+		  *mode*
+		     'r' for reading and 'w' for writing
+	      :Returns: *XDRFILE* handle
+
+.. function:: xdrfile_close(XDRFILE) -> status
+
+              Close the xdrfile pointed to by *XDRFILE*.
+
+              .. Warning:: Closing an already closed file will lead to a
+                           crash with a double-free pointer error.
+
+XTC functions
+~~~~~~~~~~~~~
+
+The XTC trajectory format is a lossy compression format that only stores
+coordinates. Compression level is determined by the *precision* argument to the
+:func:`write_xtc` function. Coordinates (Gromacs_ uses nm natively) are
+multiplied by *precision* and truncated to the integer part. A typical value is
+1000.0, which gives an accuracy of 1/100 of an Angstroem.
+
+The advantage of XTC over TRR is its significantly reduced size.
+
+
+.. function:: read_xtc_natoms(fn) -> natoms
+
+              Read the number of atoms *natoms* from a xtc file *fn*.
+
+              :Arguments:
+                *fn*
+                   file name of an xtc file
+
+              :Raises: :exc:`IOError` if the supplied filed is not a XTC
+                       or if it is not readable.
+
+.. function:: read_xtc_numframes(fn) -> (numframes, offsets)
+
+              Read through the whole trajectory headers to obtain the total number of frames.
+              The process is speeded up by reading frame headers for the amount of data in the frame,
+              and then skipping directly to the next header. An array of frame offsets is also
+              returned, which can later be used to seek direcly to arbitrary frames in the trajectory.
+
+              :Arguments:
+                *fn*
+                   file name of an xtc file
+
+              :Returns:
+                a tuple containing:
+                  *numframes*
+                     an int with the total frame count in the trajectory
+                  *offsets*
+                     a numpy array of int64 recording the starting byte offset of each frame
+
+              :Raises: :exc:`IOError` if the supplied filed is not a XTC
+                       or if it is not readable.
+
+.. function:: read_xtc(XDRFILE, box, x) -> (status, step, time, precision)
+
+              Read the next frame from the opened xtc trajectory into *x*.
+
+              :Arguments:
+                *XDRFILE*
+                   open *XDRFILE* object
+                *box*
+                   pre-allocated numpy ``array((DIM,DIM),dtype=numpy.float32)`` which
+                   is filled with the unit cell box vectors
+                *x*
+                   pre-allocated numpy ``array((natoms, DIM),dtype=numpy.float32)``
+                   which is updated with the coordinates from the frame
+
+              :Returns:
+                a tuple containing:
+                  *status*
+                     integer status (0 = exdrOK), see `Status symbols`_ for other
+                     values)
+                  *step*
+                     simulation step
+                  *time*
+                     simulation time in ps
+                  *precision*
+                     precision of the lossy xtc format (typically 1000.0)
+
+.. function:: write_xtc(XDRFILE, step, time, box, x, prec) -> status
+
+              Write the next frame *x* to the opened xtc trajectory.
+
+              :Arguments:
+                *XDRFILE*
+                   open *XDRFILE* object (writable)
+                *step*
+                   simulation step
+                *time*
+                   time step in ps
+                *box*
+                   numpy ``array((DIM,DIM),dtype=numpy.float32)`` which contains
+                   the unit cell box vectors
+                *x*
+                   numpy ``array((natoms, DIM),dtype=nump.float32)``
+                   which contains the coordinates from the frame
+                *precision*
+                   precision of the lossy xtc format (typically 1000.0)
+
+              :Returns: *status*, integer status (0 = OK), see the ``libxdrfile2.exdr*``
+                        constants under `Status symbols`_ for other values)
+
+TRR functions
+~~~~~~~~~~~~~
+
+TRR is the Gromacs_ native full-feature trajectory storage format. It can contain position
+coordinates, velocities and forces, and the lambda value for free energy perturbation
+calculations. Velocities and forces are optional in the sense that they can be all zero.
+
+.. function:: read_trr_natoms(fn) -> natoms
+
+              Read the number of atoms *natoms* from a trr file *fn*.
+
+              :Arguments:
+                *fn*
+                   file name of a trr file
+
+              :Raises: :exc:`IOError` if the supplied filed is not a TRR
+                       or if it is not readable.
+
+.. function:: read_trr_numframes(fn) -> (numframes, offsets)
+
+              Read through the whole trajectory headers to obtain the total number of frames.
+              The process is speeded up by reading frame headers for the amount of data in the frame,
+              and then skipping directly to the next header. An array of frame offsets is also
+              returned, which can later be used to seek direcly to arbitrary frames in the trajectory.
+
+              :Arguments:
+                *fn*
+                   file name of an xtc file
+
+              :Returns:
+                a tuple containing:
+                  *numframes*
+                     an int with the total frame count in the trajectory
+                  *offsets*
+                     a numpy array of int64 recording the starting byte offset of each frame
+
+              :Raises: :exc:`IOError` if the supplied filed is not a TRR or if it is not readable.
+
+.. function:: read_trr(XDRFILE, box, x, v, f) -> (status, step, time, lambda)
+
+              Read the next frame from the opened trr trajectory into *x*, *v*, and *f*.
+
+              :Arguments:
+                *XDRFILE*
+                   open *XDRFILE* object
+                *box*
+                   pre-allocated numpy ``array((DIM,DIM),dtype=numpy.float32)`` which
+                   is filled with the unit cell box vectors
+                *x*
+                   pre-allocated numpy ``array((natoms, DIM),dtype=nump.float32)``
+                   which is updated with the **coordinates** from the frame
+                *v*
+                   pre-allocated numpy ``array((natoms, DIM),dtype=nump.float32)``
+                   which is updated with the **velocities** from the frame
+                *f*
+                   pre-allocated numpy ``array((natoms, DIM),dtype=nump.float32)``
+                   which is updated with the **forces** from the frame
+
+              :Returns:
+                a tuple containing:
+                  *status*
+                     integer status (0 = exdrOK), see the ``libxdrfile2.exdr*`` constants
+                     under `Status symbols`_ for other values)
+                  *step*
+                     simulation step
+                  *time*
+                     simulation time in ps
+                  *lambda*
+                     current lambda value (only interesting for free energy perturbation)
+                  *has_x*
+                     boolean indicating whether coordinates were read from the TRR
+                  *has_v*
+                     boolean indicating whether velocities were read from the TRR
+                  *has_f*
+                     boolean indicating whether forces were read from the TRR
+
+.. function:: write_trr(XDRFILE, step, time, lambda, box, x, v, f) -> status
+
+              Write the next frame to the opened trr trajectory.
+
+              :Arguments:
+                *XDRFILE*
+                   open *XDRFILE* object (writable)
+                *step*
+                   simulation step
+                *time*
+                   time step in ps
+                *lambda*
+                   free energy lambda value (typically 0.0)
+                *box*
+                   numpy ``array((DIM,DIM),dtype=numpy.float32)`` which contains
+                   the unit cell box vectors
+                *x*
+                   numpy ``array((natoms, DIM),dtype=nump.float32)``
+                   which contains the **coordinates** from the frame
+                *v*
+                   numpy ``array((natoms, DIM),dtype=nump.float32)``
+                   which contains the **velocities** from the frame
+                *f*
+                   numpy ``array((natoms, DIM),dtype=nump.float32)``
+                   which contains the **forces** from the frame
+
+              .. versionchanged:: 0.8.0
+                   either one of *x*, *v*, or *f* can now be set as a natom,0-DIM
+                   numpy ``array((natom, 0),dtype=nump.float32)``. This will cause the
+                   corresponding property to be skipped when writing to file.
+
+              :Returns: *status*, integer status (0 = OK), see the ``libxdrfile2.exdr*``
+                        constants under `Status symbols`_ for other values)
+
+
+"""
+
+
+from sys import version_info
+if version_info >= (2,6,0):
+    def swig_import_helper():
+        from os.path import dirname
+        import imp
+        fp = None
+        try:
+            fp, pathname, description = imp.find_module('_libxdrfile2', [dirname(__file__)])
+        except ImportError:
+            import _libxdrfile2
+            return _libxdrfile2
+        if fp is not None:
+            try:
+                _mod = imp.load_module('_libxdrfile2', fp, pathname, description)
+            finally:
+                fp.close()
+            return _mod
+    _libxdrfile2 = swig_import_helper()
+    del swig_import_helper
+else:
+    import _libxdrfile2
+del version_info
+try:
+    _swig_property = property
+except NameError:
+    pass # Python < 2.2 doesn't have 'property'.
+def _swig_setattr_nondynamic(self,class_type,name,value,static=1):
+    if (name == "thisown"): return self.this.own(value)
+    if (name == "this"):
+        if type(value).__name__ == 'SwigPyObject':
+            self.__dict__[name] = value
+            return
+    method = class_type.__swig_setmethods__.get(name,None)
+    if method: return method(self,value)
+    if (not static):
+        self.__dict__[name] = value
+    else:
+        raise AttributeError("You cannot add attributes to %s" % self)
+
+def _swig_setattr(self,class_type,name,value):
+    return _swig_setattr_nondynamic(self,class_type,name,value,0)
+
+def _swig_getattr(self,class_type,name):
+    if (name == "thisown"): return self.this.own()
+    method = class_type.__swig_getmethods__.get(name,None)
+    if method: return method(self)
+    raise AttributeError(name)
+
+def _swig_repr(self):
+    try: strthis = "proxy of " + self.this.__repr__()
+    except: strthis = ""
+    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
+
+try:
+    _object = object
+    _newclass = 1
+except AttributeError:
+    class _object : pass
+    _newclass = 0
+
+
+exdrOK = _libxdrfile2.exdrOK
+exdrHEADER = _libxdrfile2.exdrHEADER
+exdrSTRING = _libxdrfile2.exdrSTRING
+exdrDOUBLE = _libxdrfile2.exdrDOUBLE
+exdrINT = _libxdrfile2.exdrINT
+exdrFLOAT = _libxdrfile2.exdrFLOAT
+exdrUINT = _libxdrfile2.exdrUINT
+exdr3DX = _libxdrfile2.exdr3DX
+exdrCLOSE = _libxdrfile2.exdrCLOSE
+exdrMAGIC = _libxdrfile2.exdrMAGIC
+exdrNOMEM = _libxdrfile2.exdrNOMEM
+exdrENDOFFILE = _libxdrfile2.exdrENDOFFILE
+exdrFILENOTFOUND = _libxdrfile2.exdrFILENOTFOUND
+exdrNR = _libxdrfile2.exdrNR
+SEEK_SET = _libxdrfile2.SEEK_SET
+SEEK_CUR = _libxdrfile2.SEEK_CUR
+SEEK_END = _libxdrfile2.SEEK_END
+
+def xdrfile_open(*args):
+  """xdrfile_open(path, mode) -> XDRFILE *"""
+  return _libxdrfile2.xdrfile_open(*args)
+
+def xdrfile_close(*args):
+  """xdrfile_close(fp) -> int"""
+  return _libxdrfile2.xdrfile_close(*args)
+
+def read_xtc_natoms(*args):
+  """read_xtc_natoms(fn) -> int"""
+  return _libxdrfile2.read_xtc_natoms(*args)
+
+def read_xtc_numframes(*args):
+  """read_xtc_numframes(fn) -> PyObject *"""
+  return _libxdrfile2.read_xtc_numframes(*args)
+
+def read_trr_natoms(*args):
+  """read_trr_natoms(fn) -> int"""
+  return _libxdrfile2.read_trr_natoms(*args)
+
+def read_trr_numframes(*args):
+  """read_trr_numframes(fn) -> PyObject *"""
+  return _libxdrfile2.read_trr_numframes(*args)
+DIM = _libxdrfile2.DIM
+
+def read_xtc(*args):
+  """read_xtc(XDRFILE, box, x) -> (status, step, time, precision)"""
+  return _libxdrfile2.read_xtc(*args)
+
+def read_trr(*args):
+  """read_trr(XDRFILE, box, x, v, f) -> (status, step, time, lambda)"""
+  return _libxdrfile2.read_trr(*args)
+
+def write_xtc(*args):
+  """write_xtc(XDRFILE, step, time, box, x, prec) -> status"""
+  return _libxdrfile2.write_xtc(*args)
+
+def write_trr(*args):
+  """write_trr(XDRFILE, step, time, lambda, box, x, v, f) -> status"""
+  return _libxdrfile2.write_trr(*args)
+
+def xdr_seek(*args):
+  """xdr_seek(xd, pos, whence) -> int"""
+  return _libxdrfile2.xdr_seek(*args)
+
+def xdr_tell(*args):
+  """xdr_tell(xd) -> long long"""
+  return _libxdrfile2.xdr_tell(*args)
+# This file is compatible with both classic and new-style classes.
+
+
diff --git a/pymolfile/libpymolfile/libvmdmolfile_wrap.c b/pymolfile/libpymolfile-old/libvmdmolfile_wrap.c
similarity index 100%
rename from pymolfile/libpymolfile/libvmdmolfile_wrap.c
rename to pymolfile/libpymolfile-old/libvmdmolfile_wrap.c
diff --git a/pymolfile/libpymolfile-old/numpy.i b/pymolfile/libpymolfile-old/numpy.i
new file mode 100644
index 0000000000000000000000000000000000000000..ec649b942fac2682d78bf8a99edcccbb698c7d17
--- /dev/null
+++ b/pymolfile/libpymolfile-old/numpy.i
@@ -0,0 +1,1638 @@
+/* -*- C -*-  (not really, but good for syntax highlighting) */
+#ifdef SWIGPYTHON
+
+%{
+#ifndef SWIG_FILE_WITH_INIT
+#  define NO_IMPORT_ARRAY
+#endif
+#include "stdio.h"
+#include <numpy/arrayobject.h>
+%}
+
+/**********************************************************************/
+
+%fragment("NumPy_Backward_Compatibility", "header")
+{
+/* Support older NumPy data type names
+*/
+%#if NDARRAY_VERSION < 0x01000000
+%#define NPY_BOOL          PyArray_BOOL
+%#define NPY_BYTE          PyArray_BYTE
+%#define NPY_UBYTE         PyArray_UBYTE
+%#define NPY_SHORT         PyArray_SHORT
+%#define NPY_USHORT        PyArray_USHORT
+%#define NPY_INT           PyArray_INT
+%#define NPY_UINT          PyArray_UINT
+%#define NPY_LONG          PyArray_LONG
+%#define NPY_ULONG         PyArray_ULONG
+%#define NPY_LONGLONG      PyArray_LONGLONG
+%#define NPY_ULONGLONG     PyArray_ULONGLONG
+%#define NPY_FLOAT         PyArray_FLOAT
+%#define NPY_DOUBLE        PyArray_DOUBLE
+%#define NPY_LONGDOUBLE    PyArray_LONGDOUBLE
+%#define NPY_CFLOAT        PyArray_CFLOAT
+%#define NPY_CDOUBLE       PyArray_CDOUBLE
+%#define NPY_CLONGDOUBLE   PyArray_CLONGDOUBLE
+%#define NPY_OBJECT        PyArray_OBJECT
+%#define NPY_STRING        PyArray_STRING
+%#define NPY_UNICODE       PyArray_UNICODE
+%#define NPY_VOID          PyArray_VOID
+%#define NPY_NTYPES        PyArray_NTYPES
+%#define NPY_NOTYPE        PyArray_NOTYPE
+%#define NPY_CHAR          PyArray_CHAR
+%#define NPY_USERDEF       PyArray_USERDEF
+%#define npy_intp          intp
+
+%#define NPY_MAX_BYTE      MAX_BYTE
+%#define NPY_MIN_BYTE      MIN_BYTE
+%#define NPY_MAX_UBYTE     MAX_UBYTE
+%#define NPY_MAX_SHORT     MAX_SHORT
+%#define NPY_MIN_SHORT     MIN_SHORT
+%#define NPY_MAX_USHORT    MAX_USHORT
+%#define NPY_MAX_INT       MAX_INT
+%#define NPY_MIN_INT       MIN_INT
+%#define NPY_MAX_UINT      MAX_UINT
+%#define NPY_MAX_LONG      MAX_LONG
+%#define NPY_MIN_LONG      MIN_LONG
+%#define NPY_MAX_ULONG     MAX_ULONG
+%#define NPY_MAX_LONGLONG  MAX_LONGLONG
+%#define NPY_MIN_LONGLONG  MIN_LONGLONG
+%#define NPY_MAX_ULONGLONG MAX_ULONGLONG
+%#define NPY_MAX_INTP      MAX_INTP
+%#define NPY_MIN_INTP      MIN_INTP
+
+%#define NPY_FARRAY        FARRAY
+%#define NPY_F_CONTIGUOUS  F_CONTIGUOUS
+%#endif
+}
+
+/**********************************************************************/
+
+/* The following code originally appeared in
+ * enthought/kiva/agg/src/numeric.i written by Eric Jones.  It was
+ * translated from C++ to C by John Hunter.  Bill Spotz has modified
+ * it to fix some minor bugs, upgrade from Numeric to numpy (all
+ * versions), add some comments and functionality, and convert from
+ * direct code insertion to SWIG fragments.
+ */
+
+%fragment("NumPy_Macros", "header")
+{
+/* Macros to extract array attributes.
+ */
+%#define is_array(a)            ((a) && PyArray_Check((PyArrayObject *)a))
+%#define array_type(a)          (int)(PyArray_TYPE(a))
+%#define array_numdims(a)       (((PyArrayObject *)a)->nd)
+%#define array_dimensions(a)    (((PyArrayObject *)a)->dimensions)
+%#define array_size(a,i)        (((PyArrayObject *)a)->dimensions[i])
+%#define array_data(a)          (((PyArrayObject *)a)->data)
+%#define array_is_contiguous(a) (PyArray_ISCONTIGUOUS(a))
+%#define array_is_native(a)     (PyArray_ISNOTSWAPPED(a))
+%#define array_is_fortran(a)    (PyArray_ISFORTRAN(a))
+}
+
+/**********************************************************************/
+
+%fragment("NumPy_Utilities", "header")
+{
+  /* Given a PyObject, return a string describing its type.
+   */
+  const char* pytype_string(PyObject* py_obj) {
+    if (py_obj == NULL          ) return "C NULL value";
+    if (py_obj == Py_None       ) return "Python None" ;
+    if (PyCallable_Check(py_obj)) return "callable"    ;
+    if (PyString_Check(  py_obj)) return "string"      ;
+    if (PyInt_Check(     py_obj)) return "int"         ;
+    if (PyFloat_Check(   py_obj)) return "float"       ;
+    if (PyDict_Check(    py_obj)) return "dict"        ;
+    if (PyList_Check(    py_obj)) return "list"        ;
+    if (PyTuple_Check(   py_obj)) return "tuple"       ;
+    #if PY_MAJOR_VERSION < 3
+      if (PyFile_Check(    py_obj)) return "file"        ;
+    #endif
+    if (PyModule_Check(  py_obj)) return "module"      ;
+    #if PY_MAJOR_VERSION < 3
+      if (PyInstance_Check(py_obj)) return "instance"    ;
+    #endif
+
+    return "unkown type";
+  }
+
+  /* Given a NumPy typecode, return a string describing the type.
+   */
+  const char* typecode_string(int typecode) {
+    static const char* type_names[25] = {"bool", "byte", "unsigned byte",
+                                   "short", "unsigned short", "int",
+                                   "unsigned int", "long", "unsigned long",
+                                   "long long", "unsigned long long",
+                                   "float", "double", "long double",
+                                   "complex float", "complex double",
+                                   "complex long double", "object",
+                                   "string", "unicode", "void", "ntypes",
+                                   "notype", "char", "unknown"};
+    return typecode < 24 ? type_names[typecode] : type_names[24];
+  }
+
+  /* Make sure input has correct numpy type.  Allow character and byte
+   * to match.  Also allow int and long to match.  This is deprecated.
+   * You should use PyArray_EquivTypenums() instead.
+   */
+  int type_match(int actual_type, int desired_type) {
+    return PyArray_EquivTypenums(actual_type, desired_type);
+  }
+}
+
+/**********************************************************************/
+
+%fragment("NumPy_Object_to_Array", "header",
+          fragment="NumPy_Backward_Compatibility",
+          fragment="NumPy_Macros",
+          fragment="NumPy_Utilities")
+{
+  /* Given a PyObject pointer, cast it to a PyArrayObject pointer if
+   * legal.  If not, set the python error string appropriately and
+   * return NULL.
+   */
+  PyArrayObject* obj_to_array_no_conversion(PyObject* input, int typecode)
+  {
+    PyArrayObject* ary = NULL;
+    if (is_array(input) && (typecode == NPY_NOTYPE ||
+                            PyArray_EquivTypenums(array_type(input), typecode)))
+    {
+      ary = (PyArrayObject*) input;
+    }
+    else if is_array(input)
+    {
+      const char* desired_type = typecode_string(typecode);
+      const char* actual_type  = typecode_string(array_type(input));
+      PyErr_Format(PyExc_TypeError,
+                   "Array of type '%s' required.  Array of type '%s' given",
+                   desired_type, actual_type);
+      ary = NULL;
+    }
+    else
+    {
+      const char * desired_type = typecode_string(typecode);
+      const char * actual_type  = pytype_string(input);
+      PyErr_Format(PyExc_TypeError,
+                   "Array of type '%s' required.  A '%s' was given",
+                   desired_type, actual_type);
+      ary = NULL;
+    }
+    return ary;
+  }
+
+  /* Convert the given PyObject to a NumPy array with the given
+   * typecode.  On success, return a valid PyArrayObject* with the
+   * correct type.  On failure, the python error string will be set and
+   * the routine returns NULL.
+   */
+  PyArrayObject* obj_to_array_allow_conversion(PyObject* input, int typecode,
+                                               int* is_new_object)
+  {
+    PyArrayObject* ary = NULL;
+    PyObject* py_obj;
+    if (is_array(input) && (typecode == NPY_NOTYPE ||
+                            PyArray_EquivTypenums(array_type(input),typecode)))
+    {
+      ary = (PyArrayObject*) input;
+      *is_new_object = 0;
+    }
+    else
+    {
+      py_obj = PyArray_FROMANY(input, typecode, 0, 0, NPY_DEFAULT);
+      /* If NULL, PyArray_FromObject will have set python error value.*/
+      ary = (PyArrayObject*) py_obj;
+      *is_new_object = 1;
+    }
+    return ary;
+  }
+
+  /* Given a PyArrayObject, check to see if it is contiguous.  If so,
+   * return the input pointer and flag it as not a new object.  If it is
+   * not contiguous, create a new PyArrayObject using the original data,
+   * flag it as a new object and return the pointer.
+   */
+  PyArrayObject* make_contiguous(PyArrayObject* ary, int* is_new_object,
+                                 int min_dims, int max_dims)
+  {
+    PyArrayObject* result;
+    if (array_is_contiguous(ary))
+    {
+      result = ary;
+      *is_new_object = 0;
+    }
+    else
+    {
+      result = (PyArrayObject*) PyArray_ContiguousFromObject((PyObject*)ary,
+                                                             array_type(ary),
+                                                             min_dims,
+                                                             max_dims);
+      *is_new_object = 1;
+    }
+    return result;
+  }
+
+  /* Given a PyArrayObject, check to see if it is Fortran-contiguous.
+   * If so, return the input pointer, but do not flag it as not a new
+   * object.  If it is not Fortran-contiguous, create a new
+   * PyArrayObject using the original data, flag it as a new object
+   * and return the pointer.
+   */
+  PyArrayObject* make_fortran(PyArrayObject* ary, int* is_new_object,
+                              int min_dims, int max_dims)
+  {
+    PyArrayObject* result;
+    if (array_is_fortran(ary))
+    {
+      result = ary;
+      *is_new_object = 0;
+    }
+    else
+    {
+      Py_INCREF(ary->descr);
+      result = (PyArrayObject*) PyArray_FromArray(ary, ary->descr, NPY_FORTRAN);
+      *is_new_object = 1;
+    }
+    return result;
+  }
+
+  /* Convert a given PyObject to a contiguous PyArrayObject of the
+   * specified type.  If the input object is not a contiguous
+   * PyArrayObject, a new one will be created and the new object flag
+   * will be set.
+   */
+  PyArrayObject* obj_to_array_contiguous_allow_conversion(PyObject* input,
+                                                          int typecode,
+                                                          int* is_new_object)
+  {
+    int is_new1 = 0;
+    int is_new2 = 0;
+    PyArrayObject* ary2;
+    PyArrayObject* ary1 = obj_to_array_allow_conversion(input, typecode,
+                                                        &is_new1);
+    if (ary1)
+    {
+      ary2 = make_contiguous(ary1, &is_new2, 0, 0);
+      if ( is_new1 && is_new2)
+      {
+        Py_DECREF(ary1);
+      }
+      ary1 = ary2;
+    }
+    *is_new_object = is_new1 || is_new2;
+    return ary1;
+  }
+
+  /* Convert a given PyObject to a Fortran-ordered PyArrayObject of the
+   * specified type.  If the input object is not a Fortran-ordered
+   * PyArrayObject, a new one will be created and the new object flag
+   * will be set.
+   */
+  PyArrayObject* obj_to_array_fortran_allow_conversion(PyObject* input,
+                                                       int typecode,
+                                                       int* is_new_object)
+  {
+    int is_new1 = 0;
+    int is_new2 = 0;
+    PyArrayObject* ary2;
+    PyArrayObject* ary1 = obj_to_array_allow_conversion(input, typecode,
+                                                        &is_new1);
+    if (ary1)
+    {
+      ary2 = make_fortran(ary1, &is_new2, 0, 0);
+      if (is_new1 && is_new2)
+      {
+        Py_DECREF(ary1);
+      }
+      ary1 = ary2;
+    }
+    *is_new_object = is_new1 || is_new2;
+    return ary1;
+  }
+
+} /* end fragment */
+
+
+/**********************************************************************/
+
+%fragment("NumPy_Array_Requirements", "header",
+          fragment="NumPy_Backward_Compatibility",
+          fragment="NumPy_Macros")
+{
+  /* Test whether a python object is contiguous.  If array is
+   * contiguous, return 1.  Otherwise, set the python error string and
+   * return 0.
+   */
+  int require_contiguous(PyArrayObject* ary)
+  {
+    int contiguous = 1;
+    if (!array_is_contiguous(ary))
+    {
+      PyErr_SetString(PyExc_TypeError,
+                      "Array must be contiguous.  A non-contiguous array was given");
+      contiguous = 0;
+    }
+    return contiguous;
+  }
+
+  /* Require that a numpy array is not byte-swapped.  If the array is
+   * not byte-swapped, return 1.  Otherwise, set the python error string
+   * and return 0.
+   */
+  int require_native(PyArrayObject* ary)
+  {
+    int native = 1;
+    if (!array_is_native(ary))
+    {
+      PyErr_SetString(PyExc_TypeError,
+                      "Array must have native byteorder.  "
+                      "A byte-swapped array was given");
+      native = 0;
+    }
+    return native;
+  }
+
+  /* Require the given PyArrayObject to have a specified number of
+   * dimensions.  If the array has the specified number of dimensions,
+   * return 1.  Otherwise, set the python error string and return 0.
+   */
+  int require_dimensions(PyArrayObject* ary, int exact_dimensions)
+  {
+    int success = 1;
+    if (array_numdims(ary) != exact_dimensions)
+    {
+      PyErr_Format(PyExc_TypeError,
+                   "Array must have %d dimensions.  Given array has %d dimensions",
+                   exact_dimensions, array_numdims(ary));
+      success = 0;
+    }
+    return success;
+  }
+
+  /* Require the given PyArrayObject to have one of a list of specified
+   * number of dimensions.  If the array has one of the specified number
+   * of dimensions, return 1.  Otherwise, set the python error string
+   * and return 0.
+   */
+  int require_dimensions_n(PyArrayObject* ary, int* exact_dimensions, int n)
+  {
+    int success = 0;
+    int i;
+    char dims_str[255] = "";
+    char s[255];
+    for (i = 0; i < n && !success; i++)
+    {
+      if (array_numdims(ary) == exact_dimensions[i])
+      {
+        success = 1;
+      }
+    }
+    if (!success)
+    {
+      for (i = 0; i < n-1; i++)
+      {
+        sprintf(s, "%d, ", exact_dimensions[i]);
+        strcat(dims_str,s);
+      }
+      sprintf(s, " or %d", exact_dimensions[n-1]);
+      strcat(dims_str,s);
+      PyErr_Format(PyExc_TypeError,
+                   "Array must have %s dimensions.  Given array has %d dimensions",
+                   dims_str, array_numdims(ary));
+    }
+    return success;
+  }
+
+  /* Require the given PyArrayObject to have a specified shape.  If the
+   * array has the specified shape, return 1.  Otherwise, set the python
+   * error string and return 0.
+   */
+  int require_size(PyArrayObject* ary, npy_intp* size, int n)
+  {
+    int i;
+    int success = 1;
+    int len;
+    char desired_dims[255] = "[";
+    char s[255];
+    char actual_dims[255] = "[";
+    for(i=0; i < n;i++)
+    {
+      if (size[i] != -1 &&  size[i] != array_size(ary,i))
+      {
+        success = 0;
+      }
+    }
+    if (!success)
+    {
+      for (i = 0; i < n; i++)
+      {
+        if (size[i] == -1)
+        {
+          sprintf(s, "*,");
+        }
+        else
+        {
+          sprintf(s, "%ld,", (long int)size[i]);
+        }
+        strcat(desired_dims,s);
+      }
+      len = strlen(desired_dims);
+      desired_dims[len-1] = ']';
+      for (i = 0; i < n; i++)
+      {
+        sprintf(s, "%ld,", (long int)array_size(ary,i));
+        strcat(actual_dims,s);
+      }
+      len = strlen(actual_dims);
+      actual_dims[len-1] = ']';
+      PyErr_Format(PyExc_TypeError,
+                   "Array must have shape of %s.  Given array has shape of %s",
+                   desired_dims, actual_dims);
+    }
+    return success;
+  }
+
+  /* Require the given PyArrayObject to to be FORTRAN ordered.  If the
+   * the PyArrayObject is already FORTRAN ordered, do nothing.  Else,
+   * set the FORTRAN ordering flag and recompute the strides.
+   */
+  int require_fortran(PyArrayObject* ary)
+  {
+    int success = 1;
+    int nd = array_numdims(ary);
+    int i;
+    if (array_is_fortran(ary)) return success;
+    /* Set the FORTRAN ordered flag */
+    ary->flags = NPY_FARRAY;
+    /* Recompute the strides */
+    ary->strides[0] = ary->strides[nd-1];
+    for (i=1; i < nd; ++i)
+      ary->strides[i] = ary->strides[i-1] * array_size(ary,i-1);
+    return success;
+  }
+}
+
+/* Combine all NumPy fragments into one for convenience */
+%fragment("NumPy_Fragments", "header",
+          fragment="NumPy_Backward_Compatibility",
+          fragment="NumPy_Macros",
+          fragment="NumPy_Utilities",
+          fragment="NumPy_Object_to_Array",
+          fragment="NumPy_Array_Requirements") { }
+
+/* End John Hunter translation (with modifications by Bill Spotz)
+ */
+
+/* %numpy_typemaps() macro
+ *
+ * This macro defines a family of 41 typemaps that allow C arguments
+ * of the form
+ *
+ *     (DATA_TYPE IN_ARRAY1[ANY])
+ *     (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
+ *     (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+ *
+ *     (DATA_TYPE IN_ARRAY2[ANY][ANY])
+ *     (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ *     (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
+ *     (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ *     (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+ *
+ *     (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
+ *     (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ *     (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
+ *     (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ *     (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
+ *
+ *     (DATA_TYPE INPLACE_ARRAY1[ANY])
+ *     (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
+ *     (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
+ *
+ *     (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
+ *     (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ *     (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
+ *     (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ *     (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
+ *
+ *     (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
+ *     (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ *     (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
+ *     (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ *     (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3)
+ *
+ *     (DATA_TYPE ARGOUT_ARRAY1[ANY])
+ *     (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
+ *     (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
+ *
+ *     (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
+ *
+ *     (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
+ *
+ *     (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1)
+ *     (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1)
+ *
+ *     (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ *     (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2)
+ *     (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ *     (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2)
+ *
+ *     (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+ *     (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)
+ *     (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+ *     (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3)
+ *
+ * where "DATA_TYPE" is any type supported by the NumPy module, and
+ * "DIM_TYPE" is any int-like type suitable for specifying dimensions.
+ * The difference between "ARRAY" typemaps and "FARRAY" typemaps is
+ * that the "FARRAY" typemaps expect FORTRAN ordering of
+ * multidimensional arrays.  In python, the dimensions will not need
+ * to be specified (except for the "DATA_TYPE* ARGOUT_ARRAY1"
+ * typemaps).  The IN_ARRAYs can be a numpy array or any sequence that
+ * can be converted to a numpy array of the specified type.  The
+ * INPLACE_ARRAYs must be numpy arrays of the appropriate type.  The
+ * ARGOUT_ARRAYs will be returned as new numpy arrays of the
+ * appropriate type.
+ *
+ * These typemaps can be applied to existing functions using the
+ * %apply directive.  For example:
+ *
+ *     %apply (double* IN_ARRAY1, int DIM1) {(double* series, int length)};
+ *     double prod(double* series, int length);
+ *
+ *     %apply (int DIM1, int DIM2, double* INPLACE_ARRAY2)
+ *           {(int rows, int cols, double* matrix        )};
+ *     void floor(int rows, int cols, double* matrix, double f);
+ *
+ *     %apply (double IN_ARRAY3[ANY][ANY][ANY])
+ *           {(double tensor[2][2][2]         )};
+ *     %apply (double ARGOUT_ARRAY3[ANY][ANY][ANY])
+ *           {(double low[2][2][2]                )};
+ *     %apply (double ARGOUT_ARRAY3[ANY][ANY][ANY])
+ *           {(double upp[2][2][2]                )};
+ *     void luSplit(double tensor[2][2][2],
+ *                  double low[2][2][2],
+ *                  double upp[2][2][2]    );
+ *
+ * or directly with
+ *
+ *     double prod(double* IN_ARRAY1, int DIM1);
+ *
+ *     void floor(int DIM1, int DIM2, double* INPLACE_ARRAY2, double f);
+ *
+ *     void luSplit(double IN_ARRAY3[ANY][ANY][ANY],
+ *                  double ARGOUT_ARRAY3[ANY][ANY][ANY],
+ *                  double ARGOUT_ARRAY3[ANY][ANY][ANY]);
+ */
+
+%define %numpy_typemaps(DATA_TYPE, DATA_TYPECODE, DIM_TYPE)
+
+/************************/
+/* Input Array Typemaps */
+/************************/
+
+/* Typemap suite for (DATA_TYPE IN_ARRAY1[ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE IN_ARRAY1[ANY])
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE IN_ARRAY1[ANY])
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[1] = { $1_dim0 };
+  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 1) ||
+      !require_size(array, size, 1)) SWIG_fail;
+  $1 = ($1_ltype) array_data(array);
+}
+%typemap(freearg)
+  (DATA_TYPE IN_ARRAY1[ANY])
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[1] = { -1 };
+  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 1) ||
+      !require_size(array, size, 1)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = (DIM_TYPE) array_size(array,0);
+}
+%typemap(freearg)
+  (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[1] = {-1};
+  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 1) ||
+      !require_size(array, size, 1)) SWIG_fail;
+  $1 = (DIM_TYPE) array_size(array,0);
+  $2 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+  (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE IN_ARRAY2[ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE IN_ARRAY2[ANY][ANY])
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE IN_ARRAY2[ANY][ANY])
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[2] = { $1_dim0, $1_dim1 };
+  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 2) ||
+      !require_size(array, size, 2)) SWIG_fail;
+  $1 = ($1_ltype) array_data(array);
+}
+%typemap(freearg)
+  (DATA_TYPE IN_ARRAY2[ANY][ANY])
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[2] = { -1, -1 };
+  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 2) ||
+      !require_size(array, size, 2)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = (DIM_TYPE) array_size(array,0);
+  $3 = (DIM_TYPE) array_size(array,1);
+}
+%typemap(freearg)
+  (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[2] = { -1, -1 };
+  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 2) ||
+      !require_size(array, size, 2)) SWIG_fail;
+  $1 = (DIM_TYPE) array_size(array,0);
+  $2 = (DIM_TYPE) array_size(array,1);
+  $3 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[2] = { -1, -1 };
+  array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE,
+                                                &is_new_object);
+  if (!array || !require_dimensions(array, 2) ||
+      !require_size(array, size, 2) || !require_fortran(array)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = (DIM_TYPE) array_size(array,0);
+  $3 = (DIM_TYPE) array_size(array,1);
+}
+%typemap(freearg)
+  (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[2] = { -1, -1 };
+  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 2) ||
+      !require_size(array, size, 2) || !require_fortran(array)) SWIG_fail;
+  $1 = (DIM_TYPE) array_size(array,0);
+  $2 = (DIM_TYPE) array_size(array,1);
+  $3 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[3] = { $1_dim0, $1_dim1, $1_dim2 };
+  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 3) ||
+      !require_size(array, size, 3)) SWIG_fail;
+  $1 = ($1_ltype) array_data(array);
+}
+%typemap(freearg)
+  (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ *                    DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[3] = { -1, -1, -1 };
+  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 3) ||
+      !require_size(array, size, 3)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = (DIM_TYPE) array_size(array,0);
+  $3 = (DIM_TYPE) array_size(array,1);
+  $4 = (DIM_TYPE) array_size(array,2);
+}
+%typemap(freearg)
+  (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
+ *                    DATA_TYPE* IN_ARRAY3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[3] = { -1, -1, -1 };
+  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 3) ||
+      !require_size(array, size, 3)) SWIG_fail;
+  $1 = (DIM_TYPE) array_size(array,0);
+  $2 = (DIM_TYPE) array_size(array,1);
+  $3 = (DIM_TYPE) array_size(array,2);
+  $4 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ *                    DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[3] = { -1, -1, -1 };
+  array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE,
+                                                &is_new_object);
+  if (!array || !require_dimensions(array, 3) ||
+      !require_size(array, size, 3) | !require_fortran(array)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = (DIM_TYPE) array_size(array,0);
+  $3 = (DIM_TYPE) array_size(array,1);
+  $4 = (DIM_TYPE) array_size(array,2);
+}
+%typemap(freearg)
+  (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
+ *                    DATA_TYPE* IN_FARRAY3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[3] = { -1, -1, -1 };
+  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 3) ||
+      !require_size(array, size, 3) || !require_fortran(array)) SWIG_fail;
+  $1 = (DIM_TYPE) array_size(array,0);
+  $2 = (DIM_TYPE) array_size(array,1);
+  $3 = (DIM_TYPE) array_size(array,2);
+  $4 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/***************************/
+/* In-Place Array Typemaps */
+/***************************/
+
+/* Typemap suite for (DATA_TYPE INPLACE_ARRAY1[ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE INPLACE_ARRAY1[ANY])
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE INPLACE_ARRAY1[ANY])
+  (PyArrayObject* array=NULL)
+{
+  npy_intp size[1] = { $1_dim0 };
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,1) || !require_size(array, size, 1) ||
+      !require_contiguous(array) || !require_native(array)) SWIG_fail;
+  $1 = ($1_ltype) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
+  (PyArrayObject* array=NULL, int i=1)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,1) || !require_contiguous(array)
+      || !require_native(array)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = 1;
+  for (i=0; i < array_numdims(array); ++i) $2 *= array_size(array,i);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
+  (PyArrayObject* array=NULL, int i=0)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,1) || !require_contiguous(array)
+      || !require_native(array)) SWIG_fail;
+  $1 = 1;
+  for (i=0; i < array_numdims(array); ++i) $1 *= array_size(array,i);
+  $2 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
+  (PyArrayObject* array=NULL)
+{
+  npy_intp size[2] = { $1_dim0, $1_dim1 };
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,2) || !require_size(array, size, 2) ||
+      !require_contiguous(array) || !require_native(array)) SWIG_fail;
+  $1 = ($1_ltype) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+  (PyArrayObject* array=NULL)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,2) || !require_contiguous(array)
+      || !require_native(array)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = (DIM_TYPE) array_size(array,0);
+  $3 = (DIM_TYPE) array_size(array,1);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
+  (PyArrayObject* array=NULL)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,2) || !require_contiguous(array) ||
+      !require_native(array)) SWIG_fail;
+  $1 = (DIM_TYPE) array_size(array,0);
+  $2 = (DIM_TYPE) array_size(array,1);
+  $3 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+  (PyArrayObject* array=NULL)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,2) || !require_contiguous(array)
+      || !require_native(array) || !require_fortran(array)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = (DIM_TYPE) array_size(array,0);
+  $3 = (DIM_TYPE) array_size(array,1);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
+  (PyArrayObject* array=NULL)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,2) || !require_contiguous(array) ||
+      !require_native(array) || !require_fortran(array)) SWIG_fail;
+  $1 = (DIM_TYPE) array_size(array,0);
+  $2 = (DIM_TYPE) array_size(array,1);
+  $3 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
+  (PyArrayObject* array=NULL)
+{
+  npy_intp size[3] = { $1_dim0, $1_dim1, $1_dim2 };
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,3) || !require_size(array, size, 3) ||
+      !require_contiguous(array) || !require_native(array)) SWIG_fail;
+  $1 = ($1_ltype) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ *                    DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+  (PyArrayObject* array=NULL)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,3) || !require_contiguous(array) ||
+      !require_native(array)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = (DIM_TYPE) array_size(array,0);
+  $3 = (DIM_TYPE) array_size(array,1);
+  $4 = (DIM_TYPE) array_size(array,2);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
+ *                    DATA_TYPE* INPLACE_ARRAY3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
+  (PyArrayObject* array=NULL)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,3) || !require_contiguous(array)
+      || !require_native(array)) SWIG_fail;
+  $1 = (DIM_TYPE) array_size(array,0);
+  $2 = (DIM_TYPE) array_size(array,1);
+  $3 = (DIM_TYPE) array_size(array,2);
+  $4 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ *                    DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+  (PyArrayObject* array=NULL)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,3) || !require_contiguous(array) ||
+      !require_native(array) || !require_fortran(array)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = (DIM_TYPE) array_size(array,0);
+  $3 = (DIM_TYPE) array_size(array,1);
+  $4 = (DIM_TYPE) array_size(array,2);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
+ *                    DATA_TYPE* INPLACE_FARRAY3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3)
+  (PyArrayObject* array=NULL)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,3) || !require_contiguous(array)
+      || !require_native(array) || !require_fortran(array)) SWIG_fail;
+  $1 = (DIM_TYPE) array_size(array,0);
+  $2 = (DIM_TYPE) array_size(array,1);
+  $3 = (DIM_TYPE) array_size(array,2);
+  $4 = (DATA_TYPE*) array_data(array);
+}
+
+/*************************/
+/* Argout Array Typemaps */
+/*************************/
+
+/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY1[ANY])
+ */
+%typemap(in,numinputs=0,
+         fragment="NumPy_Backward_Compatibility,NumPy_Macros")
+  (DATA_TYPE ARGOUT_ARRAY1[ANY])
+  (PyObject * array = NULL)
+{
+  npy_intp dims[1] = { $1_dim0 };
+  array = PyArray_SimpleNew(1, dims, DATA_TYPECODE);
+  if (!array) SWIG_fail;
+  $1 = ($1_ltype) array_data(array);
+}
+%typemap(argout)
+  (DATA_TYPE ARGOUT_ARRAY1[ANY])
+{
+  $result = SWIG_Python_AppendOutput($result,array$argnum);
+}
+
+/* Typemap suite for (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
+ */
+%typemap(in,numinputs=1,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
+  (PyObject * array = NULL)
+{
+  npy_intp dims[1];
+  if (!PyInt_Check($input))
+  {
+    const char* typestring = pytype_string($input);
+    PyErr_Format(PyExc_TypeError,
+                 "Int dimension expected.  '%s' given.",
+                 typestring);
+    SWIG_fail;
+  }
+  $2 = (DIM_TYPE) PyInt_AsLong($input);
+  dims[0] = (npy_intp) $2;
+  array = PyArray_SimpleNew(1, dims, DATA_TYPECODE);
+  if (!array) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+}
+%typemap(argout)
+  (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
+{
+  $result = SWIG_Python_AppendOutput($result,array$argnum);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
+ */
+%typemap(in,numinputs=1,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
+  (PyObject * array = NULL)
+{
+  npy_intp dims[1];
+  if (!PyInt_Check($input))
+  {
+    const char* typestring = pytype_string($input);
+    PyErr_Format(PyExc_TypeError,
+                 "Int dimension expected.  '%s' given.",
+                 typestring);
+    SWIG_fail;
+  }
+  $1 = (DIM_TYPE) PyInt_AsLong($input);
+  dims[0] = (npy_intp) $1;
+  array = PyArray_SimpleNew(1, dims, DATA_TYPECODE);
+  if (!array) SWIG_fail;
+  $2 = (DATA_TYPE*) array_data(array);
+}
+%typemap(argout)
+  (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
+{
+  $result = SWIG_Python_AppendOutput($result,array$argnum);
+}
+
+/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
+ */
+%typemap(in,numinputs=0,
+         fragment="NumPy_Backward_Compatibility,NumPy_Macros")
+  (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
+  (PyObject * array = NULL)
+{
+  npy_intp dims[2] = { $1_dim0, $1_dim1 };
+  array = PyArray_SimpleNew(2, dims, DATA_TYPECODE);
+  if (!array) SWIG_fail;
+  $1 = ($1_ltype) array_data(array);
+}
+%typemap(argout)
+  (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
+{
+  $result = SWIG_Python_AppendOutput($result,array$argnum);
+}
+
+/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
+ */
+%typemap(in,numinputs=0,
+         fragment="NumPy_Backward_Compatibility,NumPy_Macros")
+  (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
+  (PyObject * array = NULL)
+{
+  npy_intp dims[3] = { $1_dim0, $1_dim1, $1_dim2 };
+  array = PyArray_SimpleNew(3, dims, DATA_TYPECODE);
+  if (!array) SWIG_fail;
+  $1 = ($1_ltype) array_data(array);
+}
+%typemap(argout)
+  (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
+{
+  $result = SWIG_Python_AppendOutput($result,array$argnum);
+}
+
+/*****************************/
+/* Argoutview Array Typemaps */
+/*****************************/
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1    )
+  (DATA_TYPE*  data_temp        , DIM_TYPE  dim_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility")
+  (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1)
+{
+  npy_intp dims[1] = { *$2 };
+  PyObject * array = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$1));
+  if (!array) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,array);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1    , DATA_TYPE** ARGOUTVIEW_ARRAY1)
+  (DIM_TYPE  dim_temp, DATA_TYPE*  data_temp        )
+{
+  $1 = &dim_temp;
+  $2 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility")
+  (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1)
+{
+  npy_intp dims[1] = { *$1 };
+  PyObject * array = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$2));
+  if (!array) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,array);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1     , DIM_TYPE* DIM2     )
+  (DATA_TYPE*  data_temp        , DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility")
+  (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+{
+  npy_intp dims[2] = { *$2, *$3 };
+  PyObject * array = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1));
+  if (!array) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,array);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1     , DIM_TYPE* DIM2     , DATA_TYPE** ARGOUTVIEW_ARRAY2)
+  (DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp, DATA_TYPE*  data_temp        )
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2)
+{
+  npy_intp dims[2] = { *$1, *$2 };
+  PyObject * array = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3));
+  if (!array) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,array);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1     , DIM_TYPE* DIM2     )
+  (DATA_TYPE*  data_temp        , DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+  (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+{
+  npy_intp dims[2] = { *$2, *$3 };
+  PyObject * obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject * array = (PyArrayObject*) obj;
+  if (!array || !require_fortran(array)) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1     , DIM_TYPE* DIM2     , DATA_TYPE** ARGOUTVIEW_FARRAY2)
+  (DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp, DATA_TYPE*  data_temp        )
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2)
+{
+  npy_intp dims[2] = { *$1, *$2 };
+  PyObject * obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3));
+  PyArrayObject * array = (PyArrayObject*) obj;
+  if (!array || !require_fortran(array)) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+                      DIM_TYPE* DIM3)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+  (DATA_TYPE* data_temp, DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+  $4 = &dim3_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility")
+  (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+{
+  npy_intp dims[3] = { *$2, *$3, *$4 };
+  PyObject * array = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1));
+  if (!array) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,array);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3,
+                      DATA_TYPE** ARGOUTVIEW_ARRAY3)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)
+  (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp)
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &dim3_temp;
+  $4 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)
+{
+  npy_intp dims[3] = { *$1, *$2, *$3 };
+  PyObject * array = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$3));
+  if (!array) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,array);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+                      DIM_TYPE* DIM3)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+  (DATA_TYPE* data_temp, DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+  $4 = &dim3_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+  (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+{
+  npy_intp dims[3] = { *$2, *$3, *$4 };
+  PyObject * obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject * array = (PyArrayObject*) obj;
+  if (!array || require_fortran(array)) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3,
+                      DATA_TYPE** ARGOUTVIEW_FARRAY3)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3)
+  (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp)
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &dim3_temp;
+  $4 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3)
+{
+  npy_intp dims[3] = { *$1, *$2, *$3 };
+  PyObject * obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$3));
+  PyArrayObject * array = (PyArrayObject*) obj;
+  if (!array || require_fortran(array)) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+%enddef    /* %numpy_typemaps() macro */
+/* *************************************************************** */
+
+/* Concrete instances of the %numpy_typemaps() macro: Each invocation
+ * below applies all of the typemaps above to the specified data type.
+ */
+%numpy_typemaps(signed char       , NPY_BYTE     , int)
+%numpy_typemaps(unsigned char     , NPY_UBYTE    , int)
+%numpy_typemaps(short             , NPY_SHORT    , int)
+%numpy_typemaps(unsigned short    , NPY_USHORT   , int)
+%numpy_typemaps(int               , NPY_INT      , int)
+%numpy_typemaps(unsigned int      , NPY_UINT     , int)
+%numpy_typemaps(long              , NPY_LONG     , int)
+%numpy_typemaps(unsigned long     , NPY_ULONG    , int)
+%numpy_typemaps(long long         , NPY_LONGLONG , int)
+%numpy_typemaps(unsigned long long, NPY_ULONGLONG, int)
+%numpy_typemaps(float             , NPY_FLOAT    , int)
+%numpy_typemaps(double            , NPY_DOUBLE   , int)
+
+/* ***************************************************************
+ * The follow macro expansion does not work, because C++ bool is 4
+ * bytes and NPY_BOOL is 1 byte
+ *
+ *    %numpy_typemaps(bool, NPY_BOOL, int)
+ */
+
+/* ***************************************************************
+ * On my Mac, I get the following warning for this macro expansion:
+ * 'swig/python detected a memory leak of type 'long double *', no destructor found.'
+ *
+ *    %numpy_typemaps(long double, NPY_LONGDOUBLE, int)
+ */
+
+/* ***************************************************************
+ * Swig complains about a syntax error for the following macro
+ * expansions:
+ *
+ *    %numpy_typemaps(complex float,  NPY_CFLOAT , int)
+ *
+ *    %numpy_typemaps(complex double, NPY_CDOUBLE, int)
+ *
+ *    %numpy_typemaps(complex long double, NPY_CLONGDOUBLE, int)
+ */
+
+#endif /* SWIGPYTHON */
diff --git a/pymolfile/libpymolfile/python_molfile.i b/pymolfile/libpymolfile-old/python_molfile.i
similarity index 100%
rename from pymolfile/libpymolfile/python_molfile.i
rename to pymolfile/libpymolfile-old/python_molfile.i
diff --git a/pymolfile/libpymolfile-old/tester.f b/pymolfile/libpymolfile-old/tester.f
new file mode 100644
index 0000000000000000000000000000000000000000..40e250bb80cc1ad0d8446dd5d37f2726679b5636
--- /dev/null
+++ b/pymolfile/libpymolfile-old/tester.f
@@ -0,0 +1,110 @@
+c     testing frontend for the molfile plugin fortran interface
+c     $Id: tester.f,v 1.1 2006/03/10 22:48:49 johns Exp $
+c     (c) 2006 Axel Kohlmeyer <akohlmey@cmm.chem.upenn.edu>
+
+      program molfile
+      implicit none
+
+      integer*4 natom, maxatom, handle(4), status
+      parameter (maxatom=3000*3)
+      real*4    xyz(maxatom), box(6)
+
+      character infile*200, intype*10
+      integer i,j
+
+      print*,'molfile fortran tester v0.01'
+
+C     set some default values
+      infile = 'TRAJEC.dcd'
+      intype = 'auto'
+      natom  = -1
+      handle(1) = -1
+      handle(2) = -1
+      handle(3) = -1
+      handle(4) = -1
+      
+      print*,'filename: ', infile
+      print*,'type:     ', intype
+
+C     set up everything and 
+C     register all static plugins
+      call f77_molfile_init
+
+      call f77_molfile_open_read(handle(1),natom,infile,intype)
+
+      if (handle(1).lt.0) then
+         print*,'file type unknown or not registered'
+      else
+         print*,'file successfully opened:'
+         print*,'handle:',handle(1)
+         print*,'natom: ',natom
+      end if
+
+      do i=1,2000
+         status = 1   ! status=1 on entry means read
+         call f77_molfile_read_next(handle(1),natom,xyz(1),box,status);
+         print*,'read ',i,'  status:',status
+         print*,'atom(1)', (xyz(j),j=1,3)
+         print*,'atom(10)',(xyz(j),j=31,33)
+         print*,'atom(100)',(xyz(j),j=301,303)
+         print*,'box',box
+         if(status.eq.0) go to 666
+         status = 0   ! status=0 on entry means skip
+         call f77_molfile_read_next(handle(1),natom,xyz,box,status);
+         print*,'read ',i,'  status:',status
+         if(status.eq.0) go to 666
+      end do
+ 666  continue
+
+      infile='li-nh3_4-end.pdb'
+      intype='pdb'
+      call f77_molfile_open_read(handle(2),natom,infile,intype)
+
+      if (handle(2).lt.0) then
+         print*,'file type unknown or not registered'
+      else
+         print*,'file successfully opened:'
+         print*,'handle:',handle(2)
+         print*,'natom: ',natom
+      end if
+
+      do i=1,2000
+         status = 1   ! status=1 on entry means read
+         call f77_molfile_read_next(handle(2),natom,xyz(1),box,status);
+         print*,'read ',i,'  status:',status
+         if(status.eq.0) go to 6666
+         print*,'atom(1)',  (xyz(j),j=1,3)
+         print*,'atom(10)', (xyz(j),j=31,33)
+         print*,'atom(100)',(xyz(j),j=301,303)
+         print*,'box',box
+         status = 0   ! status=0 on entry means skip
+         call f77_molfile_read_next(handle(2),natom,xyz,box,status);
+         print*,'read ',i,'  status:',status
+         if(status.eq.0) go to 6666
+      end do
+ 6666 continue
+      call f77_molfile_open_read(handle(3),natom,infile,intype)
+      print*,'handle:',handle(3)
+
+      call f77_molfile_close_read(handle(1),status)
+      print*,'handle:',handle(1)
+      call f77_molfile_open_read(handle(1),natom,infile,intype)
+      print*,'handle:',handle(1)
+      call f77_molfile_open_read(handle(4),natom,infile,intype)
+      print*,'handle:',handle(4)
+
+
+      call f77_molfile_close_read(handle(2),status)
+      print*,'handle:',handle(2)
+      call f77_molfile_close_read(handle(1),status)
+      print*,'handle:',handle(1)
+      call f77_molfile_close_read(handle(3),status)
+      print*,'handle:',handle(3)
+      call f77_molfile_close_read(handle(2),status)
+      print*,'handle:',handle(2)
+      call f77_molfile_close_read(handle(4),status)
+      print*,'handle:',handle(4)
+
+      call f77_molfile_finish
+
+      end
diff --git a/pymolfile/libpymolfile/xdrfile.c b/pymolfile/libpymolfile-old/xdrfile.c
similarity index 100%
rename from pymolfile/libpymolfile/xdrfile.c
rename to pymolfile/libpymolfile-old/xdrfile.c
diff --git a/pymolfile/libpymolfile/xdrfile.h b/pymolfile/libpymolfile-old/xdrfile.h
similarity index 100%
rename from pymolfile/libpymolfile/xdrfile.h
rename to pymolfile/libpymolfile-old/xdrfile.h
diff --git a/pymolfile/libpymolfile/xdrfile_trr.c b/pymolfile/libpymolfile-old/xdrfile_trr.c
similarity index 100%
rename from pymolfile/libpymolfile/xdrfile_trr.c
rename to pymolfile/libpymolfile-old/xdrfile_trr.c
diff --git a/pymolfile/libpymolfile/xdrfile_trr.h b/pymolfile/libpymolfile-old/xdrfile_trr.h
similarity index 100%
rename from pymolfile/libpymolfile/xdrfile_trr.h
rename to pymolfile/libpymolfile-old/xdrfile_trr.h
diff --git a/pymolfile/libpymolfile/xdrfile_xtc.c b/pymolfile/libpymolfile-old/xdrfile_xtc.c
similarity index 100%
rename from pymolfile/libpymolfile/xdrfile_xtc.c
rename to pymolfile/libpymolfile-old/xdrfile_xtc.c
diff --git a/pymolfile/libpymolfile/xdrfile_xtc.h b/pymolfile/libpymolfile-old/xdrfile_xtc.h
similarity index 100%
rename from pymolfile/libpymolfile/xdrfile_xtc.h
rename to pymolfile/libpymolfile-old/xdrfile_xtc.h
diff --git a/pymolfile/libpymolfile/f77_molfile.c b/pymolfile/libpymolfile/f77_molfile.c
new file mode 100644
index 0000000000000000000000000000000000000000..1bb6aee33f8e61628d32f88fa160be5f8813234f
--- /dev/null
+++ b/pymolfile/libpymolfile/f77_molfile.c
@@ -0,0 +1,363 @@
+
+/* 
+ * molfile fortran interface
+ * $Id: f77_molfile.c,v 1.1 2006/03/10 22:48:49 johns Exp $
+ * (c) 2006 Axel Kohlmeyer <akohlmey@cmm.chem.upenn.edu>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "molfile_plugin.h"
+#include "libmolfile_plugin.h"
+#include "vmdplugin.h"
+
+#define F77TESTME 1
+
+/* fortran name mangling */ 
+#if defined(_F77_NO_UNDERSCORE)
+#define FNAME(n) n
+#elif defined(_F77_F2C_UNDERSCORE)
+#define FNAME(n) n ## __
+#else
+#define FNAME(n) n ## _
+#endif
+
+/* interface typedef magic */
+typedef int int4;
+
+struct molfile_f77_handle 
+{
+    void  *handle;
+    const char *fname;
+    const char *ftype;
+    molfile_plugin_t *plugin;
+};
+typedef struct molfile_f77_handle f77_fd;
+
+/* plugin list */
+#ifndef MAXPLUGINS
+#define MAXPLUGINS 200
+#endif
+static int numplugins=0;
+static molfile_plugin_t *plugin_list[MAXPLUGINS];
+
+/* we maintain a static list of assigned handles */
+#ifndef MAXHADNLES
+#define MAXHANDLES 200
+#endif
+static int4 numhandles=0;
+static f77_fd handle_list[MAXHANDLES];
+
+/* helper functions */
+/* helper function to copy fortran style (a la sun fortran) strings into
+ * valid c style strings. just using the string pointers will not work,
+ * since the strings are NOT zero terminated.
+ *
+ * WARNING: do not forget to free(2) them later, 
+ * or you'll have a memory leak!
+ */
+static char *f77strdup(const char *s,const int sz)
+{
+    char *r;
+
+    r = (char *)malloc(sz + 1);
+    r = (char *)memcpy(r, s, sz);
+    r[sz] = '\0';
+    return r;
+}
+
+/* trim off whitespace at the end of a string */
+static void f77trim(char *s,const int sz)
+{
+    int i;
+
+    i=1;
+    while( (i++ < sz) && isspace(s[sz-i]) ) {
+        s[sz-i] ='\0';
+    }
+}
+
+/* get the filename extension */
+static const char *f77getfnext(const char *s)
+{
+    int i,len;
+
+    len = strlen(s);
+    for (i=len; i>=0; --i) {
+        if(s[i] == '.') {
+            return &s[i+1];
+        }
+    }
+    return NULL;
+}
+
+/* check validity of plugins and register them. */
+static int f77register(void *ptr, vmdplugin_t *plugin) {
+
+    if (!plugin->type || !plugin->name || !plugin->author) {
+        fprintf(stderr," skipping plugin with incomplete header\n");
+        return -1;
+    }
+
+#if F77TESTME    
+    fprintf(stderr, " trying to register plugin #%d: %s,  type:    %s/%d\n"
+            " written by: %s\n\n", numplugins+1, plugin->name, 
+            plugin->type, plugin->abiversion, plugin->author);
+#endif
+
+    if (plugin->abiversion != vmdplugin_ABIVERSION) {
+        fprintf(stderr, " skipping plugin with incompatible ABI:%d/%d\n",
+                plugin->abiversion, vmdplugin_ABIVERSION);
+        return -2;
+    }
+
+    if (0 != strncmp(plugin->type, "mol file", 8)) {
+        fprintf(stderr, " skipping plugin of incompatible type:%s\n",
+                plugin->type);
+        return -3;
+    }
+
+    if (numplugins < MAXPLUGINS) {
+        plugin_list[numplugins] = (molfile_plugin_t *) plugin;
+        ++numplugins;
+        return 0;
+    }
+    
+    fprintf(stderr, " too many plugins: %d. increase MAXPLUGINS, "
+            "recompile, and try again.\n", numplugins);
+    
+    return -4;
+}
+
+
+/* the official fortran API */
+
+/* register all available plugins and clear handles. */
+void FNAME(f77_molfile_init)(void) 
+{
+    int i;
+    
+    MOLFILE_INIT_ALL;
+
+    for (i=0; i<MAXHANDLES; ++i) {
+        handle_list[i].handle = NULL;
+    }
+
+    MOLFILE_REGISTER_ALL(NULL,f77register);
+
+    /* 
+     * FIXME: check all plugins and make 
+     * sure the babel plugin(s) are last.
+     */
+}
+
+/* unregister all available plugins */
+void FNAME(f77_molfile_finish)(void) 
+{
+#if 0
+    int i;
+
+    /* FIXME: add code to close and nullify all open handles */
+    for (i=0; i<MAXHANDLES; ++i) {
+        handle_list[i] = NULL;
+    }
+#endif
+
+    MOLFILE_FINI_ALL;
+}
+
+
+/* open a file and provide file descriptor */
+void FNAME(f77_molfile_open_read)(int4 *handle, int4 *natoms,
+                        const char *infile, const char *intype, 
+                        const int len_if, const int len_it)
+{
+    char *fname, *ftype;
+    molfile_plugin_t *plugin;
+    int i;
+    
+    if (numhandles >= MAXHANDLES) {
+        fprintf(stderr, "too many molfile f77 handles.\n");
+        *handle = -666;
+        return;
+    }
+
+    fname = f77strdup(infile, len_if);
+    f77trim(fname,len_if);
+    
+    ftype = f77strdup(intype, len_it);
+    f77trim(ftype,len_it);
+            
+    fprintf(stderr, " %s: trying for: %s/%d, %s/%d\n", 
+            __FUNCTION__, fname, len_if, ftype, len_it);
+
+    plugin = NULL;
+    /* determine plugin type automatically */
+    if(0 == strncmp(intype, "auto", 4)) {
+        const char *fext;
+        
+        fext = f77getfnext(fname);
+        if (fext == NULL) {
+            fprintf(stderr, " could not determine file name extension "
+                    "for automatic plugin guess\n");
+            *handle = -111;
+            return;
+        }
+#if F77TESTME
+        fprintf(stderr, " filename extension: %s\n", fext);
+#endif
+
+        for (i=0; (i<numplugins) && plugin==NULL; ++i) {
+#if F77TESTME
+            fprintf(stderr, " tying filename extension: %s\n",
+                    plugin_list[i]->filename_extension);
+#endif
+            if (0 == strcmp(plugin_list[i]->filename_extension, fext)) {
+                fprintf(stderr, " using plugin: %s\n", 
+                        plugin_list[i]->prettyname);
+                
+                plugin = plugin_list[i];
+            }
+        }
+        if (plugin == NULL) {
+            fprintf(stderr, " could not determine matching plugin type"
+                    "from file name extension\n");
+            *handle = -222;
+            return;
+        }
+    } else {
+        
+        for (i=0; (i<numplugins) && (plugin==NULL); ++i) {
+#if F77TESTME
+            fprintf(stderr, " tying plugin type: %s\n",
+                    plugin_list[i]->name);
+#endif
+            if (0 == strcmp(plugin_list[i]->name, ftype)) {
+                fprintf(stderr, " using plugin: %s\n", 
+                        plugin_list[i]->prettyname);
+                plugin = plugin_list[i];
+            }
+        }
+        if (plugin == NULL) {
+            fprintf(stderr, " could not find plugin for type %s\n",ftype);
+            *handle = -333;
+            return;
+        }
+    }
+    
+    if(plugin == NULL) { /* this should not happen, but... */
+        fprintf(stderr, " no plugin found.\n");
+        *handle = -444;
+        return;
+    }
+    
+    /* build handle */
+    ++numhandles;
+    for (i=0; i<numhandles; ++i) {
+        if(handle_list[i].plugin == NULL) {
+            *handle = i;
+            handle_list[i].fname=fname;
+            handle_list[i].ftype=plugin->name;
+            handle_list[i].plugin=plugin;
+        }
+    }
+
+    /* open file for reading and detect number of atoms */
+    *natoms=MOLFILE_NUMATOMS_UNKNOWN;
+    handle_list[*handle].handle= 
+        plugin->open_file_read(fname,plugin->name,natoms);
+    if(handle_list[*handle].handle == NULL) {
+        fprintf(stderr, " open of %s-plugin for file %s failed\n",
+                plugin->type, fname);
+        --numhandles;
+        handle_list[*handle].plugin=NULL;
+        *handle=-777;
+        return;
+    }
+    
+    return;
+}
+
+/* read next time step */
+void FNAME(f77_molfile_read_next)(int4 *handle, int4 *natoms, float *xyz, 
+                             float *box, int4 *status)
+{
+    molfile_plugin_t *plugin;
+    molfile_timestep_t step;
+    int retval;
+
+    /* do some sanity checks on the handle */
+    if((*handle < 0) || (*handle >= MAXHANDLES)) {
+        fprintf(stderr, " %s: illegal handle: %d\n",
+                __FUNCTION__, *handle);
+        *status = 0;
+        return;
+    }
+
+    plugin = handle_list[*handle].plugin;
+    if(plugin==NULL) {
+        fprintf(stderr, " %s: inactive handle: %d\n",
+                __FUNCTION__, *handle);
+        *status = 0;
+        return;
+    }
+
+    /* skip or read the timestep as demanded */
+    if(status == 0) {
+        retval = plugin->read_next_timestep(handle_list[*handle].handle,
+                                             *natoms, NULL);
+    } else {
+        step.coords = xyz;
+        retval = plugin->read_next_timestep(handle_list[*handle].handle,
+                                             *natoms, &step);
+    }
+
+    /* copy the box parameters */
+    if (retval == MOLFILE_SUCCESS) {
+        *status = 1;
+        box[0]=step.A;
+        box[1]=step.B;
+        box[2]=step.C;
+        box[3]=step.alpha;
+        box[4]=step.beta;
+        box[5]=step.gamma;
+    } else {
+        *status = 0;
+    }
+}
+            
+/* close a read file descriptor */
+void FNAME(f77_molfile_close_read)(int4 *handle)
+{
+    molfile_plugin_t *plugin;
+    
+    /* do some sanity checks on the handle */
+    if((*handle < 0) || (*handle >= MAXHANDLES)) {
+        fprintf(stderr, " %s: illegal handle: %d\n",
+                __FUNCTION__, *handle);
+        *handle = -111;
+        return;
+    }
+
+    plugin = handle_list[*handle].plugin;
+    if(plugin==NULL) {
+        fprintf(stderr, " %s: inactive handle: %d\n",
+                __FUNCTION__, *handle);
+        *handle = -222;
+        return;
+    }
+
+#if F77TESTME
+    fprintf(stderr, " %s: trying to close handle %d"
+            " for file %s\n", __FUNCTION__, *handle, 
+            handle_list[*handle].fname);
+#endif
+
+    plugin->close_file_read(handle_list[*handle].handle);
+    --numhandles;
+    handle_list[*handle].plugin=NULL;
+    *handle=-1;
+}
diff --git a/pymolfile/libpymolfile/libvmdmolfile.i b/pymolfile/libpymolfile/libvmdmolfile.i
index 5bc26bba13286284a3c168a6d2394d526c215668..e5314f178c70209e9765dcabcf1f04f68f8a798b 100644
--- a/pymolfile/libpymolfile/libvmdmolfile.i
+++ b/pymolfile/libpymolfile/libvmdmolfile.i
@@ -1,390 +1,17 @@
 /* -*- C -*-  (not really, but good for syntax highlighting) */
 /* SWIG interface for libvmdmolfile of VMD molfile_plugins
    Copyright (c) 2017 Berk Onat <b.onat@warwick.ac.uk>
-   Published under the GNU GENERAL PUBLIC LICENSE Version 2 (or higher)
+   Published under BSD LICENSE
 
-   swig -python -outdir MDAnalysis/coordinates/xdrfile src/xdrfile/libxdrfile2.i
+   swig -python -outdir . src/xdrfile/libxdrfile2.i
 */
 %define DOCSTRING
 "
 :Author:  Berk Onat <b.onat@warwick.ac.uk>
 :Year:    2017
-:Licence: GNU GENERAL PUBLIC LICENSE Version 2 (or higher)
+:Licence: BSD LICENSE
 
 
-The Gromacs XTC/TRR library :mod:`libxdrfile2`
-==============================================
-
-:mod:`libxdrfile2`, a derivative of the Gromacs_ `libxdrfile library`_, provides an
-interface to some high-level functions for XTC/TRR trajectory handling.
-Only functions required for reading and processing whole trajectories are exposed at
-the moment; low-level routines to read individual numbers are not provided. In
-addition, :mod:`libxdrfile2` exposes functions to allow fast frame indexing and XDR
-file seeking.
-
-The functions querying the numbers of atoms in a trajectory frame
-(:func:`read_xtc_natoms` and :func:`read_trr_natoms`) open a file themselves and
-only require the file name.
-
-All other functions operate on a *XDRFILE* object, which is a special file
-handle for xdr files.  Any xdr-based trajectory file (XTC or TRR format) always
-has to be opened with :func:`xdrfile_open`. When done, close the trajectory
-with :func:`xdrfile_close`.
-
-The functions fill or read existing arrays of coordinates; they never allocate
-these arrays themselves. Hence they need to be setup outside libxdrfile2 as
-numpy arrays. The exception to these are the indexing ones functions that take
-care of array allocation and transference to a garbage-collectable memory object.
-
-
-.. _Gromacs: http://www.gromacs.org
-.. _libxdrfile library: http://www.gromacs.org/Developer_Zone/Programming_Guide/XTC_Library
-
-.. versionchanged:: 0.8.0
-   :mod:`libxdrfile2` is now used instead of :mod:`libxdrfile`. :mod:`libxdrfile2` is
-   based on :mod:`libxdrfile` but has xdr seeking and indexing capabilities.
-   Unlike :mod:`libxdrfile` before it, :mod:`libxdrfile2` is distributed under the GNU
-   GENERAL PUBLIC LICENSE, version 2 (or higher).
-
-
-Example: Reading from a XTC
----------------------------
-
-In the example we read coordinate frames from an existing XTC trajectory::
-
-  import numpy as np
-  from libxdrfile2 import xdrfile_open, xdrfile_close, read_xtc_natoms, read_xtc, DIM, exdrOK
-  xtc = 'md.xtc'
-
-  # get number of atoms
-  natoms = read_xtc_natoms(xtc)
-
-  # allocate coordinate array of the right size and type
-  # (the type float32 is crucial to match the underlying C-code!!)
-  x = np.zeros((natoms, DIM), dtype=np.float32)
-  # allocate unit cell box
-  box = np.zeros((DIM, DIM), dtype=np.float32)
-
-  # open file
-  XTC = xdrfile_open(xtc, 'r')
-
-  # loop through file until return status signifies end or a problem
-  # (it should become exdrENDOFFILE on the last iteration)
-  status = exdrOK
-  while status == exdrOK:
-     status,step,time,prec = read_xtc(XTC, box, x)
-     # do something with x
-     centre = x.mean(axis=0)
-     print 'Centre of geometry at %(time)g ps: %(centre)r' % vars()
-
-  # finally close file
-  xdrfile_close(XTC)
-
-Note that only the *contents* of the coordinate and unitcell arrays *x* and
-*box* change.
-
-
-Functions and constants
------------------------
-
-The module defines a number of constants such as :data:`DIM` or the
-`Status symbols`_.
-
-.. data:: DIM
-
-          The number of cartesian dimensions for which the underlying C-code
-          was compiled; this is most certainly 3.
-
-
-Status symbols
-~~~~~~~~~~~~~~
-
-A number of symbols are exported; they all start with the letters
-``exdr``. Important ones are:
-
-.. data:: exdrOK
-
-          Success of xdr file read/write operation.
-
-.. data:: exdrCLOSE
-
-          xdr file is closed
-
-.. data:: exdrENDOFFILE
-
-          end of file was reached (response of :func:`read_xtc` and
-          :func:`read_trr` after the last read frame)
-
-.. data:: exdrFILENOTFOUND
-
-          :func:`xdrfile_open` cannot find the requested file
-
-Other symbols that are used internally are:
-
-.. data:: exdrHEADER
-
-          header
-
-.. data:: exdrSTRING
-
-          string
-
-.. data:: exdrDOUBLE
-
-          double precision floating point number
-
-.. data:: exdrINT
-
-          integer
-
-.. data:: exdrFLOAT
-
-          floating point number
-
-.. data:: exdrUINT
-
-          unsigned integer
-
-.. data:: exdr3DX
-
-          compressed 3D coordinates
-
-.. data:: exdrMAGIC
-
-          magic number
-
-.. data:: exdrNOMEM
-
-          not enough memory to allocate space for a XDR data structure.
-
-Opening and closing of XDR files
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Two low-level functions are used to obtain a *XDRFILE* object (a file handle)
-to access xdr files such as XTC or TRR trajectories.
-
-.. function:: xdrfile_open(path, mode) -> XDRFILE
-
-              Open *path* and returns a *XDRFILE* handle that is required by other
-              functions.
-
-              :Arguments:
-		  *path*
-		     file name
-		  *mode*
-		     'r' for reading and 'w' for writing
-	      :Returns: *XDRFILE* handle
-
-.. function:: xdrfile_close(XDRFILE) -> status
-
-              Close the xdrfile pointed to by *XDRFILE*.
-
-              .. Warning:: Closing an already closed file will lead to a
-                           crash with a double-free pointer error.
-
-XTC functions
-~~~~~~~~~~~~~
-
-The XTC trajectory format is a lossy compression format that only stores
-coordinates. Compression level is determined by the *precision* argument to the
-:func:`write_xtc` function. Coordinates (Gromacs_ uses nm natively) are
-multiplied by *precision* and truncated to the integer part. A typical value is
-1000.0, which gives an accuracy of 1/100 of an Angstroem.
-
-The advantage of XTC over TRR is its significantly reduced size.
-
-
-.. function:: read_xtc_natoms(fn) -> natoms
-
-              Read the number of atoms *natoms* from a xtc file *fn*.
-
-              :Arguments:
-                *fn*
-                   file name of an xtc file
-
-              :Raises: :exc:`IOError` if the supplied filed is not a XTC
-                       or if it is not readable.
-
-.. function:: read_xtc_numframes(fn) -> (numframes, offsets)
-
-              Read through the whole trajectory headers to obtain the total number of frames.
-              The process is speeded up by reading frame headers for the amount of data in the frame,
-              and then skipping directly to the next header. An array of frame offsets is also
-              returned, which can later be used to seek direcly to arbitrary frames in the trajectory.
-
-              :Arguments:
-                *fn*
-                   file name of an xtc file
-
-              :Returns:
-                a tuple containing:
-                  *numframes*
-                     an int with the total frame count in the trajectory
-                  *offsets*
-                     a numpy array of int64 recording the starting byte offset of each frame
-
-              :Raises: :exc:`IOError` if the supplied filed is not a XTC
-                       or if it is not readable.
-
-.. function:: read_xtc(XDRFILE, box, x) -> (status, step, time, precision)
-
-              Read the next frame from the opened xtc trajectory into *x*.
-
-              :Arguments:
-                *XDRFILE*
-                   open *XDRFILE* object
-                *box*
-                   pre-allocated numpy ``array((DIM,DIM),dtype=numpy.float32)`` which
-                   is filled with the unit cell box vectors
-                *x*
-                   pre-allocated numpy ``array((natoms, DIM),dtype=numpy.float32)``
-                   which is updated with the coordinates from the frame
-
-              :Returns:
-                a tuple containing:
-                  *status*
-                     integer status (0 = exdrOK), see `Status symbols`_ for other
-                     values)
-                  *step*
-                     simulation step
-                  *time*
-                     simulation time in ps
-                  *precision*
-                     precision of the lossy xtc format (typically 1000.0)
-
-.. function:: write_xtc(XDRFILE, step, time, box, x, prec) -> status
-
-              Write the next frame *x* to the opened xtc trajectory.
-
-              :Arguments:
-                *XDRFILE*
-                   open *XDRFILE* object (writable)
-                *step*
-                   simulation step
-                *time*
-                   time step in ps
-                *box*
-                   numpy ``array((DIM,DIM),dtype=numpy.float32)`` which contains
-                   the unit cell box vectors
-                *x*
-                   numpy ``array((natoms, DIM),dtype=nump.float32)``
-                   which contains the coordinates from the frame
-                *precision*
-                   precision of the lossy xtc format (typically 1000.0)
-
-              :Returns: *status*, integer status (0 = OK), see the ``libxdrfile2.exdr*``
-                        constants under `Status symbols`_ for other values)
-
-TRR functions
-~~~~~~~~~~~~~
-
-TRR is the Gromacs_ native full-feature trajectory storage format. It can contain position
-coordinates, velocities and forces, and the lambda value for free energy perturbation
-calculations. Velocities and forces are optional in the sense that they can be all zero.
-
-.. function:: read_trr_natoms(fn) -> natoms
-
-              Read the number of atoms *natoms* from a trr file *fn*.
-
-              :Arguments:
-                *fn*
-                   file name of a trr file
-
-              :Raises: :exc:`IOError` if the supplied filed is not a TRR
-                       or if it is not readable.
-
-.. function:: read_trr_numframes(fn) -> (numframes, offsets)
-
-              Read through the whole trajectory headers to obtain the total number of frames.
-              The process is speeded up by reading frame headers for the amount of data in the frame,
-              and then skipping directly to the next header. An array of frame offsets is also
-              returned, which can later be used to seek direcly to arbitrary frames in the trajectory.
-
-              :Arguments:
-                *fn*
-                   file name of an xtc file
-
-              :Returns:
-                a tuple containing:
-                  *numframes*
-                     an int with the total frame count in the trajectory
-                  *offsets*
-                     a numpy array of int64 recording the starting byte offset of each frame
-
-              :Raises: :exc:`IOError` if the supplied filed is not a TRR or if it is not readable.
-
-.. function:: read_trr(XDRFILE, box, x, v, f) -> (status, step, time, lambda)
-
-              Read the next frame from the opened trr trajectory into *x*, *v*, and *f*.
-
-              :Arguments:
-                *XDRFILE*
-                   open *XDRFILE* object
-                *box*
-                   pre-allocated numpy ``array((DIM,DIM),dtype=numpy.float32)`` which
-                   is filled with the unit cell box vectors
-                *x*
-                   pre-allocated numpy ``array((natoms, DIM),dtype=nump.float32)``
-                   which is updated with the **coordinates** from the frame
-                *v*
-                   pre-allocated numpy ``array((natoms, DIM),dtype=nump.float32)``
-                   which is updated with the **velocities** from the frame
-                *f*
-                   pre-allocated numpy ``array((natoms, DIM),dtype=nump.float32)``
-                   which is updated with the **forces** from the frame
-
-              :Returns:
-                a tuple containing:
-                  *status*
-                     integer status (0 = exdrOK), see the ``libxdrfile2.exdr*`` constants
-                     under `Status symbols`_ for other values)
-                  *step*
-                     simulation step
-                  *time*
-                     simulation time in ps
-                  *lambda*
-                     current lambda value (only interesting for free energy perturbation)
-                  *has_x*
-                     boolean indicating whether coordinates were read from the TRR
-                  *has_v*
-                     boolean indicating whether velocities were read from the TRR
-                  *has_f*
-                     boolean indicating whether forces were read from the TRR
-
-.. function:: write_trr(XDRFILE, step, time, lambda, box, x, v, f) -> status
-
-              Write the next frame to the opened trr trajectory.
-
-              :Arguments:
-                *XDRFILE*
-                   open *XDRFILE* object (writable)
-                *step*
-                   simulation step
-                *time*
-                   time step in ps
-                *lambda*
-                   free energy lambda value (typically 0.0)
-                *box*
-                   numpy ``array((DIM,DIM),dtype=numpy.float32)`` which contains
-                   the unit cell box vectors
-                *x*
-                   numpy ``array((natoms, DIM),dtype=nump.float32)``
-                   which contains the **coordinates** from the frame
-                *v*
-                   numpy ``array((natoms, DIM),dtype=nump.float32)``
-                   which contains the **velocities** from the frame
-                *f*
-                   numpy ``array((natoms, DIM),dtype=nump.float32)``
-                   which contains the **forces** from the frame
-
-              .. versionchanged:: 0.8.0
-                   either one of *x*, *v*, or *f* can now be set as a natom,0-DIM
-                   numpy ``array((natom, 0),dtype=nump.float32)``. This will cause the
-                   corresponding property to be skipped when writing to file.
-
-              :Returns: *status*, integer status (0 = OK), see the ``libxdrfile2.exdr*``
-                        constants under `Status symbols`_ for other values)
-
 "
 %enddef
 
@@ -392,13 +19,18 @@ calculations. Velocities and forces are optional in the sense that they can be a
 
 
 %{
-/* Python SWIG interface to molfile_plugin of VMD version 1.9.3
+/* Python SWIG interface to libvmdmolfile
    Copyright (c) 2017 Berk Onat <b.onat@warwick.ac.uk>
-   Published under the GNU LESSER GENERAL PUBLIC LICENSE Version 3 (or higher)
+   Published under BSD LICENSE
  */
 #define SWIG_FILE_WITH_INIT
 #include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
 #include "molfile_plugin.h"
+#include "libmolfile_plugin.h"
+#include "vmdplugin.h"
 %}
 
 %include "numpy.i"
@@ -409,10 +41,11 @@ import_array();
 
 
 /* 
+  Wrapping only high-level plugin functions to register VMD 
+  plugins and to retrive the data through molfile_plugin interface.
 
-   I am only wrapping 'high level' functions and modify call
-   signatures so that one does not need anything like pointers from
-   python.
+  Only modifing call signatures. This will help one to access functions 
+  without dealing with pointers from python.
 */
 
 
diff --git a/pymolfile/libpymolfile/numpy.i b/pymolfile/libpymolfile/numpy.i
index ec649b942fac2682d78bf8a99edcccbb698c7d17..b8fdaeb1f0ca308cd86c3cd942e6f1fd28f16dd0 100644
--- a/pymolfile/libpymolfile/numpy.i
+++ b/pymolfile/libpymolfile/numpy.i
@@ -1,11 +1,46 @@
 /* -*- C -*-  (not really, but good for syntax highlighting) */
+
+/*
+ * Copyright (c) 2005-2015, NumPy Developers.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *        notice, this list of conditions and the following disclaimer.
+ *
+ *     * Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials provided
+ *        with the distribution.
+ *
+ *     * Neither the name of the NumPy Developers nor the names of any
+ *        contributors may be used to endorse or promote products derived
+ *        from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
 #ifdef SWIGPYTHON
 
 %{
 #ifndef SWIG_FILE_WITH_INIT
-#  define NO_IMPORT_ARRAY
+#define NO_IMPORT_ARRAY
 #endif
 #include "stdio.h"
+#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
 #include <numpy/arrayobject.h>
 %}
 
@@ -13,56 +48,10 @@
 
 %fragment("NumPy_Backward_Compatibility", "header")
 {
-/* Support older NumPy data type names
-*/
-%#if NDARRAY_VERSION < 0x01000000
-%#define NPY_BOOL          PyArray_BOOL
-%#define NPY_BYTE          PyArray_BYTE
-%#define NPY_UBYTE         PyArray_UBYTE
-%#define NPY_SHORT         PyArray_SHORT
-%#define NPY_USHORT        PyArray_USHORT
-%#define NPY_INT           PyArray_INT
-%#define NPY_UINT          PyArray_UINT
-%#define NPY_LONG          PyArray_LONG
-%#define NPY_ULONG         PyArray_ULONG
-%#define NPY_LONGLONG      PyArray_LONGLONG
-%#define NPY_ULONGLONG     PyArray_ULONGLONG
-%#define NPY_FLOAT         PyArray_FLOAT
-%#define NPY_DOUBLE        PyArray_DOUBLE
-%#define NPY_LONGDOUBLE    PyArray_LONGDOUBLE
-%#define NPY_CFLOAT        PyArray_CFLOAT
-%#define NPY_CDOUBLE       PyArray_CDOUBLE
-%#define NPY_CLONGDOUBLE   PyArray_CLONGDOUBLE
-%#define NPY_OBJECT        PyArray_OBJECT
-%#define NPY_STRING        PyArray_STRING
-%#define NPY_UNICODE       PyArray_UNICODE
-%#define NPY_VOID          PyArray_VOID
-%#define NPY_NTYPES        PyArray_NTYPES
-%#define NPY_NOTYPE        PyArray_NOTYPE
-%#define NPY_CHAR          PyArray_CHAR
-%#define NPY_USERDEF       PyArray_USERDEF
-%#define npy_intp          intp
-
-%#define NPY_MAX_BYTE      MAX_BYTE
-%#define NPY_MIN_BYTE      MIN_BYTE
-%#define NPY_MAX_UBYTE     MAX_UBYTE
-%#define NPY_MAX_SHORT     MAX_SHORT
-%#define NPY_MIN_SHORT     MIN_SHORT
-%#define NPY_MAX_USHORT    MAX_USHORT
-%#define NPY_MAX_INT       MAX_INT
-%#define NPY_MIN_INT       MIN_INT
-%#define NPY_MAX_UINT      MAX_UINT
-%#define NPY_MAX_LONG      MAX_LONG
-%#define NPY_MIN_LONG      MIN_LONG
-%#define NPY_MAX_ULONG     MAX_ULONG
-%#define NPY_MAX_LONGLONG  MAX_LONGLONG
-%#define NPY_MIN_LONGLONG  MIN_LONGLONG
-%#define NPY_MAX_ULONGLONG MAX_ULONGLONG
-%#define NPY_MAX_INTP      MAX_INTP
-%#define NPY_MIN_INTP      MIN_INTP
-
-%#define NPY_FARRAY        FARRAY
-%#define NPY_F_CONTIGUOUS  F_CONTIGUOUS
+%#if NPY_API_VERSION < 0x00000007
+%#define NPY_ARRAY_DEFAULT NPY_DEFAULT
+%#define NPY_ARRAY_FARRAY  NPY_FARRAY
+%#define NPY_FORTRANORDER  NPY_FORTRAN
 %#endif
 }
 
@@ -80,24 +69,46 @@
 {
 /* Macros to extract array attributes.
  */
-%#define is_array(a)            ((a) && PyArray_Check((PyArrayObject *)a))
-%#define array_type(a)          (int)(PyArray_TYPE(a))
-%#define array_numdims(a)       (((PyArrayObject *)a)->nd)
-%#define array_dimensions(a)    (((PyArrayObject *)a)->dimensions)
-%#define array_size(a,i)        (((PyArrayObject *)a)->dimensions[i])
-%#define array_data(a)          (((PyArrayObject *)a)->data)
-%#define array_is_contiguous(a) (PyArray_ISCONTIGUOUS(a))
-%#define array_is_native(a)     (PyArray_ISNOTSWAPPED(a))
-%#define array_is_fortran(a)    (PyArray_ISFORTRAN(a))
+%#if NPY_API_VERSION < 0x00000007
+%#define is_array(a)            ((a) && PyArray_Check((PyArrayObject*)a))
+%#define array_type(a)          (int)(PyArray_TYPE((PyArrayObject*)a))
+%#define array_numdims(a)       (((PyArrayObject*)a)->nd)
+%#define array_dimensions(a)    (((PyArrayObject*)a)->dimensions)
+%#define array_size(a,i)        (((PyArrayObject*)a)->dimensions[i])
+%#define array_strides(a)       (((PyArrayObject*)a)->strides)
+%#define array_stride(a,i)      (((PyArrayObject*)a)->strides[i])
+%#define array_data(a)          (((PyArrayObject*)a)->data)
+%#define array_descr(a)         (((PyArrayObject*)a)->descr)
+%#define array_flags(a)         (((PyArrayObject*)a)->flags)
+%#define array_enableflags(a,f) (((PyArrayObject*)a)->flags) = f
+%#define array_is_fortran(a)    (PyArray_ISFORTRAN((PyArrayObject*)a))
+%#else
+%#define is_array(a)            ((a) && PyArray_Check(a))
+%#define array_type(a)          PyArray_TYPE((PyArrayObject*)a)
+%#define array_numdims(a)       PyArray_NDIM((PyArrayObject*)a)
+%#define array_dimensions(a)    PyArray_DIMS((PyArrayObject*)a)
+%#define array_strides(a)       PyArray_STRIDES((PyArrayObject*)a)
+%#define array_stride(a,i)      PyArray_STRIDE((PyArrayObject*)a,i)
+%#define array_size(a,i)        PyArray_DIM((PyArrayObject*)a,i)
+%#define array_data(a)          PyArray_DATA((PyArrayObject*)a)
+%#define array_descr(a)         PyArray_DESCR((PyArrayObject*)a)
+%#define array_flags(a)         PyArray_FLAGS((PyArrayObject*)a)
+%#define array_enableflags(a,f) PyArray_ENABLEFLAGS((PyArrayObject*)a,f)
+%#define array_is_fortran(a)    (PyArray_IS_F_CONTIGUOUS((PyArrayObject*)a))
+%#endif
+%#define array_is_contiguous(a) (PyArray_ISCONTIGUOUS((PyArrayObject*)a))
+%#define array_is_native(a)     (PyArray_ISNOTSWAPPED((PyArrayObject*)a))
 }
 
 /**********************************************************************/
 
-%fragment("NumPy_Utilities", "header")
+%fragment("NumPy_Utilities",
+          "header")
 {
   /* Given a PyObject, return a string describing its type.
    */
-  const char* pytype_string(PyObject* py_obj) {
+  const char* pytype_string(PyObject* py_obj)
+  {
     if (py_obj == NULL          ) return "C NULL value";
     if (py_obj == Py_None       ) return "Python None" ;
     if (PyCallable_Check(py_obj)) return "callable"    ;
@@ -107,44 +118,71 @@
     if (PyDict_Check(    py_obj)) return "dict"        ;
     if (PyList_Check(    py_obj)) return "list"        ;
     if (PyTuple_Check(   py_obj)) return "tuple"       ;
-    #if PY_MAJOR_VERSION < 3
-      if (PyFile_Check(    py_obj)) return "file"        ;
-    #endif
+%#if PY_MAJOR_VERSION < 3
+    if (PyFile_Check(    py_obj)) return "file"        ;
     if (PyModule_Check(  py_obj)) return "module"      ;
-    #if PY_MAJOR_VERSION < 3
-      if (PyInstance_Check(py_obj)) return "instance"    ;
-    #endif
+    if (PyInstance_Check(py_obj)) return "instance"    ;
+%#endif
 
-    return "unkown type";
+    return "unknown type";
   }
 
   /* Given a NumPy typecode, return a string describing the type.
    */
-  const char* typecode_string(int typecode) {
-    static const char* type_names[25] = {"bool", "byte", "unsigned byte",
-                                   "short", "unsigned short", "int",
-                                   "unsigned int", "long", "unsigned long",
-                                   "long long", "unsigned long long",
-                                   "float", "double", "long double",
-                                   "complex float", "complex double",
-                                   "complex long double", "object",
-                                   "string", "unicode", "void", "ntypes",
-                                   "notype", "char", "unknown"};
+  const char* typecode_string(int typecode)
+  {
+    static const char* type_names[25] = {"bool",
+                                         "byte",
+                                         "unsigned byte",
+                                         "short",
+                                         "unsigned short",
+                                         "int",
+                                         "unsigned int",
+                                         "long",
+                                         "unsigned long",
+                                         "long long",
+                                         "unsigned long long",
+                                         "float",
+                                         "double",
+                                         "long double",
+                                         "complex float",
+                                         "complex double",
+                                         "complex long double",
+                                         "object",
+                                         "string",
+                                         "unicode",
+                                         "void",
+                                         "ntypes",
+                                         "notype",
+                                         "char",
+                                         "unknown"};
     return typecode < 24 ? type_names[typecode] : type_names[24];
   }
 
-  /* Make sure input has correct numpy type.  Allow character and byte
-   * to match.  Also allow int and long to match.  This is deprecated.
-   * You should use PyArray_EquivTypenums() instead.
+  /* Make sure input has correct numpy type.  This now just calls
+     PyArray_EquivTypenums().
    */
-  int type_match(int actual_type, int desired_type) {
+  int type_match(int actual_type,
+                 int desired_type)
+  {
     return PyArray_EquivTypenums(actual_type, desired_type);
   }
+
+%#ifdef SWIGPY_USE_CAPSULE
+  void free_cap(PyObject * cap)
+  {
+    void* array = (void*) PyCapsule_GetPointer(cap,SWIGPY_CAPSULE_NAME);
+    if (array != NULL) free(array);
+  }
+%#endif
+
+
 }
 
 /**********************************************************************/
 
-%fragment("NumPy_Object_to_Array", "header",
+%fragment("NumPy_Object_to_Array",
+          "header",
           fragment="NumPy_Backward_Compatibility",
           fragment="NumPy_Macros",
           fragment="NumPy_Utilities")
@@ -153,7 +191,8 @@
    * legal.  If not, set the python error string appropriately and
    * return NULL.
    */
-  PyArrayObject* obj_to_array_no_conversion(PyObject* input, int typecode)
+  PyArrayObject* obj_to_array_no_conversion(PyObject* input,
+                                            int        typecode)
   {
     PyArrayObject* ary = NULL;
     if (is_array(input) && (typecode == NPY_NOTYPE ||
@@ -172,11 +211,12 @@
     }
     else
     {
-      const char * desired_type = typecode_string(typecode);
-      const char * actual_type  = pytype_string(input);
+      const char* desired_type = typecode_string(typecode);
+      const char* actual_type  = pytype_string(input);
       PyErr_Format(PyExc_TypeError,
                    "Array of type '%s' required.  A '%s' was given",
-                   desired_type, actual_type);
+                   desired_type,
+                   actual_type);
       ary = NULL;
     }
     return ary;
@@ -187,11 +227,12 @@
    * correct type.  On failure, the python error string will be set and
    * the routine returns NULL.
    */
-  PyArrayObject* obj_to_array_allow_conversion(PyObject* input, int typecode,
-                                               int* is_new_object)
+  PyArrayObject* obj_to_array_allow_conversion(PyObject* input,
+                                               int       typecode,
+                                               int*      is_new_object)
   {
     PyArrayObject* ary = NULL;
-    PyObject* py_obj;
+    PyObject*      py_obj;
     if (is_array(input) && (typecode == NPY_NOTYPE ||
                             PyArray_EquivTypenums(array_type(input),typecode)))
     {
@@ -200,7 +241,7 @@
     }
     else
     {
-      py_obj = PyArray_FROMANY(input, typecode, 0, 0, NPY_DEFAULT);
+      py_obj = PyArray_FROMANY(input, typecode, 0, 0, NPY_ARRAY_DEFAULT);
       /* If NULL, PyArray_FromObject will have set python error value.*/
       ary = (PyArrayObject*) py_obj;
       *is_new_object = 1;
@@ -213,8 +254,10 @@
    * not contiguous, create a new PyArrayObject using the original data,
    * flag it as a new object and return the pointer.
    */
-  PyArrayObject* make_contiguous(PyArrayObject* ary, int* is_new_object,
-                                 int min_dims, int max_dims)
+  PyArrayObject* make_contiguous(PyArrayObject* ary,
+                                 int*           is_new_object,
+                                 int            min_dims,
+                                 int            max_dims)
   {
     PyArrayObject* result;
     if (array_is_contiguous(ary))
@@ -225,9 +268,9 @@
     else
     {
       result = (PyArrayObject*) PyArray_ContiguousFromObject((PyObject*)ary,
-                                                             array_type(ary),
-                                                             min_dims,
-                                                             max_dims);
+                                                              array_type(ary),
+                                                              min_dims,
+                                                              max_dims);
       *is_new_object = 1;
     }
     return result;
@@ -239,8 +282,8 @@
    * PyArrayObject using the original data, flag it as a new object
    * and return the pointer.
    */
-  PyArrayObject* make_fortran(PyArrayObject* ary, int* is_new_object,
-                              int min_dims, int max_dims)
+  PyArrayObject* make_fortran(PyArrayObject* ary,
+                              int*           is_new_object)
   {
     PyArrayObject* result;
     if (array_is_fortran(ary))
@@ -250,8 +293,14 @@
     }
     else
     {
-      Py_INCREF(ary->descr);
-      result = (PyArrayObject*) PyArray_FromArray(ary, ary->descr, NPY_FORTRAN);
+      Py_INCREF(array_descr(ary));
+      result = (PyArrayObject*) PyArray_FromArray(ary,
+                                                  array_descr(ary),
+%#if NPY_API_VERSION < 0x00000007
+                                                  NPY_FORTRANORDER);
+%#else
+                                                  NPY_ARRAY_F_CONTIGUOUS);
+%#endif
       *is_new_object = 1;
     }
     return result;
@@ -263,13 +312,14 @@
    * will be set.
    */
   PyArrayObject* obj_to_array_contiguous_allow_conversion(PyObject* input,
-                                                          int typecode,
-                                                          int* is_new_object)
+                                                          int       typecode,
+                                                          int*      is_new_object)
   {
     int is_new1 = 0;
     int is_new2 = 0;
     PyArrayObject* ary2;
-    PyArrayObject* ary1 = obj_to_array_allow_conversion(input, typecode,
+    PyArrayObject* ary1 = obj_to_array_allow_conversion(input,
+                                                        typecode,
                                                         &is_new1);
     if (ary1)
     {
@@ -290,17 +340,18 @@
    * will be set.
    */
   PyArrayObject* obj_to_array_fortran_allow_conversion(PyObject* input,
-                                                       int typecode,
-                                                       int* is_new_object)
+                                                       int       typecode,
+                                                       int*      is_new_object)
   {
     int is_new1 = 0;
     int is_new2 = 0;
     PyArrayObject* ary2;
-    PyArrayObject* ary1 = obj_to_array_allow_conversion(input, typecode,
+    PyArrayObject* ary1 = obj_to_array_allow_conversion(input,
+                                                        typecode,
                                                         &is_new1);
     if (ary1)
     {
-      ary2 = make_fortran(ary1, &is_new2, 0, 0);
+      ary2 = make_fortran(ary1, &is_new2);
       if (is_new1 && is_new2)
       {
         Py_DECREF(ary1);
@@ -310,13 +361,12 @@
     *is_new_object = is_new1 || is_new2;
     return ary1;
   }
-
 } /* end fragment */
 
-
 /**********************************************************************/
 
-%fragment("NumPy_Array_Requirements", "header",
+%fragment("NumPy_Array_Requirements",
+          "header",
           fragment="NumPy_Backward_Compatibility",
           fragment="NumPy_Macros")
 {
@@ -336,6 +386,22 @@
     return contiguous;
   }
 
+  /* Test whether a python object is (C_ or F_) contiguous.  If array is
+   * contiguous, return 1.  Otherwise, set the python error string and
+   * return 0.
+   */
+  int require_c_or_f_contiguous(PyArrayObject* ary)
+  {
+    int contiguous = 1;
+    if (!(array_is_contiguous(ary) || array_is_fortran(ary)))
+    {
+      PyErr_SetString(PyExc_TypeError,
+                      "Array must be contiguous (C_ or F_).  A non-contiguous array was given");
+      contiguous = 0;
+    }
+    return contiguous;
+  }
+
   /* Require that a numpy array is not byte-swapped.  If the array is
    * not byte-swapped, return 1.  Otherwise, set the python error string
    * and return 0.
@@ -357,14 +423,16 @@
    * dimensions.  If the array has the specified number of dimensions,
    * return 1.  Otherwise, set the python error string and return 0.
    */
-  int require_dimensions(PyArrayObject* ary, int exact_dimensions)
+  int require_dimensions(PyArrayObject* ary,
+                         int            exact_dimensions)
   {
     int success = 1;
     if (array_numdims(ary) != exact_dimensions)
     {
       PyErr_Format(PyExc_TypeError,
                    "Array must have %d dimensions.  Given array has %d dimensions",
-                   exact_dimensions, array_numdims(ary));
+                   exact_dimensions,
+                   array_numdims(ary));
       success = 0;
     }
     return success;
@@ -375,7 +443,9 @@
    * of dimensions, return 1.  Otherwise, set the python error string
    * and return 0.
    */
-  int require_dimensions_n(PyArrayObject* ary, int* exact_dimensions, int n)
+  int require_dimensions_n(PyArrayObject* ary,
+                           int*           exact_dimensions,
+                           int            n)
   {
     int success = 0;
     int i;
@@ -399,7 +469,8 @@
       strcat(dims_str,s);
       PyErr_Format(PyExc_TypeError,
                    "Array must have %s dimensions.  Given array has %d dimensions",
-                   dims_str, array_numdims(ary));
+                   dims_str,
+                   array_numdims(ary));
     }
     return success;
   }
@@ -408,7 +479,9 @@
    * array has the specified shape, return 1.  Otherwise, set the python
    * error string and return 0.
    */
-  int require_size(PyArrayObject* ary, npy_intp* size, int n)
+  int require_size(PyArrayObject* ary,
+                   npy_intp*      size,
+                   int            n)
   {
     int i;
     int success = 1;
@@ -448,104 +521,152 @@
       actual_dims[len-1] = ']';
       PyErr_Format(PyExc_TypeError,
                    "Array must have shape of %s.  Given array has shape of %s",
-                   desired_dims, actual_dims);
+                   desired_dims,
+                   actual_dims);
     }
     return success;
   }
 
-  /* Require the given PyArrayObject to to be FORTRAN ordered.  If the
-   * the PyArrayObject is already FORTRAN ordered, do nothing.  Else,
-   * set the FORTRAN ordering flag and recompute the strides.
+  /* Require the given PyArrayObject to to be Fortran ordered.  If the
+   * the PyArrayObject is already Fortran ordered, do nothing.  Else,
+   * set the Fortran ordering flag and recompute the strides.
    */
   int require_fortran(PyArrayObject* ary)
   {
     int success = 1;
     int nd = array_numdims(ary);
     int i;
+    npy_intp * strides = array_strides(ary);
     if (array_is_fortran(ary)) return success;
-    /* Set the FORTRAN ordered flag */
-    ary->flags = NPY_FARRAY;
+    /* Set the Fortran ordered flag */
+    array_enableflags(ary,NPY_ARRAY_FARRAY);
     /* Recompute the strides */
-    ary->strides[0] = ary->strides[nd-1];
+    strides[0] = strides[nd-1];
     for (i=1; i < nd; ++i)
-      ary->strides[i] = ary->strides[i-1] * array_size(ary,i-1);
+      strides[i] = strides[i-1] * array_size(ary,i-1);
     return success;
   }
 }
 
 /* Combine all NumPy fragments into one for convenience */
-%fragment("NumPy_Fragments", "header",
+%fragment("NumPy_Fragments",
+          "header",
           fragment="NumPy_Backward_Compatibility",
           fragment="NumPy_Macros",
           fragment="NumPy_Utilities",
           fragment="NumPy_Object_to_Array",
-          fragment="NumPy_Array_Requirements") { }
+          fragment="NumPy_Array_Requirements")
+{
+}
 
 /* End John Hunter translation (with modifications by Bill Spotz)
  */
 
 /* %numpy_typemaps() macro
  *
- * This macro defines a family of 41 typemaps that allow C arguments
+ * This macro defines a family of 75 typemaps that allow C arguments
  * of the form
  *
- *     (DATA_TYPE IN_ARRAY1[ANY])
- *     (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
- *     (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+ *    1. (DATA_TYPE IN_ARRAY1[ANY])
+ *    2. (DATA_TYPE* IN_ARRAY1, DIM_TYPE DIM1)
+ *    3. (DIM_TYPE DIM1, DATA_TYPE* IN_ARRAY1)
+ *
+ *    4. (DATA_TYPE IN_ARRAY2[ANY][ANY])
+ *    5. (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ *    6. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
+ *    7. (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ *    8. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+ *
+ *    9. (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
+ *   10. (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ *   11. (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ *   12. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
+ *   13. (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ *   14. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
  *
- *     (DATA_TYPE IN_ARRAY2[ANY][ANY])
- *     (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
- *     (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2)
- *     (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
- *     (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2)
+ *   15. (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY])
+ *   16. (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ *   17. (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ *   18. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, , DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4)
+ *   19. (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ *   20. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4)
  *
- *     (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY])
- *     (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
- *     (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3)
- *     (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
- *     (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3)
+ *   21. (DATA_TYPE INPLACE_ARRAY1[ANY])
+ *   22. (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
+ *   23. (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
  *
- *     (DATA_TYPE INPLACE_ARRAY1[ANY])
- *     (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1)
- *     (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
+ *   24. (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
+ *   25. (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ *   26. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
+ *   27. (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
+ *   28. (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
  *
- *     (DATA_TYPE INPLACE_ARRAY2[ANY][ANY])
- *     (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
- *     (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2)
- *     (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2)
- *     (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2)
+ *   29. (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
+ *   30. (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ *   31. (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ *   32. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
+ *   33. (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+ *   34. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3)
  *
- *     (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY])
- *     (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
- *     (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
- *     (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
- *     (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3)
+ *   35. (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY])
+ *   36. (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ *   37. (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ *   38. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_ARRAY4)
+ *   39. (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+ *   40. (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_FARRAY4)
  *
- *     (DATA_TYPE ARGOUT_ARRAY1[ANY])
- *     (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
- *     (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
+ *   41. (DATA_TYPE ARGOUT_ARRAY1[ANY])
+ *   42. (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
+ *   43. (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
  *
- *     (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
+ *   44. (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
  *
- *     (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
+ *   45. (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
  *
- *     (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1)
- *     (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1)
+ *   46. (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY])
  *
- *     (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
- *     (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2)
- *     (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
- *     (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2)
+ *   47. (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1)
+ *   48. (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1)
  *
- *     (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
- *     (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)
- *     (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
- *     (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3)
+ *   49. (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ *   50. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2)
+ *   51. (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ *   52. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2)
+ *
+ *   53. (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+ *   54. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)
+ *   55. (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+ *   56. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3)
+ *
+ *   57. (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ *   58. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_ARRAY4)
+ *   59. (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ *   60. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_FARRAY4)
+ *
+ *   61. (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1)
+ *   62. (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEWM_ARRAY1)
+ *
+ *   63. (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ *   64. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_ARRAY2)
+ *   65. (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ *   66. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_FARRAY2)
+ *
+ *   67. (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+ *   68. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_ARRAY3)
+ *   69. (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+ *   70. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_FARRAY3)
+ *
+ *   71. (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ *   72. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_ARRAY4)
+ *   73. (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ *   74. (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_FARRAY4)
+ *
+ *   75. (DATA_TYPE* INPLACE_ARRAY_FLAT, DIM_TYPE DIM_FLAT)
  *
  * where "DATA_TYPE" is any type supported by the NumPy module, and
  * "DIM_TYPE" is any int-like type suitable for specifying dimensions.
  * The difference between "ARRAY" typemaps and "FARRAY" typemaps is
- * that the "FARRAY" typemaps expect FORTRAN ordering of
+ * that the "FARRAY" typemaps expect Fortran ordering of
  * multidimensional arrays.  In python, the dimensions will not need
  * to be specified (except for the "DATA_TYPE* ARGOUT_ARRAY1"
  * typemaps).  The IN_ARRAYs can be a numpy array or any sequence that
@@ -605,7 +726,8 @@
   (PyArrayObject* array=NULL, int is_new_object=0)
 {
   npy_intp size[1] = { $1_dim0 };
-  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+  array = obj_to_array_contiguous_allow_conversion($input,
+                                                   DATA_TYPECODE,
                                                    &is_new_object);
   if (!array || !require_dimensions(array, 1) ||
       !require_size(array, size, 1)) SWIG_fail;
@@ -632,7 +754,8 @@
   (PyArrayObject* array=NULL, int is_new_object=0)
 {
   npy_intp size[1] = { -1 };
-  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+  array = obj_to_array_contiguous_allow_conversion($input,
+                                                   DATA_TYPECODE,
                                                    &is_new_object);
   if (!array || !require_dimensions(array, 1) ||
       !require_size(array, size, 1)) SWIG_fail;
@@ -660,7 +783,8 @@
   (PyArrayObject* array=NULL, int is_new_object=0)
 {
   npy_intp size[1] = {-1};
-  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+  array = obj_to_array_contiguous_allow_conversion($input,
+                                                   DATA_TYPECODE,
                                                    &is_new_object);
   if (!array || !require_dimensions(array, 1) ||
       !require_size(array, size, 1)) SWIG_fail;
@@ -688,7 +812,8 @@
   (PyArrayObject* array=NULL, int is_new_object=0)
 {
   npy_intp size[2] = { $1_dim0, $1_dim1 };
-  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+  array = obj_to_array_contiguous_allow_conversion($input,
+                                                   DATA_TYPECODE,
                                                    &is_new_object);
   if (!array || !require_dimensions(array, 2) ||
       !require_size(array, size, 2)) SWIG_fail;
@@ -744,7 +869,8 @@
   (PyArrayObject* array=NULL, int is_new_object=0)
 {
   npy_intp size[2] = { -1, -1 };
-  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+  array = obj_to_array_contiguous_allow_conversion($input,
+                                                   DATA_TYPECODE,
                                                    &is_new_object);
   if (!array || !require_dimensions(array, 2) ||
       !require_size(array, size, 2)) SWIG_fail;
@@ -773,7 +899,8 @@
   (PyArrayObject* array=NULL, int is_new_object=0)
 {
   npy_intp size[2] = { -1, -1 };
-  array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE,
+  array = obj_to_array_fortran_allow_conversion($input,
+                                                DATA_TYPECODE,
                                                 &is_new_object);
   if (!array || !require_dimensions(array, 2) ||
       !require_size(array, size, 2) || !require_fortran(array)) SWIG_fail;
@@ -802,7 +929,8 @@
   (PyArrayObject* array=NULL, int is_new_object=0)
 {
   npy_intp size[2] = { -1, -1 };
-  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+  array = obj_to_array_fortran_allow_conversion($input,
+                                                   DATA_TYPECODE,
                                                    &is_new_object);
   if (!array || !require_dimensions(array, 2) ||
       !require_size(array, size, 2) || !require_fortran(array)) SWIG_fail;
@@ -831,7 +959,8 @@
   (PyArrayObject* array=NULL, int is_new_object=0)
 {
   npy_intp size[3] = { $1_dim0, $1_dim1, $1_dim2 };
-  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+  array = obj_to_array_contiguous_allow_conversion($input,
+                                                   DATA_TYPECODE,
                                                    &is_new_object);
   if (!array || !require_dimensions(array, 3) ||
       !require_size(array, size, 3)) SWIG_fail;
@@ -875,6 +1004,88 @@
     { Py_DECREF(array$argnum); }
 }
 
+/* Typemap suite for (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ *                    DIM_TYPE DIM3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+  /* for now, only concerned with lists */
+  $1 = PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+  (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL, int* is_new_object_array=NULL)
+{
+  npy_intp size[2] = { -1, -1 };
+  PyArrayObject* temp_array;
+  Py_ssize_t i;
+  int is_new_object;
+
+  /* length of the list */
+  $2 = PyList_Size($input);
+
+  /* the arrays */
+  array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *));
+  object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *));
+  is_new_object_array = (int *)calloc($2,sizeof(int));
+
+  if (array == NULL || object_array == NULL || is_new_object_array == NULL)
+  {
+    SWIG_fail;
+  }
+
+  for (i=0; i<$2; i++)
+  {
+    temp_array = obj_to_array_contiguous_allow_conversion(PySequence_GetItem($input,i), DATA_TYPECODE, &is_new_object);
+
+    /* the new array must be stored so that it can be destroyed in freearg */
+    object_array[i] = temp_array;
+    is_new_object_array[i] = is_new_object;
+
+    if (!temp_array || !require_dimensions(temp_array, 2)) SWIG_fail;
+
+    /* store the size of the first array in the list, then use that for comparison. */
+    if (i == 0)
+    {
+      size[0] = array_size(temp_array,0);
+      size[1] = array_size(temp_array,1);
+    }
+
+    if (!require_size(temp_array, size, 2)) SWIG_fail;
+
+    array[i] = (DATA_TYPE*) array_data(temp_array);
+  }
+
+  $1 = (DATA_TYPE**) array;
+  $3 = (DIM_TYPE) size[0];
+  $4 = (DIM_TYPE) size[1];
+}
+%typemap(freearg)
+  (DATA_TYPE** IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+  Py_ssize_t i;
+
+  if (array$argnum!=NULL) free(array$argnum);
+
+  /*freeing the individual arrays if needed */
+  if (object_array$argnum!=NULL)
+  {
+    if (is_new_object_array$argnum!=NULL)
+    {
+      for (i=0; i<$2; i++)
+      {
+        if (object_array$argnum[i] != NULL && is_new_object_array$argnum[i])
+        { Py_DECREF(object_array$argnum[i]); }
+      }
+      free(is_new_object_array$argnum);
+    }
+    free(object_array$argnum);
+  }
+}
+
 /* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
  *                    DATA_TYPE* IN_ARRAY3)
  */
@@ -952,7 +1163,8 @@
   (PyArrayObject* array=NULL, int is_new_object=0)
 {
   npy_intp size[3] = { -1, -1, -1 };
-  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+  array = obj_to_array_fortran_allow_conversion($input,
+                                                   DATA_TYPECODE,
                                                    &is_new_object);
   if (!array || !require_dimensions(array, 3) ||
       !require_size(array, size, 3) || !require_fortran(array)) SWIG_fail;
@@ -968,6 +1180,245 @@
     { Py_DECREF(array$argnum); }
 }
 
+/* Typemap suite for (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY])
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY])
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[4] = { $1_dim0, $1_dim1, $1_dim2 , $1_dim3};
+  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 4) ||
+      !require_size(array, size, 4)) SWIG_fail;
+  $1 = ($1_ltype) array_data(array);
+}
+%typemap(freearg)
+  (DATA_TYPE IN_ARRAY4[ANY][ANY][ANY][ANY])
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ *                    DIM_TYPE DIM3, DIM_TYPE DIM4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[4] = { -1, -1, -1, -1 };
+  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 4) ||
+      !require_size(array, size, 4)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = (DIM_TYPE) array_size(array,0);
+  $3 = (DIM_TYPE) array_size(array,1);
+  $4 = (DIM_TYPE) array_size(array,2);
+  $5 = (DIM_TYPE) array_size(array,3);
+}
+%typemap(freearg)
+  (DATA_TYPE* IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ *                    DIM_TYPE DIM3, DIM_TYPE DIM4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+  /* for now, only concerned with lists */
+  $1 = PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+  (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL, int* is_new_object_array=NULL)
+{
+  npy_intp size[3] = { -1, -1, -1 };
+  PyArrayObject* temp_array;
+  Py_ssize_t i;
+  int is_new_object;
+
+  /* length of the list */
+  $2 = PyList_Size($input);
+
+  /* the arrays */
+  array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *));
+  object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *));
+  is_new_object_array = (int *)calloc($2,sizeof(int));
+
+  if (array == NULL || object_array == NULL || is_new_object_array == NULL)
+  {
+    SWIG_fail;
+  }
+
+  for (i=0; i<$2; i++)
+  {
+    temp_array = obj_to_array_contiguous_allow_conversion(PySequence_GetItem($input,i), DATA_TYPECODE, &is_new_object);
+
+    /* the new array must be stored so that it can be destroyed in freearg */
+    object_array[i] = temp_array;
+    is_new_object_array[i] = is_new_object;
+
+    if (!temp_array || !require_dimensions(temp_array, 3)) SWIG_fail;
+
+    /* store the size of the first array in the list, then use that for comparison. */
+    if (i == 0)
+    {
+      size[0] = array_size(temp_array,0);
+      size[1] = array_size(temp_array,1);
+      size[2] = array_size(temp_array,2);
+    }
+
+    if (!require_size(temp_array, size, 3)) SWIG_fail;
+
+    array[i] = (DATA_TYPE*) array_data(temp_array);
+  }
+
+  $1 = (DATA_TYPE**) array;
+  $3 = (DIM_TYPE) size[0];
+  $4 = (DIM_TYPE) size[1];
+  $5 = (DIM_TYPE) size[2];
+}
+%typemap(freearg)
+  (DATA_TYPE** IN_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+  Py_ssize_t i;
+
+  if (array$argnum!=NULL) free(array$argnum);
+
+  /*freeing the individual arrays if needed */
+  if (object_array$argnum!=NULL)
+  {
+    if (is_new_object_array$argnum!=NULL)
+    {
+      for (i=0; i<$2; i++)
+      {
+        if (object_array$argnum[i] != NULL && is_new_object_array$argnum[i])
+        { Py_DECREF(object_array$argnum[i]); }
+      }
+      free(is_new_object_array$argnum);
+    }
+    free(object_array$argnum);
+  }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4,
+ *                    DATA_TYPE* IN_ARRAY4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[4] = { -1, -1, -1 , -1};
+  array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 4) ||
+      !require_size(array, size, 4)) SWIG_fail;
+  $1 = (DIM_TYPE) array_size(array,0);
+  $2 = (DIM_TYPE) array_size(array,1);
+  $3 = (DIM_TYPE) array_size(array,2);
+  $4 = (DIM_TYPE) array_size(array,3);
+  $5 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_ARRAY4)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ *                    DIM_TYPE DIM3, DIM_TYPE DIM4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[4] = { -1, -1, -1, -1 };
+  array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE,
+                                                &is_new_object);
+  if (!array || !require_dimensions(array, 4) ||
+      !require_size(array, size, 4) | !require_fortran(array)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = (DIM_TYPE) array_size(array,0);
+  $3 = (DIM_TYPE) array_size(array,1);
+  $4 = (DIM_TYPE) array_size(array,2);
+  $5 = (DIM_TYPE) array_size(array,3);
+}
+%typemap(freearg)
+  (DATA_TYPE* IN_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4,
+ *                    DATA_TYPE* IN_FARRAY4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4)
+{
+  $1 = is_array($input) || PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4)
+  (PyArrayObject* array=NULL, int is_new_object=0)
+{
+  npy_intp size[4] = { -1, -1, -1 , -1 };
+  array = obj_to_array_fortran_allow_conversion($input, DATA_TYPECODE,
+                                                   &is_new_object);
+  if (!array || !require_dimensions(array, 4) ||
+      !require_size(array, size, 4) || !require_fortran(array)) SWIG_fail;
+  $1 = (DIM_TYPE) array_size(array,0);
+  $2 = (DIM_TYPE) array_size(array,1);
+  $3 = (DIM_TYPE) array_size(array,2);
+  $4 = (DIM_TYPE) array_size(array,3);
+  $5 = (DATA_TYPE*) array_data(array);
+}
+%typemap(freearg)
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* IN_FARRAY4)
+{
+  if (is_new_object$argnum && array$argnum)
+    { Py_DECREF(array$argnum); }
+}
+
 /***************************/
 /* In-Place Array Typemaps */
 /***************************/
@@ -1191,24 +1642,90 @@
   $4 = (DIM_TYPE) array_size(array,2);
 }
 
-/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
- *                    DATA_TYPE* INPLACE_ARRAY3)
+/* Typemap suite for (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ *                    DIM_TYPE DIM3)
  */
 %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
            fragment="NumPy_Macros")
-  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
+  (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
 {
-  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
-                                                 DATA_TYPECODE);
+  $1 = PySequence_Check($input);
 }
 %typemap(in,
          fragment="NumPy_Fragments")
-  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
-  (PyArrayObject* array=NULL)
+  (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+  (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL)
 {
-  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
-  if (!array || !require_dimensions(array,3) || !require_contiguous(array)
-      || !require_native(array)) SWIG_fail;
+  npy_intp size[2] = { -1, -1 };
+  PyArrayObject* temp_array;
+  Py_ssize_t i;
+
+  /* length of the list */
+  $2 = PyList_Size($input);
+
+  /* the arrays */
+  array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *));
+  object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *));
+
+  if (array == NULL || object_array == NULL)
+  {
+    SWIG_fail;
+  }
+
+  for (i=0; i<$2; i++)
+  {
+    temp_array = obj_to_array_no_conversion(PySequence_GetItem($input,i), DATA_TYPECODE);
+
+    /* the new array must be stored so that it can be destroyed in freearg */
+    object_array[i] = temp_array;
+
+    if ( !temp_array || !require_dimensions(temp_array, 2) ||
+      !require_contiguous(temp_array) ||
+      !require_native(temp_array) ||
+      !PyArray_EquivTypenums(array_type(temp_array), DATA_TYPECODE)
+    ) SWIG_fail;
+
+    /* store the size of the first array in the list, then use that for comparison. */
+    if (i == 0)
+    {
+      size[0] = array_size(temp_array,0);
+      size[1] = array_size(temp_array,1);
+    }
+
+    if (!require_size(temp_array, size, 2)) SWIG_fail;
+
+    array[i] = (DATA_TYPE*) array_data(temp_array);
+  }
+
+  $1 = (DATA_TYPE**) array;
+  $3 = (DIM_TYPE) size[0];
+  $4 = (DIM_TYPE) size[1];
+}
+%typemap(freearg)
+  (DATA_TYPE** INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3)
+{
+  if (array$argnum!=NULL) free(array$argnum);
+  if (object_array$argnum!=NULL) free(object_array$argnum);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
+ *                    DATA_TYPE* INPLACE_ARRAY3)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3)
+  (PyArrayObject* array=NULL)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,3) || !require_contiguous(array)
+      || !require_native(array)) SWIG_fail;
   $1 = (DIM_TYPE) array_size(array,0);
   $2 = (DIM_TYPE) array_size(array,1);
   $3 = (DIM_TYPE) array_size(array,2);
@@ -1263,6 +1780,195 @@
   $4 = (DATA_TYPE*) array_data(array);
 }
 
+/* Typemap suite for (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY])
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY])
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE INPLACE_ARRAY4[ANY][ANY][ANY][ANY])
+  (PyArrayObject* array=NULL)
+{
+  npy_intp size[4] = { $1_dim0, $1_dim1, $1_dim2 , $1_dim3 };
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,4) || !require_size(array, size, 4) ||
+      !require_contiguous(array) || !require_native(array)) SWIG_fail;
+  $1 = ($1_ltype) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ *                    DIM_TYPE DIM3, DIM_TYPE DIM4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+  (PyArrayObject* array=NULL)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,4) || !require_contiguous(array) ||
+      !require_native(array)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = (DIM_TYPE) array_size(array,0);
+  $3 = (DIM_TYPE) array_size(array,1);
+  $4 = (DIM_TYPE) array_size(array,2);
+  $5 = (DIM_TYPE) array_size(array,3);
+}
+
+/* Typemap suite for (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ *                    DIM_TYPE DIM3, DIM_TYPE DIM4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+  $1 = PySequence_Check($input);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+  (DATA_TYPE** array=NULL, PyArrayObject** object_array=NULL)
+{
+  npy_intp size[3] = { -1, -1, -1 };
+  PyArrayObject* temp_array;
+  Py_ssize_t i;
+
+  /* length of the list */
+  $2 = PyList_Size($input);
+
+  /* the arrays */
+  array = (DATA_TYPE **)malloc($2*sizeof(DATA_TYPE *));
+  object_array = (PyArrayObject **)calloc($2,sizeof(PyArrayObject *));
+
+  if (array == NULL || object_array == NULL)
+  {
+    SWIG_fail;
+  }
+
+  for (i=0; i<$2; i++)
+  {
+    temp_array = obj_to_array_no_conversion(PySequence_GetItem($input,i), DATA_TYPECODE);
+
+    /* the new array must be stored so that it can be destroyed in freearg */
+    object_array[i] = temp_array;
+
+    if ( !temp_array || !require_dimensions(temp_array, 3) ||
+      !require_contiguous(temp_array) ||
+      !require_native(temp_array) ||
+      !PyArray_EquivTypenums(array_type(temp_array), DATA_TYPECODE)
+    ) SWIG_fail;
+
+    /* store the size of the first array in the list, then use that for comparison. */
+    if (i == 0)
+    {
+      size[0] = array_size(temp_array,0);
+      size[1] = array_size(temp_array,1);
+      size[2] = array_size(temp_array,2);
+    }
+
+    if (!require_size(temp_array, size, 3)) SWIG_fail;
+
+    array[i] = (DATA_TYPE*) array_data(temp_array);
+  }
+
+  $1 = (DATA_TYPE**) array;
+  $3 = (DIM_TYPE) size[0];
+  $4 = (DIM_TYPE) size[1];
+  $5 = (DIM_TYPE) size[2];
+}
+%typemap(freearg)
+  (DATA_TYPE** INPLACE_ARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+  if (array$argnum!=NULL) free(array$argnum);
+  if (object_array$argnum!=NULL) free(object_array$argnum);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4,
+ *                    DATA_TYPE* INPLACE_ARRAY4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_ARRAY4)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_ARRAY4)
+  (PyArrayObject* array=NULL)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,4) || !require_contiguous(array)
+      || !require_native(array)) SWIG_fail;
+  $1 = (DIM_TYPE) array_size(array,0);
+  $2 = (DIM_TYPE) array_size(array,1);
+  $3 = (DIM_TYPE) array_size(array,2);
+  $4 = (DIM_TYPE) array_size(array,3);
+  $5 = (DATA_TYPE*) array_data(array);
+}
+
+/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2,
+ *                    DIM_TYPE DIM3, DIM_TYPE DIM4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* INPLACE_FARRAY4, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4)
+  (PyArrayObject* array=NULL)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,4) || !require_contiguous(array) ||
+      !require_native(array) || !require_fortran(array)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = (DIM_TYPE) array_size(array,0);
+  $3 = (DIM_TYPE) array_size(array,1);
+  $4 = (DIM_TYPE) array_size(array,2);
+  $5 = (DIM_TYPE) array_size(array,3);
+}
+
+/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3,
+ *                    DATA_TYPE* INPLACE_FARRAY4)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_FARRAY4)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DIM_TYPE DIM4, DATA_TYPE* INPLACE_FARRAY4)
+  (PyArrayObject* array=NULL)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_dimensions(array,4) || !require_contiguous(array)
+      || !require_native(array) || !require_fortran(array)) SWIG_fail;
+  $1 = (DIM_TYPE) array_size(array,0);
+  $2 = (DIM_TYPE) array_size(array,1);
+  $3 = (DIM_TYPE) array_size(array,2);
+  $4 = (DIM_TYPE) array_size(array,3);
+  $5 = (DATA_TYPE*) array_data(array);
+}
+
 /*************************/
 /* Argout Array Typemaps */
 /*************************/
@@ -1272,7 +1978,7 @@
 %typemap(in,numinputs=0,
          fragment="NumPy_Backward_Compatibility,NumPy_Macros")
   (DATA_TYPE ARGOUT_ARRAY1[ANY])
-  (PyObject * array = NULL)
+  (PyObject* array = NULL)
 {
   npy_intp dims[1] = { $1_dim0 };
   array = PyArray_SimpleNew(1, dims, DATA_TYPECODE);
@@ -1282,7 +1988,7 @@
 %typemap(argout)
   (DATA_TYPE ARGOUT_ARRAY1[ANY])
 {
-  $result = SWIG_Python_AppendOutput($result,array$argnum);
+  $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
 }
 
 /* Typemap suite for (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
@@ -1290,7 +1996,7 @@
 %typemap(in,numinputs=1,
          fragment="NumPy_Fragments")
   (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
-  (PyObject * array = NULL)
+  (PyObject* array = NULL)
 {
   npy_intp dims[1];
   if (!PyInt_Check($input))
@@ -1310,7 +2016,7 @@
 %typemap(argout)
   (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1)
 {
-  $result = SWIG_Python_AppendOutput($result,array$argnum);
+  $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
 }
 
 /* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
@@ -1318,7 +2024,7 @@
 %typemap(in,numinputs=1,
          fragment="NumPy_Fragments")
   (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
-  (PyObject * array = NULL)
+  (PyObject* array = NULL)
 {
   npy_intp dims[1];
   if (!PyInt_Check($input))
@@ -1338,7 +2044,7 @@
 %typemap(argout)
   (DIM_TYPE DIM1, DATA_TYPE* ARGOUT_ARRAY1)
 {
-  $result = SWIG_Python_AppendOutput($result,array$argnum);
+  $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
 }
 
 /* Typemap suite for (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
@@ -1346,7 +2052,7 @@
 %typemap(in,numinputs=0,
          fragment="NumPy_Backward_Compatibility,NumPy_Macros")
   (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
-  (PyObject * array = NULL)
+  (PyObject* array = NULL)
 {
   npy_intp dims[2] = { $1_dim0, $1_dim1 };
   array = PyArray_SimpleNew(2, dims, DATA_TYPECODE);
@@ -1356,7 +2062,7 @@
 %typemap(argout)
   (DATA_TYPE ARGOUT_ARRAY2[ANY][ANY])
 {
-  $result = SWIG_Python_AppendOutput($result,array$argnum);
+  $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
 }
 
 /* Typemap suite for (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
@@ -1364,7 +2070,7 @@
 %typemap(in,numinputs=0,
          fragment="NumPy_Backward_Compatibility,NumPy_Macros")
   (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
-  (PyObject * array = NULL)
+  (PyObject* array = NULL)
 {
   npy_intp dims[3] = { $1_dim0, $1_dim1, $1_dim2 };
   array = PyArray_SimpleNew(3, dims, DATA_TYPECODE);
@@ -1374,7 +2080,25 @@
 %typemap(argout)
   (DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY])
 {
-  $result = SWIG_Python_AppendOutput($result,array$argnum);
+  $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
+}
+
+/* Typemap suite for (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY])
+ */
+%typemap(in,numinputs=0,
+         fragment="NumPy_Backward_Compatibility,NumPy_Macros")
+  (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY])
+  (PyObject* array = NULL)
+{
+  npy_intp dims[4] = { $1_dim0, $1_dim1, $1_dim2, $1_dim3 };
+  array = PyArray_SimpleNew(4, dims, DATA_TYPECODE);
+  if (!array) SWIG_fail;
+  $1 = ($1_ltype) array_data(array);
+}
+%typemap(argout)
+  (DATA_TYPE ARGOUT_ARRAY4[ANY][ANY][ANY][ANY])
+{
+  $result = SWIG_Python_AppendOutput($result,(PyObject*)array$argnum);
 }
 
 /*****************************/
@@ -1385,7 +2109,7 @@
  */
 %typemap(in,numinputs=0)
   (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1    )
-  (DATA_TYPE*  data_temp        , DIM_TYPE  dim_temp)
+  (DATA_TYPE*  data_temp = NULL , DIM_TYPE  dim_temp)
 {
   $1 = &data_temp;
   $2 = &dim_temp;
@@ -1395,16 +2119,18 @@
   (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1)
 {
   npy_intp dims[1] = { *$2 };
-  PyObject * array = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$1));
+  PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
   if (!array) SWIG_fail;
-  $result = SWIG_Python_AppendOutput($result,array);
+  $result = SWIG_Python_AppendOutput($result,obj);
 }
 
 /* Typemap suite for (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1)
  */
 %typemap(in,numinputs=0)
   (DIM_TYPE* DIM1    , DATA_TYPE** ARGOUTVIEW_ARRAY1)
-  (DIM_TYPE  dim_temp, DATA_TYPE*  data_temp        )
+  (DIM_TYPE  dim_temp, DATA_TYPE*  data_temp = NULL )
 {
   $1 = &dim_temp;
   $2 = &data_temp;
@@ -1414,16 +2140,18 @@
   (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1)
 {
   npy_intp dims[1] = { *$1 };
-  PyObject * array = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$2));
+  PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$2));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
   if (!array) SWIG_fail;
-  $result = SWIG_Python_AppendOutput($result,array);
+  $result = SWIG_Python_AppendOutput($result,obj);
 }
 
 /* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
  */
 %typemap(in,numinputs=0)
   (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1     , DIM_TYPE* DIM2     )
-  (DATA_TYPE*  data_temp        , DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp)
+  (DATA_TYPE*  data_temp = NULL , DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp)
 {
   $1 = &data_temp;
   $2 = &dim1_temp;
@@ -1434,16 +2162,18 @@
   (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
 {
   npy_intp dims[2] = { *$2, *$3 };
-  PyObject * array = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1));
+  PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
   if (!array) SWIG_fail;
-  $result = SWIG_Python_AppendOutput($result,array);
+  $result = SWIG_Python_AppendOutput($result,obj);
 }
 
 /* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2)
  */
 %typemap(in,numinputs=0)
   (DIM_TYPE* DIM1     , DIM_TYPE* DIM2     , DATA_TYPE** ARGOUTVIEW_ARRAY2)
-  (DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp, DATA_TYPE*  data_temp        )
+  (DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp, DATA_TYPE*  data_temp = NULL )
 {
   $1 = &dim1_temp;
   $2 = &dim2_temp;
@@ -1454,16 +2184,18 @@
   (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2)
 {
   npy_intp dims[2] = { *$1, *$2 };
-  PyObject * array = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3));
+  PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
   if (!array) SWIG_fail;
-  $result = SWIG_Python_AppendOutput($result,array);
+  $result = SWIG_Python_AppendOutput($result,obj);
 }
 
 /* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
  */
 %typemap(in,numinputs=0)
   (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1     , DIM_TYPE* DIM2     )
-  (DATA_TYPE*  data_temp        , DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp)
+  (DATA_TYPE*  data_temp = NULL  , DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp)
 {
   $1 = &data_temp;
   $2 = &dim1_temp;
@@ -1474,8 +2206,9 @@
   (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
 {
   npy_intp dims[2] = { *$2, *$3 };
-  PyObject * obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1));
-  PyArrayObject * array = (PyArrayObject*) obj;
+  PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
   if (!array || !require_fortran(array)) SWIG_fail;
   $result = SWIG_Python_AppendOutput($result,obj);
 }
@@ -1484,7 +2217,7 @@
  */
 %typemap(in,numinputs=0)
   (DIM_TYPE* DIM1     , DIM_TYPE* DIM2     , DATA_TYPE** ARGOUTVIEW_FARRAY2)
-  (DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp, DATA_TYPE*  data_temp        )
+  (DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp, DATA_TYPE*  data_temp = NULL  )
 {
   $1 = &dim1_temp;
   $2 = &dim2_temp;
@@ -1495,8 +2228,9 @@
   (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2)
 {
   npy_intp dims[2] = { *$1, *$2 };
-  PyObject * obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3));
-  PyArrayObject * array = (PyArrayObject*) obj;
+  PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
   if (!array || !require_fortran(array)) SWIG_fail;
   $result = SWIG_Python_AppendOutput($result,obj);
 }
@@ -1505,8 +2239,8 @@
                       DIM_TYPE* DIM3)
  */
 %typemap(in,numinputs=0)
-  (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
-  (DATA_TYPE* data_temp, DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp)
+  (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    )
+  (DATA_TYPE* data_temp = NULL  , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp)
 {
   $1 = &data_temp;
   $2 = &dim1_temp;
@@ -1518,9 +2252,11 @@
   (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
 {
   npy_intp dims[3] = { *$2, *$3, *$4 };
-  PyObject * array = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1));
+  PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
   if (!array) SWIG_fail;
-  $result = SWIG_Python_AppendOutput($result,array);
+  $result = SWIG_Python_AppendOutput($result,obj);
 }
 
 /* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3,
@@ -1528,7 +2264,7 @@
  */
 %typemap(in,numinputs=0)
   (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)
-  (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp)
+  (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL)
 {
   $1 = &dim1_temp;
   $2 = &dim2_temp;
@@ -1540,17 +2276,19 @@
   (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)
 {
   npy_intp dims[3] = { *$1, *$2, *$3 };
-  PyObject * array = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$3));
+  PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
   if (!array) SWIG_fail;
-  $result = SWIG_Python_AppendOutput($result,array);
+  $result = SWIG_Python_AppendOutput($result,obj);
 }
 
 /* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
                       DIM_TYPE* DIM3)
  */
 %typemap(in,numinputs=0)
-  (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
-  (DATA_TYPE* data_temp, DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp)
+  (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    )
+  (DATA_TYPE* data_temp = NULL   , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp)
 {
   $1 = &data_temp;
   $2 = &dim1_temp;
@@ -1562,9 +2300,10 @@
   (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
 {
   npy_intp dims[3] = { *$2, *$3, *$4 };
-  PyObject * obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1));
-  PyArrayObject * array = (PyArrayObject*) obj;
-  if (!array || require_fortran(array)) SWIG_fail;
+  PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array || !require_fortran(array)) SWIG_fail;
   $result = SWIG_Python_AppendOutput($result,obj);
 }
 
@@ -1572,8 +2311,8 @@
                       DATA_TYPE** ARGOUTVIEW_FARRAY3)
  */
 %typemap(in,numinputs=0)
-  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3)
-  (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp)
+  (DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DATA_TYPE** ARGOUTVIEW_FARRAY3)
+  (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL   )
 {
   $1 = &dim1_temp;
   $2 = &dim2_temp;
@@ -1585,54 +2324,843 @@
   (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3)
 {
   npy_intp dims[3] = { *$1, *$2, *$3 };
-  PyObject * obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$3));
-  PyArrayObject * array = (PyArrayObject*) obj;
-  if (!array || require_fortran(array)) SWIG_fail;
+  PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array || !require_fortran(array)) SWIG_fail;
   $result = SWIG_Python_AppendOutput($result,obj);
 }
 
-%enddef    /* %numpy_typemaps() macro */
-/* *************************************************************** */
-
-/* Concrete instances of the %numpy_typemaps() macro: Each invocation
- * below applies all of the typemaps above to the specified data type.
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+                      DIM_TYPE* DIM3, DIM_TYPE* DIM4)
  */
-%numpy_typemaps(signed char       , NPY_BYTE     , int)
-%numpy_typemaps(unsigned char     , NPY_UBYTE    , int)
-%numpy_typemaps(short             , NPY_SHORT    , int)
-%numpy_typemaps(unsigned short    , NPY_USHORT   , int)
-%numpy_typemaps(int               , NPY_INT      , int)
-%numpy_typemaps(unsigned int      , NPY_UINT     , int)
-%numpy_typemaps(long              , NPY_LONG     , int)
-%numpy_typemaps(unsigned long     , NPY_ULONG    , int)
-%numpy_typemaps(long long         , NPY_LONGLONG , int)
-%numpy_typemaps(unsigned long long, NPY_ULONGLONG, int)
-%numpy_typemaps(float             , NPY_FLOAT    , int)
-%numpy_typemaps(double            , NPY_DOUBLE   , int)
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DIM_TYPE* DIM4    )
+  (DATA_TYPE* data_temp = NULL  , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+  $4 = &dim3_temp;
+  $5 = &dim4_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility")
+  (DATA_TYPE** ARGOUTVIEW_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+{
+  npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
+  PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
 
-/* ***************************************************************
- * The follow macro expansion does not work, because C++ bool is 4
- * bytes and NPY_BOOL is 1 byte
- *
- *    %numpy_typemaps(bool, NPY_BOOL, int)
- */
+  if (!array) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
 
-/* ***************************************************************
- * On my Mac, I get the following warning for this macro expansion:
- * 'swig/python detected a memory leak of type 'long double *', no destructor found.'
- *
- *    %numpy_typemaps(long double, NPY_LONGDOUBLE, int)
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
+                      DATA_TYPE** ARGOUTVIEW_ARRAY4)
  */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DIM_TYPE* DIM4    , DATA_TYPE** ARGOUTVIEW_ARRAY4)
+  (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL  )
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &dim3_temp;
+  $4 = &dim4_temp;
+  $5 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_ARRAY4)
+{
+  npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
+  PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
+  PyArrayObject* array = (PyArrayObject*) obj;
 
-/* ***************************************************************
- * Swig complains about a syntax error for the following macro
- * expansions:
- *
- *    %numpy_typemaps(complex float,  NPY_CFLOAT , int)
- *
- *    %numpy_typemaps(complex double, NPY_CDOUBLE, int)
- *
- *    %numpy_typemaps(complex long double, NPY_CLONGDOUBLE, int)
+  if (!array) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+                      DIM_TYPE* DIM3, DIM_TYPE* DIM4)
  */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DIM_TYPE* DIM4    )
+  (DATA_TYPE* data_temp = NULL   , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+  $4 = &dim3_temp;
+  $5 = &dim4_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+  (DATA_TYPE** ARGOUTVIEW_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+{
+  npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
+  PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array || !require_fortran(array)) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
+                      DATA_TYPE** ARGOUTVIEW_FARRAY4)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DIM_TYPE* DIM4    , DATA_TYPE** ARGOUTVIEW_FARRAY4)
+  (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL   )
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &dim3_temp;
+  $4 = &dim4_temp;
+  $5 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEW_FARRAY4)
+{
+  npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
+  PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array || !require_fortran(array)) SWIG_fail;
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/*************************************/
+/* Managed Argoutview Array Typemaps */
+/*************************************/
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1    )
+  (DATA_TYPE*  data_temp = NULL  , DIM_TYPE  dim_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Utilities")
+  (DATA_TYPE** ARGOUTVIEWM_ARRAY1, DIM_TYPE* DIM1)
+{
+  npy_intp dims[1] = { *$2 };
+  PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEWM_ARRAY1)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1    , DATA_TYPE** ARGOUTVIEWM_ARRAY1)
+  (DIM_TYPE  dim_temp, DATA_TYPE*  data_temp = NULL  )
+{
+  $1 = &dim_temp;
+  $2 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Utilities")
+  (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEWM_ARRAY1)
+{
+  npy_intp dims[1] = { *$1 };
+  PyObject* obj = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$2));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1     , DIM_TYPE* DIM2     )
+  (DATA_TYPE*  data_temp = NULL  , DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Utilities")
+  (DATA_TYPE** ARGOUTVIEWM_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+{
+  npy_intp dims[2] = { *$2, *$3 };
+  PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_ARRAY2)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1     , DIM_TYPE* DIM2     , DATA_TYPE** ARGOUTVIEWM_ARRAY2)
+  (DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp, DATA_TYPE*  data_temp = NULL  )
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Utilities")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_ARRAY2)
+{
+  npy_intp dims[2] = { *$1, *$2 };
+  PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1     , DIM_TYPE* DIM2     )
+  (DATA_TYPE*  data_temp = NULL   , DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities")
+  (DATA_TYPE** ARGOUTVIEWM_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2)
+{
+  npy_intp dims[2] = { *$2, *$3 };
+  PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array || !require_fortran(array)) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_FARRAY2)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1     , DIM_TYPE* DIM2     , DATA_TYPE** ARGOUTVIEWM_FARRAY2)
+  (DIM_TYPE  dim1_temp, DIM_TYPE  dim2_temp, DATA_TYPE*  data_temp = NULL   )
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEWM_FARRAY2)
+{
+  npy_intp dims[2] = { *$1, *$2 };
+  PyObject* obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array || !require_fortran(array)) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+                      DIM_TYPE* DIM3)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    )
+  (DATA_TYPE* data_temp = NULL   , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+  $4 = &dim3_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Utilities")
+  (DATA_TYPE** ARGOUTVIEWM_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+{
+  npy_intp dims[3] = { *$2, *$3, *$4 };
+  PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3,
+                      DATA_TYPE** ARGOUTVIEWM_ARRAY3)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DATA_TYPE** ARGOUTVIEWM_ARRAY3)
+  (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL   )
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &dim3_temp;
+  $4 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Utilities")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_ARRAY3)
+{
+  npy_intp dims[3] = { *$1, *$2, *$3 };
+  PyObject* obj= PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+                      DIM_TYPE* DIM3)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    )
+  (DATA_TYPE* data_temp = NULL    , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+  $4 = &dim3_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities")
+  (DATA_TYPE** ARGOUTVIEWM_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+{
+  npy_intp dims[3] = { *$2, *$3, *$4 };
+  PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array || !require_fortran(array)) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3,
+                      DATA_TYPE** ARGOUTVIEWM_FARRAY3)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DATA_TYPE** ARGOUTVIEWM_FARRAY3)
+  (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp = NULL    )
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &dim3_temp;
+  $4 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEWM_FARRAY3)
+{
+  npy_intp dims[3] = { *$1, *$2, *$3 };
+  PyObject* obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$4));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array || !require_fortran(array)) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+                      DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DIM_TYPE* DIM4    )
+  (DATA_TYPE* data_temp = NULL   , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+  $4 = &dim3_temp;
+  $5 = &dim4_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Utilities")
+  (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+{
+  npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
+  PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
+                      DATA_TYPE** ARGOUTVIEWM_ARRAY4)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DIM_TYPE* DIM4    , DATA_TYPE** ARGOUTVIEWM_ARRAY4)
+  (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL   )
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &dim3_temp;
+  $4 = &dim4_temp;
+  $5 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Utilities")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_ARRAY4)
+{
+  npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
+  PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+                      DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DIM_TYPE* DIM4    )
+  (DATA_TYPE* data_temp = NULL    , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+  $4 = &dim3_temp;
+  $5 = &dim4_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities")
+  (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
+{
+  npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
+  PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array || !require_fortran(array)) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
+                      DATA_TYPE** ARGOUTVIEWM_FARRAY4)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DIM_TYPE* DIM4    , DATA_TYPE** ARGOUTVIEWM_FARRAY4)
+  (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL    )
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &dim3_temp;
+  $4 = &dim4_temp;
+  $5 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_FARRAY4)
+{
+  npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
+  PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array || !require_fortran(array)) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+                      DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DIM_TYPE* DIM4    )
+  (DATA_TYPE* data_temp = NULL   , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+  $4 = &dim3_temp;
+  $5 = &dim4_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Utilities")
+  (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+{
+  npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
+  PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
+                      DATA_TYPE** ARGOUTVIEWM_ARRAY4)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DIM_TYPE* DIM4    , DATA_TYPE** ARGOUTVIEWM_ARRAY4)
+  (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL   )
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &dim3_temp;
+  $4 = &dim4_temp;
+  $5 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Utilities")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_ARRAY4)
+{
+  npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
+  PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
+                      DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+ */
+%typemap(in,numinputs=0)
+  (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DIM_TYPE* DIM4    )
+  (DATA_TYPE* data_temp = NULL    , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
+{
+  $1 = &data_temp;
+  $2 = &dim1_temp;
+  $3 = &dim2_temp;
+  $4 = &dim3_temp;
+  $5 = &dim4_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities")
+  (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
+{
+  npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
+  PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array || !require_fortran(array)) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
+                      DATA_TYPE** ARGOUTVIEWM_FARRAY4)
+ */
+%typemap(in,numinputs=0)
+  (DIM_TYPE* DIM1    , DIM_TYPE* DIM2    , DIM_TYPE* DIM3    , DIM_TYPE* DIM4    , DATA_TYPE** ARGOUTVIEWM_FARRAY4)
+  (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL    )
+{
+  $1 = &dim1_temp;
+  $2 = &dim2_temp;
+  $3 = &dim3_temp;
+  $4 = &dim4_temp;
+  $5 = &data_temp;
+}
+%typemap(argout,
+         fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities")
+  (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_FARRAY4)
+{
+  npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
+  PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
+  PyArrayObject* array = (PyArrayObject*) obj;
+
+  if (!array || !require_fortran(array)) SWIG_fail;
+
+%#ifdef SWIGPY_USE_CAPSULE
+    PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
+%#else
+    PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
+%#endif
+
+%#if NPY_API_VERSION < 0x00000007
+  PyArray_BASE(array) = cap;
+%#else
+  PyArray_SetBaseObject(array,cap);
+%#endif
+
+  $result = SWIG_Python_AppendOutput($result,obj);
+}
+
+/**************************************/
+/* In-Place Array Typemap - flattened */
+/**************************************/
+
+/* Typemap suite for (DATA_TYPE* INPLACE_ARRAY_FLAT, DIM_TYPE DIM_FLAT)
+ */
+%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
+           fragment="NumPy_Macros")
+  (DATA_TYPE* INPLACE_ARRAY_FLAT, DIM_TYPE DIM_FLAT)
+{
+  $1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
+                                                 DATA_TYPECODE);
+}
+%typemap(in,
+         fragment="NumPy_Fragments")
+  (DATA_TYPE* INPLACE_ARRAY_FLAT, DIM_TYPE DIM_FLAT)
+  (PyArrayObject* array=NULL, int i=1)
+{
+  array = obj_to_array_no_conversion($input, DATA_TYPECODE);
+  if (!array || !require_c_or_f_contiguous(array)
+      || !require_native(array)) SWIG_fail;
+  $1 = (DATA_TYPE*) array_data(array);
+  $2 = 1;
+  for (i=0; i < array_numdims(array); ++i) $2 *= array_size(array,i);
+}
+
+%enddef    /* %numpy_typemaps() macro */
+/* *************************************************************** */
+
+/* Concrete instances of the %numpy_typemaps() macro: Each invocation
+ * below applies all of the typemaps above to the specified data type.
+ */
+%numpy_typemaps(signed char       , NPY_BYTE     , int)
+%numpy_typemaps(unsigned char     , NPY_UBYTE    , int)
+%numpy_typemaps(short             , NPY_SHORT    , int)
+%numpy_typemaps(unsigned short    , NPY_USHORT   , int)
+%numpy_typemaps(int               , NPY_INT      , int)
+%numpy_typemaps(unsigned int      , NPY_UINT     , int)
+%numpy_typemaps(long              , NPY_LONG     , int)
+%numpy_typemaps(unsigned long     , NPY_ULONG    , int)
+%numpy_typemaps(long long         , NPY_LONGLONG , int)
+%numpy_typemaps(unsigned long long, NPY_ULONGLONG, int)
+%numpy_typemaps(float             , NPY_FLOAT    , int)
+%numpy_typemaps(double            , NPY_DOUBLE   , int)
+
+/* ***************************************************************
+ * The follow macro expansion does not work, because C++ bool is 4
+ * bytes and NPY_BOOL is 1 byte
+ *
+ *    %numpy_typemaps(bool, NPY_BOOL, int)
+ */
+
+/* ***************************************************************
+ * On my Mac, I get the following warning for this macro expansion:
+ * 'swig/python detected a memory leak of type 'long double *', no destructor found.'
+ *
+ *    %numpy_typemaps(long double, NPY_LONGDOUBLE, int)
+ */
+
+#ifdef __cplusplus
+
+%include <std_complex.i>
+
+%numpy_typemaps(std::complex<float>,  NPY_CFLOAT , int)
+%numpy_typemaps(std::complex<double>, NPY_CDOUBLE, int)
+
+#endif
 
 #endif /* SWIGPYTHON */
diff --git a/pymolfile/python/Makefile.am b/pymolfile/python/Makefile.am
new file mode 100644
index 0000000000000000000000000000000000000000..e96a0767ea13418531a936613ba50816b0f9f86d
--- /dev/null
+++ b/pymolfile/python/Makefile.am
@@ -0,0 +1 @@
+EXTRA_DIST=*.py
\ No newline at end of file
diff --git a/pymolfile/python/Makefile.in b/pymolfile/python/Makefile.in
new file mode 100644
index 0000000000000000000000000000000000000000..1856705397c949ce4289a492ffd2ea45516f16b8
--- /dev/null
+++ b/pymolfile/python/Makefile.in
@@ -0,0 +1,335 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005  Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/python
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+ASFLAGS = @ASFLAGS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+F77LINK = @F77LINK@
+FFLAGS = @FFLAGS@
+FLIBS = @FLIBS@
+GMXANA_LIBOBJS = @GMXANA_LIBOBJS@
+GMXLIB_LIBOBJS = @GMXLIB_LIBOBJS@
+GMX_FORTRAN_FALSE = @GMX_FORTRAN_FALSE@
+GMX_FORTRAN_TRUE = @GMX_FORTRAN_TRUE@
+GREP = @GREP@
+INCLUDES = @INCLUDES@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBSUFFIX = @LIBSUFFIX@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MDLIB_LIBOBJS = @MDLIB_LIBOBJS@
+MPICC = @MPICC@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+RPM = @RPM@
+SET_MAKE = @SET_MAKE@
+SHARED_VERSION_INFO = @SHARED_VERSION_INFO@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+EXTRA_DIST = *.py
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  src/python/Makefile'; \
+	cd $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu  src/python/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+distclean-libtool:
+	-rm -f libtool
+uninstall-info-am:
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+	list='$(DISTFILES)'; for file in $$list; do \
+	  case $$file in \
+	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+	  esac; \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+	    dir="/$$dir"; \
+	    $(mkdir_p) "$(distdir)$$dir"; \
+	  else \
+	    dir=''; \
+	  fi; \
+	  if test -d $$d/$$file; then \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+	    fi; \
+	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+	  else \
+	    test -f $(distdir)/$$file \
+	    || cp -p $$d/$$file $(distdir)/$$file \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-libtool
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	distclean distclean-generic distclean-libtool distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-exec install-exec-am \
+	install-info install-info-am install-man install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \
+	uninstall-info-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/pymolfile/python/sample.py b/pymolfile/python/sample.py
new file mode 100755
index 0000000000000000000000000000000000000000..56b5d4fbf241d354de3193e9e3f17e824c0e8d5a
--- /dev/null
+++ b/pymolfile/python/sample.py
@@ -0,0 +1,46 @@
+#!/usr/bin/python
+#  -*- mode: python; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*-
+# 
+#  $Id$
+# 
+#  Copyright (c) Erik Lindahl, David van der Spoel 2003-2007.
+#  Coordinate compression (c) by Frans van Hoesel.
+#  Python wrapper (c) by Roland Schulz
+# 
+#  IN contrast to the rest of Gromacs, XDRFILE is distributed under the
+#  BSD license, so you can use it any way you wish, including closed source:
+# 
+#  Permission is hereby granted, free of charge, to any person obtaining a
+#  copy of this software and associated documentation files (the "Software"),
+#  to deal in the Software without restriction, including without limitation
+#  the rights to use, copy, modify, merge, publish, distribute, sublicense,
+#  and/or sell copies of the Software, and to permit persons to whom the
+#  Software is furnished to do so, subject to the following conditions:
+# 
+#  The above copyright notice and this permission notice shall be included in
+#  all copies or substantial portions of the Software.
+# 
+#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+#  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+#  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+#  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+#  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+#  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+#  DEALINGS IN THE SOFTWARE.
+# 
+from xdrfile import *
+import sys
+
+#you have to compile with --enable-shared
+#and have libxdrfile.so in the LD_LIBRARY_PATH
+
+if len(sys.argv)!=2:
+  print "Missing file argument\nUsage: sample.py FILE"
+  sys.exit()
+
+
+x=xdrfile(sys.argv[1]) 
+for f in x:   #iterates frames
+    print "%8s %8s %8s %8s   Step: %8d "%("Atom","X","Y","Z",f.step) #print header
+    for i,a in enumerate(f.x):  #iterate atoms
+      print "%8d %8.1f %8.1f %8.1f"%(i+1,a[0],a[1],a[2]) #print atom number, x, y, z
diff --git a/pymolfile/python/xdrfile.py b/pymolfile/python/xdrfile.py
new file mode 100644
index 0000000000000000000000000000000000000000..ba4d75e1ae3ae527a860635acd06535fe08d54f4
--- /dev/null
+++ b/pymolfile/python/xdrfile.py
@@ -0,0 +1,147 @@
+#  -*- mode: python; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*-
+# 
+#  $Id$
+# 
+#  Copyright (c) Erik Lindahl, David van der Spoel 2003-2007.
+#  Coordinate compression (c) by Frans van Hoesel.
+#  Python wrapper (c) by Roland Schulz
+# 
+#  IN contrast to the rest of Gromacs, XDRFILE is distributed under the
+#  BSD license, so you can use it any way you wish, including closed source:
+# 
+#  Permission is hereby granted, free of charge, to any person obtaining a
+#  copy of this software and associated documentation files (the "Software"),
+#  to deal in the Software without restriction, including without limitation
+#  the rights to use, copy, modify, merge, publish, distribute, sublicense,
+#  and/or sell copies of the Software, and to permit persons to whom the
+#  Software is furnished to do so, subject to the following conditions:
+# 
+#  The above copyright notice and this permission notice shall be included in
+#  all copies or substantial portions of the Software.
+# 
+#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+#  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+#  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+#  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+#  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+#  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+#  DEALINGS IN THE SOFTWARE.
+# 
+
+from ctypes import *
+import os.path
+
+mTrr,mNumPy=1,2
+try:
+    from numpy import *
+    from numpy.ctypeslib import ndpointer
+    auto_mode=mNumPy                 
+except:
+    auto_mode=0
+
+
+class frame:
+    #variables
+    #x: rvec*natoms / numpy array if installed
+    #box DIM*DIM
+    #step 
+    #time 
+    #prec 
+    #lam: lambda
+
+    def __init__(self,n,mode):
+        #create vector for x
+        if mode&mNumPy:
+            self.x=empty((n,3),dtype=float32)
+            self.box = empty((3,3),float32)
+        else:
+            self.x=((c_float*3)*n)() 
+            self.box = (c_float*3*3)()
+
+
+class xdrfile:
+    exdrOK, exdrHEADER, exdrSTRING, exdrDOUBLE, exdrINT, exdrFLOAT, exdrUINT, exdr3DX, exdrCLOSE, exdrMAGIC, exdrNOMEM, exdrENDOFFILE, exdrNR = range(13)
+
+    #
+    def __init__(self,fn,mode="Auto",ft="Auto"):
+        if mode=="NumPy":
+          self.mode=mNumPy
+          try:
+            empty
+          except NameError:
+              raise IOError("NumPy selected but not correctly installed")
+        elif mode=="Std":
+          self.mode=0
+        elif mode=="Auto":
+          self.mode=auto_mode
+        else: 
+          raise IOError("unsupported mode")
+          
+        if ft=="Auto":
+          ft = os.path.splitext(fn)[1][1:]
+          
+        if ft=="trr":
+            self.mode|=mTrr
+        elif ft=="xtc":
+            pass
+        else:
+            raise IOError("Only xtc and trr supported")
+        
+        #load libxdrfil
+        try: 
+          self.xdr=cdll.LoadLibrary("libxdrfile.so")
+        except:
+          raise IOError("libxdrfile.so can't be loaded")
+          
+        #open file
+        self.xd = self.xdr.xdrfile_open(fn,"r")
+        if not self.xd: raise IOError("Cannot open file: '%s'"%fn)
+        
+        #read natoms
+        natoms=c_int()
+        if self.mode&mTrr:
+            r=self.xdr.read_trr_natoms(fn,byref(natoms))
+        else:
+            r=self.xdr.read_xtc_natoms(fn,byref(natoms))
+        if r!=self.exdrOK: raise IOError("Error reading: '%s'"%fn)
+        self.natoms=natoms.value
+        
+        #for NumPy define argtypes - ndpointer is not automatically converted to POINTER(c_float)
+        #alternative of ctypes.data_as(POINTER(c_float)) requires two version for numpy and c_float array
+        if self.mode&mNumPy:
+            self.xdr.read_xtc.argtypes=[c_int,c_int,POINTER(c_int),POINTER(c_float),
+              ndpointer(ndim=2,dtype=float32),ndpointer(ndim=2,dtype=float32),POINTER(c_float)]
+            self.xdr.read_trr.argtypes=[c_int,c_int,POINTER(c_int),POINTER(c_float),POINTER(c_float),
+              ndpointer(ndim=2,dtype=float32),ndpointer(ndim=2,dtype=float32),
+              POINTER(c_float),POINTER(c_float)]
+             
+        
+    def __iter__(self):
+        f = frame(self.natoms,self.mode)
+        #temporary c_type variables (frame variables are python type)
+        step = c_int()
+        time = c_float()
+        prec = c_float()
+        lam = c_float()
+        while 1:
+            #read next frame
+            if not self.mode&mTrr:
+                result = self.xdr.read_xtc(self.xd,self.natoms,byref(step),byref(time),f.box,
+                        f.x,byref(prec))
+                f.prec=prec.value
+            else:
+                result = self.xdr.read_trr(self.xd,self.natoms,byref(step),byref(time),byref(lam),
+                        f.box,f.x,None,None) #TODO: make v,f possible
+                f.lam=lam.value
+                
+            #check return value
+            if result==self.exdrENDOFFILE: break
+            if result==self.exdrINT and self.mode&mTrr: 
+              break  #TODO: dirty hack. read_trr return exdrINT not exdrENDOFFILE
+            if result!=self.exdrOK: raise IOError("Error reading xdr file")
+            
+            #convert c_type to python 
+            f.step=step.value
+            f.time=time.value
+            yield f
+        
diff --git a/pymolfile/python/xdrfile_test.py b/pymolfile/python/xdrfile_test.py
new file mode 100755
index 0000000000000000000000000000000000000000..d4c6025b23a637d5afa2fa084d40a436bd9692c3
--- /dev/null
+++ b/pymolfile/python/xdrfile_test.py
@@ -0,0 +1,65 @@
+#!/usr/bin/python
+#  -*- mode: python; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*-
+# 
+#  $Id$
+# 
+#  Copyright (c) Erik Lindahl, David van der Spoel 2003-2007.
+#  Coordinate compression (c) by Frans van Hoesel.
+#  Python wrapper (c) by Roland Schulz
+# 
+#  IN contrast to the rest of Gromacs, XDRFILE is distributed under the
+#  BSD license, so you can use it any way you wish, including closed source:
+# 
+#  Permission is hereby granted, free of charge, to any person obtaining a
+#  copy of this software and associated documentation files (the "Software"),
+#  to deal in the Software without restriction, including without limitation
+#  the rights to use, copy, modify, merge, publish, distribute, sublicense,
+#  and/or sell copies of the Software, and to permit persons to whom the
+#  Software is furnished to do so, subject to the following conditions:
+# 
+#  The above copyright notice and this permission notice shall be included in
+#  all copies or substantial portions of the Software.
+# 
+#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+#  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+#  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+#  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+#  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+#  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+#  DEALINGS IN THE SOFTWARE.
+# 
+from xdrfile import *
+from math import *
+
+#you have to compile with --enable-shared
+#and have libxdrfile.so in the LD_LIBRARY_PATH
+#it expect the test.xtc/test.trr file generated by xdrfile_c_test
+
+DIM=3
+natoms1 = 173
+step1 = 1993
+prec1 = 1000
+time1 = 1097.23
+lam1 = 0.4
+box1=[[(i+1)*3.7 + (j+1) for j in range(DIM)] for i in range(DIM)]
+toler = 1e-3
+
+def test(fn):
+    x=xdrfile(fn)
+    if x.natoms != natoms1: print "natoms != natoms1",x.natoms,natoms1
+    for k,f in enumerate(x):
+        if f.step != step1+k: print "incorrect step",f.step,step1+k,k
+        if fabs(f.time-time1-k) > toler: print "incorrect time",f.time,time1+k
+        if not x.mode&mTrr and fabs(f.prec-prec1) > toler: print "incorrect precision",f.prec,prec1
+        if x.mode&mTrr and fabs(f.lam-lam1) > toler: print "incorrect lambda",f.lam,lam1
+        for i in range(DIM):
+            for j in range(DIM):
+                if fabs(f.box[i][j] - box1[i][j]) > toler: print "box incorrect",f.box[i][j],box1[i][j]
+        for i in range(x.natoms):
+            for j in range(DIM):
+                target = (i+1)*3.7 + (j+1)
+                if  f.x[i][j] - target > toler : print "x incorrect"
+    print fn,"OK"
+
+test("../test.trr")
+test("../test.xtc")