Index: src/lemon/maps.h
===================================================================
--- src/lemon/maps.h	(revision 987)
+++ src/lemon/maps.h	(revision 1041)
@@ -18,5 +18,8 @@
 #define LEMON_MAPS_H
 
+#include<math.h>
+
 ///\file
+///\ingroup maps
 ///\brief Miscellaneous property maps
 ///
@@ -27,4 +30,7 @@
 
 namespace lemon {
+
+  /// \addtogroup maps
+  /// @{
 
   /// Base class of maps.
@@ -169,5 +175,276 @@
     };
   };
+
+
+  ///Sum of two maps
+
+  ///This \ref concept::ReadMap "read only map" returns the sum of the two
+  ///given maps. Its \c Key and \c Value will be inherited from \c M1.
+  ///The \c Key and \c Value of M2 must be convertible to those of \c M1.
+
+  template<class M1,class M2> 
+  class AddMap
+  {
+    const M1 &m1;
+    const M2 &m2;
+  public:
+    typedef typename M1::Key Key;
+    typedef typename M1::Value Value;
+
+    ///Constructor
+
+    ///\e
+    ///
+    AddMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
+    Value operator[](Key k) {return m1[k]+m2[k];}
+  };
+  
+  ///Returns an \ref AddMap class
+
+  ///This function just returns an \ref AddMap class.
+  ///\todo How to call these type of functions?
+  ///
+  ///\relates AddMap
+  ///\todo Wrong scope in Doxygen when \c \\relates is used
+  template<class M1,class M2> 
+  inline AddMap<M1,M2> addMap(const M1 &m1,const M2 &m2) 
+  {
+    return AddMap<M1,M2>(m1,m2);
+  }
+
+  ///Difference of two maps
+
+  ///This \ref concept::ReadMap "read only map" returns the difference
+  ///of the values returned by the two
+  ///given maps. Its \c Key and \c Value will be inherited from \c M1.
+  ///The \c Key and \c Value of \c M2 must be convertible to those of \c M1.
+
+  template<class M1,class M2> 
+  class SubMap
+  {
+    const M1 &m1;
+    const M2 &m2;
+  public:
+    typedef typename M1::Key Key;
+    typedef typename M1::Value Value;
+
+    ///Constructor
+
+    ///\e
+    ///
+    SubMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
+    Value operator[](Key k) {return m1[k]-m2[k];}
+  };
+  
+  ///Returns a \ref SubMap class
+
+  ///This function just returns a \ref SubMap class.
+  ///
+  ///\relates SubMap
+  template<class M1,class M2> 
+  inline SubMap<M1,M2> subMap(const M1 &m1,const M2 &m2) 
+  {
+    return SubMap<M1,M2>(m1,m2);
+  }
+
+  ///Product of two maps
+
+  ///This \ref concept::ReadMap "read only map" returns the product of the
+  ///values returned by the two
+  ///given
+  ///maps. Its \c Key and \c Value will be inherited from \c M1.
+  ///The \c Key and \c Value of \c M2 must be convertible to those of \c M1.
+
+  template<class M1,class M2> 
+  class MulMap
+  {
+    const M1 &m1;
+    const M2 &m2;
+  public:
+    typedef typename M1::Key Key;
+    typedef typename M1::Value Value;
+
+    ///Constructor
+
+    ///\e
+    ///
+    MulMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
+    Value operator[](Key k) {return m1[k]*m2[k];}
+  };
+  
+  ///Returns a \ref MulMap class
+
+  ///This function just returns a \ref MulMap class.
+  ///\relates MulMap
+  template<class M1,class M2> 
+  inline MulMap<M1,M2> mulMap(const M1 &m1,const M2 &m2) 
+  {
+    return MulMap<M1,M2>(m1,m2);
+  }
+ 
+  ///Quotient of two maps
+
+  ///This \ref concept::ReadMap "read only map" returns the quotient of the
+  ///values returned by the two
+  ///given maps. Its \c Key and \c Value will be inherited from \c M1.
+  ///The \c Key and \c Value of \c M2 must be convertible to those of \c M1.
+
+  template<class M1,class M2> 
+  class DivMap
+  {
+    const M1 &m1;
+    const M2 &m2;
+  public:
+    typedef typename M1::Key Key;
+    typedef typename M1::Value Value;
+
+    ///Constructor
+
+    ///\e
+    ///
+    DivMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
+    Value operator[](Key k) {return m1[k]/m2[k];}
+  };
+  
+  ///Returns a \ref DivMap class
+
+  ///This function just returns a \ref DivMap class.
+  ///\relates DivMap
+  template<class M1,class M2> 
+  inline DivMap<M1,M2> divMap(const M1 &m1,const M2 &m2) 
+  {
+    return DivMap<M1,M2>(m1,m2);
+  }
+  
+  ///Composition of two maps
+
+  ///This \ref concept::ReadMap "read only map" returns the composition of
+  ///two
+  ///given maps. That is to say, if \c m1 is of type \c M1 and \c m2 is
+  ///of \c M2,
+  ///then for
+  ///\code
+  ///  ComposeMap<M1,M2> cm(m1,m2);
+  ///\endcode
+  ///<tt>cm[x]</tt> will be equal to <tt>m1[m2[x]]</tt>
+  ///
+  ///Its \c Key is inherited from \c M2 and its \c Value is from
+  ///\c M1.
+  ///The \c M2::Value must be convertible to \c M1::Key.
+  ///\todo Check the requirements.
+
+  template<class M1,class M2> 
+  class ComposeMap
+  {
+    const M1 &m1;
+    const M2 &m2;
+  public:
+    typedef typename M2::Key Key;
+    typedef typename M1::Value Value;
+
+    ///Constructor
+
+    ///\e
+    ///
+    ComposeMap(const M1 &_m1,const M2 &_m2) : m1(_m1), m2(_m2) {};
+    Value operator[](Key k) {return m1[m2[k]];}
+  };
+  
+  ///Returns a \ref ComposeMap class
+
+  ///This function just returns a \ref ComposeMap class.
+  ///\relates ComposeMap
+  template<class M1,class M2> 
+  inline ComposeMap<M1,M2> composeMap(const M1 &m1,const M2 &m2) 
+  {
+    return ComposeMap<M1,M2>(m1,m2);
+  }
+
+  ///Negative value of a map
+
+  ///This \ref concept::ReadMap "read only map" returns the negative
+  ///value of the
+  ///value returned by the
+  ///given map. Its \c Key and \c Value will be inherited from \c M.
+  ///The unary \c - operator must be defined for \c Value, of course.
+
+  template<class M> 
+  class NegMap
+  {
+    const M &m;
+  public:
+    typedef typename M::Key Key;
+    typedef typename M::Value Value;
+
+    ///Constructor
+
+    ///\e
+    ///
+    NegMap(const M &_m) : m(_m) {};
+    Value operator[](Key k) {return -m[k];}
+  };
+  
+  ///Returns a \ref NegMap class
+
+  ///This function just returns a \ref NegMap class.
+  ///\relates NegMap
+  template<class M> 
+  inline NegMap<M> negMap(const M &m) 
+  {
+    return NegMap<M>(m);
+  }
+
+
+  //\todo We need a unified way to handle the situation below!
+  struct _UnConvertible {};
+  template<class A> inline A t_abs(A a) {return _UnConvertible();}
+
+  template<> inline int t_abs<>(int n) {return abs(n);}
+  template<> inline long int t_abs<>(long int n) {return labs(n);}
+  //\bug llabs() is overloaded
+  template<> inline long long int t_abs<>(long long int n) {return ::llabs(n);}
+
+  template<> inline float t_abs<>(float n) {return fabsf(n);}
+  template<> inline double t_abs<>(double n) {return fabs(n);}
+  template<> inline long double t_abs<>(long double n) {return fabsl(n);}
+
+  ///Absolute value of a map
+
+  ///This \ref concept::ReadMap "read only map" returns the absolute value
+  ///of the
+  ///value returned by the
+  ///given map. Its \c Key and \c Value will be inherited from \c M.
+  ///The function <tt>Value abs(Value)<tt> must be defined, of course.
+
+  template<class M> 
+  class AbsMap
+  {
+    const M &m;
+  public:
+    typedef typename M::Key Key;
+    typedef typename M::Value Value;
+
+    ///Constructor
+
+    ///\e
+    ///
+    AbsMap(const M &_m) : m(_m) {};
+    Value operator[](Key k) {return t_abs(m[k]);}
+  };
+  
+  ///Returns a \ref AbsMap class
+
+  ///This function just returns a \ref AbsMap class.
+  ///\relates AbsMap
+  template<class M> 
+  inline AbsMap<M> absMap(const M &m) 
+  {
+    return AbsMap<M>(m);
+  }
+
+  /// @}
   
 }
