diff --git a/examples/groupless/multistep/CMakeLists.txt b/examples/groupless/multistep/CMakeLists.txt
index 97c434eab396f551791abb62bb7e53e70872e8a1..902a35b6cfe0c6d1a21d5773670956858c679959 100644
--- a/examples/groupless/multistep/CMakeLists.txt
+++ b/examples/groupless/multistep/CMakeLists.txt
@@ -9,6 +9,17 @@ if(ADIOS_USE_MPI)
   add_executable(writer_multistep writer_multistep.cpp)
   target_include_directories(writer_multistep PRIVATE ${MPI_C_INCLUDE_PATH})
   target_link_libraries(writer_multistep ${MPI_C_LIBRARIES})
+
+  add_executable(reader_stepping reader_stepping.cpp)
+  target_include_directories(reader_stepping PRIVATE ${MPI_C_INCLUDE_PATH})
+  target_link_libraries(reader_stepping ${MPI_C_LIBRARIES})
+
+  add_executable(reader_allsteps reader_allsteps.cpp)
+  target_include_directories(reader_allsteps PRIVATE ${MPI_C_INCLUDE_PATH})
+  target_link_libraries(reader_allsteps ${MPI_C_LIBRARIES})
+
 endif()
 target_link_libraries(writer_multistep adios2)
+target_link_libraries(reader_stepping adios2)
+target_link_libraries(reader_allsteps adios2)
 
diff --git a/examples/groupless/multistep/reader_allsteps.cpp b/examples/groupless/multistep/reader_allsteps.cpp
index 0b3afb4f8a169dc9925a0bec264ad8f420f94bc9..935d298c8492968e42aa4c0d6608089d41566b91 100644
--- a/examples/groupless/multistep/reader_allsteps.cpp
+++ b/examples/groupless/multistep/reader_allsteps.cpp
@@ -14,6 +14,41 @@
 #include <adios2.h>
 #include <mpi.h>
 
