diff --git a/.gitignore b/.gitignore
index 45f236b2510613e004301d6117ac37e798b04faa..66a3c55a3e539f8808ce60a1217144e6ae635d14 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,8 @@
 *.a
 *.so
 *.tmp
+*.exe
+*.bp
 
 #Eclipse
 .cproject
diff --git a/buildDataMan.sh b/buildDataMan.sh
index 9a298da4bbc366d1f2c680fa354b657e41178062..d629be60a9760fe40e599e863b59d300dc3ab3b5 100755
--- a/buildDataMan.sh
+++ b/buildDataMan.sh
@@ -6,12 +6,11 @@
 #     Author: wfg
 
 DATAMAN_LOCATION=/home/wfg/Applications/DataMan
-echo "#################################################################"
-echo "Start building ADIOS ./lib/libadios.a ./libadios_nompi.a"
-make HAVE_DATAMAN=yes DATAMAN_LOC=$DATAMAN_LOCATION       #build the ./lib/libadios.a and ./libadios_nompi.a
-echo "#################################################################"
+echo "######################################################################################"
+echo "Start building ADIOS ./lib/libadios.a ./libadios_nompi.a with DataMan library" 
+echo "######################################################################################"
 echo
-
+make HAVE_DATAMAN=yes DATAMAN_LOC=$DATAMAN_LOCATION       #build the ./lib/libadios.a and ./libadios_nompi.a
 echo
 echo "#################################################################"
 echo "Building Dataman Reader and Writer examples"
@@ -25,6 +24,8 @@ echo
 echo "#################################################################"
 echo "Running nompi.exe examples"
 echo "#################################################################"
+echo
+echo
 echo "#################################################################"
 echo "DataMan writer"
 echo "#################################################################"
diff --git a/examples/hello/datamanWriter/Makefile b/examples/hello/datamanWriter/Makefile
index 9f1a78619608543ebe1f87cc49ad26f6528be2ac..89e148f2c855cd4b91a8eb8df7a41af3623caf5a 100644
--- a/examples/hello/datamanWriter/Makefile
+++ b/examples/hello/datamanWriter/Makefile
@@ -28,16 +28,16 @@ CFLAGS=-Wall -O0 -g -Wpedantic -std=c++11
 
 #SYSTEM LIBS
 LIB+= -lpthread
-LIB_NOMPI+= -lpthread
+LIB_NOMPI+= -ldl -lpthread 
 
 
 all: mpi nompi
 
 mpi: $(ADIOS_LIB) $(ADIOS_HFiles)
-	$(MPICC) $(CFLAGS) $(INC) -DHAVE_MPI $(BASE_NAME).cpp -o $(BASE_NAME).exe $(LIB) -lpthread
+	$(MPICC) $(CFLAGS) $(INC) -DHAVE_MPI $(BASE_NAME).cpp -o $(BASE_NAME).exe $(LIB)
 	
 nompi: $(ADIOS_NOMPI_LIB) $(NoMPI_HFiles)
-	$(CC) $(CFLAGS) $(INC) $(BASE_NAME)_nompi.cpp -o $(BASE_NAME)_nompi.exe $(LIB_NOMPI) -lpthread
+	$(CC) $(CFLAGS) $(INC) $(BASE_NAME)_nompi.cpp -o $(BASE_NAME)_nompi.exe $(LIB_NOMPI)
 
 clean:
 	rm *.exe;
diff --git a/examples/hello/datamanWriter/helloDataManWriter.cpp b/examples/hello/datamanWriter/helloDataManWriter.cpp
index 7eff00a7eaa191c08d6f9b2409b9a58d341e6bd2..689217ec55f4df84dce92313ca6f2940ee047d10 100644
--- a/examples/hello/datamanWriter/helloDataManWriter.cpp
+++ b/examples/hello/datamanWriter/helloDataManWriter.cpp
@@ -29,10 +29,17 @@ int main( int argc, char* argv [] )
     std::vector<double> myDoubles = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
     const std::size_t Nx = myDoubles.size();
 
