Index: oln/funobj/infsup.hh
===================================================================
--- oln/funobj/infsup.hh	(revision 270)
+++ oln/funobj/infsup.hh	(working copy)
@@ -29,7 +29,7 @@
 # define OLENA_CORE_FUNOBJ_INFSUP_HH
 
 # include <oln/funobj/arith.hh>
-# include <oln/funobj/logic.hh>
+//# include <oln/funobj/logic.hh>
 
 
 namespace oln
Index: oln/funobj/logic.hh
===================================================================
--- oln/funobj/logic.hh	(revision 270)
+++ oln/funobj/logic.hh	(working copy)
@@ -1,97 +0,0 @@
-// Copyright (C) 2005  EPITA Research and Development Laboratory
-//
-// This file is part of the Olena Library.  This library is free
-// software; you can redistribute it and/or modify it under the terms
-// of the GNU General Public License version 2 as published by the
-// Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING.  If not, write to
-// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
-// MA 02111-1307, USA.
-//
-// As a special exception, you may use this file as part of a free
-// software library without restriction.  Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to
-// produce an executable, this file does not by itself cause the
-// resulting executable to be covered by the GNU General Public
-// License.  This exception does not however invalidate any other
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-
-#ifndef OLENA_CORE_FUNOBJ_LOGIC_HH
-# define OLENA_CORE_FUNOBJ_LOGIC_HH
-
-# include <oln/funobj/abstract/binary.hh>
-
-
-
-
-# define oln_decl_funobj_logic(OperatorName, OperatorBody)			\
-										\
-  namespace f_ {								\
-    template <typename L, typename R> struct OperatorName##_;			\
-  }										\
-										\
-  template <typename L, typename R>						\
-  struct set_super_type < f_::OperatorName##_<L,R> >				\
-  {										\
-    typedef f_::abstract::binary< f_::OperatorName##_<L,R> > ret;		\
-  };										\
-										\
-  template <typename L, typename R>						\
-  struct set_props < category::fun2, f_::OperatorName##_<L,R> >			\
-  {										\
-    typedef bool res_type;							\
-    typedef L left_type;							\
-    typedef R right_type;							\
-  };										\
-										\
-  namespace f_									\
-  {										\
-										\
-    template <typename L, typename R>						\
-    struct OperatorName##_ : public oln_super2_of_(f_::OperatorName##_<L,R>)	\
-    {										\
-      typedef OperatorName##_<L,R> self_type;					\
-										\
-      const oln_fun2_type_of(self_type, res)					\
-	impl_binop(const L& lhs, const R& rhs) const				\
-	{									\
-	  return OperatorBody;							\
-	}									\
-    };										\
-										\
-  }										\
-										\
-  typedef f_::binary_meta<f_::OperatorName##_> f_##OperatorName##_type;		\
-  static f_##OperatorName##_type f_##OperatorName;				\
-										\
-struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
-
-
-
-namespace oln
-{
-
-  oln_decl_funobj_logic( and,   lhs && rhs);
-  oln_decl_funobj_logic(nand, !(lhs && rhs));
-  oln_decl_funobj_logic(  or,   lhs || rhs);
-  oln_decl_funobj_logic( nor, !(lhs || rhs));
-  oln_decl_funobj_logic( xor, (lhs && !rhs) || (!lhs && rhs));
-  oln_decl_funobj_logic(xnor, (lhs && rhs) || (!lhs && !rhs));
-
-  // FIXME: what about 'not'?!!!
-
-
-} // end of namespace oln
-
-
-
-#endif // ! OLENA_CORE_FUNOBJ_LOGIC_HH
Index: oln/funobj/cmp.hh
===================================================================
--- oln/funobj/cmp.hh	(revision 270)
+++ oln/funobj/cmp.hh	(working copy)
@@ -1,97 +0,0 @@
-// Copyright (C) 2005  EPITA Research and Development Laboratory
-//
-// This file is part of the Olena Library.  This library is free
-// software; you can redistribute it and/or modify it under the terms
-// of the GNU General Public License version 2 as published by the
-// Free Software Foundation.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; see the file COPYING.  If not, write to
-// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
-// MA 02111-1307, USA.
-//
-// As a special exception, you may use this file as part of a free
-// software library without restriction.  Specifically, if other files
-// instantiate templates or use macros or inline functions from this
-// file, or you compile this file and link it with other files to
-// produce an executable, this file does not by itself cause the
-// resulting executable to be covered by the GNU General Public
-// License.  This exception does not however invalidate any other
-// reasons why the executable file might be covered by the GNU General
-// Public License.
-
-#ifndef OLENA_CORE_FUNOBJ_CMP_HH
-# define OLENA_CORE_FUNOBJ_CMP_HH
-
-# include <oln/funobj/abstract/binary.hh>
-
-
-
-
-# define oln_decl_funobj_cmp(OperatorName, OperatorSymbol)			\
-										\
-  namespace f_ {								\
-    template <typename L, typename R> struct OperatorName##_;			\
-  }										\
-										\
-  template <typename L, typename R>						\
-  struct set_super_type < f_::OperatorName##_<L,R> >				\
-  {										\
-    typedef f_::abstract::binary< f_::OperatorName##_<L,R> > ret;		\
-  };										\
-										\
-  template <typename L, typename R>						\
-  struct set_props < category::fun2, f_::OperatorName##_<L,R> >			\
-  {										\
-    typedef bool res_type;							\
-    typedef L left_type;							\
-    typedef R right_type;							\
-  };										\
-										\
-  namespace f_									\
-  {										\
-										\
-    template <typename L, typename R>						\
-    struct OperatorName##_ : public oln_super2_of_(f_::OperatorName##_<L,R>)	\
-    {										\
-      typedef OperatorName##_<L,R> self_type;					\
-										\
-      const oln_fun2_type_of(self_type, res)					\
-	impl_binop(const L& left, const R& right) const				\
-	{									\
-	  return left OperatorSymbol right;					\
-	}									\
-    };										\
-										\
-  }										\
-										\
-  typedef f_::binary_meta<f_::OperatorName##_> f_##OperatorName##_type;		\
-  static f_##OperatorName##_type f_##OperatorName;				\
-										\
-struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
-
-
-
-namespace oln
-{
-
-  oln_decl_funobj_cmp(eq, ==);
-  oln_decl_funobj_cmp(neq, !=);
-
-  oln_decl_funobj_cmp(less, <);
-  oln_decl_funobj_cmp(leq, <=);
-
-  oln_decl_funobj_cmp(greater, >);
-  oln_decl_funobj_cmp(geq, >=);
-
-
-} // end of namespace oln
-
-
-
-#endif // ! OLENA_CORE_FUNOBJ_CMP_HH
Index: oln/core/typedefs.hh
===================================================================
--- oln/core/typedefs.hh	(revision 270)
+++ oln/core/typedefs.hh	(working copy)
@@ -56,8 +56,14 @@
 namespace oln
 {
 
+
   mlc_equip_namespace_with_properties();
 
+
+  // misc
+
+  mlc_decl_typedef(exact_type);
+
   // general
 
   mlc_decl_typedef(grid_type);
Index: oln/core/abstract/image.hh
===================================================================
--- oln/core/abstract/image.hh	(revision 270)
+++ oln/core/abstract/image.hh	(working copy)
@@ -48,6 +48,8 @@
   // fwd decls
   namespace abstract
   {
+    template <typename P> class point;
+    template <typename I> class image;
     template <typename I> class image_without_nbh;
     template <typename I> class readonly_image;
     template <typename I> class raw_image;
@@ -172,6 +174,14 @@
     }
   };
 
+
+  template <typename I>
+  struct set_props < category::image, abstract::image<I> >
+  {
+    typedef I exact_type;
+  };
+
+
 } // end of namespace oln
 
 
@@ -300,6 +310,11 @@
        ! concrete methods !
        *------------------*/
 
+      template <typename P>
+      void operator()(const oln::abstract::point<P>&) const
+      {
+	// FIXME: provide an explicit err msg, e.g., "(p) should not be used on an ima"
+      }
 
       /*! \brief Give access to the value stored at \a p in the
       ** current image.  Precisely it returns a box that encloses this
Index: oln/core/abstract/piter.hh
===================================================================
--- oln/core/abstract/piter.hh	(revision 270)
+++ oln/core/abstract/piter.hh	(working copy)
@@ -28,7 +28,6 @@
 #ifndef OLENA_CORE_ABSTRACT_PITER_HH
 # define OLENA_CORE_ABSTRACT_PITER_HH
 
-# include <mlc/any.hh>
 # include <mlc/types.hh>
 # include <mlc/contract.hh>
 
Index: oln/core/abstract/grid.hh
===================================================================
--- oln/core/abstract/grid.hh	(revision 270)
+++ oln/core/abstract/grid.hh	(working copy)
@@ -28,7 +28,7 @@
 #ifndef OLENA_CORE_ABSTRACT_GRID_HH
 # define OLENA_CORE_ABSTRACT_GRID_HH
 
-# include <mlc/any.hh>
+# include <oln/core/abstract/any.hh>
 # include <oln/core/typedefs.hh>
 
 
@@ -94,7 +94,7 @@
   namespace abstract {
 
     template <typename E>
-    struct grid : public mlc::any<E>
+    struct grid : public oln::abstract::any<E>
     {
     protected:
       grid()
Index: oln/core/abstract/any.hh
===================================================================
--- oln/core/abstract/any.hh	(revision 0)
+++ oln/core/abstract/any.hh	(revision 0)
@@ -0,0 +1,73 @@
+// Copyright (C) 2001, 2002, 2003, 2004, 2005 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLENA_CORE_ABSTRACT_ANY_HH
+# define OLENA_CORE_ABSTRACT_ANY_HH
+
+# include <mlc/any.hh>
+# include <mlc/bool.hh>
+# include <mlc/is_a.hh>
+
+
+namespace oln {
+
+  namespace abstract {
+
+
+    template <typename E>
+    struct any
+      :
+      public mlc::any<E, mlc::dispatch_policy::simple>
+    {
+    protected:
+      typedef mlc::any<E, mlc::dispatch_policy::simple> super;
+      any(E* exact_ptr) : super(exact_ptr) {}
+      any() {}
+    };
+
+
+    template <typename E>
+    struct any_best_speed
+      :
+      public mlc::any<E, mlc::dispatch_policy::best_speed>
+    {
+    protected:
+      typedef mlc::any<E, mlc::dispatch_policy::best_speed> super;
+      any_best_speed(E* exact_ptr = 0) : super(exact_ptr) {}
+    };
+
+
+  } // end of namespace oln::abstract
+
+} // end of namespace oln
+
+
+# define oln_is_any(Type) mlc::or_< mlc_is_a(Type, oln::abstract::any),			\
+                                    mlc_is_a(Type, oln::abstract::any_best_speed) >
+
+
+#endif // ! OLENA_CORE_ABSTRACT_ANY_HH
Index: oln/core/abstract/point.hh
===================================================================
--- oln/core/abstract/point.hh	(revision 270)
+++ oln/core/abstract/point.hh	(working copy)
@@ -28,11 +28,11 @@
 #ifndef OLENA_CORE_ABSTRACT_POINT_HH
 # define OLENA_CORE_ABSTRACT_POINT_HH
 
-# include <mlc/any.hh>
 # include <mlc/if.hh>
 # include <mlc/cmp.hh>
 # include <mlc/contract.hh>
 
+# include <oln/core/abstract/any.hh>
 # include <oln/core/coord.hh>
 # include <oln/core/typedefs.hh>
 # include <oln/core/abstract/grid.hh>
@@ -110,7 +110,7 @@
     ** Parameter E is the exact type of point.
     */
     template <typename E>
-    struct point : public mlc::any<E>
+    struct point : public oln::abstract::any<E>
     {
 
       typedef E exact_type;
@@ -203,21 +203,6 @@
   } // end of namespace abstract
 
 
-  // FIXME: read FIXME in oln/core/abstract/size.hh ...
-
-//   namespace internal
-//   {
-
-//     template <typename P>
-//     bool operator_eq(const oln::abstract::point<P>& lhs,
-// 		     const oln::abstract::point<P>& rhs)
-//     {
-//       return lhs.operator==(rhs); // FIXME: rename 'point::operator==' into 'point::eq'
-//     }
-
-//   } // end of namespace oln::internal
-
-
 } // end of namespace oln
 
 
Index: oln/core/abstract/data_storage.hh
===================================================================
--- oln/core/abstract/data_storage.hh	(revision 270)
+++ oln/core/abstract/data_storage.hh	(working copy)
@@ -28,8 +28,9 @@
 #ifndef OLENA_CORE_ABSTRACT_DATA_STORAGE_HH
 # define OLENA_CORE_ABSTRACT_DATA_STORAGE_HH
 
-# include <mlc/any.hh>
 # include <mlc/to_string.hh>
+
+# include <oln/core/abstract/any.hh>
 # include <oln/core/typedefs.hh>
 
 
