Index: XIOS/dev/dev_trunk_omp/inputs/COMPLETE/context_surface.xml
===================================================================
--- XIOS/dev/dev_trunk_omp/inputs/COMPLETE/context_surface.xml	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/inputs/COMPLETE/context_surface.xml	(revision 1668)
@@ -20,5 +20,5 @@
         <variable id="my_attribute5" type="double">100.201</variable>
       </field>
-      <field field_ref="field_A_srf_K" />
+      <field field_ref="field_A_srf_K" build_workflow_graph=".TRUE." />
       <field field_ref="field_A_srf_K_2" name="field_A_srf_K_2" /> <!-- Should be identical to field_A_srf_K -->
       <field field_ref="field_A_srf_K" name="field_A_srf_K_3">field_A_srf_K</field> <!-- Should be identical to field_A_srf_K -->
Index: XIOS/dev/dev_trunk_omp/inputs/iodef.xml
===================================================================
--- XIOS/dev/dev_trunk_omp/inputs/iodef.xml	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/inputs/iodef.xml	(revision 1668)
@@ -18,5 +18,5 @@
       <file id="output" name="output" enabled=".TRUE.">
         <!-- <field field_ref="field_Domain" name="field_A" /> -->
-        <field field_ref="field_A" name="field_A" /> 
+        <field field_ref="field_A" name="field_A" build_workflow_graph=".TRUE." /> 
         <field field_ref="field_A_zoom" name="field_B" />
      </file>
Index: XIOS/dev/dev_trunk_omp/src/config/field_attribute.conf
===================================================================
--- XIOS/dev/dev_trunk_omp/src/config/field_attribute.conf	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/src/config/field_attribute.conf	(revision 1668)
@@ -19,4 +19,5 @@
 DECLARE_ATTRIBUTE(bool,      indexed_output)
 DECLARE_ATTRIBUTE(bool,      check_if_active)
+DECLARE_ATTRIBUTE(bool,      build_workflow_graph)
 
 DECLARE_ATTRIBUTE(StdString, domain_ref, false)
Index: XIOS/dev/dev_trunk_omp/src/cxios.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/cxios.cpp	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/src/cxios.cpp	(revision 1668)
@@ -15,5 +15,5 @@
 using namespace ep_lib;
 #endif
-
+#include "graphviz.hpp"
 namespace xios
 {
@@ -172,4 +172,6 @@
        globalRegistry->toFile("xios_registry.bin") ;
        delete globalRegistry ;
+       
+       CGraphviz::buildStaticWorkflowGraph();
      }
 
Index: XIOS/dev/dev_trunk_omp/src/filter/file_server_writer_filter.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/filter/file_server_writer_filter.cpp	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/src/filter/file_server_writer_filter.cpp	(revision 1668)
@@ -28,3 +28,9 @@
     return true;
   }
+
+  int CFileServerWriterFilter::getFilterId(void)
+  {
+    return filterId;
+  }
+
 } // namespace xios
Index: XIOS/dev/dev_trunk_omp/src/filter/file_server_writer_filter.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/filter/file_server_writer_filter.hpp	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/src/filter/file_server_writer_filter.hpp	(revision 1668)
@@ -37,4 +37,9 @@
       bool virtual isDataExpected(const CDate& date) const;
 
+      /*!
+       * Returns filter's id needed in case of building workflow graph
+       */
+      int getFilterId();
+
     protected:
       /*!
@@ -48,4 +53,6 @@
       CField* field; //<! The associated field
       std::map<Time, CDataPacketPtr> packets; //<! The stored packets
+      int filterId;            //<! Filter's id needed in case of building a workflow
+
   }; // class CFileServerWriterFilter
 } // namespace xios
Index: XIOS/dev/dev_trunk_omp/src/filter/file_writer_filter.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/filter/file_writer_filter.cpp	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/src/filter/file_writer_filter.cpp	(revision 1668)
@@ -3,8 +3,9 @@
 #include "field.hpp"
 #include "utils.hpp"
+#include "workflow_graph.hpp"
 
 namespace xios
 {
-  CFileWriterFilter::CFileWriterFilter(CGarbageCollector& gc, CField* field)
+  CFileWriterFilter::CFileWriterFilter(CGarbageCollector& gc, CField* field, bool buildWorkflowGraph /* =false */)
     : CInputPin(gc, 1)
     , field(field)
@@ -13,4 +14,9 @@
       ERROR("CFileWriterFilter::CFileWriterFilter(CField* field)",
             "The field cannot be null.");
+    if (buildWorkflowGraph)
+    {
+      filterId = InvalidableObject::count;
+      InvalidableObject::count++;
+    }
   }
 
@@ -46,3 +52,9 @@
     return true;
   }
+
+  int CFileWriterFilter::getFilterId(void)
+  {
+    return filterId;
+  }
+
 } // namespace xios
Index: XIOS/dev/dev_trunk_omp/src/filter/file_writer_filter.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/filter/file_writer_filter.hpp	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/src/filter/file_writer_filter.hpp	(revision 1668)
@@ -20,6 +20,9 @@
        * \param gc the associated garbage collector
        * \param field the associated field
+       * \param[in] buildWorkflowGraph indicates whether the workflow will be visualized
        */
-      CFileWriterFilter(CGarbageCollector& gc, CField* field);
+      CFileWriterFilter(CGarbageCollector& gc, CField* field, bool buildWorkflowGraph = false);
+
+      inline StdString GetName(void) {return StdString("File writer filter");};
 
       /*!
@@ -37,4 +40,9 @@
       bool virtual isDataExpected(const CDate& date) const;
 
+      /*!
+       * Returns filter's id needed in case of building workflow graph
+       */
+      int getFilterId();
+
     protected:
       /*!
@@ -48,4 +56,6 @@
       CField* field; //<! The associated field
       std::map<Time, CDataPacketPtr> packets; //<! The stored packets
+      int filterId;                           //<! Filter's id needed in case of building a workflow
+
   }; // class CFileWriterFilter
 } // namespace xios
Index: XIOS/dev/dev_trunk_omp/src/filter/filter.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/filter/filter.cpp	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/src/filter/filter.cpp	(revision 1668)
@@ -3,10 +3,12 @@
 namespace xios
 {
-  CFilter::CFilter(CGarbageCollector& gc, size_t inputSlotsCount, IFilterEngine* engine)
+  CFilter::CFilter(CGarbageCollector& gc, size_t inputSlotsCount, IFilterEngine* engine, bool buildWorkflowGraph /*= false*/)
     : CInputPin(gc, inputSlotsCount)