+    std::vector<std::complex<float>> myCFloats;
+    myCFloats.reserve( 3 );
+    myCFloats.emplace_back( 1, 3 );
+    myCFloats.emplace_back( 2, 2 );
+    myCFloats.emplace_back( 3, 1 );
+
     try
     {
         //Define variable and local size
         auto& ioMyDoubles = adios.DefineVariable<double>( "myDoubles", {Nx} );
+        auto& ioMyCFloats = adios.DefineVariable<std::complex<float>>( "myCFloats", {3} );
 
         //Define method for engine creation, it is basically straight-forward parameters
         adios::Method& datamanSettings = adios.DeclareMethod( "WAN", "DataManWriter" ); //default method type is Writer
@@ -52,6 +59,7 @@ int main( int argc, char* argv [] )
             throw std::ios_base::failure( "ERROR: failed to create DataMan I/O engine at Open\n" );
 
         datamanWriter->Write( ioMyDoubles, myDoubles.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived
+        datamanWriter->Write( ioMyCFloats, myCFloats.data() );
         datamanWriter->Close( );
 
     }
diff --git a/examples/hello/datamanWriter/helloDataManWriter_nompi.cpp b/examples/hello/datamanWriter/helloDataManWriter_nompi.cpp
index 792bc620e2add336ef803861b72c38cfe8009445..86aa5e05a3ab4762e21f1f9c2ba099f46de5844c 100644
--- a/examples/hello/datamanWriter/helloDataManWriter_nompi.cpp
+++ b/examples/hello/datamanWriter/helloDataManWriter_nompi.cpp
@@ -20,11 +20,18 @@ int main( int argc, char* argv [] )
     std::vector<double> myDoubles = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
     const std::size_t Nx = myDoubles.size();
 
+    std::vector<std::complex<float>> myCFloats;
+    myCFloats.reserve( 3 );
+    myCFloats.emplace_back( 1, 3 );
+    myCFloats.emplace_back( 2, 2 );
+    myCFloats.emplace_back( 3, 1 );
+
     try
     {
         //Define variable and local size
         //Define variable and local size
         auto& ioMyDoubles = adios.DefineVariable<double>( "myDoubles", adios::Dims{Nx} );
+        auto& ioMyCFloats = adios.DefineVariable<std::complex<float>>( "myCFloats", {3} );
 
         //Define method for engine creation, it is basically straight-forward parameters
         adios::Method& datamanSettings = adios.DeclareMethod( "WAN", "DataManWriter" ); //default method type is Writer
@@ -39,8 +46,8 @@ int main( int argc, char* argv [] )
         if( datamanWriter == nullptr )
             throw std::ios_base::failure( "ERROR: failed to create DataMan I/O engine at Open\n" );
 
-        //datamanWriter->Write( "myDoubles", myDoubles.data() ); //you can write either by string or by object
         datamanWriter->Write( ioMyDoubles, myDoubles.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived
+        datamanWriter->Write( ioMyCFloats, myCFloats.data() );
         datamanWriter->Close( );
     }
     catch( std::invalid_argument& e )
diff --git a/examples/hello/writer/helloWriter_nompi.cpp b/examples/hello/writer/helloWriter_nompi.cpp
index 7438715cc89fba5393db5bb19683995e383536d7..b15518a2e1a4323f123047a83f36431e848b1c56 100644
--- a/examples/hello/writer/helloWriter_nompi.cpp
+++ b/examples/hello/writer/helloWriter_nompi.cpp
@@ -27,7 +27,7 @@ int main( int argc, char* argv [] )
 
         //Define method for engine creation, it is basically straight-forward parameters
         adios::Method& bpWriterSettings = adios.DeclareMethod( "SinglePOSIXFile" ); //default method type is Writer
-        bpWriterSettings.AddTransport( "POSIX", "have_metadata_file=yes" );
+        bpWriterSettings.AddTransport( "File", "have_metadata_file=yes" );
 
         //Create engine smart pointer due to polymorphism,
         //Open returns a smart pointer to Engine containing the Derived class Writer
diff --git a/include/ADIOS.h b/include/ADIOS.h
index 93a152e9adfc47d196a5471900aea234e3970692..939bdf3c0792e29e26433a0a323d5cb53e3cbada 100644
--- a/include/ADIOS.h
+++ b/include/ADIOS.h
@@ -406,6 +406,39 @@ Variable<long double>& ADIOS::DefineVariable( const std::string name, const Dims
 }
 
 
+template<> inline
+Variable<std::complex<float>>& ADIOS::DefineVariable( const std::string name, const Dims dimensions,
+                                                      const Dims globalDimensions, const Dims globalOffsets )
+{
+    CheckVariableInput( name, dimensions );
+    m_CFloat.emplace_back( name, dimensions, globalDimensions, globalOffsets, m_DebugMode );
+    m_Variables.emplace( name, std::make_pair( GetType<std::complex<float>>(), m_CFloat.size()-1 ) );
+    return m_CFloat.back();
+}
+
+
+template<> inline
+Variable<std::complex<double>>& ADIOS::DefineVariable( const std::string name, const Dims dimensions,
+                                                       const Dims globalDimensions, const Dims globalOffsets )
+{
+    CheckVariableInput( name, dimensions );
+    m_CDouble.emplace_back( name, dimensions, globalDimensions, globalOffsets, m_DebugMode );
+    m_Variables.emplace( name, std::make_pair( GetType<std::complex<double>>(), m_CDouble.size()-1 ) );
+    return m_CDouble.back();
+}
+
+
+template<> inline
+Variable<std::complex<long double>>& ADIOS::DefineVariable( const std::string name, const Dims dimensions,
+                                                            const Dims globalDimensions, const Dims globalOffsets )
+{
+    CheckVariableInput( name, dimensions );
+    m_CLDouble.emplace_back( name, dimensions, globalDimensions, globalOffsets, m_DebugMode );
+    m_Variables.emplace( name, std::make_pair( GetType<std::complex<double>>(), m_CLDouble.size()-1 ) );
+    return m_CLDouble.back();
+}
+
+
 //Get template specialization
 template<> inline
 Variable<char>& ADIOS::GetVariable( const std::string name )
@@ -459,6 +492,18 @@ template<> inline
 Variable<long double>& ADIOS::GetVariable( const std::string name )
 { return m_LDouble[ GetVariableIndex<long double>(name) ]; }
 
+template<> inline
+Variable<std::complex<float>>& ADIOS::GetVariable( const std::string name )
+{ return m_CFloat[ GetVariableIndex<std::complex<float>>(name) ]; }
+
+template<> inline
+Variable<std::complex<double>>& ADIOS::GetVariable( const std::string name )
+{ return m_CDouble[ GetVariableIndex<std::complex<double>>(name) ]; }
+
+template<> inline
+Variable<std::complex<long double>>& ADIOS::GetVariable( const std::string name )
+{ return m_CLDouble[ GetVariableIndex<std::complex<long double>>(name) ]; }
+
 
 
 } //end namespace
diff --git a/include/core/Engine.h b/include/core/Engine.h
index 942cc8ae737890e7358cfeea946c4913633f2c69..e9c176cde782cdf8917da05c4dab5beed0126e68 100644
--- a/include/core/Engine.h
+++ b/include/core/Engine.h
@@ -233,6 +233,13 @@ protected:
 
     bool TransportNamesUniqueness( ) const; ///< checks if transport names are unique among the same types (file I/O)
 
+
+    /**
+     * Throws an exception in debug mode if transport index is out of range.
+     * @param transportIndex must be in the range [ -1 , m_Transports.size()-1 ]
+     */
+    void CheckTransportIndex( const int transportIndex );
+
 };
 
 
