diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 7f606ea7fa4baf827cb634a1a8a63cd710ee4b26..978bc0d91a1c894ac29673554651ba46eb0669a7 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -6,6 +6,7 @@
 add_subdirectory(basics)
 add_subdirectory(hello)
 add_subdirectory(heatTransfer)
+add_subdirectory(plugins)
 
 if(ADIOS2_BUILD_EXAMPLES_EXPERIMENTAL)
   add_subdirectory(experimental)
diff --git a/examples/plugins/CMakeLists.txt b/examples/plugins/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..bd9914576866a2c9a4c1c4a6d7766e3d65acde19
--- /dev/null
+++ b/examples/plugins/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(engine)
diff --git a/examples/plugins/engine/CMakeLists.txt b/examples/plugins/engine/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..37b3215da513cf1d15f56679ce14174ecd764d8c
--- /dev/null
+++ b/examples/plugins/engine/CMakeLists.txt
@@ -0,0 +1,5 @@
+add_executable(examplePluginEngine_class
+  examplePluginEngine_class.cpp
+  ExampleEnginePlugin.h ExampleEnginePlugin.cpp
+)
+target_link_libraries(examplePluginEngine_class adios2)
diff --git a/examples/plugins/engine/ExampleEnginePlugin.cpp b/examples/plugins/engine/ExampleEnginePlugin.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..09d55a509900e074eccb0df05b258f9b52dee8ba
--- /dev/null
+++ b/examples/plugins/engine/ExampleEnginePlugin.cpp
@@ -0,0 +1,106 @@
+/*
+ * Distributed under the OSI-approved Apache License, Version 2.0.  See
+ * accompanying file Copyright.txt for details.
+ *
+ * ExampleEnginePlugin.cpp This plugin does nothing but write API calls out to a
+ * log file.
+ *
+ *  Created on: Jul 31, 2017
+ *      Author: Chuck Atkins <chuck.atkins@kitware.com>
+ */
+
+#include "ExampleEnginePlugin.h"
+
+#include <cstdio>
+#include <cstring>
+#include <ctime>
+
+#ifndef _WIN32_
+#include <sys/time.h>
+#endif
+
+namespace
+{
+std::string now()
+{
+    tm *timeInfo;
+#ifdef _WIN32
+    time_t rawTime;
+    std::time(&rawTime);
+    timeInfo = std::localtime(&rawtime);
+#else
+    timeval curTime;
+    gettimeofday(&curTime, nullptr);
+    timeInfo = std::localtime(&curTime.tv_sec);
+#endif
+
+    char timeBuf[80];
+    std::memset(timeBuf, 0, sizeof(timeBuf));
+    std::strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%dT%H:%M:%S", timeInfo);
+
+#ifdef _WIN32
+    return std::string(timeBuf);
+#else
+    double subSec = curTime.tv_usec / 1e6;
+    char subSecBuf[9];
+    std::memset(subSecBuf, 0, sizeof(subSecBuf));
+    std::sprintf(subSecBuf, "%1.6f", subSec);
+    return std::string(timeBuf) + std::string(&subSecBuf[1]);
+#endif
+}
+}
+
+namespace adios2
+{
+
+ExampleEnginePlugin::ExampleEnginePlugin(IO &io, const std::string &name,
+                                         const OpenMode openMode,
+                                         MPI_Comm mpiComm)
+: adios2::PluginEngineInterface(io, name, openMode, mpiComm)
+{
+    Init();
+}
+
+ExampleEnginePlugin::~ExampleEnginePlugin() { m_Log.close(); }
+
+void ExampleEnginePlugin::Close(const int transportIndex)
+{
+    m_Log << now() << " Close with transportIndex " << transportIndex
+          << std::endl;
+}
+
+void ExampleEnginePlugin::Init()
+{
+    std::string logName = "ExamplePlugin.log";
+    auto paramLogNameIt = m_IO.m_Parameters.find("LogName");
+    if (paramLogNameIt != m_IO.m_Parameters.end())
+    {
+        logName = paramLogNameIt->second;
+    }
+
+    m_Log.open(logName);
+    if (!m_Log)
+    {
+        throw std::ios_base::failure(
+            "ExampleEnginePlugin: Failed to open log file " + logName);
+    }
+
+    m_Log << now() << " Init" << std::endl;
+}
+
+#define define(T)                                                              \
+    void ExampleEnginePlugin::DoWrite(Variable<T> &variable, const T *values)  \
+    {                                                                          \
+        m_Log << now() << " Writing variable \"" << variable.m_Name << "\""    \
+              << std::endl;                                                    \
+    }
+ADIOS2_FOREACH_TYPE_1ARG(define)
+#undef define
+void ExampleEnginePlugin::DoWrite(VariableCompound &variable,
+                                  const void *values)
+{
+    m_Log << now() << " Writing variable \"" << variable.m_Name << "\""
+          << std::endl;
+}
+
+} // end namespace adios2
diff --git a/examples/plugins/engine/ExampleEnginePlugin.h b/examples/plugins/engine/ExampleEnginePlugin.h
new file mode 100644
index 0000000000000000000000000000000000000000..aa81d0a1aa1c9e906d0dcaeb4ca91a7ab710e446
--- /dev/null
+++ b/examples/plugins/engine/ExampleEnginePlugin.h
@@ -0,0 +1,51 @@
+/*
+ * Distributed under the OSI-approved Apache License, Version 2.0.  See
+ * accompanying file Copyright.txt for details.
+ *
+ * ExampleEnginePlugin.h This plugin does nothing but write API calls out to a
+ * log file.
+ *
+ *  Created on: Jul 31, 2017
+ *      Author: Chuck Atkins <chuck.atkins@kitware.com>
+ */
+
+#ifndef EXAMPLEENGINEPLUGIN_H_
+#define EXAMPLEENGINEPLUGIN_H_
+
+#include <fstream>
+#include <string>
+
+#include <adios2/ADIOSMPICommOnly.h>
+#include <adios2/ADIOSMacros.h>
+#include <adios2/ADIOSTypes.h>
+#include <adios2/core/IO.h>
+#include <adios2/engine/plugin/PluginEngineInterface.h>
+
+namespace adios2
+{
+
+/** An engine interface to be used aby the plugin infrastructure */
+class ExampleEnginePlugin : public PluginEngineInterface
+{
+public:
+    ExampleEnginePlugin(IO &io, const std::string &name,
+                        const OpenMode openMode, MPI_Comm mpiComm);
+    virtual ~ExampleEnginePlugin();
+
+    void Close(const int transportIndex = -1) override;
+
+protected:
+    void Init() override;
+
+#define declare(T)                                                             \
+    void DoWrite(Variable<T> &variable, const T *values) override;
+    ADIOS2_FOREACH_TYPE_1ARG(declare)
+#undef declare
+    void DoWrite(VariableCompound &variable, const void *values) override;
+
+private:
+    std::ofstream m_Log;
+};
+
+} // end namespace adios2
+#endif /* EXAMPLEENGINEPLUGIN_H_ */
diff --git a/examples/plugins/engine/examplePluginEngine_class.cpp b/examples/plugins/engine/examplePluginEngine_class.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e8a65905dd72e905b3284e07c3f3919558fb1a73
--- /dev/null
+++ b/examples/plugins/engine/examplePluginEngine_class.cpp
@@ -0,0 +1,77 @@
+/*
+ * Distributed under the OSI-approved Apache License, Version 2.0.  See
+ * accompanying file Copyright.txt for details.
+ *
+ * helloBPWriter_nompi.cpp sequential non-mpi version of helloBPWriter
+ *
+ *  Created on: Jan 9, 2017
+ *      Author: William F Godoy godoywf@ornl.gov
+ */
+
+#include <ios>       //std::ios_base::failure
+#include <iostream>  //std::cout
+#include <stdexcept> //std::invalid_argument std::exception
+#include <vector>
+
+#include <adios2.h>
+#include <adios2/engine/plugin/PluginEngine.h>
+
+#include "ExampleEnginePlugin.h"
+
+int main(int argc, char *argv[])
+{
+    /** Application variable */
+    std::vector<float> myFloats = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+    const std::size_t Nx = myFloats.size();
+
+    adios2::PluginEngine::RegisterPlugin<adios2::ExampleEnginePlugin>(
+        "MyPlugin");
+
+    try
+    {
+        /** ADIOS class factory of IO class objects, DebugON is recommended */
+        adios2::ADIOS adios(adios2::DebugON);
+
+        /*** IO class object: settings and factory of Settings: Variables,
+         * Parameters, Transports, and Execution: Engines */
+        adios2::IO &io = adios.DeclareIO("PluginIO");
+
+        /** global array: name, { shape (total dimensions) }, { start (local) },
+         * { count (local) }, all are constant dimensions */
+        adios2::Variable<float> &var = io.DefineVariable<float>(
+            "data", {}, {}, {Nx}, adios2::ConstantDims);
+
+        /** Engine derived class, spawned to start IO operations */
+        io.SetEngine("PluginEngine");
+        io.SetParameters({{"PluginName", "MyPlugin"}});
+        auto writer = io.Open("TestPlugin", adios2::OpenMode::Write);
+
+        if (!writer)
+        {
+            throw std::ios_base::failure("ERROR: writer not created at Open\n");
+        }
+
+        /** Write variable for buffering */
+        writer->Write<float>(var, myFloats.data());
+
+        /** Create bp file, engine becomes unreachable after this*/
+        writer->Close();
+    }
+    catch (std::invalid_argument &e)
+    {
+        std::cout << "Invalid argument exception, STOPPING PROGRAM\n";
+        std::cout << e.what() << "\n";
+    }
+    catch (std::ios_base::failure &e)
+    {
+        std::cout << "IO System base failure exception, STOPPING PROGRAM\n";
+        std::cout << e.what() << "\n";
+    }
+    catch (std::exception &e)
+    {
+        std::cout << "Exception, STOPPING PROGRAM from rank\n";
+        std::cout << e.what() << "\n";
+    }
+
+    return 0;
+}
diff --git a/source/adios2/CMakeLists.txt b/source/adios2/CMakeLists.txt
index 8c24fa723db3064a87564df1deddb524e78cad7f..374bacb349b5bea89ffd9b114ac3daf79dd1d20a 100644
--- a/source/adios2/CMakeLists.txt
+++ b/source/adios2/CMakeLists.txt
@@ -29,6 +29,10 @@ add_library(adios2
 #  engine/bp/BPFileReader.cpp
   engine/bp/BPFileWriter.cpp engine/bp/BPFileWriter.tcc
 
+  engine/plugin/PluginEngine.h engine/plugin/PluginEngine.inl
+  engine/plugin/PluginEngine.cpp
+  engine/plugin/PluginEngineInterface.h engine/plugin/PluginEngineInterface.cpp
+
   toolkit/capsule/Capsule.cpp
   toolkit/capsule/heap/STLVector.cpp 
  
diff --git a/source/adios2/core/IO.cpp b/source/adios2/core/IO.cpp
index 6a6d0d7763657067236e61839048fc06f12c66db..fb0a84b9c1c2c236677b8b85b955e436b9de4826 100644
--- a/source/adios2/core/IO.cpp
+++ b/source/adios2/core/IO.cpp
@@ -13,6 +13,7 @@
 
 #include "adios2/ADIOSMPI.h"
 #include "adios2/engine/bp/BPFileWriter.h"
+#include "adios2/engine/plugin/PluginEngine.h"
 #include "adios2/helper/adiosFunctions.h" //BuildParametersMap
 
 #ifdef ADIOS2_HAVE_DATAMAN // external dependencies
@@ -283,6 +284,10 @@ std::shared_ptr<Engine> IO::Open(const std::string &name,
                                     "HDF5 library, can't use HDF5\n");
 #endif
     }
