diff --git a/examples/heatTransfer/read/CMakeLists.txt b/examples/heatTransfer/read/CMakeLists.txt
index f14e54596ca5891401524289f561ed709e6afe55..2a4ff60f7820bffb18a092572058dc7e9f0b75de 100644
--- a/examples/heatTransfer/read/CMakeLists.txt
+++ b/examples/heatTransfer/read/CMakeLists.txt
@@ -7,6 +7,11 @@ if(ADIOS2_HAVE_MPI)
   add_executable(heatTransfer_read_adios2 heatRead_adios2.cpp PrintData.h)
   target_link_libraries(heatTransfer_read_adios2 adios2 MPI::MPI_C)
 
+ if(ADIOS2_HAVE_HDF5)
+    add_executable(heatTransfer_read_a2h5 heatRead_a2h5.cpp PrintData.h)
+    target_link_libraries(heatTransfer_read_a2h5 adios2 MPI::MPI_C)
+  endif()
+
   if(ADIOS2_HAVE_ADIOS1)
     add_executable(heatTransfer_read_adios1 heatRead_adios1.cpp PrintData.h)
     target_link_libraries(heatTransfer_read_adios1 adios1::adios MPI::MPI_C)
diff --git a/examples/heatTransfer/read/heatRead_a2h5.cpp b/examples/heatTransfer/read/heatRead_a2h5.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7820fb89d32d9778a5f18cf5760814489aa6450c
--- /dev/null
+++ b/examples/heatTransfer/read/heatRead_a2h5.cpp
@@ -0,0 +1,161 @@
+
+#include <mpi.h>
+
+#include "adios2.h"
+
+#include <cstdint>
+#include <iomanip>
+#include <iostream>
+#include <math.h>
+#include <memory>
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+#include "PrintData.h"
+
+int main(int argc, char *argv[])
+{
+    MPI_Init(&argc, &argv);
+
+    if (argc < 2)
+    {
+        std::cout << "Not enough arguments: need an input file\n";
+        return 1;
+    }
+    const char *inputfile = argv[1];
+
+    /* World comm spans all applications started with the same aprun command
+     on a Cray XK6. So we have to split and create the local
+     'world' communicator for the reader only.
+     In normal start-up, the communicator will just equal the MPI_COMM_WORLD.
+     */
+
+    int wrank, wnproc;
+    MPI_Comm_rank(MPI_COMM_WORLD, &wrank);
+    MPI_Comm_size(MPI_COMM_WORLD, &wnproc);
+    MPI_Barrier(MPI_COMM_WORLD);
+
+    const unsigned int color = 2;
+    MPI_Comm mpiReaderComm;
+    MPI_Comm_split(MPI_COMM_WORLD, color, wrank, &mpiReaderComm);
+
+    int rank, nproc;
+    MPI_Comm_rank(mpiReaderComm, &rank);
+    MPI_Comm_size(mpiReaderComm, &nproc);
+
+    try
+    {
+        adios2::ADIOS ad("adios2.xml", mpiReaderComm, adios2::DebugOFF);
+
+        // Define method for engine creation
+        // 1. Get method def from config file or define new one
+
+        adios2::IO &h5ReaderIO = ad.DeclareIO("input");
+        if (!h5ReaderIO.InConfigFile())
+        {
+            // if not defined by user, we can change the default settings
+            // BPFileWriter is the default engine
+            // h5ReaderIO.SetEngine("ADIOS1Reader");
+            h5ReaderIO.SetEngine("HDF5Reader");
+            // h5ReaderIO.SetParameters({{"num_threads", "2"}});
+
+            // ISO-POSIX file is the default transport
+            // Passing parameters to the transport
+            h5ReaderIO.AddTransport("File", {{"verbose", "4"}});
+        }
+
+        adios2::Engine &h5Reader =
+            h5ReaderIO.Open(inputfile, adios2::Mode::Read, mpiReaderComm);
+
+        unsigned int gndx;
+        unsigned int gndy;
+        // h5Reader->Read<unsigned int>("gndx", &gndx);
+        // h5Reader->Read<unsigned int>("gndy", &gndy);
+
+        adios2::Variable<unsigned int> *vgndx =
+            h5ReaderIO.InquireVariable<unsigned int>("gndx");
+
+        // gndx = vgndx->GetData()[0];
+        adios2::Variable<unsigned int> *vgndy =
+            h5ReaderIO.InquireVariable<unsigned int>("gndy");
+        // gndy = vgndy->GetData()[0];
+        adios2::Variable<double> *vT = h5ReaderIO.InquireVariable<double>("T");
+
+        if ((vgndx == NULL) || (vgndy == NULL) || (vT == NULL))
+        {
+            std::cout << "Unable to find expected variables: gndx, gndy and T"
+                      << std::endl;
+            return 1;
+        }
+
+        h5Reader.GetSync<unsigned int>(*vgndx, gndx);
+        h5Reader.GetSync<unsigned int>(*vgndy, gndy);
+
+        if (rank == 0)
+        {
+            std::cout << "gndx       = " << gndx << std::endl;
+            std::cout << "gndy       = " << gndy << std::endl;
+            std::cout << "# of steps = " << vgndy->GetAvailableStepsCount()
+                      << std::endl;
+        }
+
+        // 1D decomposition of the columns, which is inefficient for reading!
+        adios2::Dims readsize({gndx, gndy / nproc});
+        adios2::Dims offset({0LL, rank * readsize[1]});
+        if (rank == nproc - 1)
+        {
+            // last process should read all the rest of columns
+            readsize[1] = gndy - readsize[1] * (nproc - 1);
+        }
+
+        std::cout << "rank " << rank << " reads " << readsize[1]
+                  << " columns from offset " << offset[1] << std::endl;
+
+        if (readsize[1] == 0)
+        {
+            std::cout << "Nothing to read. exiting" << std::endl;
+            return 0;
+        }
+
+        double *T = new double[vT->GetAvailableStepsCount() * readsize[0] *
+                               readsize[1]];
+
+        // Create a 2D selection for the subset
+        vT->SetSelection(adios2::Box<adios2::Dims>(offset, readsize));
+        vT->SetStepSelection(
+            adios2::Box<std::size_t>(0, vT->GetAvailableStepsCount()));
+
+        h5Reader.GetSync<double>(*vT, T);
+        // Arrays are read by scheduling one or more of them
+        // and performing the reads at once
+        // h5Reader->ScheduleRead<double>(*vT, T);
+        // h5Reader->PerformReads(adios2::ReadMode::Blocking);
+
+        printData(T, readsize.data(), offset.data(), rank,
+                  vT->GetAvailableStepsCount());
+        h5Reader.Close();
+        delete[] T;
+    }
+    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/heatTransfer/write/IO_h5mixer.cpp b/examples/heatTransfer/write/IO_h5mixer.cpp
index a6365cff3dabe320f493580208ace70ad4f5a46f..1e6e4d99a7a6d1592786d2815dd94450624b1080 100644
--- a/examples/heatTransfer/write/IO_h5mixer.cpp
+++ b/examples/heatTransfer/write/IO_h5mixer.cpp
@@ -24,7 +24,8 @@
 
 static int rank_saved;
 adios2::ADIOS *ad = nullptr;
-std::shared_ptr<adios2::Engine> h5mixerWriter;
+// std::shared_ptr<adios2::Engine> h5mixerWriter;
+adios2::Engine *h5mixerWriter = nullptr;
 adios2::Variable<double> *varT = nullptr;
 adios2::Variable<unsigned int> *varGndx = nullptr;
 
@@ -70,7 +71,7 @@ IO::IO(const Settings &s, MPI_Comm comm)
     // varT.AddTransform( tr, "" );
     // varT.AddTransform( tr,"accuracy=0.001" );  // for ZFP
 
-    h5mixerWriter = h5io.Open(m_outputfilename, adios2::OpenMode::Write, comm);
+    h5mixerWriter = &h5io.Open(m_outputfilename, adios2::Mode::Write, comm);
 
     if (!h5mixerWriter)
     {
@@ -88,6 +89,35 @@ IO::~IO()
 void IO::write(int step, const HeatTransfer &ht, const Settings &s,
                MPI_Comm comm)
 {
+
+    h5mixerWriter->BeginStep();
+    /* This selection is redundant and not required, since we defined
+     * the selection already in DefineVariable(). It is here just as an example.
+     */
+    // Make a selection to describe the local dimensions of the variable we
+    // write and its offsets in the global spaces. This could have been done in
+    // adios.DefineVariable()
+    varT->SetSelection(
+        adios2::Box<adios2::Dims>({s.offsx, s.offsy}, {s.ndx, s.ndy}));
+
+    /* Select the area that we want to write from the data pointer we pass to
+         the
+         writer.
+         Think HDF5 memspace, just not hyperslabs, only a bounding box
+       selection. Engine will copy this bounding box from the data pointer into
+       the output buffer. Size of the bounding box should match the "space"
+       selection which was given above. Default memspace is always the full
+       selection.
+    */
+    varT->SetMemorySelection(adios2::Box<adios2::Dims>({1, 1}, {s.ndx, s.ndy}));
+
+    h5mixerWriter->PutSync<unsigned int>(*varGndx, s.gndx);
+    h5mixerWriter->PutSync<unsigned int>("gndy", s.gndy);
+    h5mixerWriter->PutSync<double>(*varT, ht.data_noghost().data());
+
+    h5mixerWriter->EndStep();
+
+#ifdef NEVER
 #if 1
 
     /* This selection is redundant and not required, since we defined
@@ -120,9 +150,8 @@ void IO::write(int step, const HeatTransfer &ht, const Settings &s,
     h5mixerWriter->Advance();
 
 #else
-
     h5mixerWriter->Write<double>(*varT, ht.data_noghost().data());
     h5mixerWriter->Advance();
-
+#endif
 #endif
 }
diff --git a/source/adios2/engine/hdf5/HDF5ReaderP.cpp b/source/adios2/engine/hdf5/HDF5ReaderP.cpp
index a10a3e7b1b476d80c1960e2089236638108b8546..2d99551393100d93ea07acde3f58ce3fd30d5990 100644
--- a/source/adios2/engine/hdf5/HDF5ReaderP.cpp
+++ b/source/adios2/engine/hdf5/HDF5ReaderP.cpp
@@ -9,15 +9,16 @@
  */
 
 #include "HDF5ReaderP.h"
+#include "HDF5ReaderP.tcc"
 
 #include "adios2/ADIOSMPI.h"
 
 namespace adios2
 {
 
-HDF5ReaderP::HDF5ReaderP(IO &io, const std::string &name, const Mode mode,
+HDF5ReaderP::HDF5ReaderP(IO &io, const std::string &name, const Mode openMode,
                          MPI_Comm mpiComm)
-: Engine("HDF5Reader", io, name, mode, mpiComm), m_H5File(io.m_DebugMode)
+: Engine("HDF5Reader", io, name, openMode, mpiComm), m_H5File(io.m_DebugMode)
 {
     m_EndMessage = ", in call to IO HDF5Reader Open " + m_Name + "\n";
     Init();
@@ -39,6 +40,7 @@ bool HDF5ReaderP::IsValid()
     }
     return isValid;
 }
+
 void HDF5ReaderP::Init()
 {
     if (m_OpenMode != Mode::Read)
@@ -49,81 +51,196 @@ void HDF5ReaderP::Init()
     }
 
     m_H5File.Init(m_Name, m_MPIComm, false);
-    m_H5File.GetNumTimeSteps();
-}
-
-template <class T>
-void HDF5ReaderP::UseHDFRead(const std::string &variableName, T *values,
-                             hid_t h5Type)
-{
-    int rank, size;
-    MPI_Comm_rank(m_MPIComm, &rank);
-    MPI_Comm_size(m_MPIComm, &size);
-
-    hid_t dataSetId =
-        H5Dopen(m_H5File.m_GroupId, variableName.c_str(), H5P_DEFAULT);
-
-    if (dataSetId < 0)
-    {
-        return;
-    }
-    hid_t fileSpace = H5Dget_space(dataSetId);
-
-    if (fileSpace < 0)
-    {
-        return;
-    }
-    int ndims = H5Sget_simple_extent_ndims(fileSpace);
-    hsize_t dims[ndims];
-    herr_t status_n = H5Sget_simple_extent_dims(fileSpace, dims, NULL);
-
-    // hsize_t start[ndims] = {0}, count[ndims] = {0}, stride[ndims] = {1};
-    hsize_t start[ndims], count[ndims], stride[ndims];
-
-    int totalElements = 1;
-    for (int i = 0; i < ndims; i++)
+    int ts = m_H5File.GetNumTimeSteps();
+    if (ts == 0)
     {
-        count[i] = dims[i];
-        totalElements *= dims[i];
-        start[i] = 0;
-        count[i] = 0;
-        stride[i] = 1;
+        throw std::runtime_error("This h5 file is NOT written by ADIOS2");
     }
 
-    start[0] = rank * dims[0] / size;
-    count[0] = dims[0] / size;
-    if (rank == size - 1)
+    /*
+     */
+    if (!m_InStreamMode)
     {
-        count[0] = dims[0] - count[0] * (size - 1);
+        m_H5File.ReadAllVariables(m_IO);
     }
-
-    hid_t ret = H5Sselect_hyperslab(fileSpace, H5S_SELECT_SET, start, stride,
-                                    count, NULL);
-    if (ret < 0)
+    else
     {
-        return;
+        m_H5File.ReadAllVariables(m_IO);
     }
+}
 
-    hid_t memDataSpace = H5Screate_simple(ndims, count, NULL);
-
-    int elementsRead = 1;
-    for (int i = 0; i < ndims; i++)
+template <class T>
+void HDF5ReaderP::UseHDFRead(Variable<T> &variable, T *data, hid_t h5Type)
+{
+    int ts = 0;
+    T *values = data;
+    while (ts < variable.m_StepsCount)
     {
-        elementsRead *= count[i];
-    }
-
-    T data_array[elementsRead];
-    ret = H5Dread(dataSetId, h5Type, memDataSpace, fileSpace, H5P_DEFAULT,
-                  data_array);
-
-    H5Sclose(memDataSpace);
+        m_H5File.SetTimeStep(variable.m_StepsStart + ts);
+
+        hid_t dataSetId =
+            H5Dopen(m_H5File.m_GroupId, variable.m_Name.c_str(), H5P_DEFAULT);
+        if (dataSetId < 0)
+        {
+            return;
+        }
+
+        hid_t fileSpace = H5Dget_space(dataSetId);
+        if (fileSpace < 0)
+        {
+            return;
+        }
+
+        size_t slabsize = 1;
+
+        int ndims = std::max(variable.m_Shape.size(), variable.m_Count.size());
+        if (0 == ndims)
+        { // is scalar
+            hid_t ret = H5Dread(dataSetId, h5Type, H5S_ALL, H5S_ALL,
+                                H5P_DEFAULT, values);
+        }
+        else
+        {
+            hsize_t start[ndims], count[ndims], stride[ndims];
+
+            for (int i = 0; i < ndims; i++)
+            {
+                count[i] = variable.m_Count[i];
+                start[i] = variable.m_Start[i];
+                slabsize *= count[i];
+                stride[i] = 1;
+            }
+            hid_t ret = H5Sselect_hyperslab(fileSpace, H5S_SELECT_SET, start,
+                                            stride, count, NULL);
+            if (ret < 0)
+                return;
+
+            hid_t memDataSpace = H5Screate_simple(ndims, count, NULL);
+            int elementsRead = 1;
+            for (int i = 0; i < ndims; i++)
+            {
+                elementsRead *= count[i];
+            }
+
+            ret = H5Dread(dataSetId, h5Type, memDataSpace, fileSpace,
+                          H5P_DEFAULT, values);
+            H5Sclose(memDataSpace);
+        }
+
+        H5Sclose(fileSpace);
+        H5Dclose(dataSetId);
+
+        ts++;
+        values += slabsize;
+    } // while
+}
 
-    H5Sclose(fileSpace);
-    H5Dclose(dataSetId);
+/*
+template <class T>
+void HDF5ReaderP::UseHDFRead(const std::string &variableName, T *values,
+                           hid_t h5Type)
+{
+  int rank, size;
+  MPI_Comm_rank(m_MPIComm, &rank);
+  MPI_Comm_size(m_MPIComm, &size);
+
+  hid_t dataSetId =
+      H5Dopen(m_H5File.m_GroupId, variableName.c_str(), H5P_DEFAULT);
+
+  if (dataSetId < 0)
+  {
+      return;
+  }
+
+  hid_t fileSpace = H5Dget_space(dataSetId);
+
+  if (fileSpace < 0)
+  {
+      return;
+  }
+  int ndims = H5Sget_simple_extent_ndims(fileSpace);
+
+  if (ndims == 0) { // SCALAR
+    hid_t ret = H5Dread(dataSetId, h5Type, H5S_ALL, H5S_ALL, H5P_DEFAULT,
+values); return;
+  }
+
+  hsize_t dims[ndims];
+  herr_t status_n = H5Sget_simple_extent_dims(fileSpace, dims, NULL);
+
+  // hsize_t start[ndims] = {0}, count[ndims] = {0}, stride[ndims] = {1};
+  hsize_t start[ndims], count[ndims], stride[ndims];
+
+  int totalElements = 1;
+  for (int i = 0; i < ndims; i++)
+  {
+      count[i] = dims[i];
+      totalElements *= dims[i];
+      start[i] = 0;
+      //count[i] = 0;
+      stride[i] = 1;
+  }
+
+  start[0] = rank * dims[0] / size;
+  count[0] = dims[0] / size;
+  if (rank == size - 1)
+  {
+      count[0] = dims[0] - count[0] * (size - 1);
+  }
+
+  hid_t ret = H5Sselect_hyperslab(fileSpace, H5S_SELECT_SET, start, stride,
+                                  count, NULL);
+  if (ret < 0)
+  {
+      return;
+  }
+
+  hid_t memDataSpace = H5Screate_simple(ndims, count, NULL);
+
+  int elementsRead = 1;
+  for (int i = 0; i < ndims; i++)
+  {
+      elementsRead *= count[i];
+  }
+
+#ifdef NEVER
+  //T data_array[elementsRead];
+
+  std::vector<T> data_vector;
+  data_vector.reserve(elementsRead);
+  T* data_array = data_vector.data();
+  ret = H5Dread(dataSetId, h5Type, memDataSpace, fileSpace, H5P_DEFAULT,
+                data_array);
+#else
+  ret = H5Dread(dataSetId, h5Type, memDataSpace, fileSpace, H5P_DEFAULT,
+values); #endif
+
+
+  H5Sclose(memDataSpace);
+
+  H5Sclose(fileSpace);
+  H5Dclose(dataSetId);
 }
+*/
 
 void HDF5ReaderP::EndStep() { m_H5File.Advance(); }
 
 void HDF5ReaderP::Close(const int transportIndex) { m_H5File.Close(); }
 
+#define declare_type(T)                                                        \
+    void HDF5ReaderP::DoGetSync(Variable<T> &variable, T *data)                \
+    {                                                                          \
+        GetSyncCommon(variable, data);                                         \
+    }                                                                          \
+    void HDF5ReaderP::DoGetDeferred(Variable<T> &variable, T *data)            \
+    {                                                                          \
+        GetDeferredCommon(variable, data);                                     \
+    }                                                                          \
+    void HDF5ReaderP::DoGetDeferred(Variable<T> &variable, T &data)            \
+    {                                                                          \
+        GetDeferredCommon(variable, &data);                                    \
+    }
+ADIOS2_FOREACH_TYPE_1ARG(declare_type)
+#undef declare_type
+
 } // end namespace adios
diff --git a/source/adios2/engine/hdf5/HDF5ReaderP.h b/source/adios2/engine/hdf5/HDF5ReaderP.h
index 786dbbfb39e426aa01493fd5ab9497980842b86e..695e632c2186eeba87973ecff760d049820d0fdc 100644
--- a/source/adios2/engine/hdf5/HDF5ReaderP.h
+++ b/source/adios2/engine/hdf5/HDF5ReaderP.h
@@ -29,7 +29,7 @@ public:
      * @param mpiComm
      * @param method
      */
-    HDF5ReaderP(IO &adios, const std::string &name, const Mode mode,
+    HDF5ReaderP(IO &adios, const std::string &name, const Mode openMode,
                 MPI_Comm mpiComm);
 
     ~HDF5ReaderP();
@@ -40,12 +40,28 @@ public:
 
     void Close(const int transportIndex = -1) final;
 
-    template <class T>
-    void UseHDFRead(const std::string &variableName, T *values, hid_t h5Type);
-
 private:
     interop::HDF5Common m_H5File;
     void Init() final;
+
+    bool m_InStreamMode = false; // default is not streaming
+#define declare_type(T)                                                        \
+    void DoGetSync(Variable<T> &, T *) final;                                  \
+    void DoGetDeferred(Variable<T> &, T *) final;                              \
+    void DoGetDeferred(Variable<T> &, T &) final;
+    ADIOS2_FOREACH_TYPE_1ARG(declare_type)
+#undef declare_type
+
+    template <class T>
+    void GetSyncCommon(Variable<T> &variable, T *data);
+
+    template <class T>
+    void GetDeferredCommon(Variable<T> &variable, T *data);
+
+    template <class T>
+    // void UseHDFRead(const std::string &variableName, T *values, hid_t
+    // h5Type);
+    void UseHDFRead(Variable<T> &variable, T *values, hid_t h5Type);
 };
 };
 #endif /* ADIOS2_ENGINE_HDF5_HDF5READERP_H_ */
