diff --git a/GaudiUtils/include/GaudiUtils/Histo2String.h b/GaudiUtils/include/GaudiUtils/Histo2String.h
index b860bc1ad44126c422344f4373bbef74f70257e4..5d3560bd56a8e27b810fd8704fed236058ca4953 100644
--- a/GaudiUtils/include/GaudiUtils/Histo2String.h
+++ b/GaudiUtils/include/GaudiUtils/Histo2String.h
@@ -31,14 +31,17 @@
 namespace AIDA {
   class IHistogram1D;
   class IHistogram2D;
+  class IHistogram3D;
 } // namespace AIDA
 // ============================================================================
 // ROOT
 // ============================================================================
 class TH1D; // ROOT
 class TH2D; // ROOT
+class TH3D; // ROOT
 class TH1F; // ROOT
 class TH2F; // ROOT
+class TH3F; // ROOT
 // ============================================================================
 namespace Gaudi {
   // ===========================================================================
@@ -64,6 +67,16 @@ namespace Gaudi {
      */
     GAUDI_API std::ostream& toStream( const TH2D& histo, std::ostream& stream, const bool asXML = false );
     // =========================================================================
+    /** stream the ROOT histogram into output stream
+     *  @param histo  (INPUT)  the histogram to be streamed
+     *  @param stream (OUTPUT) the stream
+     *  @param asXML  (INPUT)  use XML-format
+     *  @return the updated stream
+     *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
+     *  @date 2009-09-26
+     */
+    GAUDI_API std::ostream& toStream( const TH3D& histo, std::ostream& stream, const bool asXML = false );
+    // =========================================================================
     /** stream the ROOT histogram into output stream
      *  @param histo  (INPUT)  the histogram to be streamed
      *  @param stream (OUTPUT) the stream
@@ -84,6 +97,16 @@ namespace Gaudi {
      */
     GAUDI_API std::ostream& toStream( const TH2F& histo, std::ostream& stream, const bool asXML = false );
     // ========================================================================
+    /** stream the AIDA histogram into output stream
+     *  @param histo  (INPUT)  the histogram to be streamed
+     *  @param stream (OUTPUT) the stream
+     *  @param asXML  (INPUT)  use XML-format
+     *  @return the updated stream
+     *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
+     *  @date 2009-09-26
+     */
+    GAUDI_API std::ostream& toStream( const TH3F& histo, std::ostream& stream, const bool asXML = false );
+    // ========================================================================
     /** stream the AIDA histogram into output stream
      *  @param histo  (INPUT)  the histogram to be streamed
      *  @param stream (OUTPUT) the stream
@@ -104,6 +127,16 @@ namespace Gaudi {
      */
     GAUDI_API std::ostream& toStream( const AIDA::IHistogram2D& histo, std::ostream& stream, const bool asXML = false );
     // ========================================================================
+    /** stream the AIDA histogram into output stream
+     *  @param histo  (INPUT)  the histogram to be streamed
+     *  @param stream (OUTPUT) the stream
+     *  @param asXML  (INPUT)  use XML-format
+     *  @return the updated stream
+     *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
+     *  @date 2009-09-26
+     */
+    GAUDI_API std::ostream& toStream( const AIDA::IHistogram3D& histo, std::ostream& stream, const bool asXML = false );
+    // ========================================================================
     /** convert the histogram into the string
      *  @param histo  (INPUT)  the histogram to be streamed
      *  @param asXML  (INPUT)  use XML-format
@@ -122,6 +155,15 @@ namespace Gaudi {
      */
     GAUDI_API std::string toString( const TH2D& histo, const bool asXML = false );
     // ========================================================================
+    /** convert the histogram into the string
+     *  @param histo  (INPUT)  the histogram to be streamed
+     *  @param asXML  (INPUT)  use XML-format
+     *  @return the string representation of the histogram
+     *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
+     *  @date 2009-09-26
+     */
+    GAUDI_API std::string toString( const TH3D& histo, const bool asXML = false );
+    // ========================================================================
     /** convert the histogram into the string
      *  @param histo  (INPUT)  the histogram to be streamed
      *  @param asXML  (INPUT)  use XML-format
@@ -140,6 +182,15 @@ namespace Gaudi {
      */
     GAUDI_API std::string toString( const TH2F& histo, const bool asXML = false );
     // ========================================================================
+    /** convert the histogram into the string
+     *  @param histo  (INPUT)  the histogram to be streamed
+     *  @param asXML  (INPUT)  use XML-format
+     *  @return the string representation of the histogram
+     *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
+     *  @date 2009-09-26
+     */
+    GAUDI_API std::string toString( const TH3F& histo, const bool asXML = false );
+    // ========================================================================
     /** convert the histogram into the string
      *  @param histo  (INPUT)  the histogram to be streamed
      *  @param asXML  (INPUT)  use XML-format
@@ -158,6 +209,15 @@ namespace Gaudi {
      */
     GAUDI_API std::string toString( const AIDA::IHistogram2D& histo, const bool asXML = false );
     // ========================================================================
+    /** convert the histogram into the string
+     *  @param histo  (INPUT)  the histogram to be streamed
+     *  @param asXML  (INPUT)  use XML-format
+     *  @return the string representation of the histogram
+     *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
+     *  @date 2009-09-26
+     */
+    GAUDI_API std::string toString( const AIDA::IHistogram3D& histo, const bool asXML = false );
+    // ========================================================================
     /** convert the histogram into the string
      *  @param histo  (INPUT)  the histogram to be streamed
      *  @param asXML  (INPUT)  use XML-format
@@ -212,6 +272,24 @@ namespace Gaudi {
      */
     GAUDI_API std::string toString( TH2D* histo );
     // ========================================================================
+    /** convert the histogram into the string
+     *  @param histo  (INPUT)  the histogram to be streamed
+     *  @param asXML  (INPUT)  use XML-format
+     *  @return the string representation of the histogram
+     *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
+     *  @date 2009-09-26
+     */
+    GAUDI_API std::string toString( const TH3D* histo );
+    // ========================================================================
+    /** convert the histogram into the string
+     *  @param histo  (INPUT)  the histogram to be streamed
+     *  @param asXML  (INPUT)  use XML-format
+     *  @return the string representation of the histogram
+     *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
+     *  @date 2009-09-26
+     */
+    GAUDI_API std::string toString( TH3D* histo );
+    // ========================================================================
   } // namespace Utils
   // ==========================================================================
 } //                                                     end of namespace Gaudi