@@ -84,7 +85,7 @@
   namespace abstract {
 
     template <typename E>
-    struct data_storage : public mlc::any<E>
+    struct data_storage : public oln::abstract::any<E>
     {
       // typedefs
 
Index: oln/core/abstract/dpoint.hh
===================================================================
--- oln/core/abstract/dpoint.hh	(revision 270)
+++ oln/core/abstract/dpoint.hh	(working copy)
@@ -28,8 +28,9 @@
 #ifndef OLENA_CORE_ABSTRACT_DPOINT_HH
 # define OLENA_CORE_ABSTRACT_DPOINT_HH
 
-# include <mlc/any.hh>
 # include <mlc/contract.hh>
+
+# include <oln/core/abstract/any.hh>
 # include <oln/core/coord.hh>
 # include <oln/core/typedefs.hh>
 
@@ -53,7 +54,7 @@
     ** Parameter E is the exact type of dpoint.
     */
     template <typename E>
-    struct dpoint : public mlc::any<E>
+    struct dpoint : public oln::abstract::any<E>
     {
       typedef E exact_type;
 
Index: oln/core/abstract/iter.hh
===================================================================
--- oln/core/abstract/iter.hh	(revision 270)
+++ oln/core/abstract/iter.hh	(working copy)
@@ -28,9 +28,9 @@
 #ifndef OLENA_CORE_ABSTRACT_ITER_HH
 # define OLENA_CORE_ABSTRACT_ITER_HH
 
-# include <mlc/any.hh>
 # include <mlc/contract.hh>
 
+# include <oln/core/abstract/any.hh>
 # include <oln/core/typedefs.hh>
 
 
@@ -39,7 +39,7 @@
   namespace abstract {
 
     template <typename E>
-    struct iter : public mlc::any<E>
+    struct iter : public oln::abstract::any<E>
     {
 
       void next()
Index: oln/core/abstract/neighborhood.hh
===================================================================
--- oln/core/abstract/neighborhood.hh	(revision 270)
+++ oln/core/abstract/neighborhood.hh	(working copy)
@@ -28,6 +28,7 @@
 #ifndef OLENA_CORE_NEIGHBORHOOD_HH
 # define OLENA_CORE_NEIGHBORHOOD_HH
 
+# include <oln/core/abstract/any.hh>
 # include <oln/core/typedefs.hh>
 
 
@@ -103,7 +104,7 @@
     **
     */
     template <typename E>
-    struct neighborhood : public mlc::any<E>
+    struct neighborhood : public oln::abstract::any<E>
     {
 
     protected:
Index: oln/core/abstract/window.hh
===================================================================
--- oln/core/abstract/window.hh	(revision 270)
+++ oln/core/abstract/window.hh	(working copy)
@@ -29,6 +29,7 @@
 # define OLENA_CORE_ABSTRACT_WINDOW_HH
 
 # include <mlc/contract.hh>
+# include <oln/core/abstract/any.hh>
 # include <oln/core/typedefs.hh>
 
 
@@ -95,7 +96,7 @@
     */
 
     template<class W>
-    struct window : public mlc::any<W>
+    struct window : public oln::abstract::any<W>
     {
     public:
       typedef oln_wn_type_of(W, dpoint) dpoint_type;
Index: oln/core/abstract/size.hh
===================================================================
--- oln/core/abstract/size.hh	(revision 270)
+++ oln/core/abstract/size.hh	(working copy)
@@ -28,9 +28,10 @@
 #ifndef OLENA_CORE_ABSTRACT_SIZE_HH
 # define OLENA_CORE_ABSTRACT_SIZE_HH
 
-# include <mlc/any.hh>
 # include <mlc/if.hh>
 # include <mlc/cmp.hh>
+
+# include <oln/core/abstract/any.hh>
 # include <oln/core/typedefs.hh>
 
 
@@ -55,7 +56,7 @@
     /// Abstract class for size classes.
 
     template <typename E>
-    struct size : public mlc::any__best_memory<E>
+    struct size : public oln::abstract::any<E> // FIXME: was mlc::any__best_memory<E> (!?)
     {
 
       // FIXME: remove?
@@ -90,20 +91,7 @@
 
   } // end of namespace abstract
 
-//   // FIXME: this op is better than the corresponding collection of
-//   // op for subclasses
-//   namespace internal
-//   {
 
-//     template <typename S>
-//     bool operator_eq(const oln::abstract::size<S>& lhs,
-// 		     const oln::abstract::size<S>& rhs)
-//     {
-//       return lhs.operator==(rhs);
-//     }
-
-//   } // end of namespace oln::internal
-
 } // end of namespace oln
 
 
Index: oln/core/abstract/internal/image_impl.hh
===================================================================
--- oln/core/abstract/internal/image_impl.hh	(revision 270)
+++ oln/core/abstract/internal/image_impl.hh	(working copy)
@@ -28,8 +28,8 @@
 #ifndef OLENA_CORE_ABSTRACT_INTERNAL_IMAGE_IMPL_HH
 # define OLENA_CORE_ABSTRACT_INTERNAL_IMAGE_IMPL_HH
 
-# include <mlc/any.hh>
 # include <mlc/types.hh>
+# include <oln/core/abstract/any.hh>
 
 
 namespace oln {
@@ -50,7 +50,9 @@
       };
 
       template <typename A, typename E>
-      struct get_image_impl_helper <A, mlc::no_type, E> : public virtual mlc::any__best_speed<E>
+      struct get_image_impl_helper <A, mlc::no_type, E>
+	:
+	public virtual oln::abstract::any_best_speed<E>
       {
 	// no impl
       };
@@ -65,7 +67,9 @@
       };
 
       template <typename E>
-      struct image_impl : public mlc::any__best_speed<E>
+      struct image_impl
+	:
+	public virtual oln::abstract::any_best_speed<E>
       {
 	typedef oln_type_of(E, delegated) D;
 	D& delegate() { return this->exact().impl_delegate(); }
Index: oln/core/coord.hh
===================================================================
--- oln/core/coord.hh	(revision 270)
+++ oln/core/coord.hh	(working copy)
@@ -30,16 +30,19 @@
 
 # include <iostream>
 # include <limits.h>
+
 # include <mlc/contract.hh>
 
+# include <oln/core/abstract/any.hh>
 
+
 // FIXME: this file should be in oln/utils/
 
 
 namespace oln {
 
 
-  class coord_t
+  class coord_t : public oln::abstract::any< coord_t >
   {
   public:
 
@@ -153,25 +156,51 @@
 
   };
 
+  /// Operators ==.
 
-  namespace internal
+  bool operator==(const coord_t& lhs, const coord_t& rhs)
   {
+    precondition(lhs.is_defined() and rhs.is_defined());
+    return coord_t::value_type(lhs) == coord_t::value_type(rhs);
+  }
 
-    bool operator_eq(const coord_t& lhs, const coord_t& rhs)
-    {
-      precondition(lhs.is_defined() and rhs.is_defined());
-      return coord_t::value_type(lhs) == coord_t::value_type(rhs);
-    }
+  bool operator==(const coord_t::value_type& lhs,
+		  const coord_t& rhs)
+  {
+    precondition(rhs.is_defined());
+    return lhs == coord_t::value_type(rhs);
+  }
 
-    bool operator_less(const coord_t& lhs, const coord_t& rhs)
-    {
-      precondition(lhs.is_defined() and rhs.is_defined());
-      return coord_t::value_type(lhs) < coord_t::value_type(rhs);
-    }
+  bool operator==(const coord_t& lhs,
+		  const coord_t::value_type& rhs)
+  {
+    precondition(lhs.is_defined());
+    return coord_t::value_type(lhs) == rhs;
+  }
 
-  } // end of namespace oln::internal
+  /// Operators <.
 
+  bool operator<(const coord_t& lhs, const coord_t& rhs)
+  {
+    precondition(lhs.is_defined() and rhs.is_defined());
+    return coord_t::value_type(lhs) < coord_t::value_type(rhs);
+  }
 
+  bool operator<(const coord_t::value_type& lhs,
+		 const coord_t& rhs)
+  {
+    precondition(rhs.is_defined());
+    return lhs < coord_t::value_type(rhs);
+  }
+
+  bool operator<(const coord_t& lhs,
+		 const coord_t::value_type& rhs)
+  {
+    precondition(lhs.is_defined());
+    return coord_t::value_type(lhs) < rhs;
+  }
+
+
 } // end of namespace oln
 
 
Index: oln/core/2d/dpoint2d.hh
===================================================================
--- oln/core/2d/dpoint2d.hh	(revision 270)
+++ oln/core/2d/dpoint2d.hh	(working copy)
@@ -150,22 +150,17 @@
     return tmp;
   }
 
-  namespace internal
+  const dpoint2d operator+(const dpoint2d& lhs, const dpoint2d& rhs)
   {
+    dpoint2d tmp(lhs.row() + rhs.row(), lhs.col() + rhs.col());
+    return tmp;
+  }
 
-    const dpoint2d operator_plus(const dpoint2d& lhs, const dpoint2d& rhs)
-    {
-      dpoint2d tmp(lhs.row() + rhs.row(), lhs.col() + rhs.col());
-      return tmp;
-    }
+  bool operator==(const dpoint2d& lhs, const dpoint2d& rhs)
+  {
+    return lhs.row() == rhs.row() and lhs.col() == rhs.col();
+  }
 
-    bool operator_eq(const dpoint2d& lhs, const dpoint2d& rhs)
-    {
-      return lhs.row() == rhs.row() and lhs.col() == rhs.col();
-    }
-    
-  } // end of namespace oln::internal
-
 } // end of namespace oln
 
 
Index: oln/core/2d/point2d.hh
===================================================================
--- oln/core/2d/point2d.hh	(revision 270)
+++ oln/core/2d/point2d.hh	(working copy)
@@ -158,16 +158,11 @@
     return tmp;
   }
 
-  namespace internal
+  bool operator==(const point2d& lhs, const point2d& rhs)
   {
+    return lhs.operator==(rhs); // FIXME: should be lhs.eq(rhs)
+  }
 
-    bool operator_eq(const point2d& lhs, const point2d& rhs)
-    {
-      return lhs.operator==(rhs); // FIXME: should be lhs.eq(rhs)
-    }
-
-  } // end of namespace oln::internal
-
 } // end of namespace oln
 
 
Index: oln/core/2d/size2d.hh
===================================================================
--- oln/core/2d/size2d.hh	(revision 270)
+++ oln/core/2d/size2d.hh	(working copy)
@@ -106,17 +106,6 @@
   };
 
 
-  namespace internal
-  {
-
-    bool operator_eq(const size2d& lhs, const size2d& rhs)
-    {
-      return lhs.operator==(rhs);
-    }
-
-  } // end of namespace oln::internal
-
-
 } // end of namespace oln
 
 
Index: oln/core/3d/image3d.hh
===================================================================
--- oln/core/3d/image3d.hh	(revision 270)
+++ oln/core/3d/image3d.hh	(working copy)
@@ -28,8 +28,6 @@
 #ifndef OLENA_CORE_3D_IMAGE3D_HH
 # define OLENA_CORE_3D_IMAGE3D_HH
 
-# include <mlc/traits.hh>
-
 # include <oln/core/abstract/image_with_data.hh>
 # include <oln/core/abstract/image_like_.hh>
 # include <oln/core/3d/array3d.hh>
Index: oln/core/pw/binary_op.hh
===================================================================
--- oln/core/pw/binary_op.hh	(revision 270)
+++ oln/core/pw/binary_op.hh	(working copy)
@@ -29,12 +29,15 @@
 # define OLENA_CORE_PW_BINARY_OP_HH
 
 # include <mlc/is_a.hh>
+# include <mlc/afun.hh>
 # include <oln/core/pw/abstract/binary_function.hh>