-    , COutputPin(gc)
+    , COutputPin(gc, false, buildWorkflowGraph)
     , engine(engine)
     , inputSlotCount(inputSlotCount)
   { /* Nothing to do */ }
+
+  StdString CFilter::GetName(void)    { return StdString("Filter"); }
 
   void CFilter::onInputReady(std::vector<CDataPacketPtr> data)
Index: XIOS/dev/dev_trunk_omp/src/filter/filter.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/filter/filter.hpp	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/src/filter/filter.hpp	(revision 1668)
@@ -23,6 +23,9 @@
        * \param inputSlotsCount the number of input slots
        * \param engine the filter engine
+       * \param buildWorkflowGraph indicates whether data will be visualized
        */
-      CFilter(CGarbageCollector& gc, size_t inputSlotsCount, IFilterEngine* engine);
+      CFilter(CGarbageCollector& gc, size_t inputSlotsCount, IFilterEngine* engine, bool buildWorkflowGraph = false);
+
+      StdString virtual GetName(void);
 
       /*!
Index: XIOS/dev/dev_trunk_omp/src/filter/garbage_collector.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/filter/garbage_collector.cpp	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/src/filter/garbage_collector.cpp	(revision 1668)
@@ -3,4 +3,8 @@
 namespace xios
 {
+
+  int InvalidableObject::count = 0;
+  #pragma omp threadprivate(InvalidableObject::count)
+  
   void CGarbageCollector::registerObject(InvalidableObject* Object, Time timestamp)
   {
Index: XIOS/dev/dev_trunk_omp/src/filter/garbage_collector.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/filter/garbage_collector.hpp	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/src/filter/garbage_collector.hpp	(revision 1668)
@@ -20,4 +20,8 @@
      */
     void virtual invalidate(Time timestamp) = 0;
+  
+    static int count; //!< Counter used to identify a filter in case building workflow graph
+    #pragma omp threadprivate(count)
+    
   }; // struct InvalidableObject
 
Index: XIOS/dev/dev_trunk_omp/src/filter/input_pin.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/filter/input_pin.cpp	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/src/filter/input_pin.cpp	(revision 1668)
@@ -3,4 +3,5 @@
 #include "garbage_collector.hpp"
 #include "exception.hpp"
+#include "workflow_graph.hpp"
 
 namespace xios
@@ -11,5 +12,10 @@
     , triggers(slotsCount)
     , hasTriggers(false)
-  { /* Nothing to do */ }
+  {   }
+
+  StdString CInputPin::GetName(void)
+  {
+    return StdString("Input pin");
+  }
 
   void CInputPin::setInput(size_t inputSlot, CDataPacketPtr packet)
@@ -77,3 +83,9 @@
     inputs.erase(inputs.begin(), inputs.lower_bound(timestamp));
   }
+
+  int CInputPin::getFilterId(void)
+  {
+    return -1;
+  }
+
 } // namespace xios
Index: XIOS/dev/dev_trunk_omp/src/filter/input_pin.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/filter/input_pin.hpp	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/src/filter/input_pin.hpp	(revision 1668)
@@ -26,4 +26,6 @@
        */
       CInputPin(CGarbageCollector& gc, size_t slotsCount);
+      
+      StdString virtual GetName(void);
 
       /*!
@@ -79,4 +81,10 @@
        */
       void virtual invalidate(Time timestamp);
+      
+      /*!
+       * Returns filter's id needed in case of building workflow graph
+       * This function should never be called from this class, instead functions defined in derived classes or in class COutputPin should be used
+       */
+      int virtual getFilterId();
 
     protected:
Index: XIOS/dev/dev_trunk_omp/src/filter/output_pin.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/filter/output_pin.cpp	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/src/filter/output_pin.cpp	(revision 1668)
@@ -1,11 +1,24 @@
 #include "output_pin.hpp"
 #include "exception.hpp"
+#include "workflow_graph.hpp"
 
 namespace xios
 {
-  COutputPin::COutputPin(CGarbageCollector& gc, bool manualTrigger /*= false*/)
+  COutputPin::COutputPin(CGarbageCollector& gc, bool manualTrigger /*= false*/, bool buildWorkflowGraph /* =false */)
     : gc(gc)
     , manualTrigger(manualTrigger)
-  { /* Nothing to do */ }
+    , buildWorkflowGraph(buildWorkflowGraph)
+  {
+    if (buildWorkflowGraph)
+    {
+      filterId = InvalidableObject::count;
+      InvalidableObject::count++;
+    }
+  }
+
+  StdString COutputPin::GetName(void)
+  {
+    return StdString("Output pin");
+  }
 
   void COutputPin::connectOutput(std::shared_ptr<CInputPin> inputPin, size_t inputSlot)
@@ -26,4 +39,12 @@
       ERROR("void COutputPin::onOutputReady(CDataPacketPtr packet)",
             "The packet cannot be null.");
+
+    if (buildWorkflowGraph)
+    {
+    	if(CWorkflowGraph::mapFilterTimestamps_ptr==0) CWorkflowGraph::mapFilterTimestamps_ptr = new std::unordered_map <int, vector<Time> >;
+      if(CWorkflowGraph::timestamps_ptr==0) CWorkflowGraph::timestamps_ptr = new set<Time>;
+      (*CWorkflowGraph::mapFilterTimestamps_ptr)[this->getFilterId()].push_back(packet->timestamp);
+    	CWorkflowGraph::timestamps_ptr->insert(packet->timestamp);
+    }
 
     if (manualTrigger) // Don't use canBeTriggered here, this function is virtual and can be overriden
@@ -101,3 +122,9 @@
     outputPackets.erase(outputPackets.begin(), outputPackets.lower_bound(timestamp));
   }