+
+
 #endif // LEMON_MAPS_H
Index: src/test/Makefile.am
===================================================================
--- src/test/Makefile.am	(revision 970)
+++ src/test/Makefile.am	(revision 1041)
@@ -18,4 +18,5 @@
 	graph_utils_test \
 	kruskal_test \
+	maps_test \
 	min_cost_flow_test \
 	suurballe_test \
@@ -39,4 +40,5 @@
 graph_wrapper_test_SOURCES = graph_wrapper_test.cc
 kruskal_test_SOURCES = kruskal_test.cc
+maps_test_SOURCES = maps_test.cc
 min_cost_flow_test_SOURCES = min_cost_flow_test.cc
 suurballe_test_SOURCES = suurballe_test.cc
Index: src/test/map_test.h
===================================================================
--- src/test/map_test.h	(revision 946)
+++ src/test/map_test.h	(revision 1041)
@@ -25,5 +25,5 @@
 //! \ingroup misc
 //! \file
-//! \brief Some utility to test map classes.
+//! \brief Some utilities to test map classes.
 
 namespace lemon {
Index: src/test/maps_test.cc
===================================================================
--- src/test/maps_test.cc	(revision 1041)
+++ src/test/maps_test.cc	(revision 1041)
@@ -0,0 +1,35 @@
+#include <lemon/concept_check.h>
+#include <lemon/concept/maps.h>
+#include <lemon/maps.h>
+
+#include "test_tools.h"
+
+using namespace lemon;
+using namespace lemon::concept;
+
+struct A {};
+struct B {};
+
+typedef ReadMap<A,double> DoubleMap;
+
+int main()
+{ // checking graph components
+  
+  checkConcept<ReadMap<A,B>, ReadMap<A,B> >();
+  checkConcept<WriteMap<A,B>, WriteMap<A,B> >();
+  checkConcept<ReadWriteMap<A,B>, ReadWriteMap<A,B> >();
+  checkConcept<ReferenceMap<A,B,B&,const B&>, ReferenceMap<A,B,B&,const B&> >();
+
+  checkConcept<ReadMap<A,double>, AddMap<DoubleMap,DoubleMap> >();
+  checkConcept<ReadMap<A,double>, SubMap<DoubleMap,DoubleMap> >();
+  checkConcept<ReadMap<A,double>, MulMap<DoubleMap,DoubleMap> >();
+  checkConcept<ReadMap<A,double>, DivMap<DoubleMap,DoubleMap> >();
+  checkConcept<ReadMap<A,double>, NegMap<DoubleMap> >();
+  checkConcept<ReadMap<A,double>, AbsMap<DoubleMap> >();
+  
+  checkConcept<ReadMap<B,double>, ComposeMap<DoubleMap,ReadMap<B,A> > >();
+
+  std::cout << __FILE__ ": All tests passed.\n";
+  
+  return 0;
+}
