diff --git a/bindings/python/Makefile b/bindings/python/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..d7f98bb0786a20d6b40c94caeb1d6f4dc7d2ae53
--- /dev/null
+++ b/bindings/python/Makefile
@@ -0,0 +1,43 @@
+#Makefile
+# Created on: Jun 8, 2017
+#     Author: William F Godoy
+
+
+MPICC:=mpic++
+
+CPPFiles:=$(shell find ./source -type f -name "*.cpp")
+OBJS:=$(patsubst %.cpp, ./bin/%.o, $(notdir $(CPPFiles)) )
+
+# Python
+PYTHON_VERSION:= 2.7
+PYTHON_INC:= /usr/include/python$(PYTHON_VERSION)
+PYTHON_LIBLOC:= /usr/lib/python$(PYTHON_VERSION)/config-x86_64-linux-gnu/
+ 
+
+# ADIOS2
+ADIOS2_INC:= /usr/local/include
+ADIOS2_LIB:= /usr/local/lib
+
+# PyBind11
+PyBind11_INC:= /home/wfg/workspace/ADIOS2/thirdparty/pybind11/include
+
+
+CFLAGS:=-c -Wall -fPIC -O0 -g -std=c++11 -Wno-deprecated-declarations
+INC:= -I$(PYTHON_INC) -I$(ADIOS2_INC) -I$(PyBind11_INC)
+LIBS:= -L$(ADIOS2_LIB) -ladios2 -L$(PYTHON_LIBLOC) -lpython$(PYTHON_VERSION)
+
+ 
+# compile mesh classes
+TARGET = adios2py
+
+all: $(TARGET).so
+ 
+$(TARGET).so: $(OBJS)
+	$(MPICC) -shared -o $(TARGET).so -Wl,--export-dynamic $(OBJS) $(LIBS) 
+ 
+./bin/%.o: ./source/%.cpp
+	@( mkdir -p ./bin );
+	$(MPICC) $(INC) $(CFLAGS) -o $@ $<
+	
+clean:
+	rm ./bin/*.o *.so
\ No newline at end of file
diff --git a/bindings/python/helloBPWriter.py b/bindings/python/helloBPWriter.py
new file mode 100644
index 0000000000000000000000000000000000000000..f5f90c5ca31d6170a14ba5c2df8b809bb0f72985
--- /dev/null
+++ b/bindings/python/helloBPWriter.py
@@ -0,0 +1,26 @@
+#
+# Distributed under the OSI-approved Apache License, Version 2.0.  See
+# accompanying file Copyright.txt for details.
+#
+# test_hello.py
+#  Created on: Feb 2, 2017
+#      Author: wfg
+
+from mpi4py import MPI
+from adios2py import *
+import numpy as np
+
+
+# User data
+myArray = np.array([1, 2, 3, 4])
+
+print "Read " + str(Read)
+
+adios = ADIOS(MPI.COMM_WORLD, True)
+
+bpIO = adios.DeclareIO("BPN2N")
+ioArray = bpIO.DefineVariable("bpArray", [myArray.size], [0], [myArray.size], True)
+  
+bpFileWriter = bpIO.Open("myArray.bp", Write)
+bpFileWriter.Write(ioArray, myArray)
+bpFileWriter.Close()
diff --git a/bindings/python/source/ADIOSPy.cpp b/bindings/python/source/ADIOSPy.cpp
index f820b568dfc301fa1a2dc12a72dcb1cb43a2cb38..c613882bb935ee3ab1397a99dca5dec03f0a2249 100644
--- a/bindings/python/source/ADIOSPy.cpp
+++ b/bindings/python/source/ADIOSPy.cpp
@@ -10,68 +10,23 @@
 
 #include "ADIOSPy.h"
 
-#include "bindings/python/source/adiosPyTypes.h"
+#include "adiosPyTypes.h"
+
+#include <iostream>
 
 namespace adios
 {
 
 ADIOSPy::ADIOSPy(MPI_Comm mpiComm, const bool debug)
-: m_DebugMode(debug), ADIOS(mpiComm, debug)
+: m_DebugMode(debug), m_ADIOS(mpiComm, debug)
 {
 }
 
-IOPy &ADIOSPy::DeclareIO(const std::string name)
+IOPy ADIOSPy::DeclareIO(const std::string name)
 {
+    std::cout << "Declaring IO " << name << "\n";
+
     return IOPy(m_ADIOS.DeclareIO(name), m_DebugMode);
 }
 
-// VariablePy ADIOSPy::DefineVariablePy(const std::string name,
-//                                     const pyList localDimensionsPy,
-//                                     const pyList globalDimensionsPy,
-//                                     const pyList globalOffsetsPy)
-//{
-//    if (m_DebugMode == true)
-//    {
-//        if (m_VariablesPyNames.count(name) == 1)
-//            throw std::invalid_argument("ERROR: Variable " + name +
-//                                        " is already defined\n");
-//    }
-//
-//    m_VariablesPyNames.insert(name);
-//    return VariablePy(name, localDimensionsPy, globalDimensionsPy,
-//                      globalOffsetsPy);
-//}
-//
-// void ADIOSPy::DefineVariableType(VariablePy &variablePy) {}
-//
-// EnginePy ADIOSPy::OpenPy(const std::string name, const std::string
-// accessMode,
-//                         const MethodPy &method, pyObject py_comm)
-//{
-//    EnginePy enginePy(*this);
-//
-//    bool isEmpty = IsEmpty(py_comm);
-//
-//    if (isEmpty == true) // None
-//    {
-//        enginePy.m_Engine = Open(name, accessMode, method);
-//    }
-//    else
-//    {
-//        if (import_mpi4py() < 0)
-//            throw std::logic_error(
-//                "ERROR: could not import mpi4py communicator in Open " + name
-//                +
-//                "\n");
-//        MPI_Comm *comm_p = PyMPIComm_Get(py_comm.ptr());
-//        if (comm_p == nullptr)
-//            throw std::invalid_argument(
-//                "ERROR: MPI communicator is nullptr in Open " + name + "\n");
-//
-//        enginePy.m_Engine = Open(name, accessMode, *comm_p, method);
-//    }
-//
-//    return enginePy;
-//}
-
-} // end namespace
+} // end namespace adios
diff --git a/bindings/python/source/ADIOSPy.h b/bindings/python/source/ADIOSPy.h
index 2de1bfdac571cfa43e67eda2bea6799ab54d9174..f390697d5325a8648e851244eb112ce24e942e3d 100644
--- a/bindings/python/source/ADIOSPy.h
+++ b/bindings/python/source/ADIOSPy.h
@@ -8,16 +8,14 @@
  *      Author: William F Godoy godoywf@ornl.gov
  */
 
-#ifndef BINDINGS_PYTHON_SOURCE_ADIOSPY_H_
-#define BINDINGS_PYTHON_SOURCE_ADIOSPY_H_
+#ifndef ADIOS2_BINDINGS_PYTHON_SOURCE_ADIOSPY_H_
+#define ADIOS2_BINDINGS_PYTHON_SOURCE_ADIOSPY_H_
 
 /// \cond EXCLUDE_FROM_DOXYGEN
 #include <string>
 /// \endcond
 
 #include "IOPy.h"
