diff --git a/include/hpp/statistics/bin.hh b/include/hpp/statistics/bin.hh
index 3f76157497ddd2fe584042e7ac80e6d46ef34ba9..aa40be13fbc7c122a0f4cd7f3cfe4882d791c480 100644
--- a/include/hpp/statistics/bin.hh
+++ b/include/hpp/statistics/bin.hh
@@ -19,31 +19,169 @@
 # define HPP_STATISTICS_HH
 
 # include <ostream>
+# include <set>
 
 # include <hpp/statistics/config.hh>
 
 namespace hpp {
   namespace statistics {
     class Bin;
-    std::ostream& operator<< (std::ostream& os, const Bin& b);
+    template < typename T >
+      class Statistics;
+  } // namespace statistics
+} // namespace hpp
+
+std::ostream& operator<< (std::ostream&, const hpp::statistics::Bin&);
+template < typename T >
+std::ostream& operator<< (std::ostream&, const hpp::statistics::Statistics <T>&);
 
+namespace hpp {
+  namespace statistics {
     /// Abstract class representing a bin.
     ///
     /// Bins are use for statistics. They keep the number of
     /// of apparition of a given value.
+    /// Inherited class should also implement comparison and equality
+    /// operators.
     class HPP_STATISTICS_DLLAPI Bin
     {
       public:
         /// Return the number of element in the bin.
-        virtual size_t freq () const = 0;
+        size_t freq () const
+        {
+          return freq_;
+        }
+
+        /// Add an occurence
+        /// \return The frequency after increment;
+        size_t operator ++()
+        {
+          return ++freq_;
+        }
+
+        /// Add an occurence
+        /// \return The frequency before increment;
+        size_t operator ++(int)
+        {
+          return freq_++;
+        }
+
+        /// Print the bin.
+        std::ostream& print (std::ostream& os) const;
 
-      private:
         /// Print the inner value of the bin.
         virtual std::ostream& printValue (std::ostream& os) const = 0;
 
-        friend std::ostream& operator<< (std::ostream&, const Bin&);
+      protected:
+        /// Constructor
+        Bin () : freq_ (0) {}
+
+      private:
+        /// The number of occurence.
+        size_t freq_;
+    };
+    
+    /// Template class to do statistics.
+    /// You should derivate class Bin and construct a class
+    /// Statistics < YourBin >.
+    template < typename T >
+    class HPP_STATISTICS_DLLAPI Statistics
+    {
+      public:
+        typedef typename std::set <T>::iterator iterator;
+        typedef typename std::set <T>::const_iterator const_iterator;
+
+        /// Return the number of occurence of a Bin
+        virtual size_t freq (const T& bin) const;
+
+        /// Return the total number of occurence.
+        unsigned int numberOfOccurence () const
+        {
+          return counts_;
+        }
+        
+        /// Put the results in a stream.
+        virtual std::ostream& print (std::ostream& os) const;
+
+      protected:
+        /// Constructor
+        Statistics();
+
+        /// Increment a Bin
+        /// \note bin is inserted in the set of bins if it was not
+        /// already in the set.
+        virtual void increment (T& bin);
+
+        /// Return an iterator pointing at the beginning of
+        /// the set of bins.
+        const_iterator begin() const
+        {
+          return bins_.begin();
+        }
+
+        /// Return an iterator pointing at the end of
+        /// the set of bins.
+        const_iterator end() const
+        {
+          return bins_.end();
+        }
+
+      private:
+        std::set < T > bins_;
+
+        unsigned int counts_;
     };
   } // namespace statistics
 } // namespace hpp
 