+    else if (m_EngineType == "PluginEngine")
+    {
+        engine = std::make_shared<PluginEngine>(*this, name, openMode, mpiComm);
+    }
     else
     {
         if (m_DebugMode)
diff --git a/source/adios2/engine/plugin/PluginEngine.cpp b/source/adios2/engine/plugin/PluginEngine.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c81aa060fa61b6e8b135d801f9e1682f0b57eb6d
--- /dev/null
+++ b/source/adios2/engine/plugin/PluginEngine.cpp
@@ -0,0 +1,191 @@
+/*
+ * Distributed under the OSI-approved Apache License, Version 2.0.  See
+ * accompanying file Copyright.txt for details.
+ *
+ * PluginEngine.cpp
+ *
+ *  Created on: July 17, 2017
+ *      Author: Chuck Atkins <chuck.atkins@kitware.com>
+ */
+
+#include "PluginEngine.h"
+#include "PluginEngineInterface.h"
+
+#include <functional>
+#include <map>
+#include <memory>
+#include <stdexcept>
+#include <utility>
+
+#include "adios2/helper/adiosDynamicBinder.h"
+
+namespace adios2
+{
+
+/******************************************************************************/
+
+struct PluginEngine::Impl
+{
+    using Registry =
+        std::map<std::string, std::pair<EngineCreateFun, EngineDestroyFun>>;
+    static Registry m_Registry;
+
+    std::string m_PluginName;
+    std::unique_ptr<adios2::DynamicBinder> m_Binder;
+    EngineCreateFun m_HandleCreate;
+    EngineDestroyFun m_HandleDestroy;
+    PluginEngineInterface *m_Plugin = nullptr;
+};
+PluginEngine::Impl::Registry PluginEngine::Impl::m_Registry;
+
+/******************************************************************************/
+
+void PluginEngine::RegisterPlugin(const std::string pluginName,
+                                  EngineCreateFun create,
+                                  EngineDestroyFun destroy)
+{
+    PluginEngine::Impl::m_Registry.emplace(pluginName,
+                                           std::make_pair(create, destroy));
+}
+
+/******************************************************************************/
+
+PluginEngine::PluginEngine(IO &io, const std::string &name,
+                           const OpenMode openMode, MPI_Comm mpiComm)
+: Engine("Plugin", io, name, openMode, mpiComm), m_Impl(new Impl)
+{
+    Init();
+    m_Impl->m_Plugin =
+        m_Impl->m_HandleCreate(io, m_Impl->m_PluginName, openMode, mpiComm);
+}
+
+PluginEngine::~PluginEngine() { m_Impl->m_HandleDestroy(m_Impl->m_Plugin); }
+
+void PluginEngine::PerformReads(ReadMode mode)
+{
+    m_Impl->m_Plugin->PerformReads(mode);
+}
+
+void PluginEngine::Release() { m_Impl->m_Plugin->Release(); }
+
+void PluginEngine::Advance(const float timeoutSeconds)
+{
+    m_Impl->m_Plugin->Advance(timeoutSeconds);
+}
+
+void PluginEngine::Advance(const AdvanceMode mode, const float timeoutSeconds)
+{
+    m_Impl->m_Plugin->Advance(mode, timeoutSeconds);
+}
+
+void PluginEngine::AdvanceAsync(const AdvanceMode mode,
+                                AdvanceAsyncCallback callback)
+{
+    m_Impl->m_Plugin->AdvanceAsync(mode, callback);
+}
+
+void PluginEngine::SetCallBack(
+    std::function<void(const void *, std::string, std::string, std::string,
+                       std::vector<size_t>)>
+        callback)
+{
+    m_Impl->m_Plugin->SetCallBack(callback);
+}
+
+void PluginEngine::Close(const int transportIndex)
+{
+    m_Impl->m_Plugin->Close(transportIndex);
+}
+
+void PluginEngine::Init()
+{
+    auto paramPluginNameIt = m_IO.m_Parameters.find("PluginName");
+    if (paramPluginNameIt == m_IO.m_Parameters.end())
+    {
+        throw std::invalid_argument("PluginEngine: PluginName must be "
+                                    "specified in engine parameters");
+    }
+    m_Impl->m_PluginName = paramPluginNameIt->second;
+
+    // First we check to see if we can find the plugin currently registerd
+    auto registryEntryIt =
+        PluginEngine::Impl::m_Registry.find(m_Impl->m_PluginName);
+
+    if (registryEntryIt != PluginEngine::Impl::m_Registry.end())
+    {
+        m_Impl->m_HandleCreate = registryEntryIt->second.first;
+        m_Impl->m_HandleDestroy = registryEntryIt->second.second;
+    }
+    else
+    {
+        // It's not currently registered so try to load it from a shared
+        // library
+        //
+        auto paramPluginLibraryIt = m_IO.m_Parameters.find("PluginLibrary");
+        if (paramPluginLibraryIt == m_IO.m_Parameters.end())
+        {
+            throw std::invalid_argument(
+                "PluginEngine: PluginLibrary must be specified in "
+                "engine parameters if no PluginName "
+                "is specified");
+        }
+        std::string &pluginLibrary = paramPluginLibraryIt->second;
+
+        m_Impl->m_Binder.reset(new adios2::DynamicBinder(pluginLibrary));
+
+        m_Impl->m_HandleCreate = reinterpret_cast<EngineCreatePtr>(
+            m_Impl->m_Binder->GetSymbol("EngineCreate"));
+        if (!m_Impl->m_HandleCreate)
+        {
+            throw std::runtime_error("PluginEngine: Unable to locate "
+                                     "EngineCreate symbol in specified plugin "
+                                     "library");
+        }
+
+        m_Impl->m_HandleDestroy = reinterpret_cast<EngineDestroyPtr>(
+            m_Impl->m_Binder->GetSymbol("EngineDestroy"));
+        if (!m_Impl->m_HandleDestroy)
+        {
+            throw std::runtime_error("PluginEngine: Unable to locate "
+                                     "EngineDestroy symbol in specified plugin "
+                                     "library");
+        }
+    }
+}
+
+#define define(T)                                                              \
+    void PluginEngine::DoWrite(Variable<T> &variable, const T *values)         \
+    {                                                                          \
+        m_Impl->m_Plugin->DoWrite(variable, values);                           \
+    }                                                                          \
+    void PluginEngine::DoScheduleRead(Variable<T> &variable, const T *values)  \
+    {                                                                          \
+        m_Impl->m_Plugin->DoScheduleRead(variable, values);                    \
+    }                                                                          \
+    void PluginEngine::DoScheduleRead(const std::string &variableName,         \
+                                      const T *values)                         \
+    {                                                                          \
+        m_Impl->m_Plugin->DoScheduleRead(variableName, values);                \
+    }
+ADIOS2_FOREACH_TYPE_1ARG(define)
+#undef define
+void PluginEngine::DoWrite(VariableCompound &variable, const void *values)
+{
+    m_Impl->m_Plugin->DoWrite(variable, values);
+}
+
+#define define(T, L)                                                           \
+    Variable<T> *PluginEngine::InquireVariable##L(const std::string &name,     \
+                                                  const bool readIn)           \
+    {                                                                          \
+        return m_Impl->m_Plugin->InquireVariable##L(name, readIn);             \
+    }
+ADIOS2_FOREACH_TYPE_2ARGS(define)
+#undef define
+VariableBase *PluginEngine::InquireVariableUnknown(const std::string &name,
+                                                   const bool readIn)
+{
+    return m_Impl->m_Plugin->InquireVariableUnknown(name, readIn);
+}
+
+} // end namespace adios
diff --git a/source/adios2/engine/plugin/PluginEngine.h b/source/adios2/engine/plugin/PluginEngine.h
new file mode 100644
index 0000000000000000000000000000000000000000..290f04efdab7b4d213ffb12dea2451e8b149f2b2
--- /dev/null
+++ b/source/adios2/engine/plugin/PluginEngine.h
@@ -0,0 +1,112 @@
+/*
+ * Distributed under the OSI-approved Apache License, Version 2.0.  See
+ * accompanying file Copyright.txt for details.
+ *
+ * PluginEngine.h Support for an engine implemented outside libadios2
+ *
+ *  Created on: July 17, 2017
+ *      Author: Chuck Atkins <chuck.atkins@kitware.com>
+ */
+
+#ifndef ADIOS2_ENGINE_PLUGIN_PLUGINENGINE_H_
+#define ADIOS2_ENGINE_PLUGIN_PLUGINENGINE_H_
+
+#include "PluginEngineInterface.h"
+
+#include <functional>  // for function
+#include <memory>      // for unique_ptr
+#include <string>      // for string
+#include <type_traits> // for add_pointer
+#include <vector>      // for vector
+
+#include "adios2/ADIOSMPICommOnly.h"
+#include "adios2/ADIOSMacros.h"
+#include "adios2/ADIOSTypes.h"
+#include "adios2/core/Engine.h"
+#include "adios2/core/IO.h"
+#include "adios2/core/Variable.h"
+#include "adios2/core/VariableCompound.h"
+
+namespace adios2
+{
+
+/** A front-end wrapper for an engine implemented outside of libadios2 */
+class PluginEngine : public Engine
+{
+public:
+    // Function pointers used for the plugin factory methods
+
+    using EngineCreatePtr = std::add_pointer<PluginEngineInterface *(
+        IO &, const std::string &, const OpenMode, MPI_Comm)>::type;
+    using EngineDestroyPtr =
+        std::add_pointer<void(PluginEngineInterface *)>::type;
+    using EngineCreateFun =
+        std::function<std::remove_pointer<EngineCreatePtr>::type>;
+    using EngineDestroyFun =
+        std::function<std::remove_pointer<EngineDestroyPtr>::type>;
+
+    static void RegisterPlugin(const std::string pluginName,
+                               EngineCreateFun create,
+                               EngineDestroyFun destroy);
+    static void RegisterPlugin(const std::string pluginName,
+                               EngineCreatePtr create, EngineDestroyPtr destroy)
+    {
+        RegisterPlugin(pluginName, EngineCreateFun(create),
+                       EngineDestroyFun(destroy));
+    }
+
+    // This is just a shortcut method to handle the case where the class type is
+    // directly available to the caller so a sim[ple new and delete call is
+    // sufficient to create and destroy the engine object
+    template <typename T>
+    static void RegisterPlugin(const std::string name);
+
+public:
+    PluginEngine(IO &io, const std::string &name, const OpenMode openMode,
+                 MPI_Comm mpiComm);
+    virtual ~PluginEngine();
+
+    void PerformReads(ReadMode mode) override;
+    void Release() override;
+    void Advance(const float timeoutSeconds = 0.0) override;
+    void Advance(const AdvanceMode mode,
+                 const float timeoutSeconds = 0.0) override;
+    void AdvanceAsync(const AdvanceMode mode,
+                      AdvanceAsyncCallback callback) override;
+
+    void SetCallBack(std::function<void(const void *, std::string, std::string,
+                                        std::string, std::vector<size_t>)>
+                         callback) override;
+
+    void Close(const int transportIndex = -1) override;
+
+protected:
+    void Init() override;
+
+#define declare(T)                                                             \
+    void DoWrite(Variable<T> &variable, const T *values) override;             \
+    void DoScheduleRead(Variable<T> &variable, const T *values) override;      \
+    void DoScheduleRead(const std::string &variableName, const T *values)      \
+        override;
+    ADIOS2_FOREACH_TYPE_1ARG(declare)
+#undef declare
+    void DoWrite(VariableCompound &variable, const void *values) override;
+
+#define declare(T, L)                                                          \
+    Variable<T> *InquireVariable##L(const std::string &name,                   \
+                                    const bool readIn) override;
+    ADIOS2_FOREACH_TYPE_2ARGS(declare)
+#undef declare
+    VariableBase *InquireVariableUnknown(const std::string &name,
+                                         const bool readIn) override;
+
+private:
+    struct Impl;
+    std::unique_ptr<Impl> m_Impl;
+};
+
+} // end namespace adios
+
+#include "PluginEngine.inl"
+
+#endif /* ADIOS2_ENGINE_PLUGIN_PLUGINENGINE_H_ */
diff --git a/source/adios2/engine/plugin/PluginEngine.inl b/source/adios2/engine/plugin/PluginEngine.inl
new file mode 100644
index 0000000000000000000000000000000000000000..e28cbd8b327c306a64cb57bc4b83bc830ee74653
--- /dev/null
+++ b/source/adios2/engine/plugin/PluginEngine.inl
@@ -0,0 +1,36 @@
+/*
+ * Distributed under the OSI-approved Apache License, Version 2.0.  See
+ * accompanying file Copyright.txt for details.
+ *
+ * PluginEngine.h Support for an engine implemented outside libadios2
+ *
+ *  Created on: July 17, 2017
+ *      Author: Chuck Atkins <chuck.atkins@kitware.com>
+ */
+
+#ifndef ADIOS2_ENGINE_PLUGIN_ENGINE_INL_
+#define ADIOS2_ENGINE_PLUGIN_ENGINE_INL_
+#ifndef ADIOS2_ENGINE_PLUGIN_PLUGINENGINE_H_
+#error "Inline file should only be included from it's header, never on it's own"
+#endif
+
+#include "PluginEngine.h"
+
+namespace adios2
+{
+
+template <typename T>
+void PluginEngine::RegisterPlugin(const std::string name)
+{
+    EngineCreateFun createFun =
+        [](IO &io, const std::string &name, const OpenMode openMode,
+           MPI_Comm mpiComm) -> PluginEngineInterface * {
+        return new T(io, name, openMode, mpiComm);
+    };
+    EngineDestroyFun destroyFun = [](Engine *obj) -> void { delete obj; };
+
+    RegisterPlugin(name, createFun, destroyFun);
+}
+}
+
+#endif // ADIOS2_ENGINE_PLUGIN_ENGINE_INL_
diff --git a/source/adios2/engine/plugin/PluginEngineInterface.cpp b/source/adios2/engine/plugin/PluginEngineInterface.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a6e20d69668f2e31f41c4deabe0319c130abeed4
--- /dev/null
+++ b/source/adios2/engine/plugin/PluginEngineInterface.cpp
@@ -0,0 +1,23 @@
+/*
+ * Distributed under the OSI-approved Apache License, Version 2.0.  See
+ * accompanying file Copyright.txt for details.
+ *
+ * PluginEngineInterface.cxx
+ *
+ *  Created on: Aug 17, 2017
+ *      Author: Chuck Atkins <chuck.atkins@kitware.com>
+ */
+
+#include "PluginEngineInterface.h"
+
+namespace adios2
+{
+
+PluginEngineInterface::PluginEngineInterface(IO &io, const std::string &name,
+                                             const OpenMode openMode,
+                                             MPI_Comm mpiComm)
+: Engine("PluginInterface", io, name, openMode, mpiComm)
+{
+}
+
+} // end namespace adios
diff --git a/source/adios2/engine/plugin/PluginEngineInterface.h b/source/adios2/engine/plugin/PluginEngineInterface.h
new file mode 100644
index 0000000000000000000000000000000000000000..20d9e9c144f6b348528cf142856826b66ce24623
--- /dev/null
+++ b/source/adios2/engine/plugin/PluginEngineInterface.h
@@ -0,0 +1,41 @@
+/*
+ * Distributed under the OSI-approved Apache License, Version 2.0.  See
+ * accompanying file Copyright.txt for details.
+ *
+ * PluginEngineInterface.h Engines using the plugin interface should derive from
+ * this class.
+ *
+ *  Created on: July 17, 2017
+ *      Author: Chuck Atkins <chuck.atkins@kitware.com>
+ */
+
+#ifndef ADIOS2_ENGINE_PLUGIN_PLUGINENGINEINTERFACE_H_
+#define ADIOS2_ENGINE_PLUGIN_PLUGINENGINEINTERFACE_H_
+
+/// \cond EXCLUDE_FROM_DOXYGEN
+/// \endcond
+
+#include "adios2/ADIOSConfig.h"
+#include "adios2/ADIOSMPICommOnly.h"
+#include "adios2/ADIOSTypes.h"
+#include "adios2/core/Engine.h"
+#include "adios2/core/IO.h"
+
+namespace adios2
+{
+
+/** An engine interface to be used aby the plugin infrastructure */
+class PluginEngineInterface : public Engine
+{
+    // Give the plugin engine access to everything
+    friend class PluginEngine;
+
+public:
+    PluginEngineInterface(IO &io, const std::string &name,
+                          const OpenMode openMode, MPI_Comm mpiComm);
+    virtual ~PluginEngineInterface() = default;
+};
+
+} // end namespace adios
+
+#endif /* ADIOS2_ENGINE_PLUGIN_PLUGINENGINEINTERFACE_H_ */
diff --git a/source/adios2/helper/adiosDynamicBinder.cpp b/source/adios2/helper/adiosDynamicBinder.cpp
index d87873ea03f7924dea2de05449d9ca78599edd3e..00ecd6342178804ac83816e31f16f46f71d798a5 100644
--- a/source/adios2/helper/adiosDynamicBinder.cpp
+++ b/source/adios2/helper/adiosDynamicBinder.cpp
@@ -10,12 +10,12 @@
 
 #include "adiosDynamicBinder.h"
 
-#include <algorithm>                    // for copy
-#include <iostream>                     // for operator<<, stringstream, bas...
-#include <iterator>                     // for ostream_iterator
-#include <sstream>                      // for stringstream
-#include <stdexcept>                    // for runtime_error
-#include <vector>                       // for vector
+#include <algorithm> // for copy
+#include <iostream>  // for operator<<, stringstream, bas...
+#include <iterator>  // for ostream_iterator
+#include <sstream>   // for stringstream
+#include <stdexcept> // for runtime_error
+#include <vector>    // for vector
 
 #include <adios2sys/DynamicLoader.hxx>