+
+  int COutputPin::getFilterId(void)
+  {
+    return filterId;
+  }
+
 } // namespace xios
Index: XIOS/dev/dev_trunk_omp/src/filter/output_pin.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/filter/output_pin.hpp	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/src/filter/output_pin.hpp	(revision 1668)
@@ -19,7 +19,10 @@
        * \param gc the garbage collector associated with this ouput pin
        * \param slotsCount the number of slots
+       * \param buildWorkflowGraph indicates whether data will be visualized
        */
-      COutputPin(CGarbageCollector& gc, bool manualTrigger = false);
+      COutputPin(CGarbageCollector& gc, bool manualTrigger = false, bool buildWorkflowGraph = false);
 
+      StdString virtual GetName(void);
+      
       /*!
        * Connects to a specific slot of the input pin of a downstream filter.
@@ -66,4 +69,9 @@
       void virtual invalidate(Time timestamp);
 
+      /*!
+       * Returns filter's id needed in case of building workflow graph
+       */
+      int getFilterId();
+
     protected:
       /*!
@@ -97,4 +105,12 @@
       //! Output buffer, store the packets until the output is triggered
       std::map<Time, CDataPacketPtr> outputPackets;
+
+      //! Indicates whether the workflow will be visualized
+      bool buildWorkflowGraph;
+
+      //! Filter's id needed in case of building a workflow graph
+      int filterId;
+
+
   }; // class COutputPin
 } // namespace xios
Index: XIOS/dev/dev_trunk_omp/src/filter/pass_through_filter.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/filter/pass_through_filter.cpp	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/src/filter/pass_through_filter.cpp	(revision 1668)
@@ -3,6 +3,6 @@
 namespace xios
 {
-  CPassThroughFilter::CPassThroughFilter(CGarbageCollector& gc)
-    : CFilter(gc, 1, this)
+  CPassThroughFilter::CPassThroughFilter(CGarbageCollector& gc, bool buildWorkflowGraph /*= false*/)
+    : CFilter(gc, 1, this, buildWorkflowGraph)
   { /* Nothing to do */ }
 
Index: XIOS/dev/dev_trunk_omp/src/filter/pass_through_filter.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/filter/pass_through_filter.hpp	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/src/filter/pass_through_filter.hpp	(revision 1668)
@@ -17,6 +17,9 @@
        *
        * \param gc the associated garbage collector
+       * \param buildWorkflowGraph indicates whether data will be visualized
        */
-      CPassThroughFilter(CGarbageCollector& gc);
+      CPassThroughFilter(CGarbageCollector& gc, bool buildWorkflowGraph = false);
+
+      inline StdString GetName(void) {return StdString("Pass through filter");};
 
     protected:
Index: XIOS/dev/dev_trunk_omp/src/filter/source_filter.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/filter/source_filter.cpp	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/src/filter/source_filter.cpp	(revision 1668)
@@ -4,4 +4,5 @@
 #include "calendar_util.hpp"
 #include <limits> 
+#include "workflow_graph.hpp"
 
 namespace xios
@@ -11,6 +12,7 @@
                                const CDuration offset /*= NoneDu*/, bool manualTrigger /*= false*/,
                                bool hasMissingValue /*= false*/,
-                               double defaultValue /*= 0.0*/)
-    : COutputPin(gc, manualTrigger)
+                               double defaultValue /*= 0.0*/,
+                               bool buildWorkflowGraph /*= false*/)
+    : COutputPin(gc, manualTrigger, buildWorkflowGraph)
     , grid(grid)
     , compression(compression)
Index: XIOS/dev/dev_trunk_omp/src/filter/source_filter.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/filter/source_filter.hpp	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/src/filter/source_filter.hpp	(revision 1668)
@@ -27,4 +27,5 @@
        * \param hasMissingValue whether data has missing value
        * \param defaultValue missing value to detect
+       * \param[in] buildWorkflowGraph indicates whether the workflow will be visualized
        */
       CSourceFilter(CGarbageCollector& gc, CGrid* grid,
@@ -33,5 +34,8 @@
                     const CDuration offset = NoneDu, bool manualTrigger = false,
                     bool hasMissingValue = false,
-                    double defaultValue = 0.0);
+                    double defaultValue = 0.0,
+					bool buildWorkflowGraph = false);
+
+      inline StdString GetName(void) {return StdString("Source filter");};
 
       /*!
Index: XIOS/dev/dev_trunk_omp/src/filter/spatial_transform_filter.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/filter/spatial_transform_filter.cpp	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/src/filter/spatial_transform_filter.cpp	(revision 1668)
@@ -8,13 +8,15 @@
 using namespace ep_lib;
 #endif
-
+#include "workflow_graph.hpp"
 namespace xios
 {
-  CSpatialTransformFilter::CSpatialTransformFilter(CGarbageCollector& gc, CSpatialTransformFilterEngine* engine, double outputValue, size_t inputSlotsCount)
-    : CFilter(gc, inputSlotsCount, engine), outputDefaultValue(outputValue)
+  CSpatialTransformFilter::CSpatialTransformFilter(CGarbageCollector& gc, CSpatialTransformFilterEngine* engine,
+                                                   double outputValue, size_t inputSlotsCount, bool buildWorkflowGraph /*= false*/)
+    : CFilter(gc, inputSlotsCount, engine, buildWorkflowGraph), outputDefaultValue(outputValue)
   { /* Nothing to do */ }
 
   std::pair<std::shared_ptr<CSpatialTransformFilter>, std::shared_ptr<CSpatialTransformFilter> >