+/// Implementation
+
+namespace hpp {
+  namespace statistics {
+    template < typename T >
+    void Statistics <T>::increment (T& b)
+    {
+      b++;
+      std::pair< iterator, bool > it = bins_.insert (b);
+      if (!it.second) {
+        // The bin exists already. We must copy and reinsert it.
+        b = *(it.first);
+        b++;
+        bins_.erase (it.first);
+        bins_.insert (b);
+      }
+      counts_++;
+    }
+
+    template < typename T >
+    size_t Statistics <T>::freq (const T& b) const
+    {
+      typename std::set< T >::iterator it = bins_.find (b);
+      if (it == bins_.end ()) {
+        return 0;
+      }
+      return it->freq ();
+    }
+
+    template < typename T >
+      Statistics <T>::Statistics () :bins_ (), counts_(0)
+    {}
+
+    template < typename T >
+    std::ostream& Statistics<T>::print (std::ostream& os) const
+    {
+      const_iterator it;
+      for (it = begin(); it != end(); it++)
+        os << (*it) << std::endl;
+      return os;
+    }
+  } // namespace statistics
+} // namespace hpp
+
+  template < typename T >
+std::ostream& operator<< (std::ostream& os, const hpp::statistics::Statistics <T>& ss)
+{
+  return ss.print (os);
+}
+
 #endif // HPP_STATISTICS_HH
