diff --git a/pymolfile/] b/pymolfile/]
deleted file mode 100644
index 3667a47ab4607d1e5a9a3d67121514c96b30af25..0000000000000000000000000000000000000000
--- a/pymolfile/]
+++ /dev/null
@@ -1,254 +0,0 @@
-
-from __future__ import absolute_import
-from __future__ import print_function
-
-import os
-import re
-import sys
-import numpy as np
-import warnings
-
-if sys.version_info > (3,):
-    long = int
-
-try:
-    from .molfile import libpymolfile
-except ImportError:
-    warnings.warn("libpymolfile package not available, pymolfile does not work without its library!")
-
-
-def plugins():
-    """ Information on the available molfile plugins
-
-        Example tuple: ('psf', 'psf', 1, 1, 1, 0, 1, 1, 1, 0, 
-            'CHARMM,NAMD,XPLOR PSF', 'mol file reader', 
-            'Justin Gullingsrud, John Stone', 1, 9, 17, 1)
-
-        The fields in the tuple represent info in ordered as follows:
-            1: format extension
-            2: format name
-            3: read_structure is avaliable if 1
-            4: read_bonds is avaliable if 1
-            5: read_angles is avaliable if 1
-            6: read_next_timestep is avaliable if 1
-            7: write_structure is avaliable if 1
-            8: write_bonds is avaliable if 1
-            9: write_angles is avaliable if 1
-           10: write_timestep is avaliable if 1
-           11: long name of the plugin
-           12: type of plugin
-           13: authors of the plugin
-           14: major version of the plugin
-           15: minor version of the plugin
-           16: ABI version of the plugin
-           17: 1 if is reentrant (returns is_reentrant) 
-
-    Returns: A list of tuples that includes the information and 
-             capabilities of each molfile plugin. The information is 
-             extracted from molfile_plugin_t. 
-    """
-    max_num_plugins = 200
-    c_list = libpymolfile.molfile_plugin_list(max_num_plugins)
-    numlist = libpymolfile.molfile_init()
-    plugins_list = [libpymolfile.molfile_plugin_info(c_list, i) for i in range(numlist)]
-    libpymolfile.molfile_finish()
-    return plugins_list
-
-def open(file_name_with_path, topology=None, 
-         file_format=None, topology_format=None, 
-         plugin=None, topology_plugin=None):
-    """ The main function to read topology and 
-        trajectory files
-
-        Returns: Depends on the file format and arguments:
-                 If structure file is supplied, it returns topology class.
-                 If only trajectory file is supplied, it returns trajectory class 
-                     without topology information. (the number of atoms must be known)
-                 If both files are supplied, it returns trajectory class with 
-                     topology information.
-    """
-    pass
-
-def get_dir_base_extension(file_name):
-    """ Splits directory, file base and file extensions
-
-        Returns: directory without leading '/', 
-                 file base name, and file extension without '.'
-    """
-    file_base, file_extension_with_dot = os.path.splitext(os.path.basename(file_name))
-    file_extension = file_extension_with_dot.split(".")[-1]
-    file_dir = os.path.dirname(file_name)
-    return file_dir, file_base, file_extension
-
-def get_extension(file_name):
-    """ Gets file extension of a file
-
-        Returns: file extension without '.'
-    """
-    file_extension_with_dot  = os.path.splitext(os.path.basename(file_name))[1]
-    return file_extension_with_dot.split(".")[-1]
-
-def get_plugin_with_ext(file_ext):
-    """ Search molfile plugins list and returns the plugin info 
-        for the first matched extension.
-
-        Returns: Plugin no in the list and the list item (the plugin info tuple)
-    """
-    if not MOLFILE_PLUGINS:
-        MOLFILE_PLUGINS = plugins()
-
-    if MOLFILE_PLUGINS:
-        plugin_no = -1
-        for plugin_info in MOLFILE_PLUGINS:
-            plugin_no += 1
-            if file_ext == plugin_info[1]:
-                return (plugin_no, plugin_info)
-
-    return None
-
-def get_plugin_with_name(plugin_name):
-    """ Search molfile plugins list and returns the plugin info 
-        for the first matching name in plugin name field.
-
-        Returns: Plugin no in the list and the list item (the plugin info tuple)
-    """
-    if not MOLFILE_PLUGINS:
-        MOLFILE_PLUGINS = plugins()
-
-    if MOLFILE_PLUGINS:
-        plugin_no = -1
-        for plugin_info in MOLFILE_PLUGINS:
-            plugin_no += 1
-            if plugin_name == plugin_info[2]:
-                return (plugin_no, plugin_info)
-
-    return None
-
-
-class OpenMolfile(object):
-
-    self.plugin_list = MOLFILE_PLUGINS
-    self.trajectory = None
-    self.topology = None
-    self.smolobject = None
-    self.cmolobject = None
-    self.kwords = { 
-        "file_format" : None,
-        "file_plugin" : None,
-        "topology" : None,
-        "topology_format" : None,
-        "topology_plugin" : None,
-        "natoms" : None
-        }
-
-    def __init__(self, file_name, **kwargs):
-        if kwargs:
-            for k, v in kwargs.items():
-                if k in self.kwords:
-                    self.kwords[k] = v
-
-        if file_name:
-            if self.kwords["file_format"] is None:
-               file_dir, file_base, file_ext = get_dir_base_extension(file_name)
-               if file_ext:
-                   self.kwords["file_format"] = file_ext
-               else:
-                   self.kwords["file_format"] = file_base
-
-            if self.kwords["file_plugin"] is None:
-                self.kwords["file_plugin"] = "auto"
-
-            if "auto" in self.kwords["file_plugin"]:
-                plugin_item = get_plugin_with_ext(self.kwords["file_format"])
-                self.kwords["file_plugin"] = 
-
-            if self.kwords["file_plugin"]:
-                if not MOLFILE_PLUGINS:
-                    MOLFILE_PLUGINS = plugins()
-
-
-
-
-                c_list = libpymolfile.molfile_plugin_list(max_num_plugins)
-                numlist = libpymolfile.molfile_init()
-                self.cmolobject = libpymolfile.get_plugin(MOLFILE_PLUGINS, 83) #trr
-
-
-
-        else:
-            return None
-
-
-
-
-
-
-
-
-
-
-
-def get_listof_parts( filename, filepath, fileformats ):
-    pattern = re.escape( filename[1:-4] ) + "\.part[0-9]{4,4}\.(xtc|trr)$"
-    parts = []
-    for f in os.listdir( directory ):
-        m = re.match( pattern, f )
-        if m and os.path.isfile( os.path.join( directory, f ) ):
-            parts.append( os.path.join( directory, f ) )
-    return sorted( parts )
-
-
-def get_trajectory( file_name ):
-    ext = os.path.splitext( file_name )[1].lower()
-    types = {
-        ".xtc": XtcTrajectory,
-        ".trr": TrrTrajectory,
-        ".netcdf": NetcdfTrajectory,
-        ".nc": NetcdfTrajectory,
-        ".dcd": DcdTrajectory,
-    }
-    if ext in types:
-        return types[ ext ]( file_name )
-    else:
-        raise Exception( "extension '%s' not supported" % ext )
-
-class Topology( object ):
-
-    self.structure = None
-    self.bonds = None
-    self.angles = None
-
-    def __init__( self, file_name ):
-        pass
-
-
-
-class Trajectory( object ):
-    def __init__( self, file_name ):
-        pass
-
-    def update( self, force=False ):
-        pass
-
-    def _get_frame( self, index ):
-        pass
-
-    def get_frame( self, index, atom_indices=None ):
-        box, coords, time = self._get_frame( int( index ) )
-        if atom_indices:
-            coords = np.concatenate([
-            ])
-        return {
-            "coords": coords
-            "velocities": coords
-        }
-
-    def get_frame_string( self, index, atom_indices=None ):
-        frame = self.get_frame( index, atom_indices=atom_indices )
-        return (
-        )
-
-    def __del__( self ):
-        pass
-
-
diff --git a/pymolfile/__init__.py b/pymolfile/__init__.py
index 62fae02b838f8df5482f3f643ceacdf3ddc3a1ee..0e4f244a9fecb0fa27699383764a33f9bd9b22cf 100644
--- a/pymolfile/__init__.py
+++ b/pymolfile/__init__.py
@@ -5,5 +5,7 @@ from . import pymolfile
 
 __all__ = [ "pymolfile" ]
 
+MAX_NUM_PLUGINS = 200
+C_MOLFILE_PLUGINS = libpymolfile.molfile_plugin_list(MAX_NUM_PLUGINS)
 MOLFILE_PLUGINS = pymolfile.plugins()
 