diff --git a/GaudiUtils/include/GaudiUtils/HistoParsers.h b/GaudiUtils/include/GaudiUtils/HistoParsers.h
index e2e831ec68f4f072a1a1e16ed7da4836a256361b..a470c7f92a80b3bdfc0d6d8fe53c2e1f6128278f 100644
--- a/GaudiUtils/include/GaudiUtils/HistoParsers.h
+++ b/GaudiUtils/include/GaudiUtils/HistoParsers.h
@@ -24,14 +24,17 @@
 namespace AIDA {
   class IHistogram1D; // AIDA
   class IHistogram2D; // AIDA
+  class IHistogram3D; // AIDA
 } // namespace AIDA
 // =============================================================================
 // ROOT
 // =============================================================================
 class TH1D; // ROOT
 class TH2D; // ROOT
+class TH3D; // ROOT
 class TH1F; // ROOT
 class TH2F; // ROOT
+class TH3F; // ROOT
 // =============================================================================
 namespace Gaudi {
   // ===========================================================================
@@ -51,6 +54,13 @@ namespace Gaudi {
      */
     GAUDI_API StatusCode parse( TH2D& result, const std::string& input );
     // =========================================================================
+    /** parse ROOT histogram from text representation
+     *  @param result (OUTPUT) the histogram
+     *  @param input  (INPUT)  the input to be parsed
+     *  @return status code
+     */
+    GAUDI_API StatusCode parse( TH3D& result, const std::string& input );
+    // =========================================================================
     /** parse ROOT histogram from text representation
      *  @param result (OUTPUT) the histogram
      *  @param input  (INPUT)  the input to be parsed
@@ -65,6 +75,13 @@ namespace Gaudi {
      */
     GAUDI_API StatusCode parse( TH2F& result, const std::string& input );
     // =========================================================================
+    /** parse AIDA histogram from text representation
+     *  @param result (OUTPUT) the histogram
+     *  @param input  (INPUT)  the input to be parsed
+     *  @return status code
+     */
+    GAUDI_API StatusCode parse( TH3F& result, const std::string& input );
+    // =========================================================================
     /** parse AIDA histogram from text representation
      *  @param result (OUTPUT) the histogram
      *  @param input  (INPUT)  the input to be parsed
@@ -79,6 +96,13 @@ namespace Gaudi {
      */
     GAUDI_API StatusCode parse( AIDA::IHistogram2D& result, const std::string& input );
     // =========================================================================
+    /** parse AIDA histogram from text representation
+     *  @param result (OUTPUT) the histogram
+     *  @param input  (INPUT)  the input to be parsed
+     *  @return status code
+     */
+    GAUDI_API StatusCode parse( AIDA::IHistogram3D& result, const std::string& input );
+    // =========================================================================
     /** parse ROOT histogram from text representation
      *  @param result (OUTPUT) the histogram
      *  @param input  (INPUT)  the input to be parsed
@@ -93,6 +117,13 @@ namespace Gaudi {
      */
     GAUDI_API StatusCode parse( TH2D*& result, const std::string& input );
     // =========================================================================
+    /** parse ROOT histogram from text representation
+     *  @param result (OUTPUT) the histogram
+     *  @param input  (INPUT)  the input to be parsed
+     *  @return status code
+     */
+    GAUDI_API StatusCode parse( TH3D*& result, const std::string& input );
+    // =========================================================================
   } // namespace Parsers
   // ===========================================================================
 } // end of namespace Gaudi