-#include "adios2/ADIOSMPICommOnly.h"
-#include "adios2/core/ADIOS.h"
 
 namespace adios
 {
@@ -29,10 +27,7 @@ public:
     ADIOSPy(MPI_Comm mpiComm, const bool debug = false);
     ~ADIOSPy() = default;
 
-    /** testing mpi4py should go away*/
-    void HelloMPI();
-
-    IOPy &DeclareIO(const std::string methodName);
+    IOPy DeclareIO(const std::string name);
 
 private:
     const bool m_DebugMode;
diff --git a/bindings/python/source/EnginePy.cpp b/bindings/python/source/EnginePy.cpp
index 91310f2a7d2af6086e969a289331e5fff62b619f..b60efe9712288c6bd1e441ab64711fd17511b466 100644
--- a/bindings/python/source/EnginePy.cpp
+++ b/bindings/python/source/EnginePy.cpp
@@ -8,99 +8,61 @@
  *      Author: wgodoy
  */
 
-#include <string>
+#include "EnginePy.h"
 
-#include "adios2/EnginePy.h"
+#include "adios2/ADIOSMacros.h"
 
-#include "adios2/adiosPyFunctions.h"
+#include "adiosPyFunctions.h"
+
+#include <iostream>
 
 namespace adios
 {
 
-EnginePy::EnginePy(ADIOSPy &adiosPy) : m_ADIOSPy{adiosPy} {}
-
-EnginePy::~EnginePy() {}
-
-void EnginePy::WritePy(VariablePy &variable, const pyArray &array)
+EnginePy::EnginePy(IO &io, const std::string &name, const OpenMode openMode,
+                   MPI_Comm mpiComm)
+: m_IO(io), m_Engine(m_IO.Open(name, openMode, mpiComm)),
+  m_DebugMode(m_IO.m_DebugMode)
 {
+}
 
-    if (variable.m_IsVariableDefined == false) // here define variable
+void EnginePy::Write(VariablePy &variable, const pyArray &array)
+{
+    if (variable.m_IsDefined)
     {
-        if (IsType<char>(array))
-            DefineVariableInADIOS<char>(variable);
-        else if (IsType<unsigned char>(array))
-            DefineVariableInADIOS<unsigned char>(variable);
-        else if (IsType<short>(array))
-            DefineVariableInADIOS<short>(variable);
-        else if (IsType<unsigned short>(array))
-            DefineVariableInADIOS<unsigned short>(variable);
-        else if (IsType<int>(array))
-            DefineVariableInADIOS<int>(variable);
-        else if (IsType<unsigned int>(array))
-            DefineVariableInADIOS<unsigned int>(variable);
-        else if (IsType<long int>(array))
-            DefineVariableInADIOS<long int>(variable);
-        else if (IsType<unsigned long int>(array))
-            DefineVariableInADIOS<unsigned long int>(variable);
-        else if (IsType<long long int>(array))
-            DefineVariableInADIOS<long long int>(variable);
-        else if (IsType<unsigned long long int>(array))
-            DefineVariableInADIOS<unsigned long long int>(variable);
-        else if (IsType<float>(array))
-            DefineVariableInADIOS<float>(variable);
-        else if (IsType<double>(array))
-            DefineVariableInADIOS<double>(variable);
-        else if (IsType<long double>(array))
-            DefineVariableInADIOS<long double>(variable);
-        else if (IsType<std::complex<float>>(array))
-            DefineVariableInADIOS<std::complex<float>>(variable);
-        else if (IsType<std::complex<double>>(array))
-            DefineVariableInADIOS<std::complex<double>>(variable);
-        else if (IsType<std::complex<long double>>(array))
-            DefineVariableInADIOS<std::complex<long double>>(variable);
+        // do nothing, not supporting compound types in Python, yet
+    }
+#define declare_type(T)                                                        \
+    else if (pybind11::isinstance<pybind11::array_t<T>>(array))                \
+    {                                                                          \
+        DefineVariableInIO<T>(variable);                                       \
     }
+    ADIOS2_FOREACH_TYPE_1ARG(declare_type)
+#undef declare_type
 
-    if (IsType<char>(array))
-        WriteVariableInADIOS<char>(variable, array);
-    else if (IsType<unsigned char>(array))
-        WriteVariableInADIOS<unsigned char>(variable, array);
-    else if (IsType<short>(array))
-        WriteVariableInADIOS<short>(variable, array);
-    else if (IsType<unsigned short>(array))
-        WriteVariableInADIOS<unsigned short>(variable, array);
-    else if (IsType<int>(array))
-        WriteVariableInADIOS<int>(variable, array);
-    else if (IsType<unsigned int>(array))
-        WriteVariableInADIOS<unsigned int>(variable, array);
-    else if (IsType<long int>(array))
-        WriteVariableInADIOS<long int>(variable, array);
-    else if (IsType<unsigned long int>(array))
-        WriteVariableInADIOS<unsigned long int>(variable, array);
-    else if (IsType<long long int>(array))
-        WriteVariableInADIOS<long long int>(variable, array);
-    else if (IsType<unsigned long long int>(array))
-        WriteVariableInADIOS<unsigned long long int>(variable, array);
-    else if (IsType<float>(array))
-        WriteVariableInADIOS<float>(variable, array);
-    else if (IsType<double>(array))
-        WriteVariableInADIOS<double>(variable, array);
-    else if (IsType<long double>(array))
-        WriteVariableInADIOS<long double>(variable, array);
-    else if (IsType<std::complex<float>>(array))
-        WriteVariableInADIOS<std::complex<float>>(variable, array);
-    else if (IsType<std::complex<double>>(array))
-        WriteVariableInADIOS<std::complex<double>>(variable, array);
-    else if (IsType<std::complex<long double>>(array))
-        WriteVariableInADIOS<std::complex<long double>>(variable, array);
+    if (!variable.m_IsDefined)
+    {
+        if (m_DebugMode)
+        {
+            throw std::runtime_error("ERROR: variable " + variable.m_Name +
+                                     " couldn't not be created in IO  " +
+                                     m_IO.m_Name + " , in call to Write\n");
+        }
+    }
+#define declare_type(T)                                                        \
+    else if (pybind11::isinstance<pybind11::array_t<T>>(array))                \
+    {                                                                          \
+        WriteInIO<T>(variable, array);                                         \
+    }
+    ADIOS2_FOREACH_TYPE_1ARG(declare_type)
+#undef declare_type
 }
 
-void EnginePy::Advance() { m_Engine->Advance(); }
-
-void EnginePy::Close() { m_Engine->Close(-1); }
-
-void EnginePy::GetEngineType() const
+void EnginePy::Advance(const float timeoutSeconds)
 {
-    std::cout << "Engine type " << m_Engine->m_EngineType << "\n";
+    m_Engine->Advance(timeoutSeconds);
 }
 
-} // end namespace
+void EnginePy::Close() { m_Engine->Close(); }
+
+} // end namespace adios
diff --git a/bindings/python/source/EnginePy.h b/bindings/python/source/EnginePy.h
index 70ad66d44839537dbf9dc5d3c44779d75f7a3e4c..19f6e1dea69d28ac0041e366dd9ffac40399961c 100644
--- a/bindings/python/source/EnginePy.h
+++ b/bindings/python/source/EnginePy.h
@@ -5,61 +5,54 @@
  * EnginePy.h
  *
  *  Created on: Mar 15, 2017
- *      Author: wgodoy
+ *      Author: William F Godoy godoywf@ornl.gov
  */
 
-#ifndef BINDINGS_PYTHON_SOURCE_ENGINEPY_H_
-#define BINDINGS_PYTHON_SOURCE_ENGINEPY_H_
+#ifndef ADIOS2_BINDINGS_PYTHON_SOURCE_ENGINEPY_H_
+#define ADIOS2_BINDINGS_PYTHON_SOURCE_ENGINEPY_H_
+
+/// \cond EXCLUDE_FROM_DOXYGEN
+#include <memory> //std::shared_ptr
+#include <string>
+/// \endcond
+
+#include <adios2.h>
 
-#include "ADIOSPy.h"
 #include "VariablePy.h"
-#include "adios2/core/Engine.h"
-#include "adiosPyFunctions.h"
+#include "adiosPyTypes.h" //pyArray
 
 namespace adios
 {
+
 class EnginePy
 {
 
 public:
-    EnginePy();
+    EnginePy(IO &io, const std::string &name, const OpenMode openMode,
+             MPI_Comm mpiComm);
 
-    ~EnginePy();
+    ~EnginePy() = default;
 
-    Engine *m_Engine;
+    void Write(VariablePy &variable, const pyArray &array);
 
-    void WritePy(VariablePy &variable, const pyArray &array);
-
-    void Advance();
+    void Advance(const float timeoutSeconds = 0.);
 
     void Close();
 
 private:
+    IO &m_IO;
+    std::shared_ptr<Engine> m_Engine;
+    const bool m_DebugMode;
+
     template <class T>
-    void DefineVariableInADIOS(VariablePy &variable);
+    void DefineVariableInIO(VariablePy &variable);
 
     template <class T>
-    void WriteVariableInADIOS(VariablePy &variable, const pyArray &array);
-
-    //    template <class T>
-    //    void DefineVariableInADIOS(VariablePy &variable)
-    //    {
-    //        auto &var = m_ADIOSPy.DefineVariable<T>(
-    //            variable.m_Name, variable.m_LocalDimensions,
-    //            variable.m_GlobalDimensions, variable.m_GlobalOffsets);
-    //        variable.m_VariablePtr = &var;
-    //        variable.m_IsVariableDefined = true;
-    //    }
-    //
-    //    template <class T>
-    //    void WriteVariableInADIOS(VariablePy &variable, const pyArray &array)
-    //    {
-    //        m_Engine->Write(
-    //            *reinterpret_cast<Variable<T> *>(variable.m_VariablePtr),
-    //            PyArrayToPointer<T>(array));
-    //    }
+    void WriteInIO(VariablePy &variable, const pyArray &array);
 };
 
-} // end namespace
+} // end namespace adios
+
+#include "EnginePy.inl"
 
 #endif /* BINDINGS_PYTHON_SOURCE_ENGINEPY_H_ */
diff --git a/bindings/python/source/EnginePy.inl b/bindings/python/source/EnginePy.inl
new file mode 100644
index 0000000000000000000000000000000000000000..33b7cae0c9b2c1043678e49c18682b4b211b35de
--- /dev/null
+++ b/bindings/python/source/EnginePy.inl
@@ -0,0 +1,43 @@
+/*
+ * Distributed under the OSI-approved Apache License, Version 2.0.  See
+ * accompanying file Copyright.txt for details.
+ *
+ * EnginePy.tcc
+ *
+ *  Created on: Jun 8, 2017
+ *      Author: William F Godoy godoywf@ornl.gov
+ */
+
+#ifndef ADIOS2_BINDINGS_PYTHON_SOURCE_ENGINEPY_INL_
+#define ADIOS2_BINDINGS_PYTHON_SOURCE_ENGINEPY_INL_
+#ifndef ADIOS2_BINDINGS_PYTHON_SOURCE_ENGINEPY_H_
+#error "Inline file should only be included from it's header, never on it's own"
+#endif
+
+#include "adiosPyFunctions.h"
+
+namespace adios
+{
+
+template <class T>
+void EnginePy::DefineVariableInIO(VariablePy &variable)
+{
+    auto &var = m_IO.DefineVariable<T>(
+        variable.m_Name, PyListToDims(variable.m_Shape),
+        PyListToDims(variable.m_Start), PyListToDims(variable.m_Count),
+        variable.m_IsConstantDims);
+
+    variable.m_VariableBase = &var;
+    variable.m_IsDefined = true;
+}
+
+template <class T>
+void EnginePy::WriteInIO(VariablePy &variable, const pyArray &array)
+{
+    m_Engine->Write(*dynamic_cast<Variable<T> *>(variable.m_VariableBase),
+                    reinterpret_cast<const T *>(array.data()));
+}
+
+} // end namespace adios
+
+#endif /* BINDINGS_PYTHON_SOURCE_ENGINEPY_TCC_ */
diff --git a/bindings/python/source/IOPy.cpp b/bindings/python/source/IOPy.cpp
index 646c52f57e94fddf2db51a951245c469f427e2ad..692b2b018005f261f1500cbb0573565ba76cfc06 100644
--- a/bindings/python/source/IOPy.cpp
+++ b/bindings/python/source/IOPy.cpp
@@ -10,20 +10,54 @@
 
 #include "IOPy.h"
 