diff --git a/pymolfile/__pycache__/pymolfile.cpython-36.pyc b/pymolfile/__pycache__/pymolfile.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1e19a06a51bf6003652eb8cfb19bc4b9a0a26c52
Binary files /dev/null and b/pymolfile/__pycache__/pymolfile.cpython-36.pyc differ
diff --git a/pymolfile/molfile/__pycache__/libpymolfile.cpython-36.pyc b/pymolfile/molfile/__pycache__/libpymolfile.cpython-36.pyc
index 09623bd45a3e5dc77246c0a88f466113249b2ab2..bc43e9aae4503301f6e3a92af0ca934b25c01e4b 100644
Binary files a/pymolfile/molfile/__pycache__/libpymolfile.cpython-36.pyc and b/pymolfile/molfile/__pycache__/libpymolfile.cpython-36.pyc differ
diff --git a/pymolfile/molfile/_libpymolfile.so b/pymolfile/molfile/_libpymolfile.so
index e72261324ff900aeaa9dbe33df442ea998472857..fdfdcc550fe4a6a7dba7e86c38a4b9974d2da208 100755
Binary files a/pymolfile/molfile/_libpymolfile.so and b/pymolfile/molfile/_libpymolfile.so differ
diff --git a/pymolfile/molfile/_libpymolfile.so.dSYM/Contents/Resources/DWARF/_libpymolfile.so b/pymolfile/molfile/_libpymolfile.so.dSYM/Contents/Resources/DWARF/_libpymolfile.so
index c62a68708ff5b2653918f126239f92fabd92fefb..a0b3a8c49d4db6f95fffdd9921c301f5d99e2fdd 100644
Binary files a/pymolfile/molfile/_libpymolfile.so.dSYM/Contents/Resources/DWARF/_libpymolfile.so and b/pymolfile/molfile/_libpymolfile.so.dSYM/Contents/Resources/DWARF/_libpymolfile.so differ
diff --git a/pymolfile/molfile/compile.sh b/pymolfile/molfile/compile.sh
index 100753d1b510ba934722e4328b09af79d11eb990..b04a1dd781331d66c0b4a562a414fcfecdd11ea2 100644
--- a/pymolfile/molfile/compile.sh
+++ b/pymolfile/molfile/compile.sh
@@ -1,4 +1,6 @@
+echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
 swig -py3 -Wall -c++ -python libpymolfile.i
+echo "'-._.-'-._.-'-._.-'-._.-'-._.-'-._.-'-._.-'-._.-'-._.-'-._.-'-._.-'-._.-'-._.-'"
 g++-7 -fPIC -Wall -Wextra -shared -g -Wunused-function -Wunused-parameter  \
     -I/labEnv3/lib/python3.6/site-packages/numpy/core/include/  \
     -I./include \
diff --git a/pymolfile/molfile/libpymolfile.i b/pymolfile/molfile/libpymolfile.i
index 263d94239065b3e5ea31358fbbff2d9961ec0d35..4531072d9c1840d9e5080f4ec2a81303a30575ea 100644
--- a/pymolfile/molfile/libpymolfile.i
+++ b/pymolfile/molfile/libpymolfile.i
@@ -30,9 +30,6 @@
 #include <ctype.h>
 #include <string.h>
 #include <inttypes.h>
-#include "molfile_plugin.h"
-#include "libmolfile_plugin.h"
-#include "vmdplugin.h"
 #include "pymolfile.h"
 %}
 
@@ -57,7 +54,7 @@ import_array();
    initialize and finalize molfile plugins
 */
 %feature("autodoc", "0") molfile_plugin_list;
-extern molfile_plugin_t** molfile_plugin_list(int maxsize);
+extern PyObject* molfile_plugin_list(int maxsize);
 
 %feature("autodoc", "0") molfile_init;
 extern int molfile_init(void);
@@ -66,16 +63,20 @@ extern int molfile_init(void);
 extern int molfile_finish(void);
 
 %feature("autodoc", "0") get_plugin;
-extern molfile_plugin_t* get_plugin(molfile_plugin_t** plugin_list, int plugin_no);
+extern PyObject* get_plugin(PyObject* molcapsule, int plug_no);
+
 
 %feature("autodoc", "0") molfile_plugin_info;
+extern PyObject * molfile_plugin_info(PyObject* molcapsule, int plugin_no);
+/*
 %exception molfile_plugin_info {
   $action
   if (PyErr_Occurred()) SWIG_fail;
 }
 %inline %{
-PyObject * molfile_plugin_info(molfile_plugin_t** plugin_list, int plugin_no) {
+PyObject * molfile_plugin_info(PyObject* molcapsule, int plugin_no) {
     molfile_plugin_t *plugin;
+    molfile_plugin_t** plugin_list = (molfile_plugin_t**) PyMolfileCapsule_AsVoidPtr(molcapsule);   
     int *plugno = &plugin_no;
     int has_readstructure = 0;
     int has_readbonds = 0;
@@ -87,12 +88,12 @@ PyObject * molfile_plugin_info(molfile_plugin_t** plugin_list, int plugin_no) {
     int has_writetimestep = 0;
     int plugin_list_size = sizeof(plugin_list) / sizeof(molfile_plugin_t**);
     if (plugno==NULL || plugin_no<0){
-      PyErr_Format(PyExc_IOError, "[%d] Error: molfile plugin handle no should be given, be positive value and should not exceed the list length'%d'. You set '%d'", pluginNOINIT, plugin_list_size, plugin_no);
+      PyErr_Format(PyExc_IOError, "Error: molfile plugin handle no should be given, be positive value and should not exceed the list length'%d'. You set '%d'", plugin_list_size, plugin_no);
       return 0;
     }
     plugin = plugin_list[plugin_no];
     if(plugin==NULL || !plugin->open_file_read){
-      PyErr_Format(PyExc_IOError, "[%d] Error: molfile plugin '%d' is not initialized.", pluginNOINIT, plugin_no);
+      PyErr_Format(PyExc_IOError, "Error: molfile plugin '%d' is not initialized.", plugin_no);
       return 0;
     }
     if (plugin->read_structure) has_readstructure = 1;
@@ -124,6 +125,7 @@ PyObject * molfile_plugin_info(molfile_plugin_t** plugin_list, int plugin_no) {
     return tuple;
   }
 %}
+*/
 
 
 %feature("autodoc", "0") my_open_file_read;