diff --git a/GaudiUtils/src/Lib/H1.h b/GaudiUtils/src/Lib/H1.h
index 6f89720d66018170a3d89be33b11cb47f072acb2..1356af992c85ebb9f912c8efafb2ebb14199845e 100644
--- a/GaudiUtils/src/Lib/H1.h
+++ b/GaudiUtils/src/Lib/H1.h
@@ -168,6 +168,66 @@ namespace {
     Bins        m_bins;
   };
   // ==========================================================================
+  /** @struct H3
+   *  the trivial representation of the 3D-histogram
+   *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
+   *  @date 2009-10-21
+   */
+  struct H3 final {
+    //
+    void setName( std::string value ) { m_name = std::move( value ); }
+    void setTitle( std::string value ) { m_title = std::move( value ); }
+    void setXEdges( Edges value ) { m_xedges = std::move( value ); }
+    void setYEdges( Edges value ) { m_yedges = std::move( value ); }
+    void setZEdges( Edges value ) { m_zedges = std::move( value ); }
+    void setBins( Bins value ) { m_bins = std::move( value ); }
+    //
+    H3& operator*=( std::string value ) {
+      setName( std::move( value ) );
+      return *this;
+    }
+    H3& operator/=( std::string value ) {
+      setTitle( std::move( value ) );
+      return *this;
+    }
+    H3& operator&=( Edges value ) {
+      setXEdges( std::move( value ) );
+      return *this;
+    }
+    H3& operator|=( Edges value ) {
+      setYEdges( std::move( value ) );
+      return *this;
+    }
+    H3& operator-=( Edges value ) {
+      setZEdges( std::move( value ) );
+      return *this;
+    }
+    H3& operator+=( Bins value ) {
+      setBins( std::move( value ) );
+      return *this;
+    }
+    //
+    bool ok() const {
+      if ( m_bins.empty() ) { return false; }
+      if ( !m_xedges.ok() ) { return false; }
+      if ( !m_yedges.ok() ) { return false; }
+      if ( !m_zedges.ok() ) { return false; }
+      if ( m_bins.size() != ( m_xedges.nBins() + 2 ) * ( m_yedges.nBins() + 2 ) * ( m_zedges.nBins() + 2 ) ) {
+        return false;
+      }
+      return true;
+    }
+    //
+    //
+    std::string m_name;
+    std::string m_title;
+    Edges       m_xedges;
+    Edges       m_yedges;
+    Edges       m_zedges;
+    Bins        m_bins;
+  };
+
+  // ==========================================================================
 } // end of anonymous namespace
 // ============================================================================
 // The END
diff --git a/GaudiUtils/src/Lib/Histo2String.cpp b/GaudiUtils/src/Lib/Histo2String.cpp
index 5f42ebe2e077b55279118a1f3565f455f8648283..8e8af0d39346189125f974dbaefb0e8af5d3fdd9 100644
--- a/GaudiUtils/src/Lib/Histo2String.cpp
+++ b/GaudiUtils/src/Lib/Histo2String.cpp
@@ -17,11 +17,14 @@
 #include "TH1F.h"
 #include "TH2D.h"
 #include "TH2F.h"