diff --git a/source/adios2/engine/hdf5/HDF5ReaderP.tcc b/source/adios2/engine/hdf5/HDF5ReaderP.tcc
new file mode 100644
index 0000000000000000000000000000000000000000..20eeb3c6baea434fec30c43b45d9362731df7a5d
--- /dev/null
+++ b/source/adios2/engine/hdf5/HDF5ReaderP.tcc
@@ -0,0 +1,44 @@
+/*
+ * Distributed under the OSI-approved Apache License, Version 2.0.  See
+ * accompanying file Copyright.txt for details.
+ *
+ * HDF5ReaderP.tcc
+ *
+ *  Created on: Oct 30, 2017
+ *      Author: jgu@lbl.gov
+ */
+
+#ifndef ADIOS2_ENGINE_HDF5_HDF5FILEREADER_TCC_
+#define ADIOS2_ENGINE_HDF5_HDF5FILEREADER_TCC_
+
+#include "HDF5ReaderP.h"
+
+namespace adios2
+{
+
+template <class T>
+void HDF5ReaderP::GetSyncCommon(Variable<T> &variable, T *data)
+{
+    // subfile info
+    /*  no good way to check it is not reference to null
+        if (&variable  == nullptr) {
+           return;
+        }
+    */
+    hid_t h5Type = m_H5File.GetHDF5Type<T>();
+    //    UseHDFRead(variable.m_Name, data, h5Type);
+    UseHDFRead(variable, data, h5Type);
+}
+
+template <class T>
+void HDF5ReaderP::GetDeferredCommon(Variable<T> &variable, T *data)
+{
+    // returns immediately
+    // m_HDF53Deserializer.GetDeferredVariable(variable, data);
+
+    throw std::runtime_error("Todo: GetDefCommon");
+}
+
+} // end namespace adios2
+
+#endif /* ADIOS2_ENGINE_HDF5_HDF5FILEREADER_TCC_ */
diff --git a/source/adios2/engine/mixer/HDFMixer.cpp b/source/adios2/engine/mixer/HDFMixer.cpp
index 8c86fdc7e77eac108d55578407b3a58e5935b98d..bfd1d59cb83b1b8a608cad3444b5fe31075e5624 100644
--- a/source/adios2/engine/mixer/HDFMixer.cpp
+++ b/source/adios2/engine/mixer/HDFMixer.cpp
@@ -14,12 +14,12 @@
 #include "adios2/ADIOSMPI.h"
 #include "adios2/core/IO.h"
 #include "adios2/helper/adiosFunctions.h" //CheckIndexRange