-  CSpatialTransformFilter::buildFilterGraph(CGarbageCollector& gc, CGrid* srcGrid, CGrid* destGrid, bool hasMissingValue, double missingValue)
+  CSpatialTransformFilter::buildFilterGraph(CGarbageCollector& gc, CGrid* srcGrid, CGrid* destGrid, bool hasMissingValue, double missingValue,
+                                            bool buildWorkflowGraph)
   {
     if (!srcGrid || !destGrid)
@@ -41,6 +43,8 @@
 
       std::shared_ptr<CSpatialTransformFilter> filter ;
-      if( isSpatialTemporal) filter = std::shared_ptr<CSpatialTransformFilter>(new CSpatialTemporalFilter(gc, engine, gridTransformation, defaultValue, inputCount));
-      else filter = std::shared_ptr<CSpatialTransformFilter>(new CSpatialTransformFilter(gc, engine, defaultValue, inputCount));
+      if( isSpatialTemporal)
+        filter = std::shared_ptr<CSpatialTransformFilter>(new CSpatialTemporalFilter(gc, engine, gridTransformation, defaultValue, inputCount, buildWorkflowGraph));
+      else
+        filter = std::shared_ptr<CSpatialTransformFilter>(new CSpatialTransformFilter(gc, engine, defaultValue, inputCount, buildWorkflowGraph));
 
       
@@ -48,5 +52,19 @@
         lastFilter = filter;
       else
+      {
         filter->connectOutput(firstFilter, 0);
+        if (buildWorkflowGraph)
+        {
+          if(CWorkflowGraph::mapFilters_ptr==0) CWorkflowGraph::mapFilters_ptr = new std::unordered_map <int, StdString>;
+          if(CWorkflowGraph::mapFieldToFilters_ptr==0) CWorkflowGraph::mapFieldToFilters_ptr = new std::unordered_map <StdString, vector <int> >;
+          int filterOut = (std::static_pointer_cast<COutputPin>(filter))->getFilterId();
+          int filterIn = (std::static_pointer_cast<COutputPin>(firstFilter))->getFilterId();
+          // PASS field's id here
+          (*CWorkflowGraph::mapFieldToFilters_ptr)["XXX"].push_back(filterOut);
+          (*CWorkflowGraph::mapFieldToFilters_ptr)["XXX"].push_back(filterIn);
+          (*CWorkflowGraph::mapFilters_ptr)[filterOut] = "Spatial transform filter";
+          (*CWorkflowGraph::mapFilters_ptr)[filterIn] = "Spatial transform filter";
+        }
+      }
 
       firstFilter = filter;
@@ -73,6 +91,8 @@
   }
 
-  CSpatialTemporalFilter::CSpatialTemporalFilter(CGarbageCollector& gc, CSpatialTransformFilterEngine* engine, CGridTransformation* gridTransformation, double outputValue, size_t inputSlotsCount)
-    : CSpatialTransformFilter(gc, engine, outputValue, inputSlotsCount), record(0)
+  CSpatialTemporalFilter::CSpatialTemporalFilter(CGarbageCollector& gc, CSpatialTransformFilterEngine* engine,
+                                                  CGridTransformation* gridTransformation, double outputValue,
+                                                  size_t inputSlotsCount, bool buildWorkflowGraph)
+    : CSpatialTransformFilter(gc, engine, outputValue, inputSlotsCount, buildWorkflowGraph), record(0)
   {
       const CGridTransformationSelector::ListAlgoType& algoList = gridTransformation->getAlgoList() ;
Index: XIOS/dev/dev_trunk_omp/src/filter/spatial_transform_filter.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/filter/spatial_transform_filter.hpp	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/src/filter/spatial_transform_filter.hpp	(revision 1668)
@@ -23,6 +23,10 @@
        * \param outputValue default value of output pin
        * \param [in] inputSlotsCount number of input, by default there is only one for field src
+       * \param buildWorkflowGraph indicates whether data will be visualized
        */
-      CSpatialTransformFilter(CGarbageCollector& gc, CSpatialTransformFilterEngine* engine, double outputValue, size_t inputSlotsCount = 1);
+      CSpatialTransformFilter(CGarbageCollector& gc, CSpatialTransformFilterEngine* engine,
+                              double outputValue, size_t inputSlotsCount = 1, bool buildWorkflowGraph = false);
+
+      inline StdString GetName(void) {return StdString("Spatial transform filter");};
 
       /*!
@@ -34,8 +38,9 @@
        * \param hasMissingValue whether field source has missing value
        * \param defaultValue default value
+       * \param buildWorkflowGraph indicates whether data will be visualized
        * \return the first and the last filters of the filter graph
        */
       static std::pair<std::shared_ptr<CSpatialTransformFilter>, std::shared_ptr<CSpatialTransformFilter> >
-      buildFilterGraph(CGarbageCollector& gc, CGrid* srcGrid, CGrid* destGrid, bool hasMissingValue, double defaultValue);
+      buildFilterGraph(CGarbageCollector& gc, CGrid* srcGrid, CGrid* destGrid, bool hasMissingValue, double defaultValue, bool buildWorkflowGraph = false);
 
     protected:
@@ -67,6 +72,9 @@
        * \param outputValue default value of output pin
        * \param [in] inputSlotsCount number of input, by default there is only one for field src
+       * \param buildWorkflowGraph indicates whether data will be visualized
+       *
        */
-      CSpatialTemporalFilter(CGarbageCollector& gc, CSpatialTransformFilterEngine* engine, CGridTransformation* gridTransformation, double outputValue, size_t inputSlotsCount = 1);
+      CSpatialTemporalFilter(CGarbageCollector& gc, CSpatialTransformFilterEngine* engine, CGridTransformation* gridTransformation,
+                            double outputValue, size_t inputSlotsCount = 1, bool buildWorkflowGraph = false);
 
 
Index: XIOS/dev/dev_trunk_omp/src/filter/store_filter.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/filter/store_filter.cpp	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/src/filter/store_filter.cpp	(revision 1668)
@@ -138,3 +138,9 @@
     packets.erase(packets.begin(), packets.lower_bound(timestamp));
   }
