diff --git a/bindings/python/ADIOSPy.cpp b/bindings/python/ADIOSPy.cpp
index a64b2d8a281d572df963e604d4ef832a63448391..c7d161221a7b91bfbfad7e7957be707de8bb7a14 100644
--- a/bindings/python/ADIOSPy.cpp
+++ b/bindings/python/ADIOSPy.cpp
@@ -12,15 +12,30 @@
 
 #include "adiosPyTypes.h"
 
+#include "adios2/ADIOSMPI.h"
+
 namespace adios
 {
 
-ADIOSPy::ADIOSPy(MPI_Comm mpiComm, const bool debug)
-: m_DebugMode(debug), m_ADIOS(mpiComm, debug)
+ADIOSPy::ADIOSPy(const std::string configFile, MPI_Comm mpiComm,
+                 const bool debugMode)
+: m_DebugMode(debugMode), m_ADIOS(configFile, mpiComm, debugMode)
 {
 }
 
-ADIOSPy::ADIOSPy(const bool debug) : m_DebugMode(debug), m_ADIOS(debug) {}
+ADIOSPy::ADIOSPy(MPI_Comm mpiComm, const bool debugMode)
+: ADIOSPy("", mpiComm, debugMode)
+{
+}
+
+ADIOSPy::ADIOSPy(const std::string configFile, const bool debugMode)
+: ADIOSPy("", MPI_COMM_SELF, debugMode)
+{
+}
+
+ADIOSPy::ADIOSPy(const bool debugMode) : ADIOSPy("", MPI_COMM_SELF, debugMode)
+{
+}
 
 IOPy ADIOSPy::DeclareIO(const std::string name)
 {
diff --git a/bindings/python/ADIOSPy.h b/bindings/python/ADIOSPy.h
index d8cc68c9e453ebd5d840c07b369c75e3cf98107a..e1ed1f0e1964f600f87d229cadf55ae2b9acabf6 100644
--- a/bindings/python/ADIOSPy.h
+++ b/bindings/python/ADIOSPy.h
@@ -18,6 +18,7 @@
 #include <adios2.h>
 
 #include "IOPy.h"
+#include "adios2/ADIOSMPICommOnly.h"
 
 namespace adios
 {
@@ -26,8 +27,11 @@ class ADIOSPy
 {
 
 public:
-    ADIOSPy(MPI_Comm mpiComm, const bool debug);
-    ADIOSPy(const bool debug);
+    ADIOSPy(const std::string configFile, MPI_Comm mpiComm,
+            const bool debugMode);
+    ADIOSPy(MPI_Comm mpiComm, const bool debugMode);
+    ADIOSPy(const std::string configFile, const bool debugMode);
+    ADIOSPy(const bool debugMode);
     ~ADIOSPy() = default;
 
     IOPy DeclareIO(const std::string name);
diff --git a/bindings/python/gluePyBind11.cpp b/bindings/python/gluePyBind11.cpp
index a257180426b998d9537b878bc836ffa97f9960dd..358d3778193bde08867ce9027f5de5afc858c9e8 100644
--- a/bindings/python/gluePyBind11.cpp
+++ b/bindings/python/gluePyBind11.cpp
@@ -25,6 +25,26 @@
 #include "adiosPyTypes.h"
 
 #ifdef ADIOS2_HAVE_MPI
+adios::ADIOSPy ADIOSPyInitConfig(const std::string configFile,
+                                 adios::pyObject &object, const bool debugMode)
+{
+    MPI_Comm *mpiCommPtr = PyMPIComm_Get(object.ptr());
+
+    if (import_mpi4py() < 0)
+    {
+        throw std::runtime_error("ERROR: could not import mpi4py "
+                                 "communicator, in call to ADIOS "
+                                 "constructor\n");
+    }
+
+    if (mpiCommPtr == nullptr)
+    {
+        throw std::runtime_error("ERROR: mpi4py communicator is null, in call "
+                                 "to ADIOS constructor\n");
+    }
+    return adios::ADIOSPy(configFile, *mpiCommPtr, debugMode);
+}
+
 adios::ADIOSPy ADIOSPyInit(adios::pyObject &object, const bool debugMode)
 {
     MPI_Comm *mpiCommPtr = PyMPIComm_Get(object.ptr());
@@ -44,6 +64,12 @@ adios::ADIOSPy ADIOSPyInit(adios::pyObject &object, const bool debugMode)
     return adios::ADIOSPy(*mpiCommPtr, debugMode);
 }
 #else
+adios::ADIOSPy ADIOSPyInitConfig(const std::string configFile,
+                                 const bool debugMode)
+{
+    return adios::ADIOSPy(debugMode);
+}
+
 adios::ADIOSPy ADIOSPyInit(const bool debugMode)
 {
     return adios::ADIOSPy(debugMode);
@@ -69,6 +95,8 @@ PYBIND11_PLUGIN(adios2)
     m.attr("OpenModeAppend") = static_cast<int>(adios::OpenMode::Append);
     m.attr("OpenModeReadWrite") = static_cast<int>(adios::OpenMode::ReadWrite);
     m.def("ADIOS", &ADIOSPyInit, "Function that creates an ADIOS class object");
+    m.def("ADIOS", &ADIOSPyInitConfig,
+          "Function that creates an ADIOS class object using a config file");
 
     pybind11::class_<adios::ADIOSPy>(m, "ADIOSPy")
         .def("DeclareIO", &adios::ADIOSPy::DeclareIO);
diff --git a/examples/experimental/runtimeconfig/grandSchema.xml b/examples/experimental/runtimeconfig/grandSchema.xml
new file mode 100644
index 0000000000000000000000000000000000000000..71d80bd30be8c3aff11cb1adf55e28493a71fb6d
--- /dev/null
+++ b/examples/experimental/runtimeconfig/grandSchema.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+<adios-config>
+
+    <io name="Output">
+        
+        <var name="myArray"> <!-- provide a sequence of transforms -->
+            <transform type='BZip2'> <!-- not implemented yet -->
+                BlockSize100K=3; <!-- must be a number between 0 and 9-->
+            </transform>
+            <transform type="Zfp"> <!-- not implemented yet, mutually exclusive options -->
+                Tolerance=1e-3; <!-- must be a number between 0 and 9-->
+                <!-- Rate=1; --> <!-- must be a number between 0 and 9-->
+                <!-- Precision=1; --> <!-- must be a number between 0 and 9-->
+            </transform>
+        </var>
+        
+        <engine type="BPSuperEngine">
+            Threads=4; <!-- for memory operations and asynchronous tasks --> 
+        	Verbose=4;  <!-- 0 (default) to 5, not implemented -->   
+        	ProfileUnits=Microseconds; <!-- Microseconds (default), Milliseconds, Seconds, Minutes, Hours -->
+        	MaxBufferSize=20Mb;  <!-- XXKb, XXMb, or XXXGb supported, 16Mb (default should depend on system) -->
+        	InitialBufferSize=1Mb; <!-- XXKb, XXMb, or XXXGb supported, 16Kb (default shoudl depende on system) -->
+        	BufferGrowthFactor=2;  <!-- exponential growth factor > 1,  1.5 (default), for this case: 1, 2, 4, 8, 16, 20 Mb-->
+        </engine>
+        
+        <transport type="File">
+            ProfileUnits=Microseconds; <!-- Microseconds, Milliseconds, Seconds, Minutes, Hours --> 
+            Library=stdio; <!-- lowest level IO library, POSIX (default), stdio (C FILE*), fstream (C++), and interop: hdf5, netcdf? -->
+            CacheSize=8192; <!-- not to be confused with ADIOS heap buffer, this is the low-level setvbuffer, putsetbuf, default is 8192 bytes in most systems -->    
+            CollectiveMetadata=Yes; <!--  this transport requires a collective/global metadata at the end, default = no --> 
+        </transport>
+        
+        <transport type="File">
+            ProfileUnits=Microseconds; <!-- Microseconds, Milliseconds, Seconds, Minutes, Hours --> 
+            Library=hdf5; <!-- lowest level IO library, POSIX (default), stdio (C FILE*), fstream (C++), and interop: hdf5, netcdf? -->
+            Name=data.h5; <!-- Mandatory if more than one File transport to avoid conflict  -->
+        </transport>
+        
+        <transport type="SharedMemory">
+            ProfileUnits=Microseconds; <!-- Microseconds, Milliseconds, Seconds, Minutes, Hours --> 
+            Library=SystemV; <!-- lowest level shared memory library: SystemV (default), Boost (interprocess), IPC (POSIX), IPCMMap (POSIX) -->
+            Name=data.shmem; <!-- Mandatory to create process key  -->
+            SetSize=10Mb; <!-- Mandatory and fixed size (can't be extended)  -->
+        </transport>
+        
+        <transport type="NVRAM">
+            ProfileUnits=Microseconds; <!-- Microseconds, Milliseconds, Seconds, Minutes, Hours --> 
+            Library=POSIX; <!-- lowest level library -->
+            Name=/bb_location/data.bb; <!-- Mandatory  -->
+            SetSize=10Mb; <!-- Mandatory and fixed size (can't be extended)  -->
+        </transport>
+        
+        <transport type="WAN">
+            ProfileUnits=Microseconds; <!-- Microseconds, Milliseconds, Seconds, Minutes, Hours --> 
+            IPAddress=128.219.4.85; <!-- Mandatory -->
+            Port=500; <!-- Default=500? -->
+            Library=zmq; <!-- lowest level IO library, zmq, UDP, etc. -->
+            CacheSize=8192; <!-- not to be confused with ADIOS heap buffer, this is transport library cache, always in bytes -->    
+        </transport>
+        
+        <transport type="RDMA"> <!-- Staging gets more complex  depending on library requirements-->
+        	ProfileUnits=Microseconds; <!-- Microseconds, Milliseconds, Seconds, Minutes, Hours --> 
+            Library=ibverbs; <!-- SST (default), Flexpath, Dataspaces, ibverbs -->
+            Port=18515; <!-- ibverbs -->
+            IBPort=1; <!-- ibverbs -->
+            SetSize=1Mb; <!-- Mandatory and fixed size (can't be extended) -->
+            TXDepth=100; <!-- ibverbs -->
+            SocketFD=-1; <!-- ibverbs -->
+            ServerName=NULL;  <!-- ibverbs -->
+            RemoteConnection=NULL; <!-- ibverbs -->
+            IBDev=NULL; <!-- ibverbs -->
+        </transport>
+        
+    </io>
+    
+</adios-config>
\ No newline at end of file
diff --git a/examples/experimental/runtimeconfig/multipleIOResolutions.xml b/examples/experimental/runtimeconfig/multipleIOResolutions.xml
new file mode 100644
index 0000000000000000000000000000000000000000..28fe854084bc7e8126f68f2a3b70aa65b7dfc6af
--- /dev/null
+++ b/examples/experimental/runtimeconfig/multipleIOResolutions.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<adios-config>
+
+    <io name="LowResolution">
+        <var name="myArray"> <!-- provide a sequence of transforms -->
+            <transform type="Zfp"> <!-- not implemented yet, mutually exclusive options -->
+                Tolerance=1e-2; <!-- must be a number between 0 and 9-->
+                <!-- Rate=1; --> <!-- must be a number between 0 and 9-->
+                <!-- Precision=1; --> <!-- must be a number between 0 and 9-->
+            </transform>
+        </var>
+    </io>
+     
+    <io name="HighResolution">
+        <var name="myArray"> <!-- provide a sequence of transforms -->
+            <transform type="Zfp"> <!-- not implemented yet, mutually exclusive options -->
+                Tolerance=1e-5; <!-- must be a number between 0 and 9-->
+                <!-- Rate=1; --> <!-- must be a number between 0 and 9-->
+                <!-- Precision=1; --> <!-- must be a number between 0 and 9-->
+            </transform>
+        </var>
+    </io>
+         
+</adios-config>
\ No newline at end of file
diff --git a/examples/experimental/runtimeconfig/multipleTransformedVariables.xml b/examples/experimental/runtimeconfig/multipleTransformedVariables.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8338320d5ce13b1fd8cd5be57c639d52ff58fb5e
--- /dev/null
+++ b/examples/experimental/runtimeconfig/multipleTransformedVariables.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<adios-config>
+
+    <io name="LowResolution">
+        <transform type="Zfp"> <!-- not implemented yet, mutually exclusive options -->
+	        Tolerance=1e-2; <!-- must be a number between 0 and 9 -->
+	        <!-- Rate=1; --> <!-- must be a number between 0 and 9 -->
+	        <!-- Precision=1; --> <!-- must be a number between 0 and 9 -->
+	        <variable name="myArray1"></variable>
+	        <variable name="myArray2"></variable>
+	        <variable name="myArray3"></variable>
+        </transform>
+    </io>
+     
+    <io name="HighResolution">
+        <transform type="Zfp"> <!-- not implemented yet, mutually exclusive options -->
+	        Tolerance=1e-5; <!-- must be a number between 0 and 9 -->
+	        <!-- Rate=1; --> <!-- must be a number between 0 and 9 -->
+	        <!-- Precision=1; --> <!-- must be a number between 0 and 9 -->
+	        <variable name="myArray1"></variable>
+	        <variable name="myArray2"></variable>
+	        <variable name="myArray3"></variable>
+        </transform>
+    </io>
+         
+</adios-config>
diff --git a/examples/hello/bpWriter/CMakeLists.txt b/examples/hello/bpWriter/CMakeLists.txt
index a3d4cd35a3f9ffd3e32239d26fbda027e69ca8b1..c5707cdf0ed9b9ac1d0de36b7bd77b20f70d9c6f 100644
--- a/examples/hello/bpWriter/CMakeLists.txt
+++ b/examples/hello/bpWriter/CMakeLists.txt
@@ -9,7 +9,16 @@ if(ADIOS2_HAVE_MPI)
   add_executable(hello_bpWriter helloBPWriter.cpp)
   target_include_directories(hello_bpWriter PRIVATE ${MPI_C_INCLUDE_PATH})
   target_link_libraries(hello_bpWriter ${MPI_C_LIBRARIES})
+  
+  add_executable(hello_bpWriterXML helloBPWriterXML.cpp)
+  target_include_directories(hello_bpWriterXML PRIVATE ${MPI_C_INCLUDE_PATH})
+  target_link_libraries(hello_bpWriterXML ${MPI_C_LIBRARIES})
+  
 else()
   add_executable(hello_bpWriter helloBPWriter_nompi.cpp)
+  add_executable(hello_bpWriterXML helloBPWriterXML_nompi.cpp)
+  
 endif()
+
+target_link_libraries(hello_bpWriterXML adios2)
 target_link_libraries(hello_bpWriter adios2)
diff --git a/examples/hello/bpWriter/config.xml b/examples/hello/bpWriter/config.xml
deleted file mode 100644
index 10dfa830e33baed86ec3c2667f0bd6b67b2c8aa1..0000000000000000000000000000000000000000
--- a/examples/hello/bpWriter/config.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0"?>
-<adios-config>
-
-    <io name="Output">
-        <engine name="BPFileWriter">verbose=4;profile_units=mus</engine>
-        <transport name= "File">
-            profile_units=mus; 
-            abort_on_error;
-            have_metadata_file 
-               =
-                 no;
-        </transport>
-
-        <!-- Create a named transform and add variables to it here. 
-             name is optional, required only if it is used outside the definition
-             options is optional to pass parameters to the transformation
-        -->
-        <transform name="LossyCompression" transform="zfp" options="accuracy=0.001">
-            <var name="myMatrix"/>
-            <var name="ThisVarDoesNotExists"/>
-        </transform>
-
-        <!-- Unnamed transformation -->
-        <transform transform="bzip2">
-            <var name="myMatrix2"/>
-        </transform>
-
-        <!-- A variable can have its own private transform definition. 
-             Also its own ordered chain of transformations.
-             Also can refer to a transform defined previously
-        -->
-        <var name="myDoubles"> 
-            <transform transform="identity">verbose=DEBUG</transform>
-            <transform name="LossyCompression"/>
-        </var>
-
-        <buffer max-size-MB="20"/>
-    </io>
-
-</adios-config>
-
diff --git a/examples/hello/bpWriter/helloBPWriter.py b/examples/hello/bpWriter/helloBPWriter.py
index 780507684e067c519173210be2e3f8a855a67082..7332f5e7333b159d00187035f4d3911c239a3f53 100644
--- a/examples/hello/bpWriter/helloBPWriter.py
+++ b/examples/hello/bpWriter/helloBPWriter.py
@@ -1,32 +1,35 @@
-# clang-format off
 #
 # Distributed under the OSI-approved Apache License, Version 2.0.  See
 # accompanying file Copyright.txt for details.
 #
-# test_hello.py
+# helloBPWriter.py
 #  Created on: Feb 2, 2017
 #      Author: William F Godoy godoywf@ornl.gov
 
 from mpi4py import MPI
+import numpy
 import adios2
-import numpy as np
+
+# MPI
+comm = MPI.COMM_WORLD
+rank = comm.Get_rank()
+size = comm.Get_size()
 
 # User data
-myArray = np.array([1., 2., 3., 4., 5., 6.])
+myArray = numpy.array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
+Nx = myArray.size
 
-# ADIOS
-adios = adios2.ADIOS(MPI.COMM_WORLD, adios2.DebugON)
+# ADIOS MPI Communicator, debug mode
+adios = adios2.ADIOS(comm, adios2.DebugON)
 
-# IO
-bpIO = adios.DeclareIO("BPN2N")
+# ADIOS IO
+bpIO = adios.DeclareIO("BPFile_N2N")
 
-# Variable
+# ADIOS Variable name, shape, start, offset, constant dims
 ioArray = bpIO.DefineVariable(
-    "bpArray", [myArray.size], [0], [myArray.size], adios2.ConstantDims)
+    "bpArray", [size * Nx], [rank * Nx], [Nx], adios2.ConstantDims)
 
-# Engine
-bpFileWriter = bpIO.Open("myArray.bp", adios2.OpenModeWrite)
-# bpFileWriter = bpIO.Open("myArray.bp", adiosOpenModeWrite,
-# MPI.COMM_WORLD) //doesn't work
+# ADIOS Engine
+bpFileWriter = bpIO.Open("npArray.bp", adios2.OpenModeWrite)
 bpFileWriter.Write(ioArray, myArray)
 bpFileWriter.Close()
diff --git a/examples/hello/bpWriter/helloBPWriter.xml b/examples/hello/bpWriter/helloBPWriter.xml
new file mode 100644
index 0000000000000000000000000000000000000000..bda56e4c18b67f1c4a68d0558c470b80e8c9b616
--- /dev/null
+++ b/examples/hello/bpWriter/helloBPWriter.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<adios-config>
+
+    <io name="BPFile_N2N">
+        <engine type="BPFileWriter">
+            Threads=1; <!-- for vectorized memory operations and asynchronous tasks --> 
+            ProfileUnits=Microseconds; <!-- Microseconds (default), Milliseconds, Seconds, Minutes, Hours -->
+            MaxBufferSize=20Mb;  <!-- XXKb, XXMb, or XXXGb supported, 16Mb (default should depend on system) -->
+            InitialBufferSize=1Mb; <!-- XXKb, XXMb, or XXXGb supported, 16Kb (default should depend on system) -->
+            BufferGrowthFactor=2;  <!-- exponential growth factor > 1,  1.5 (default, e.g. STL default=2), for this case: 1, 2, 4, 8, 16, 20 Mb-->
+        </engine>
+
+        <transport type="File">
+            Library=POSIX;
+            ProfileUnits=Milliseconds;
+        </transport>
+
+    </io>
+
+</adios-config>
\ No newline at end of file
diff --git a/examples/hello/bpWriter/helloBPWriterXML.cpp b/examples/hello/bpWriter/helloBPWriterXML.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..807b0c9c32f948dc2aebe694fdd194664eef8653
--- /dev/null
+++ b/examples/hello/bpWriter/helloBPWriterXML.cpp
@@ -0,0 +1,82 @@
+/*
+ * Distributed under the OSI-approved Apache License, Version 2.0.  See
+ * accompanying file Copyright.txt for details.
+ *
+ * helloBPWriter.cpp: Simple self-descriptive example of how to write a variable
+ * to a BP File that lives in several MPI processes.
+ *
+ *  Created on: Feb 16, 2017
+ *      Author: William F Godoy godoywf@ornl.gov
+ */
+
+#include <ios>      //std::ios_base::failure
+#include <iostream> //std::cout
+#include <mpi.h>
+#include <stdexcept> //std::invalid_argument std::exception
+#include <vector>
+
+#include <adios2.h>
+
+int main(int argc, char *argv[])
+{
+    MPI_Init(&argc, &argv);
+    int rank, size;
+    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+    MPI_Comm_size(MPI_COMM_WORLD, &size);
+
+    /** Application variable */
+    std::vector<float> myFloats = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+    const std::size_t Nx = myFloats.size();
+
+    try
+    {
+        /** ADIOS class factory of IO class objects, DebugON is recommended */
+        adios::ADIOS adios("helloBPWriter.xml", MPI_COMM_WORLD, adios::DebugON);
+
+        /*** IO class object: settings and factory of Settings: Variables,
+         * Parameters, Transports, and Execution: Engines */
+        adios::IO &bpIO = adios.DeclareIO("BPFile_N2N");
+
+        /** global array : name, { shape (total) }, { start (local) }, { count
+         * (local) }, all are constant dimensions */
+        adios::Variable<float> &bpFloats = bpIO.DefineVariable<float>(
+            "bpFloats", {size * Nx}, {rank * Nx}, {Nx}, adios::ConstantDims);
+
+        /** Engine derived class, spawned to start IO operations */
+        auto bpWriter = bpIO.Open("myVector.bp", adios::OpenMode::Write);
+
+        if (!bpWriter)
+        {
+            throw std::ios_base::failure(
+                "ERROR: bpWriter not created at Open\n");
+        }
+
+        /** Write variable for buffering */
+        bpWriter->Write<float>(bpFloats, myFloats.data());
+
+        /** Create bp file, engine becomes unreachable after this*/
+        bpWriter->Close();
+    }
+    catch (std::invalid_argument &e)
+    {
+        std::cout << "Invalid argument exception, STOPPING PROGRAM from rank "
+                  << rank << "\n";
+        std::cout << e.what() << "\n";
+    }
+    catch (std::ios_base::failure &e)
+    {
+        std::cout
+            << "IO System base failure exception, STOPPING PROGRAM from rank "
+            << rank << "\n";
+        std::cout << e.what() << "\n";
+    }
+    catch (std::exception &e)
+    {
+        std::cout << "Exception, STOPPING PROGRAM from rank " << rank << "\n";
+        std::cout << e.what() << "\n";
+    }
+
+    MPI_Finalize();
+
+    return 0;
+}
diff --git a/examples/hello/bpWriter/helloBPWriterXML.py b/examples/hello/bpWriter/helloBPWriterXML.py
new file mode 100644
index 0000000000000000000000000000000000000000..2d81dd0bd990693198d92fed91eca035e3b81548
--- /dev/null
+++ b/examples/hello/bpWriter/helloBPWriterXML.py
@@ -0,0 +1,36 @@
+#
+# Distributed under the OSI-approved Apache License, Version 2.0.  See
+# accompanying file Copyright.txt for details.
+#
+# helloBPWriterXML.py
+#  Created on: Feb 2, 2017
+#      Author: William F Godoy godoywf@ornl.gov
+
+from mpi4py import MPI
+import adios2
+import numpy
+
+# MPI
+comm = MPI.COMM_WORLD
+rank = comm.Get_rank()
+size = comm.Get_size()
+
+# User data
+myArray = numpy.array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
+Nx = myArray.size
+
+# ADIOS config file, MPI communicator, debug mode
+adios = adios2.ADIOS("helloBPWriter.xml", comm, adios2.DebugON)
+
+# ADIOS IO, name must be the same as in helloBPWriter.xml for runtime settings
+bpIO = adios.DeclareIO("BPFile_N2N")
+
+# Variable name, shape, start, count, ConstantDims = True
+ioArray = bpIO.DefineVariable(
+    "bpArray", [size * Nx], [rank * Nx], [Nx], adios2.ConstantDims)
+
+# Engine name, open mode
+bpFileWriter = bpIO.Open("npArray.bp", adios2.OpenModeWrite)
+# Write  variable, numpy object
+bpFileWriter.Write(ioArray, myArray)
+bpFileWriter.Close()
diff --git a/examples/hello/bpWriter/helloBPWriterXML_nompi.cpp b/examples/hello/bpWriter/helloBPWriterXML_nompi.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8028787a699932f8f7c4079f30b5de9c67f61630
--- /dev/null
+++ b/examples/hello/bpWriter/helloBPWriterXML_nompi.cpp
@@ -0,0 +1,71 @@
+/*
+ * Distributed under the OSI-approved Apache License, Version 2.0.  See
+ * accompanying file Copyright.txt for details.
+ *
+ * helloBPWriterXML_nompi.cpp: sequential non-mpi version of helloBPWriterXML
+ *
+ *  Created on: Feb 16, 2017
+ *      Author: William F Godoy godoywf@ornl.gov
+ */
+
+#include <ios>      //std::ios_base::failure
+#include <iostream> //std::cout
+#include <mpi.h>
+#include <stdexcept> //std::invalid_argument std::exception
+#include <vector>
+
+#include <adios2.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();
+
+    try
+    {
+        /** ADIOS class factory of IO class objects, DebugON is recommended */
+        adios::ADIOS adios("helloBPWriter.xml", adios::DebugON);
+
+        /*** IO class object: settings and factory of Settings: Variables,
+         * Parameters, Transports, and Execution: Engines */
+        adios::IO &bpIO = adios.DeclareIO("BPFile_N2N");
+
+        /** global array : name, { shape (total) }, { start (local) }, { count
+         * (local) }, all are constant dimensions */
+        adios::Variable<float> &bpFloats = bpIO.DefineVariable<float>(
+            "bpFloats", {}, {}, {Nx}, adios::ConstantDims);
+
+        /** Engine derived class, spawned to start IO operations */
+        auto bpWriter = bpIO.Open("myVector.bp", adios::OpenMode::Write);
+
+        if (!bpWriter)
+        {
+            throw std::ios_base::failure(
+                "ERROR: bpWriter not created at Open\n");
+        }
+
+        /** Write variable for buffering */
+        bpWriter->Write<float>(bpFloats, myFloats.data());
+
+        /** Create bp file, engine becomes unreachable after this*/
+        bpWriter->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/examples/hello/bpWriter/helloBPWriterXML_nompi.py b/examples/hello/bpWriter/helloBPWriterXML_nompi.py
new file mode 100644
index 0000000000000000000000000000000000000000..0373d1e67294ef45e72ff7e1ef04e9f767098da7
--- /dev/null
+++ b/examples/hello/bpWriter/helloBPWriterXML_nompi.py
@@ -0,0 +1,30 @@
+#
+# Distributed under the OSI-approved Apache License, Version 2.0.  See
+# accompanying file Copyright.txt for details.
+#
+# helloBPWriterXML_nompi.py serial non-MPI version of helloBPWriter.py
+#  Created on: Feb 2, 2017
+#      Author: William F Godoy godoywf@ornl.gov
+
+import numpy
+import adios2
+
+
+# User data
+myArray = numpy.array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
+Nx = myArray.size
+
+# ADIOS config file, debug mode
+adios = adios2.ADIOS("helloBPWriter.xml", adios2.DebugON)
+
+# ADIOS IO, name must be the same as in helloBPWriter.xml for runtime settings
+bpIO = adios.DeclareIO("BPFile_N2N")
+
+# ADIOS local array: Variable name, shape, start, offset
+ioArray = bpIO.DefineVariable(
+    "bpArray", [], [], [Nx], adios2.ConstantDims)
+
+# ADIOS Engine
+bpFileWriter = bpIO.Open("npArray.bp", adios2.OpenModeWrite)
+bpFileWriter.Write(ioArray, myArray)
+bpFileWriter.Close()
diff --git a/source/adios2/ADIOSMPI.h b/source/adios2/ADIOSMPI.h
index 3524532d34ee3e5b81ef977f6269cf25a813047e..95ae7619aebdb9b32af02a9f6adbd7b2488f06a3 100644
--- a/source/adios2/ADIOSMPI.h
+++ b/source/adios2/ADIOSMPI.h
@@ -14,4 +14,17 @@
 #include "adios2/mpidummy.h"
 #endif
 
+#include <climits> //UXXX_MAX
+#include <cstdint> //SIZE_MAX
+
+#if SIZE_MAX == UINT_MAX
+#define ADIOS2_MPI_SIZE_T MPI_UNSIGNED
+#elif SIZE_MAX == ULONG_MAX
+#define ADIOS2_MPI_SIZE_T MPI_UNSIGNED_LONG
+#elif SIZE_MAX == ULLONG_MAX
+#define ADIOS2_MPI_SIZE_T MPI_UNSIGNED_LONG_LONG
+#else
+#error "size_t could not be mapped to a MPI Type"
+#endif
+
 #endif /* ADIOS2_ADIOSMPI_H_ */
diff --git a/source/adios2/core/ADIOS.cpp b/source/adios2/core/ADIOS.cpp
index ee373fb869ae75a4d98457b0624646fbfb31af55..194dbdddbf081a4f511cf95c17c632a143fe8c79 100644
--- a/source/adios2/core/ADIOS.cpp
+++ b/source/adios2/core/ADIOS.cpp
@@ -19,6 +19,7 @@
 /// \endcond
 
 #include "adios2/ADIOSMPI.h"
+#include "adios2/helper/adiosFunctions.h"
 
 namespace adios
 {
@@ -31,9 +32,14 @@ ADIOS::ADIOS(const std::string configFile, MPI_Comm mpiComm,
     {
         CheckMPI();
     }
-    // XML to be implemented later
-    // InitXML( m_XMLConfigFile, m_MPIComm, m_DebugMode, m_HostLanguage,
-    // m_Transforms, m_Groups );
+    if (!configFile.empty())
+    {
+        if (configFile.substr(configFile.size() - 3) == "xml")
+        {
+            InitXML(configFile, m_MPIComm, m_DebugMode, m_Transforms, m_IOs);
+        }
+        // TODO expand for other formats
+    }
 }
 
 ADIOS::ADIOS(const std::string configFile, const bool debugMode)
@@ -56,7 +62,7 @@ IO &ADIOS::DeclareIO(const std::string ioName)
     {
         if (m_DebugMode)
         {
-            if (itIO->second.InConfigFile())
+            if (!itIO->second.InConfigFile())
             {
                 throw std::invalid_argument(
                     "ERROR: IO class object with name " + ioName +
diff --git a/source/adios2/helper/adiosString.cpp b/source/adios2/helper/adiosString.cpp
index 90b6399b131dd8f19b513e6d37236d3d63b3a65d..bc7841276e0f8e0490ac6006134e1d618940919b 100644
--- a/source/adios2/helper/adiosString.cpp
+++ b/source/adios2/helper/adiosString.cpp
@@ -24,9 +24,9 @@ std::string FileToString(const std::string &fileName)
 {
     std::ifstream fileStream(fileName);
 
-    if (!fileStream.good())
+    if (!fileStream)
     {
-        throw std::ios_base::failure(
+        throw std::invalid_argument(
             "ERROR: file " + fileName +
             " could not be opened. Check permissions or existence\n");
     }
diff --git a/source/adios2/helper/adiosSystem.cpp b/source/adios2/helper/adiosSystem.cpp
index 9836130796bb035d886d0d8c60bd334c20748ac5..bc8acdcfbd07366e149c0d79f6aa86d9eba3f2b4 100644
--- a/source/adios2/helper/adiosSystem.cpp
+++ b/source/adios2/helper/adiosSystem.cpp
@@ -16,7 +16,9 @@
 #include <chrono> //system_clock, now
 #include <ctime>  //std::ctime
 
+#include "adios2/ADIOSMPI.h"
 #include "adios2/ADIOSTypes.h"
+#include "adios2/helper/adiosString.h"
 
 namespace adios
 {
@@ -77,4 +79,41 @@ std::string LocalTimeDate() noexcept
     return std::string(std::ctime(&now));
 }
 
+std::string BroadcastString(const std::string &input, MPI_Comm mpiComm)
+{
+    std::string receivedInput;
+    size_t characterCount = 0;
+
+    int rank;
+    MPI_Comm_rank(mpiComm, &rank);
+
+    if (rank == 0) // sender
+    {
+        characterCount = input.size();
+
+        // broadcast size for allocation
+        MPI_Bcast(&characterCount, 1, ADIOS2_MPI_SIZE_T, 0, mpiComm);
+
+        // broadcast contents
+        MPI_Bcast(const_cast<char *>(input.c_str()),
+                  static_cast<int>(characterCount), MPI_CHAR, 0, mpiComm);
+
+        return input;
+    }
+    else // receivers
+    {
+        // receive size
+        MPI_Bcast(&characterCount, 1, ADIOS2_MPI_SIZE_T, 0, mpiComm);
+
+        // allocate receiver
+        std::vector<char> stringReceiver(characterCount);
+        MPI_Bcast(stringReceiver.data(), static_cast<int>(characterCount),
+                  MPI_CHAR, 0, mpiComm);
+
+        receivedInput.assign(stringReceiver.begin(), stringReceiver.end());
+    }
+
+    return receivedInput;
+}
+
 } // end namespace adios
diff --git a/source/adios2/helper/adiosSystem.h b/source/adios2/helper/adiosSystem.h
index 9374d160370839377b6c4897f3b489fbb850216e..389e095dd838048a5503549abe4fea970dbc0eb4 100644
--- a/source/adios2/helper/adiosSystem.h
+++ b/source/adios2/helper/adiosSystem.h
@@ -17,6 +17,8 @@
 #include <vector>
 /// \endcond
 
+#include "adios2/ADIOSMPICommOnly.h"
+
 namespace adios
 {
 
@@ -41,6 +43,15 @@ bool IsLittleEndian() noexcept;
  */
 std::string LocalTimeDate() noexcept;
 
+/**
+ * Rank 0: opens file, dumps contents string and broadcast.
+ * Others: receive std::vector<char> and copy to a string
+ * @param fileName
+ * @param mpiComm
+ * @return fileContents as a single string
+ */
+std::string BroadcastString(const std::string &input, MPI_Comm mpiComm);
+
 } // end namespace adios
 
 #endif /* ADIOS2_HELPER_ADIOSSYSTEM_H_ */
diff --git a/source/adios2/helper/adiosXML.cpp b/source/adios2/helper/adiosXML.cpp
index 746a436145472b910e58d2dccec7e6adc8b9d363..d52968e1ecfc1e24989269973d320b4a2b1dfb4b 100644
--- a/source/adios2/helper/adiosXML.cpp
+++ b/source/adios2/helper/adiosXML.cpp
@@ -11,386 +11,457 @@
 #include "adiosXML.h"
 
 /// \cond EXCLUDE_FROM_DOXYGEN
+#include <sstream>
 #include <stdexcept> //std::invalid_argument
 /// \endcond
 
+#include "adios2/ADIOSTypes.h"
+#include "adios2/helper/adiosString.h"
+
 namespace adios
 {
 
-void GetSubString(const std::string initialTag, const std::string finalTag,
-                  const std::string content, std::string &subString,
-                  std::string::size_type &currentPosition)
+void RemoveCommentsXML(std::string &currentContent) noexcept
 {
-    auto lf_Wipe = [](std::string &subString,
-                      std::string::size_type &currentPosition) {
-        subString.clear();
-        currentPosition = std::string::npos;
-    };
+    std::string::size_type startComment(currentContent.find("<!--"));
 
+    while (startComment != currentContent.npos)
+    {
+        std::string::size_type endComment(currentContent.find("-->"));
+        currentContent.erase(startComment, endComment - startComment + 3);
+        startComment = currentContent.find("<!--");
+    }
+}
+
+TagXML GetTagXML(const std::string tagName, const std::string &content,
+                 std::string::size_type &position)
+{
     auto lf_SetPositions =
-        [](const char quote, const std::string::size_type quotePosition,
-           const std::string &content, std::string::size_type &currentPosition,
-           std::string::size_type &closingQuotePosition) {
-            currentPosition = quotePosition;
-            closingQuotePosition = content.find(quote, currentPosition + 1);
-        };
-
-    // BODY OF FUNCTION STARTS HERE
-    std::string::size_type start(content.find(initialTag, currentPosition));
-    if (start == content.npos)
+        [](const std::string input, const std::string &content,
+           std::string::size_type &position) -> std::string::size_type {
+
+        const std::string::size_type inputPosition =
+            GetStringPositionXML(input, content, position);
+
+        if (inputPosition != std::string::npos)
+        {
+            position = inputPosition + input.size();
+        }
+        return inputPosition;
+    };
+
+    TagXML tagXML;
+
+    std::string name(tagName);
+    if (name.back() == ' ')
     {
-        lf_Wipe(subString, currentPosition);
-        return;
+        name.pop_back();
     }
-    currentPosition = start;
 
-    std::string::size_type end(content.find(finalTag, currentPosition));
-    if (end == content.npos)
+    auto openingStart = lf_SetPositions("<" + name, content, position);
+    auto openingEnd = lf_SetPositions(">", content, position);
+
+    if (openingStart == std::string::npos || openingEnd == std::string::npos)
     {
-        lf_Wipe(subString, currentPosition);
-        return;
+        tagXML.IsFull = false;
+        return tagXML;
     }
 
-    // here make sure the finalTag is not a value surrounded by " " or ' ', if
-    // so
-    // find next
-    bool isValue = true;
+    tagXML.Header = content.substr(openingStart, openingEnd + 1 - openingStart);
+
+    auto closingStart =
+        GetStringPositionXML("</" + name + ">", content, position);
 
-    while (isValue)
+    if (closingStart == std::string::npos)
     {
-        std::string::size_type singleQuotePosition =
-            content.find('\'', currentPosition);
-        std::string::size_type doubleQuotePosition =
-            content.find('\"', currentPosition);
+        throw std::invalid_argument(
+            "ERROR: could not find closing tag </" + name +
+            "> in XML config file, in call to ADIOS constructor\n");
+    }
+    tagXML.IsFull = true;
+    tagXML.Elements =
+        content.substr(openingEnd + 1, closingStart - (openingEnd + 1));
+
+    //    std::cout << "START..." << tagXML.Header << "...";
+    //    std::cout << tagXML.Elements << "...END\n";
+
+    return tagXML;
+}
+
+std::string::size_type
+GetStringPositionXML(const std::string input, const std::string &content,
+                     const std::string::size_type &startPosition) noexcept
+{
+    std::string::size_type foundPosition(content.find(input, startPosition));
+    if (foundPosition == content.npos)
+    {
+        return foundPosition;
+    }
+
+    // check if it is not inside " " or ' '
+    std::string::size_type currentPosition(startPosition);
+
+    while (foundPosition != content.npos)
+    {
+        const std::string::size_type singleQuotePosition(
+            content.find('\'', currentPosition));
+        const std::string::size_type doubleQuotePosition(
+            content.find('\"', currentPosition));
 
         if ((singleQuotePosition == content.npos &&
              doubleQuotePosition == content.npos) ||
             (singleQuotePosition == content.npos &&
-             end < doubleQuotePosition) ||
+             foundPosition < doubleQuotePosition) ||
             (doubleQuotePosition == content.npos &&
-             end < singleQuotePosition) ||
-            (end < singleQuotePosition && end < doubleQuotePosition))
+             foundPosition < singleQuotePosition) ||
+            (foundPosition < singleQuotePosition &&
+             foundPosition < doubleQuotePosition))
         {
             break;
         }
-
         // find the closing corresponding quote
         std::string::size_type closingQuotePosition;
 
-        if (singleQuotePosition == content.npos)
-        { // no ' anywhere
-            lf_SetPositions('\"', doubleQuotePosition, content, currentPosition,
-                            closingQuotePosition);
+        if (singleQuotePosition != content.npos &&
+            doubleQuotePosition == content.npos)
+        {
+            currentPosition = singleQuotePosition;
+            closingQuotePosition = content.find('\'', currentPosition + 1);
         }
-        else if (doubleQuotePosition == content.npos)
-        { // no " anywhere
-            lf_SetPositions('\'', singleQuotePosition, content, currentPosition,
-                            closingQuotePosition);
+        else if (singleQuotePosition == content.npos &&
+                 doubleQuotePosition != content.npos)
+        {
+            currentPosition = doubleQuotePosition;
+            closingQuotePosition = content.find('\"', currentPosition + 1);
         }
         else
         {
             if (singleQuotePosition < doubleQuotePosition)
             {
-                lf_SetPositions('\'', singleQuotePosition, content,
-                                currentPosition, closingQuotePosition);
+                currentPosition = singleQuotePosition;
+                closingQuotePosition = content.find('\'', currentPosition + 1);
             }
             else
-            { // find the closing "
-                lf_SetPositions('\"', doubleQuotePosition, content,
-                                currentPosition, closingQuotePosition);
+            {
+                currentPosition = doubleQuotePosition;
+                closingQuotePosition = content.find('\"', currentPosition + 1);
             }
         }
-
-        if (closingQuotePosition ==
-            content.npos) // if can't find closing it's open until the end
+        // if can't find closing it's open until the end
+        if (closingQuotePosition == content.npos)
         {
-            lf_Wipe(subString, currentPosition);
-            return;
+            currentPosition == content.npos;
+            break;
         }
 
         currentPosition = closingQuotePosition + 1;
 
-        if (closingQuotePosition < end)
+        if (closingQuotePosition < foundPosition)
         {
             continue;
         }
+        else
+        {
+            // if this point is reached it means it's a value inside " " or ' ',
+            // iterate
+            foundPosition = content.find(input, currentPosition);
+            currentPosition = foundPosition;
+        }
+    }
+
+    return foundPosition;
+}
+
+Params GetTagAttributesXML(const std::string &tagHeader)
+{
+    auto lf_GetQuotedValue = [](const char quote,
+                                const std::string::size_type &quotePosition,
+                                std::string &currentTag) -> std::string {
+
+        currentTag = currentTag.substr(quotePosition + 1);
+        auto nextQuotePosition = currentTag.find(quote);
+
+        if (nextQuotePosition == currentTag.npos)
+        {
+            throw std::invalid_argument(
+                "ERROR: Invalid attribute in..." + currentTag +
+                "...check XML file, in call to ADIOS constructor\n");
+        }
+
+        const std::string value(currentTag.substr(0, nextQuotePosition));
+        currentTag = currentTag.substr(nextQuotePosition + 1);
+        return value;
+    };
+
+    auto lf_GetAttributes = [&](const std::string &tag) -> Params {
+        Params attributes;
+        std::string currentTag(tag.substr(tag.find_first_of(" \t\n")));
+
+        while (currentTag.find('=') != currentTag.npos) // equalPosition
+        {
+            currentTag =
+                currentTag.substr(currentTag.find_first_not_of(" \t\n"));
+            auto equalPosition = currentTag.find('=');
+            if (currentTag.size() <= equalPosition + 1)
+            {
+                throw std::invalid_argument(
+                    "ERROR: tag " + tag +
+                    " is incomplete, check XML config file, "
+                    "in call to ADIOS constructor\n");
+            }
+
+            const std::string key(currentTag.substr(0, equalPosition));
+            std::string value;
+
+            const char quote = currentTag[equalPosition + 1];
+            if (quote == '\'' || quote == '"')
+            {
+                value = lf_GetQuotedValue(quote, equalPosition + 1, currentTag);
+            }
+            else
+            {
+                // throw exception here?
+            }
+
+            attributes.emplace(key, value);
+        }
+        return attributes;
+    };
+
+    // BODY of function starts here
+    Params attributes;
+    // eliminate < >
+    std::string openingTag = tagHeader.substr(1, tagHeader.size() - 2);
+
+    if (tagHeader.back() == '/') // last char is / --> "XML empty tag"
+    {
+        // attributes = lf_GetAttributes(openingTag);
+        // throw exception here, ADIOS2 doesn't allow XML empty tags
+    }
+    else if (tagHeader[0] == '/') // first char is / ---> closing tag
+    {
+        attributes = lf_GetAttributes(openingTag);
+        if (attributes.size() > 0)
+        {
+            throw std::invalid_argument(
+                "ERROR: closing tag " + tagHeader +
+                " can't have attributes, in call to ADIOS constructor\n");
+        }
+    }
+    else // opening tag
+    {
+        attributes = lf_GetAttributes(openingTag);
+    }
+    return attributes;
+}
+
+void InitXML(const std::string configXML, const MPI_Comm mpiComm,
+             const bool debugMode,
+             std::vector<std::shared_ptr<Transform>> &transforms,
+             std::map<std::string, IO> &ios)
+{
+    // independent IO
+    std::string fileContents(FileToString(configXML));
+    RemoveCommentsXML(fileContents);
+
+    // adios-config
+    std::string::size_type position(0);
+    const TagXML adiosConfigXML(
+        GetTagXML("adios-config", fileContents, position));
+
+    // process transforms, not yet implemented
+
+    while (position != std::string::npos)
+    {
+        const TagXML transformXML(
+            GetTagXML("transform ", adiosConfigXML.Elements, position));
 
-        // if this point is reached it means it's a value inside " " or ' ',
-        // move to
-        // the next end
-        end = content.find(finalTag, currentPosition);
+        if (transformXML.Header.empty())
+        {
+            break;
+        }
+        // InitTransform(transformTag, debugMode, transforms);
     }
 
-    subString = content.substr(start, end - start + finalTag.size());
-    currentPosition = end;
+    position = 0;
+    // process IOs
+    while (position != std::string::npos)
+    {
+        // io
+        const TagXML ioXML(GetTagXML("io ", adiosConfigXML.Elements, position));
+
+        if (ioXML.Header.empty()) // no more groups to find
+        {
+            break;
+        }
+        InitIOXML(ioXML, mpiComm, debugMode, transforms, ios);
+    }
 }
 
-void GetQuotedValue(const char quote,
-                    const std::string::size_type &quotePosition,
-                    std::string &currentTag, std::string &value)
+void InitIOXML(const TagXML &ioXML, const MPI_Comm mpiComm,
+               const bool debugMode,
+               std::vector<std::shared_ptr<Transform>> &transforms,
+               std::map<std::string, IO> &ios)
 {
-    currentTag = currentTag.substr(quotePosition + 1);
-    auto nextQuotePosition = currentTag.find(quote);
+    const Params ioAttributes(GetTagAttributesXML(ioXML.Header));
+
+    std::string ioName;
+    for (const auto &ioAttribute : ioAttributes)
+    {
+        if (ioAttribute.first == "name")
+        {
+            ioName = ioAttribute.second;
+        }
+    }
+
+    if (debugMode)
+    {
+        if (ioName.empty())
+        {
+            throw std::invalid_argument(
+                "ERROR: io name=\"value\" attribute not found in opening XML "
+                "tag " +
+                ioXML.Header +
+                ", check XML config file, in call to ADIOS constructor\n");
+        }
+
+        if (ios.count(ioName) == 1) // io exists
+        {
+            throw std::invalid_argument("ERROR: io name " + ioName +
+                                        " must be unique in XML config file, "
+                                        "in call to ADIOS constructor\n");
+        }
+    }
+
+    // emplace io with inConfigFile argument as true
+    auto itIO = ios.emplace(ioName, IO(ioName, mpiComm, true, debugMode));
+
+    // process engine
+    std::string::size_type position(0);
+
+    TagXML engineXML(GetTagXML("engine ", ioXML.Elements, position));
+    if (!engineXML.Header.empty()) // found first one
+    {
+        InitEngineXML(engineXML, debugMode, itIO.first->second);
+    }
 
-    if (nextQuotePosition == currentTag.npos)
+    if (debugMode)
     {
-        throw std::invalid_argument("ERROR: Invalid attribute in..." +
-                                    currentTag + "...check XML file\n");
+        // try finding a 2nd one from current position
+        TagXML engineXML(GetTagXML("engine ", ioXML.Elements, position));
+        if (!engineXML.Header.empty()) // found first one
+        {
+            throw std::invalid_argument(
+                "ERROR: more than one engine found in <io name=" + ioName +
+                "...>, only one per io tag is allowed in XML "
+                "config file, in call to "
+                "ADIOS constructor\n");
+        }
     }
 
-    value = currentTag.substr(0, nextQuotePosition);
-    currentTag = currentTag.substr(nextQuotePosition + 1);
+    position = 0;
+    // process transports
+    while (position != std::string::npos)
+    {
+        TagXML transportXML(GetTagXML("transport", ioXML.Elements, position));
+
+        if (transportXML.Header.empty()) // no more groups to find
+        {
+            break;
+        }
+        InitTransportXML(transportXML, debugMode, itIO.first->second);
+    }
 }
 
-void GetPairs(const std::string tag,
-              std::vector<std::pair<const std::string, const std::string>>
-                  &pairs) noexcept
+void InitEngineXML(const TagXML &engineXML, const bool debugMode, IO &io)
 {
-    std::string currentTag(
-        tag.substr(tag.find_first_of(" \t\n"))); // initialize current tag
+    const Params attributes = GetTagAttributesXML(engineXML.Header);
 
-    while (currentTag.find('=') != currentTag.npos) // equalPosition
+    std::string type;
+    for (const auto &attribute : attributes)
     {
-        currentTag = currentTag.substr(currentTag.find_first_not_of(" \t\n"));
-        auto equalPosition = currentTag.find('=');
-        const std::string field(
-            currentTag.substr(0, equalPosition)); // get field
-        std::string value;
-
-        const char quote = currentTag[equalPosition + 1];
-        if (quote == '\'' || quote == '"') // single quotes
+        if (attribute.first == "type")
         {
-            GetQuotedValue(quote, equalPosition + 1, currentTag, value);
+            type = attribute.second;
+            break;
         }
+    }
 
-        pairs.push_back(
-            std::pair<const std::string, const std::string>(field, value));
+    if (!type.empty())
+    {
+        io.SetEngine(type);
     }
+
+    io.SetParameters(ParseParamsXML(engineXML.Elements, debugMode));
 }
 
-void GetPairsFromTag(
-    const std::string &fileContent, const std::string tag,
-    std::vector<std::pair<const std::string, const std::string>> &pairs)
+void InitTransportXML(const TagXML &transportXML, const bool debugMode, IO &io)
 {
-    if (tag.back() == '/') // last char is / --> "XML empty tag"
+    const Params attributes = GetTagAttributesXML(transportXML.Header);
+
+    std::string type;
+    for (const auto &attribute : attributes)
     {
-        GetPairs(tag, pairs);
+        if (attribute.first == "type")
+        {
+            type = attribute.second;
+            break;
+        }
     }
-    else if (tag[0] == '/') // first char is / ---> closing tag
+
+    if (type.empty())
     {
+        throw std::invalid_argument(
+            "ERROR: missing transport type in " + transportXML.Header +
+            ", in XML config file, in call to ADIOS constructor\n");
     }
-    else // opening tag
+
+    io.AddTransport(type, ParseParamsXML(transportXML.Elements, debugMode));
+}
+
+Params ParseParamsXML(const std::string &tagElements, const bool debugMode)
+{
+    auto start = tagElements.find_first_not_of(" \t\n");
+    auto end = tagElements.find_last_not_of(" \t\n");
+
+    std::string parametersString(tagElements.substr(start, end - start + 1));
+    if (debugMode)
     {
-        const std::string tagName(tag.substr(0, tag.find_first_of(" \t\n\r")));
-        const std::string closingTagName("</" + tagName +
-                                         ">"); // check for closing tagName
+        if (parametersString.back() != ';')
+        {
+            throw std::invalid_argument(
+                "ERROR: parameters in config XML file must end with a ; " +
+                tagElements + ", in call to ADIOS constructor\n");
+        }
+    }
+
+    std::istringstream parametersSS(parametersString);
+    std::string pair;
+
+    Params parameters;
+
+    while (std::getline(parametersSS, pair, ';'))
+    {
+        pair = pair.substr(pair.find_first_not_of(" \t\n"));
+        auto equalPosition = pair.find("=");
 
-        if (fileContent.find(closingTagName) == fileContent.npos)
+        if (debugMode)
         {
-            throw std::invalid_argument("ERROR: closing tag " + closingTagName +
-                                        " missing, check XML file\n");
+            if (equalPosition == std::string::npos ||
+                equalPosition == pair.size())
+            {
+                throw std::invalid_argument("ERROR: wrong parameter " + pair +
+                                            " format is "
+                                            "key=value in XML config file, in "
+                                            "call to ADIOS constructor\n");
+            }
         }
 
-        GetPairs(tag, pairs);
+        const std::string key(pair.substr(0, equalPosition));
+        const std::string value(pair.substr(equalPosition + 1));
+        parameters.emplace(key, value);
     }
+    return parameters;
 }
 
-// void SetMembers( const std::string& fileContent, const MPI_Comm mpiComm,
-// const bool debugMode,
-//                 std::string& hostLanguage, std::vector<
-//                 std::shared_ptr<Transform> >& transforms,
-//                 std::map< std::string, Group >& groups )
-//{
-//    //adios-config
-//    std::string currentContent;
-//    std::string::size_type currentPosition( 0 );
-//    GetSubString( "<adios-config ", "</adios-config>", fileContent,
-//    currentContent, currentPosition );
-//
-//    //remove comment sections
-//    std::string::size_type startComment ( currentContent.find( "<!--" ) );
-//
-//    while( startComment != currentContent.npos )
-//    {
-//        std::string::size_type endComment( currentContent.find( "-->") );
-//        currentContent.erase( startComment, endComment-startComment+3 );
-//        startComment = currentContent.find( "<!--" );
-//    }
-//
-//    //Tag <adios-config
-//    currentPosition = 0;
-//
-//    std::string tag; //use for < > tags
-//    GetSubString( "<adios-config", ">", currentContent, tag, currentPosition
-//    );
-//    tag = tag.substr( 1, tag.size() - 2 ); //eliminate < >
-//
-//    std::vector< std::pair<const std::string, const std::string> > pairs; //
-//    pairs in tag
-//    GetPairsFromTag( currentContent, tag, pairs );
-//
-//    for( auto& pair : pairs )
-//        if( pair.first == "host-language" )
-//            hostLanguage = pair.second;
-//
-//    if( debugMode )
-//    {
-//        if( Support::HostLanguages.count( hostLanguage ) == 0 )
-//            throw std::invalid_argument("ERROR: host language " + hostLanguage
-//            + " not supported.\n" );
-//
-//        if( hostLanguage.empty() )
-//            throw std::invalid_argument("ERROR: host language is empty.\n" );
-//    }
-//
-//    //adios-group
-//    currentPosition = 0;
-//
-//    while( currentPosition != std::string::npos )
-//    {
-//        std::string xmlGroup;
-//        GetSubString("<adios-group ", "</adios-group>", currentContent,
-//        xmlGroup, currentPosition ); //Get all group contents
-//
-//        if( xmlGroup.empty() ) //no more groups to find
-//            break;
-//
-//        //get group name
-//        std::string::size_type groupPosition( 0 );
-//        GetSubString( "<adios-group ", ">", xmlGroup, tag, groupPosition );
-//        if( debugMode )
-//        {
-//            if( tag.size() < 2 )
-//                throw std::invalid_argument( "ERROR: wrong tag " + tag + " in
-//                adios-group\n" ); //check < or <=
-//        }
-//
-//        tag = tag.substr( 1, tag.size() - 2 ); //eliminate < >
-//        GetPairsFromTag( xmlGroup, tag, pairs );
-//        std::string groupName;
-//
-//        for( auto& pair : pairs )
-//        {
-//            if( pair.first == "name")
-//                groupName = pair.second;
-//        }
-//
-//        if( debugMode )
-//        {
-//            if( groupName.empty() )
-//                throw std::invalid_argument( "ERROR: group name not found. \n"
-//                );
-//
-//            if( groups.count( groupName ) == 1 ) //group exists
-//                throw std::invalid_argument( "ERROR: group " + groupName + "
-//                defined twice.\n" );
-//        }
-//
-//        groups.emplace( groupName, Group( groupName, xmlGroup, transforms,
-//        debugMode ) );
-//
-//        currentContent.erase( currentContent.find( xmlGroup ), xmlGroup.size()
-//        );
-//        currentPosition = 0;
-//    }
-//
-//    //transport
-//    //lambda function to check priority and iteration casting to unsigned int
-//    auto lf_UIntCheck = []( const std::string method, const std::string
-//    fieldStr, const std::string fieldName,
-//                            const bool debugMode, int& field )
-//    {
-//        field = 0;
-//        if( !fieldStr.empty())
-//        {
-//            field = std::stoi( fieldStr ); //throws invalid_argument
-//
-//            if( debugMode )
-//            {
-//                if( field < 0 )
-//                    throw std::invalid_argument("ERROR: " + fieldName + " in
-//                    transport " + method + " can't be negative\n" );
-//            }
-//        }
-//    };
-//
-//    //this section will have to change, doing nothing for now
-//    currentPosition = 0;
-//    while( currentPosition != std::string::npos )
-//    {
-//        GetSubString( "<transport ", ">", currentContent, tag, currentPosition
-//        );
-//        if( tag.empty() ) break;
-//        tag = tag.substr( 1, tag.size() - 2 ); //eliminate < >
-//        pairs.clear();
-//        GetPairsFromTag( currentContent, tag, pairs );
-//
-//        std::string groupName, method, priorityStr, iterationStr;
-//        for( auto& pair : pairs )
-//        {
-//            if( pair.first == "group" )  groupName = pair.second;
-//            else if( pair.first == "method" ) method = pair.second;
-//            else if( pair.first == "priority" ) priorityStr = pair.second;
-//            else if( pair.first == "iteration" ) iterationStr = pair.second;
-//        }
-//
-//        auto itGroup = groups.find( groupName );
-//        if( debugMode )
-//        {
-//            if( itGroup == groups.end() ) //not found
-//                throw std::invalid_argument( "ERROR: in transport " + method +
-//                " group " + groupName + " not found.\n" );
-//        }
-//
-//        int priority, iteration;
-//        lf_UIntCheck( method, priorityStr, "priority", debugMode, priority );
-//        lf_UIntCheck( method, iterationStr, "iteration", debugMode, iteration
-//        );
-//        //here do something with the capsule
-//    }
-//}
-
-// void InitXML( const std::string xmlConfigFile, const MPI_Comm mpiComm, const
-// bool debugMode,
-//              std::string& hostLanguage, std::vector<
-//              std::shared_ptr<Transform> >& transforms,
-//              std::map< std::string, Group >& groups )
-//{
-//    int xmlFileContentSize;
-//    std::string xmlFileContent;
-//
-//    int rank;
-//    MPI_Comm_rank( mpiComm, &rank );
-//
-//    if( rank == 0 ) //serial part
-//    {
-//        DumpFileToString( xmlConfigFile, xmlFileContent ); //in
-//        ADIOSFunctions.h dumps all XML Config File to xmlFileContent
-//        xmlFileContentSize = xmlFileContent.size( ) + 1; // add one for the
-//        null character
-//
-//        MPI_Bcast( &xmlFileContentSize, 1, MPI_INT, 0, mpiComm ); //broadcast
-//        size for allocation
-//        MPI_Bcast( (char*)xmlFileContent.c_str(), xmlFileContentSize,
-//        MPI_CHAR, 0, mpiComm ); //broadcast contents
-//    }
-//    else
-//    {
-//        MPI_Bcast( &xmlFileContentSize, 1, MPI_INT, 0, mpiComm  ); //receive
-//        size
-//
-//        char* xmlFileContentMPI = new char[ xmlFileContentSize ]; //allocate
-//        xml C-char
-//        MPI_Bcast( xmlFileContentMPI, xmlFileContentSize, MPI_CHAR, 0, mpiComm
-//        ); //receive xml C-char
-//        xmlFileContent.assign( xmlFileContentMPI ); //copy to a string
-//
-//        delete []( xmlFileContentMPI ); //delete char* needed for MPI, might
-//        add size is moving to C++14 for optimization, avoid memory leak
-//    }
-//
-//    SetMembers( xmlFileContent,  mpiComm, debugMode, hostLanguage, transforms,
-//    groups );
-//}
-
 } // end namespace adios
diff --git a/source/adios2/helper/adiosXML.h b/source/adios2/helper/adiosXML.h
index f3df2990549ed646f2f66457e82a3b2ec5ad55f0..22d6abd8904d0cf1eb39523a6e68e7730ebb76a0 100644
--- a/source/adios2/helper/adiosXML.h
+++ b/source/adios2/helper/adiosXML.h
@@ -12,95 +12,61 @@
 #define ADIOS2_HELPER_ADIOSXML_H_
 
 /// \cond EXCLUDE_FROM_DOXYGEN
+#include <map>
+#include <memory> //std::shared_ptr
 #include <string>
 #include <utility> //std::pair
 #include <vector>
 /// \endcond
 
+#include "adios2/core/IO.h"
+#include "adios2/core/Transform.h"
+
 namespace adios
 {
 
-/**
- * Extracts a substring between two tags from content
- * @param initialTag
- * @param finalTag
- * @param content full string
- * @param subString if found return substring between initialTag and finalTag,
- * otherwise returns empty
- * @param currentPosition to start the search, moved forward to finalTag
- * position
- */
-void GetSubString(const std::string initialTag, const std::string finalTag,
-                  const std::string content, std::string &subString,
-                  std::string::size_type &currentPosition);
+struct TagXML
+{
+    std::string Header;
+    std::string Elements;
+    bool IsFull;
+};
 
-/**
- * Extracts the value inside quotes in a string currentTag ( Example: currentTag
- * --> field1="value1" field2="value2" )
- * @param quote double " or single '
- * @param quotePosition position of the opening quote in currentTag
- * @param currentTag initial tag value, modified by cutting the first found " "
- * portion, currentTag --> field2="value2"
- * @param value value1 in the example above
- */
-void GetQuotedValue(const char quote,
-                    const std::string::size_type &quotePosition,
-                    std::string &currentTag, std::string &value);
+void RemoveCommentsXML(std::string &currentContent) noexcept;
 
-/**
- * Get attributes field1="value1" field2="value2" by looping through a single
- * XML tag
- * @param tag field0="value0" field1="value1" in a single string
- * @param pairs pairs[0].first=field0 pairs[0].second=value0
- * pairs[1].first=field1 pairs[1].second=value1
- */
-void GetPairs(const std::string tag,
-              std::vector<std::pair<const std::string, const std::string>>
-                  &pairs) noexcept;
+TagXML GetTagXML(const std::string tagName, const std::string &content,
+                 std::string::size_type &position);
 
-/**
- * Determine tag type and call GetPairs to populate pairs
- * @param fileContent file Content in a single string
- * @param tag field0="value0" field1="value1" in a single string
- * @param pairs pairs[0].first=field0 pairs[0].second=value0
- * pairs[1].first=field1 pairs[1].second=value1
- */
-void GetPairsFromTag(
-    const std::string &fileContent, const std::string tag,
-    std::vector<std::pair<const std::string, const std::string>> &pairs);
+std::string::size_type
+GetStringPositionXML(const std::string input, const std::string &content,
+                     const std::string::size_type &startPosition) noexcept;
 
-/**
- * Set members m_Groups and m_HostLanguage from XML file content, called within
- * Init functions
- * @param fileContent file Content in a single string
- * @param mpiComm MPI Communicator passed from application passed to Transport
- * method if required
- * @param hostLanguage return the host language from fileContent
- * @param transforms return the modified transforms vector if there are
- * variables with transformations
- * @param groups passed returns the map of groups defined in fileContent
- */
-// void SetMembers( const std::string& fileContent, const MPI_Comm mpiComm,
-//                 std::string& hostLanguage, std::vector<
-//                 std::shared_ptr<Transform> >& transforms,
-//                 std::map< std::string, Group >& groups );
+Params GetTagAttributesXML(const std::string &tagHeader);
 
 /**
- * Called inside the ADIOS XML constructors to get contents from file, broadcast
- * and set hostLanguage and groups from ADIOS class
- * @param xmlConfigFile xml config file name
- * @param mpiComm communicator used from broadcasting
- * @param debugMode from ADIOS m_DebugMode passed to CGroup in groups
- * @param hostLanguage set from host-language in xml file
- * @param transforms return the modified transforms vector if there are
- * variables with transformations
- * @param groups passed returns the map of groups defined in fileContent
+ * Called inside the ADIOS XML constructors to get contents from file,
+ * broadcast and fill transforms and ios
+ * @param configXMLFile
+ * @param mpiComm
+ * @param debugMode
+ * @param transforms
+ * @param ios
  */
-// void InitXML( const std::string xmlConfigFile, const MPI_Comm mpiComm, const
-// bool debugMode,
-//              std::string& hostLanguage, std::vector<
-//              std::shared_ptr<Transform> >& transforms,
-//              std::map< std::string, Group >& groups );
+void InitXML(const std::string configXML, const MPI_Comm mpiComm,
+             const bool debugMode,
+             std::vector<std::shared_ptr<Transform>> &transforms,
+             std::map<std::string, IO> &ios);
+
+void InitIOXML(const TagXML &ioXML, const MPI_Comm mpiComm,
+               const bool debugMode,
+               std::vector<std::shared_ptr<Transform>> &transforms,
+               std::map<std::string, IO> &ios);
+
+void InitEngineXML(const TagXML &engineXML, const bool debugMode, IO &io);
+
+void InitTransportXML(const TagXML &transportXML, const bool debugMode, IO &io);
+
+Params ParseParamsXML(const std::string &tagContents, const bool debugMode);
 }
 
 #endif /* ADIOS2_HELPER_ADIOSXML_H_ */
diff --git a/source/adios2/mpidummy.h b/source/adios2/mpidummy.h
index ed2b120584d2a334de31a43edfe6811cbce58dbb..249f9206f653020379d046dc729c7ae429045cf3 100644
--- a/source/adios2/mpidummy.h
+++ b/source/adios2/mpidummy.h
@@ -54,6 +54,9 @@ typedef int MPI_Fint;
 #define MPI_INT 1
 #define MPI_CHAR 2
 #define MPI_DOUBLE 3
+#define MPI_UNSIGNED 4
+#define MPI_UNSIGNED_LONG 5
+#define MPI_UNSIGNED_LONG_LONG 6
 
 #define MPI_ANY_SOURCE 0
 #define MPI_ANY_TAG 0