diff --git a/include/core/Variable.h b/include/core/Variable.h
index 036e68e3daf927bcbe094356760f4d104ef6c322..c6f6b3c8c1fa983f2aeaadae14d93b940eea8d17 100644
--- a/include/core/Variable.h
+++ b/include/core/Variable.h
@@ -72,10 +72,21 @@ public:
             if( size > 10 )
                 size = 10;
 
-            for( std::size_t i = 0; i < size; ++i  )
+            if( m_Type.find("complex") != m_Type.npos ) //it's complex
             {
-                logInfo << m_AppValues[i] << " ";
+                for( unsigned int i = 0; i < size; ++i  )
+                {
+                    logInfo << "( " << std::real( m_AppValues[i] ) << " , " << std::imag( m_AppValues[i] ) << " )  ";
+                }
             }
+            else
+            {
+                for( unsigned int i = 0; i < size; ++i  )
+                {
+                    logInfo << m_AppValues[i] << " ";
+                }
+            }
+
             logInfo << " ...";
         }
         logInfo << "\n";
diff --git a/include/engine/bp/BPWriter.h b/include/engine/bp/BPWriter.h
index 105361c58caae7636b1eb70dc46a91e978ddef9b..ce99908c675250dff927ed9f82024563195ba946 100644
--- a/include/engine/bp/BPWriter.h
+++ b/include/engine/bp/BPWriter.h
@@ -79,10 +79,14 @@ public:
 private:
 
     capsule::STLVector m_Buffer; ///< heap capsule using STL std::vector<char>
+    std::size_t m_BufferVariableCountPosition = 0; ///< needs to be updated in every advance step
+    bool m_IsFirstClose = true; ///< set to false after first Close is reached so metadata doesn't have to be accommodated for a subsequent Close
+    std::size_t m_MaxBufferSize;
+    float m_GrowthFactor = 1.5; ///< capsule memory growth factor, new_memory = m_GrowthFactor * current_memory
+
     format::BP1Writer m_BP1Writer; ///< format object will provide the required BP functionality to be applied on m_Buffer and m_Transports
     format::BP1MetadataSet m_MetadataSet; ///< metadata set accompanying the heap buffer data in bp format. Needed by m_BP1Writer
-    std::size_t m_MaxBufferSize;
-    float m_GrowthFactor = 1.5;
+
     bool m_TransportFlush = false; ///< true: transport flush happened, buffer must be reset
 
     void Init( );
@@ -105,10 +109,10 @@ private:
         //set variable
         variable.m_AppValues = values;
         m_WrittenVariables.insert( variable.m_Name );
-        //precalculate new metadata and payload sizes
+
+        //pre-calculate new metadata and payload sizes
         const std::size_t indexSize = m_BP1Writer.GetVariableIndexSize( variable );
         const std::size_t payloadSize = variable.PayLoadSize(); //will change if compression is applied