+
+  int CStoreFilter::getFilterId(void)
+  {
+    return filterId;
+  }
+
 } // namespace xios
Index: XIOS/dev/dev_trunk_omp/src/filter/store_filter.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/filter/store_filter.hpp	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/src/filter/store_filter.hpp	(revision 1668)
@@ -73,4 +73,9 @@
       void virtual invalidate(Time timestamp);
 
+      /*!
+       * Returns filter's id needed in case of building workflow graph
+       */
+      int getFilterId();
+
     protected:
       /*!
@@ -88,4 +93,6 @@
       const double missingValue; //!< The value to use to replace missing values
       std::map<Time, CDataPacketPtr> packets; //<! The stored packets
+      int filterId;                     //!< Filter's id needed in case of building a workflow
+
   }; // class CStoreFilter
 } // namespace xios
Index: XIOS/dev/dev_trunk_omp/src/filter/temporal_filter.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/filter/temporal_filter.cpp	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/src/filter/temporal_filter.cpp	(revision 1668)
@@ -9,6 +9,6 @@
   CTemporalFilter::CTemporalFilter(CGarbageCollector& gc, const std::string& opId,
                                    const CDate& initDate, const CDuration samplingFreq, const CDuration samplingOffset, const CDuration opFreq,
-                                   bool ignoreMissingValue /*= false*/)
-    : CFilter(gc, 1, this)
+                                   bool ignoreMissingValue /*= false*/, bool buildWorkflowGraph /*= false*/)
+    : CFilter(gc, 1, this, buildWorkflowGraph)
     , functor(createFunctor(opId, ignoreMissingValue, tmpData))
     , isOnceOperation(functor->timeType() == func::CFunctor::once)
Index: XIOS/dev/dev_trunk_omp/src/filter/temporal_filter.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/filter/temporal_filter.hpp	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/src/filter/temporal_filter.hpp	(revision 1668)
@@ -29,5 +29,7 @@
       CTemporalFilter(CGarbageCollector& gc, const std::string& opId,
                       const CDate& initDate, const CDuration samplingFreq, const CDuration samplingOffset, const CDuration opFreq,
-                      bool ignoreMissingValue = false);
+                      bool ignoreMissingValue = false, bool buildWorkflowGraph = false);
+
+      inline StdString GetName(void) {return StdString("Temporal filter");};
 
       /*!
Index: XIOS/dev/dev_trunk_omp/src/graphviz.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/graphviz.cpp	(revision 1668)
+++ XIOS/dev/dev_trunk_omp/src/graphviz.cpp	(revision 1668)
@@ -0,0 +1,64 @@
+#include "graphviz.hpp"
+#include "workflow_graph.hpp"
+
+namespace xios
+{
+
+  CGraphviz::CGraphviz()
+  { }
+
+  /*!
+   *
+   */
+  void CGraphviz::buildStaticWorkflowGraph()
+  TRY
+  {
+    if (CWorkflowGraph::mapFieldToFilters_ptr !=0 && !CWorkflowGraph::mapFieldToFilters_ptr->empty())
+    {
+      CWorkflowGraph::buildStaticWorkflow();
+    
+      typedef boost::property<boost::edge_name_t, std::string> EdgeProperty;
+      typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::no_property, EdgeProperty> Graph;
+
+      // Input 1: nodes (=filters)
+      vector<StdString>& nodes = CWorkflowGraph::filters;
+      const int nbNodes = nodes.size();
+
+      // Input 2: edges (=fields)
+      vector<StdString>& edges = CWorkflowGraph::fields;
+
+      // Input 3: nodes to edges connectivity
+      vector<pair<int, int> >& nodesToEdges = CWorkflowGraph::fieldsToFilters;
+      const int nbEdges = nodesToEdges.size();
+
+      // Declare a graph object, adding the edges and edge properties
+      Graph g(nbNodes);
+      for (int j = 0; j < nbEdges; ++j)
+      {
+        graph_traits<Graph>::edge_descriptor e;
+        bool inserted;
+        boost::tie(e, inserted) = boost::add_edge(nodesToEdges[j].first, nodesToEdges[j].second, edges[j], g);
+      }
+
+      std::for_each(vertices(g).first, vertices(g).second, exercise_vertex<Graph>(g));
+
+      std::map<std::string,std::string> graph_attr, vertex_attr, edge_attr;
+      graph_attr["size"] = "5,5";
+      graph_attr["rankdir"] = "LR";
+      graph_attr["ratio"] = "fill";
+      vertex_attr["shape"] = "record";
+      vertex_attr["width"] = "2.2";
+      vertex_attr["fontsize"] = "16";
+
+      const std::string filename = "graph.dot";
+      std::ofstream file (filename.c_str());
+
+      boost::write_graphviz(file, g,
+          boost::make_label_writer(&nodes[0]),
+          boost::make_label_writer(get(edge_name, g)),
+          boost::make_graph_attributes_writer(graph_attr, vertex_attr, edge_attr));
+         
+    }
+  }
+  CATCH
+}
Index: XIOS/dev/dev_trunk_omp/src/graphviz.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/graphviz.hpp	(revision 1668)
+++ XIOS/dev/dev_trunk_omp/src/graphviz.hpp	(revision 1668)
@@ -0,0 +1,33 @@
+#ifndef __GRAPHVIZ_HPP__
+#define __GRAPHVIZ_HPP__
+
+#include <algorithm>
+#include <boost/utility.hpp>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/graphviz.hpp>
+
+namespace xios
+{
+
+  class CGraphviz
+  {
+
+    public:
+
+      CGraphviz();
+      static void buildStaticWorkflowGraph();
+
+    private:
+      template <class Graph> struct exercise_vertex;
+
+  }; // class CGraphviz
+
+  template <class Graph> struct CGraphviz::exercise_vertex {
+    exercise_vertex(Graph& g_) : g(g_) { }
+    typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
+    void operator()(const Vertex& v) const { } Graph& g;
+  };
+
+} // namespace xios
+
+#endif
Index: XIOS/dev/dev_trunk_omp/src/node/field.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/node/field.cpp	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/src/node/field.cpp	(revision 1668)
@@ -24,4 +24,5 @@
 #include "spatial_transform_filter.hpp"
 #include "file_server_writer_filter.hpp"