@@ -133,11 +135,12 @@ PyObject * molfile_plugin_info(molfile_plugin_t** plugin_list, int plugin_no) {
   if (PyErr_Occurred()) SWIG_fail;
 }
 %inline %{
-PyObject * my_open_file_read(molfile_plugin_t* plugin, char* fname, char* ftype, int natoms) {
+PyObject * my_open_file_read(PyObject* molcapsule, char* fname, char* ftype, int natoms) {
     if (PyType_Ready(&MolObjectType) < 0)
         return NULL;
     PyTypeObject *type = &MolObjectType;
     MolObject *plugin_c;
+    molfile_plugin_t* plugin = (molfile_plugin_t*) PyMolfileCapsule_AsVoidPtr(molcapsule);   
     plugin_c = (MolObject *)type->tp_alloc(type, 0);
     plugin_c->plugin = plugin;
     plugin_c->file_handle = plugin->open_file_read(fname, ftype, &natoms);
@@ -159,7 +162,7 @@ PyObject * my_close_file_read(PyObject* molpack) {
     void* file_handle;
     int numatoms;
     MolObject* plugin_handle = (MolObject*) molpack;
-    plugin = plugin_handle->plugin;
+    plugin = plugin_handle->plugin;   
     file_handle = plugin_handle->file_handle;
     numatoms = plugin_handle->natoms;
     plugin->close_file_read(file_handle); 
diff --git a/pymolfile/molfile/libpymolfile.py b/pymolfile/molfile/libpymolfile.py
index cb5776343d31d4f4d488fc87d9d25dc3ea21901d..a57642aa6cb2eb903f6ce95a5d4ac44f7d63d090 100644
--- a/pymolfile/molfile/libpymolfile.py
+++ b/pymolfile/molfile/libpymolfile.py
@@ -107,8 +107,8 @@ except __builtin__.Exception:
     _newclass = 0
 
 
-def molfile_plugin_list(maxsize: 'int') -> "molfile_plugin_t **":
-    """molfile_plugin_list(maxsize) -> molfile_plugin_t **"""
+def molfile_plugin_list(maxsize: 'int') -> "PyObject *":
+    """molfile_plugin_list(maxsize) -> PyObject *"""
     return _libpymolfile.molfile_plugin_list(maxsize)
 
 def molfile_init() -> "int":
@@ -119,17 +119,17 @@ def molfile_finish() -> "int":
     """molfile_finish() -> int"""
     return _libpymolfile.molfile_finish()
 
-def get_plugin(plugin_list: 'molfile_plugin_t **', plugin_no: 'int') -> "molfile_plugin_t *":
-    """get_plugin(plugin_list, plugin_no) -> molfile_plugin_t *"""
-    return _libpymolfile.get_plugin(plugin_list, plugin_no)
+def get_plugin(molcapsule: 'PyObject *', plug_no: 'int') -> "PyObject *":
+    """get_plugin(molcapsule, plug_no) -> PyObject *"""
+    return _libpymolfile.get_plugin(molcapsule, plug_no)
 
-def molfile_plugin_info(plugin_list: 'molfile_plugin_t **', plugin_no: 'int') -> "PyObject *":
-    """molfile_plugin_info(plugin_list, plugin_no) -> PyObject *"""
-    return _libpymolfile.molfile_plugin_info(plugin_list, plugin_no)
+def molfile_plugin_info(molcapsule: 'PyObject *', plugin_no: 'int') -> "PyObject *":
+    """molfile_plugin_info(molcapsule, plugin_no) -> PyObject *"""
+    return _libpymolfile.molfile_plugin_info(molcapsule, plugin_no)
 
-def open_file_read(plugin: 'molfile_plugin_t *', fname: 'char *', ftype: 'char *', natoms: 'int') -> "PyObject *":
-    """open_file_read(plugin, fname, ftype, natoms) -> PyObject *"""
-    return _libpymolfile.open_file_read(plugin, fname, ftype, natoms)
+def open_file_read(molcapsule: 'PyObject *', fname: 'char *', ftype: 'char *', natoms: 'int') -> "PyObject *":
+    """open_file_read(molcapsule, fname, ftype, natoms) -> PyObject *"""
+    return _libpymolfile.open_file_read(molcapsule, fname, ftype, natoms)
 
 def close_file_read(molpack: 'PyObject *') -> "PyObject *":
     """close_file_read(molpack) -> PyObject *"""
diff --git a/pymolfile/molfile/libpymolfile_wrap.cxx b/pymolfile/molfile/libpymolfile_wrap.cxx
index e6fbc91446d74b4a71d28b0aaff7f349ea61e78c..533687b00f09f7f7734804817b5a34f0917f375f 100644
--- a/pymolfile/molfile/libpymolfile_wrap.cxx
+++ b/pymolfile/molfile/libpymolfile_wrap.cxx
@@ -3004,10 +3004,8 @@ SWIG_Python_NonDynamicSetAttr(PyObject *obj, PyObject *name, PyObject *value) {
 /* -------- TYPES TABLE (BEGIN) -------- */
 
 #define SWIGTYPE_p_char swig_types[0]
-#define SWIGTYPE_p_molfile_plugin_t swig_types[1]
-#define SWIGTYPE_p_p_molfile_plugin_t swig_types[2]
-static swig_type_info *swig_types[4];
-static swig_module_info swig_module = {swig_types, 3, 0, 0, 0, 0};
+static swig_type_info *swig_types[2];
+static swig_module_info swig_module = {swig_types, 1, 0, 0, 0, 0};
 #define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
 #define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
 
@@ -3123,9 +3121,6 @@ namespace swig {
 #include <ctype.h>
 #include <string.h>
 #include <inttypes.h>
-#include "molfile_plugin.h"
-#include "libmolfile_plugin.h"
-#include "vmdplugin.h"
 #include "pymolfile.h"
 
 
@@ -3298,62 +3293,12 @@ SWIGINTERNINLINE PyObject*
 }
 
 
-PyObject * molfile_plugin_info(molfile_plugin_t** plugin_list, int plugin_no) {
-    molfile_plugin_t *plugin;
-    int *plugno = &plugin_no;
-    int has_readstructure = 0;
-    int has_readbonds = 0;
-    int has_readangles = 0;
-    int has_writestructure = 0;
-    int has_writebonds = 0;
-    int has_writeangles = 0;
-    int has_readnexttimestep = 0;
-    int has_writetimestep = 0;
-    int plugin_list_size = sizeof(plugin_list) / sizeof(molfile_plugin_t**);
-    if (plugno==NULL || plugin_no<0){
-      PyErr_Format(PyExc_IOError, "[%d] Error: molfile plugin handle no should be given, be positive value and should not exceed the list length'%d'. You set '%d'", pluginNOINIT, plugin_list_size, plugin_no);
-      return 0;
-    }
-    plugin = plugin_list[plugin_no];
-    if(plugin==NULL || !plugin->open_file_read){
-      PyErr_Format(PyExc_IOError, "[%d] Error: molfile plugin '%d' is not initialized.", pluginNOINIT, plugin_no);
-      return 0;
-    }
-    if (plugin->read_structure) has_readstructure = 1;
-    if (plugin->read_bonds) has_readbonds = 1;
-    if (plugin->read_angles) has_readangles = 1;
-    if (plugin->read_next_timestep) has_readnexttimestep = 1;
-    if (plugin->write_structure) has_writestructure = 1;
-    if (plugin->write_bonds) has_writebonds = 1;
-    if (plugin->write_angles) has_writeangles = 1;
-    if (plugin->write_timestep) has_writetimestep = 1;
-    PyObject *tuple = PyTuple_New(17);
-    PyTuple_SET_ITEM(tuple, 0, PyString_FromString(plugin->filename_extension));
-    PyTuple_SET_ITEM(tuple, 1, PyString_FromString(plugin->name));
-    PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong((long)has_readstructure));
-    PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong((long)has_readbonds));
-    PyTuple_SET_ITEM(tuple, 4, PyInt_FromLong((long)has_readangles));
-    PyTuple_SET_ITEM(tuple, 5, PyInt_FromLong((long)has_readnexttimestep));
-    PyTuple_SET_ITEM(tuple, 6, PyInt_FromLong((long)has_writestructure));
-    PyTuple_SET_ITEM(tuple, 7, PyInt_FromLong((long)has_writebonds));
-    PyTuple_SET_ITEM(tuple, 8, PyInt_FromLong((long)has_writeangles));
-    PyTuple_SET_ITEM(tuple, 9, PyInt_FromLong((long)has_writetimestep));
-    PyTuple_SET_ITEM(tuple, 10, PyString_FromString(plugin->prettyname));
-    PyTuple_SET_ITEM(tuple, 11, PyString_FromString(plugin->type));
-    PyTuple_SET_ITEM(tuple, 12, PyString_FromString(plugin->author));
-    PyTuple_SET_ITEM(tuple, 13, PyInt_FromLong((long)plugin->majorv));
-    PyTuple_SET_ITEM(tuple, 14, PyInt_FromLong((long)plugin->minorv));
-    PyTuple_SET_ITEM(tuple, 15, PyInt_FromLong((long)plugin->abiversion));
-    PyTuple_SET_ITEM(tuple, 16, PyInt_FromLong((long)plugin->is_reentrant));
-    return tuple;
-  }
-
-
-PyObject * my_open_file_read(molfile_plugin_t* plugin, char* fname, char* ftype, int natoms) {
+PyObject * my_open_file_read(PyObject* molcapsule, char* fname, char* ftype, int natoms) {
     if (PyType_Ready(&MolObjectType) < 0)
         return NULL;
     PyTypeObject *type = &MolObjectType;
     MolObject *plugin_c;
+    molfile_plugin_t* plugin = (molfile_plugin_t*) PyMolfileCapsule_AsVoidPtr(molcapsule);   
     plugin_c = (MolObject *)type->tp_alloc(type, 0);
     plugin_c->plugin = plugin;
     plugin_c->file_handle = plugin->open_file_read(fname, ftype, &natoms);
@@ -3497,7 +3442,7 @@ PyObject * my_close_file_read(PyObject* molpack) {
     void* file_handle;
     int numatoms;
     MolObject* plugin_handle = (MolObject*) molpack;
-    plugin = plugin_handle->plugin;
+    plugin = plugin_handle->plugin;   
     file_handle = plugin_handle->file_handle;
     numatoms = plugin_handle->natoms;
     plugin->close_file_read(file_handle); 
@@ -3515,7 +3460,7 @@ SWIGINTERN PyObject *_wrap_molfile_plugin_list(PyObject *SWIGUNUSEDPARM(self), P
   int val1 ;
   int ecode1 = 0 ;
   PyObject * obj0 = 0 ;
-  molfile_plugin_t **result = 0 ;
+  PyObject *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"O:molfile_plugin_list",&obj0)) SWIG_fail;
   ecode1 = SWIG_AsVal_int(obj0, &val1);
@@ -3523,8 +3468,8 @@ SWIGINTERN PyObject *_wrap_molfile_plugin_list(PyObject *SWIGUNUSEDPARM(self), P
     SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "molfile_plugin_list" "', argument " "1"" of type '" "int""'");
   } 
   arg1 = static_cast< int >(val1);
-  result = (molfile_plugin_t **)molfile_plugin_list(arg1);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_p_molfile_plugin_t, 0 |  0 );
+  result = (PyObject *)molfile_plugin_list(arg1);
+  resultobj = result;
   return resultobj;
 fail:
   return NULL;
@@ -3559,29 +3504,23 @@ fail:
 
 SWIGINTERN PyObject *_wrap_get_plugin(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  molfile_plugin_t **arg1 = (molfile_plugin_t **) 0 ;
+  PyObject *arg1 = (PyObject *) 0 ;
   int arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
   int val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
-  molfile_plugin_t *result = 0 ;
+  PyObject *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OO:get_plugin",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_p_molfile_plugin_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "get_plugin" "', argument " "1"" of type '" "molfile_plugin_t **""'"); 
-  }
-  arg1 = reinterpret_cast< molfile_plugin_t ** >(argp1);
+  arg1 = obj0;
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
     SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "get_plugin" "', argument " "2"" of type '" "int""'");
   } 
   arg2 = static_cast< int >(val2);
-  result = (molfile_plugin_t *)get_plugin(arg1,arg2);
-  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_molfile_plugin_t, 0 |  0 );
+  result = (PyObject *)get_plugin(arg1,arg2);
+  resultobj = result;
   return resultobj;
 fail:
   return NULL;
@@ -3590,10 +3529,8 @@ fail:
 
 SWIGINTERN PyObject *_wrap_molfile_plugin_info(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  molfile_plugin_t **arg1 = (molfile_plugin_t **) 0 ;
+  PyObject *arg1 = (PyObject *) 0 ;
   int arg2 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
   int val2 ;
   int ecode2 = 0 ;
   PyObject * obj0 = 0 ;
@@ -3601,20 +3538,13 @@ SWIGINTERN PyObject *_wrap_molfile_plugin_info(PyObject *SWIGUNUSEDPARM(self), P
   PyObject *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OO:molfile_plugin_info",&obj0,&obj1)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_p_molfile_plugin_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "molfile_plugin_info" "', argument " "1"" of type '" "molfile_plugin_t **""'"); 
-  }
-  arg1 = reinterpret_cast< molfile_plugin_t ** >(argp1);
+  arg1 = obj0;
   ecode2 = SWIG_AsVal_int(obj1, &val2);
   if (!SWIG_IsOK(ecode2)) {
     SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "molfile_plugin_info" "', argument " "2"" of type '" "int""'");
   } 
   arg2 = static_cast< int >(val2);