-
         //Buffer reallocation, expensive part
         m_TransportFlush = CheckBuffersAllocation( indexSize, payloadSize );
 
@@ -126,11 +130,7 @@ private:
         }
         else //Write data to buffer
         {
-            //EXPENSIVE part, might want to use threads if large.
-            MemcpyThreads( m_Buffer.m_Data.data(), variable.m_AppValues, payloadSize, m_Cores );
-            //update indices
-            m_Buffer.m_DataPosition += payloadSize;
-            m_Buffer.m_DataAbsolutePosition += payloadSize;
+            m_BP1Writer.WriteVariablePayload( variable, m_Buffer, m_Cores );
         }
     }
 
diff --git a/include/engine/dataman/DataManReader.h b/include/engine/dataman/DataManReader.h
index ade638d4140e74bbd9f4aff9ea4bd3c5cf0a7154..3e4df180242bb499c031923d3b28b5b48c7ec1a2 100644
--- a/include/engine/dataman/DataManReader.h
+++ b/include/engine/dataman/DataManReader.h
@@ -16,7 +16,7 @@
 //supported capsules
 #include "capsule/heap/STLVector.h"
 
-
+#include "DataManager.h"
 
 namespace adios
 {
diff --git a/include/engine/dataman/DataManWriter.h b/include/engine/dataman/DataManWriter.h
index ca4d9781fdcfabd1038f32fb866efdb68c0de421..b5d2c91576d8d98632d4da22934f5a5acfbd6326 100644
--- a/include/engine/dataman/DataManWriter.h
+++ b/include/engine/dataman/DataManWriter.h
@@ -56,6 +56,9 @@ public:
     void Write( Variable<float>& variable, const float* values );
     void Write( Variable<double>& variable, const double* values );
     void Write( Variable<long double>& variable, const long double* values );
+    void Write( Variable<std::complex<float>>& variable, const std::complex<float>* values );
+    void Write( Variable<std::complex<double>>& variable, const std::complex<double>* values );
+    void Write( Variable<std::complex<long double>>& variable, const std::complex<long double>* values );
 
     void Write( const std::string variableName, const char* values );
     void Write( const std::string variableName, const unsigned char* values );
@@ -70,6 +73,10 @@ public:
     void Write( const std::string variableName, const float* values );
     void Write( const std::string variableName, const double* values );
     void Write( const std::string variableName, const long double* values );
+    void Write( const std::string variableName, const std::complex<float>* values );
+    void Write( const std::string variableName, const std::complex<double>* values );
+    void Write( const std::string variableName, const std::complex<long double>* values );
+
 
     void Close( const int transportIndex = -1 );
 
@@ -102,6 +109,9 @@ private:
         variable.m_AppValues = values;
         m_WrittenVariables.insert( variable.m_Name );
 
+        DataManager dataManager;
+        dataManager.add_stream( "0", "0", 1, 1, 1, "0" );
+
         //This part will go away, this is just to monitor variables per rank
         std::cout << "I am hooked to the DataMan library\n";
         MPI_Barrier( m_MPIComm );
diff --git a/include/format/BP1.h b/include/format/BP1.h
index b4139cd2f8e0804aa3fa91fbf8da43cb274a01d2..1696c143b89073b894790b59a0f2d5aef080852c 100644
--- a/include/format/BP1.h
+++ b/include/format/BP1.h
@@ -33,24 +33,23 @@ struct BP1MetadataSet
     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::uint64_t PGLength = 0; ///< length in bytes of process groups
     std::size_t PGIndexPosition = 16;
     std::vector<char> PGIndex = std::vector<char>( 102400 ); ///< process group index metadata
 
     std::uint32_t VarsCount = 0; ///< number of written Variables
-    std::uint64_t VarsLength = 0; ///< length in bytes of written Variables
     std::size_t   VarsIndexPosition = 12; ///< initial position in bytes
     std::vector<char> VarsIndex = std::vector<char>( 102400 ); ///< metadata variable index, start with 1Kb
 
     std::uint32_t AttributesCount = 0; ///< number of Attributes
-    std::uint64_t AttributesLength = 0; ///< length in bytes of Attributes
     std::size_t AttributesIndexPosition = 12; ///< initial position in bytes
-    std::vector<char> AttributeIndex = std::vector<char>( 102400 ); ///< metadata attribute index, start with 1Kb
+    std::vector<char> AttributesIndex = std::vector<char>( 102400 ); ///< metadata attribute index, start with 1Kb
 
-    std::vector<char> MiniFooter = std::vector<char>( 28 );
+    std::vector<char> MiniFooter = std::vector<char>( 28 ); ///< 56?
 };
 