+#include <mpi4py/mpi4py.h>
+
 namespace adios
 {
 
-IOPy::IOPy(IO &io, const bool debugMode) : m_IO(io), m_DebugMode(debugMode) {}
+IOPy::IOPy(IO &io, const bool debugMode) : m_IO(io), m_DebugMode(debugMode)
+{
+    m_IO.m_HostLanguage = "Python";
+}
 
-void IOPy::SetParameters(const pybind11::kwargs kwargs)
-{ // transform to vector and call m_IO SetParameters
+void IOPy::SetParameters(const pyKwargs &kwargs)
+{
+    m_IO.SetParameters(KwargsToParams(kwargs));
 }
 
-unsigned int IOPy::AddTransport(const std::string type,
-                                const pybind11::kwargs kwargs)
+unsigned int IOPy::AddTransport(const std::string type, const pyKwargs &kwargs)
 {
-    // transform to vector and call AddTransport
-    return -1;
+    return m_IO.AddTransport(type, KwargsToParams(kwargs));
 }
 
+VariablePy IOPy::DefineVariable(const std::string &name, const pyList shape,
+                                const pyList start, const pyList count,
+                                const bool isConstantDims)
+{
+    return VariablePy(name, shape, start, count, isConstantDims, m_DebugMode);
+}
+
+EnginePy IOPy::Open(const std::string &name, const int openMode)
+{
+    //    MPI_Comm *mpiCommPtr = PyMPIComm_Get(pyMPIComm.ptr());
+    //
+    //    if (m_DebugMode)
+    //    {
+    //        if (mpiCommPtr == NULL)
+    //        {
+    //            throw std::runtime_error("ERROR: mpi4py communicator for
+    //            engine " +
+    //                                     name + " is null, in call to IO
+    //                                     Open\n");
+    //        }
+    //    }
+    return EnginePy(m_IO, name, static_cast<adios::OpenMode>(openMode),
+                    m_IO.m_MPIComm);
+}
+
+// EnginePy IOPy::Open(const std::string &name, const OpenMode openMode)
+//{
+//    return EnginePy(m_IO, name, openMode, m_IO.m_MPIComm);
+//}
+
 } // end namespace
diff --git a/bindings/python/source/IOPy.h b/bindings/python/source/IOPy.h
index 5bc5bf10e8e75fff207adb2c956cdceb36256360..6bacc3a4183f443d6acfd16f24c6f207a661cf5f 100644
--- a/bindings/python/source/IOPy.h
+++ b/bindings/python/source/IOPy.h
@@ -8,10 +8,14 @@
  *      Author: William F Godoy godoywf@ornl.gov
  */
 
-#ifndef BINDINGS_PYTHON_SOURCE_IOPY_H_
-#define BINDINGS_PYTHON_SOURCE_IOPY_H_
+#ifndef ADIOS2_BINDINGS_PYTHON_SOURCE_IOPY_H_
+#define ADIOS2_BINDINGS_PYTHON_SOURCE_IOPY_H_
 
-#include "adios2/core/IO.h"
+/// \cond EXCLUDE_FROM_DOXYGEN
+#include <string>
+/// \endcond
+
+#include "EnginePy.h"
 #include "adiosPyTypes.h"
 
 namespace adios
@@ -21,23 +25,23 @@ class IOPy
 {
 
 public:
+    IO &m_IO;
+    const bool m_DebugMode;
+
     IOPy(IO &io, const bool debugMode);
 
     ~IOPy() = default;
 
-    void SetParameters(const pyKwargs kwargs);
-    unsigned int AddTransport(const std::string type, const pyKwargs kwargs);
+    void SetParameters(const pyKwargs &kwargs);
+    unsigned int AddTransport(const std::string type, const pyKwargs &kwargs);
 
     VariablePy DefineVariable(const std::string &name, const pyList shape,
                               const pyList start, const pyList count,
-                              const bool isConstantShape = false);
+                              const bool isConstantDims);
 
-    EnginePy Open(const std::string name, const std::string openMode,
-                  pyObject py_comm = pyObject());
+    EnginePy Open(const std::string &name, const int openMode);
 
-private:
-    IO &m_IO;
-    const bool m_DebugMode;
+    // EnginePy Open(const std::string &name, const OpenMode openMode);
 };
 
 } // end namespace adios
diff --git a/bindings/python/source/VariablePy.cpp b/bindings/python/source/VariablePy.cpp
index 8480f70f6ce20071d607005419dc50d42c462dc4..76813c6cd1431402ff67f38baeac8b8e462cc64f 100644
--- a/bindings/python/source/VariablePy.cpp
+++ b/bindings/python/source/VariablePy.cpp
@@ -13,29 +13,35 @@
 namespace adios
 {
 
-VariablePy::VariablePy(const std::string name, const pyList localDimensionsPy,
-                       const pyList globalDimensionsPy,
-                       const pyList globalOffsetsPy)
-: m_Name{name}, m_LocalDimensions{ListToVector(localDimensionsPy)},
-  m_GlobalDimensions{ListToVector(globalDimensionsPy)},
-  m_GlobalOffsets{ListToVector(globalOffsetsPy)}
+VariablePy::VariablePy(const std::string &name, const pyList shape,
+                       const pyList start, const pyList count,
+                       const bool isConstantDims, const bool debugMode)
+: m_Name(name), m_Shape(shape), m_Start(count), m_Count(count),
+  m_IsConstantDims(isConstantDims), m_DebugMode(debugMode)
 {
 }
 
-VariablePy::~VariablePy() {}
-
-void VariablePy::SetLocalDimensions(const pyList list)
+void VariablePy::SetDimensions(const pyList shape, const pyList start,
+                               const pyList count)
 {
-    //      this->m_Dimensions = ListToVector( list );
+    if (m_DebugMode)
+    {
+        if (m_IsConstantDims)
+        {
+            throw std::invalid_argument(
+                "ERROR: variable " + m_Name +
+                " dimensions are constant, in call from SetDimensions\n");
+        }
+    }
+
+    m_Shape = shape;
+    m_Start = start;
+    m_Count = count;
 }
 
-void VariablePy::SetGlobalDimensionsAndOffsets(const pyList globalDimensions,
-                                               const pyList globalOffsets)
+std::string VariablePy::GetType() const noexcept
 {
-    //        this->m_GlobalDimensions = ListToVector( globalDimensions );
-    //        this->m_GlobalOffsets = ListToVector( globalOffsets );
+    return m_VariableBase->m_Type;
 }
 
-Dims VariablePy::GetLocalDimensions() { return this->m_LocalDimensions; }
-
-} // end namespace
+} // end namespace adios
diff --git a/bindings/python/source/VariablePy.h b/bindings/python/source/VariablePy.h
index 401ac13d436242688ffd1b730d831d7d6ea18204..980fcc46f4922b823be2947b69458337f3d12154 100644
--- a/bindings/python/source/VariablePy.h
+++ b/bindings/python/source/VariablePy.h
@@ -8,10 +8,11 @@
  *      Author: William F Godoy godoywf@ornl.gov
  */
 
-#ifndef BINDINGS_PYTHON_SOURCE_VARIABLEPY_H_
-#define BINDINGS_PYTHON_SOURCE_VARIABLEPY_H_
+#ifndef ADIOS2_BINDINGS_PYTHON_SOURCE_VARIABLEPY_H_
+#define ADIOS2_BINDINGS_PYTHON_SOURCE_VARIABLEPY_H_
+
+#include <adios2.h>
 
-#include "adios2/core/VariableBase.h"
 #include "adiosPyFunctions.h"
 
 namespace adios
@@ -21,23 +22,28 @@ class VariablePy
 {
 
 public:
-    VariablePy(const std::string name, const pyList shape, const pyList start,
-               const pyList count, const bool isConstateShape);
+    const std::string m_Name;
+    pyList m_Shape;
+    pyList m_Start;
+    pyList m_Count;
+    const bool m_IsConstantDims;
+
+    VariableBase *m_VariableBase = nullptr;
+    bool m_IsDefined = false;
 
-    ~VariablePy();
+    VariablePy(const std::string &name, const pyList shape, const pyList start,
+               const pyList count, const bool isConstantDims,
+               const bool debugMode);
+
+    ~VariablePy() = default;
 
     void SetDimensions(const pyList shape, const pyList start,
                        const pyList count);
 
-    Dims GetLocalDimensions();
-
-    VariableBase *m_VariableBase = nullptr;
-    bool m_IsVariableDefined = false;
+    std::string GetType() const noexcept;
 
-    const std::string m_Name;
-    Dims m_LocalDimensions;
-    Dims m_GlobalDimensions;
-    Dims m_GlobalOffsets;
+private:
+    const bool m_DebugMode;
 };
 
 } // end namespace adios
