diff --git a/examples/hello/timeBP/Makefile b/examples/hello/timeBP/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..2c80ba83ad6861ddd6ea9c6b37a57ddac58f0bb6
--- /dev/null
+++ b/examples/hello/timeBP/Makefile
@@ -0,0 +1,31 @@
+# Makefile for testing purposes, will build helloWriter_OOP_mpi (make or make mpi) or helloWriter_OOP_nompi (make nompi) 
+# Created on: Oct 4, 2016
+#     Author: wfg
+
+BASE_NAME=timeBPWriter
+
+#COMPILERS
+CC=g++
+MPICC=mpic++
+
+#ADIOS LOCATION
+ADIOS_DIR=../../..
+ADIOS_INCLUDE=-I$(ADIOS_DIR)/include
+ADIOS_LIB=$(ADIOS_DIR)/lib/libadios.a
+ADIOS_NOMPI_LIB=$(ADIOS_DIR)/lib/libadios_nompi.a
+
+#FLAGS
+CFLAGS=-Wall -Wpedantic -std=c++11 -O0 -g
+LDFLAGS=
+
+all: mpi nompi
+
+mpi: $(ADIOS_LIB) $(ADIOS_HFiles)
+	$(MPICC) $(CFLAGS) $(ADIOS_INCLUDE) $(BASE_NAME).cpp -o $(BASE_NAME).exe $(ADIOS_LIB) $(LDFLAGS) -lpthread
+	
+nompi: $(ADIOS_NOMPI_LIB) $(NoMPI_HFiles)
+	$(CC) $(CFLAGS) $(ADIOS_INCLUDE) -DADIOS_NOMPI $(BASE_NAME)_nompi.cpp -o $(BASE_NAME)_nompi.exe $(ADIOS_NOMPI_LIB) $(LDFLAGS) -lpthread
+
+clean:
+	rm *.exe
+     
\ No newline at end of file
diff --git a/examples/hello/timeBP/test.sh b/examples/hello/timeBP/test.sh
new file mode 100755
index 0000000000000000000000000000000000000000..ef262a74c54cf2bdd7895fb273ce3516e9279667
--- /dev/null
+++ b/examples/hello/timeBP/test.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+rm -fr *.bp
+make clean
+make -j4
diff --git a/examples/hello/timeBP/timeBPWriter.cpp b/examples/hello/timeBP/timeBPWriter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..48dc5b33f04ff6c4887a9bcc8117ce6cbda34fe4
--- /dev/null
+++ b/examples/hello/timeBP/timeBPWriter.cpp
@@ -0,0 +1,113 @@
+/*
+ * timeBPWriter.cpp  example for time aggregation
+ *
+ *  Created on: Feb 16, 2017
+ *      Author: wfg
+ */
+
+
+#include <vector>
+#include <iostream>
+
+#include <mpi.h>
+
+
+#include "ADIOS_CPP.h"
+
+
+int main( int argc, char* argv [] )
+{
+    MPI_Init( &argc, &argv );
+    int rank;
+    MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+    const bool adiosDebug = true;
+    adios::ADIOS adios( MPI_COMM_WORLD, adiosDebug );
+
+    //Application variable
+    std::vector<double> myDoubles = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+    const std::size_t Nx = myDoubles.size();
+
+    const std::size_t rows = 3;
+    const std::size_t columns = 3;
+
+    std::vector<float> myMatrix;
+    if( rank % 2 == 0 ) //even rank
+    {
+        myMatrix.reserve( rows * columns );
+        myMatrix.push_back( 1 ); myMatrix.push_back( 2 ), myMatrix.push_back( 3 );
+        myMatrix.push_back( 4 ); myMatrix.push_back( 5 ), myMatrix.push_back( 6 );
+        myMatrix.push_back( 7 ); myMatrix.push_back( 8 ), myMatrix.push_back( 8 );
+    }
+
+    std::vector<float> myMatrix2 = { -1, -2, -3,
+                                     -4, -5, -6,
+                                     -7, -8, -9 };
+
+    try
+    {
+        //Define variable and local size
+        adios::Variable<double>& ioMyDoubles = adios.DefineVariable<double>( "myDoubles", {Nx} );
+        adios::Variable<float>& ioMyMatrix = adios.DefineVariable<float>( "myMatrix", {rows,columns} );
+        adios::Variable<float>& ioMyMatrix2 = adios.DefineVariable<float>( "myMatrix2", {rows,columns} );
+
+        //Define method for engine creation, it is basically straight-forward parameters
+        adios::Method& bpWriterSettings = adios.DeclareMethod( "MyMethod" ); //default method type is BPWriter
+        bpWriterSettings.SetParameters( "profile_units=mus" );
+        bpWriterSettings.AddTransport( "File", "profile_units=mus", "have_metadata_file=no" ); //uses default POSIX library
+
+        //Create engine smart pointer due to polymorphism,
+        //Open returns a smart pointer to Engine containing the Derived class Writer
+        auto bpWriter = adios.Open( "time.bp", "w", bpWriterSettings );
+
+        if( bpWriter == nullptr )
+            throw std::ios_base::failure( "ERROR: couldn't create bpWriter at Open\n" );
+
+
+        for( unsigned int t = 0; t < 10; ++t )
+        {
+            myDoubles[0] = t;
+            bpWriter->Write<double>( ioMyDoubles, myDoubles.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived
+
+            if( rank % 2 == 0 ) //even rank
+            {
+                myMatrix[0] = t;
+                myMatrix2[0] = t;
+
+                bpWriter->Write<float>( ioMyMatrix, myMatrix.data() );
+                bpWriter->Write<float>( ioMyMatrix2, myMatrix2.data() );
+            }
+            bpWriter->Advance();
+        }
+
+        bpWriter->Close( );
+    }
+    catch( std::invalid_argument& e )
+    {
+        if( rank == 0 )
+        {
+            std::cout << "Invalid argument exception, STOPPING PROGRAM\n";
+            std::cout << e.what() << "\n";
+        }
+    }
+    catch( std::ios_base::failure& e )
+    {
+        if( rank == 0 )
+        {
+            std::cout << "System exception, STOPPING PROGRAM\n";
+            std::cout << e.what() << "\n";
+        }
+    }
+    catch( std::exception& e )
+    {
+        if( rank == 0 )
+        {
+            std::cout << "Exception, STOPPING PROGRAM\n";
+            std::cout << e.what() << "\n";
+        }
+    }
+
+    MPI_Finalize( );
+
+    return 0;
+
+}
diff --git a/examples/hello/timeBP/timeBPWriter_nompi.cpp b/examples/hello/timeBP/timeBPWriter_nompi.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5301a5ac3c3e312e56e18d004c33f863c8632a00
--- /dev/null
+++ b/examples/hello/timeBP/timeBPWriter_nompi.cpp
@@ -0,0 +1,89 @@
+/*
+ * timeBPWriter.cpp  example for time aggregation
+ *
+ *  Created on: Feb 16, 2017
+ *      Author: wfg
+ */
+
+
+#include <vector>
+#include <iostream>
+
+#include "ADIOS_CPP.h"
+
+
+int main( int argc, char* argv [] )
+{
+    const bool adiosDebug = true;
+    adios::ADIOS adios( adiosDebug );
+
+    //Application variable
+    std::vector<double> myDoubles = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+    const std::size_t Nx = myDoubles.size();
+
+    const std::size_t rows = 3;
+    const std::size_t columns = 3;
+
+    std::vector<float> myMatrix;
+    myMatrix.reserve( rows * columns );
+    myMatrix.push_back( 1 ); myMatrix.push_back( 2 ), myMatrix.push_back( 3 );
+    myMatrix.push_back( 4 ); myMatrix.push_back( 5 ), myMatrix.push_back( 6 );
+    myMatrix.push_back( 7 ); myMatrix.push_back( 8 ), myMatrix.push_back( 8 );
+
+
+    std::vector<float> myMatrix2 = { -1, -2, -3,
+                                     -4, -5, -6,
+                                     -7, -8, -9 };
+
+    try
+    {
+        //Define variable and local size
+        adios::Variable<double>& ioMyDoubles = adios.DefineVariable<double>( "myDoubles", {Nx} );
+        adios::Variable<float>& ioMyMatrix = adios.DefineVariable<float>( "myMatrix", {rows,columns} );
+        adios::Variable<float>& ioMyMatrix2 = adios.DefineVariable<float>( "myMatrix2", {rows,columns} );
+
+        //Define method for engine creation, it is basically straight-forward parameters
+        adios::Method& bpWriterSettings = adios.DeclareMethod( "SingleFile" ); //default method type is BPWriter
+        bpWriterSettings.SetParameters( "profile_units=mus" );
+        bpWriterSettings.AddTransport( "File", "profile_units=mus", "have_metadata_file=no" ); //uses default POSIX library
+
+        //Create engine smart pointer due to polymorphism,
+        //Open returns a smart pointer to Engine containing the Derived class Writer
+        //auto bpWriter = adios.Open( "time_nompi.bp", "w", bpWriterSettings );
+
+        adios::BPFileWriter bpWriter( adios, "time_nompi.bp", "w", adios.m_MPIComm, bpWriterSettings, adiosDebug );
+
+        for( unsigned int t = 0; t < 2; ++t )
+        {
+            myDoubles[0] = t;
+//            myMatrix[0] = t;
+//            myMatrix2[0] = t;
+
+            bpWriter.Write( ioMyDoubles, myDoubles.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived
+//            bpWriter.Write( ioMyMatrix, myMatrix.data() );
+//            bpWriter.Write( ioMyMatrix2, myMatrix2.data() );
+            bpWriter.Advance();
+        }
+
+        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 << "System exception, STOPPING PROGRAM\n";
+        std::cout << e.what() << "\n";
+    }
+    catch( std::exception& e )
+    {
+        std::cout << "Exception, STOPPING PROGRAM\n";
+        std::cout << e.what() << "\n";
+    }
+
+    return 0;
+
+}
diff --git a/include/format/BP1.h b/include/format/BP1.h
index aac0b353499d59464845812e7291f88c3a7fdcd0..faef9a5bf59a918cb51e108f12a5990a727aae12 100644
--- a/include/format/BP1.h
+++ b/include/format/BP1.h
@@ -28,31 +28,32 @@ namespace format
 {
 
 /**
- * Struct that tracks metadata indices in bp format
+ * Used for Variables and Attributes, needed in a container for characteristic sets merge independently for each Variable or Attribute
+ */
+struct BP1Index
+{
+    std::vector<char> Index = std::vector<char>( 102400, '\0' ); ///< metadata variable index, start with 100Kb
+    std::size_t Position = 0; ///< initial position in bytes
+    std::uint64_t Count = 0; ///< number of characteristics sets (time and spatial aggregation)
+};
+
+/**
+ * Single struct that tracks metadata indices in bp format
  */
 struct BP1MetadataSet
 {
-    std::string TimeStepName; ///< time step name associated with this PG
     std::uint32_t TimeStep = 0; ///< current time step, updated with advance step, if append it will be updated to last
 
-    std::uint64_t PGCount = 0; ///< number of process groups
-    std::size_t PGIndexPosition = 16;
-    std::vector<char> PGIndex = std::vector<char>( 102400, '\0' ); ///< process group index metadata
-
-    std::uint32_t VarsCount = 0; ///< number of written Variables
-    std::size_t   VarsIndexPosition = 12; ///< initial position in bytes
-    std::vector<char> VarsIndex = std::vector<char>( 102400, '\0' ); ///< metadata variable index, start with 1Kb
-
-    std::uint32_t AttributesCount = 0; ///< number of Attributes
-    std::size_t AttributesIndexPosition = 12; ///< initial position in bytes
-    std::vector<char> AttributesIndex = std::vector<char>( 102400, '\0' ); ///< metadata attribute index, start with 1Kb
+    BP1Index PGIndex;
+    std::unordered_map< std::string, BP1Index > VarsIndices; ///< key: variable name, value: bp metadata variable index
+    std::unordered_map< std::string, BP1Index > AttributesIndices; ///< key: attribute name, value: bp metadata attribute index
 
     const unsigned int MiniFooterSize = 28; ///< 28 for now
 
     //PG (relative) positions in Data buffer to be updated
-    std::uint32_t DataPGVarsCount = 0;
     std::size_t DataPGLengthPosition = 0; ///< current PG initial ( relative ) position, needs to be updated in every advance step or init
-    std::size_t DataVarsCountPosition = 0; ///< current PG variable count ( relative ) position, needs to be updated in every advance step or init
+    std::uint32_t DataPGVarsCount = 0; ///< variables in current PG
+    std::size_t DataPGVarsCountPosition = 0; ///< current PG variable count ( relative ) position, needs to be updated in every advance step or init
     bool DataPGIsOpen = false;
 
     Profiler Log;
@@ -121,8 +122,6 @@ protected:
         ,METHOD_FILE        = 27
         ,METHOD_ZMQ         = 28
         ,METHOD_MDTM        = 29
-
-
     };
 
 
@@ -195,7 +194,6 @@ protected:
         return type_unknown;
     }
 
-
     std::vector<int> GetMethodIDs( const std::vector< std::shared_ptr<Transport> >& transports ) const noexcept;
 
 };