+#include "workflow_graph.hpp"
 
 namespace xios{
@@ -1120,4 +1121,5 @@
 
      const bool detectMissingValues = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true);
+     const bool buildWorkflowGraph = (!build_workflow_graph.isEmpty() && build_workflow_graph == true);
      const double defaultValue  = detectMissingValues ? default_value : (!default_value.isEmpty() ? default_value : 0.0);
 
@@ -1171,11 +1173,26 @@
            if (!field_ref.isEmpty())
            {
-             CGrid* gridRef = CField::get(field_ref)->grid;
+             CField* fieldRef = CField::get(field_ref);
+             fieldRef->build_workflow_graph.setValue(buildWorkflowGraph);
+             CGrid* gridRef = fieldRef->grid;
 
              if (grid && grid != gridRef && grid->hasTransform())
              {
-                 std::pair<std::shared_ptr<CFilter>, std::shared_ptr<CFilter> > filters = CSpatialTransformFilter::buildFilterGraph(gc, gridRef, grid, detectMissingValues, defaultValue); 
+               std::pair<std::shared_ptr<CFilter>, std::shared_ptr<CFilter> > filters = CSpatialTransformFilter::buildFilterGraph(gc, gridRef, grid,
+                                                                                         detectMissingValues, defaultValue, buildWorkflowGraph);
 
                filter->connectOutput(filters.first, 0);
+
+               if (buildWorkflowGraph)
+               {
+                 if(CWorkflowGraph::mapFilters_ptr==0) CWorkflowGraph::mapFilters_ptr = new std::unordered_map <int, StdString>;
+                 if(CWorkflowGraph::mapFieldToFilters_ptr==0) CWorkflowGraph::mapFieldToFilters_ptr = new std::unordered_map <StdString, vector <int> >;
+                 int filterOut = filter->getFilterId();
+                 int filterIn = (std::static_pointer_cast<COutputPin>(filters.second))->getFilterId();
+                 (*CWorkflowGraph::mapFieldToFilters_ptr)[this->getId()].push_back(filterOut);
+                 (*CWorkflowGraph::mapFieldToFilters_ptr)[this->getId()].push_back(filterIn);
+                 (*CWorkflowGraph::mapFilters_ptr)[filterOut] = filter->GetName();
+                 (*CWorkflowGraph::mapFilters_ptr)[filterIn] = filters.second->GetName();
+               }
                filter = filters.second;
              }
@@ -1186,5 +1203,8 @@
          // Check if we have a reference on another field
          else if (!field_ref.isEmpty())
+         {
+           CField::get(field_ref)->build_workflow_graph.setValue(buildWorkflowGraph);
            instantDataFilter = getFieldReference(gc);
+         }
          // Check if the data is to be read from a file
          else if (file && !file->mode.isEmpty() && file->mode == CFile::mode_attr::read)
@@ -1192,5 +1212,5 @@
            checkTimeAttributes();
            instantDataFilter = serverSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, false, freq_offset, true,
-                                                                                                       detectMissingValues, defaultValue));
+                                                                                                       detectMissingValues, defaultValue, buildWorkflowGraph));
          }
          else // The data might be passed from the model
@@ -1198,5 +1218,10 @@
             if (check_if_active.isEmpty()) check_if_active = false; 
             instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, false, true, NoneDu, false,
-                                                                                                        detectMissingValues, defaultValue));
+                                                                                                      detectMissingValues, defaultValue, buildWorkflowGraph));
+            if (buildWorkflowGraph) 
+            {
+              if(CWorkflowGraph::mapFilters_ptr==0) CWorkflowGraph::mapFilters_ptr = new std::unordered_map <int, StdString>;
+              (*CWorkflowGraph::mapFilters_ptr)[instantDataFilter->getFilterId()] = instantDataFilter->GetName();
+            }  
          }
        }
@@ -1214,6 +1239,17 @@
          if (file && (file->mode.isEmpty() || file->mode == CFile::mode_attr::write))
          {
-           fileWriterFilter = std::shared_ptr<CFileWriterFilter>(new CFileWriterFilter(gc, this));
+           fileWriterFilter = std::shared_ptr<CFileWriterFilter>(new CFileWriterFilter(gc, this, buildWorkflowGraph));
            getTemporalDataFilter(gc, file->output_freq)->connectOutput(fileWriterFilter, 0);
+           if (buildWorkflowGraph)
+           {
+             if(CWorkflowGraph::mapFilters_ptr==0) CWorkflowGraph::mapFilters_ptr = new std::unordered_map <int, StdString>;
+             if(CWorkflowGraph::mapFieldToFilters_ptr==0) CWorkflowGraph::mapFieldToFilters_ptr = new std::unordered_map <StdString, vector <int> >;
+             int filterOut = getTemporalDataFilter(gc, file->output_freq)->getFilterId();
+             int filterIn = fileWriterFilter->getFilterId();
+             (*CWorkflowGraph::mapFieldToFilters_ptr)[this->getId()].push_back(filterOut);
+             (*CWorkflowGraph::mapFieldToFilters_ptr)[this->getId()].push_back(filterIn);
+             (*CWorkflowGraph::mapFilters_ptr)[filterOut] = "Temporal filter";
+             (*CWorkflowGraph::mapFilters_ptr)[filterIn] = fileWriterFilter->GetName();
+           }
          }
        }
@@ -1238,4 +1274,5 @@
      CField* fieldRef = CField::get(field_ref);
      fieldRef->buildFilterGraph(gc, false);