-#include "adios2/toolkit/transport/file/FileStream.h"
+#include "adios2/toolkit/transport/file/FileFStream.h"
 
 namespace adios2
 {
 
-HDFMixer::HDFMixer(IO &io, const std::string &name, const Mode mode,
+HDFMixer::HDFMixer(IO &io, const std::string &name, const Mode openMode,
                    MPI_Comm mpiComm)
 : Engine("HDFMixer", io, name, openMode, mpiComm),
   m_HDFVDSWriter(mpiComm, m_DebugMode),
@@ -40,14 +40,21 @@ void HDFMixer::Init()
 }
 
 #define declare_type(T)                                                        \
-    void HDFMixer::DoWrite(Variable<T> &variable, const T *values)             \
+    void HDFMixer::DoPutSync(Variable<T> &variable, const T *values)           \
     {                                                                          \
-        DoWriteCommon(variable, values);                                       \
+        DoPutSyncCommon(variable, values);                                     \
     }
 ADIOS2_FOREACH_TYPE_1ARG(declare_type)
 #undef declare_type
 
-void HDFMixer::Advance(const float /*timeout_sec*/)
+StepStatus HDFMixer::BeginStep(StepMode mode, const float timeout_sec)
+{
+    return StepStatus::OK;
+}
+
+// void HDFMixer::Advance(const float /*timeout_sec*/)
+// void HDFMixer::EndStep(const float /*timeout_sec*/)
+void HDFMixer::EndStep()
 {
     m_HDFSerialWriter.Advance();
     m_HDFVDSWriter.Advance();
@@ -55,18 +62,18 @@ void HDFMixer::Advance(const float /*timeout_sec*/)
 
 void HDFMixer::Close(const int transportIndex)
 {
-    if (m_DebugMode)
-    {
-        if (!m_TransportsManager.CheckTransportIndex(transportIndex))
-        {
-            auto transportsSize = m_TransportsManager.m_Transports.size();
-            throw std::invalid_argument(
-                "ERROR: transport index " + std::to_string(transportIndex) +
-                " outside range, -1 (default) to " +
-                std::to_string(transportsSize - 1) + ", in call to Close\n");
-        }
-    }
-
+    /*if (m_DebugMode)
+      {
+          if (!m_TransportsManager.CheckTransportIndex(transportIndex))
+          {
+              auto transportsSize = m_TransportsManager.m_Transports.size();
+              throw std::invalid_argument(
+                  "ERROR: transport index " + std::to_string(transportIndex) +
+                  " outside range, -1 (default) to " +
+                  std::to_string(transportsSize - 1) + ", in call to Close\n");
+          }
+      }
+    */
     // close bp buffer by flattening data and metadata
     m_HDFSerialWriter.Close();
     m_HDFVDSWriter.Close();
diff --git a/source/adios2/engine/mixer/HDFMixer.h b/source/adios2/engine/mixer/HDFMixer.h
index e4616f6fc298b31b89218e9290267cba03d98ab5..64a8947d7d84f5a1220e9511a8830330513ffdcc 100644
--- a/source/adios2/engine/mixer/HDFMixer.h
+++ b/source/adios2/engine/mixer/HDFMixer.h
@@ -27,7 +27,7 @@
 #include "adios2/ADIOSTypes.h"
 #include "adios2/core/Variable.h"
 #include "adios2/helper/adiosFunctions.h"
-#include "adios2/toolkit/capsule/heap/STLVector.h"
+//#include "adios2/toolkit/capsule/heap/STLVector.h"
 #include "adios2/toolkit/transportman/TransportMan.h" //transport::TransportsMan
 
 #include <iostream>
@@ -45,13 +45,15 @@ public:
      * @param openMode w (supported), r, a from OpenMode in ADIOSTypes.h
      * @param mpiComm MPI communicator
      */
-    HDFMixer(IO &io, const std::string &name, const Mode mode,
+    HDFMixer(IO &io, const std::string &name, const Mode openMode,
              MPI_Comm mpiComm);
 
     ~HDFMixer();
 
-    void Advance(const float timeoutSeconds = 0.f) final;
-
+    // void Advance(const float timeoutSeconds = 0.0) final;
+    StepStatus BeginStep(StepMode mode, const float timeout_sec);
+    // void EndStep(const float /*timeout_sec*/);
+    void EndStep() final;
     /**
      * Closes a single transport or all transports
      * @param transportIndex, if -1 (default) closes all transports, otherwise
@@ -87,7 +89,7 @@ private:
     void InitBuffer();
 
 #define declare_type(T)                                                        \
-    void DoWrite(Variable<T> &variable, const T *values) final;
+    void DoPutSync(Variable<T> &variable, const T *values) /*final */;
     ADIOS2_FOREACH_TYPE_1ARG(declare_type)
 #undef declare_type
 
@@ -97,13 +99,13 @@ private:
      * @param values
      */
     template <class T>
-    void DoWriteCommon(Variable<T> &variable, const T *values);
+    void DoPutSyncCommon(Variable<T> &variable, const T *values);
 
     /** Write a profiling.json file from m_H51Writer and m_TransportsManager
      * profilers*/
     void WriteProfilingJSONFile();
 };
 
-} // end namespace adios2
+} // end namespace adios
 
 #endif /* ADIOS2_ENGINE_H5_HDFMIXER_H_ */
diff --git a/source/adios2/engine/mixer/HDFMixer.tcc b/source/adios2/engine/mixer/HDFMixer.tcc
index d3d92bcac52cc202c3643a17cbe70194d3a1fadc..0618e9d46cbaa1abd031540001c26bb58e3b8e5f 100644
--- a/source/adios2/engine/mixer/HDFMixer.tcc
+++ b/source/adios2/engine/mixer/HDFMixer.tcc
@@ -14,12 +14,13 @@ namespace adios2
 {
 
 template <class T>
-void HDFMixer::DoWriteCommon(Variable<T> &variable, const T *values)
+void HDFMixer::DoPutSyncCommon(Variable<T> &variable, const T *values)
 {
-    variable.m_AppValues = values;
-    m_WrittenVariables.insert(variable.m_Name);
+    //set values
+    variable.SetData(values);
+    //m_WrittenVariables.insert(variable.m_Name);
     Variable<T> local(variable.m_Name, {}, {}, variable.m_Count,
-                      variable.m_Count.size(), false);
+                      variable.m_Count.size(), NULL, false);
 
     // m_HDFSerialWriter.m_H5File.Write(variable, values);
     // writes only the m_Count() part
@@ -43,4 +44,4 @@ void HDFMixer::DoWriteCommon(Variable<T> &variable, const T *values)
     }
 }
 