+#include "TH3D.h"
+#include "TH3F.h"
 // ============================================================================
 // AIDA
 // ============================================================================
 #include "AIDA/IHistogram1D.h"
 #include "AIDA/IHistogram2D.h"
+#include "AIDA/IHistogram3D.h"
 // ============================================================================
 // GaudiKernel
 // ============================================================================
@@ -156,6 +159,102 @@ namespace {
     return stream;
   }
   // ==========================================================================
+  template <class HISTO>
+  std::ostream& _toStream_3D_( const HISTO& histo, std::ostream& stream, const bool asXML ) {
+    if ( asXML ) { return Gaudi::Utils::Histos::toXml( histo, stream ); }
+    //
+    stream << "{ ";
+    //
+    stream << "'name'  : ";
+    Gaudi::Utils::toStream( std::string( histo.GetName() ), stream ) << " , ";
+    stream << "'title' : ";
+    Gaudi::Utils::toStream( std::string( histo.GetTitle() ), stream ) << " , ";
+    //
+    const TAxis* xaxis = histo.GetXaxis();
+    const int    xBins = xaxis->GetNbins();
+    //
+    stream << std::endl << "'X' : { ";
+    if ( xaxis->IsVariableBinSize() ) {
+      const TArrayD*      xbins = xaxis->GetXbins();
+      const unsigned int  xsize = xbins->GetSize();
+      std::vector<double> edges;
+      for ( unsigned int iBin = 0; iBin < xsize; ++iBin ) { edges.push_back( xbins->At( iBin ) ); }
+      // the edges
+      stream << "'edges' : ";
+      Gaudi::Utils::toStream( edges, stream ) << " }," << std::endl;
+    } else {
+      stream << "'nbins' : ";
+      Gaudi::Utils::toStream( xBins, stream ) << " , ";
+      stream << "'low'   : ";
+      Gaudi::Utils::toStream( xaxis->GetXmin(), stream ) << " , ";
+      stream << "'high'  : ";
+      Gaudi::Utils::toStream( xaxis->GetXmax(), stream ) << " }, " << std::endl;
+    }
+    //
+    const TAxis* yaxis = histo.GetYaxis();
+    const int    yBins = yaxis->GetNbins();
+    //
+    stream << std::endl << "'Y' : { ";
+    if ( yaxis->IsVariableBinSize() ) {
+      const TArrayD*      ybins = yaxis->GetXbins();
+      const unsigned int  ysize = ybins->GetSize();
+      std::vector<double> edges;
+      for ( unsigned int iBin = 0; iBin < ysize; ++iBin ) { edges.push_back( ybins->At( iBin ) ); }
+      // the edges
+      stream << " 'edges' : ";
+      Gaudi::Utils::toStream( edges, stream ) << " }," << std::endl;
+    } else {
+      stream << "'nbins' : ";
+      Gaudi::Utils::toStream( yBins, stream ) << " , ";
+      stream << "'low'   : ";
+      Gaudi::Utils::toStream( yaxis->GetXmin(), stream ) << " , ";
+      stream << "'high'  : ";
+      Gaudi::Utils::toStream( yaxis->GetXmax(), stream ) << " }, " << std::endl;
+    }
+    //
+    const TAxis* zaxis = histo.GetZaxis();
+    const int    zBins = zaxis->GetNbins();
+    //
+    stream << std::endl << "'Z' : { ";
+    if ( zaxis->IsVariableBinSize() ) {
+      const TArrayD*      zbins = zaxis->GetXbins();
+      const unsigned int  zsize = zbins->GetSize();
+      std::vector<double> edges;
+      for ( unsigned int iBin = 0; iBin < zsize; ++iBin ) { edges.push_back( zbins->At( iBin ) ); }
+      // the edges
+      stream << " 'edges' : ";
+      Gaudi::Utils::toStream( edges, stream ) << " }," << std::endl;
+    } else {
+      stream << "'nbins' : ";
+      Gaudi::Utils::toStream( zBins, stream ) << " , ";
+      stream << "'low'   : ";
+      Gaudi::Utils::toStream( zaxis->GetXmin(), stream ) << " , ";
+      stream << "'high'  : ";
+      Gaudi::Utils::toStream( zaxis->GetXmax(), stream ) << " }, " << std::endl;
+    }
+    //
+    // finally: the content
+    stream << "'bins' : " << std::endl << " [ ";
+    for ( int kBin = 0; kBin <= zBins + 1; ++kBin ) {
+      for ( int jBin = yBins + 1; jBin >= 0; --jBin ) {
+        if ( yBins + 1 != jBin ) { stream << std::endl; }
+        for ( int iBin = 0; iBin <= xBins + 1; ++iBin ) {
+          //
+          Gaudi::Utils::toStream(
+              std::make_pair( histo.GetBinContent( iBin, jBin, kBin ), histo.GetBinError( iBin, jBin, kBin ) ),
+              stream );
+          //
+          if ( !( ( ( xBins + 1 ) == iBin ) && ( 0 == jBin ) && ( ( zBins + 1 ) == kBin ) ) ) { stream << " , "; }
+        }
+      }
+    }
+    stream << " ]";
+    //
+    stream << " }";
+    //
+    return stream;
+  }
+  // ==========================================================================
 } //                                                 end of anonymous namespace
 // ============================================================================
 /*  stream the ROOT histogram into output stream
@@ -198,6 +297,26 @@ std::ostream& Gaudi::Utils::toStream( const TH2F& histo, std::ostream& stream, c
   return _toStream_2D_( histo, stream, asXML );
 }
 // ============================================================================
+/*  stream the ROOT histogram into output stream
+ *  @param histo  (INPUT)  the histogram to be streamed
+ *  @param stream (OUTPUT) the stream
+ *  @param asXML  (INPUT)  use XML-format
+ */
+// ============================================================================
+std::ostream& Gaudi::Utils::toStream( const TH3D& histo, std::ostream& stream, const bool asXML ) {
+  return _toStream_3D_( histo, stream, asXML );
+}
+// ============================================================================
+/*  stream the ROOT histogram into output stream
+ *  @param histo  (INPUT)  the histogram to be streamed
+ *  @param stream (OUTPUT) the stream
+ *  @param asXML  (INPUT)  use XML-format
+ */
+// ============================================================================
+std::ostream& Gaudi::Utils::toStream( const TH3F& histo, std::ostream& stream, const bool asXML ) {
+  return _toStream_3D_( histo, stream, asXML );
+}
+// ============================================================================
 /*  stream the AIDA histogram into output stream
  *  @param histo  (INPUT)  the histogram to be streamed
  *  @param stream (OUTPUT) the stream
@@ -220,6 +339,19 @@ std::ostream& Gaudi::Utils::toStream( const AIDA::IHistogram2D& histo, std::ostr
   auto root = Gaudi::Utils::Aida2ROOT::aida2root( &histo );
   return root ? toStream( *root, stream, asXML ) : stream;
 }
+// ============================================================================
+/*  stream the AIDA histogram into output stream
+ *  @param histo  (INPUT)  the histogram to be streamed
+ *  @param stream (OUTPUT) the stream
+ *  @param asXML  (INPUT)  use XML-format
+ */
+// ============================================================================
+std::ostream& Gaudi::Utils::toStream( const AIDA::IHistogram3D& histo, std::ostream& stream, const bool asXML ) {
+  //
+  auto root = Gaudi::Utils::Aida2ROOT::aida2root( &histo );
+  return root ? toStream( *root, stream, asXML ) : stream;
+}
+
 // ============================================================================
 /*  convert the histogram into the string
  *  @param histo  (INPUT)  the histogram to be streamed
@@ -285,6 +417,34 @@ std::string Gaudi::Utils::toString( const TH2F& histo, const bool asXML ) {
  *  @date 2009-09-26
  */
 // ============================================================================