-# include <oln/funobj/abstract/binary.hh>
+# include <oln/core/pw/value.hh>
+# include <oln/core/pw/image.hh>
 
 
 namespace oln {
 
+  // FIXME: binary_op should be named binary_fun?
 
   // fwd decl
   namespace pw {
@@ -50,9 +53,9 @@
   struct set_props < category::pw, pw::binary_op<F,L,R> >
   {
     typedef
-    typename f_::mbinary_result< F,
-				 oln_pw_type_of(L, value),
-				 oln_pw_type_of(R, value) >::ret
+    typename mlc::mfun_res_traits< F,
+				   oln_pw_type_of(L, value),
+				   oln_pw_type_of(R, value) >::ret
     value_type;
   };
 
@@ -60,6 +63,8 @@
 
   namespace pw {
 
+    // FIXME: binary_op only works with mlc::abstract::meta_binary_function
+    // FIXME: think about another type that works with mlc::abstract::binary_function...
 
     template <typename F, typename L, typename R>
     struct binary_op : public abstract::binary_function< L, R, binary_op<F,L,R> >
@@ -74,10 +79,18 @@
 	super_type(left, right),
 	fun()
       {
-	mlc::or_< mlc_is_a(F, f_::binary_meta),
-	          mlc_is_a(F, f_::binary1_meta) >::ensure();
+	mlc_is_a(F, mlc::abstract::meta_binary_function)::ensure();
       }
 
+      binary_op(const F& fun,
+		const abstract::function<L>& left,
+		const abstract::function<R>& right) :
+	super_type(left, right),
+	fun(fun)
+      {
+	mlc_is_a(F, mlc::abstract::meta_binary_function)::ensure();
+      }
+
       typedef oln_pw_type_of(self_type, point) point_type;
       typedef oln_pw_type_of(self_type, value) value_type;
 
@@ -96,4 +109,64 @@
 
 
 
+namespace mlc
+{
+
+
+  template <typename F, typename A1, typename A2>
+  struct decl_overload <tag::mbfun, 1,
+			F, A1, A2> : public where< mlc::and_<mlc_is_a(A1, oln::pw::abstract::function),
+							     mlc_is_a(A2, oln::pw::abstract::function)> >
+  {
+    typedef oln_pw_type_of(A1, exact) A1_;
+    typedef oln_pw_type_of(A2, exact) A2_;
+
+    typedef oln::pw::binary_op<F,A1_,A2_> ret;
+
+    template <class A1_, class A2_>
+    static ret exec(const F& fun,
+		    const oln::pw::abstract::function<A1_>& arg1,
+		    const oln::pw::abstract::function<A2_>& arg2)
+    {
+      // safety check:
+      mlc_is_a(F, mlc::abstract::meta_binary_function)::ensure();
+      ret tmp(arg1, arg2);
+      return tmp;
+    }
+  };
+
+
+  template <typename F, typename I1, typename I2>
+  struct decl_overload <tag::mbfun, 2,
+			F, I1, I2> : public where< mlc::and_<mlc_is_a(I1, oln::abstract::image),
+							     mlc_is_a(I2, oln::abstract::image)> >
+  {
+    // FIXME: oln_type_of(I, exact) does not work yet...
+    typedef I1 /*oln_type_of(I1, exact)*/ I1_;
+    typedef I2 /*oln_type_of(I2, exact)*/ I2_;
+
+    typedef oln::pw::binary_op<F,
+                               oln::pw::value<I1_>,
+                               oln::pw::value<I2_> > PWF;
+    typedef oln::pw::image<PWF> ret;
+
+    template <class I1_, class I2_>
+    static ret exec(const F& fun,
+		    const oln::abstract::image<I1_>& arg1,
+		    const oln::abstract::image<I2_>& arg2)
+    {
+      // safety check:
+      mlc_is_a(F, mlc::abstract::meta_binary_function)::ensure();
+      
+      oln::pw::value<I1_> left_pw_val(arg1);
+      oln::pw::value<I2_> right_pw_val(arg2);
+      PWF pw_fun(fun, left_pw_val, right_pw_val);
+      ret tmp(pw_fun);
+      return tmp;
+    }
+  };
+
+} // end of namespace mlc
+
+
 #endif // ! OLENA_CORE_PW_BINARY_OP_HH
Index: oln/core/pw/image.hh
===================================================================
--- oln/core/pw/image.hh	(revision 270)
+++ oln/core/pw/image.hh	(working copy)
@@ -41,17 +41,20 @@
 
 namespace oln {
 
+  // FIXME: should be oln::pw::image instead of oln::image_from_pwf?
 
   // fwd decl
-  template <typename F> class image_from_pwf;
+  namespace pw {
+    template <typename F> class image;
+  }
 
   // super
   template <typename F>
-  struct set_super_type < image_from_pwf<F> > { typedef abstract::image_entry< image_from_pwf<F> > ret; };
+  struct set_super_type < pw::image<F> > { typedef abstract::image_entry< pw::image<F> > ret; };
 
   // props
   template <typename F>
-  struct set_props < category::image, image_from_pwf<F> >
+  struct set_props < category::image, pw::image<F> >
   {
     typedef oln_pw_type_of(F, point) point_type;
     typedef oln_pw_type_of(F, value) value_type;
@@ -79,99 +82,104 @@
   };
 
 
-  /// Class image_from_pwf<F>.
-
-  template <typename F>
-  struct image_from_pwf : public abstract::image_entry< image_from_pwf<F> >
+  namespace pw
   {
-    typedef image_from_pwf<F> self_type;
 
-    F fun;
+    /// Class pw::image<F>.
 
-    image_from_pwf(const pw::abstract::function<F>& fun) :
-      fun(fun.exact())
+    template <typename F>
+    struct image : public oln::abstract::image_entry< pw::image<F> >
     {
-      this->exact_ptr = this;
-    }
+      typedef pw::image<F> self_type;
 
-    image_from_pwf(const self_type& rhs) :
-      fun(rhs.fun)
-    {
-      this->exact_ptr = this;
-    }
+      F fun;
 
-    typedef oln_pw_type_of(F, point) point_type;
-    typedef oln_pw_type_of(F, value) value_type;
-    typedef oln_pw_type_of(F, size)  size_type;
+      image(const pw::abstract::function<F>& fun) :
+	fun(fun.exact())
+      {
+	this->exact_ptr = this;
+      }
 
-    const size_type& impl_size() const
-    {
-      return this->fun.size();
-    }
+      image(const self_type& rhs) :
+	fun(rhs.fun)
+      {
+	this->exact_ptr = this;
+      }
 
-    bool impl_hold(const point_type& p) const
-    {
-      return this->fun.hold(p);
-    }
+      typedef oln_pw_type_of(F, point) point_type;
+      typedef oln_pw_type_of(F, value) value_type;
+      typedef oln_pw_type_of(F, size)  size_type;
 
-    bool impl_hold_large(const point_type& p) const
-    {
-      return this->fun.hold_large(p);
-    }
+      const size_type& impl_size() const
+      {
+	return this->fun.size();
+      }
 
-    const value_type impl_get(const point_type& p) const
-    {
-      return this->fun(p);
-    }
+      bool impl_hold(const point_type& p) const
+      {
+	return this->fun.hold(p);
+      }
 
-    // FIXME: remove below
-    unsigned long impl_npoints() const
-    {
-      return 1;
-    }
-    void impl_resize_border(size_t new_border, bool copy_border) const
-    {
-    }
+      bool impl_hold_large(const point_type& p) const
+      {
+	return this->fun.hold_large(p);
+      }
 
-  };
+      const value_type impl_get(const point_type& p) const
+      {
+	return this->fun(p);
+      }
 
+      // FIXME: remove below
+      unsigned long impl_npoints() const
+      {
+	return 1;
+      }
+      void impl_resize_border(size_t new_border, bool copy_border) const
+      {
+      }
 
+    };
 
-  /// Routine image_for_all_p.
+  } // end of namespace pw
 
+
+
+  /// Routine pw_image.
+
   template <typename F>
-  image_from_pwf<F> image_for_all_p(const pw::abstract::function<F>& fun)
+  pw::image<F> pw_image(const pw::abstract::function<F>& fun)
   {
-    image_from_pwf<F> tmp(fun);
+    pw::image<F> tmp(fun);
     return tmp;
   }
 
 
-  /// Specialization of image_for_all_p (so that "image_for_all_p(pw_value(ima)) == ima").
+  /// Specialization of pw_image (so that "pw_image(pw_value(ima)) == ima").
 
   template <typename I>
-  const I& image_for_all_p(const pw::value<I>& pwv)
+  const I& pw_image(const pw::value<I>& pwv)
   {
     return pwv.ima.unbox();
   }
 
 
-  /// Specializations of image_for_all_p to produce compile-time errors.
-  // FIXME: struct OLENA_ERROR__arg_of__image_for_all_p__should_be_a_point_wise_function();
+  /// Specializations of pw_image to produce compile-time errors.
+  // FIXME: struct OLENA_ERROR__arg_of__pw_image__should_be_a_point_wise_function();
 
   template <typename I>
-  void image_for_all_p(const abstract::image<I>&)
+  void pw_image(const abstract::image<I>&)
   {}
 
   template <typename P>
-  void image_for_all_p(const abstract::point<P>&)
+  void pw_image(const abstract::point<P>&)
   {}
 
 
-  /// Specialization of pw_value (so that "pw_value(image_for_all_p(fun)) == fun").
+  /// Specialization of pw_value (so that "pw_value(pw_image(fun)) == fun").
 
   template <typename F>
-  F pw_value(const image_from_pwf<F>& ima)
+  F pw_value(const pw::image<F>& ima)
   {
     F tmp = ima.fun;
     return tmp;
Index: oln/core/pw/macros.hh
===================================================================
--- oln/core/pw/macros.hh	(revision 270)
+++ oln/core/pw/macros.hh	(working copy)
@@ -28,45 +28,6 @@
 #ifndef OLENA_CORE_PW_MACROS_HH
 # define OLENA_CORE_PW_MACROS_HH
 
-# include <oln/utils/overload.hh>
-# include <oln/core/pw/binary_op.hh>
-# include <oln/core/pw/literal.hh>
+// FIXME: empty (obsolete) file...
 
-
-
-# define oln_pw_decl_binary(OperatorName)			\
-								\
-  template <typename F1, typename F2>				\
-  struct set_overload_2 < tag::op_##OperatorName,		\
-			  where<F1, pw::abstract::function>,	\
-			  where<F2, pw::abstract::function> >	\
-  {								\
-    typedef pw::binary_op< f_##OperatorName##_type,		\
-			   F1, F2> ret;				\
-    static ret exec(const F1& lhs, const F2& rhs)		\
-    {								\
-      ret tmp(lhs, rhs);					\
-      return tmp;						\
-    }								\
-  };								\
-								\
-  template <typename F, typename T>				\
-  struct set_overload_2 < tag::op_##OperatorName,		\
-			  where<F, pw::abstract::function>,	\
-			  where<T, whatever> >			\
-  {								\
-    typedef pw::literal<T> rhs_type;				\
-    typedef pw::binary_op< oln::f_##OperatorName##_type,	\
-			   F, rhs_type> ret;			\
-    static ret exec(const F& lhs, const T& rhs)			\
-    {								\
-      rhs_type rhs_(rhs);					\
-      ret tmp(lhs, rhs_);					\
-      return tmp;						\
-    }								\
-  };								\
-								\
-struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
-
-
 #endif // ! OLENA_CORE_PW_MACROS_HH
Index: oln/core/pw/abstract/function.hh
===================================================================
--- oln/core/pw/abstract/function.hh	(revision 270)
+++ oln/core/pw/abstract/function.hh	(working copy)
@@ -28,7 +28,7 @@
 #ifndef OLENA_CORE_PW_ABSTRACT_FUNCTION_HH
 # define OLENA_CORE_PW_ABSTRACT_FUNCTION_HH
 
-# include <mlc/any.hh>
+# include <oln/core/abstract/any.hh>
 # include <oln/core/abstract/image.hh>
 # include <oln/core/typedefs.hh>
 
@@ -80,23 +80,31 @@
     }
   };
 
-
+  // fwd decls
   namespace pw {
-
-    // fwd decls
     namespace abstract {
       template <typename E> struct function;
     }
     template <typename T> struct literal;
     // FIXME:...
-//     template <typename L, typename R> struct minus;
-//     template <typename F> struct not_;
+    //     template <typename L, typename R> struct minus;
+    //     template <typename F> struct not_;
+  } // end of namespace oln::pw
 
 
+  template <typename E>
+  struct set_props < category::pw, pw::abstract::function<E> >
+  {
+    typedef E exact_type;
+  };
+
+
+  namespace pw {
+
     namespace abstract {
 
       template <typename E>
-      struct function : public mlc::any<E>
+      struct function : public oln::abstract::any<E>
       {
 	typedef oln_pw_type_of(E, point) point_type;
 	typedef oln_pw_type_of(E, value) value_type;
@@ -112,6 +120,12 @@
 	  return this->exact().impl_get(p);
 	}
 
+	template <typename P>
+	void operator[](const P&) const
+	{
+	  // FIXME: provide an explicit err msg, e.g., "[p] should not be used on a pwf"
+	}
+
 	bool hold(const point_type& p) const
 	{
 	  return this->exact().impl_hold(p);
Index: oln/core/pw/apply.hh
===================================================================
--- oln/core/pw/apply.hh	(revision 270)
+++ oln/core/pw/apply.hh	(working copy)
@@ -33,6 +33,8 @@
 # include <oln/core/pw/abstract/binary_function.hh>
 # include <oln/core/pw/macros.hh>
 
+// FIXME: this file contents will be obsolete when...
+// FIXME: ...we have fun(pwf) work
 
 namespace oln {
 
Index: oln/core/pw/arith.hh
===================================================================
--- oln/core/pw/arith.hh	(revision 270)
+++ oln/core/pw/arith.hh	(working copy)
@@ -28,63 +28,236 @@
 #ifndef OLENA_CORE_PW_ARITH_HH
 # define OLENA_CORE_PW_ARITH_HH
 
-# include <oln/funobj/arith.hh>
-# include <oln/funobj/infsup.hh>
-# include <oln/core/pw/macros.hh>
+# include <mlc/cmp.hh>
+# include <mlc/ftraits.hh>
+# include <mlc/farith.hh>
 
+# include <oln/core/abstract/image_typeness.hh>
+# include <oln/core/gen/cst.hh>
 
-namespace oln
-{
+# include <oln/core/pw/image.hh>
+# include <oln/core/pw/unary_op.hh>
+# include <oln/core/pw/binary_op.hh>
+# include <oln/core/pw/literal.hh>
 
-  oln_pw_decl_binary(plus);
-  oln_pw_decl_binary(minus);
-  oln_pw_decl_binary(times);
-  oln_pw_decl_binary(div);
-  oln_pw_decl_binary(mod);
+# include <oln/ops/overload.hh>
 
 
-  // min max
 
-  template <typename L, typename R>
-  pw::binary_op< f_min_type, L, R >
-  min (const pw::abstract::function<L>& lhs,
-       const pw::abstract::function<R>& rhs)
-  {
-    pw::binary_op< f_min_type, L, R > tmp(lhs, rhs);
-    return tmp;
-  }
 
-  template <typename L, typename R>
-  pw::binary_op< f_max_type, L, R >
-  max (const pw::abstract::function<L>& lhs,
-       const pw::abstract::function<R>& rhs)
-  {
-    pw::binary_op< f_max_type, L, R > tmp(lhs, rhs);
-    return tmp;
-  }
+// overload ids:
+// 1  <=>  pwf      OP pwf
+// 2  <=>  pwf      OP builtin
+// 3  <=>  builtin  OP pwf
+// 4  <=>  pwf      OP constant
+// 5  <=>  constant OP pwf 
 
-  // inf sup
+// 6  <=>  image OP image  (in oln/core/ops/arith.hh)
+// ...
 
-  template <typename L, typename R>
-  pw::binary_op< f_inf_type, L, R >
-  inf (const pw::abstract::function<L>& lhs,
-       const pw::abstract::function<R>& rhs)
-  {
-    pw::binary_op< f_inf_type, L, R > tmp(lhs, rhs);
-    return tmp;
-  }
 
-  template <typename L, typename R>
-  pw::binary_op< f_sup_type, L, R >
-  sup (const pw::abstract::function<L>& lhs,
-       const pw::abstract::function<R>& rhs)
-  {
-    pw::binary_op< f_sup_type, L, R > tmp(lhs, rhs);
-    return tmp;
-  }
+/*
 
+// FIXME: these built-in types are not handled in operators:
 
+												\
+  oln_pw_decl_binary_arith_op_with_builtin(OperatorName, OperatorSymbol, float);		\
+  oln_pw_decl_binary_arith_op_with_builtin(OperatorName, OperatorSymbol, double);		\
+  oln_pw_decl_binary_arith_op_with_builtin(OperatorName, OperatorSymbol, char);			\
+  oln_pw_decl_binary_arith_op_with_builtin(OperatorName, OperatorSymbol, signed int);		\
+
+  oln_pw_decl_binary_arith_op_with_builtin(OperatorName, OperatorSymbol, long double);
+  oln_pw_decl_binary_arith_op_with_builtin(OperatorName, OperatorSymbol, unsigned char);
+  oln_pw_decl_binary_arith_op_with_builtin(OperatorName, OperatorSymbol, signed char);
+  oln_pw_decl_binary_arith_op_with_builtin(OperatorName, OperatorSymbol, unsigned short);
+  oln_pw_decl_binary_arith_op_with_builtin(OperatorName, OperatorSymbol, signed short);
+  oln_pw_decl_binary_arith_op_with_builtin(OperatorName, OperatorSymbol, unsigned int);
+  oln_pw_decl_binary_arith_op_with_builtin(OperatorName, OperatorSymbol, unsigned long);
+  oln_pw_decl_binary_arith_op_with_builtin(OperatorName, OperatorSymbol, signed long);
+
+*/
+
+
+
+# define oln_pw_decl_binary_arith_op_with_builtin(OperatorName, OperatorSymbol, BuiltIn)	\
+												\
+  template <typename L>										\
+  const mlc_binary_ret(OperatorName, L, BuiltIn)						\
+  operator OperatorSymbol (const pw::abstract::function<L>& lhs,				\
+                           BuiltIn rhs)								\
+  {												\
+    mlc::neq< oln_typeness_of(oln_pw_type_of(L, value)), typeness::binary_tag >::ensure();	\
+    pw::literal<BuiltIn> rhs_(rhs);								\
+    mlc_binary_ret(OperatorName, L, BuiltIn) tmp(lhs, rhs_);					\
+    return tmp;											\
+  }												\
+												\
+  template <typename R>										\
+  const mlc_binary_ret(OperatorName, BuiltIn, R)						\
+  operator OperatorSymbol (BuiltIn lhs,								\
+                           const pw::abstract::function<R>& rhs)				\
+  {												\
+    mlc::neq< oln_typeness_of(oln_pw_type_of(R, value)), typeness::binary_tag >::ensure();	\
+    pw::literal<BuiltIn> lhs_(lhs);								\
+    mlc_binary_ret(OperatorName, BuiltIn, R) tmp(lhs_, rhs);					\
+    return tmp;											\
+  }												\
+												\
+struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
+
+
+
+
+/// Macro oln_pw_decl_binary_arith_op.
+
+# define oln_pw_decl_binary_arith_op(OperatorName, OperatorSymbol)				\
+												\
+  /*  1  <=>  pwf OP pwf  */									\
+												\
+  template <typename L, typename R>								\
+  struct decl_overload< mlc::tag::OperatorName##_, 1, L, R >					\
+    : mlc::where< mlc::and_< mlc_is_a(L, pw::abstract::function),				\
+			     mlc_is_a(R, pw::abstract::function) > >				\
+  {												\
+    typedef pw::binary_op< mlc::f_##OperatorName##_type,					\
+                           L,									\
+                           R > ret;								\
+  };												\
+												\
+  template <typename L, typename R>								\
+  const mlc_binary_ret(OperatorName, L, R)							\
+  operator OperatorSymbol (const pw::abstract::function<L>& lhs,				\
+                           const pw::abstract::function<R>& rhs)				\
+  {												\
+    mlc::neq< oln_typeness_of(oln_pw_type_of(L, value)), typeness::binary_tag >::ensure();	\
+    mlc::neq< oln_typeness_of(oln_pw_type_of(R, value)), typeness::binary_tag >::ensure();	\
+    precondition(lhs.size() == rhs.size());							\
+    pw::binary_op< mlc::f_##OperatorName##_type,						\
+                   L, R > tmp(lhs, rhs);							\
+    return tmp;											\
+  }												\
+												\
+  /*  2  <=>  pwf OP builtin  */								\
+  /*  3  <=>  builtin OP pwf  */								\
+												\
+  template <typename L, typename R>								\
+  struct decl_overload< mlc::tag::OperatorName##_, 2, L, R >					\
+    : mlc::where< mlc::and_< mlc_is_a(L, pw::abstract::function),				\
+			     mlc::is_builtin<R> > >						\
+  {												\
+    typedef pw::binary_op< mlc::f_##OperatorName##_type,					\
+                           L,									\
+                           pw::literal<R> > ret;						\
+  };												\
+												\
+  template <typename L, typename R>								\
+  struct decl_overload< mlc::tag::OperatorName##_, 3, L, R >					\
+    : mlc::where< mlc::and_< mlc::is_builtin<L>,						\
+			     mlc_is_a(R, pw::abstract::function) > >				\
+  {												\
+    typedef pw::binary_op< mlc::f_##OperatorName##_type,					\
+                           pw::literal<L>,							\
+                           R > ret;								\
+  };												\
+												\
+  /*  4  <=>  pwf OP constant  */								\
+												\
+  template <typename L, typename R>								\
+  struct decl_overload< mlc::tag::OperatorName##_, 4, L, R >					\
+    : mlc::where< mlc::and_< mlc_is_a(L, pw::abstract::function),				\
+			     mlc_is_a(R, constant) > >						\
+  {												\
+    typedef pw::binary_op< mlc::f_##OperatorName##_type,					\
+                           L,									\
+                           pw::literal<typename R::value_type> > ret;				\
+  };												\
+												\
+  template <typename L, typename R>								\
+  const mlc_binary_ret(OperatorName, L, constant<R>)						\
+  operator OperatorSymbol (const pw::abstract::function<L>& lhs,				\
+                           const constant<R>& rhs)						\
+  {												\
+    mlc::neq< oln_typeness_of(oln_pw_type_of(L, value)), typeness::binary_tag >::ensure();	\
+    mlc::neq< oln_typeness_of(R), typeness::binary_tag >::ensure();				\
+    pw::literal<R> rhs_(rhs);									\
+    mlc_binary_ret(OperatorName, L, constant<R>) tmp(lhs, rhs_);				\
+    return tmp;											\
+  }												\
+												\
+  /*  5  <=>  constant OP pwf  */								\
+												\
+  template <typename L, typename R>								\
+  struct decl_overload< mlc::tag::OperatorName##_, 5, L, R >					\
+    : mlc::where< mlc::and_< mlc_is_a(L, constant),						\
+			     mlc_is_a(R, pw::abstract::function) > >				\
+  {												\
+    typedef pw::binary_op< mlc::f_##OperatorName##_type,					\
+                           pw::literal<typename L::value_type>,					\
+                           R > ret;								\
+  };												\
+												\
+  template <typename L, typename R>								\
+  const mlc_binary_ret(OperatorName, constant<L>, R)						\
+  operator OperatorSymbol (const constant<L>& lhs,						\
+                           const pw::abstract::function<R>& rhs)				\
+  {												\
+    mlc::neq< oln_typeness_of(L), typeness::binary_tag >::ensure();				\
+    mlc::neq< oln_typeness_of(oln_pw_type_of(R, value)), typeness::binary_tag >::ensure();	\
+    pw::literal<L> lhs_(lhs);									\
+    mlc_binary_ret(OperatorName, constant<L>, R) tmp(lhs_, rhs);				\
+    return tmp;											\
+  }												\
+												\
+struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
+
+
+
+
+
+
+
+
+/// Macro oln_pw_decl_unary_arith_op.
+
+# define oln_pw_decl_unary_arith_op(OperatorName, OperatorSymbol)				\
+												\
+  template <typename R>										\
+  struct decl_overload< mlc::tag::OperatorName##_, 1, R >					\
+    : mlc::where< mlc_is_a(R, pw::abstract::function) >						\
+  {												\
+    typedef pw::unary_op< mlc::f_##OperatorName##_type,						\
+                          R > ret;								\
+  };												\
+												\
+  template <typename R>										\
+  mlc_unary_ret(OperatorName, R)								\
+  operator OperatorSymbol (const pw::abstract::function<R>& rhs)				\
+  {												\
+    mlc::neq< oln_typeness_of(oln_pw_type_of(R, value)), typeness::binary_tag >::ensure();	\
+    oln::pw::unary_op< mlc::f_##OperatorName##_type,						\
+                       R > tmp(rhs);								\
+    return tmp;											\
+  }												\
+												\
+struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
+
+
+
+namespace oln {
+
+  oln_pw_decl_unary_arith_op(  inc,    ++ );
+  oln_pw_decl_unary_arith_op(  dec,    -- );
+  oln_pw_decl_unary_arith_op(  uminus, - );
+
+  oln_pw_decl_binary_arith_op( plus,   + );
+  oln_pw_decl_binary_arith_op( minus,  - );
+  oln_pw_decl_binary_arith_op( times,  * );
+  oln_pw_decl_binary_arith_op( div,    / );
+  oln_pw_decl_binary_arith_op( mod,    % );
+
 } // end of namespace oln
 
 
+
+
 #endif // ! OLENA_CORE_PW_ARITH_HH
Index: oln/core/pw/unary_op.hh
===================================================================
--- oln/core/pw/unary_op.hh	(revision 270)
+++ oln/core/pw/unary_op.hh	(working copy)
@@ -29,8 +29,10 @@
 # define OLENA_CORE_PW_UNARY_OP_HH
 
 # include <mlc/is_a.hh>
+# include <mlc/afun.hh>
 # include <oln/core/pw/abstract/unary_function.hh>
-# include <oln/funobj/abstract/unary.hh>
+# include <oln/core/pw/value.hh>
+# include <oln/core/pw/image.hh>
 
 
 
@@ -50,12 +52,18 @@
   template <typename F, typename A>
   struct set_props < category::pw, pw::unary_op<F,A> >
   {
-    typedef typename f_::munary_result<F,A>::ret value_type;
+    typedef
+    typename mlc::mfun_res_traits< F,
+				   oln_pw_type_of(A, value) >::ret
+    value_type;
   };
 
 
   namespace pw {
 
+    // FIXME: unary_op only works with mlc::abstract::meta_unary_function
+    // FIXME: think about another type that works with mlc::abstract::unary_function...
+
     template <typename F, typename A>
     struct unary_op : public abstract::unary_function< A, pw::unary_op<F,A> >
     {
@@ -68,9 +76,15 @@
 	super_type(arg),
 	fun()
       {
-	mlc_is_a(F, f_::abstract::munary)::ensure();
-// 	mlc_is_a(F, f_::unary_meta)::ensure();
+	mlc_is_a(F, mlc::abstract::meta_unary_function)::ensure();
       }
+      unary_op(const F& fun,
+	       const abstract::function<A>& arg) :
+	super_type(arg),
+	fun(fun)
+      {
+	mlc_is_a(F, mlc::abstract::meta_unary_function)::ensure();
+      }
 
       typedef oln_pw_type_of(self_type, point) point_type;
       typedef oln_pw_type_of(self_type, value) value_type;
@@ -89,4 +103,56 @@
 } // end of namespace oln
 
 
+
+
+namespace mlc
+{
+
+  template <typename F, typename A>
+  struct decl_overload <tag::mufun, 1,
+			F, A> : public where< mlc_is_a(A, oln::pw::abstract::function) >
+  {
+    typedef oln_pw_type_of(A, exact) A_;
+
+    typedef oln::pw::unary_op<F,A_> ret;
+
+    template <class A_>
+    static ret exec(const F& fun,
+		    const oln::pw::abstract::function<A_>& arg)
+    {
+      // safety check:
+      mlc_is_a(F, mlc::abstract::meta_unary_function)::ensure();
+      ret tmp(fun, arg);
+      return tmp;
+    }
+  };
+
+
+  template <typename F, typename I>
+  struct decl_overload <tag::mufun, 2,
+			F, I> : public where< mlc_is_a(I, oln::abstract::image) >
+  {
+    // FIXME: oln_type_of(I, exact) does not work yet...
+    typedef I /*oln_type_of(I, exact)*/ I_;
+
+    typedef oln::pw::unary_op<F, oln::pw::value<I_> > PWF;
+    typedef oln::pw::image<PWF> ret;
+
+    template <class I_>
+    static ret exec(const F& fun,
+		    const oln::abstract::image<I_>& arg)
+    {
+      // safety check:
+      mlc_is_a(F, mlc::abstract::meta_unary_function)::ensure();
+      
+      oln::pw::value<I_> pw_val(arg);
+      PWF pw_fun(fun, pw_val);
+      ret tmp(pw_fun);
+      return tmp;
+    }
+  };
+
+} // end of namespace mlc
+
+
 #endif // ! OLENA_CORE_PW_UNARY_OP_HH
Index: oln/core/pw/check.hh
===================================================================
--- oln/core/pw/check.hh	(revision 270)
+++ oln/core/pw/check.hh	(working copy)
@@ -37,12 +37,11 @@
 
   namespace pw {
 
-
     template <typename F>
     bool check(const abstract::function<F>& pred)
     {
       mlc::eq< oln_typeness_of(oln_pw_type_of(F, value)), typeness::binary_tag >::ensure();
-      typedef image_from_pwf<F> I;
+      typedef pw::image<F> I;
       I ima(pred);
       oln_type_of(I, fwd_piter) p(ima.size());
       for_all_p (p)
@@ -51,9 +50,14 @@
       return true;
     }
 
-
   } // end of namespace oln::pw
 
+  template <typename F>
+  bool pw_check(const pw::abstract::function<F>& pred)
+  {
+    return pw::check(pred);
+  }
+
 } // end of namespace oln
 
 
Index: oln/core/pw/logic.hh
===================================================================
--- oln/core/pw/logic.hh	(revision 270)
+++ oln/core/pw/logic.hh	(working copy)
@@ -28,10 +28,158 @@
 #ifndef OLENA_CORE_PW_LOGIC_HH
 # define OLENA_CORE_PW_LOGIC_HH
 
-# include <oln/funobj/logic.hh>
-# include <oln/core/pw/macros.hh>
 
+# include <mlc/cmp.hh>
+# include <mlc/ftraits.hh>
+# include <mlc/flogic.hh>
 
+# include <oln/core/pw/image.hh>
+# include <oln/core/pw/unary_op.hh>
+# include <oln/core/pw/binary_op.hh>
+# include <oln/core/pw/literal.hh>
 
+# include <oln/ops/overload.hh>
 
+
+// overload of UNARY op ids:
+// 1  <=>  pwf      OP pwf
+// 2  <=>  image OP image  (in oln/core/ops/logic.hh)
+// ...
+
+
+
+// overload of BINARY ops ids:
+// 1  <=>  pwf      OP pwf
+// 2  <=>  pwf      OP bool
+// 3  <=>  bool     OP pwf
+// 4  <=>  image OP image  (in oln/core/ops/logic.hh)
+// ...
+
+
+
+
+
+
+/// Macro oln_pw_decl_binary_logic_op.
+
+# define oln_pw_decl_binary_logic_op(OperatorName, OperatorSymbol)	\
+									\
+  /*  1  <=>  pwf OP pwf  */						\
+									\
+  template <typename L, typename R>					\
+  struct decl_overload< mlc::tag::OperatorName##_, 1, L, R >		\
+    : mlc::where< mlc::and_< mlc_is_a(L, pw::abstract::function),	\
+			     mlc_is_a(R, pw::abstract::function) > >	\
+  {									\
+    typedef pw::binary_op< mlc::f_##OperatorName##_type,		\
+                           L,						\
+                           R > ret;					\
+  };									\
+									\
+  template <typename L, typename R>					\
+  const mlc_binary_ret(OperatorName, L, R)				\
+  operator OperatorSymbol (const pw::abstract::function<L>& lhs,	\
+                           const pw::abstract::function<R>& rhs)	\
+  {									\
+    mlc::is_Boolean<oln_pw_type_of(L, value)>::ensure();		\
+    mlc::is_Boolean<oln_pw_type_of(R, value)>::ensure();		\
+    precondition(lhs.size() == rhs.size());				\
+    pw::binary_op< mlc::f_##OperatorName##_type,			\
+                   L, R > tmp(lhs, rhs);				\
+    return tmp;								\
+  }									\
+									\
+  /*  2  <=>  pwf OP bool  */						\
+									\
+  template <typename L, typename R>					\
+  struct decl_overload< mlc::tag::OperatorName##_, 2, L, R >		\
+    : mlc::where< mlc::and_< mlc_is_a(L, pw::abstract::function),	\
+			     mlc::is_Boolean<R> > >			\
+  {									\
+    typedef pw::binary_op< mlc::f_##OperatorName##_type,		\
+                           L,						\
+                           pw::literal<R> > ret;			\
+  };									\
+									\
+  template <typename L>							\
+  const mlc_binary_ret(OperatorName, L, bool)				\
+  operator OperatorSymbol (const pw::abstract::function<L>& lhs,	\
+                           bool rhs)					\
+  {									\
+    mlc::is_Boolean<oln_pw_type_of(L, value)>::ensure();		\
+    pw::literal<bool> rhs_(rhs);					\
+    mlc_binary_ret(OperatorName, L, bool) tmp(lhs, rhs_);		\
+    return tmp;								\
+  }									\
+									\
+  /*  3  <=>  bool OP pwf  */						\
+									\
+  template <typename L, typename R>					\
+  struct decl_overload< mlc::tag::OperatorName##_, 3, L, R >		\
+    : mlc::where< mlc::and_< mlc::is_Boolean<L>,			\
+			     mlc_is_a(R, pw::abstract::function) > >	\
+  {									\
+    typedef pw::binary_op< mlc::f_##OperatorName##_type,		\
+                           pw::literal<L>,				\
+                           R > ret;					\
+  };									\
+									\
+  template <typename R>							\
+  const mlc_binary_ret(OperatorName, bool, R)				\
+  operator OperatorSymbol (bool lhs,					\
+                           const pw::abstract::function<R>& rhs)	\
+  {									\
+    mlc::is_Boolean<oln_pw_type_of(R, value)>::ensure();		\
+    pw::literal<bool> lhs_(lhs);					\
+    mlc_binary_ret(OperatorName, bool, R) tmp(lhs_, rhs);		\
+    return tmp;								\
+  }									\
+									\
+struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
+
+
+
+
+
+
+
+
+/// Macro oln_pw_decl_unary_logic_op.
+
+# define oln_pw_decl_unary_logic_op(OperatorName, OperatorSymbol)	\
+									\
+  template <typename R>							\
+  struct decl_overload< mlc::tag::OperatorName##_, 1, R >		\
+    : mlc::where< mlc_is_a(R, pw::abstract::function) >			\
+  {									\
+    typedef pw::unary_op< mlc::f_##OperatorName##_type,			\
+                          R > ret;					\
+  };									\
+									\
+  template <typename R>							\
+  mlc_unary_ret(OperatorName, R)					\
+  operator OperatorSymbol (const pw::abstract::function<R>& rhs)	\
+  {									\
+    mlc::is_Boolean<oln_pw_type_of(R, value)>::ensure();		\
+    oln::pw::unary_op< mlc::f_##OperatorName##_type,			\
+                       R > tmp(rhs);					\
+    return tmp;								\
+  }									\
+									\
+struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
+
+
+
+
+namespace oln {
+
+  oln_pw_decl_unary_logic_op(  not, not );
+
+  oln_pw_decl_binary_logic_op( and, and );
+  oln_pw_decl_binary_logic_op( or,  or  );
+  oln_pw_decl_binary_logic_op( xor, xor );
+
+} // end of namespace oln
+
+
 #endif // ! OLENA_CORE_PW_LOGIC_HH
Index: oln/core/pw/cmp.hh
===================================================================
--- oln/core/pw/cmp.hh	(revision 270)
+++ oln/core/pw/cmp.hh	(working copy)
@@ -28,22 +28,179 @@
 #ifndef OLENA_CORE_PW_CMP_HH
 # define OLENA_CORE_PW_CMP_HH
 
-# include <oln/funobj/cmp.hh>
-# include <oln/core/pw/macros.hh>
+# include <mlc/ftraits.hh>
+# include <mlc/fcmp.hh>
 
+# include <oln/core/pw/image.hh>
+# include <oln/core/pw/binary_op.hh>
+# include <oln/core/pw/literal.hh>
 
+# include <oln/core/gen/cst.hh>
+# include <oln/ops/overload.hh>
+
+
+
+
+// overload ids:
+// 1  <=>  pwf      OP pwf
+// 2  <=>  pwf      OP builtin
+// 3  <=>  builtin  OP pwf
+// 4  <=>  pwf      OP constant
+// 5  <=>  constant OP pwf 
+
+// 6  <=>  image OP image  (in oln/core/ops/cmp.hh)
+// ...
+
+
+
+
+// FIXME: add:
+
+//   oln_pw_decl_cmp_op_with_builtin(OperatorName, OperatorSymbol, float);
+//   oln_pw_decl_cmp_op_with_builtin(OperatorName, OperatorSymbol, double);
+//   oln_pw_decl_cmp_op_with_builtin(OperatorName, OperatorSymbol, char);
+//   oln_pw_decl_cmp_op_with_builtin(OperatorName, OperatorSymbol, signed int);
+
+
+
+# define oln_pw_decl_cmp_op_with_builtin(OperatorName, OperatorSymbol, BuiltIn)	\
+										\
+  template <typename L>								\
+  const mlc_binary_ret(OperatorName, L, BuiltIn)				\
+  operator OperatorSymbol (const pw::abstract::function<L>& lhs,		\
+                           BuiltIn rhs)						\
+  {										\
+    pw::literal<BuiltIn> rhs_(rhs);						\
+    mlc_binary_ret(OperatorName, L, BuiltIn) tmp(lhs, rhs_);			\
+    return tmp;									\
+  }										\
+										\
+  template <typename R>								\
+  const mlc_binary_ret(OperatorName, BuiltIn, R)				\
+  operator OperatorSymbol (BuiltIn lhs,						\
+                           const pw::abstract::function<R>& rhs)		\
+  {										\
+    pw::literal<BuiltIn> lhs_(lhs);						\
+    mlc_binary_ret(OperatorName, BuiltIn, R) tmp(lhs_, rhs);			\
+    return tmp;									\
+  }										\
+										\
+struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
+
+
+
+
+/// Macro oln_pw_decl_cmp_op.
+
+# define oln_pw_decl_cmp_op(OperatorName, OperatorSymbol)			\
+										\
+  /*  1  <=>  pwf OP pwf  */							\
+										\
+  template <typename L, typename R>						\
+  struct decl_overload< mlc::tag::OperatorName##_, 1, L, R >			\
+    : mlc::where< mlc::and_< mlc_is_a(L, pw::abstract::function),		\
+			     mlc_is_a(R, pw::abstract::function) > >		\
+  {										\
+    typedef pw::binary_op< mlc::f_##OperatorName##_type,			\
+                           L,							\
+                           R > ret;						\
+  };										\
+										\
+  template <typename L, typename R>						\
+  const mlc_binary_ret(OperatorName, L, R)					\
+  operator OperatorSymbol (const pw::abstract::function<L>& lhs,		\
+                           const pw::abstract::function<R>& rhs)		\
+  {										\
+    precondition(lhs.size() == rhs.size());					\
+    pw::binary_op< mlc::f_##OperatorName##_type,				\
+                   L, R > tmp(lhs, rhs);					\
+    return tmp;									\
+  }										\
+										\
+  /*  2  <=>  pwf OP builtin  */						\
+  /*  3  <=>  builtin OP pwf  */						\
+										\
+  template <typename L, typename R>						\
+  struct decl_overload< mlc::tag::OperatorName##_, 2, L, R >			\
+    : mlc::where< mlc::and_< mlc_is_a(L, pw::abstract::function),		\
+			     mlc::is_builtin<R> > >				\
+  {										\
+    typedef pw::binary_op< mlc::f_##OperatorName##_type,			\
+                           L,							\
+                           pw::literal<R> > ret;				\
+  };										\
+										\
+  template <typename L, typename R>						\
+  struct decl_overload< mlc::tag::OperatorName##_, 3, L, R >			\
+    : mlc::where< mlc::and_< mlc::is_builtin<L>,				\
+			     mlc_is_a(R, pw::abstract::function) > >		\
+  {										\
+    typedef pw::binary_op< mlc::f_##OperatorName##_type,			\
+                           pw::literal<L>,					\
+                           R > ret;						\
+  };										\
+										\
+  /*  4  <=>  pwf OP constant  */						\
+										\
+  template <typename L, typename R>						\
+  struct decl_overload< mlc::tag::OperatorName##_, 4, L, R >			\
+    : mlc::where< mlc::and_< mlc_is_a(L, pw::abstract::function),		\
+			     mlc_is_a(R, constant) > >				\
+  {										\
+    typedef pw::binary_op< mlc::f_##OperatorName##_type,			\
+                           L,							\
+                           pw::literal<typename R::value_type> > ret;		\
+  };										\
+										\
+  template <typename L, typename R>						\
+  const mlc_binary_ret(OperatorName, L, constant<R>)				\
+  operator OperatorSymbol (const pw::abstract::function<L>& lhs,		\
+                           const constant<R>& rhs)				\
+  {										\
+    pw::literal<R> rhs_(rhs);							\
+    mlc_binary_ret(OperatorName, L, constant<R>) tmp(lhs, rhs_);		\
+    return tmp;									\
+  }										\
+										\
+  /*  5  <=>  constant OP pwf  */						\
+										\
+  template <typename L, typename R>						\
+  struct decl_overload< mlc::tag::OperatorName##_, 5, L, R >			\
+    : mlc::where< mlc::and_< mlc_is_a(L, constant),				\
+			     mlc_is_a(R, pw::abstract::function) > >		\
+  {										\
+    typedef pw::binary_op< mlc::f_##OperatorName##_type,			\
+                           pw::literal<typename L::value_type>,			\
+                           R > ret;						\
+  };										\
+										\
+  template <typename L, typename R>						\
+  const mlc_binary_ret(OperatorName, constant<L>, R)				\
+  operator OperatorSymbol (const constant<L>& lhs,				\
+                           const pw::abstract::function<R>& rhs)		\
+  {										\
+    pw::literal<L> lhs_(lhs);							\
+    mlc_binary_ret(OperatorName, constant<L>, R) tmp(lhs_, rhs);		\
+    return tmp;									\
+  }										\
+										\
+struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
+
+
+
+
+
 namespace oln {
 
-  oln_pw_decl_binary(eq);
-  oln_pw_decl_binary(neq);
-  oln_pw_decl_binary(less);
-  oln_pw_decl_binary(leq);
-  oln_pw_decl_binary(greater);
-  oln_pw_decl_binary(geq);
+  oln_pw_decl_cmp_op(      eq, == );
+  oln_pw_decl_cmp_op(     neq, != );
+  oln_pw_decl_cmp_op(    less, <  );
+  oln_pw_decl_cmp_op(     leq, <= );
+  oln_pw_decl_cmp_op( greater, >  );
+  oln_pw_decl_cmp_op(     geq, >= );
 
 } // end of namespace oln
 
 
 
-
 #endif // ! OLENA_CORE_PW_CMP_HH
Index: oln/core/gen/cst.hh
===================================================================
--- oln/core/gen/cst.hh	(revision 0)
+++ oln/core/gen/cst.hh	(revision 0)
@@ -0,0 +1,65 @@
+// Copyright (C) 2005  EPITA Research and Development Laboratory
+//
+// This  file is  part of  the Olena  Library.  This  library  is free
+// software; you can redistribute it  and/or modify it under the terms
+// of the  GNU General  Public License version  2 as published  by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT  ANY  WARRANTY;  without   even  the  implied  warranty  of
+// MERCHANTABILITY or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU
+// General Public License for more details.
+//
+// You should have  received a copy of the  GNU General Public License
+// along with  this library; see the  file COPYING.  If  not, write to
+// the Free Software Foundation, 59  Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+//
+// As a  special exception, you  may use this  file as part of  a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates  or use macros or inline  functions from this
+// file, or  you compile  this file  and link it  with other  files to
+// produce  an executable,  this file  does  not by  itself cause  the
+// resulting  executable  to be  covered  by  the  GNU General  Public
+// License.   This exception  does  not however  invalidate any  other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLENA_OLN_CORE_GEN_CST_HH
+# define OLENA_OLN_CORE_GEN_CST_HH
+
+# include <oln/core/abstract/any.hh>
+# include <oln/core/gen/internal/value_box.hh>
+
+namespace oln
+{
+
+  template <typename T>
+  class constant : public abstract::any< constant<T> >
+  {
+  public:
+    constant(const T value) : value_(value) {}
+    operator T() const { return value_; }
+    const T value() const { return value_; }
+    typedef T value_type;
+  private:
+    T value_;
+  };
+
+  template <typename T>
+  const constant<T> cst(const T& value)
+  {
+    constant<T> tmp(value);
+    return tmp;
+  }
+
+  template <typename I>
+  const constant<oln_type_of(I, value)> cst(const value_box<I>& vb)
+  {
+    constant<oln_type_of(I, value)> tmp(vb.value());
+    return tmp;
+  }
+
+} // end of namespace oln
+
+#endif // !OLENA_OLN_CORE_GEN_CST_HH
Index: oln/utils/overload.hh
===================================================================
--- oln/utils/overload.hh	(revision 270)
+++ oln/utils/overload.hh	(working copy)
@@ -28,402 +28,6 @@
 #ifndef OLN_UTILS_OVERLOAD_HH
 # define OLN_UTILS_OVERLOAD_HH
 
-# include <mlc/types.hh>
-# include <mlc/is_a.hh>
-# include <mlc/if.hh>
+// FIXME: empty
 
-
-
-
-// FIXME: most code here should move to metalic!
-
-// FIXME: some piece of code should move to oln/core?
-
-
-
-
-//   // Sample use:
-
-//   struct for_doit;
-
-//   template <typename I>
-//   struct set_overload_1 < for_doit, where<I, abstract::image> >
-//   {
-//     typedef int ret;
-//     static ret exec(const abstract::image<I>& ima)
-//     {
-//       std::cout << "image" << std::endl;
-//       return 51;
-//     }
-//   };
-
-//   template <typename T>
-//   struct set_overload_1 < for_doit, where<T, whatever> >
-//   {
-//     typedef T ret;
-//     static T exec(const T& t)
-//     {
-//       std::cout << "NOT image" << std::endl;
-//       return t;
-//     }
-//   };
-
-//   template <typename T>
-//   typename overload_1<for_doit, T>::ret
-//   doit(const T& arg)
-//   {
-//     std::cout << "doit..." << std::endl;
-//     return overload_1<for_doit, T>::exec(arg);
-//   }
-
-
-
-
-// fwd decls
-
-namespace ntg
-{
-  template <typename E> struct value;
-
-} // end of namespace ntg
-
-namespace oln
-{
-
-  namespace internal
-  {
-    template <typename I> struct value_box;
-
-  } // end of namespace oln::internal
-
-  namespace abstract
-  {
-    template <typename I> struct image;
-
-  } // end of namespace oln::abstract
-
-  namespace pw
-  {
-    namespace abstract
-    {
-      template <typename F> struct function;
-
-    } // end of namespace oln::pw::abstract
-
-  } // end of namespace oln::pw
-
-} // end of namespace oln
-
-
-// end of fwd decls
-
-
-
-
-
-namespace oln
-{
-
-  /// whatever
-
-  template <typename> struct whatever;
-
-  /// when
-
-  template <typename T,
-	    template <class> class abstraction = whatever >
-  struct where;
-
-
-
-
-
-  /// Structures to be specialized by the client.
-
-  template <typename what_is_overloaded, typename where_clause>
-  struct set_overload_1
-  {
-    typedef mlc::undefined_type ret;
-  };
-
-  template <typename what_is_overloaded,
-	    typename where_clause_1, typename where_clause_2>
-  struct set_overload_2
-  {
-    typedef mlc::undefined_type ret;
-  };
-
-
-  /// Make 'whatever' be the 'default' overload.
-
-  template <typename W, typename T1, typename T2>
-  struct set_overload_2 < W, where<T1,whatever>, where<T2,whatever> >
-  {
-    typedef mlc::undefined_type ret;
-  };
-
-  template <typename W,
-	    typename T1, template <class> class A1,
-	    typename T2, template <class> class A2>
-  struct set_overload_2     < W, where<T1,A1>,       where<T2,A2>       >
-    : public set_overload_2 < W, where<T1,whatever>, where<T2,whatever> >
-  {
-    typedef set_overload_2<W, where<T1,whatever>, where<T2,whatever> > super_type;
-    using super_type::ret;
-    using super_type::exec;
-  };
-
-
-
-  namespace internal {
-
-
-    /// Function f_where: T -> type.
-
-    template <typename T>
-    struct f_where
-    {
-      typedef typename
-      mlc::if_< mlc_is_a(T, ntg::value),
-		where<T, ntg::value>, typename 
-		mlc::if_< mlc_is_a(T, oln::abstract::image),
-			  where<T, oln::abstract::image>, typename 
-			  mlc::if_< mlc_is_a(T, oln::internal::value_box),
-				    where<T, oln::internal::value_box>, typename 
-				    mlc::if_< mlc_is_a(T, oln::pw::abstract::function),
-					      where<T, oln::pw::abstract::function>,
-					      where<T>
-                                             >::ret
-                                   >::ret
-                         >::ret
-              >::ret
-      ret;
-    };
-
-
-
-  } // end of namespace oln::internal
-
-
-
-
-  /// Facades.
-
-  template <typename what_is_overloaded, typename T>
-  struct overload_1
-  {
-    typedef typename internal::f_where<T>::ret where_type;
-    typedef set_overload_1<what_is_overloaded, where_type> overload_type;
-    typedef typename overload_type::ret ret;
-
-    static ret exec(const T& arg)
-    {
-      return overload_type::exec(arg);
-    }
-  };
-
-  template <typename what_is_overloaded, typename T1, typename T2>
-  struct overload_2
-  {
-    typedef typename internal::f_where<T1>::ret where1_type;
-    typedef typename internal::f_where<T2>::ret where2_type;
-    typedef set_overload_2<what_is_overloaded, where1_type, where2_type> overload_type;
-    typedef typename overload_type::ret ret;
-
-    static ret exec(const T1& arg1, const T2& arg2)
-    {
-      return overload_type::exec(arg1, arg2);
-    }
-    // FIXME: insert a static check that exec is defined in set_overload
-  };
-
-} // end of namespace oln
-
-
-
-
-# include <ntg/core/internal/global_ops.hh>
-
-
-
-# define oln_decl_binary_op(OperatorName, OperatorSymbol)		\
-									\
-  template <typename T1, typename T2>					\
-  struct set_overload_2 < tag::op_##OperatorName,			\
-			  where<T1, whatever>,				\
-			  where<T2, whatever> >				\
-  {									\
-    typedef bool ret;							\
-    static ret exec(const T1& lhs, const T2& rhs)			\
-    {									\
-      return oln::internal::operator_##OperatorName(lhs, rhs);		\
-    }									\
-  };									\
-									\
-  template <typename T1, typename T2>					\
-  struct set_overload_2 < tag::op_##OperatorName,			\
-			  where<T1, ntg::value>,			\
-			  where<T2, whatever> >				\
-  {									\
-    typedef bool ret;							\
-    static ret exec(const T1& lhs, const T2& rhs)			\
-    {									\
-      return ntg::internal::operator OperatorSymbol (lhs, rhs);		\
-    }									\
-  };									\
-									\
-  template <typename T1, typename T2>					\
-  struct set_overload_2 < tag::op_##OperatorName,			\
-			  where<T1, whatever>,				\
-			  where<T2, ntg::value> >			\
-  {									\
-    typedef bool ret;							\
-    static ret exec(const T1& lhs, const T2& rhs)			\
-    {									\
-      return ntg::internal::operator OperatorSymbol (lhs, rhs);		\
-    }									\
-  };									\
-									\
-  template <typename T1, typename T2>					\
-  struct set_overload_2 < tag::op_##OperatorName,			\
-			  where<T1, ntg::value>,			\
-			  where<T2, ntg::value> >			\
-  {									\
-    typedef bool ret;							\
-    static ret exec(const T1& lhs, const T2& rhs)			\
-    {									\
-      return ntg::internal::operator OperatorSymbol (lhs, rhs);		\
-    }									\
-  };									\
-									\
-  template <typename T1, typename T2>					\
-  typename overload_2<tag::op_##OperatorName, T1, T2>::ret		\
-  operator OperatorSymbol (const T1& lhs, const T2& rhs)		\
-  {									\
-    return overload_2<tag::op_##OperatorName, T1, T2>::exec(lhs, rhs);	\
-  }									\
-									\
-struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
-
-
-
-
-namespace oln
-{
-
-  /// Tags for operators.
-
-  namespace tag
-  {
-
-    // Cmp tags.
-
-    struct op_eq;
-    struct op_neq;
-    struct op_less;
-    struct op_leq;
-    struct op_greater;
-    struct op_geq;
-
-    // Logic tags.
-
-    struct op_not;
-    struct op_and;
-    struct op_nand;
-    struct op_or;
-    struct op_nor;
-    struct op_xor;
-    struct op_xnor;
-
-    // Arith tags.
-
-    struct op_plus;
-    struct op_minus;
-    struct op_uminus;
-    struct op_times;
-    struct op_div;
-    struct op_mod;
-  
-  } // end of namespace tag
-
-
-
-  // Cmp operators.
-
-
-  namespace internal
-  {
-
-    // Empty fwd decl for canonical cmp operators:
-    // operator_eq and operator_less.
-    // Both operands should exactly have the same type (T).
-
-    template <typename T>
-    bool operator_eq(const T&, const T&);
-
-    template <typename T>
-    bool operator_less(const T&, const T&);
-
-
-    // Default impl for oln::internal::operator_*'s.
-
-    // Warning: an important assumption of default impls is that
-    // the return type is bool.
-
-    // FIXME: should they call operator_* or the facade?
-    // e.g., should we replace "not operator_eq(lhs, rhs)" by
-    // "not (lhs == rhs)"?
-
-    template <typename T1, typename T2>
-    bool operator_neq(const T1& lhs, const T2& rhs)
-    {
-      // "lhs != rhs"  is  "not (lhs == rhs)"
-      return not oln::internal::operator_eq(lhs, rhs);
-    }
-
-    template <typename T1, typename T2>
-    bool operator_leq(const T1& lhs, const T2& rhs)
-    {
-      // "lhs <= rhs"  is  "not (rhs < lhs)"
-      return not oln::internal::operator_less(rhs, lhs);
-    }
-
-    template <typename T1, typename T2>
-    bool operator_greater(const T1& lhs, const T2& rhs)
-    {
-      // "lhs > rhs"  is  "rhs < lhs"
-      return oln::internal::operator_less(rhs, lhs);
-    }
-
-    template <typename T1, typename T2>
-    bool operator_geq(const T1& lhs, const T2& rhs)
-    {
-      // "lhs >= rhs"  is  "not (lhs < rhs)"
-      return not oln::internal::operator_less(lhs, rhs);
-    }
-
-  } // end of namespace oln::internal
-
-
-
-  // Section dedicated to ntg types
-  // ------------------------------
-  // When such a type is involved in an "oln::operator something(lhs, rhs)"
-  // call, the default behavior is to turn to ntg to solve this call.
-  // One could think that since we presently *are* in oln, FIXME
-  // 
-
-
-  oln_decl_binary_op(      eq, == );
-  oln_decl_binary_op(     neq, != );
-  oln_decl_binary_op(    less, <  );
-  oln_decl_binary_op(     leq, <= );
-  oln_decl_binary_op( greater, >  );
-  oln_decl_binary_op(     geq, >= );
-
-
-
-} // end of namespace oln
-
-
 #endif // ! OLN_UTILS_OVERLOAD_HH
Index: oln/ops/macro.hh
===================================================================
--- oln/ops/macro.hh	(revision 270)
+++ oln/ops/macro.hh	(working copy)
@@ -28,26 +28,6 @@
 #ifndef OLENA_OPS_MACRO_HH
 # define OLENA_OPS_MACRO_HH
 
-# include <oln/core/abstract/image.hh>
-# include <oln/core/pw/value.hh>
-# include <oln/core/pw/check.hh>
+// FIXME: empty
 
-
-# define oln_decl_image_binary_op(OperatorName)				\
-									\
-  template <typename F1, typename F2>					\
-  struct set_overload_2 < tag::op_##OperatorName,			\
-			  where<F1, oln::abstract::image>,		\
-			  where<F2, oln::abstract::image> >		\
-  {									\
-    typedef bool ret;							\
-    static ret exec(const F1& lhs, const F2& rhs)			\
-    {									\
-      return oln::pw::check(oln::pw_value(lhs) == oln::pw_value(rhs));	\
-    }									\
-  };									\
-									\
-struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
-
-
 #endif // ! OLENA_OPS_MACRO_HH
Index: oln/ops/arith.hh
===================================================================
--- oln/ops/arith.hh	(revision 270)
+++ oln/ops/arith.hh	(working copy)
@@ -28,152 +28,143 @@
 #ifndef OLENA_OPS_ARITH_HH
 # define OLENA_OPS_ARITH_HH
 
+# include <mlc/bool.hh>
+# include <mlc/is_a.hh>
+# include <mlc/typedef.hh>
+
 # include <oln/core/abstract/image.hh>
 # include <oln/core/pw/image.hh>
 # include <oln/core/pw/value.hh>
 # include <oln/core/pw/arith.hh>
 
+# include <oln/ops/overload.hh>
 
-namespace oln
-{
 
-  /// Operator-like "min" and "max" between 2 images.
+# define oln_are_2_images(I1, I2)		\
+mlc::and_< mlc_is_a(I1, abstract::image),	\
+           mlc_is_a(I2, abstract::image) >
 
-  template <typename L, typename R>
-  image_from_pwf< pw::binary_op< f_min_type,
-				 pw::value<L>,
-				 pw::value<R> > >
-  min (const abstract::image<L>& lhs,
-       const abstract::image<R>& rhs)
-  {
-    return image_for_all_p( oln::min(pw_value(lhs), pw_value(rhs)) );
-  }
 
-  template <typename L, typename R>
-  image_from_pwf< pw::binary_op< f_max_type,
-				 pw::value<L>,
-				 pw::value<R> > >
-  max (const abstract::image<L>& lhs,
-       const abstract::image<R>& rhs)
-  {
-    return image_for_all_p( oln::max(pw_value(lhs), pw_value(rhs)) );
-  }
+# define oln_decl_binary_operator_overload(OperatorName, OperatorSymbol)	\
+										\
+  template <typename L, typename R>						\
+  struct decl_overload< mlc::tag::OperatorName##_, 6, L, R >			\
+    : mlc::where< oln_are_2_images(L, R) >					\
+  {										\
+    typedef pw::image< pw::binary_op< mlc::f_##OperatorName##_type,		\
+                                      pw::value<L>,				\
+                                      pw::value<R> > > ret;			\
+  };										\
+										\
+  template <typename L, typename R>						\
+  mlc_binary_ret(OperatorName, L, R)						\
+  operator OperatorSymbol (const abstract::image<L>& lhs,			\
+			   const abstract::image<R>& rhs)			\
+  {										\
+    return pw_image(pw_value(lhs) OperatorSymbol pw_value(rhs));		\
+  }										\
+										\
+struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
 
-  /// Operator-like "inf" and "sup" between 2 images.
 
-  template <typename L, typename R>
-  image_from_pwf< pw::binary_op< f_inf_type,
-				 pw::value<L>,
-				 pw::value<R> > >
-  inf (const abstract::image<L>& lhs,
-       const abstract::image<R>& rhs)
-  {
-    return image_for_all_p( oln::inf(pw_value(lhs), pw_value(rhs)) );
-  }
 
-  template <typename L, typename R>
-  image_from_pwf< pw::binary_op< f_sup_type,
-				 pw::value<L>,
-				 pw::value<R> > >
-  sup (const abstract::image<L>& lhs,
-       const abstract::image<R>& rhs)
-  {
-    return image_for_all_p( oln::sup(pw_value(lhs), pw_value(rhs)) );
-  }
+# define oln_decl_unary_operator_overload(OperatorName, OperatorSymbol)	\
+									\
+  template <typename R>							\
+  struct decl_overload< mlc::tag::OperatorName##_, 6, R >		\
+    : mlc::where< mlc_is_a(R, abstract::image) >			\
+  {									\
+    typedef pw::image< pw::unary_op< mlc::f_##OperatorName##_type,	\
+                                     pw::value<R> > > ret;		\
+  };									\
+									\
+  template <typename R>							\
+  mlc_unary_ret(OperatorName, R)					\
+  operator OperatorSymbol (const abstract::image<R>& rhs)		\
+  {									\
+    return pw_image(OperatorSymbol pw_value(rhs));			\
+  }									\
+									\
+struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
 
 
 
-  /// Operator '+' between 2 images.
+namespace oln
+{
 
-  template <typename L, typename R>
-  oln::image_from_pwf< oln::pw::binary_op< oln::f_plus_type,
-					   oln::pw::value<L>,
-					   oln::pw::value<R> > >
-  operator + (const oln::abstract::image<L>& lhs,
-	      const oln::abstract::image<R>& rhs)
-  {
-    return oln::image_for_all_p(oln::pw_value(lhs) + oln::pw_value(rhs));
-  }
+  // Binary arithmetical operators between images.
 
+  oln_decl_binary_operator_overload(  plus, + );  
+  oln_decl_binary_operator_overload( minus, - );  
+  oln_decl_binary_operator_overload( times, * );  
+  oln_decl_binary_operator_overload(   div, / );  
+  oln_decl_binary_operator_overload(   mod, % );  
 
-  /// Operator '-' between 2 images.
+  oln_decl_unary_operator_overload(    inc, ++ );  
+  oln_decl_unary_operator_overload(    dec, -- );  
+  oln_decl_unary_operator_overload( uminus, - );  
 
-  template <typename L, typename R>
-  oln::image_from_pwf< oln::pw::binary_op< oln::f_minus_type,
-					   oln::pw::value<L>,
-					   oln::pw::value<R> > >
-  operator - (const oln::abstract::image<L>& lhs,
-	      const oln::abstract::image<R>& rhs)
-  {
-    return oln::image_for_all_p(oln::pw_value(lhs) - oln::pw_value(rhs));
-  }
 
+//   /// Operator-like "min" and "max" between 2 images.
 
-  /// Operator '*' between 2 images.
+//   template <typename L, typename R>
+//   image_from_pwf< pw::binary_op< f_min_type,
+// 				 pw::value<L>,
+// 				 pw::value<R> > >
+//   min (const abstract::image<L>& lhs,
+//        const abstract::image<R>& rhs)
+//   {
+//     return image_for_all_p( oln::min(pw_value(lhs), pw_value(rhs)) );
+//   }
 
-  template <typename L, typename R>
-  oln::image_from_pwf< oln::pw::binary_op< oln::f_times_type,
-					   oln::pw::value<L>,
-					   oln::pw::value<R> > >
-  operator * (const oln::abstract::image<L>& lhs,
-	      const oln::abstract::image<R>& rhs)
-  {
-    return oln::image_for_all_p(oln::pw_value(lhs) * oln::pw_value(rhs));
-  }
+//   template <typename L, typename R>
+//   image_from_pwf< pw::binary_op< f_max_type,
+// 				 pw::value<L>,
+// 				 pw::value<R> > >
+//   max (const abstract::image<L>& lhs,
+//        const abstract::image<R>& rhs)
+//   {
+//     return image_for_all_p( oln::max(pw_value(lhs), pw_value(rhs)) );
+//   }
 
+//   /// Operator-like "inf" and "sup" between 2 images.
 
-  /// Operator '/' between 2 images.
+//   template <typename L, typename R>
+//   image_from_pwf< pw::binary_op< f_inf_type,
+// 				 pw::value<L>,
+// 				 pw::value<R> > >
+//   inf (const abstract::image<L>& lhs,
+//        const abstract::image<R>& rhs)
+//   {
+//     return image_for_all_p( oln::inf(pw_value(lhs), pw_value(rhs)) );
+//   }
 
-  template <typename L, typename R>
-  oln::image_from_pwf< oln::pw::binary_op< oln::f_div_type,
-					   oln::pw::value<L>,
-					   oln::pw::value<R> > >
-  operator / (const oln::abstract::image<L>& lhs,
-	      const oln::abstract::image<R>& rhs)
-  {
-    return oln::image_for_all_p(oln::pw_value(lhs) / oln::pw_value(rhs));
-  }
+//   template <typename L, typename R>
+//   image_from_pwf< pw::binary_op< f_sup_type,
+// 				 pw::value<L>,
+// 				 pw::value<R> > >
+//   sup (const abstract::image<L>& lhs,
+//        const abstract::image<R>& rhs)
+//   {
+//     return image_for_all_p( oln::sup(pw_value(lhs), pw_value(rhs)) );
+//   }
 
 
-  /// Operator '%' between 2 images.
 
-  template <typename L, typename R>
-  oln::image_from_pwf< oln::pw::binary_op< oln::f_mod_type,
-					   oln::pw::value<L>,
-					   oln::pw::value<R> > >
-  operator % (const oln::abstract::image<L>& lhs,
-	      const oln::abstract::image<R>& rhs)
-  {
-    return oln::image_for_all_p(oln::pw_value(lhs) % oln::pw_value(rhs));
-  }
-
-
 } // end of namespace oln
 
 
 
-// FIXME...
 
-// /// Operator - (unary) on image.
-
-// template <typename R>
-// oln::image_from_pw< oln::pw::minus< oln::pw::literal< oln_pw_type_of(R, value) >,
-// 				    oln::pw::image<R> > >
-// operator - (const oln::abstract::image<R>& rhs)
-// {
-//   return oln::image_for_all_p( - oln::p_value(rhs));
-// }
-
-
 // template <typename I, typename F>
-// void operator + (const oln::abstract::image<I>&,
-// 		 const oln::pw::abstract::function<F>&)
+// void operator + (const abstract::image<I>&,
+// 		 const pw::abstract::function<F>&)
 // {
 //   struct OLENA_ERROR__args_are_not_compatible();
 // }
 // template <typename F, typename I>
-// void operator + (const oln::pw::abstract::function<F>&,
-// 		 const oln::abstract::image<I>&)
+// void operator + (const pw::abstract::function<F>&,
+// 		 const abstract::image<I>&)
 // {
 //   struct OLENA_ERROR__args_are_not_compatible();
 // }
Index: oln/ops/overload.hh
===================================================================
--- oln/ops/overload.hh	(revision 0)
+++ oln/ops/overload.hh	(revision 0)
@@ -0,0 +1,148 @@
+// Copyright (C) 2005 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library.  This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING.  If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+// MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction.  Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.  This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef OLENA_CORE_OPS_HH
+# define OLENA_CORE_OPS_HH
+
+# include <mlc/cmp.hh>
+# include <mlc/is_a.hh>
+# include <mlc/ftraits.hh>
+
+# include <oln/core/abstract/any.hh>
+
+
+namespace oln {
+
+  namespace tag {
+
+    template <typename Tag>
+    struct is_
+    {};
+
+  } // end of namespace oln::tag
+
+  
+  template < typename Tag,
+	     unsigned i,
+	     typename T1,
+	     typename T2 = mlc::no_type,
+	     typename T3 = mlc::no_type >
+  struct decl_overload : public mlc::undefined_type // FIXME: inheritance is soon obsolete...
+  {
+  };
+
+} // end of namespace oln
+
+
+
+namespace mlc
+{
+  template <typename Tag,
+	    unsigned i,
+	    typename T1, typename T2, typename T3>
+  struct decl_overload< oln::tag::is_<Tag>,
+			i,
+			T1, T2, T3 >
+  :
+    public oln::decl_overload< Tag, i, T1, T2, T3 >
+  {
+  };
+
+} // end of namespace mlc
+
+
+
+# define oln_decl_overload_binary_traits(Name)			\
+								\
+  template <typename T1, typename T2>				\
+  struct decl_overload <tag::Name##_, oln_id, T1, T2>		\
+    : public where< or_< oln_is_any(T1), oln_is_any(T2) > >	\
+  {								\
+    typedef overload<oln::tag::is_<tag::Name##_>, T1, T2> type;	\
+    typedef or_< oln_is_any(T1), oln_is_any(T2) > cond; 	\
+    typedef mlc_typedef_onlyif_of(type, ret, cond) ret;		\
+  };								\
+								\
+struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
+
+
+
+# define oln_decl_overload_unary_traits(Name)			\
+								\
+  template <typename T>						\
+  struct decl_overload <tag::Name##_, oln_id, T>		\
+    : public where< oln_is_any(T) >				\
+  {								\
+    typedef overload<oln::tag::is_<tag::Name##_>, T> type;	\
+    typedef oln_is_any(T) cond;					\
+    typedef mlc_typedef_onlyif_of(type, ret, cond) ret;		\
+  };								\
+								\
+struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
+
+
+
+namespace mlc
+{
+
+  // Arith.
+
+  oln_decl_overload_binary_traits( plus  );
+  oln_decl_overload_binary_traits( minus );
+  oln_decl_overload_binary_traits( times );
+  oln_decl_overload_binary_traits( div   );
+  oln_decl_overload_binary_traits( mod   );
+
+  oln_decl_overload_unary_traits( uminus );
+  oln_decl_overload_unary_traits( inc );
+  oln_decl_overload_unary_traits( dec );
+
+  // Cmp.
+
+  oln_decl_overload_binary_traits(  eq  );
+  oln_decl_overload_binary_traits( neq  );
+  oln_decl_overload_binary_traits( less );
+  oln_decl_overload_binary_traits( leq  );
+  oln_decl_overload_binary_traits( greater );
+  oln_decl_overload_binary_traits( geq  );
+
+  // Logic.
+
+  oln_decl_overload_binary_traits(  and );
+  oln_decl_overload_binary_traits( nand );
+  oln_decl_overload_binary_traits(   or );
+  oln_decl_overload_binary_traits(  nor );
+  oln_decl_overload_binary_traits(  xor );
+  oln_decl_overload_binary_traits( xnor );
+
+  oln_decl_overload_unary_traits(   not );
+
+
+} // end of namespace mlc
+
+
+#endif // ! OLENA_CORE_OPS_HH
Index: oln/ops/logic.hh
===================================================================
--- oln/ops/logic.hh	(revision 270)
+++ oln/ops/logic.hh	(working copy)
@@ -28,61 +28,69 @@
 #ifndef OLENA_OPS_LOGIC_HH
 # define OLENA_OPS_LOGIC_HH
 
+# include <mlc/bool.hh>
+# include <mlc/is_a.hh>
+
 # include <oln/core/abstract/image.hh>
+# include <oln/core/pw/unary_op.hh>
+# include <oln/core/pw/binary_op.hh>
 # include <oln/core/pw/image.hh>
 # include <oln/core/pw/value.hh>
 # include <oln/core/pw/logic.hh>
 
 
-/// Operator 'and' between 2 binary images.
+# define oln_decl_binary_logic_op(OperatorName, OperatorSymbol)		\
+									\
+  template <typename L, typename R>					\
+  struct decl_overload< mlc::tag::OperatorName##_, 6, L, R >		\
+    : mlc::where< mlc::and_< mlc_is_a(L, abstract::image),		\
+			     mlc_is_a(R, abstract::image) > >		\
+  {									\
+    typedef pw::image< pw::binary_op< mlc::f_##OperatorName##_type,	\
+                                      pw::value<L>,			\
+                                      pw::value<R> > > ret;		\
+  };									\
+									\
+  template <typename L, typename R>					\
+  const mlc_binary_ret(OperatorName, L, R)				\
+  operator OperatorSymbol(const abstract::image<L>& lhs,		\
+			  const abstract::image<R>& rhs)		\
+  {									\
+    mlc::and_< mlc_is_a(L, abstract::binary_image),			\
+               mlc_is_a(R, abstract::binary_image) >::ensure();		\
+    return pw_image(pw_value(lhs) OperatorSymbol pw_value(rhs));	\
+  }									\
+									\
+struct e_n_d__w_i_t_h__s_e_m_i_c_o_l_o_n
 
-template <typename L, typename R>
-const oln::image_from_pwf< oln::pw::binary_op< oln::f_and_type,
-					       oln::pw::value<L>,
-					       oln::pw::value<R> > >
-operator and (const oln::abstract::binary_image<L>& lhs,
-	      const oln::abstract::binary_image<R>& rhs)
-{
-  return oln::image_for_all_p(oln::pw_value(lhs) and oln::pw_value(rhs));
-}
 
 
-/// Operator 'or' between 2 binary images.
-
-template <typename L, typename R>
-const oln::image_from_pwf< oln::pw::binary_op< oln::f_or_type,
-					       oln::pw::value<L>,
-					       oln::pw::value<R> > >
-operator or (const oln::abstract::binary_image<L>& lhs,
-	     const oln::abstract::binary_image<R>& rhs)
+namespace oln
 {
-  return oln::image_for_all_p(oln::pw_value(lhs) or oln::pw_value(rhs));
-}
+  oln_decl_binary_logic_op( and, and );
+  oln_decl_binary_logic_op(  or,  or );
+  oln_decl_binary_logic_op( xor, xor );
 
+  /// Unary operator 'not' on a binary image.
 
-/// Operator 'xor' between 2 binary images.
+  template <typename I>
+  struct decl_overload< mlc::tag::not_, 2, I >
+    : mlc::where< mlc_is_a(I, abstract::image) >
+  {
+    typedef pw::image< pw::unary_op< mlc::f_not_type,
+                                     pw::value<I> > > ret;
+  };
 
-template <typename L, typename R>
-const oln::image_from_pwf< oln::pw::binary_op< oln::f_xor_type,
-					       oln::pw::value<L>,
-					       oln::pw::value<R> > >
-operator xor (const oln::abstract::binary_image<L>& lhs,
-	      const oln::abstract::binary_image<R>& rhs)
-{
-  return oln::image_for_all_p(oln::pw_value(lhs) xor oln::pw_value(rhs));
-}
+  template <typename I>
+  const mlc_unary_ret(not, I)
+  operator not (const abstract::image<I>& rhs)
+  {
+    mlc_is_a(I, abstract::binary_image)::ensure();
+    return pw_image(not pw_value(rhs));
+  }
 
 
-// FIXME...
-// /// Unary operator 'not' on a binary image.
+} // end of namespace oln
 
-// template <typename I>
-// oln::image_from_pw< oln::pw::not_< oln::pw::image<I> > >
-// operator ! (const oln::abstract::binary_image<I>& rhs)
-// {
-//   return oln::image_for_all_p(!oln::p_value(rhs));
-// }
 
-
-
 #endif // ! OLENA_OPS_LOGIC_HH
Index: oln/ops/cmp.hh
===================================================================
--- oln/ops/cmp.hh	(revision 270)
+++ oln/ops/cmp.hh	(working copy)
@@ -28,20 +28,75 @@
 #ifndef OLENA_OPS_CMP_HH
 # define OLENA_OPS_CMP_HH
 
-# include <oln/ops/macro.hh>
+# include <oln/core/abstract/image.hh>
 # include <oln/core/pw/cmp.hh>
+# include <oln/core/pw/value.hh>
+# include <oln/core/pw/check.hh>
 
 
-
 namespace oln {
 
-  oln_decl_image_binary_op(eq);
-  oln_decl_image_binary_op(neq);
-  oln_decl_image_binary_op(less);
-  oln_decl_image_binary_op(leq);
-  oln_decl_image_binary_op(greater);
-  oln_decl_image_binary_op(geq);
 
+  /// Operator '==' between 2 images.
+
+  template <typename L, typename R>
+  bool operator == (const abstract::image<L>& lhs,
+		    const abstract::image<R>& rhs)
+  {
+    return pw_check(pw_value(lhs) == pw_value(rhs));
+  }
+
+
+  /// Operator '!=' between 2 images.
+
+  template <typename L, typename R>
+  bool operator != (const abstract::image<L>& lhs,
+		    const abstract::image<R>& rhs)
+  {
+    return pw_check(pw_value(lhs) != pw_value(rhs));
+  }
+
+
+  /// Operator '<'  between 2 images.
+
+  template <typename L, typename R>
+  bool operator <  (const abstract::image<L>& lhs,
+		    const abstract::image<R>& rhs)
+  {
+    return pw_check(pw_value(lhs) <  pw_value(rhs));
+  }
+
+
+  /// Operator '<=' between 2 images.
+
+  template <typename L, typename R>
+  bool operator <= (const abstract::image<L>& lhs,
+		    const abstract::image<R>& rhs)
+  {
+    return pw_check(pw_value(lhs) <= pw_value(rhs));
+  }
+
+
+  /// Operator '>'  between 2 images.
+
+  template <typename L, typename R>
+  bool operator >  (const abstract::image<L>& lhs,
+		    const abstract::image<R>& rhs)
+  {
+    return pw_check(pw_value(lhs) >  pw_value(rhs));
+  }
+
+
+  /// Operator '>=' between 2 images.
+
+  template <typename L, typename R>
+  bool operator >= (const abstract::image<L>& lhs,
+		    const abstract::image<R>& rhs)
+  {
+    return pw_check(pw_value(lhs) >= pw_value(rhs));
+  }
+
+
 } // end of namespace oln
 
 
Index: oln/basics.hh
===================================================================
--- oln/basics.hh	(revision 270)
+++ oln/basics.hh	(working copy)
@@ -38,7 +38,7 @@
 // mlc::
 
 # include <mlc/contract.hh>
-# include <mlc/traits.hh>
+# include <mlc/ftraits.hh>
 # include <mlc/any.hh>
 # include <mlc/types.hh>
 
@@ -50,6 +50,7 @@
 
 // oln::
 
+# include <oln/core/abstract/any.hh>
 # include <oln/core/coord.hh> // FIXME: why?
 
 # include <oln/core/abstract/image.hh>
Index: oln/makefile.src
===================================================================
--- oln/makefile.src	(revision 270)
+++ oln/makefile.src	(working copy)
@@ -69,6 +69,7 @@
   core/3d/size3d.hh				\
   core/3d/window3d.hh				\
 						\
+  core/abstract/any.hh				\
   core/abstract/data_storage.hh			\
   core/abstract/dpoint.hh			\
   core/abstract/grid.hh				\
@@ -108,6 +109,7 @@
   core/coord.hh					\
 						\
   core/gen/attr.hh				\
+  core/gen/cst.hh				\
   core/gen/identity.hh				\
   core/gen/image_with_nbh.hh			\
   core/gen/internal/value_box.hh		\
@@ -147,11 +149,9 @@
   funobj/abstract/unary.hh			\
   funobj/accum.hh				\
   funobj/arith.hh				\
-  funobj/cmp.hh					\
   funobj/decl_attr.hh				\
   funobj/infsup.hh				\
   funobj/invert.hh				\
-  funobj/logic.hh				\
 						\
   io/gz_stream.hh				\
   io/pnm_bin.hh					\
@@ -200,6 +200,7 @@
   ops/cmp.hh					\
   ops/logic.hh					\
   ops/macro.hh					\
+  ops/overload.hh				\
 						\
   utils/buffer.hh				\
   utils/clone.hh				\
Index: oln/morpho/local.hh
===================================================================
--- oln/morpho/local.hh	(revision 270)
+++ oln/morpho/local.hh	(working copy)
@@ -32,6 +32,7 @@
 # include <ntg/core/macros.hh>
 # include <oln/basics.hh>
 # include <oln/funobj/accum.hh>
+# include <oln/funobj/infsup.hh>
 
 
 namespace oln {
Index: oln/level/arith.hh
===================================================================
--- oln/level/arith.hh	(revision 270)
+++ oln/level/arith.hh	(working copy)
@@ -68,7 +68,7 @@
       precondition(input1.size() == input2.size());
 
       oln_type_of(I1, concrete) output("output");
-      output = clone( oln::min(input1, input2) );
+      output = clone( mlc::f_min(input1, input2) );
 
       exiting("level::min");
       return output;
@@ -92,7 +92,7 @@
       precondition(input1.size() == input2.size());
 
       oln_type_of(I1, concrete) output("output");
-      output = clone( oln::max(input1, input2) );
+      output = clone( mlc::f_max(input1, input2) );
 
       exiting("level::max");
       return output;
@@ -116,7 +116,7 @@
       precondition(input1.size() == input2.size());
 
       oln_type_of(I1, concrete) output("output");
-      output = clone( oln::inf(input1, input2) );
+      output = clone( mlc::f_inf(input1, input2) );
 
       exiting("level::inf");
       return output;
@@ -140,7 +140,7 @@
       precondition(input1.size() == input2.size());
 
       oln_type_of(I1, concrete) output("output");
-      output = clone( oln::sup(input1, input2) );
+      output = clone( mlc::f_sup(input1, input2) );
 
       exiting("level::sup");
       return output;
@@ -160,43 +160,43 @@
     };
 
 
+//     template <typename I1, typename I2>
+//     oln_arith_output(plus, I1, I2)
+//     plus (const abstract::image<I1>& input1,
+// 	  const abstract::image<I2>& input2)
+//     {
+//       // FIXME: recording(?)
+//       mlc::eq<oln_type_of(I1, grid),  oln_type_of(I2, grid)>::ensure();
+//       typedef oln::f_::plus_<oln_type_of(I1, value), oln_type_of(I2, value)> fun_type;
+//       return apply2(fun_type(), input1, input2);
+//       // FIXME: does not work yet!
+// //       return apply2(oln::f_plus, input1, input2);
+//     }
+
+
+    // plus
+
     template <typename I1, typename I2>
-    oln_arith_output(plus, I1, I2)
+    oln_arith_output(plus,I1,I2)
     plus (const abstract::image<I1>& input1,
 	  const abstract::image<I2>& input2)
     {
-      // FIXME: recording(?)
       mlc::eq<oln_type_of(I1, grid),  oln_type_of(I2, grid)>::ensure();
-      typedef oln::f_::plus_<oln_type_of(I1, value), oln_type_of(I2, value)> fun_type;
-      return apply2(fun_type(), input1, input2);
-      // FIXME: does not work yet!
-//       return apply2(oln::f_plus, input1, input2);
-    }
 
+      entering("level::plus");
+      registering(input1, "input1");
+      registering(input2, "input2");
 
-//     // plus
+      precondition(input1.size() == input2.size());
 
-//     template <typename I1, typename I2>
-//     oln_arith_output(plus,I1,I2)
-//     plus (const abstract::image<I1>& input1,
-// 	  const abstract::image<I2>& input2)
-//     {
-//       mlc::eq<oln_type_of(I1, grid),  oln_type_of(I2, grid)>::ensure();
+      oln_arith_output(plus,I1,I2) output("output");
+      output = clone( input1 + input2 );
 
-//       entering("level::plus");
-//       registering(input1, "input1");
-//       registering(input2, "input2");
+      exiting("level::plus");
+      return output;
+    }
 
-//       precondition(input1.size() == input2.size());
 
-//       oln_arith_output(plus,I1,I2) output("output");
-//       output = clone( input1 + input2 );
-
-//       exiting("level::plus");
-//       return output;
-//     }
-
-
     // minus
 
     template <typename I1, typename I2>