-} // end namespace adios2
+} // end namespace adios
diff --git a/source/adios2/toolkit/interop/hdf5/HDF5Common.cpp b/source/adios2/toolkit/interop/hdf5/HDF5Common.cpp
index 53222bbc26a3a512d6ac9dafce304b3cb802b8a1..09d80d810f660f4d580f51d80fb57011ade3062e 100644
--- a/source/adios2/toolkit/interop/hdf5/HDF5Common.cpp
+++ b/source/adios2/toolkit/interop/hdf5/HDF5Common.cpp
@@ -131,7 +131,7 @@ unsigned int HDF5Common::GetNumTimeSteps()
 {
     if (m_WriteMode)
     {
-        return 0;
+        return -1;
     }
 
     if (m_FileId < 0)
@@ -154,6 +154,167 @@ unsigned int HDF5Common::GetNumTimeSteps()
     return m_NumTimeSteps;
 }
 
+// read from all time steps
+void HDF5Common::ReadAllVariables(IO &io)
+{
+    int i = 0;
+    std::string timestepStr;
+    hsize_t numObj;
+    for (i = 0; i < m_NumTimeSteps; i++)
+    {
+        ReadVariables(i, io);
+    }
+}
+
+// read variables from the input timestep
+void HDF5Common::ReadVariables(unsigned int ts, IO &io)
+{
+    int i = 0;
+    std::string timestepStr;
+    hsize_t numObj;
+
+    StaticGetTimeStepString(timestepStr, ts);
+    hid_t gid = H5Gopen2(m_FileId, timestepStr.c_str(), H5P_DEFAULT);
+    HDF5TypeGuard g(gid, E_H5_GROUP);
+    ///    if (gid > 0) {
+    herr_t ret = H5Gget_num_objs(gid, &numObj);
+    if (ret >= 0)
+    {
+        int k = 0;
+        char name[50];
+        for (k = 0; k < numObj; k++)
+        {
+            ret = H5Gget_objname_by_idx(gid, (hsize_t)k, name, sizeof(name));
+            if (ret >= 0)
+            {
+                hid_t datasetId = H5Dopen(gid, name, H5P_DEFAULT);
+
+                HDF5TypeGuard d(datasetId, E_H5_DATASET);
+                CreateVar(io, datasetId, name);
+            }
+        }
+    }
+    /// H5Gclose(gid);
+    ///}
+}
+
+template <class T>
+void HDF5Common::AddVar(IO &io, std::string const &name, hid_t datasetId)
+{
+    Variable<T> *v = io.InquireVariable<T>(name);
+    if (NULL == v)
+    {
+        hid_t dspace = H5Dget_space(datasetId);
+        const int ndims = H5Sget_simple_extent_ndims(dspace);
+        hsize_t dims[ndims];
+        H5Sget_simple_extent_dims(dspace, dims, NULL);
+        H5Sclose(dspace);
+
+        Dims shape;
+        shape.resize(ndims);
+        if (ndims > 0)
+        {
+            // std::cout<<" ==> variable "<<name<<" is "<<ndims<<"D,
+            // "<<dims[0]<<", "<<dims[1]<<std::endl;
+            for (int i = 0; i < ndims; i++)
+                shape[i] = dims[i];
+        }
+
+        auto &foo = io.DefineVariable<T>(name, shape);
+        // default was set to 0 while m_AvailabelStepsStart is 1.
+        // correcting
+        if (0 == foo.m_AvailableStepsCount)
+        {
+            foo.m_AvailableStepsCount++;
+        }
+    }
+    else
+    {
+        /*    if (0 == v->m_AvailableStepsCount) { // default was set to 0 while
+        m_AvailabelStepsStart is 1. v->m_AvailableStepsCount ++;
+        }
+        */
+        v->m_AvailableStepsCount++;
+    }
+}
+
+void HDF5Common::CreateVar(IO &io, hid_t datasetId, std::string const &name)
+{
+    hid_t h5Type = H5Dget_type(datasetId);
+    HDF5TypeGuard t(h5Type, E_H5_DATATYPE);
+
+    if (H5Tequal(H5T_NATIVE_CHAR, h5Type))
+    {
+        AddVar<char>(io, name, datasetId);
+    }
+    else if (H5Tequal(H5T_NATIVE_SCHAR, h5Type))
+    {
+        AddVar<signed char>(io, name, datasetId);
+    }
+    else if (H5Tequal(H5T_NATIVE_UCHAR, h5Type))
+    {
+        AddVar<unsigned char>(io, name, datasetId);
+    }
+    else if (H5Tequal(H5T_NATIVE_SHORT, h5Type))
+    {
+        AddVar<short>(io, name, datasetId);
+    }
+    else if (H5Tequal(H5T_NATIVE_USHORT, h5Type))
+    {
+        AddVar<unsigned short>(io, name, datasetId);
+    }
+    else if (H5Tequal(H5T_NATIVE_INT, h5Type))
+    {
+        AddVar<int>(io, name, datasetId);
+    }
+    else if (H5Tequal(H5T_NATIVE_UINT, h5Type))
+    {
+        AddVar<unsigned int>(io, name, datasetId);
+    }
+    else if (H5Tequal(H5T_NATIVE_LONG, h5Type))
+    {
+        AddVar<long>(io, name, datasetId);
+    }
+    else if (H5Tequal(H5T_NATIVE_ULONG, h5Type))
+    {
+        AddVar<unsigned long>(io, name, datasetId);
+    }
+    else if (H5Tequal(H5T_NATIVE_LLONG, h5Type))
+    {
+        AddVar<long long>(io, name, datasetId);
+    }
+    else if (H5Tequal(H5T_NATIVE_ULLONG, h5Type))
+    {
+        AddVar<unsigned long long>(io, name, datasetId);
+    }
+    else if (H5Tequal(H5T_NATIVE_FLOAT, h5Type))
+    {
+        AddVar<float>(io, name, datasetId);
+    }
+    else if (H5Tequal(H5T_NATIVE_DOUBLE, h5Type))
+    {
+        AddVar<double>(io, name, datasetId);
+    }
+    else if (H5Tequal(H5T_NATIVE_LDOUBLE, h5Type))
+    {
+        AddVar<long double>(io, name, datasetId);
+    }
+    else if (H5Tequal(m_DefH5TypeComplexFloat, h5Type))
+    {
+        AddVar<std::complex<float>>(io, name, datasetId);
+    }
+    else if (H5Tequal(m_DefH5TypeComplexDouble, h5Type))
+    {
+        AddVar<std::complex<double>>(io, name, datasetId);
+    }
+    else if (H5Tequal(m_DefH5TypeComplexLongDouble, h5Type))
+    {
+        AddVar<std::complex<long double>>(io, name, datasetId);
+    }
+
+    // H5Tclose(h5Type);
+}
+
 void HDF5Common::Close()
 {
     if (m_FileId < 0)
@@ -173,6 +334,39 @@ void HDF5Common::Close()
     m_GroupId = -1;
 }
 