+     bool buildWorkflowGraph = (!build_workflow_graph.isEmpty() && build_workflow_graph == true);
 
      std::pair<std::shared_ptr<CFilter>, std::shared_ptr<CFilter> > filters;
@@ -1245,11 +1282,24 @@
        bool hasMissingValue = (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true);
        double defaultValue  = hasMissingValue ? default_value : (!default_value.isEmpty() ? default_value : 0.0);                                
-       filters = CSpatialTransformFilter::buildFilterGraph(gc, fieldRef->grid, grid, hasMissingValue, defaultValue);
+       filters = CSpatialTransformFilter::buildFilterGraph(gc, fieldRef->grid, grid, hasMissingValue, defaultValue, buildWorkflowGraph);
      }
      else
-       filters.first = filters.second = std::shared_ptr<CFilter>(new CPassThroughFilter(gc));
+     {
+       filters.first = filters.second = std::shared_ptr<CFilter>(new CPassThroughFilter(gc, buildWorkflowGraph));
+     }
 
      fieldRef->getInstantDataFilter()->connectOutput(filters.first, 0);
 
+     if (buildWorkflowGraph)
+     {
+       if(CWorkflowGraph::mapFilters_ptr==0) CWorkflowGraph::mapFilters_ptr = new std::unordered_map <int, StdString>;
+       if(CWorkflowGraph::mapFieldToFilters_ptr==0) CWorkflowGraph::mapFieldToFilters_ptr = new std::unordered_map <StdString, vector <int> >;
+       int filterOut = fieldRef->instantDataFilter->getFilterId();
+       int filterIn = (std::static_pointer_cast<COutputPin>(filters.first))->getFilterId();
+       (*CWorkflowGraph::mapFieldToFilters_ptr)[fieldRef->getId()].push_back(filterOut);
+       (*CWorkflowGraph::mapFieldToFilters_ptr)[fieldRef->getId()].push_back(filterIn);
+       (*CWorkflowGraph::mapFilters_ptr)[filterOut] = fieldRef->getInstantDataFilter()->GetName();
+       (*CWorkflowGraph::mapFilters_ptr)[filterIn] = filters.first->GetName();
+     }
      return filters.second;
    }
@@ -1324,4 +1374,5 @@
    {
      std::map<CDuration, std::shared_ptr<COutputPin> >::iterator it = temporalDataFilters.find(outFreq);
+     const bool buildWorkflowGraph = (!build_workflow_graph.isEmpty() && build_workflow_graph == true);
 
      if (it == temporalDataFilters.end())
@@ -1334,9 +1385,21 @@
 
        const bool detectMissingValues = (!detect_missing_value.isEmpty()  && detect_missing_value == true);
-       std::shared_ptr<CTemporalFilter> temporalFilter(new CTemporalFilter(gc, operation,
-                                                                             CContext::getCurrent()->getCalendar()->getInitDate(),
-                                                                             freq_op, freq_offset, outFreq, detectMissingValues));
+       std::shared_ptr<CTemporalFilter> temporalFilter(new CTemporalFilter(gc, operation, CContext::getCurrent()->getCalendar()->getInitDate(),
+                                                                             freq_op, freq_offset, outFreq,
+                                                                             detectMissingValues, buildWorkflowGraph));
 
        instantDataFilter->connectOutput(temporalFilter, 0);
+
+       if (buildWorkflowGraph)
+       {
+         if(CWorkflowGraph::mapFilters_ptr==0) CWorkflowGraph::mapFilters_ptr = new std::unordered_map <int, StdString>;
+         if(CWorkflowGraph::mapFieldToFilters_ptr==0) CWorkflowGraph::mapFieldToFilters_ptr = new std::unordered_map <StdString, vector <int> >;
+         int filterOut = instantDataFilter->getFilterId();
+         int filterIn = (std::static_pointer_cast<COutputPin>(temporalFilter))->getFilterId();
+         (*CWorkflowGraph::mapFieldToFilters_ptr)[this->getId()].push_back(filterOut);
+         (*CWorkflowGraph::mapFieldToFilters_ptr)[this->getId()].push_back(filterIn);
+         (*CWorkflowGraph::mapFilters_ptr)[filterOut] = getInstantDataFilter()->GetName();
+         (*CWorkflowGraph::mapFilters_ptr)[filterIn] = temporalFilter->GetName();
+       }
 
        it = temporalDataFilters.insert(std::make_pair(outFreq, temporalFilter)).first;
@@ -1374,9 +1437,24 @@
 
        const bool detectMissingValues = (!detect_missing_value.isEmpty() && detect_missing_value == true);
+       const bool buildWorkflowGraph = (!build_workflow_graph.isEmpty() && build_workflow_graph == true);
        std::shared_ptr<CTemporalFilter> temporalFilter(new CTemporalFilter(gc, operation,
-                                                                             CContext::getCurrent()->getCalendar()->getInitDate(),
-                                                                             freq_op, freq_offset, outFreq, detectMissingValues));
+                                                                           CContext::getCurrent()->getCalendar()->getInitDate(),
+                                                                           freq_op, freq_offset, outFreq,
+                                                                           detectMissingValues, buildWorkflowGraph));
 
        selfReferenceFilter->connectOutput(temporalFilter, 0);
+       if (buildWorkflowGraph)
+
+       {
+         if(CWorkflowGraph::mapFilters_ptr==0) CWorkflowGraph::mapFilters_ptr = new std::unordered_map <int, StdString>;
+         if(CWorkflowGraph::mapFieldToFilters_ptr==0) CWorkflowGraph::mapFieldToFilters_ptr = new std::unordered_map <StdString, vector <int> >;
+         int filterOut = selfReferenceFilter->getFilterId();
+         int filterIn = (std::static_pointer_cast<COutputPin>(temporalFilter))->getFilterId();
+         (*CWorkflowGraph::mapFieldToFilters_ptr)[this->getId()].push_back(filterOut);
+         (*CWorkflowGraph::mapFieldToFilters_ptr)[this->getId()].push_back(filterIn);
+         (*CWorkflowGraph::mapFilters_ptr)[filterOut] = selfReferenceFilter->GetName();
+         (*CWorkflowGraph::mapFilters_ptr)[filterIn] = temporalFilter->GetName();
+       }
+
        return temporalFilter ;
      }