+std::string Gaudi::Utils::toString( const TH3D& histo, const bool asXML ) {
+  std::ostringstream o;
+  toStream( histo, o, asXML );
+  return o.str();
+}
+// ============================================================================
+/*  convert the histogram into the string
+ *  @param histo  (INPUT)  the histogram to be streamed
+ *  @param asXML  (INPUT)  use XML-format
+ *  @return the string representation of the histogram
+ *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
+ *  @date 2009-09-26
+ */
+// ============================================================================
+std::string Gaudi::Utils::toString( const TH3F& histo, const bool asXML ) {
+  std::ostringstream o;
+  toStream( histo, o, asXML );
+  return o.str();
+}
+// ============================================================================
+/*  convert the histogram into the string
+ *  @param histo  (INPUT)  the histogram to be streamed
+ *  @param asXML  (INPUT)  use XML-format
+ *  @return the string representation of the histogram
+ *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
+ *  @date 2009-09-26
+ */
+// ============================================================================
 std::string Gaudi::Utils::toString( const AIDA::IHistogram1D& histo, const bool asXML ) {
   std::ostringstream o;
   toStream( histo, o, asXML );
@@ -305,6 +465,20 @@ std::string Gaudi::Utils::toString( const AIDA::IHistogram2D& histo, const bool
   return o.str();
 }
 // =============================================================================
+/*  convert the histogram into the string
+ *  @param histo  (INPUT)  the histogram to be streamed
+ *  @param asXML  (INPUT)  use XML-format
+ *  @return the string representation of the histogram
+ *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
+ *  @date 2009-09-26
+ */
+// ============================================================================
+std::string Gaudi::Utils::toString( const AIDA::IHistogram3D& histo, const bool asXML ) {
+  std::ostringstream o;
+  toStream( histo, o, asXML );
+  return o.str();
+}
+// =============================================================================
 /*  convert the histogram into the string
  *  @param histo  (INPUT)  the histogram to be streamed
  *  @param asXML  (INPUT)  use XML-format
@@ -365,5 +539,25 @@ std::string Gaudi::Utils::toString( TH1D* histo ) { return histo ? toString( *hi
 // =============================================================================
 std::string Gaudi::Utils::toString( TH2D* histo ) { return histo ? toString( *histo ) : "{}"; }
 // ============================================================================
+/*  convert the histogram into the string
+ *  @param histo  (INPUT)  the histogram to be streamed
+ *  @param asXML  (INPUT)  use XML-format
+ *  @return the string representation of the histogram
+ *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
+ *  @date 2009-09-26
+ */
+// =============================================================================
+std::string Gaudi::Utils::toString( const TH3D* histo ) { return histo ? toString( *histo ) : "{}"; }
+// ============================================================================
+/*  convert the histogram into the string
+ *  @param histo  (INPUT)  the histogram to be streamed
+ *  @param asXML  (INPUT)  use XML-format
+ *  @return the string representation of the histogram
+ *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
+ *  @date 2009-09-26
+ */
+// =============================================================================
+std::string Gaudi::Utils::toString( TH3D* histo ) { return histo ? toString( *histo ) : "{}"; }
+// ============================================================================
 // The END
 // ============================================================================
diff --git a/GaudiUtils/src/Lib/HistoParsers.cpp b/GaudiUtils/src/Lib/HistoParsers.cpp
index 7642a149c1dc326427bf5821a58c4c3816ac3666..73d105c0a968b6cae8e5703d701d3a9a49bd2339 100644
--- a/GaudiUtils/src/Lib/HistoParsers.cpp
+++ b/GaudiUtils/src/Lib/HistoParsers.cpp
@@ -161,6 +161,42 @@ namespace Gaudi {
     };
     REGISTER_GRAMMAR( H2, H2Grammar );
     // ========================================================================
+    template <typename Iterator, typename Skipper>
+    class H3Grammar : public qi::grammar<Iterator, H3(), qi::locals<char>, Skipper> {
+      // ======================================================================
+    public:
+      // ======================================================================
+      typedef H3 ResultT;
+      // ======================================================================
+    public:
+      // ======================================================================
+      H3Grammar() : H3Grammar::base_type( result ) {
+        inner = ( ( ( qi::lit( "name" ) | "'name'" | "\"name\"" ) >> ":" >> name[qi::_val *= qi::_1] ) |
+                  ( ( qi::lit( "title" ) | "'title'" | "\"title\"" ) >> ":" >> title[qi::_val /= qi::_1] ) |
+                  ( ( qi::lit( "X" ) | "'X'" | "\"X\"" | "x" | "'x'" | "\"x\"" ) >> ':' >> edges[qi::_val &= qi::_1] ) |
+                  ( ( qi::lit( "Y" ) | "'Y'" | "\"Y\"" | "y" | "'y'" | "\"y\"" ) >> ':' >> edges[qi::_val |= qi::_1] ) |
+                  ( ( qi::lit( "Z" ) | "'Z'" | "\"Z\"" | "z" | "'z'" | "\"z\"" ) >> ':' >> edges[qi::_val -= qi::_1] ) |
+                  ( ( qi::lit( "bins" ) | "'bins'" | "\"bins\"" ) >> ':' >> bins[qi::_val += qi::_1] ) ) %
+                ',';
+
+        begin =
+            enc::char_( '[' )[qi::_val = ']'] | enc::char_( '{' )[qi::_val = '}'] | enc::char_( '(' )[qi::_val = ')'];
+        end    = enc::char_( qi::_r1 );
+        result = ( begin[qi::_a = qi::_1] >> inner[qi::_val = qi::_1] >> end( qi::_a ) ) | inner[qi::_val = qi::_1];
+      }
+
+      StringGrammar<Iterator, Skipper>                                         name, title;
+      EdgeGrammar<Iterator, Skipper>                                           edges;
+      VectorGrammar<Iterator, std::vector<std::pair<double, double>>, Skipper> bins;
+      qi::rule<Iterator, H3(), qi::locals<char>, Skipper>                      result;
+      qi::rule<Iterator, H3(), Skipper>                                        inner;
+      qi::rule<Iterator, char()>                                               begin;
+      qi::rule<Iterator, void( char )>                                         end;
+
+      // ======================================================================
+    };
+    REGISTER_GRAMMAR( H3, H3Grammar );
+    // ========================================================================
   } // namespace Parsers
   // ==========================================================================
 } //                                                     end of namespace Gaudi