-  {
-    result = (PyObject *)molfile_plugin_info(arg1,arg2);
-    if (PyErr_Occurred()) SWIG_fail;
-  }
+  result = (PyObject *)molfile_plugin_info(arg1,arg2);
   resultobj = result;
   return resultobj;
 fail:
@@ -3624,12 +3554,10 @@ fail:
 
 SWIGINTERN PyObject *_wrap_open_file_read(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
-  molfile_plugin_t *arg1 = (molfile_plugin_t *) 0 ;
+  PyObject *arg1 = (PyObject *) 0 ;
   char *arg2 = (char *) 0 ;
   char *arg3 = (char *) 0 ;
   int arg4 ;
-  void *argp1 = 0 ;
-  int res1 = 0 ;
   int res2 ;
   char *buf2 = 0 ;
   int alloc2 = 0 ;
@@ -3645,11 +3573,7 @@ SWIGINTERN PyObject *_wrap_open_file_read(PyObject *SWIGUNUSEDPARM(self), PyObje
   PyObject *result = 0 ;
   
   if (!PyArg_ParseTuple(args,(char *)"OOOO:open_file_read",&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
-  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_molfile_plugin_t, 0 |  0 );
-  if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "open_file_read" "', argument " "1"" of type '" "molfile_plugin_t *""'"); 
-  }
-  arg1 = reinterpret_cast< molfile_plugin_t * >(argp1);
+  arg1 = obj0;
   res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
   if (!SWIG_IsOK(res2)) {
     SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "open_file_read" "', argument " "2"" of type '" "char *""'");
@@ -3806,12 +3730,12 @@ fail:
 
 static PyMethodDef SwigMethods[] = {
 	 { (char *)"SWIG_PyInstanceMethod_New", (PyCFunction)SWIG_PyInstanceMethod_New, METH_O, NULL},
-	 { (char *)"molfile_plugin_list", _wrap_molfile_plugin_list, METH_VARARGS, (char *)"molfile_plugin_list(maxsize) -> molfile_plugin_t **"},
+	 { (char *)"molfile_plugin_list", _wrap_molfile_plugin_list, METH_VARARGS, (char *)"molfile_plugin_list(maxsize) -> PyObject *"},
 	 { (char *)"molfile_init", _wrap_molfile_init, METH_VARARGS, (char *)"molfile_init() -> int"},
 	 { (char *)"molfile_finish", _wrap_molfile_finish, METH_VARARGS, (char *)"molfile_finish() -> int"},
-	 { (char *)"get_plugin", _wrap_get_plugin, METH_VARARGS, (char *)"get_plugin(plugin_list, plugin_no) -> molfile_plugin_t *"},
-	 { (char *)"molfile_plugin_info", _wrap_molfile_plugin_info, METH_VARARGS, (char *)"molfile_plugin_info(plugin_list, plugin_no) -> PyObject *"},
-	 { (char *)"open_file_read", _wrap_open_file_read, METH_VARARGS, (char *)"open_file_read(plugin, fname, ftype, natoms) -> PyObject *"},
+	 { (char *)"get_plugin", _wrap_get_plugin, METH_VARARGS, (char *)"get_plugin(molcapsule, plug_no) -> PyObject *"},
+	 { (char *)"molfile_plugin_info", _wrap_molfile_plugin_info, METH_VARARGS, (char *)"molfile_plugin_info(molcapsule, plugin_no) -> PyObject *"},
+	 { (char *)"open_file_read", _wrap_open_file_read, METH_VARARGS, (char *)"open_file_read(molcapsule, fname, ftype, natoms) -> PyObject *"},
 	 { (char *)"close_file_read", _wrap_close_file_read, METH_VARARGS, (char *)"close_file_read(molpack) -> PyObject *"},
 	 { (char *)"read_fill_structure", _wrap_read_fill_structure, METH_VARARGS, (char *)"read_fill_structure(molpack, prototype) -> PyObject *"},
 	 { (char *)"read_fill_bonds", _wrap_read_fill_bonds, METH_VARARGS, (char *)"read_fill_bonds(molpack) -> PyObject *"},
@@ -3826,23 +3750,15 @@ static PyMethodDef SwigMethods[] = {
 /* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */
 
 static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_molfile_plugin_t = {"_p_molfile_plugin_t", "molfile_plugin_t *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_p_molfile_plugin_t = {"_p_p_molfile_plugin_t", "molfile_plugin_t **", 0, 0, (void*)0, 0};
 
 static swig_type_info *swig_type_initial[] = {
   &_swigt__p_char,
-  &_swigt__p_molfile_plugin_t,
-  &_swigt__p_p_molfile_plugin_t,
 };
 
 static swig_cast_info _swigc__p_char[] = {  {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_molfile_plugin_t[] = {  {&_swigt__p_molfile_plugin_t, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_p_molfile_plugin_t[] = {  {&_swigt__p_p_molfile_plugin_t, 0, 0, 0},{0, 0, 0, 0}};
 
 static swig_cast_info *swig_cast_initial[] = {
   _swigc__p_char,
-  _swigc__p_molfile_plugin_t,
-  _swigc__p_p_molfile_plugin_t,
 };
 
 
diff --git a/pymolfile/molfile/pymolfile.c b/pymolfile/molfile/pymolfile.c
index f334813e74554d4d367eee2e4b249ba1fb9fd94b..fa2f689ce0c327c9cede5e774b51ebbf6d76e27e 100644
--- a/pymolfile/molfile/pymolfile.c
+++ b/pymolfile/molfile/pymolfile.c
@@ -1,16 +1,14 @@
 /* Hey emacs this is -*- C -*- and this is my editor vim.
  * 
- * molfile.c : C and Fortran interfaces for molfile_plugins
+ * pymolfile.c : C and Python interfaces for molfile_plugins
  * Copyright (c) Berk Onat <b.onat@warwick.ac.uk> 2017
  *
- * This program is under BSD LICENSE
+ * This program is under UIUC Open Source License please see LICENSE file
  */
 
 /*
  * The code is written following the plugin test 
- * context of f77_molfile.c by Axel Kohlmeyer and 
- * in molfile_plugin/src/f77 and catdcd.c by 
- * Justin Gullingsrud of VMD plugins.
+ * context of main.c in molfile_plugin/src/ 
  */
 
 /* Get HAVE_CONFIG_H */
@@ -36,39 +34,44 @@
 int numplugins=0;
 molfile_plugin_t** plugin_list;
 
-/* * * * * * * * * * * * * * * * * * * * * * *
- * Helper functions to set and store plugins *
- * * * * * * * * * * * * * * * * * * * * * * */
-
 #if PY_VERSION_HEX >= 0x03000000
-#define PyInt_AsSsize_t PyLong_AsSsize_t
 #define PyInt_AsLong PyLong_AsLong
-#define PyArray_Check(op) PyObject_TypeCheck(op, &PyArray_Type)
 #define PyString_FromString PyBytes_FromString
-#define PyUString_Check PyUnicode_Check
-#define PyUString_GET_SIZE PyUnicode_GET_SIZE
-#define PyUString_FromFormat PyUnicode_FromFormat
 #define PyInt_FromLong PyLong_FromLong
-#define PyString_Type PyBytes_Type
-#define PyInt_Type PyLong_Type
 
+void del_molfile_plugin_list(PyObject* molcapsule)
+{
+    plugin_list = (molfile_plugin_t**) PyMolfileCapsule_AsVoidPtr(molcapsule);   
+    free(plugin_list); 
+    Py_XDECREF(molcapsule);
+}
 #else
-#define PyBytes_FromString PyString_FromString
+void* del_molfile_plugin_list(void* molcapsule)
+{
+    plugin_list = PyMolfileCapsule_AsVoidPtr((PyObject*)molcapsule);   
+    free(plugin_list); 
+    Py_XDECREF(molcapsule);
+}
 #endif
 
+/* * * * * * * * * * * * * * * * * * * * * * *
+ * Helper functions to set and store plugins *
+ * * * * * * * * * * * * * * * * * * * * * * */
 
-#define NPY_NEXT_ALIGNED_OFFSET(offset, alignment) \
-                (((offset) + (alignment) - 1) & (-(alignment)))
-
-molfile_plugin_t* get_plugin(molfile_plugin_t** plug_list, int plug_no)
+PyObject* get_plugin(PyObject* molcapsule, int plug_no)
 {
     molfile_plugin_t* plugin;
+    molfile_plugin_t** plug_list = (molfile_plugin_t**) PyMolfileCapsule_AsVoidPtr(molcapsule);   
     if(plug_no < 0){
 	plugin = NULL;
     } else {
-	plugin = plug_list[plug_no];
+	if(plug_list != NULL){
+	    plugin = plug_list[plug_no];
+	} else {
+	    plugin = NULL;
+	}
     }
-    return plugin;
+    return PyMolfileCapsule_FromVoidPtr((void *)plugin, NULL);
 }
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * *
@@ -99,13 +102,13 @@ static int molfile_register(void*, vmdplugin_t *plugin) {
         return VMDPLUGIN_SUCCESS;
 }
 
-molfile_plugin_t** molfile_plugin_list(int maxsize)
+PyObject* molfile_plugin_list(int maxsize)
 {
     if(maxsize < MAXPLUGINS){
         maxsize = MAXPLUGINS;
     }
     plugin_list = (molfile_plugin_t**) malloc(sizeof(molfile_plugin_t*)*maxsize);
-    return plugin_list;
+    return PyMolfileCapsule_FromVoidPtr((void *)plugin_list, del_molfile_plugin_list);
 }
 
 /* register all available plugins and clear handles. */
@@ -132,6 +135,57 @@ int molfile_finish(void)
 
 /* Functions in molfile_plugin_t */
 
+PyObject * molfile_plugin_info(PyObject* molcapsule, int plugin_no) {
+    molfile_plugin_t *plugin;
+    molfile_plugin_t** plugin_list = (molfile_plugin_t**) PyMolfileCapsule_AsVoidPtr(molcapsule);   
+    int *plugno = &plugin_no;
+    int has_readstructure = 0;
+    int has_readbonds = 0;
+    int has_readangles = 0;
+    int has_writestructure = 0;
+    int has_writebonds = 0;
+    int has_writeangles = 0;
+    int has_readnexttimestep = 0;
+    int has_writetimestep = 0;
+    int plugin_list_size = sizeof(plugin_list) / sizeof(molfile_plugin_t**);
+    if (plugno==NULL || plugin_no<0){
+      PyErr_Format(PyExc_IOError, "Error: molfile plugin handle no should be given, be positive value and should not exceed the list length'%d'. You set '%d'", plugin_list_size, plugin_no);
+      return 0;
+    }
+    plugin = plugin_list[plugin_no];
+    if(plugin==NULL || !plugin->open_file_read){
+      PyErr_Format(PyExc_IOError, "Error: molfile plugin '%d' is not initialized.", plugin_no);
+      return 0;
+    }
+    if (plugin->read_structure) has_readstructure = 1;
+    if (plugin->read_bonds) has_readbonds = 1;
+    if (plugin->read_angles) has_readangles = 1;
+    if (plugin->read_next_timestep) has_readnexttimestep = 1;
+    if (plugin->write_structure) has_writestructure = 1;
+    if (plugin->write_bonds) has_writebonds = 1;
+    if (plugin->write_angles) has_writeangles = 1;
+    if (plugin->write_timestep) has_writetimestep = 1;
+    PyObject *tuple = PyTuple_New(17);
+    PyTuple_SET_ITEM(tuple, 0, PyString_FromString(plugin->filename_extension));
+    PyTuple_SET_ITEM(tuple, 1, PyString_FromString(plugin->name));
+    PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong((long)has_readstructure));
+    PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong((long)has_readbonds));
+    PyTuple_SET_ITEM(tuple, 4, PyInt_FromLong((long)has_readangles));
+    PyTuple_SET_ITEM(tuple, 5, PyInt_FromLong((long)has_readnexttimestep));
+    PyTuple_SET_ITEM(tuple, 6, PyInt_FromLong((long)has_writestructure));
+    PyTuple_SET_ITEM(tuple, 7, PyInt_FromLong((long)has_writebonds));
+    PyTuple_SET_ITEM(tuple, 8, PyInt_FromLong((long)has_writeangles));
+    PyTuple_SET_ITEM(tuple, 9, PyInt_FromLong((long)has_writetimestep));
+    PyTuple_SET_ITEM(tuple, 10, PyString_FromString(plugin->prettyname));
+    PyTuple_SET_ITEM(tuple, 11, PyString_FromString(plugin->type));
+    PyTuple_SET_ITEM(tuple, 12, PyString_FromString(plugin->author));
+    PyTuple_SET_ITEM(tuple, 13, PyInt_FromLong((long)plugin->majorv));
+    PyTuple_SET_ITEM(tuple, 14, PyInt_FromLong((long)plugin->minorv));
+    PyTuple_SET_ITEM(tuple, 15, PyInt_FromLong((long)plugin->abiversion));
+    PyTuple_SET_ITEM(tuple, 16, PyInt_FromLong((long)plugin->is_reentrant));
+    return tuple;
+}
+
 PyObject* read_fill_structure(PyObject* molpack, PyObject* prototype)
 {
 //    Py_Initialize();
@@ -146,14 +200,14 @@ PyObject* read_fill_structure(PyObject* molpack, PyObject* prototype)
     // Access plugin_handle values
     MolObject* plugin_handle = (MolObject*) molpack;
     if (plugin_handle->plugin) {
-        plugin = plugin_handle->plugin;
-    } else { 
+        plugin = plugin_handle->plugin;   
+    } else {
         PyErr_Format(PyExc_IOError, "molfile plugin is not active.");
 	return NULL;
     } 
     if (plugin_handle->file_handle) {
         file_handle = plugin_handle->file_handle;
-    } else { 
+    } else {
         PyErr_Format(PyExc_IOError, "no file handle in molfile plugin handle.");
 	return NULL; 
     } 
@@ -206,8 +260,18 @@ PyObject* read_fill_bonds(PyObject* molpack)
     PyObject *ret = NULL;
     // Access plugin_handle values
     MolObject* plugin_handle = (MolObject*) molpack;
-    plugin = plugin_handle->plugin;
-    file_handle = plugin_handle->file_handle;
+    if (plugin_handle->plugin) {
+        plugin = plugin_handle->plugin;   
+    } else {
+        PyErr_Format(PyExc_IOError, "molfile plugin is not active.");
+	return NULL;
+    } 
+    if (plugin_handle->file_handle) {
+        file_handle = plugin_handle->file_handle;
+    } else {
+        PyErr_Format(PyExc_IOError, "no file handle in molfile plugin handle.");
+	return NULL; 
+    } 
     numatoms = plugin_handle->natoms;
     if (plugin->read_bonds) {
         int nbonds, *from, *to, *bondtype, nbondtypes;
@@ -290,8 +354,18 @@ PyObject* read_fill_angles(PyObject* molpack)
     PyObject *ret = NULL;
     // Access plugin_handle values
     MolObject* plugin_handle = (MolObject*) molpack;
-    plugin = plugin_handle->plugin;
-    file_handle = plugin_handle->file_handle;
+    if (plugin_handle->plugin) {
+        plugin = plugin_handle->plugin;   
+    } else {
+        PyErr_Format(PyExc_IOError, "molfile plugin is not active.");
+	return NULL;
+    } 
+    if (plugin_handle->file_handle) {
+        file_handle = plugin_handle->file_handle;
+    } else {
+        PyErr_Format(PyExc_IOError, "no file handle in molfile plugin handle.");
+	return NULL; 
+    } 
     numatoms = plugin_handle->natoms;
     // Check if there is read_angles support in this plugin
     if (plugin->read_angles) {
@@ -476,16 +550,16 @@ PyObject* read_fill_next_timestep(PyObject* molpack)
     // Access plugin_handle values
     MolObject* plugin_handle = (MolObject*) molpack;
     if (plugin_handle->plugin) {
-        plugin = plugin_handle->plugin;
-    } else { 
+        plugin = plugin_handle->plugin;   
+    } else {
         PyErr_Format(PyExc_IOError, "molfile plugin is not active.");
-	return NULL; 
+	return NULL;
     } 
     if (plugin_handle->file_handle) {
         file_handle = plugin_handle->file_handle;
-    } else { 
+    } else {
         PyErr_Format(PyExc_IOError, "no file handle in molfile plugin handle.");
-	return NULL;
+	return NULL; 
     } 
     if (plugin_handle->natoms) {
         numatoms = plugin_handle->natoms;
@@ -597,14 +671,14 @@ PyObject* is_plugin_same(PyObject* molpack_a, PyObject* molpack_b)
     MolObject* plugin_handle_a = (MolObject*) molpack_a;
     MolObject* plugin_handle_b = (MolObject*) molpack_b;
     if (plugin_handle_a->plugin) {
-        plugin_a = plugin_handle_a->plugin;
-    } else { 
+        plugin_a = plugin_handle_a->plugin;   
+    } else {
         PyErr_Format(PyExc_IOError, "Arg 1 of the molfile plugin is not active.");
-	return NULL; 
+	return NULL;
     } 
     if (plugin_handle_b->plugin) {
-        plugin_b = plugin_handle_b->plugin;
-    } else { 
+        plugin_b = plugin_handle_b->plugin;   
+    } else {
         PyErr_Format(PyExc_IOError, "Arg 2 of the molfile plugin is not active.");
 	return NULL; 
     } 
@@ -619,18 +693,18 @@ PyObject* is_filehandle_same(PyObject* molpack_a, PyObject* molpack_b)
 {
     MolObject* plugin_handle_a = (MolObject*) molpack_a;
     MolObject* plugin_handle_b = (MolObject*) molpack_b;
-    void* file_handle_a;
-    void* file_handle_b;
+    void* file_handle_a; 
+    void* file_handle_b; 
     if (plugin_handle_a->file_handle) {
-        file_handle_a = plugin_handle_a->file_handle;
-    } else { 
+        file_handle_a = plugin_handle_a->file_handle;   
+    } else {
         PyErr_Format(PyExc_IOError, "no file handle in arg 1 of molfile plugin.");
 	return NULL;
     } 
     if (plugin_handle_b->file_handle) {
-        file_handle_b = plugin_handle_b->file_handle;
-    } else { 
-        PyErr_Format(PyExc_IOError, "no file handle in arg 1 of molfile plugin.");
+        file_handle_b = plugin_handle_b->file_handle;   
+    } else {
+        PyErr_Format(PyExc_IOError, "no file handle in arg 2 of molfile plugin.");
 	return NULL;
     } 
     if(file_handle_a == file_handle_b){
diff --git a/pymolfile/molfile/pymolfile.h b/pymolfile/molfile/pymolfile.h
index 98dbf324bdd1fbc5f74048b68cac8007561eedc7..94a0b42d5dcb259684cb942600e482c97e5ed797 100644
--- a/pymolfile/molfile/pymolfile.h
+++ b/pymolfile/molfile/pymolfile.h
@@ -31,9 +31,6 @@ extern "C"
 #include <numpy/arrayobject.h>
 
 
-//enum { pluginOK, pluginNOINIT, pluginCLOSE, pluginNOMEM, 
-//       pluginENDOFFILE, pluginFILENOTFOUND, pluginFORMATERROR };
-
 #ifndef MAXPLUGINS
 #define MAXPLUGINS 200
 #endif
@@ -46,6 +43,55 @@ struct MolObject {
     MolObject(void) {}
 };
 
+static void * PyMolfileCapsule_AsVoidPtr(PyObject *obj);
+static PyObject * PyMolfileCapsule_FromVoidPtr(void *ptr, void (*data)(PyObject *));
+void del_molfile_plugin_list(PyObject* molcapsule);
+
+#if PY_VERSION_HEX >= 0x03000000
+#define PyInt_AsSsize_t PyLong_AsSsize_t
+//#define PyInt_AsLong PyLong_AsLong
+#define PyArray_Check(op) PyObject_TypeCheck(op, &PyArray_Type)
+//#define PyString_FromString PyBytes_FromString
+#define PyUString_Check PyUnicode_Check
+#define PyUString_GET_SIZE PyUnicode_GET_SIZE
+#define PyUString_FromFormat PyUnicode_FromFormat
+//#define PyInt_FromLong PyLong_FromLong
+#define PyString_Type PyBytes_Type
+#define PyInt_Type PyLong_Type
+
+static void * PyMolfileCapsule_AsVoidPtr(PyObject *obj)
+{
+    void *ret = PyCapsule_GetPointer(obj, NULL);
+    if (ret == NULL) {
+        PyErr_Clear();
+    }   
+    return ret;
+}
+
+static PyObject * PyMolfileCapsule_FromVoidPtr(void *ptr, void (*destr)(PyObject *))
+{
+    PyObject *ret = PyCapsule_New(ptr, NULL, destr);
+    if (ret == NULL) {
+        PyErr_Clear();
+    }
+    return ret;
+}
+
+#else
+#define PyBytes_FromString PyString_FromString
+
+static void * PyMolfileCapsule_AsVoidPtr(PyObject *obj)
+{
+    return PyCObject_AsVoidPtr(obj);
+}
+
+static PyObject * PyMolfileCapsule_FromVoidPtr(void *ptr, void (*destr)(void *))
+{
+    return PyCObject_FromVoidPtr(ptr, destr);
+}
+
+#endif
+
 static void MolObject_dealloc(MolObject* self)
 {
     Py_XDECREF(self->plugin);
@@ -184,16 +230,15 @@ static PyTypeObject MolObjectType = {
     MolObject_new,                 /* tp_new */
 };
 
+PyObject * molfile_plugin_info(PyObject* molcapsule, int plugin_no);
 PyObject * read_fill_structure(PyObject* molpack, PyObject* prototype);
 PyObject * read_fill_bonds(PyObject* molpack);
 PyObject * read_fill_angles(PyObject* molpack);
 PyObject * read_fill_next_timestep(PyObject* molpack);
 PyObject * is_plugin_same(PyObject* molpack_a, PyObject* molpack_b);
 PyObject * is_filehandle_same(PyObject* molpack_a, PyObject* molpack_b);
-
-molfile_plugin_t* get_plugin(molfile_plugin_t** plug_list, int plug_no);
-
-molfile_plugin_t** molfile_plugin_list(int maxsize);
+PyObject * get_plugin(PyObject* molcapsule, int plug_no);
+PyObject * molfile_plugin_list(int maxsize);
 
 int molfile_init(void);
 
diff --git a/pymolfile/pymolfile.py b/pymolfile/pymolfile.py
index 8902abaa5629d35f9bad7c4d2cb5f5d65a955243..b96887b61467d291b7a59818c779864098ea0ce0 100644
--- a/pymolfile/pymolfile.py
+++ b/pymolfile/pymolfile.py
@@ -47,28 +47,11 @@ def plugins():
              capabilities of each molfile plugin. The information is 
              extracted from molfile_plugin_t. 
     """
-    max_num_plugins = 200
-    c_list = libpymolfile.molfile_plugin_list(max_num_plugins)
     numlist = libpymolfile.molfile_init()
-    plugins_list = [libpymolfile.molfile_plugin_info(c_list, i) for i in range(numlist)]
+    plugins_list = [libpymolfile.molfile_plugin_info(C_MOLFILE_PLUGINS, i) for i in range(numlist)]
     libpymolfile.molfile_finish()
     return plugins_list
 
-def open(file_name_with_path, topology=None, 
-         file_format=None, topology_format=None, 
-         plugin=None, topology_plugin=None):
-    """ The main function to read topology and 
-        trajectory files
-
-        Returns: Depends on the file format and arguments:
-                 If structure file is supplied, it returns topology class.
-                 If only trajectory file is supplied, it returns trajectory class 
-                     without topology information. (the number of atoms must be known)
-                 If both files are supplied, it returns trajectory class with 
-                     topology information.
-    """
-    pass
-
 def get_dir_base_extension(file_name):
     """ Splits directory, file base and file extensions
 
@@ -115,6 +98,13 @@ def get_plugin_with_ext(file_ext):
 
     return None
 
+def plugins_same(plugin_one, plugin_two):
+    if((plugin_one[1] == plugin_two[1]) and 
+       (plugin_one[2][2] == plugin_two[2][2])):
+        return True
+    else:
+        return False
+
 def get_plugin_with_name(plugin_name):
     """ Search molfile plugins list and returns the plugin info 
         for the first matching name in plugin name field.
@@ -135,54 +125,197 @@ def get_plugin_with_name(plugin_name):
 
 class Topology( object ):
 
-    self.structure = None
-    self.bonds = None
-    self.angles = None
-
     def __init__(self):
+        self.natoms = None
+        self.structure = None
+        self.bonds = None
+        self.angles = None
+
+    def __del__( self ):
         pass
 
 class Trajectory( object ):
     
-    self.atoms = None
+    def __init__(self, file_name, file_format, plugin, natoms):
+        self.natoms = None
+        self.atoms = None
+        self.plugin = None
+        self.fname = None
+        self.ftype = None
+        self.fname = file_name
+        self.ftype = file_format
+        self.plugin = plugin
+        self.natoms = natoms
 
-    def __init__(self):
-        pass
-
-    def get_frame(self, index):
-    
     def iread(self, chunk=None):
+        numlist = libpymolfile.molfile_init()
+        tplugin = libpymolfile.get_plugin(C_MOLFILE_PLUGINS, 
+                                          self.plugin[1])
+        pluginhandle = libpymolfile.open_file_read(tplugin, 
+            file_name, file_format, natoms)
+
+        step=0
+        while True:
+            try:
+                x = libpymolfile.read_fill_next_timestep(
+                        pluginhandle)
+                if x is None:
+                    break
+                step=step+1
+                if x is not None:
+                    self.atoms = x
+                    yield x
+            except (AttributeError,OSError):
+                pass
+
+        libpymolfile.close_file_read(pluginhandle)
+        libpymolfile.molfile_finish()
+
+#    def read_frame(self, index_no):
+#        numlist = libpymolfile.molfile_init()
+#        tplugin = libpymolfile.get_plugin(C_MOLFILE_PLUGINS, 
+#                                          self.plugin[1])
+#        pluginhandle = libpymolfile.open_file_read(tplugin, 
+#            file_name, file_format, natoms)
+#        libpymolfile.molfile_finish()
+
+#    def read(self, index_list, chunk=None):
+#        numlist = libpymolfile.molfile_init()
+#        tplugin = libpymolfile.get_plugin(C_MOLFILE_PLUGINS, 
+#                                          self.plugin[1])
+#        pluginhandle = libpymolfile.open_file_read(tplugin, 
+#            file_name, file_format, natoms)
+#        libpymolfile.molfile_finish()
 
-    def read(self, index, chunk=None):
-
-    def __del__(self):
+    def __del__( self ):
         pass
 
 class Molfile(object):
 
-    self.plugin_list = MOLFILE_PLUGINS
-    self.trajectory = None
-    self.topology = None
-    self.fplugin = None
-    self.tplugin = None
-    self.fmolobject = None
-    self.tmolobject = None
-    self.kwords = { 
-        "file_format" : None,
-        "file_plugin" : None,
-        "topology" : None,
-        "topology_format" : None,
-        "topology_plugin" : None,
-        "natoms" : None
-        }
-
     def __init__(self, file_name, **kwargs):
-        pass
+        self.plugin_list = MOLFILE_PLUGINS
+        self.c_plugin_list = C_MOLFILE_PLUGINS
+        self.trajectory = None
+        self.topology = None
+        self.fplugin = None
+        self.tplugin = None
+        self.smolplugin = None
+        self.cmolplugin = None
+        self.kwords = { 
+            "file_format" : None,
+            "file_plugin" : None,
+            "topology" : None,
+            "topology_format" : None,
+            "topology_plugin" : None,
+            "natoms" : None
+            }
+
+        if not C_MOLFILE_PLUGINS:
+            C_MOLFILE_PLUGINS = libpymolfile.molfile_plugin_list(MAX_NUM_PLUGINS)
+        if not MOLFILE_PLUGINS:
+            MOLFILE_PLUGINS = plugins()
+        if(MOLFILE_PLUGINS and self.plugin_list is None):
+            self.plugin_list = MOLFILE_PLUGINS
+        if(C_MOLFILE_PLUGINS and self.c_plugin_list is None):
+            self.c_plugin_list = C_MOLFILE_PLUGINS
 
     def __del__( self ):
         pass
 
+def read_topology(self, file_name, file_format, plugin):
+    """ Reads structure, bonds, angles, dihedrals, impropers and 
+        additional informations through molfile_plugin if the 
+        data is available
+     
+        The topology data in pymolfile is a list of tuples that include
+        the following fields:
+            (name, type, resname, resid, segid, chain, altloc, insertion, 
+             occupancy, bfactor, mass, charge, radius, atomicnumber)
+            
+        The data types are as follows in the tuple:
+            s = string, i = integer, f = float
+            (s, s, s, i, s, s, s, s, f, f, f, f, f, i)
+
+        Returns: Topology class if at least one of the topology
+                 data is available. If non of the data is accessible,
+                 function returns None
+    """
+    topo = None
+    if(file_name is not None and
+       file_format is not None and 
+       plugin is not None):
+        natoms=0
+        pluginhandle = libpymolfile.open_file_read(plugin, 
+                file_name, file_format, natoms)
+        natoms = pluginhandle.natoms
+        #if 0 && vmdplugin_ABIVERSION > 17
+        #  /* The new PDB file formats allows for much larger structures, */
+        #  /* which can therefore require longer chain ID strings.  The   */
+        #  /* new PDBx/mmCIF file formats do not have length limits on    */
+        #  /* fields, so PDB chains could be arbitrarily long strings     */
+        #  /* in such files.  At present, we know we need at least 3-char */
+        #  /* chains for existing PDBx/mmCIF files.                       */
+        #  char chain[4];      /**< required chain name, or ""            */
+        #else
+        #  char chain[2];      /**< required chain name, or ""            */
+        #endif
+        #
+        # Change 'chain', 'S4' to S2 for PDB
+        #
+        if 'pdb' in file_format:
+            chain_size = 'S2'
+        else:
+            chain_size = 'S4'
+        prototype = numpy.array([
+            ('C1','C','ACE',0,'','','','',1.0,1.0,1.0,1.0,1.0,6), 
+            ('C2','C','ACE',0,'','','','',1.0,1.0,1.0,1.0,1.0,6)
+            ],
+            dtype=[
+                ('name', 'S16'), ('type', 'S16'), ('resname', 'S8'),
+                ('resid', 'i4'), ('segid', 'S8'), ('chain', chain_size),
+                ('altloc', 'S2'), ('insertion', 'S2'), ('occupancy', 'f4'),
+                ('bfactor', 'f4'), ('mass', 'f4'), ('charge', 'f4'),
+                ('radius', 'f4'), ('atomicnumber', 'i4')
+                ]
+            )
+        structure = libpymolfile.read_fill_structure(pluginhandle, prototype)
+        try:
+            bonds = libpymolfile.read_fill_bonds(pluginhandle)
+        except (AttributeError, SystemError):
+            pass
+
+        try:
+            angles = libpymolfile.read_fill_angles(pluginhandle)
+        except (AttributeError, SystemError):
+            pass
+
+        if structure:
+            topo = Topology()
+            topo.natoms = natoms
+            topo.structure = structure
+            if bonds:
+                topo.bonds = bonds
+            if angles:
+                topo.angles = angles
+
+        libpymolfile.close_file_read(pluginhandle)
+
+    if topo:
+        return topo
+    else:
+        return None
+
 class OpenMolfile(Molfile):
+    """ The main class/function to read topology and 
+        trajectory files
+
+        Returns: Depends on the file format and arguments:
+                 If structure file is supplied, it returns topology class.
+                 If only trajectory file is supplied, it returns trajectory class 
+                     without topology information. (the number of atoms must be known)
+                 If both files are supplied, it returns trajectory class with 
+                     topology information.
+    """
 
     def __init__(self, file_name, **kwargs):
         if kwargs:
@@ -206,6 +339,8 @@ class OpenMolfile(Molfile):
                 if plugin_item:
                     self.fplugin = plugin_item
                     self.kwords["file_plugin"] = plugin_item[2][2]
+                else:
+                    self.kwords["file_plugin"] = None
 
             if self.kwords["file_plugin"]:
                 # Check if file_plugin reads structure info 
@@ -214,34 +349,78 @@ class OpenMolfile(Molfile):
                     # Topology may be read with the plugin.
                     # This will override topology information 
                     # if a 'topology' is supplied in keywords.
-                else:
+                    if self.kwords["file_format"] is not None:
+                        numlist = libpymolfile.molfile_init()
+                        self.smolplugin = libpymolfile.get_plugin(C_MOLFILE_PLUGINS, 
+                                                                  self.fplugin[1])
+                        self.topology = read_topology(file_name, 
+                                                      self.kwords["file_format"], 
+                                                      self.smolplugin)
+                        libpymolfile.molfile_finish()
+
+                if self.fplugin[2][3] == 0:
                     # Topology can not be read with plugin from 
                     # the file. If 'topology' is not set but 'natoms' 
-                    # is only the trajectory will be available.
-
-
-
-
-
-
-
-                c_list = libpymolfile.molfile_plugin_list(max_num_plugins)
-                numlist = libpymolfile.molfile_init()
-                self.cmolobject = libpymolfile.get_plugin(MOLFILE_PLUGINS, 83) #trr
-
-
-
-            return self
-        else:
-            return None
-
-
-
-
-
-
-
-
-
+                    # is set, only the trajectory will be available.
+                    if self.kwords["topology"] is not None:
+                        if isinstance(self.kwords["topology"], Molfile):
+                            self.topology = self.kwords["topology"].topology
+                        elif isinstance(elf.kwords["topology"], Topology):
+                            self.topology = self.kwords["topology"]
+                        else:
+                            if self.kwords["topology_format"] is None:
+                               topo_file_dir, topo_file_base, topo_file_ext = get_dir_base_extension(
+                                       self.kwords["topology"])
+                               if topo_file_ext:
+                                   self.kwords["topology_format"] = topo_file_ext
+                               else:
+                                   self.kwords["topology_format"] = topo_file_base
+
+                            if self.kwords["topology_plugin"] is None:
+                                self.kwords["topology_plugin"] = "auto"
+
+                            if "auto" in self.kwords["topology_plugin"]:
+                                topo_plugin_item = get_plugin_with_ext(self.kwords["topology_format"])
+                                if topo_plugin_item:
+                                    self.tplugin = topo_plugin_item
+                                    self.kwords["topology_plugin"] = topo_plugin_item[2][2]
+                                else:
+                                    self.kwords["topology_plugin"] = None
+
+                            if self.kwords["topology_plugin"]:
+                            # Check if topology_plugin reads structure info 
+                            # for the given file format.
+                                if self.tplugin[2][3] == 1:
+                                # Topology may be read with the plugin.
+                                # This will override the topology information. 
+                                    if self.kwords["topology_format"] is not None:
+                                        numlist = libpymolfile.molfile_init()
+                                        self.smolplugin = libpymolfile.get_plugin(C_MOLFILE_PLUGINS, 
+                                                                                  self.fplugin[1])
+                                        self.topology = read_topology(file_name, 
+                                                                      self.kwords["topology_format"], 
+                                                                      self.smolplugin)
+                                        libpymolfile.molfile_finish()
+                            else:
+                                print("Pymolfile can not determine the {0} file format " + 
+                                      "of the file {1}" % (self.kwords["topology_format"], 
+                                      topo_file_base + "." + topo_file_ext))
+
+                    if(self.fplugin[2][6] == 1):
+                        num_atoms = 0
+                        if self.topology:
+                            num_atoms = self.topology.natoms
+                        elif natoms is not None:
+                            num_atoms = natoms
+                        # Trajectory can be read if num_atoms is set
+                        if num_atoms>0:
+                            self.trajectory = Trajectory(file_name,
+                                    self.kwords["file_format"],
+                                    self.kwords["file_plugin"],
+                                    num_atoms)
+            else:
+                print("Pymolfile can not determine the {0} file format " + 
+                      "of the file {1}" % (self.kwords["file_format"], 
+                      file_base + "." + file_ext))
 
 
diff --git a/pymolfile/test.py b/pymolfile/test.py
index c081c3845eb113a85432766127def8062bf51bc6..35fb3d9cfb303bc5ded90f2ca018938d5d82bc26 100644
--- a/pymolfile/test.py
+++ b/pymolfile/test.py
@@ -1,131 +1,20 @@
 import numpy
-import molfile.libpymolfile as pym
+import pymolfile as pym
 
-mylist  = pym.molfile_plugin_list(200)
-numlist = pym.molfile_init()
-print(numlist)
-for i in range(numlist):
-    testplugin = pym.molfile_plugin_info(mylist, i)
-    print(i, testplugin)
-
-#splugin = pym.get_plugin(mylist, 99) #pdb
-cplugin = pym.get_plugin(mylist, 83) #trr
-#cplugin = pym.get_plugin(mylist, 85) #xtc
-#splugin = pym.get_plugin(mylist, 105) #psf
-splugin = pym.get_plugin(mylist, 81) #gro
-#cplugin = pym.get_plugin(mylist, 69) #dcd
-#cplugin = pym.get_plugin(mylist, 126) #nc
-print(splugin)
-print(cplugin)
-natoms=0
-#sfname="../test/DPDP.pdb"
-#cfname="../test/DPDP.nc"
+sfname="../test/DPDP.pdb"
+cfname="../test/DPDP.nc"
 
 #sfname="../test/ala3.pdb"
 #sfname="../test/ala3.psf"
 #cfname="../test/ala3.dcd"
 
-sfname="../test/md.gro"
-cfname="../test/md.trr"
+#sfname="../test/md.gro"
+#cfname="../test/md.trr"
 #cfname="../test/md.xtc"
 
 #sfname="../test/md_1u19.gro"
 #cfname="../test/md_1u19.xtc"
 
-#sftype="pdb"
-cftype="trr"
-#cftype="xtc"
-#sftype="psf"
-sftype="gro"
-#cftype="dcd"
-#cftype="nc"
-
-print("Structure plugin:")
-spluginhandle = pym.open_file_read(splugin, sfname, sftype, natoms)
-print("Coordinate plugin:")
-cpluginhandle = pym.open_file_read(cplugin, cfname, cftype, natoms)
-print(cpluginhandle)
-print(cpluginhandle.natoms)
-print(spluginhandle)
-print(spluginhandle.natoms)
-if cpluginhandle.natoms != spluginhandle.natoms:
-    print("Number of atoms do not match in structure and coordinate files.")
-    
-
-if pym.is_plugin_same(spluginhandle, cpluginhandle):
-    pym.close_file_read(cpluginhandle)
-    cpluginhandle = spluginhandle
-
-#if 0 && vmdplugin_ABIVERSION > 17
-#  /* The new PDB file formats allows for much larger structures, */
-#  /* which can therefore require longer chain ID strings.  The   */
-#  /* new PDBx/mmCIF file formats do not have length limits on    */
-#  /* fields, so PDB chains could be arbitrarily long strings     */
-#  /* in such files.  At present, we know we need at least 3-char */
-#  /* chains for existing PDBx/mmCIF files.                       */
-#  char chain[4];      /**< required chain name, or ""            */
-#else
-#  char chain[2];      /**< required chain name, or ""            */
-#endif
-# Change 'chain', 'S4' to S2 for PDB
-if 'pdb' in [sftype, cftype]:
-    print("file chain is set to S2")
-    chain_size = 'S2'
-else:
-    chain_size = 'S4'
-x = numpy.array([
-    ('C1','C','ACE',0,'','','','',1.0,1.0,1.0,1.0,1.0,6), 
-    ('C2','C','ACE',0,'','','','',1.0,1.0,1.0,1.0,1.0,6)
-    ],
-    dtype=[
-        ('name', 'S16'), ('type', 'S16'), ('resname', 'S8'),
-        ('resid', 'i4'), ('segid', 'S8'), ('chain', chain_size),
-        ('altloc', 'S2'), ('insertion', 'S2'), ('occupancy', 'f4'),
-        ('bfactor', 'f4'), ('mass', 'f4'), ('charge', 'f4'),
-        ('radius', 'f4'), ('atomicnumber', 'i4')
-        ]
-    )
-y = pym.read_fill_structure(spluginhandle, x)
-print(y)
-if y is not None:
-    print(len(y))
-
-try:
-    z = pym.read_fill_bonds(spluginhandle)
-    print(z)
-    if z is not None:
-        print(len(z))
-except (AttributeError, SystemError):
-    pass
-
-try:
-    a = pym.read_fill_angles(spluginhandle)
-    print(a)
-    if a is not None:
-        print(len(a))
-except (AttributeError, SystemError):
-    pass
-
-if pym.is_plugin_same(spluginhandle, cpluginhandle):
-    pass
-else:
-    pym.close_file_read(spluginhandle)
-
-#step=0
-#while True:
-#    try:
-#        c = pym.read_fill_next_timestep(cpluginhandle)
-#        if c is None:
-#            break
-#        step=step+1
-#        print("Step:",step)
-#        print(c)
-#        if c["coords"] is not None:
-#            print(len(c["coords"]))
-#    except (AttributeError,OSError):
-#        pass
-
-pym.close_file_read(cpluginhandle)
-pym.molfile_finish()
-
+molfile = pym.OpenMolfile(sfname)
+print(molfile)
 
diff --git a/pymolfile/test_libpymolfile.py b/pymolfile/test_libpymolfile.py
new file mode 100644
index 0000000000000000000000000000000000000000..59d978e27129152aa349c63f7f60354467f772c1
--- /dev/null
+++ b/pymolfile/test_libpymolfile.py
@@ -0,0 +1,133 @@
+import numpy
+import molfile.libpymolfile as pym
+
+mylist  = pym.molfile_plugin_list(200)
+print(mylist)
+numlist = pym.molfile_init()
+print(numlist)
+for i in range(numlist):
+    testplugin = pym.molfile_plugin_info(mylist, i)
+    print(i, testplugin)
+
+splugin = pym.get_plugin(mylist, 99) #pdb
+#cplugin = pym.get_plugin(mylist, 83) #trr
+#cplugin = pym.get_plugin(mylist, 85) #xtc
+#splugin = pym.get_plugin(mylist, 105) #psf
+#splugin = pym.get_plugin(mylist, 81) #gro
+#cplugin = pym.get_plugin(mylist, 69) #dcd
+cplugin = pym.get_plugin(mylist, 126) #nc
+print(splugin)
+print(cplugin)
+natoms=0
+sfname="../test/DPDP.pdb"
+cfname="../test/DPDP.nc"
+
+#sfname="../test/ala3.pdb"
+#sfname="../test/ala3.psf"
+#cfname="../test/ala3.dcd"
+
+#sfname="../test/md.gro"
+#cfname="../test/md.trr"
+#cfname="../test/md.xtc"
+
+#sfname="../test/md_1u19.gro"
+#cfname="../test/md_1u19.xtc"
+
+sftype="pdb"
+#cftype="trr"
+#cftype="xtc"
+#sftype="psf"
+#sftype="gro"
+#cftype="dcd"
+cftype="nc"
+
+print("Structure plugin:")
+spluginhandle = pym.open_file_read(splugin, sfname, sftype, natoms)
+print("Coordinate plugin:")
+cpluginhandle = pym.open_file_read(cplugin, cfname, cftype, natoms)
+print(cpluginhandle)
+print(cpluginhandle.natoms)
+print(spluginhandle)
+print(spluginhandle.natoms)
+if cpluginhandle.natoms != spluginhandle.natoms:
+    print("Number of atoms do not match in structure and coordinate files.")
+    
+
+if pym.is_plugin_same(spluginhandle, cpluginhandle):
+    pym.close_file_read(cpluginhandle)
+    cpluginhandle = spluginhandle
+
+#if 0 && vmdplugin_ABIVERSION > 17
+#  /* The new PDB file formats allows for much larger structures, */
+#  /* which can therefore require longer chain ID strings.  The   */
+#  /* new PDBx/mmCIF file formats do not have length limits on    */
+#  /* fields, so PDB chains could be arbitrarily long strings     */
+#  /* in such files.  At present, we know we need at least 3-char */
+#  /* chains for existing PDBx/mmCIF files.                       */
+#  char chain[4];      /**< required chain name, or ""            */
+#else
+#  char chain[2];      /**< required chain name, or ""            */
+#endif
+# Change 'chain', 'S4' to S2 for PDB
+if 'pdb' in [sftype, cftype]:
+    print("file chain is set to S2")
+    chain_size = 'S2'
+else:
+    chain_size = 'S4'
+x = numpy.array([
+    ('C1','C','ACE',0,'','','','',1.0,1.0,1.0,1.0,1.0,6), 
+    ('C2','C','ACE',0,'','','','',1.0,1.0,1.0,1.0,1.0,6)
+    ],
+    dtype=[
+        ('name', 'S16'), ('type', 'S16'), ('resname', 'S8'),
+        ('resid', 'i4'), ('segid', 'S8'), ('chain', chain_size),
+        ('altloc', 'S2'), ('insertion', 'S2'), ('occupancy', 'f4'),
+        ('bfactor', 'f4'), ('mass', 'f4'), ('charge', 'f4'),
+        ('radius', 'f4'), ('atomicnumber', 'i4')
+        ]
+    )
+y = pym.read_fill_structure(spluginhandle, x)
+if y is not None:
+    print(y)
+    print(len(y))
+
+try:
+    z = pym.read_fill_bonds(spluginhandle)
+    if z is not None:
+        print(z)
+        print(len(z))
+except (AttributeError, SystemError):
+    pass
+
+try:
+    a = pym.read_fill_angles(spluginhandle)
+    if a is not None:
+        print(a)
+        print(len(a))
+except (AttributeError, SystemError):
+    pass
+
+if pym.is_plugin_same(spluginhandle, cpluginhandle):
+    pass
+else:
+    pym.close_file_read(spluginhandle)
+
+step=0
+while True:
+#while False:
+    try:
+        c = pym.read_fill_next_timestep(cpluginhandle)
+        if c is None:
+            break
+        step=step+1
+        print("Step:",step)
+        print(c)
+        if c["coords"] is not None:
+            print(len(c["coords"]))
+    except (AttributeError,OSError):
+        pass
+
+pym.close_file_read(cpluginhandle)
+pym.molfile_finish()
+
+