diff --git a/bindings/python/source/adiosPyFunctions.cpp b/bindings/python/source/adiosPyFunctions.cpp
index f9396e05b7117e6226bf934a8357e47afcc9c97f..806fd31817e60e2318c2f00ffccca598968ebdf7 100644
--- a/bindings/python/source/adiosPyFunctions.cpp
+++ b/bindings/python/source/adiosPyFunctions.cpp
@@ -9,79 +9,35 @@
  */
 #include <iostream>
 
-#include "adios2/adiosPyFunctions.h"
+#include "adiosPyFunctions.h"
 
 namespace adios
 {
 
-#ifdef HAVE_BOOSTPYTHON
-namespace py = boost::python;
-#endif
-
-#ifdef HAVE_PYBIND11
-namespace py = pybind11;
-#endif
-
-Dims ListToVector(const pyList &list)
-{
-    const unsigned int length = py::len(list);
-    Dims vec;
-    vec.reserve(length);
-
-    for (unsigned int i = 0; i < length; i++)
-        vec.push_back(PyCast<std::size_t>(list[i]));
-
-    return vec;
-}
-
-#ifdef HAVE_BOOSTPYTHON
-std::map<std::string, std::string> DictToMap(const pyDict &dictionary)
+Dims PyListToDims(const pyList list)
 {
-    std::map<std::string, std::string> parameters;
+    const unsigned int length = pybind11::len(list);
+    Dims dimensions;
+    dimensions.reserve(length);
 
-    pyList keys = dictionary.keys();
-    const unsigned int length = py::len(keys);
-
-    for (unsigned int k = 0; k < length; ++k)
+    for (unsigned int i = 0; i < length; ++i)
     {
-        const std::string key(PyCast<std::string>(keys[k]));
-        const std::string value(PyCast<std::string>(dictionary[keys[k]]));
-        parameters.insert(std::make_pair(key, value));
+        dimensions.push_back(pybind11::cast<size_t>(list[i]));
     }
 
-    return parameters;
+    return dimensions;
 }
-#endif
 
-#ifdef HAVE_PYBIND11
-std::map<std::string, std::string> KwargsToMap(const pybind11::kwargs &kwargs)
+Params KwargsToParams(const pyKwargs &kwargs)
 {
-    std::map<std::string, std::string> parameters;
+    Params parameters;
 
     for (const auto &pair : kwargs)
     {
-        const std::string key(PyCast<std::string>(pair.first));
-        const std::string value(PyCast<std::string>(pair.second));
-        parameters.insert(std::make_pair(key, value));
+        parameters.emplace(pybind11::cast<std::string>(pair.first),
+                           pybind11::cast<std::string>(pair.second));
     }
     return parameters;
 }
-#endif
-
-bool IsEmpty(pyObject object)
-{
-    bool isEmpty = false;
-
-#ifdef HAVE_BOOSTPYTHON
-    if (object == boost::python::object())
-        isEmpty = true;
-#endif
-
-#ifdef HAVE_PYBIND11
-    if (object == pybind11::none())
-        isEmpty = true;
-#endif
-    return isEmpty;
-}
 
-} // end namespace
+} // end namespace adios
diff --git a/bindings/python/source/adiosPyFunctions.h b/bindings/python/source/adiosPyFunctions.h
index fbb3acec7b5f6b85fba82f0cb6341b2b109842f4..ed97bbaf4f2622249316067e140edeffc38adb84 100644
--- a/bindings/python/source/adiosPyFunctions.h
+++ b/bindings/python/source/adiosPyFunctions.h
@@ -8,55 +8,33 @@
  *      Author: William F Godoy godoywf@ornl.gov
  */
 
-#ifndef BINDINGS_PYTHON_SOURCE_ADIOSPYFUNCTIONS_H_
-#define BINDINGS_PYTHON_SOURCE_ADIOSPYFUNCTIONS_H_
+#ifndef ADIOS2_BINDINGS_PYTHON_SOURCE_ADIOSPYFUNCTIONS_H_
+#define ADIOS2_BINDINGS_PYTHON_SOURCE_ADIOSPYFUNCTIONS_H_
 
 #include <map>
 #include <string>
 #include <vector>
 
 #include "adios2/ADIOSTypes.h"
-#include "bindings/python/source/adiosPyTypes.h"
+#include "adiosPyTypes.h"
 
 namespace adios
 {
 
 /**
- * Transforms a boost python list to a Dims (std::vector<std::size_t>) object
- * @param list input boost python list from python program
- * @return Dims (std::vector<std::size_t>) object than can be passed to python
+ * Python list to vector of dimensions (Dims)
+ * @param list python list of numbers
+ * @return adios::Dims
  */
-Dims ListToVector(const pyList &list);
+Dims PyListToDims(const pyList list);
 
-std::map<std::string, std::string> KwargsToMap(const pyKwargs &dictionary);
-
-template <class T>
-const T *PyArrayToPointer(const pyArray &array)
-{
-
-    return reinterpret_cast<const T *>(array.data());
-}
-
-template <class T>
-bool IsType(const pyArray &array)
-{
-    bool isType = false;
-
-    if (pybind11::isinstance<pybind11::array_t<T>>(array))
-    {
-        isType = true;
-    }
-
-    return isType;
-}
-
-template <class T, class U>
-T PyCast(U object)
-{
-    return pybind11::cast<T>(object);
-}
-
-bool IsEmpty(pyObject object);
+/**
+ * Python dictionary kwargs to adios::Params (std::map<std::string,
+ * std::string>)
+ * @param kwargs dictionary
+ * @return adios::Params
+ */
+Params KwargsToParams(const pyKwargs &kwargs);
 
 } // end namespace adios
 
diff --git a/bindings/python/source/adiosPyTypes.h b/bindings/python/source/adiosPyTypes.h
index cd81c85a66abec42d58a295dd60ff6d35c9738d5..656649e56c013d3911b1d26a5a4162dfbd1ed14f 100644
--- a/bindings/python/source/adiosPyTypes.h
+++ b/bindings/python/source/adiosPyTypes.h
@@ -8,15 +8,16 @@
  *      Author: William F Godoy godoywf@ornl.gov
  */
 
-#ifndef BINDINGS_PYTHON_SOURCE_ADIOSPYTYPES_H_
-#define BINDINGS_PYTHON_SOURCE_ADIOSPYTYPES_H_
+#ifndef ADIOS2_BINDINGS_PYTHON_SOURCE_ADIOSPYTYPES_H_
+#define ADIOS2_BINDINGS_PYTHON_SOURCE_ADIOSPYTYPES_H_
 