-
+/**
+ * Base class for BP1Writer and BP1Reader format
+ */
 class BP1
 {
 
diff --git a/include/format/BP1Writer.h b/include/format/BP1Writer.h
index 1a1e5653f839ac2ddbf4f690958e387aeb873f60..32bb42e3e40d95d8ce23a2115c521c9c494027db 100644
--- a/include/format/BP1Writer.h
+++ b/include/format/BP1Writer.h
@@ -39,6 +39,7 @@ public:
     unsigned int m_Cores = 1;  ///< number of cores for thread operations in large array (min,max)
     unsigned int m_Verbosity = 0; ///< statistics verbosity, can change if redefined in Engine method.
     float m_GrowthFactor = 1.5; ///< memory growth factor, can change if redefined in Engine method.
+    const std::uint8_t m_Version = 3;
 
     /**
      * Calculates the Process Index size in bytes according to the BP format, including list of method with no parameters (for now)
@@ -212,7 +213,31 @@ public:
         }
     }
 
-    void Close( const BP1MetadataSet& metadataSet, Capsule& capsule, Transport& transport ) const;
+    /**
+     * Expensive part this is only for heap buffers need to adapt to vector of capsules
+     * @param variable
+     * @param buffer
+     */
+    template< class T >
+    void WriteVariablePayload( const Variable<T>& variable, capsule::STLVector& buffer, const unsigned int cores = 1 ) const noexcept
+    {
+        std::size_t payloadSize = variable.PayLoadSize();
+        MemcpyThreads( buffer.m_Data.data(), variable.m_AppValues, payloadSize, cores ); //EXPENSIVE part, might want to use threads if large.
+        //update indices
+        buffer.m_DataPosition += payloadSize;
+        buffer.m_DataAbsolutePosition += payloadSize;
+    }
+
+
+    /**
+     * Function that collects metadata (if first close) and writes to a single transport
+     * @param metadataSet
+     * @param capsule
+     * @param transport
+     * @param isFirstClose
+     */
+    void Close( BP1MetadataSet& metadataSet, Capsule& capsule, Transport& transport, bool& isFirstClose ) const noexcept;
+
 
 
 private:
@@ -516,17 +541,12 @@ private:
         MemcpyToBuffers( buffers, positions, &value, sizeof(T) );
     }
 
-
-
     /**
-     *
+     * Flattens the metadata indices into a single metadata buffer in capsule
+     * @param metadataSet
      * @param capsule
-     * @param transport
      */
-    void CloseRankFile( Capsule& capsule, Transport& transport ) const;
-
-    void SetMetadata( const BP1MetadataSet& metadataSet, Capsule& capsule ) const; ///< sets the metadata buffer in capsule with indices and minifooter
-    void SetMiniFooter( BP1MetadataSet& metadataSet ) const; ///< sets the minifooter
+    void FlattenMetadata( BP1MetadataSet& metadataSet, Capsule& capsule ) const noexcept; ///< sets the metadata buffer in capsule with indices and minifooter
 
 };
 
diff --git a/include/functions/adiosFunctions.h b/include/functions/adiosFunctions.h
index 017816a66b0ddd3674aff3b2a00ada2cebfb1e65..5e00002b8c28396659f176fbf568acca109a9133 100644
--- a/include/functions/adiosFunctions.h
+++ b/include/functions/adiosFunctions.h
@@ -175,7 +175,14 @@ int GrowBuffer( const std::size_t incomingDataSize, const float growthFactor, co
  * @param bytes input number of bytes
  * @param positions  += bytes
  */
-void MovePositions( const int bytes, std::vector<std::size_t>& positions );
+void MovePositions( const int bytes, std::vector<std::size_t>& positions ) noexcept;
+
+
+/**
+ * Check if system is little endian
+ * @return true: little endian, false: big endian
+ */
+bool IsLittleEndian( ) noexcept;
 
 
 } //end namespace
diff --git a/include/functions/adiosTemplates.h b/include/functions/adiosTemplates.h
index 89036f38bfd53e83cf20022faf9370dbbea1760e..4f34ca386fa1b34ca2d3a0df49109d60053d2243 100644
--- a/include/functions/adiosTemplates.h
+++ b/include/functions/adiosTemplates.h
@@ -131,7 +131,7 @@ void GetMinMax( const std::complex<T>* values, const std::size_t size, T& min, T
  * threaded version of std::memcpy
  * @param dest
  * @param source
- * @param count
+ * @param count total number of bytest (as in memcpy)
  * @param cores
  */
 template<class T, class U>
diff --git a/src/core/Engine.cpp b/src/core/Engine.cpp
index d9765feac704fa595400e9f87f55211e69aa3861..7b74cd94d4eb3c18bafd7108003bf6ad5a28fc8b 100644
--- a/src/core/Engine.cpp
+++ b/src/core/Engine.cpp
@@ -155,5 +155,10 @@ bool Engine::TransportNamesUniqueness( ) const
 }
 
 
+void Engine::CheckTransportIndex( const int transportIndex )
+{
+
+}
+
 
 } //end namespace