+template <class T>
+T **Make2DArray(int nRows, int nCols)
+{
+    T **ptr = new T *[nRows];
+    ptr[0] = new T[nRows * nCols];
+    for (int i = 1; i < nRows; i++)
+    {
+        ptr[i] = ptr[i - 1] + nCols;
+    }
+    return ptr;
+}
+
+template <class T>
+void Delete2DArray(T **ptr)
+{
+    delete[] ptr[0];
+    delete[] ptr;
+}
+
+template <class T>
+void Print2DArray(T **ptr, int nRows, int nCols, std::string name)
+{
+    std::cout << name << " = { \n";
+    for (int step = 0; step < nRows; step++)
+    {
+        std::cout << "    { ";
+        for (int col = 0; col < nCols; col++)
+        {
+            std::cout << ptr[step][col] << " ";
+        }
+        std::cout << "}\n";
+    }
+    std::cout << "}\n";
+}
+
 int main(int argc, char *argv[])
 {
     int rank, nproc;
@@ -22,29 +57,46 @@ int main(int argc, char *argv[])
     MPI_Comm_size(MPI_COMM_WORLD, &nproc);
     const bool adiosDebug = true;
 
-    adios::ADIOS adios(MPI_COMM_WORLD, adiosDebug);
-
-    // Application variable
-    std::vector<double> NiceArray;
-    std::vector<float> RaggedArray;
+    adios::ADIOS adios(MPI_COMM_WORLD, adios::Verbose::WARN);
 
-    int Nparts;
+    // Info variables from the file
     int Nwriters;
     int Nsteps;
+    // Data variables from the file
+    // 1. Global value, constant across processes, constant over time
+    unsigned int Nx;
+    // 2. Local value, varying across processes, constant over time
+    std::vector<int> ProcessID;
+    // 3. Global array, global dimensions, local dimensions and offsets are
+    // constant over time
+    std::vector<double> GlobalArrayFixedDims;
+
+    // 4. Local array, local dimensions are
+    // constant over time (but different across processors here)
+    std::vector<float> LocalArrayFixedDims;
+
+    // 5. Global value, constant across processes, VARYING value over time
+    std::vector<unsigned int> Nys;
+    // 6. Local value, varying across processes, VARYING over time
+    // Read as a 2D array, time as first dimension
+
+    // 7. Global array, dimensions and offsets are VARYING over time
+    std::vector<double> GlobalArray;
+    // 8. Local array, dimensions and offsets are VARYING over time
+    std::vector<float> IrregularArray;
 
     try
     {
         // Define method for engine creation
         // 1. Get method def from config file or define new one
-        adios::Method &bpReaderSettings = adios.GetMethod("input");
-        if (bpReaderSettings.undeclared())
+        adios::Method &bpReaderSettings = adios.DeclareMethod("input");
+        if (!bpReaderSettings.IsUserDefined())
         {
             // if not defined by user, we can change the default settings
-            bpReaderSettings.SetEngine("BP"); // BP is the default engine
-            // By default we see all steps available in a file, so the next line
-            // is
-            // not needed
-            bpReaderSettings.SetParameters("Stepping", false);
+            bpReaderSettings.SetEngine(
+                "ADIOS1Reader"); // BP is the default engine
+            // see only one step at a time
+            bpReaderSettings.SetParameters("OpenAsFile");
         }
 
         // Create engine smart pointer due to polymorphism,
@@ -53,97 +105,93 @@ int main(int argc, char *argv[])
         // this would just open with a default transport, which is "BP"
         auto bpReader = adios.Open("myNumbers.bp", "r", bpReaderSettings);
 
-        // All the above is same as default use:
-        // auto bpReader = adios.Open( "myNumbers.bp", "r");
-
         if (bpReader == nullptr)
             throw std::ios_base::failure(
                 "ERROR: failed to open ADIOS bpReader\n");
 
-        /* Note: there is no global number of steps. Each variable has its own
+        /* Note: there is no global number of steps. Each variable has its
+         * own
          * number of steps */
 
+        adios::Variable<int> *vNproc = bpReader->InquireVariableInt("Nproc");
+        Nwriters = vNproc->m_Data[0];
+        std::cout << "# of writers = " << Nwriters << std::endl;
+
         /* NX */
-        /* There is a single value for each step. We can read all into a 1D
-         * array
-         * with a step selection.
-         * We can also just conveniently get the first with a simple read
-         * statement.
-         * Steps are not automatically presented as an array dimension and read
-         * does
-         * not read it as array.
+        /* There is a single value written once.
          */
-        unsigned int Nx;
-        bpReader->Read<unsigned int>(
-            "NX",
-            &Nx); // read a Global scalar which has a single value in a step
-
-        std::shared_ptr<adios::Variable<void>> varNx =
-            bpReader.InquiryVariable("Nx");
-        std::vector<int> Nxs(varNx->nsteps()); // number of steps available
+        // read a Global scalar which has a single value in a step
+        adios::Variable<unsigned int> *vNX =
+            bpReader->InquireVariableUInt("NX");
+        Nx = vNX->m_Data[0];
+        // bpReader->Read<unsigned int>("NX", &Nx);
+        std::cout << "NX = " << Nx << std::endl;
+
+        /* NY */
+        /* We can read all into a 1D array with a step selection.
+           Steps are not automatically presented as an array dimension
+           and read does not read it as array by default.
+        */
+        adios::Variable<unsigned int> *vNY =
+            bpReader->InquireVariableUInt("NY");
+        Nys.resize(vNY->GetNSteps()); // number of steps available
         // make a StepSelection to select multiple steps. Args: From, #of
         // consecutive steps
-        std::unique_ptr<adios::StepSelection> stepsNx =
-            adios.StepSelection(0, varNx->nsteps());
         // ? How do we make a selection for an arbitrary list of steps ?
-        varNX.SetStepSelection(stepsNx);
-        bpReader->Read<unsigned int>(varNx, Nxs.data());
+        vNY->SetStepSelection(0, vNY->GetNSteps());
+        bpReader->Read<unsigned int>(*vNY, Nys.data());
 
-        auto itmax = std::max_element(std::begin(Nxs), std::end(Nxs));
-        auto itmin = std::min_element(std::begin(Nxs), std::end(Nxs));
-        if (*itmin != *itmax)
+        std::cout << "NY = { ";
+        for (const auto &it : Nys)
         {
-            throw std::ios_base::failure(
-                "ERROR: NX is not the same at all steps!\n");
+            std::cout << it << " ";
         }
-
-        /* nproc */
-        bpReader->Read<int>("nproc", &Nwriters); // also a global scalar
+        std::cout << "}\n";
 
         /* Nparts */
-        // Nparts local scalar is presented as a 1D array of Nwriters elements.
+        // Nparts local scalar is presented as a 1D array of Nwriters
+        // elements.
         // We can read all steps into a 2D array of nproc * Nwriters
-        std::shared_ptr<adios::Variable<void>> varNparts =
-            bpReader.InquiryVariable("Nparts");
-        std::vector<int> partsV(Nproc * Nwriters);
-        varNparts->SetStepSelection(
-            adios.StepSelection(0, varNparts->nsteps()));
-        bpReader->Read<int>(varNparts,
-                            partsV.data()); // missing spatial selection = whole
-                                            // array at each step
-
-        /* Nice */
+        adios::Variable<unsigned int> *vNparts =
+            bpReader->InquireVariableUInt("Nparts");
+        unsigned int **Nparts =
+            Make2DArray<unsigned int>(vNparts->GetNSteps(), Nwriters);
+        vNparts->SetStepSelection(0, vNparts->GetNSteps());
+        bpReader->Read<unsigned int>(*vNparts, Nparts[0]);
+        Print2DArray(Nparts, vNparts->GetNSteps(), Nwriters, "Nparts");
+        Delete2DArray(Nparts);
+
+        /* GlobalArrayFixedDims */
         // inquiry about a variable, whose name we know
-        std::shared_ptr<adios::Variable<void>> varNice =
-            bpReader.InquiryVariable("Nice");
+        std::shared_ptr<adios::Variable<void *>> vGlobalArrayFixedDims =
+            bpReader->InquireVariable("GlobalArrayFixedDims");
 
-        if (varNice == nullptr)
-            throw std::ios_base::failure("ERROR: failed to find variable "
-                                         "'myDoubles' in input file\n");
+        if (vGlobalArrayFixedDims == nullptr)
+            throw std::ios_base::failure(
+                "ERROR: failed to find variable "
+                "'GlobalArrayFixedDims' in input file\n");
 
         // ? how do we know about the type? std::string varNice->m_Type
-        unsigned long long int gdim =
-            varMyDoubles->m_Shape[0]; // ?member var or member func?
-        unsigned long long int ldim = gdim / nproc;
-        unsigned long long int offs = rank * ldim;
+        std::size_t gdim =
+            vGlobalArrayFixedDims->m_Shape[0]; // ?member var or member func?
+        std::size_t count = gdim / nproc;
+        std::size_t start = rank * count;
         if (rank == nproc - 1)
         {
-            ldim = gdim - (ldim * gdim);
+            count = gdim - (count * gdim);
         }
 
-        NiceArray.reserve(ldim);
+        GlobalArrayFixedDims.resize(count);
 
         // Make a 1D selection to describe the local dimensions of the variable
-        // we
-        // READ and
-        // its offsets in the global spaces
-        std::unique_ptr<adios::Selection> bbsel = adios.SelectionBoundingBox(
-            {ldim}, {offs}); // local dims and offsets; both as list
-        bpReader->Read<double>("Nice", bbsel,
-                               NiceArray.data()); // Base class Engine own the
-                                                  // Read<T> that will call
-        // overloaded Read from Derived
+        // we READ and its offsets in the global spaces
+        vGlobalArrayFixedDims->SetSelection({start}, {count});
+        bpReader->ScheduleRead<void>(vGlobalArrayFixedDims,
+                                     GlobalArrayFixedDims.data());
+        bpReader->PerformReads(adios::PerformReadMode::BLOCKINGREAD);
 
+// overloaded Read from Derived
+#if 0
         /* Ragged */
         // inquiry about a variable, whose name we know
         std::shared_ptr<adios::Variable<void>> varRagged =
@@ -162,9 +210,9 @@ int main(int argc, char *argv[])
             varRagged->InquiryBlocks();
             // now we have the dimensions per block
 
-            unsigned long long int ldim =
+            unsigned long long int count =
                 varRagged->blockinfo[rank].m_Dimensions[0];
-            RaggedArray.resize(ldim);
+            RaggedArray.resize(count);
 
             std::unique_ptr<adios::Selection> wbsel =
                 adios.SelectionWriteblock(rank);
@@ -172,7 +220,7 @@ int main(int argc, char *argv[])
 
             // We can use bounding box selection as well
             std::unique_ptr<adios::Selection> rbbsel =
-                adios.SelectionBoundingBox({1, ldim}, {rank, 0});
+                adios.SelectionBoundingBox({1, count}, {rank, 0});
             bpReader->Read<float>("Ragged", rbbsel, RaggedArray.data());
         }
 
@@ -182,6 +230,8 @@ int main(int argc, char *argv[])
         std::vector<int> raggedDims = varRagged->GetVaryingGlobalDimensions(
             1); // contains all individual sizes in that dimension
 
+#endif
+
         // Close file/stream
         bpReader->Close();
     }