+#include <adios2.h>
 #include <pybind11/numpy.h>
 #include <pybind11/pytypes.h>
 
 namespace adios
 {
-// python
+// pytypes
 using pyObject = pybind11::object;
 using pyTuple = pybind11::tuple;
 using pyDict = pybind11::dict;
diff --git a/bindings/python/source/gluePyBind11.cpp b/bindings/python/source/gluePyBind11.cpp
index efff5d3e71aa7f157bb5075b8a23c704dc9a468e..aaf9033993ced2419c633520b5fd8830579c2381 100644
--- a/bindings/python/source/gluePyBind11.cpp
+++ b/bindings/python/source/gluePyBind11.cpp
@@ -10,31 +10,33 @@
 
 #include <stdexcept>
 
+#include <adios2.h>
 #include <mpi4py/mpi4py.h>
-#include <pybind11.h>
+#include <pybind11/pybind11.h>
 
-#include "bindings/python/source/ADIOSPy.h"
-#include "bindings/python/source/EnginePy.h"
-#include "bindings/python/source/IOPy.h"
+#include "ADIOSPy.h"
+#include "EnginePy.h"
+#include "IOPy.h"
+#include "VariablePy.h"
+#include "adiosPyTypes.h"
 
-namespace py = pybind11;
-
-adios::ADIOSPy ADIOSPy(py::object py_comm, const bool debugMode)
+adios::ADIOSPy ADIOSPyInit(adios::pyObject py_comm, const bool debugMode)
 {
-    MPI_Comm *comm_p = PyMPIComm_Get(py_comm.ptr());
+    MPI_Comm *mpiCommPtr = PyMPIComm_Get(py_comm.ptr());
 
     if (debugMode)
     {
-        if (comm_p == NULL)
+        if (mpiCommPtr == NULL)
         {
-            py::error_already_set(
-                "ERROR: mpi4py communicator in ADIOS in null\n");
+            throw std::runtime_error(
+                "ERROR: mpi4py communicator is null, in call "
+                "to ADIOS constructor\n");
         }
     }
-    return adios::ADIOSPy(*comm_p, debugMode);
+    return adios::ADIOSPy(*mpiCommPtr, debugMode);
 }
 
-PYBIND11_PLUGIN(ADIOSPy)
+PYBIND11_PLUGIN(adios2py)
 {
     if (import_mpi4py() < 0)
     {
@@ -42,31 +44,42 @@ PYBIND11_PLUGIN(ADIOSPy)
             "ERROR: mpi4py not loaded correctly\n"); /* Python 2.X */
     }
 
-    py::module m("ADIOSPy", "ADIOS Python bindings using pybind11");
-
-    m.def("ADIOSPy", &ADIOSPy, "Function that creates an ADIOS object");
+    pybind11::module m("adios2py", "ADIOS2 Python bindings using pybind11");
+    m.attr("DebugON") = true;
+    m.attr("DebugOFF") = false;
+    m.attr("Write") = static_cast<int>(adios::OpenMode::Write);
+    m.attr("Read") = static_cast<int>(adios::OpenMode::Read);
+    m.attr("Append") = static_cast<int>(adios::OpenMode::Append);
+    m.attr("ReadWrite") = static_cast<int>(adios::OpenMode::ReadWrite);
+    m.def("ADIOS", &ADIOSPyInit, "Function that creates an ADIOS object");
 
-    py::class_<adios::ADIOSPy>(m, "ADIOS")
-        .def("HelloMPI", &adios::ADIOSPy::HelloMPI)
-        //.def("DefineVariable", &adios::ADIOSPy::DefineVariablePy)
-        .def("DeclareIO", &adios::ADIOSPy::DeclareIOPy,
-             py::return_value_policy::reference_internal)
-        //.def("Open", &adios::ADIOSPy::OpenPy);
+    pybind11::class_<adios::ADIOSPy>(m, "ADIOSPy")
+        .def("DeclareIO", &adios::ADIOSPy::DeclareIO);
 
-        py::class_<adios::VariablePy>(m, "Variable")
-        .def("SetLocalDimensions", &adios::VariablePy::SetLocalDimensions)
-        .def("GetLocalDimensions", &adios::VariablePy::GetLocalDimensions);
+    pybind11::class_<adios::IOPy>(m, "IOPy")
+        .def("SetParameters", &adios::IOPy::SetParameters)
+        .def("AddTransport", &adios::IOPy::AddTransport)
+        .def("DefineVariable", &adios::IOPy::DefineVariable)
+        .def("Open", &adios::IOPy::Open);
 
-    py::class_<adios::IOPy>(m, "IO")
-        .def("SetParameters", &adios::IOPy::SetParametersPy)
-        .def("AddTransport", &adios::IOPy::AddTransportPy)
-        .def("PrintAll", &adios::MethodPy::PrintAll);
+    pybind11::class_<adios::VariablePy>(m, "VariablePy")
+        .def("SetDimensions", &adios::VariablePy::SetDimensions);
 
-    // Engine
-    py::class_<adios::EnginePy>(m, "Engine")
-        .def("Write", &adios::EnginePy::WritePy)
-        .def("Advance", &adios::EnginePy::WritePy)
+    pybind11::class_<adios::EnginePy>(m, "EnginePy")
+        .def("Write", &adios::EnginePy::Write)
+        .def("Advance", &adios::EnginePy::Advance)
         .def("Close", &adios::EnginePy::Close);
 
+    // Trying overloaded function
+    // (adios::EnginePy (adios::IOPy::*)(
+    //                 const std::string &, const adios::OpenMode,
+    //                 adios::pyObject)) &
+    //                 &adios::IOPy::Open)
+    //        .def("Open", (adios::EnginePy (adios::IOPy::*)(const std::string
+    //        &,
+    //                                                       const
+    //                                                       adios::OpenMode)) &
+    //                         &adios::IOPy::Open);
+
     return m.ptr();
 }
diff --git a/bindings/python/test_hello.py b/bindings/python/test_hello.py
deleted file mode 100644
index b66f26289eca4cccf11abde4f68a1f99de2156b7..0000000000000000000000000000000000000000
--- a/bindings/python/test_hello.py
+++ /dev/null
@@ -1,52 +0,0 @@
-#
-# Distributed under the OSI-approved Apache License, Version 2.0.  See
-# accompanying file Copyright.txt for details.
-#
-# test_hello.py
-#  Created on: Feb 2, 2017
-#      Author: wfg
-
-from mpi4py import MPI
-from ADIOSPy import *
-import numpy as np
-
-# Create ADIOS and verify MPI Comm is passed correctly
-# Pass communicator and debug flag is True
-adios = ADIOSPy(MPI.COMM_WORLD, True)
-rank = MPI.COMM_WORLD.Get_rank()
-size = MPI.COMM_WORLD.Get_size()
-
-# User data
-myArray = np.array([1, 2, 3, 4])
-
-if(rank % 2 == 1):  # odd ranks only
-    oddRankArray = np.array([11., 12., 13., 14.])
-
-
-# ADIOS Define Variables
-ioArray = adios.DefineVariable("ioArray", [myArray.size], [], [])
-
-if(rank % 2 == 1):  # odd ranks only
-    ioOddRankArray = adios.DefineVariable(
-        "ioMyFloats", [oddRankArray.size], [], [])
-
-
-# Setup method and print summary
-ioSettings = adios.DeclareMethod("adiosSettings")
-ioSettings.SetParameters(profile_units='mus')
-# POSIX is default, just checking
-ioSettings.AddTransport('File', have_metadata_file='no', profile_units='mus')
-
-# Start Engine
-# Open files using N-to-N method, None means no new MPI communicator
-bpFileWriter = adios.Open("file.bp", "w", ioSettings, None)
-bpFileWriter.Write(ioArray, myArray)
-
-if(rank % 2 == 1):
-    bpFileWriter.Write(ioOddRankArray, oddRankArray)
-
-bpFileWriter.Close()
-
-if(rank == 0):
-    print "Done writing " + str(size) + " bp files"
-    ioSettings.PrintAll()
diff --git a/examples/experimental/multistep/reader_allsteps.cpp b/examples/experimental/multistep/reader_allsteps.cpp
index 7b50a98bace368713560061a28bda4509d1671e8..972537f0aaa53a9930b284da9ef8a725895db135 100644
--- a/examples/experimental/multistep/reader_allsteps.cpp
+++ b/examples/experimental/multistep/reader_allsteps.cpp
@@ -115,7 +115,7 @@ int main(int argc, char *argv[])
             bpReaderSettings.SetEngine(
                 "ADIOS1Reader"); // BP is the default engine
             // see only one step at a time
-            bpReaderSettings.SetParameters("OpenAsFile");
+            bpReaderSettings.SetParameters({"OpenAsFile=yes"});
         }
 
         // Create engine smart pointer due to polymorphism,
diff --git a/examples/experimental/multistep/writer_multistep.cpp b/examples/experimental/multistep/writer_multistep.cpp
index dc2c4706492d19b2f29b4cd9f225aa36e1dcd9f5..dc80c2e421524595a3ebd1a38a6ce263b2d3fa60 100644
--- a/examples/experimental/multistep/writer_multistep.cpp
+++ b/examples/experimental/multistep/writer_multistep.cpp
@@ -74,11 +74,11 @@ int main(int argc, char *argv[])
             bpWriterSettings.AddTransport("file"
 #ifdef ADIOS2_HAVE_MPI
                                           ,
-                                          "library=MPI-IO"
+                                          { "library=MPI-IO" }
 #endif
                                           );
             // Passing parameters to the engine
-            bpWriterSettings.SetParameters("have_metadata_file=yes");
+            bpWriterSettings.SetParameters({"have_metadata_file=yes"});
             // number of aggregators
             // bpWriterSettings.SetParameters("Aggregation", (nproc + 1) / 2);
         }
diff --git a/examples/heatTransfer/read/heatRead_adios2.cpp b/examples/heatTransfer/read/heatRead_adios2.cpp
index 93bc3faf9f691928114609678f9d8c6602a207c9..e9920eba13b1c78044919e4adf8ec2d3f7b154c1 100644
--- a/examples/heatTransfer/read/heatRead_adios2.cpp
+++ b/examples/heatTransfer/read/heatRead_adios2.cpp
@@ -55,11 +55,11 @@ int main(int argc, char *argv[])
         // if not defined by user, we can change the default settings
         // BPFileWriter is the default engine
         bpReaderIO.SetEngine("ADIOS1Reader");
-        bpReaderIO.SetParameters("num_threads=2");
+        bpReaderIO.SetParameters({"num_threads=2"});
 
         // ISO-POSIX file is the default transport
         // Passing parameters to the transport
-        bpReaderIO.AddTransport("File", "verbose=4");
+        bpReaderIO.AddTransport("File", {"verbose=4"});
     }
 
     auto bpReader =
diff --git a/examples/heatTransfer/write/IO_ph5_adios2.cpp b/examples/heatTransfer/write/IO_ph5_adios2.cpp
index 01fca5621dc5fdb1c3a193511f08525cbe61d077..e75a7131512180e076aa1e2c593bd04a6bbe8188 100644
--- a/examples/heatTransfer/write/IO_ph5_adios2.cpp
+++ b/examples/heatTransfer/write/IO_ph5_adios2.cpp
@@ -39,7 +39,7 @@ IO::IO(const Settings &s, MPI_Comm comm)
 
         const std::string aggregatorsParam("Aggregators=" +
                                            std::to_string((s.nproc + 1) / 2));
-        h5io.SetParameters("have_metadata_file=yes", aggregatorsParam);
+        h5io.SetParameters({"have_metadata_file=yes", aggregatorsParam});
     }
 
     //    ad->DefineScalar<unsigned int>("gndx", true);