diff --git a/src/engine/bp/BPWriter.cpp b/src/engine/bp/BPWriter.cpp
index 01c7b7fadb78efdf29e7edc7f3e9f5f4c3ec8b88..ad6c7de2f2749cbdd4e13e9d3bdda17140b77d09 100644
--- a/src/engine/bp/BPWriter.cpp
+++ b/src/engine/bp/BPWriter.cpp
@@ -161,15 +161,25 @@ void BPWriter::Write( const std::string variableName, const void* values )
 
 void BPWriter::AdvanceStep( )
 {
-
-
-
+    //first close current pg
 }
 
 
 void BPWriter::Close( const int transportIndex )
 {
-    //BP1BPWriter to update the metadata indices
+    CheckTransportIndex( transportIndex );
+    if( transportIndex == -1 )
+    {
+        for( auto& transport : m_Transports ) //by reference or value or it doesn't matter?
+            m_BP1Writer.Close( m_MetadataSet, m_Buffer, *transport, m_IsFirstClose );
+    }
+    else
+    {
+        m_BP1Writer.Close( m_MetadataSet, m_Buffer, *m_Transports[transportIndex], m_IsFirstClose );
+    }
+
+    //BP1Writer to update the metadata indices
+
 
 
     //merge all metadata indices in capsule.m_Metadata buffer or capsule.m_Data buffer (depends on transport predefined functionality)
@@ -177,18 +187,7 @@ void BPWriter::Close( const int transportIndex )
 
     //BP1BPWriter to write to corresponding transport
 
-    if( transportIndex == -1 ) // all transports
-    {
-        for( auto& transport : m_Transports )
-            transport->Write( m_Buffer.m_Data.data(), m_Buffer.m_DataPosition );
 
-        for( auto& transport : m_Transports )
-            transport->Close( );   //actually no need, close is in destructor (like fstream)
-    }
-    else
-    {
-        m_Transports[ transportIndex ]->Write( m_Buffer.m_Data.data(), m_Buffer.m_DataPosition );
-    }
 
     //Close the corresponding transport
 }
@@ -239,10 +238,16 @@ void BPWriter::InitTransports( )
             else
             {
                 if( m_DebugMode == true )
-                    throw std::invalid_argument( "ERROR: transport + " + itTransport->second + " not supported, in " +
+                    throw std::invalid_argument( "ERROR: file transport library " + itLibrary->second + " not supported, in " +
                                                   m_Name + m_EndMessage );
             }
         }
+        else
+        {
+            if( m_DebugMode == true )
+                throw std::invalid_argument( "ERROR: transport " + itTransport->second + " (you mean File?) not supported, in " +
+                                              m_Name + m_EndMessage );
+        }
     }
 }
 
@@ -261,10 +266,10 @@ void BPWriter::InitProcessGroup( )
 void BPWriter::WriteProcessGroupIndex( )
 {
     //pg = process group
-    const std::string pgName( std::to_string( m_RankMPI ) ); //using rank as name
+    const std::string name( std::to_string( m_RankMPI ) ); //using rank as name
     const unsigned int timeStep = m_MetadataSet.TimeStep;
     const std::string timeStepName( std::to_string( timeStep ) );
-    const std::size_t pgIndexSize = m_BP1Writer.GetProcessGroupIndexSize( pgName, timeStepName, m_Transports.size() );
+    const std::size_t pgIndexSize = m_BP1Writer.GetProcessGroupIndexSize( name, timeStepName, m_Transports.size() );
 
     //metadata
     GrowBuffer( pgIndexSize, m_GrowthFactor, m_MetadataSet.PGIndexPosition, m_MetadataSet.PGIndex );
@@ -272,22 +277,19 @@ void BPWriter::WriteProcessGroupIndex( )
     //data? Need to be careful, maybe add some trailing tolerance in variable ????
     GrowBuffer( pgIndexSize, m_GrowthFactor, m_Buffer.m_DataPosition, m_Buffer.m_Data );
 
-//    const bool isFortran = ( m_HostLanguage == "Fortran" ) ? true : false;
-//    const unsigned int processID = static_cast<unsigned int> ( m_RankMPI );
+    const bool isFortran = ( m_HostLanguage == "Fortran" ) ? true : false;
+    const unsigned int processID = static_cast<unsigned int> ( m_RankMPI );
 
-//    m_BP1BPWriter.WriteProcessGroupIndex( isFortran, name, processID, timeStepName, timeStep, m_Transports,
-//                                        m_Buffer.m_Data, m_Buffer.m_DataPosition, m_Buffer.m_DataAbsolutePosition,
-//                                        m_MetadataSet.PGIndex, m_MetadataSet.PGIndexPosition );
-
-//        const bool isFortran, const std::string name, const unsigned int processID,
-//                                                const std::string timeStepName, const unsigned int timeStep,
-//                                                std::vector<char*>& dataBuffers, std::vector<std::size_t>& dataPositions,
-//                                                std::vector<std::size_t>& dataAbsolutePositions,
-//                                                std::vector<char*>& metadataBuffers,
-//                                                std::vector<std::size_t>& metadataPositions
+    m_BP1Writer.WriteProcessGroupIndex( isFortran, name, processID, timeStepName, timeStep, m_Transports,
+                                        m_Buffer, m_MetadataSet );
 
+    m_BufferVariableCountPosition = m_Buffer.m_DataPosition; //fixed for every new PG
 }
 