Index: XIOS/dev/dev_trunk_omp/src/node/field.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/node/field.hpp	(revision 1667)
+++ XIOS/dev/dev_trunk_omp/src/node/field.hpp	(revision 1668)
@@ -7,4 +7,5 @@
 #include "functor.hpp"
 #include "functor_type.hpp"
+#include "filter.hpp"
 #include "duration.hpp"
 #include "date.hpp"
Index: XIOS/dev/dev_trunk_omp/src/workflow_graph.cpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/workflow_graph.cpp	(revision 1668)
+++ XIOS/dev/dev_trunk_omp/src/workflow_graph.cpp	(revision 1668)
@@ -0,0 +1,55 @@
+#include "workflow_graph.hpp"
+
+namespace xios
+{
+
+  std::unordered_map <StdString, vector <int > > *CWorkflowGraph::mapFieldToFilters_ptr = 0;
+  #pragma omp threadprivate(CWorkflowGraph::mapFieldToFilters_ptr)
+
+  std::unordered_map <int, StdString> *CWorkflowGraph::mapFilters_ptr = 0;
+  #pragma omp threadprivate(CWorkflowGraph::mapFilters_ptr)
+
+  std::unordered_map <int,vector<Time> > *CWorkflowGraph::mapFilterTimestamps_ptr = 0;
+  #pragma omp threadprivate(CWorkflowGraph::mapFilterTimestamps_ptr)
+
+  set<Time>  *CWorkflowGraph::timestamps_ptr = 0;
+  #pragma omp threadprivate(CWorkflowGraph::timestamps_ptr)
+
+  vector <StdString> CWorkflowGraph::filters;
+  vector <StdString> CWorkflowGraph::fields;
+  vector <pair<int, int> > CWorkflowGraph::fieldsToFilters;
+
+  CWorkflowGraph::CWorkflowGraph()
+  { }
+
+  /*!
+   * Reorganize information collected by XIOS for visualization.
+   */
+  void CWorkflowGraph::buildStaticWorkflow()
+  TRY
+  {
+    // Create a list of filters (graph nodes)
+    if(mapFilters_ptr==0) mapFilters_ptr = new std::unordered_map <int, StdString>;
+    if(mapFieldToFilters_ptr==0) mapFieldToFilters_ptr = new std::unordered_map <StdString, vector <int > >;
+    size_t filterIdx = 0;
+    filters.resize(mapFilters_ptr->size());
+    //printf("mapFilters_ptr size = %lu\n", mapFilters_ptr->size());
+    for (auto it=mapFilters_ptr->begin(); it != mapFilters_ptr->end(); it++)
+    {
+      filters[it->first]=it->second;
+      //std::cout<<"mapFilters_ptr["<<it->first<<"]="<<it->second<<std::endl;
+    }
+
+    // Create a list of fields and their filter connectivity (graph edges and edge-to-node connectivity)
+    for (auto it=mapFieldToFilters_ptr->begin(); it != mapFieldToFilters_ptr->end(); it++)
+    {
+      for (size_t i = 0; i < (it->second.size() - 1); i+=2)
+      {
+        fieldsToFilters.push_back(make_pair(it->second[i],it->second[i+1]));
+        fields.push_back(it->first);
+      }
+    }
+  }
+  CATCH
+
+}
Index: XIOS/dev/dev_trunk_omp/src/workflow_graph.hpp
===================================================================
--- XIOS/dev/dev_trunk_omp/src/workflow_graph.hpp	(revision 1668)
+++ XIOS/dev/dev_trunk_omp/src/workflow_graph.hpp	(revision 1668)
@@ -0,0 +1,61 @@
+#ifndef __WORKFLOW_GRAPH_HPP__
+#define __WORKFLOW_GRAPH_HPP__
+
+#include "xios_spl.hpp"
+#include "field.hpp"
+#include "garbage_collector.hpp"
+
+namespace xios
+{
+
+  class CWorkflowGraph
+  {
+
+    friend class CGraphviz;
+
+    public:
+
+      CWorkflowGraph();
+
+      /*! Map between fields identified by its id and their filters identified by an integer.
+       * It is filled up during reconstruction of a workflow (in function CField::buildFilterGraph()).
+      */
+      static std::unordered_map <StdString, vector <int> > *mapFieldToFilters_ptr;
+      #pragma omp threadprivate(mapFieldToFilters_ptr)
+
+      /*! Map between filter ids and filter types.
+       * It is filled up during reconstruction of a workflow (in function CField::buildFilterGraph()).
+       */
+      static std::unordered_map <int, StdString> *mapFilters_ptr;
+      #pragma omp threadprivate(mapFilters_ptr)
+
+      /*! Map between filters and timestamps.
+       * Timestamps are added into the map at the exit of a filter (in function COutputPin::onOutputReady)
+       */
+      static std::unordered_map <int, vector<Time> > *mapFilterTimestamps_ptr;
+      #pragma omp threadprivate(mapFilterTimestamps_ptr)
+
+      /*! List of timestamps.
+       * Timestamps are added at the exit of a filter (in function COutputPin::onOutputReady)
+       */
+      static set<Time> *timestamps_ptr;
+      #pragma omp threadprivate(timestamps_ptr)
+
+    private:
+
+      //! List of fields marked for visualizing of their workflow
+      static vector <StdString> fields;
+
+      //! List of connected filters for fields for visualizing of their workflow
+      static vector <StdString> filters;
+
+      //! Fields to filters connectivity
+      static vector <pair<int, int> > fieldsToFilters;
+
+      static void buildStaticWorkflow();
+
+
+  };
+}
+
+#endif