@@ -183,6 +219,14 @@ namespace {
     return h2.ok() ? StatusCode::SUCCESS : StatusCode::FAILURE;
   }
   // ==========================================================================
+  /// parse the histogram
+  StatusCode _parse( H3& h3, const std::string& input ) {
+    // check the parsing
+    StatusCode sc = Gaudi::Parsers::parse_( h3, input );
+    if ( sc.isFailure() ) { return sc; } // RETURN
+    return h3.ok() ? StatusCode::SUCCESS : StatusCode::FAILURE;
+  }
+  // ==========================================================================
   template <class HISTO1>
   std::unique_ptr<HISTO1> _parse_1D( const std::string& input, std::string& name ) {
     //
@@ -283,6 +327,59 @@ namespace {
     return histo;
   }
   // ==========================================================================
+  template <class HISTO3>
+  std::unique_ptr<HISTO3> _parse_3D( const std::string& input, std::string& name ) {
+    //
+    typedef std::unique_ptr<HISTO3> H3P;
+    // 1) parse the custom format
+    //
+    H3         h3;
+    StatusCode sc = _parse( h3, input );
+    if ( sc.isFailure() || !h3.ok() ) { return H3P(); } // RETURN
+    //
+    // 2) create the histogram
+    //
+    H3P histo( h3.m_xedges.edges.empty() || h3.m_yedges.edges.empty() || h3.m_zedges.edges.empty() ? // FIXED binning?
+                   new HISTO3( "",                 // h3.m_name.c_str   ()         ,           // NAME
+                               h3.m_title.c_str(), // TITLE
+                               h3.m_xedges.nbins,  // #bins
+                               h3.m_xedges.low,    // low edge
+                               h3.m_xedges.high,   // high edge
+                               h3.m_yedges.nbins,  // #bins
+                               h3.m_yedges.low,    // low edge
+                               h3.m_yedges.high,   // high edge
+                               h3.m_zedges.nbins,  // #bins
+                               h3.m_zedges.low,    // low edge
+                               h3.m_zedges.high )
+                                                                                                   : // high edge
+                   new HISTO3( "",                         // h3.m_name.c_str   ()         ,           // NAME
+                               h3.m_title.c_str(),         // TITLE
+                               h3.m_xedges.nBins(),        // #bins
+                               &h3.m_xedges.edges.front(), // vector of edges
+                               h3.m_yedges.nBins(),        // #bins
+                               &h3.m_yedges.edges.front(), h3.m_zedges.nBins(),
+                               &h3.m_zedges.edges.front() ) ); // vector of edges
+
+    int       ibin  = 0;
+    const int xBins = h3.m_xedges.nBins();
+    const int yBins = h3.m_yedges.nBins();
+    const int zBins = h3.m_yedges.nBins();
+
+    for ( int kBin = 0; kBin <= zBins + 1; ++kBin ) {
+      for ( int jBin = yBins + 1; jBin >= 0; --jBin ) {
+        for ( int iBin = 0; iBin <= xBins + 1; ++iBin ) {
+          histo->SetBinContent( iBin, jBin, kBin, h3.m_bins[ibin].first );
+          histo->SetBinError( iBin, jBin, kBin, h3.m_bins[ibin].second );
+          ++ibin;
+        }
+      }
+    }
+    //
+    name = h3.m_name;
+    //
+    return histo;
+  }
+  // ==========================================================================
 } //                                                 end of anonymous namespace
 // ============================================================================
 /*  parse ROOT histogram from text representation
@@ -382,6 +479,51 @@ StatusCode Gaudi::Parsers::parse( TH2F& result, const std::string& input ) {
  *  @return status code
  */
 // ============================================================================