+void HDF5Common::SetTimeStep(int timeStep)
+{
+    if (m_WriteMode)
+        throw std::ios_base::failure(
+            "ERROR: unable to change timestep at Write MODE.");
+
+    if (timeStep < 0)
+        throw std::ios_base::failure(
+            "ERROR: unable to change to negative timestep.");
+
+    GetNumTimeSteps();
+
+    if (timeStep >= m_NumTimeSteps)
+        throw std::ios_base::failure(
+            "ERROR: given time step is more than actual known steps.");
+
+    if (m_CurrentTimeStep == timeStep)
+    {
+        return;
+    }
+
+    std::string timeStepName;
+    StaticGetTimeStepString(timeStepName, timeStep);
+    m_GroupId = H5Gopen(m_FileId, timeStepName.c_str(), H5P_DEFAULT);
+    if (m_GroupId < 0)
+    {
+        throw std::ios_base::failure("ERROR: unable to open HDF5 group " +
+                                     timeStepName + ", in call to Open\n");
+    }
+
+    m_CurrentTimeStep = timeStep;
+}
+
 void HDF5Common::Advance()
 {
     if (m_GroupId >= 0)
diff --git a/source/adios2/toolkit/interop/hdf5/HDF5Common.h b/source/adios2/toolkit/interop/hdf5/HDF5Common.h
index 56029726aa57cf018423452aa0d2b3d579ea1d40..212b089fbf625181f127a9afd2c40accd94a58d8 100644
--- a/source/adios2/toolkit/interop/hdf5/HDF5Common.h
+++ b/source/adios2/toolkit/interop/hdf5/HDF5Common.h
@@ -18,6 +18,7 @@
 #include "adios2/ADIOSMPICommOnly.h"
 #include "adios2/ADIOSMacros.h"
 #include "adios2/ADIOSTypes.h"
+#include "adios2/core/IO.h" // for CreateVar
 #include "adios2/core/Variable.h"
 
 #include <stdexcept> // for Intel Compiler
@@ -27,6 +28,55 @@ namespace adios2
 namespace interop
 {
 
+typedef enum {
+    E_H5_DATASET = 0,
+    E_H5_DATATYPE = 1,
+    E_H5_GROUP = 2,
+    E_H5_SPACE = 3,
+} ADIOS_ENUM_H5;
+
+class HDF5TypeGuard
+{
+public:
+    HDF5TypeGuard(hid_t key, ADIOS_ENUM_H5 type)
+    {
+        m_Key = key;
+        m_Type = type;
+        if (key < 0)
+        {
+            throw std::ios_base::failure("ERROR: HDF5 failure detected.");
+        }
+    }
+
+    ~HDF5TypeGuard()
+    {
+        if (m_Type == E_H5_DATASET)
+        {
+            H5Dclose(m_Key);
+        }
+        else if (m_Type == E_H5_GROUP)
+        {
+            H5Gclose(m_Key);
+        }
+        else if (m_Type == E_H5_SPACE)
+        {
+            H5Sclose(m_Key);
+        }
+        else if (m_Type == E_H5_DATATYPE)
+        {
+            H5Tclose(m_Key);
+        }
+        else
+        {
+            printf(" UNABLE to close \n");
+        }
+    }
+
+private:
+    ADIOS_ENUM_H5 m_Type;
+    hid_t m_Key;
+};
+
 class HDF5Common
 {
 
@@ -45,9 +95,18 @@ public:
     void Close();
     void Advance();
 
+    void SetTimeStep(int ts);
+
     unsigned int GetNumTimeSteps();
     void WriteTimeSteps();
 
+    void ReadVariables(unsigned int ts, IO &io);
+    void ReadAllVariables(IO &io);
+    void CreateVar(IO &io, hid_t h5Type, std::string const &name);
+
+    template <class T>
+    void AddVar(IO &io, std::string const &name, hid_t datasetId);
+
     static void StaticGetTimeStepString(std::string &timeStepName, int ts);
 
     hid_t m_PropertyListId = -1;
@@ -65,6 +124,9 @@ public:
     template <class T>
     hid_t GetHDF5Type(); // should this be public?
 
+    template <class T>
+    T GetADIOSType(hid_t);
+
 private:
     const bool m_DebugMode;
     bool m_WriteMode = false;