diff --git a/examples/groupless/multistep/reader_stepping.cpp b/examples/groupless/multistep/reader_stepping.cpp
index 7835c54dbe1479aab44a75dc9143cf60ced3534f..d7c0f3d5a81f7513c1319ead4680b049259999d8 100644
--- a/examples/groupless/multistep/reader_stepping.cpp
+++ b/examples/groupless/multistep/reader_stepping.cpp
@@ -22,53 +22,84 @@ int main(int argc, char *argv[])
     MPI_Comm_size(MPI_COMM_WORLD, &nproc);
     const bool adiosDebug = true;
 
-    adios::ADIOS adios(MPI_COMM_WORLD, adiosDebug);
+    adios::ADIOS adios(MPI_COMM_WORLD);
 
-    // Application variable
-    std::vector<double> NiceArray;
-    std::vector<float> RaggedArray;
-    unsigned int Nx;
-    int Nparts;
+    // Info variables from the file
     int Nwriters;
     int Nsteps;
+    // Data variables from the file
+    // 1. Global value, constant across processes, constant over time
+    unsigned int Nx;
+    // 2. Local value, varying across processes, constant over time
+    std::vector<int> ProcessID;
+    // 3. Global array, global dimensions, local dimensions and offsets are
+    // constant over time
+    std::vector<double> GlobalArrayFixedDims;
+
+    // 4. Local array, local dimensions are
+    // constant over time (but different across processors here)
+    std::vector<float> LocalArrayFixedDims;
+
+    // 5. Global value, constant across processes, VARYING value over time
+    unsigned int Ny;
+    // 6. Local value, varying across processes, VARYING over time
+    std::vector<unsigned int> Nparts;
+    // 7. Global array, dimensions and offsets are VARYING over time
+    std::vector<double> GlobalArray;
+    // 8. Local array, dimensions and offsets are VARYING over time
+    std::vector<float> IrregularArray;
 
     try
     {
         // Define method for engine creation
         // 1. Get method def from config file or define new one
-        adios::Method &bpReaderSettings = adios.GetMethod("input");
-        if (bpReaderSettings.undeclared())
+        adios::Method &bpReaderSettings = adios.DeclareMethod("input");
+        if (!bpReaderSettings.IsUserDefined())
         {
             // if not defined by user, we can change the default settings
-            bpReaderSettings.SetEngine("BP"); // BP is the default engine
-            bpReaderSettings.SetParameters("Stepping",
-                                           true); // see only one step at a time
+            bpReaderSettings.SetEngine(
+                "ADIOS1Reader"); // BP is the default engine
+            // see only one step at a time
+            // this is default, nothing to be done
         }
 
-        // Create engine smart pointer due to polymorphism,
-        // Default behavior
-        // auto bpReader = adios.Open( "myNumbers.bp", "r" );
-        // this would just open with a default transport, which is "BP"
-        try
+        auto bpReader = adios.Open("myNumbers.bp", "r", bpReaderSettings);
+        if (bpReader != nullptr)
         {
-            auto bpReader = adios.Open("myNumbers.bp", "r", bpReaderSettings);
-
-            while (true)
+            int step = 0;
+            while (bpReader->GetAdvanceStatus() == adios::AdvanceStatus::OK)
             {
+                std::cout << "Process step " << std::to_string(step)
+                          << std::endl;
                 /* NX */
-                bpReader->Read<unsigned int>("NX",
-                                             &Nx); // read a Global scalar which
-                                                   // has a single value in a
-                                                   // step
+                if (step == 0)
+                {
+                    // read a Global scalar which has a single value in a step
+                    adios::Variable<int> *vNproc =
+                        bpReader->InquireVariableInt("Nproc");
+                    Nwriters = vNproc->m_Data[0];
+                    std::cout << "# of writers = " << Nwriters << std::endl;
+
+                    adios::Variable<unsigned int> *vNX =
+                        bpReader->InquireVariableUInt("NX");
+                    Nx = vNX->m_Data[0];
+                    // bpReader->Read<unsigned int>("NX", &Nx);
+                    std::cout << "NX = " << Nx << std::endl;
+                }
 
-                /* nproc */
-                bpReader->Read<int>("nproc", &Nwriters); // also a global scalar
+                adios::Variable<unsigned int> *vNY =
+                    bpReader->InquireVariableUInt("NY");
+                Ny = vNY->m_Data[0];
+                std::cout << "NY = " << Ny << std::endl;
 
+#if 0
                 /* Nparts */
                 // Nparts local scalar is presented as a 1D array of Nwriters
                 // elements.
                 // We can read all as a 1D array
                 std::vector<int> partsV(Nwriters);
+                adios::Variable<unsigned int> *vNproc =
+                    bpReader->InquireVariableUInt("Nproc");
                 bpReader->Read<int>("Nparts",
                                     &partsV); // read with string name, no
                                               // selection => read whole array
@@ -86,7 +117,7 @@ int main(int argc, char *argv[])
                 // ? how do we know about the type? std::string varNice->m_Type
                 unsigned long long int gdim =
                     varMyDoubles->m_Shape[0]; // ?member var or
-                                                         // member func?
+                                              // member func?
                 unsigned long long int ldim = gdim / nproc;
                 unsigned long long int offs = rank * ldim;
                 if (rank == nproc - 1)
@@ -110,8 +141,7 @@ int main(int argc, char *argv[])
                 // inquiry about a variable, whose name we know
                 std::shared_ptr<adios::Variable<void>> varRagged =
                     bpReader.InquiryVariable("Ragged");
-                if (varRagged->m_Shape[1] !=
-                    adios::VARYING_DIMENSION)
+                if (varRagged->m_Shape[1] != adios::VARYING_DIMENSION)
                 {
                     throw std::ios_base::failure(
                         "Unexpected condition: Ragged array's fast "
@@ -150,6 +180,7 @@ int main(int argc, char *argv[])
                     varRagged->GetVaryingGlobalDimensions(
                         1); // contains all individual sizes in that
                             // dimension
+#endif
 
                 // promise to not read more from this step
                 bpReader->Release();
@@ -158,27 +189,12 @@ int main(int argc, char *argv[])
                 // bpReader->Advance(adios::NextStep);
                 // bpReader->Advance(adios::LatestStep);
                 bpReader->Advance(); // default is adios::NextStep
+                ++step;
             }
 
             // Close file/stream
             bpReader->Close();
         }
-        catch (adios::end_of_stream &e)
-        {
-            if (rank == 0)
-            {
-                std::cout << "Reached end of stream, end processing loop.\n";
-            }
-            // Close file/stream
-            bpReader->Close();
-        }
-        catch (adios::file_not_found &e)
-        {
-            if (rank == 0)
-            {
-                std::cout << "File/stream does not exist, quit.\n";
-            }
-        }
     }
     catch (std::invalid_argument &e)
     {
diff --git a/examples/groupless/multistep/writer_multistep.cpp b/examples/groupless/multistep/writer_multistep.cpp
index 0879ddb4d6ef2bc8b836a593b11399043c069170..6f98f599dc0fa0ab074753c86b63c779de8750d8 100644
--- a/examples/groupless/multistep/writer_multistep.cpp
+++ b/examples/groupless/multistep/writer_multistep.cpp
@@ -23,6 +23,10 @@ int main(int argc, char *argv[])
     const bool adiosDebug = true;
     const int NSTEPS = 5;
 
+    // generate different random numbers on each process,
+    // but always the same sequence at each run
+    srand(rank * 32767);
+
     adios::ADIOS adios(MPI_COMM_WORLD, adios::Verbose::WARN);
 
     // Application variables for output
@@ -58,10 +62,11 @@ int main(int argc, char *argv[])
         // 1. Global value, constant across processes, constant over time
         adios::Variable<unsigned int> &varNX =
             adios.DefineVariable<unsigned int>("NX");
+        adios::Variable<int> &varNproc = adios.DefineVariable<int>("Nproc");
 
         // 2. Local value, varying across processes, constant over time
         adios::Variable<int> &varProcessID = adios.DefineVariable<int>(
-            "processid", {nproc}, {rank}, {1}, adios::ConstantShape);
+            "ProcessID", {nproc}, {rank}, {1}, adios::ConstantShape);
 
         // 3. Global array, global dimensions (shape), offsets (start) and local
         // dimensions (count)  are  constant over time
@@ -98,8 +103,9 @@ int main(int argc, char *argv[])
         adios::Variable<double> &varGlobalArray =
             adios.DefineVariable<double>("GlobalArray", {adios::UnknownDim});
 
-        // 8. Ragged array, dimensions and offsets are VARYING over time
-        // Want to see this at reading as a ragged 2D array with rank serving as
+        // 8. Local array, dimensions and offsets are VARYING over time
+        // Want to see this at reading as an irregular 2D array with rank
+        // serving as
         // offset in the slow dimension
         adios::Variable<float> &varIrregularArray =
             adios.DefineVariable<float>("Irregular", {nproc, adios::VarDim});
@@ -145,7 +151,8 @@ int main(int argc, char *argv[])
                 GlobalArray[i] = rank * Ny + (double)i;
             }
 
-            Nparts = rand() % 6 + 5; // random size per process, 5..10 each
+            // random size per process, 5..10 each
+            Nparts = rand() % 6 + 5;
             IrregularArray.reserve(Nparts);
             for (int i = 0; i < Nparts; i++)
             {
@@ -159,13 +166,17 @@ int main(int argc, char *argv[])
                 if (step == 0)
                 {
                     bpWriter->Write<unsigned int>(varNX, Nx);
+                    bpWriter->Write<int>("Nproc", nproc);
                 }
                 bpWriter->Write<unsigned int>(varNY, Ny);
             }
 
             // 2. and 6. Writing a local scalar on every process. Will be shown
             // at reading as a 1D array
-            bpWriter->Write<int>(varProcessID, ProcessID);
+            if (step == 0)
+            {
+                bpWriter->Write<int>(varProcessID, ProcessID);
+            }
             bpWriter->Write<unsigned int>(varNparts, Nparts);
 
             // 3.