diff --git a/include/hpp/statistics/success-bin.hh b/include/hpp/statistics/success-bin.hh
index 376eeea89e2c7f74e334deca60094f055899a88e..57fa4f8aa81854468769d449a8575eb28f0a61dc 100644
--- a/include/hpp/statistics/success-bin.hh
+++ b/include/hpp/statistics/success-bin.hh
@@ -31,9 +31,6 @@
 
 namespace hpp {
   namespace statistics {
-    class SuccessStatistics;
-    std::ostream& operator<< (std::ostream&, const SuccessStatistics&);
-
     /// This class count the number of success and failure.
     class HPP_STATISTICS_DLLAPI SuccessBin : public Bin
     {
@@ -56,17 +53,6 @@ namespace hpp {
         /// If this bin represents 'failure', returns the reason as a string.
         const std::string& reasonString () const;
 
-        /// Add an occurence
-        /// \return The frequency after increment;
-        size_t operator ++();
-
-        /// Add an occurence
-        /// \return The frequency before increment;
-        size_t operator ++(int);
-
-        /// \return The number of element in the bin.
-        size_t freq () const;
-
         /// Check for equality.
         /// \return True if both are 'success' or if they are both 'failure'
         /// with the same Reason.
@@ -106,9 +92,12 @@ namespace hpp {
         std::ostream& printValue (std::ostream& os) const;
     };
 
-    class HPP_STATISTICS_DLLAPI SuccessStatistics
+    class HPP_STATISTICS_DLLAPI SuccessStatistics :
+      public Statistics < SuccessBin >
     {
       public:
+        typedef Statistics <SuccessBin> Parent;
+
         /// Constructor
         SuccessStatistics ();
 
@@ -129,21 +118,13 @@ namespace hpp {
 
         /// Count the number of a particular failure.
         unsigned int nbFailure (const SuccessBin::Reason& r) const;
-
-      private:
-        std::set <SuccessBin> bins_;
-
-        unsigned int counts_;
-
-        /// Increment the bin.
-        void increment (SuccessBin& b);
-
-        /// Put the results in a stream.
-        std::ostream& print (std::ostream& os) const;
-
-        friend std::ostream& operator<< (std::ostream&, const SuccessStatistics&);
     };
   } // namespace statistics
 } // namespace hpp
 
+std::ostream& operator<< (std::ostream& os, const hpp::statistics::SuccessStatistics& ss)
+{
+  return ss.print (os);
+}
+
 #endif // HPP_STATISTICS_SUCCESSBIN_HH
diff --git a/src/bin.cc b/src/bin.cc
index e25a377c3c2821777a5897e1300d9d03ed676c2c..b983780bcb82e4b4ac5ede1400e64216676c8a95 100644
--- a/src/bin.cc
+++ b/src/bin.cc
@@ -18,9 +18,13 @@
 
 namespace hpp {
   namespace statistics {
-    std::ostream& operator<< (std::ostream& os, const Bin& b)
+    std::ostream& Bin::print (std::ostream& os) const
     {
-      return b.printValue (os) << " seen " << b.freq() << " time(s)." << std::endl;
+      return printValue (os) << " seen " << freq() << " time(s).";
     }
   } // namespace statistics
 } // namespace hpp
+std::ostream& operator<< (std::ostream& os, const hpp::statistics::Bin& b)
+{
+  return b.print (os);
+}
diff --git a/src/success-bin.cc b/src/success-bin.cc
index b812e24e3898cecdf5672022c3dd1e33dfe793d5..1e29da983f05e21ba560d598498a6ba232c05010 100644
--- a/src/success-bin.cc
+++ b/src/success-bin.cc
@@ -30,7 +30,7 @@ namespace hpp {
     }
 
     SuccessBin::SuccessBin (const bool success, const Reason& r) :
-      success_ (success), freq_ (0), reason_(r)
+      Bin(), success_ (success), reason_(r)
     {
       if (success_)
         reason_ = REASON_SUCCESS;
@@ -41,21 +41,6 @@ namespace hpp {
       return success_;
     }
 
-    size_t SuccessBin::freq () const
-    {
-      return freq_;
-    }
-
-    size_t SuccessBin::operator ++()
-    {
-      return ++freq_;
-    }
-
-    size_t SuccessBin::operator ++(int)
-    {
-      return freq_++;
-    }
-
     std::ostream& SuccessBin::printValue (std::ostream& os) const
     {
       os << "Event ";
@@ -79,7 +64,7 @@ namespace hpp {
       return reason_.id < other.reason ().id;
     }
 
-    SuccessStatistics::SuccessStatistics () : bins_(), counts_(0)
+    SuccessStatistics::SuccessStatistics ()
     {}
 
     void SuccessStatistics::addFailure (const SuccessBin::Reason& r)
@@ -94,52 +79,19 @@ namespace hpp {
       increment (b);
     }
 
-    void SuccessStatistics::increment (SuccessBin& b)
-    {
-      b++;
-      std::pair<std::set<SuccessBin>::iterator, bool> it = bins_.insert (b);
-      if (!it.second) {
-        // The bin exists already. We must copy and reinsert it.
-        SuccessBin bin = *(it.first);
-        bin ++;
-        bins_.erase (b);
-        bins_.insert (bin);
-      }
-      counts_++;
-    }
-
     unsigned int SuccessStatistics::nbSuccess () const
     {
-      std::set<SuccessBin>::iterator it = bins_.find (SuccessBin(true));
-      if (it != bins_.end())
-        return it->freq();
-      return 0;
+      return freq (SuccessBin(true));
     }
 
     unsigned int SuccessStatistics::nbFailure () const
     {
-      return counts_ - nbSuccess();
+      return numberOfOccurence() - nbSuccess();
     }
 
     unsigned int SuccessStatistics::nbFailure (const SuccessBin::Reason& r) const
     {
-      std::set<SuccessBin>::iterator it = bins_.find (SuccessBin(false, r));
-      if (it != bins_.end())
-        return it->freq();
-      return 0;
-    }
-
-    std::ostream& SuccessStatistics::print (std::ostream& os) const
-    {
-      std::set <SuccessBin>::const_iterator it;
-      for (it = bins_.begin(); it != bins_.end(); it++)
-        os << (*it);
-      return os;
-    }
-
-    std::ostream& operator<< (std::ostream& os, const SuccessStatistics& ss)
-    {
-      return ss.print (os);
+      return freq (SuccessBin (false, r));
     }
   } // namespace statistics
 } // namespace hpp
diff --git a/tests/test-successstatistics.cc b/tests/test-successstatistics.cc
index bd3eeacf19580091bbfd70e0247e002b706cb8fe..f9dfe2ff1d43486fbf21235dde09d533c6e9d223 100644
--- a/tests/test-successstatistics.cc
+++ b/tests/test-successstatistics.cc
@@ -49,7 +49,7 @@ int main ()
   if (   ss.nbSuccess () != counter[0]
       || ss.nbFailure (SuccessBin::REASON_UNKNOWN) != counter[1]
       || ss.nbFailure (REASON_TEST) != counter[2]) {
-    std::cout << ss;
+    std::cout << ss << std::endl;
     std::cout << "Real frequencies are: ( " << counter[0] << ", " << counter[1]
       << ", " << counter [2] << ")" << std::endl;
     return EXIT_FAILURE;