diff --git a/configure.ac b/configure.ac
index a86dd74fc..84d990cfb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -183,6 +183,7 @@ src/plugins/io_msi/Makefile
src/plugins/io_pdb/Makefile
src/plugins/io_rmcprofile/Makefile
src/plugins/io_sybylmol2/Makefile
+src/plugins/io_test/Makefile
src/plugins/io_vfield/Makefile
src/plugins/io_xyz/Makefile
src/plugins/method_mopac71/Makefile
diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt
index 8df274b58..a800cad84 100644
--- a/src/plugins/CMakeLists.txt
+++ b/src/plugins/CMakeLists.txt
@@ -33,6 +33,7 @@ add_subdirectory(io_pdb)
add_subdirectory(io_rmcprofile)
#add_subdirectory(io_siesta)
add_subdirectory(io_sybylmol2)
+add_subdirectory(io_test)
add_subdirectory(io_vfield)
add_subdirectory(io_xyz)
add_subdirectory(method_mopac71)
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 393251311..8e02e2aa4 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -1,5 +1,5 @@
SUBDIRS = interfaces
-SUBDIRS += io_akf io_chemshell io_cif io_cube io_dlpoly io_dlputils io_epsr io_ff io_gamessus io_gromacs io_mdlmol io_mopac io_msi io_pdb io_rmcprofile io_sybylmol2 io_vfield io_xyz
+SUBDIRS += io_akf io_chemshell io_cif io_cube io_dlpoly io_dlputils io_epsr io_ff io_gamessus io_gromacs io_mdlmol io_mopac io_msi io_pdb io_rmcprofile io_sybylmol2 io_test io_vfield io_xyz
#SUBDIRS += io_csd io_espresso io_gaussian io_siesta
SUBDIRS += method_mopac71
SUBDIRS += tool_rings tool_test
diff --git a/src/plugins/io_test/CMakeLists.txt b/src/plugins/io_test/CMakeLists.txt
new file mode 100644
index 000000000..ff1d2e11f
--- /dev/null
+++ b/src/plugins/io_test/CMakeLists.txt
@@ -0,0 +1,30 @@
+# Meta-Objects
+set(xyztest_MOC_HDRS
+ xyztest.h
+)
+QT5_WRAP_CPP(xyztest_MOC_SRCS ${xyztest_MOC_HDRS} OPTIONS -I${PROJECT_SOURCE_DIR}/src)
+
+add_library(xyztest MODULE
+ xyztest_funcs.cpp
+ ${xyztest_MOC_SRCS}
+)
+set_target_properties(xyztest PROPERTIES
+ LIBRARY_OUTPUT_DIRECTORY ${Aten_BINARY_DIR}/data/plugins
+ COMPILE_DEFINITIONS "QT_PLUGIN"
+ PREFIX ""
+)
+
+if(UNIX AND NOT APPLE)
+install(TARGETS xyztest
+ RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}/aten/plugins COMPONENT RuntimePlugins
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/aten/plugins COMPONENT RuntimePlugins
+)
+endif(UNIX AND NOT APPLE)
+
+target_include_directories(xyztest PRIVATE
+ ${PROJECT_SOURCE_DIR}/src
+ ${PROJECT_BINARY_DIR}/src
+ ${Qt5Core_INCLUDE_DIRS}
+ ${Qt5Gui_INCLUDE_DIRS}
+)
+
diff --git a/src/plugins/io_test/Makefile.am b/src/plugins/io_test/Makefile.am
new file mode 100644
index 000000000..14f4fac91
--- /dev/null
+++ b/src/plugins/io_test/Makefile.am
@@ -0,0 +1,16 @@
+pluginexecdir = ${pkglibdir}/plugins
+pluginexec_LTLIBRARIES = xyztest.la
+
+# Rules
+.hui.lo:
+ ${QTMOC} -o $*.cpp -I../../ @ATEN_INCLUDES@ $<
+ ${LIBTOOL} --tag=CXX --mode=compile $(CXX) -I$(top_srcdir)/src -I../ -I./ ${AM_CPPFLAGS} -c $*.cpp -o $@
+ rm $*.cpp
+
+clean-local:
+ -rm -f xyztest.cpp
+
+xyztest_la_SOURCES = xyztest.hui xyztest_funcs.cpp
+xyztest_la_LDFLAGS = -module -shared -avoid-version
+
+AM_CPPFLAGS = -I${top_srcdir}/src @ATEN_INCLUDES@ @ATEN_CFLAGS@
diff --git a/src/plugins/io_test/xyztest.hui b/src/plugins/io_test/xyztest.hui
new file mode 100644
index 000000000..bf64fae20
--- /dev/null
+++ b/src/plugins/io_test/xyztest.hui
@@ -0,0 +1,114 @@
+/*
+ *** Simple XYZ Plugin
+ *** src/plugins/io_test/xyztest.hui
+ Copyright T. Youngs 2016-2016
+
+ This file is part of Aten.
+
+ Aten is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Aten is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Aten. If not, see .
+*/
+
+#ifndef ATEN_TESTXYZPLUGIN_H
+#define ATEN_TESTXYZPLUGIN_H
+
+#include "plugins/interfaces/fileplugin.h"
+
+ATEN_BEGIN_NAMESPACE
+
+// Forward Declarations
+/* none */
+
+// XYZ Model Import / Export Plugin
+class TestModelPlugin : public QObject, public FilePluginInterface
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "com.projectaten.Aten.FilePluginInterface.v1")
+ Q_INTERFACES(AtenSpace::FilePluginInterface)
+
+
+ /*
+ * Core
+ */
+ public:
+ // Constructor
+ TestModelPlugin();
+ // Destructor
+ ~TestModelPlugin();
+
+
+ /*
+ * Instance Handling
+ */
+ private:
+ // Return a copy of the plugin object
+ BasePluginInterface* makeCopy() const;
+
+
+ /*
+ * Definition
+ */
+ public:
+ // Return type of plugin
+ PluginTypes::PluginType type() const;
+ // Return category of plugin
+ int category() const;
+ // Return name of plugin
+ QString name() const;
+ // Return nickname of plugin
+ QString nickname() const;
+ // Return whether the plugin is enabled
+ bool enabled() const;
+ // Return description (long name) of plugin
+ QString description() const;
+ // Return related file extensions
+ QStringList extensions() const;
+ // Return exact names
+ QStringList exactNames() const;
+
+
+ /*
+ * Input / Output
+ */
+ public:
+ // Return whether this plugin can import data
+ bool canImport() const;
+ // Import data via the supplied parser
+ bool importData();
+ // Return whether this plugin can export data
+ bool canExport() const;
+ // Export data via the supplied parser
+ bool exportData();
+ // Import next partial data chunk
+ bool importNextPart();
+ // Skip next partial data chunk
+ bool skipNextPart();
+
+
+ /*
+ * Options
+ */
+ public:
+ // Return whether the plugin has import options
+ bool hasImportOptions() const;
+ // Show import options dialog
+ bool showImportOptionsDialog(KVMap& targetOptions) const;
+ // Return whether the plugin has export options
+ bool hasExportOptions() const;
+ // Show export options dialog
+ bool showExportOptionsDialog(KVMap& targetOptions) const;
+};
+
+ATEN_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/io_test/xyztest_funcs.cpp b/src/plugins/io_test/xyztest_funcs.cpp
new file mode 100644
index 000000000..5d6220ebf
--- /dev/null
+++ b/src/plugins/io_test/xyztest_funcs.cpp
@@ -0,0 +1,207 @@
+/*
+ *** Simple XYZ Plugin Functions
+ *** src/plugins/io_test/xyztest_funcs.cpp
+ Copyright T. Youngs 2016-2016
+
+ This file is part of Aten.
+
+ Aten is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Aten is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Aten. If not, see .
+*/
+
+#include "plugins/io_test/xyztest.hui"
+#include "model/model.h"
+
+// Constructor
+TestModelPlugin::TestModelPlugin()
+{
+}
+
+// Destructor
+TestModelPlugin::~TestModelPlugin()
+{
+}
+
+/*
+ * Instance Handling
+ */
+
+// Return a copy of the plugin object
+BasePluginInterface* TestModelPlugin::makeCopy() const
+{
+ return new TestModelPlugin;
+}
+
+/*
+ * Definition
+ */
+
+// Return type of plugin
+PluginTypes::PluginType TestModelPlugin::type() const
+{
+ return PluginTypes::FilePlugin;
+}
+
+// Return category of plugin
+int TestModelPlugin::category() const
+{
+ return PluginTypes::ModelFilePlugin;
+}
+
+// Name of plugin
+QString TestModelPlugin::name() const
+{
+ return QString("XYZ Files (XMol Style) (Test)");
+}
+
+// Nickname of plugin
+QString TestModelPlugin::nickname() const
+{
+ return QString("xyz");
+}
+
+// Return whether the plugin is enabled
+bool TestModelPlugin::enabled() const
+{
+ return false;
+}
+
+// Description (long name) of plugin
+QString TestModelPlugin::description() const
+{
+ return QString("Import/export for XMol-style XYZ coordinate files (Test)");
+}
+
+// Related file extensions
+QStringList TestModelPlugin::extensions() const
+{
+ return QStringList() << "xyz";
+}
+
+// Exact names
+QStringList TestModelPlugin::exactNames() const
+{
+ return QStringList();
+}
+
+/*
+ * Input / Output
+ */
+
+// Return whether this plugin can import data
+bool TestModelPlugin::canImport() const
+{
+ return true;
+}
+
+// Import data from the specified file
+bool TestModelPlugin::importData()
+{
+ int nAtoms, n;
+ QString e, name;
+ Vec3 r;
+
+ // Read data
+ while (!fileParser_.eofOrBlank())
+ {
+ // Read number of atoms from file
+ if (!fileParser_.readLineAsInteger(nAtoms)) return false;
+
+ // Next line is name of model
+ if (!fileParser_.readLine(name)) return false;
+
+ // Create a new model now....
+ createModel();
+ targetModel()->setName(name);
+
+ // Load atoms for model
+ for (n=0; naddAtom(ElementMap().find(fileParser_.argc(0)), r);
+ }
+
+ // Rebond the model
+ targetModel()->calculateBonding(true);
+ }
+
+ return true;
+}
+
+// Return whether this plugin can export data
+bool TestModelPlugin::canExport() const
+{
+ return true;
+}
+
+// Export data to the specified file
+bool TestModelPlugin::exportData()
+{
+ // Write number atoms line
+ fileParser_.writeLineF("%i", targetModel()->nAtoms());
+
+ // Write title line
+ fileParser_.writeLine(targetModel()->name());
+
+ // Write atom information
+ for (Atom* i = targetModel()->atoms(); i != NULL; i = i->next)
+ {
+ fileParser_.writeLineF("%-8s %12.6f %12.6f %12.6f %12.6f", ElementMap().symbol(i->element()), i->r().x, i->r().y, i->r().z, i->charge());
+ }
+
+ return true;
+}
+
+// Import next partial data chunk
+bool TestModelPlugin::importNextPart()
+{
+ return false;
+}
+
+// Skip next partial data chunk
+bool TestModelPlugin::skipNextPart()
+{
+ return false;
+}
+
+
+/*
+ * Options
+ */
+
+// Return whether the plugin has import options
+bool TestModelPlugin::hasImportOptions() const
+{
+ return false;
+}
+
+// Show import options dialog
+bool TestModelPlugin::showImportOptionsDialog(KVMap& targetOptions) const
+{
+ return false;
+}
+
+// Return whether the plugin has export options
+bool TestModelPlugin::hasExportOptions() const
+{
+ return false;
+}
+
+// Show export options dialog
+bool TestModelPlugin::showExportOptionsDialog(KVMap& targetOptions) const
+{
+ return false;
+}