+StatusCode Gaudi::Parsers::parse( TH3D& result, const std::string& input ) {
+  // 1) check the parsing
+  std::string name;
+  auto        h3 = _parse_3D<TH3D>( input, name );
+  if ( h3 ) {
+    result.Reset();
+    h3->Copy( result ); // ASSIGN
+    result.SetName( name.c_str() );
+    return StatusCode::SUCCESS; // RETURN
+  }
+  //
+  // XML-like text?
+  return ( std::string::npos != input.find( '<' ) ) ? Gaudi::Utils::Histos::fromXml( result, input )
+                                                    : StatusCode::FAILURE;
+}
+// ============================================================================
+/*  parse ROOT histogram from text representation
+ *  @param result (OUTPUT) the histogram
+ *  @param input  (INPUT)  the input to be parsed
+ *  @return status code
+ */
+// ============================================================================
+StatusCode Gaudi::Parsers::parse( TH3F& result, const std::string& input ) {
+  // 1) check the parsing
+  std::string name;
+  auto        h3 = _parse_3D<TH3F>( input, name );
+  if ( h3 ) {
+    result.Reset();
+    h3->Copy( result ); // ASSIGN
+    result.SetName( name.c_str() );
+    return StatusCode::SUCCESS; // RETURN
+  }
+  //
+  // XML-like text?
+  if ( std::string::npos != input.find( '<' ) ) { return Gaudi::Utils::Histos::fromXml( result, input ); }
+  //
+  return StatusCode::FAILURE;
+}
+// ============================================================================
+/*  parse ROOT histogram from text representation
+ *  @param result (OUTPUT) the histogram
+ *  @param input  (INPUT)  the input to be parsed
+ *  @return status code
+ */
+// ============================================================================
 StatusCode Gaudi::Parsers::parse( TH1D*& result, const std::string& input ) {
   if ( result ) { return parse( *result, input ); } // RETURN
 
@@ -422,6 +564,29 @@ StatusCode Gaudi::Parsers::parse( TH2D*& result, const std::string& input ) {
                                                     : StatusCode::FAILURE;
 }
 // ============================================================================
+/*  parse ROOT histogram from text representation
+ *  @param result (OUTPUT) the histogram
+ *  @param input  (INPUT)  the input to be parsed
+ *  @return status code
+ */
+// ============================================================================
+StatusCode Gaudi::Parsers::parse( TH3D*& result, const std::string& input ) {
+  if ( result ) { return parse( *result, input ); } // RETURN
+
+  // 1) check the parsing
+  std::string name;
+  auto        h3 = _parse_3D<TH3D>( input, name );
+  if ( h3 ) {
+    result = h3.release();
+    result->SetName( name.c_str() );
+    return StatusCode::SUCCESS; // RETURN
+  }
+  //
+  // XML-like text?
+  return ( std::string::npos != input.find( '<' ) ) ? Gaudi::Utils::Histos::fromXml( result, input )
+                                                    : StatusCode::FAILURE;
+}
+// ============================================================================
 /*  parse AIDA histogram from text representation
  *  @param result (OUTPUT) the histogram
  *  @param input  (INPUT)  the input to be parsed
@@ -448,5 +613,18 @@ StatusCode Gaudi::Parsers::parse( AIDA::IHistogram2D& result, const std::string&
   return root ? parse( *root, input ) : StatusCode::FAILURE;
 }
 // ============================================================================
+/*  parse AIDA histogram from text representation
+ *  @param result (OUTPUT) the histogram
+ *  @param input  (INPUT)  the input to be parsed
+ *  @return status code
+ */
+// ============================================================================
+StatusCode Gaudi::Parsers::parse( AIDA::IHistogram3D& result, const std::string& input ) {
+  // 1) convert to ROOT
+  auto root = Gaudi::Utils::Aida2ROOT::aida2root( &result );
+  // 2) read ROOT histogram
+  return root ? parse( *root, input ) : StatusCode::FAILURE;
+}
+// ============================================================================
 // The END
 // ============================================================================