diff --git a/examples/hello/adios1Writer/helloADIOS1Writer.cpp b/examples/hello/adios1Writer/helloADIOS1Writer.cpp
index 1041f895cafe00c998b1adc4a7d8a3dc7486e604..e6bcb4f8737e36f2374b820a9d351131c9358805 100644
--- a/examples/hello/adios1Writer/helloADIOS1Writer.cpp
+++ b/examples/hello/adios1Writer/helloADIOS1Writer.cpp
@@ -42,7 +42,7 @@ int main(int argc, char *argv[])
          * Parameters, Transports, and Execution: Engines */
         adios::IO &adios1IO = adios.DeclareIO("ADIOS1IO");
         adios1IO.SetEngine("ADIOS1Writer");
-        adios1IO.AddTransport("file", "library=MPI");
+        adios1IO.AddTransport("file", {"library=MPI"});
 
         /** global array : name, { shape (total) }, { start (local) }, { count
          * (local) }, all are constant dimensions */
diff --git a/examples/hello/datamanReader/helloDataManReader.cpp b/examples/hello/datamanReader/helloDataManReader.cpp
index 7dc984af37870f05187ff1fbd073a226b11f5d16..408c9e7c6c7f05209abf5234123edbab0e41c512 100644
--- a/examples/hello/datamanReader/helloDataManReader.cpp
+++ b/examples/hello/datamanReader/helloDataManReader.cpp
@@ -8,8 +8,10 @@
  *      Author: Jason Wang
  */
 
+#include <chrono>
 #include <iostream>
 #include <numeric>
+#include <thread>
 #include <vector>
 
 #include <adios2.h>
@@ -43,8 +45,9 @@ int main(int argc, char *argv[])
 
         adios::IO &dataManIO = adios.DeclareIO("WAN");
         dataManIO.SetEngine("DataManReader");
-        dataManIO.SetParameters("real_time=yes", "method_type=stream",
-                                "method=dump");
+        dataManIO.SetParameters(
+            {"real_time=yes", "method_type=stream", "method=dump"});
+
         auto dataManReader =
             dataManIO.Open("myDoubles.bp", adios::OpenMode::Read);
 
diff --git a/examples/hello/datamanReader/helloDataManReader_nompi.cpp b/examples/hello/datamanReader/helloDataManReader_nompi.cpp
index 965e47c364dd527ed287bf45f11d0e62a6cacfeb..1e525fc242ad33694d7b0e45a0e649394f68e46d 100644
--- a/examples/hello/datamanReader/helloDataManReader_nompi.cpp
+++ b/examples/hello/datamanReader/helloDataManReader_nompi.cpp
@@ -8,8 +8,10 @@
  *      Author: Jason Wang
  */
 
+#include <chrono>
 #include <iostream>
 #include <numeric>
+#include <thread>
 #include <vector>
 
 #include <adios2.h>
@@ -38,8 +40,8 @@ int main(int argc, char *argv[])
 
         adios::IO &dataManIO = adios.DeclareIO("WAN");
         dataManIO.SetEngine("DataManReader");
-        dataManIO.SetParameters("real_time=yes", "method_type=stream",
-                                "method=dump");
+        dataManIO.SetParameters(
+            {"real_time=yes", "method_type=stream", "method=dump"});
         auto dataManReader =
             dataManIO.Open("myDoubles.bp", adios::OpenMode::Read);
 
diff --git a/examples/hello/datamanWriter/helloDataManWriter.cpp b/examples/hello/datamanWriter/helloDataManWriter.cpp
index dcdf4bff7f289f2d4f716e073a7d2221e3059af1..1c50713797e9bc9e48d7f5cdeb45d31d4fac49ed 100644
--- a/examples/hello/datamanWriter/helloDataManWriter.cpp
+++ b/examples/hello/datamanWriter/helloDataManWriter.cpp
@@ -31,8 +31,8 @@ int main(int argc, char *argv[])
         adios::ADIOS adios(MPI_COMM_WORLD, adios::DebugON);
         adios::IO &dataManIO = adios.DeclareIO("WANIO");
         dataManIO.SetEngine("DataManWriter");
-        dataManIO.SetParameters("peer-to-peer=yes", "real_time=yes",
-                                "compress=no", "method=dump");
+        dataManIO.SetParameters({"peer-to-peer=yes", "real_time=yes",
+                                 "compress=no", "method=dump"});
 
         // Define variable and local size
         auto bpFloats =
diff --git a/examples/hello/datamanWriter/helloDataManWriter_nompi.cpp b/examples/hello/datamanWriter/helloDataManWriter_nompi.cpp
index cbc08fb607c34025ce4697fe8de833928234d61b..fa9fb7f79a362cc13de65c19d96d4d391ea5455b 100644
--- a/examples/hello/datamanWriter/helloDataManWriter_nompi.cpp
+++ b/examples/hello/datamanWriter/helloDataManWriter_nompi.cpp
@@ -24,8 +24,8 @@ int main(int argc, char *argv[])
         adios::ADIOS adios(adios::DebugON);
         adios::IO &dataManIO = adios.DeclareIO("WANIO");
         dataManIO.SetEngine("DataManWriter");
-        dataManIO.SetParameters("peer-to-peer=yes", "real_time=yes",
-                                "compress=no", "method=dump");
+        dataManIO.SetParameters({"peer-to-peer=yes", "real_time=yes",
+                                 "compress=no", "method=dump"});
 
         // Define variable and local size
         auto bpFloats =