+
+
+
+
 bool BPWriter::CheckBuffersAllocation( const std::size_t indexSize, const std::size_t payloadSize )
 {
     //Check if data in buffer needs to be reallocated
diff --git a/src/engine/dataman/DataManWriter.cpp b/src/engine/dataman/DataManWriter.cpp
index 824cf3a6ecf2314b6f689b2cc1090f5741ce2a02..e9b74032241e544f75833b902c45a35199f2798a 100644
--- a/src/engine/dataman/DataManWriter.cpp
+++ b/src/engine/dataman/DataManWriter.cpp
@@ -125,6 +125,16 @@ void DataManWriter::Write( Variable<double>& variable, const double* values )
 void DataManWriter::Write( Variable<long double>& variable, const long double* values )
 { WriteVariableCommon( variable, values ); }
 
+void DataManWriter::Write( Variable<std::complex<float>>& variable, const std::complex<float>* values )
+{ WriteVariableCommon( variable, values ); }
+
+void DataManWriter::Write( Variable<std::complex<double>>& variable, const std::complex<double>* values )
+{ WriteVariableCommon( variable, values ); }
+
+void DataManWriter::Write( Variable<std::complex<long double>>& variable, const std::complex<long double>* values )
+{ WriteVariableCommon( variable, values ); }
+
+//String version
 void DataManWriter::Write( const std::string variableName, const char* values )
 { WriteVariableCommon( m_ADIOS.GetVariable<char>( variableName ), values ); }
 
@@ -164,6 +174,14 @@ void DataManWriter::Write( const std::string variableName, const double* values
 void DataManWriter::Write( const std::string variableName, const long double* values )
 { WriteVariableCommon( m_ADIOS.GetVariable<long double>( variableName ), values ); }
 
+void DataManWriter::Write( const std::string variableName, const std::complex<float>* values )
+{ WriteVariableCommon( m_ADIOS.GetVariable<std::complex<float>>( variableName ), values ); }
+
+void DataManWriter::Write( const std::string variableName, const std::complex<double>* values )
+{ WriteVariableCommon( m_ADIOS.GetVariable<std::complex<double>>( variableName ), values ); }
+
+void DataManWriter::Write( const std::string variableName, const std::complex<long double>* values )
+{ WriteVariableCommon( m_ADIOS.GetVariable<std::complex<long double>>( variableName ), values ); }
 
 
 void DataManWriter::Close( const int transportIndex )
diff --git a/src/format/BP1Writer.cpp b/src/format/BP1Writer.cpp
index 09a1e8cac84ec84959ba27c756ba70d867844bbb..59eb3a1263dd76132f72c3a5ad5b4a10cae92bc7 100644
--- a/src/format/BP1Writer.cpp
+++ b/src/format/BP1Writer.cpp
@@ -46,6 +46,8 @@ void BP1Writer::WriteProcessGroupIndex( const bool isFortran, const std::string
     buffer.m_DataPosition = dataPositions[0];
     buffer.m_DataAbsolutePosition = dataAbsolutePositions[0];
     metadataSet.PGIndexPosition = metadataPositions[0];
+
+    ++metadataSet.PGCount;
 }
 
 
@@ -91,17 +93,21 @@ void BP1Writer::WriteProcessGroupIndex( const bool isFortran, const std::string
 }
 
 
-
-void BP1Writer::Close( const BP1MetadataSet& metadataSet, Capsule& capsule, Transport& transport ) const
+void BP1Writer::Close( BP1MetadataSet& metadataSet, Capsule& capsule,
+                       Transport& transport, bool& isFirstClose ) const noexcept
 {
-
-
-
+    if( isFirstClose == true )
+    {
+        FlattenMetadata( metadataSet, capsule ); //now capsule
+        isFirstClose = false;
+    }
+    //implementing N-to-N for now, no aggregation
+    transport.Write( capsule.GetData(), capsule.m_DataPosition );
+    transport.Write( capsule.GetMetadata(), capsule.GetMetadataSize() ); //we can improve this by copying metadata to data
+    transport.Close();
 }
 
 
-
-
 void BP1Writer::WriteProcessGroupIndexCommon( const bool isFortran, const std::string name, const unsigned int processID,
                                               const std::string timeStepName, const unsigned int timeStep,
                                               const std::vector<int>& methodIDs,
@@ -218,35 +224,58 @@ void BP1Writer::WriteDimensionRecord( std::vector<char*>& buffers, std::vector<s
 }
 
 
-void BP1Writer::CloseRankFile( Capsule& capsule, Transport& transport ) const
+
+void BP1Writer::FlattenMetadata( BP1MetadataSet& metadataSet, Capsule& capsule ) const noexcept
 {
+    //Finish writing metadata counts and lengths (IndexPosition)
+    const std::size_t pgLength = metadataSet.PGIndexPosition;
+    std::memcpy( &metadataSet.PGIndex[0], &metadataSet.PGCount, 8 );
+    std::memcpy( &metadataSet.PGIndex[8], &pgLength, 8 );
 
-}
+    const std::size_t varsIndexLength = metadataSet.VarsIndexPosition;
+    std::memcpy( &metadataSet.VarsIndex[0], &metadataSet.VarsCount, 4 );
+    std::memcpy( &metadataSet.VarsIndex[4], &varsIndexLength, 8 );
 
+    const std::size_t attributesIndexLength = metadataSet.AttributesIndexPosition;
+    std::memcpy( &metadataSet.AttributesIndex[0], &metadataSet.AttributesCount, 4 );
+    std::memcpy( &metadataSet.AttributesIndex[4], &attributesIndexLength, 8 );
 
+    const std::size_t metadataSize = pgLength + varsIndexLength + attributesIndexLength + metadataSet.MiniFooter.size();
 
+    capsule.ResizeMetadata( metadataSize );
+    char* metadata = capsule.GetMetadata();
 
-void BP1Writer::SetMiniFooter( BP1MetadataSet& metadataSet ) const
-{
+    std::memcpy( &metadata[0], metadataSet.PGIndex.data(), pgLength );
+    std::memcpy( &metadata[pgLength], metadataSet.VarsIndex.data(), varsIndexLength );
+    std::memcpy( &metadata[varsIndexLength], metadataSet.AttributesIndex.data(), attributesIndexLength );
 
+    //getting absolute offsets, minifooter is 28 bytes for now
+    const std::uint64_t offsetPGIndex = capsule.m_DataAbsolutePosition;
+    const std::uint64_t offsetVarsIndex = offsetPGIndex + pgLength;
+    const std::uint64_t offsetAttributeIndex = offsetVarsIndex + varsIndexLength;
+    std::size_t position = attributesIndexLength;
 
+    //offsets
+    std::memcpy( &metadata[position], &offsetPGIndex, 8 );
+    std::memcpy( &metadata[position+8], &offsetVarsIndex, 8 );
+    std::memcpy( &metadata[position+16], &offsetAttributeIndex, 8 );
 
+    position += 24; //position position to version record
+    if( IsLittleEndian() == true )//little endian machine
+    {
+        constexpr std::uint8_t littleEndian = 0;
+        std::memcpy( &metadata[position], &littleEndian, 1 );
+    }
+    else //big endian
+    {
+        constexpr std::uint8_t bigEndian = 1;
+        std::memcpy( &metadata[position], &bigEndian, 1 );
+    }
+    position += 3;
+    std::memcpy( &metadata[position], &m_Version, 1 );
 }
 
 
-void BP1Writer::SetMetadata( const BP1MetadataSet& metadataSet, Capsule& capsule ) const
-{
-
-    //setup metadata to capsule metadata buffer
-    //    const std::size_t processGroupIndexSize = m_ProcessGroupsLength + 16;
-    //    const std::size_t variableIndexSize = m_VariablesLength + 12;
-    //    const std::size_t attributeIndexSize = m_AttributesLength + 12;
-    //    const std::size_t minifooterSize = 28; //28
-    //    const std::size_t metadataSize = processGroupIndexSize + variableIndexSize + attributeIndexSize + minifooterSize;
-    //
-    //    capsule.ResizeMetadata( metadataSize );
-}
-
 
 
 
diff --git a/src/functions/adiosFunctions.cpp b/src/functions/adiosFunctions.cpp
index fa18131dea59adab2f6277ed3846e34fa3932603..8af45108a683752b320a38651a1b19774676e365 100644
--- a/src/functions/adiosFunctions.cpp
+++ b/src/functions/adiosFunctions.cpp
@@ -571,11 +571,18 @@ int GrowBuffer( const std::size_t incomingDataSize, const float growthFactor, co
 }
 
 
-void MovePositions( const int bytes, std::vector<std::size_t>& positions )
+void MovePositions( const int bytes, std::vector<std::size_t>& positions ) noexcept
 {
     for( auto& position : positions )
         position += bytes;
 }
 
 
+bool IsLittleEndian( ) noexcept
+{
+    std::uint16_t hexa = 0x1234;
+    return *reinterpret_cast<std::uint8_t*>(&hexa) != 0x12;
+}
+
+
 } //end namespace