diff --git a/source/adios2/CMakeLists.txt b/source/adios2/CMakeLists.txt
index 30c544588c2e48b2d3e6aedbcbd9a7ee0488d3f3..084fe733e90df32ce8647ef96ec58103ddde151d 100644
--- a/source/adios2/CMakeLists.txt
+++ b/source/adios2/CMakeLists.txt
@@ -11,6 +11,7 @@ add_library(adios2
   core/SelectionBoundingBox.cpp
   core/SelectionPoints.cpp
   core/Transform.cpp
+  core/Variable.cpp core/Variable.tcc
   core/VariableBase.cpp
   core/VariableCompound.cpp core/VariableCompound.tcc
   
diff --git a/source/adios2/core/Engine.cpp b/source/adios2/core/Engine.cpp
index 8595d6db4441c0cc400374a670ec10658f09875b..dbf25da839fe1c1ff5732852d9abadae07887d1d 100644
--- a/source/adios2/core/Engine.cpp
+++ b/source/adios2/core/Engine.cpp
@@ -16,6 +16,8 @@
 #include <set>
 /// \endcond
 
+#include "adios2/helper/adiosFunctions.h" //GetType<T>
+
 namespace adios
 {
 
diff --git a/source/adios2/core/Engine.h b/source/adios2/core/Engine.h
index f18e561df28e38dc610c09bff8646f443bdafc69..5cc189a64ea74250868cdd6f24ae4fd0e869a86c 100644
--- a/source/adios2/core/Engine.h
+++ b/source/adios2/core/Engine.h
@@ -18,6 +18,7 @@
 #include <functional> //std::function
 #include <map>
 #include <memory> //std::shared_ptr
+#include <set>
 #include <string>
 #include <vector>
 /// \endcond
diff --git a/source/adios2/core/IO.cpp b/source/adios2/core/IO.cpp
index a9753acc3aa3a178605d8eb2ef2eadb06b7b791e..a91d1cc899991c48ceef0785babcae5cf5f7ddd6 100644
--- a/source/adios2/core/IO.cpp
+++ b/source/adios2/core/IO.cpp
@@ -8,11 +8,12 @@
  *      Author: William F Godoy godoywf@ornl.gov
  */
 
+#include "adios2/helper/adiosFunctions.h" //BuildParametersMap
+
 #include "IO.h"
 #include "IO.tcc"
 
 #include "adios2/ADIOSMPI.h"
-#include "adios2/helper/adiosFunctions.h" //BuildParametersMap
 
 #include "adios2/engine/bp/BPFileWriter.h"
 
@@ -44,6 +45,26 @@ IO::IO(const std::string name, MPI_Comm mpiComm, const bool inConfigFile,
 void IO::SetEngine(const std::string engineType) { m_EngineType = engineType; }
 void IO::SetIOMode(const IOMode ioMode) { m_IOMode = ioMode; };
 
+void IO::SetParameters(const std::vector<std::string> &parametersVector)
+{
+    m_Parameters = BuildParametersMap(parametersVector, m_DebugMode);
+}
+
+void IO::SetParameters(const Params &parameters) { m_Parameters = parameters; }
+
+unsigned int IO::AddTransport(const std::string type,
+                              const std::vector<std::string> &parametersVector)
+{
+    Params parametersMap(BuildParametersMap(parametersVector, m_DebugMode));
+    return AddTransportCommon(type, parametersMap);
+}
+
+unsigned int IO::AddTransport(const std::string type, const Params &parameters)
+{
+    Params parametersMap(parameters);
+    return AddTransportCommon(type, parametersMap);
+}
+
 VariableCompound &IO::GetVariableCompound(const std::string &name)
 {
     return m_Compound.at(GetVariableIndex(name));
@@ -219,34 +240,15 @@ std::shared_ptr<Engine> IO::Open(const std::string &name,
 }
 
 // PRIVATE Functions
-unsigned int
-IO::AddTransportParameters(const std::string type,
-                           const std::vector<std::string> &parameters)
+unsigned int IO::AddTransportCommon(const std::string type, Params &parameters)
 {
     if (m_DebugMode)
     {
-        if (type.empty() || type.find("=") != type.npos)
-        {
-            throw std::invalid_argument(
-                "ERROR: first argument in AddTransport must "
-                "be a single word for transport\n");
-        }
-    }
-
-    Params mapParameters = BuildParametersMap(parameters, m_DebugMode);
-
-    if (m_DebugMode)
-    {
-        if (mapParameters.count("transport") == 1)
-        {
-            std::invalid_argument("ERROR: transport can't be redefined with "
-                                  "\"transport=type\", "
-                                  "type must be the first argument\n");
-        }
+        CheckTransportType(type);
     }
 
-    mapParameters["transport"] = type;
-    m_TransportsParameters.push_back(std::move(mapParameters));
+    parameters["transport"] = type;
+    m_TransportsParameters.push_back(parameters);
     return static_cast<unsigned int>(m_TransportsParameters.size() - 1);
 }
 
@@ -276,6 +278,18 @@ bool IO::VariableExists(const std::string &name) const
     return exists;
 }
 
+void IO::CheckTransportType(const std::string type) const
+{
+    if (type.empty() || type.find("=") != type.npos)
+    {
+        throw std::invalid_argument(
+            "ERROR: wrong first argument " + type +
+            ", must "
+            "be a single word for a supported transport type, in "
+            "call to IO AddTransport \n");
+    }
+}
+
 // Explicitly instantiate the necessary public template implementations
 #define define_template_instantiation(T)                                       \
     template Variable<T> &IO::DefineVariable<T>(                               \
diff --git a/source/adios2/core/IO.h b/source/adios2/core/IO.h
index 87df704d816b8d62df8180bfb7c72eac1b0399e0..ebb84816785c8bb776d149ee93acc39a8404dc76 100644
--- a/source/adios2/core/IO.h
+++ b/source/adios2/core/IO.h
@@ -13,6 +13,7 @@
 
 /// \cond EXCLUDE_FROM_DOXYGEN
 #include <map>
+#include <set>
 #include <string>
 #include <utility> //std::pair
 #include <vector>
@@ -48,7 +49,7 @@ public:
     const bool m_DebugMode = false;
 
     /** from ADIOS class passed to Engine created with Open */
-    const std::string m_HostLanguage = "C++";
+    std::string m_HostLanguage = "C++";
 
     /** From SetParameter, parameters for a particular engine from m_Type */
     Params m_Parameters;
@@ -79,12 +80,18 @@ public:
     void SetIOMode(const IOMode mode);
 
     /**
-     * Sets parameters for the method in "parameter=value" format
-     * @param args list of parameters with format "parameter1=value1", ...,
-     * "parameterN=valueN"
+     * Sets IO parameters in "parameter=value" format
+     * @param paramsVector each vector entry with format
+     * "parameter1=value1", ..., "parameterN=valueN"
+     */
+    void SetParameters(const std::vector<std::string> &parametersVector);
+
+    /**
+     * Version that passes a map to fill out parameters
+     * initializer list = { "param1", "value1" },  {"param2", "value2"},
+     * @param params adios::Params std::map<std::string, std::string>
      */
-    template <class... Args>
-    void SetParameters(Args... args);
+    void SetParameters(const Params &parameters = Params());
 
     /**
      * Adds a transport and its parameters for the method
@@ -92,8 +99,11 @@ public:
      * @param args list of parameters for a transport with format
      * "parameter1=value1", ..., "parameterN=valueN"
      */
-    template <class... Args>
-    unsigned int AddTransport(const std::string type, Args... args);
+    unsigned int AddTransport(const std::string type,
+                              const std::vector<std::string> &paramsVector);
+
+    unsigned int AddTransport(const std::string type,
+                              const Params &params = Params());
 
     /**
      * Define a Variable of primitive data type for I/O.
@@ -124,6 +134,7 @@ public:
      * change over time
      * @return reference to Variable object
      */
+
     template <class T>
     VariableCompound &
     DefineVariableCompound(const std::string &name, const Dims shape = Dims{},
@@ -242,14 +253,12 @@ private:
     std::set<std::string> m_EngineNames;
 
     /**
-     * Called from AddTransport to transform parameter to a map
+     * Called from AddTransport overloads
      * @param type
      * @param parameters
      * @return transport index
      */
-    unsigned int
-    AddTransportParameters(const std::string type,
-                           const std::vector<std::string> &parameters);
+    unsigned int AddTransportCommon(const std::string type, Params &parameters);
 
     /** Gets the internal reference to a variable map for type T
      *  This function is specialized in IO.tcc */
@@ -265,6 +274,8 @@ private:
      * @return true: variable name exists, false: variable name doesn't exist
      */
     bool VariableExists(const std::string &name) const;
+
+    void CheckTransportType(const std::string type) const;
 };
 
 // Explicit declaration of the public template methods
diff --git a/source/adios2/core/IO.inl b/source/adios2/core/IO.inl
index d7a8505442911b709dcaa079c624cc42daae98e2..4b9efbfb382639b9ec7de1ca9a05d12a50fde2ad 100644
--- a/source/adios2/core/IO.inl
+++ b/source/adios2/core/IO.inl
@@ -14,26 +14,11 @@
 #error "Inline file should only be included from it's header, never on it's own"
 #endif
 
-#include "adios2/ADIOSMacros.h"
-#include "adios2/helper/adiosFunctions.h" //BuildParametersMap
+#include "IO.h"
 
 namespace adios
 {
 
-template <class... Args>
-void IO::SetParameters(Args... args)
-{
-    std::vector<std::string> parameters = {args...};
-    m_Parameters = BuildParametersMap(parameters, m_DebugMode);
-}
-
-template <class... Args>
-unsigned int IO::AddTransport(const std::string type, Args... args)
-{
-    std::vector<std::string> parameters = {args...};
-    return AddTransportParameters(type, parameters);
-}
-
 template <class T>
 VariableCompound &IO::DefineVariableCompound(const std::string &name,
                                              const Dims shape, const Dims start,
@@ -44,16 +29,16 @@ VariableCompound &IO::DefineVariableCompound(const std::string &name,
     {
         if (VariableExists(name))
         {
-            std::invalid_argument("ERROR: variable " + name +
-                                  " exists in IO object " + m_Name +
-                                  ", in call to DefineVariable\n");
+            throw std::invalid_argument("ERROR: variable " + name +
+                                        " exists in IO object " + m_Name +
+                                        ", in call to DefineVariable\n");
         }
     }
     const unsigned int size = m_Compound.size();
     auto itVariableCompound = m_Compound.emplace(
         size, VariableCompound(name, sizeof(T), shape, start, count,
                                constantShape, m_DebugMode));
-    m_Variables.emplace(name, std::make_pair(GetType<T>(), size));
+    m_Variables.emplace(name, std::make_pair("compound", size));
     return itVariableCompound.first->second;
 }
 
diff --git a/source/adios2/core/Variable.cpp b/source/adios2/core/Variable.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..424844882bba2a41d3a68c61b9f23cd3ddb498b3
--- /dev/null
+++ b/source/adios2/core/Variable.cpp
@@ -0,0 +1,17 @@
+/*
+ * Distributed under the OSI-approved Apache License, Version 2.0.  See
+ * accompanying file Copyright.txt for details.
+ *
+ * Variable.cpp  needed for template separation using Variable.tcc
+ *
+ *  Created on: Jun 8, 2017
+ *      Author: William F Godoy godoywf@ornl.gov
+ */
+
+#include "Variable.h"
+#include "Variable.tcc"
+
+namespace adios
+{
+
+} // end namespace adios
diff --git a/source/adios2/core/Variable.h b/source/adios2/core/Variable.h
index 9b859f3fabf94a8a907e20586f1402df638ffa50..2cc4cad3638fe715c856ae0eaafce3291a1c6e2c 100644
--- a/source/adios2/core/Variable.h
+++ b/source/adios2/core/Variable.h
@@ -18,10 +18,9 @@
 #include <vector>
 /// \endcond
 
-#include "VariableBase.h"
-#include "adios2/ADIOSConfig.h"
 #include "adios2/ADIOSMacros.h"
 #include "adios2/core/Transform.h"
+#include "adios2/core/VariableBase.h"
 
 namespace adios
 {
@@ -62,6 +61,4 @@ public:
 
 } // end namespace adios
 
-#include "Variable.inl"
-
 #endif /* ADIOS2_CORE_VARIABLE_H_ */
diff --git a/source/adios2/core/Variable.inl b/source/adios2/core/Variable.inl
deleted file mode 100644
index 4abb6e3c45592bf362aec74f2786619d94d04eb8..0000000000000000000000000000000000000000
--- a/source/adios2/core/Variable.inl
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Distributed under the OSI-approved Apache License, Version 2.0.  See
- * accompanying file Copyright.txt for details.
- *
- * Variable.inl
- *
- *  Created on: May 1, 2017
- *      Author: William F Godoy godoywf@ornl.gov
- */
-
-#ifndef ADIOS2_CORE_VARIABLE_INL_
-#define ADIOS2_CORE_VARIABLE_INL_
-#ifndef ADIOS2_CORE_VARIABLE_H_
-#error "Inline file should only be included from it's header, never on it's own"
-#endif
-
-#include "Variable.h"
-
-#include "adios2/helper/adiosFunctions.h" //GetType
-
-namespace adios
-{
-
-template <class T>
-Variable<T>::Variable(const std::string &name, const Dims shape,
-                      const Dims start, const Dims count,
-                      const bool constantShape, const bool debugMode)
-: VariableBase(name, GetType<T>(), sizeof(T), shape, start, count,
-               constantShape, debugMode)
-{
-}
-
-template <class T>
-void Variable<T>::ApplyTransforms()
-{
-}
-
-} // end namespace adios
-
-#endif /* ADIOS2_CORE_VARIABLE_INL_ */
diff --git a/source/adios2/core/Variable.tcc b/source/adios2/core/Variable.tcc
new file mode 100644
index 0000000000000000000000000000000000000000..4da41c61ece51ece8fe463664b7ff2d3f61705c7
--- /dev/null
+++ b/source/adios2/core/Variable.tcc
@@ -0,0 +1,43 @@
+/*
+ * Distributed under the OSI-approved Apache License, Version 2.0.  See
+ * accompanying file Copyright.txt for details.
+ *
+ * Variable.tcc
+ *
+ *  Created on: May 1, 2017
+ *      Author: William F Godoy godoywf@ornl.gov
+ */
+
+#ifndef ADIOS2_CORE_VARIABLE_TCC_
+#define ADIOS2_CORE_VARIABLE_TCC_
+
+#include "Variable.h"
+
+#include "adios2/ADIOSMacros.h"
+#include "adios2/helper/adiosFunctions.h" //GetType
+
+namespace adios
+{
+
+#define declare_type(T)                                                        \
+                                                                               \
+    template <>                                                                \
+    Variable<T>::Variable(const std::string &name, const Dims shape,           \
+                          const Dims start, const Dims count,                  \
+                          const bool constantShape, const bool debugMode)      \
+    : VariableBase(name, GetType<T>(), sizeof(T), shape, start, count,         \
+                   constantShape, debugMode)                                   \
+    {                                                                          \
+    }                                                                          \
+                                                                               \
+    template <>                                                                \
+    void Variable<T>::ApplyTransforms()                                        \
+    {                                                                          \
+    }
+
+ADIOS2_FOREACH_TYPE_1ARG(declare_type)
+#undef declare_type
+
+} // end namespace adios
+
+#endif /* ADIOS2_CORE_VARIABLE_TCC_ */
diff --git a/source/adios2/core/VariableBase.cpp b/source/adios2/core/VariableBase.cpp
index db50a21db91c2ab96911c5cc74a4b76d7888da84..4d7a30a22c10102fd9c843b9918b4aa47b46c0cb 100644
--- a/source/adios2/core/VariableBase.cpp
+++ b/source/adios2/core/VariableBase.cpp
@@ -15,15 +15,17 @@
 #include <stdexcept> //std::invalid_argument
 /// \endcond
 
+#include "adios2/helper/adiosFunctions.h" //GetTotalSize
+
 namespace adios
 {
 
 VariableBase::VariableBase(const std::string &name, const std::string type,
                            const size_t elementSize, const Dims shape,
                            const Dims start, const Dims count,
-                           const bool constantShape, const bool debugMode)
+                           const bool constantDims, const bool debugMode)
 : m_Name(name), m_Type(type), m_ElementSize(elementSize), m_Shape(shape),
-  m_Start(start), m_Count(count), m_ConstantShape(constantShape),
+  m_Start(start), m_Count(count), m_ConstantDims(constantDims),
   m_DebugMode(debugMode)
 {
     InitShapeType();
@@ -50,7 +52,7 @@ void VariableBase::SetSelection(const Dims start, const Dims count)
                 m_Name + ", in call to SetSelection\n");
         }
 
-        if (m_ConstantShape)
+        if (m_ConstantDims)
         {
             throw std::invalid_argument(
                 "ERROR: selection is not valid for constant shape variable " +
@@ -123,6 +125,16 @@ void VariableBase::SetStepSelection(const unsigned int startStep,
     m_ReadNSteps = countStep;
 }
 
+void VariableBase::AddTransform(
+    Transform &transform, const std::vector<std::string> &parametersVector)
+{
+}
+
+void VariableBase::AddTransform(Transform &transform,
+                                const Params &parametersVector)
+{
+}
+
 // transforms related functions
 void VariableBase::ClearTransforms() { m_TransformsInfo.clear(); }
 
@@ -133,7 +145,7 @@ void VariableBase::InitShapeType()
     {
         if (m_DebugMode)
         {
-            if (m_ConstantShape)
+            if (m_ConstantDims)
             {
                 throw std::invalid_argument(
                     "ERROR: isConstantShape (true) argument is invalid "
diff --git a/source/adios2/core/VariableBase.h b/source/adios2/core/VariableBase.h
index 7c17a1687623d7fa5ea3e5263557f1b5e3cffcfd..d6a69264db62080235e7d89ad2d0a1b0fd23baab 100644
--- a/source/adios2/core/VariableBase.h
+++ b/source/adios2/core/VariableBase.h
@@ -22,7 +22,6 @@
 #include "adios2/ADIOSTypes.h"
 #include "adios2/core/SelectionBoundingBox.h"
 #include "adios2/core/Transform.h"
-#include "adios2/helper/adiosFunctions.h"
 
 namespace adios
 {
@@ -41,10 +40,10 @@ public:
      *  VariableCompound -> from constructor sizeof(struct) */
     const size_t m_ElementSize;
 
-    ShapeID m_ShapeID;                  ///< see shape types in ADIOSTypes.h
-    bool m_SingleValue = false;         ///< true: single value, false: array
-    const bool m_ConstantShape = false; ///< true: fix m_Shape, m_Start, m_Count
-    Dims m_Shape;                       ///< total dimensions across MPI
+    ShapeID m_ShapeID;                 ///< see shape types in ADIOSTypes.h
+    bool m_SingleValue = false;        ///< true: single value, false: array
+    const bool m_ConstantDims = false; ///< true: fix m_Shape, m_Start, m_Count
+    Dims m_Shape;                      ///< total dimensions across MPI
     Dims m_Start; ///< starting point (offsets) in global shape
     Dims m_Count; ///< dimensions from m_Start in global shape
 
@@ -106,14 +105,11 @@ public:
     void SetStepSelection(const unsigned int startStep,
                           const unsigned int countStep);
 
-    template <class... Args>
-    void AddTransform(Transform &transform, Args... args)
-    {
-        std::vector<std::string> parameters = {args...};
-        m_TransformsInfo.emplace_back(
-            transform,
-            BuildParametersMap(parameters, m_DebugMode)); // need to check
-    }
+    void AddTransform(Transform &transform,
+                      const std::vector<std::string> &parametersVector);
+
+    void AddTransform(Transform &transform,
+                      const Params &parametersVector = Params());
 
     /** Apply current sequence of transforms defined by AddTransform */
     virtual void ApplyTransforms() = 0;
@@ -136,9 +132,9 @@ private:
         /** reference to object derived from Transform class */
         Transform &Object;
         /** parameters from AddTransform */
-        std::map<std::string, std::string> Parameters;
+        Params Parameters;
         /** resulting sizes from transformation */
-        std::vector<std::size_t> Sizes;
+        Dims Sizes;
     };
 
     /**
diff --git a/source/adios2/core/VariableCompound.tcc b/source/adios2/core/VariableCompound.tcc
index 8293bce149e8278fc6f18c167a36fc0c1cfc13d4..1c382e24b69c4b3f40048c2ff42e8488e407a34f 100644
--- a/source/adios2/core/VariableCompound.tcc
+++ b/source/adios2/core/VariableCompound.tcc
@@ -13,7 +13,7 @@
 
 #include "VariableCompound.h"
 
-#include "adios2/ADIOSConfig.h"
+#include "adios2/helper/adiosFunctions.h" //GetType
 
 namespace adios
 {
diff --git a/source/adios2/engine/dataman/DataManWriter.tcc b/source/adios2/engine/dataman/DataManWriter.tcc
index 9c3023e4574142d4cc4af2137923339ad1128237..113b0771d4b1b4f213beb429e9b439e5c0a4997a 100644
--- a/source/adios2/engine/dataman/DataManWriter.tcc
+++ b/source/adios2/engine/dataman/DataManWriter.tcc
@@ -14,6 +14,7 @@
 #include "DataManWriter.h"
 
 #include "adios2/ADIOSMPI.h"
+#include "adios2/helper/adiosFunctions.h" //GetType<T>
 
 namespace adios
 {
diff --git a/source/adios2/helper/adiosString.cpp b/source/adios2/helper/adiosString.cpp
index 69d34efd7e2d87447a3f64f0594bde7876e46c70..90b6399b131dd8f19b513e6d37236d3d63b3a65d 100644
--- a/source/adios2/helper/adiosString.cpp
+++ b/source/adios2/helper/adiosString.cpp
@@ -49,15 +49,15 @@ Params BuildParametersMap(const std::vector<std::string> &parameters,
             if (equalPosition == parameter.npos)
             {
                 throw std::invalid_argument(
-                    "ERROR: wrong format for parameter " + parameter +
-                    ", format must be field=value \n");
+                    "ERROR: wrong format for IO parameter " + parameter +
+                    ", format must be key=value for each entry \n");
             }
 
             if (equalPosition == parameter.size() - 1)
             {
-                throw std::invalid_argument("ERROR: empty value in parameter " +
-                                            parameter +
-                                            ", format must be field=value \n");
+                throw std::invalid_argument(
+                    "ERROR: empty value in IO parameter " + parameter +
+                    ", format must be key=value \n");
             }
         }