* mln/world/k1/fill_0_from_1_faces.hh,
	* mln/world/k1/fill_1_from_2_faces.hh,
	* mln/world/k2/fill_non_primary_from_primary_2_faces.hh,
	* mln/world/kn/fill_0_from_1_faces.hh,
	* mln/world/kn/fill_0_from_2_faces.hh,
	* mln/world/kn/fill_1_from_2_faces.hh,
	* mln/world/kn/fill_1_from_aux_2_faces.hh,
	* mln/world/kn/fill_2_from_1_faces.hh,
	* mln/world/kn/internal/fill_primary_2_faces_from_input.hh,
	* mln/world/kn/un_immerse.hh: Here.
	* mln/world/kn/safe_cast.hh: Add safe_cast overloads.
---
 milena/ChangeLog                                   |   17 +++++
 milena/mln/world/k1/fill_0_from_1_faces.hh         |   26 +++++----
 milena/mln/world/k1/fill_1_from_2_faces.hh         |   31 ++++++----
 .../k2/fill_non_primary_from_primary_2_faces.hh    |   63 +++++++++----------
 milena/mln/world/kn/fill_0_from_1_faces.hh         |   29 +++++----
 milena/mln/world/kn/fill_0_from_2_faces.hh         |   26 +++++----
 milena/mln/world/kn/fill_1_from_2_faces.hh         |   26 +++++----
 milena/mln/world/kn/fill_1_from_aux_2_faces.hh     |   39 +++++++-----
 milena/mln/world/kn/fill_2_from_1_faces.hh         |   23 ++++---
 .../kn/internal/fill_primary_2_faces_from_input.hh |   13 ++--
 milena/mln/world/kn/safe_cast.hh                   |   64 +++++++++++++++++++-
 milena/mln/world/kn/un_immerse.hh                  |    6 +-
 12 files changed, 230 insertions(+), 133 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 6dedd0d..d0db77e 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,20 @@
+2012-11-01  Guillaume Lazzara  <z(a)lrde.epita.fr>
+
+	Make use of safe_cast.
+
+	* mln/world/k1/fill_0_from_1_faces.hh,
+	* mln/world/k1/fill_1_from_2_faces.hh,
+	* mln/world/k2/fill_non_primary_from_primary_2_faces.hh,
+	* mln/world/kn/fill_0_from_1_faces.hh,
+	* mln/world/kn/fill_0_from_2_faces.hh,
+	* mln/world/kn/fill_1_from_2_faces.hh,
+	* mln/world/kn/fill_1_from_aux_2_faces.hh,
+	* mln/world/kn/fill_2_from_1_faces.hh,
+	* mln/world/kn/internal/fill_primary_2_faces_from_input.hh,
+	* mln/world/kn/un_immerse.hh: Here.
+
+	* mln/world/kn/safe_cast.hh: Add safe_cast overloads.
+
 2012-10-31  Guillaume Lazzara  <z(a)lrde.epita.fr>
 
 	* mln/world/kn/display_enlarged.hh: Fix.
diff --git a/milena/mln/world/k1/fill_0_from_1_faces.hh b/milena/mln/world/k1/fill_0_from_1_faces.hh
index c906461..a0c3179 100644
--- a/milena/mln/world/k1/fill_0_from_1_faces.hh
+++ b/milena/mln/world/k1/fill_0_from_1_faces.hh
@@ -32,6 +32,7 @@
 
 # include <mln/core/alias/point2d.hh>
 # include <mln/world/kn/is_0_face.hh>
+# include <mln/world/kn/safe_cast.hh>
 # include <mln/world/kn/is_1_face_vertical.hh>
 # include <mln/world/kn/is_1_face_horizontal.hh>
 
@@ -85,15 +86,18 @@ namespace mln
       {
 	trace::entering("mln::world::k1::fill_0_from_1_faces");
 
-	mln_precondition(exact(inout_).is_valid());
 	I& inout = exact(inout_);
 	const F& f = exact(f_);
 
+	mln_precondition(inout.is_valid());
+
 	mln_piter(I) p(inout.domain());
 	for_all(p)
 	  if (kn::is_0_face(p))
-	    inout(p) = f(inout(p + up), inout(p + left),
-			 inout(p + right), inout(p + down));
+	    inout(p) = kn::safe_cast(f(kn::safe_cast(inout(p + up)),
+				       kn::safe_cast(inout(p + left)),
+				       kn::safe_cast(inout(p + right)),
+				       kn::safe_cast(inout(p + down))));
 
 	trace::exiting("mln::world::k1::fill_0_from_1_faces");
       }
@@ -103,24 +107,24 @@ namespace mln
       {
 	trace::entering("mln::world::k1::fill_0_from_1_faces");
 
-	mln_precondition(exact(inout_).is_valid());
 	I& inout = exact(inout_);
+ 	mln_precondition(inout.is_valid());
 
-	A accu(exact(accu_));
-
+	A accu = exact(accu_);
+	typedef mln_argument(A) arg;
 	mln_piter(I) p(inout.domain());
 	for_all(p)
 	  if (kn::is_0_face(p))
 	  {
 	    if (inout.domain().has(p + up))
-	      accu.take(inout(p + up));
+	      accu.take(kn::safe_cast_to<arg>(inout(p + up)));
 	    if (inout.domain().has(p + left))
-	      accu.take(inout(p + left));
+	      accu.take(kn::safe_cast_to<arg>(inout(p + left)));
 	    if (inout.domain().has(p + right))
-	      accu.take(inout(p + right));
+	      accu.take(kn::safe_cast_to<arg>(inout(p + right)));
 	    if (inout.domain().has(p + down))
-	      accu.take(inout(p + down));
-	    inout(p) = accu.to_result();
+	      accu.take(kn::safe_cast_to<arg>(inout(p + down)));
+	    inout(p) = safe_cast(accu.to_result());
 	  }
 
 	trace::exiting("mln::world::k1::fill_0_from_1_faces");
diff --git a/milena/mln/world/k1/fill_1_from_2_faces.hh b/milena/mln/world/k1/fill_1_from_2_faces.hh
index 72922ec..a4873c2 100644
--- a/milena/mln/world/k1/fill_1_from_2_faces.hh
+++ b/milena/mln/world/k1/fill_1_from_2_faces.hh
@@ -34,6 +34,7 @@
 # include <mln/world/kn/is_1_face_vertical.hh>
 # include <mln/world/kn/is_1_face_horizontal.hh>
 # include <mln/world/kn/border/compute_1_faces.hh>
+# include <mln/world/kn/safe_cast.hh>
 
 namespace mln
 {
@@ -87,19 +88,21 @@ namespace mln
       {
 	trace::entering("mln::world::k1::fill_1_from_2_faces");
 
-	mln_precondition(exact(inout_).is_valid());
 	I& inout = exact(inout_);
 	const F& f = exact(f_);
 
+	mln_precondition(inout.is_valid());
+
 	kn::border::compute_1_faces(inout, f);
 
-	mln_box(I) b = inout.domain();
-	mln_piter(I) p(b);
+	mln_piter(I) p(inout.domain());
 	for_all(p)
 	  if (kn::is_1_face_vertical(p))
-	    inout(p) = f(inout(p + left), inout(p + right));
+	    inout(p) = kn::safe_cast(f(kn::safe_cast(inout(p + left)),
+				       kn::safe_cast(inout(p + right))));
 	  else if (kn::is_1_face_horizontal(p))
-	    inout(p) = f(inout(p + up), inout(p + down));
+	    inout(p) = kn::safe_cast(f(kn::safe_cast(inout(p + up)),
+				       kn::safe_cast(inout(p + down))));
 
 	trace::exiting("mln::world::k1::fill_1_from_2_faces");
       }
@@ -109,29 +112,31 @@ namespace mln
       {
 	trace::entering("mln::world::k1::fill_1_from_2_faces");
 
-	mln_precondition(exact(inout_).is_valid());
 	I& inout = exact(inout_);
-	A accu(exact(accu_));
+	A accu = exact(accu_);
+
+	mln_precondition(inout.is_valid());
 
+	typedef mln_argument(A) arg;
 	mln_piter(I) p(inout.domain());
 	for_all(p)
 	  if (kn::is_1_face_vertical(p))
 	  {
 	    accu.init();
 	    if (inout.domain().has(p + left))
-	      accu.take(inout(p + left));
+	      accu.take(kn::safe_cast_to<arg>(inout(p + left)));
 	    if (inout.domain().has(p + right))
-	      accu.take(inout(p + right));
-	    inout(p) = accu.to_result();
+	      accu.take(kn::safe_cast_to<arg>(inout(p + right)));
+	    inout(p) = kn::safe_cast(accu.to_result());
 	  }
 	  else if (kn::is_1_face_horizontal(p))
 	  {
 	    accu.init();
 	    if (inout.domain().has(p + up))
-	      accu.take(inout(p + up));
+	      accu.take(kn::safe_cast_to<arg>(inout(p + up)));
 	    if (inout.domain().has(p + down))
-	      accu.take(inout(p + down));
-	    inout(p) = accu.to_result();
+	      accu.take(kn::safe_cast_to<arg>(inout(p + down)));
+	    inout(p) = kn::safe_cast(accu.to_result());
 	  }
 
 	trace::exiting("mln::world::k1::fill_1_from_2_faces");
diff --git a/milena/mln/world/k2/fill_non_primary_from_primary_2_faces.hh b/milena/mln/world/k2/fill_non_primary_from_primary_2_faces.hh
index 0f8d71c..f218fd5 100644
--- a/milena/mln/world/k2/fill_non_primary_from_primary_2_faces.hh
+++ b/milena/mln/world/k2/fill_non_primary_from_primary_2_faces.hh
@@ -111,36 +111,33 @@ namespace mln
       {
 	trace::entering("mln::world::k2::fill_non_primary_from_primary_2_faces");
 
-	mln_precondition(exact(ima_).is_valid());
 	I& ima = exact(ima_);
 	const F2& f_intermediate = exact(f_intermediate_);
 	const F4& f_center = exact(f_center_);
 
-	typedef mln_value(I) VI;
-	typedef mln_argument(F2) V2;
-	typedef mln_argument(F4) V4;
-	mln_box(I) b = ima.domain();
-	mln_piter(I) p(b);
+	mln_precondition(ima.is_valid());
+
+	mln_piter(I) p(ima.domain());
 	for_all(p)
 	  if (is_non_primary_2_face_vertical(p))
 	  {
-	    ima(p) = kn::safe_cast_to<VI>(
-	      f_intermediate(kn::safe_cast_to<V2>(ima(p + 2 * left)),
-			     kn::safe_cast_to<V2>(ima(p + 2 * right))));
+	    ima(p) = kn::safe_cast(
+	      f_intermediate(kn::safe_cast(ima(p + 2 * left)),
+			     kn::safe_cast(ima(p + 2 * right))));
 	  }
 	  else if (is_non_primary_2_face_horizontal(p))
 	  {
-	    ima(p) = kn::safe_cast_to<VI>(
-	      f_intermediate(kn::safe_cast_to<V2>(ima(p + 2 * up)),
-			     kn::safe_cast_to<V2>(ima(p + 2 * down))));
+	    ima(p) = kn::safe_cast(
+	      f_intermediate(kn::safe_cast(ima(p + 2 * up)),
+			     kn::safe_cast(ima(p + 2 * down))));
 	  }
 	  else if (is_non_primary_2_face_center(p))
 	  {
-	    ima(p) = kn::safe_cast_to<VI>(
-	      f_center(kn::safe_cast_to<V4>(ima(p + 2 * up_left)),
-		       kn::safe_cast_to<V4>(ima(p + 2 * up_right)),
-		       kn::safe_cast_to<V4>(ima(p + 2 * down_left)),
-		       kn::safe_cast_to<V4>(ima(p + 2 * down_right))));
+	    ima(p) = kn::safe_cast(
+	      f_center(kn::safe_cast(ima(p + 2 * up_left)),
+		       kn::safe_cast(ima(p + 2 * up_right)),
+		       kn::safe_cast(ima(p + 2 * down_left)),
+		       kn::safe_cast(ima(p + 2 * down_right))));
 	  }
 
 	trace::exiting("mln::world::k2::fill_non_primary_from_primary_2_faces");
@@ -152,46 +149,44 @@ namespace mln
 						 const Accumulator<A>& accu_)
       {
 	trace::entering("mln::world::k2::fill_non_primary_from_primary_2_faces");
-
-	mln_precondition(exact(ima_).is_valid());
 	I& ima = exact(ima_);
 	A accu = exact(accu_);
 
-	typedef mln_value(I) VI;
-	typedef mln_argument(A) V;
-	mln_box(I) b = ima.domain();
-	mln_piter(I) p(b);
+	mln_precondition(ima.is_valid());
+
+	typedef mln_argument(A) arg;
+	mln_piter(I) p(ima.domain());
 	for_all(p)
 	  if (is_non_primary_2_face_vertical(p))
 	  {
 	    accu.init();
 	    if (ima.domain().has(p + 2 * left))
-	      accu.take(kn::safe_cast_to<V>(ima(p + 2 * left)));
+	      accu.take(kn::safe_cast_to<arg>(ima(p + 2 * left)));
 	    if (ima.domain().has(p + 2 * right))
-	      accu.take(kn::safe_cast_to<V>(ima(p + 2 * right)));
-	    ima(p) = kn::safe_cast_to<VI>(accu.to_result());
+	      accu.take(kn::safe_cast_to<arg>(ima(p + 2 * right)));
+	    ima(p) = kn::safe_cast(accu.to_result());
 	  }
 	  else if (is_non_primary_2_face_horizontal(p))
 	  {
 	    accu.init();
 	    if (ima.domain().has(p + 2 * up))
-	      accu.take(kn::safe_cast_to<V>(ima(p + 2 * up)));
+	      accu.take(kn::safe_cast_to<arg>(ima(p + 2 * up)));
 	    if (ima.domain().has(p + 2 * down))
-	      accu.take(kn::safe_cast_to<V>(ima(p + 2 * down)));
-	    ima(p) = kn::safe_cast_to<VI>(accu.to_result());
+	      accu.take(kn::safe_cast_to<arg>(ima(p + 2 * down)));
+	    ima(p) = kn::safe_cast(accu.to_result());
 	  }
 	  else if (is_non_primary_2_face_center(p))
 	  {
 	    accu.init();
 	    if (ima.domain().has(p + 2 * up_left))
-	      accu.take(kn::safe_cast_to<V>(ima(p + 2 * up_left)));
+	      accu.take(kn::safe_cast_to<arg>(ima(p + 2 * up_left)));
 	    if (ima.domain().has(p + 2 * up_right))
-	      accu.take(kn::safe_cast_to<V>(ima(p + 2 * up_right)));
+	      accu.take(kn::safe_cast_to<arg>(ima(p + 2 * up_right)));
 	    if (ima.domain().has(p + 2 * down_left))
-	      accu.take(kn::safe_cast_to<V>(ima(p + 2 * down_left)));
+	      accu.take(kn::safe_cast_to<arg>(ima(p + 2 * down_left)));
 	    if (ima.domain().has(p + 2 * down_right))
-	      accu.take(kn::safe_cast_to<V>(ima(p + 2 * down_right)));
-	    ima(p) = kn::safe_cast_to<VI>(accu.to_result());
+	      accu.take(kn::safe_cast_to<arg>(ima(p + 2 * down_right)));
+	    ima(p) = kn::safe_cast(accu.to_result());
 	  }
 
 	trace::exiting("mln::world::k2::fill_non_primary_from_primary_2_faces");
diff --git a/milena/mln/world/kn/fill_0_from_1_faces.hh b/milena/mln/world/kn/fill_0_from_1_faces.hh
index adcea78..188c4a6 100644
--- a/milena/mln/world/kn/fill_0_from_1_faces.hh
+++ b/milena/mln/world/kn/fill_0_from_1_faces.hh
@@ -32,6 +32,7 @@
 
 # include <mln/core/alias/point2d.hh>
 # include <mln/world/kn/is_0_face.hh>
+# include <mln/world/kn/safe_cast.hh>
 
 namespace mln
 {
@@ -85,26 +86,25 @@ namespace mln
       {
 	trace::entering("mln::world::kn::fill_0_from_1_faces");
 
-	mln_precondition(exact(inout_).is_valid());
 	I& inout = exact(inout_);
-	(void) accu_;
+	mln_precondition(inout.is_valid());
 
-	A accu = A();
-	mln_box(I) b = inout.domain();
-	mln_piter(I) p(b);
+	A accu = exact(accu_);
+	typedef mln_argument(A) arg;
+	mln_piter(I) p(inout.domain());
 	for_all(p)
 	  if (is_0_face(p))
 	  {
 	    accu.init();
 	    if (inout.domain().has(p + left))
-	      accu.take(inout(p + left));
+	      accu.take(safe_cast_to<arg>(inout(p + left)));
 	    if (inout.domain().has(p + right))
-	      accu.take(inout(p + right));
+	      accu.take(safe_cast_to<arg>(inout(p + right)));
 	    if (inout.domain().has(p + up))
-	      accu.take(inout(p + up));
+	      accu.take(safe_cast_to<arg>(inout(p + up)));
 	    if (inout.domain().has(p + down))
-	      accu.take(inout(p + down));
-	    inout(p) = accu.to_result();
+	      accu.take(safe_cast_to<arg>(inout(p + down)));
+	    inout(p) = safe_cast(accu.to_result());
 	  }
 
 	trace::exiting("mln::world::kn::fill_0_from_1_faces");
@@ -117,15 +117,18 @@ namespace mln
       {
 	trace::entering("mln::world::kn::fill_0_from_1_faces");
 
-	mln_precondition(exact(inout_).is_valid());
 	I& inout = exact(inout_);
 	const F& f = exact(f_);
 
+	mln_precondition(inout.is_valid());
+
 	mln_piter(I) p(inout.domain());
 	for_all(p)
 	  if (is_0_face(p))
-	    inout(p) = f(inout(p + left), inout(p + right),
-			 inout(p + up), inout(p + down));
+	    inout(p) = safe_cast(f(safe_cast(inout(p + left)),
+				   safe_cast(inout(p + right)),
+				   safe_cast(inout(p + up)),
+				   safe_cast(inout(p + down))));
 
 	trace::exiting("mln::world::kn::fill_0_from_1_faces");
       }
diff --git a/milena/mln/world/kn/fill_0_from_2_faces.hh b/milena/mln/world/kn/fill_0_from_2_faces.hh
index 6e6ee82..7164309 100644
--- a/milena/mln/world/kn/fill_0_from_2_faces.hh
+++ b/milena/mln/world/kn/fill_0_from_2_faces.hh
@@ -32,6 +32,7 @@
 
 # include <mln/core/alias/point2d.hh>
 # include <mln/world/kn/is_0_face.hh>
+# include <mln/world/kn/safe_cast.hh>
 
 namespace mln
 {
@@ -76,15 +77,18 @@ namespace mln
       {
 	trace::entering("mln::world::kn::fill_0_from_2_faces");
 
-	mln_precondition(exact(inout_).is_valid());
 	I& inout = exact(inout_);
 	F& f = exact(f_);
 
+	mln_precondition(inout.is_valid());
+
 	mln_piter(I) p(inout.domain());
 	for_all(p)
 	  if (kn::is_0_face(p))
-	    inout(p) = f(inout(p + up_left), inout(p + up_right),
-			 inout(p + down_left), inout(p + down_right));
+	    inout(p) = safe_cast(f(safe_cast(inout(p + up_left)),
+				   safe_cast(inout(p + up_right)),
+				   safe_cast(inout(p + down_left)),
+				   safe_cast(inout(p + down_right))));
 
 	trace::exiting("mln::world::kn::fill_0_from_2_faces");
       }
@@ -95,25 +99,25 @@ namespace mln
       {
 	trace::entering("mln::world::kn::fill_0_from_2_faces");
 
-	mln_precondition(exact(inout_).is_valid());
 	I& inout = exact(inout_);
-	(void) accu_;
+	mln_precondition(inout.is_valid());
 
-	A accu = A();
+	A accu = exact(accu_);
+	typedef mln_argument(A) arg;
 	mln_piter(I) p(inout.domain());
 	for_all(p)
 	  if (kn::is_0_face(p))
 	  {
 	    accu.init();
 	    if (inout.domain().has(p + up_left))
-	      accu.take(inout(p + up_left));
+	      accu.take(safe_cast_to<arg>(inout(p + up_left)));
 	    if (inout.domain().has(p + up_right))
-	      accu.take(inout(p + up_right));
+	      accu.take(safe_cast_to<arg>(inout(p + up_right)));
 	    if (inout.domain().has(p + down_left))
-	      accu.take(inout(p + down_left));
+	      accu.take(safe_cast_to<arg>(inout(p + down_left)));
 	    if (inout.domain().has(p + down_right))
-	      accu.take(inout(p + down_right));
-	    inout(p) = accu.to_result();
+	      accu.take(safe_cast_to<arg>(inout(p + down_right)));
+	    inout(p) = safe_cast(accu.to_result());
 	  }
 
 	trace::exiting("mln::world::kn::fill_0_from_2_faces");
diff --git a/milena/mln/world/kn/fill_1_from_2_faces.hh b/milena/mln/world/kn/fill_1_from_2_faces.hh
index 2177f48..c190347 100644
--- a/milena/mln/world/kn/fill_1_from_2_faces.hh
+++ b/milena/mln/world/kn/fill_1_from_2_faces.hh
@@ -34,6 +34,7 @@
 # include <mln/world/kn/is_1_face_vertical.hh>
 # include <mln/world/kn/is_1_face_horizontal.hh>
 # include <mln/world/kn/border/compute_1_faces.hh>
+# include <mln/world/kn/safe_cast.hh>
 
 namespace mln
 {
@@ -87,29 +88,30 @@ namespace mln
       {
 	trace::entering("mln::world::kn::fill_1_from_2_faces");
 
-	mln_precondition(exact(inout_).is_valid());
 	I& inout = exact(inout_);
+	mln_precondition(inout.is_valid());
 
-	A accu(exact(accu_));
+	A accu = exact(accu_);
+	typedef mln_argument(A) arg;
 	mln_piter(I) p(inout.domain());
 	for_all(p)
 	  if (kn::is_1_face_vertical(p))
 	  {
 	    accu.init();
 	    if (inout.domain().has(p + left))
-	      accu.take(inout(p + left));
+	      accu.take(safe_cast_to<arg>(inout(p + left)));
 	    if (inout.domain().has(p + right))
-	      accu.take(inout(p + right));
-	    inout(p) = accu.to_result();
+	      accu.take(safe_cast_to<arg>(inout(p + right)));
+	    inout(p) = safe_cast(accu.to_result());
 	  }
 	  else if (is_1_face_horizontal(p))
 	  {
 	    accu.init();
 	    if (inout.domain().has(p + up))
-	      accu.take(inout(p + up));
+	      accu.take(safe_cast_to<arg>(inout(p + up)));
 	    if (inout.domain().has(p + down))
-	      accu.take(inout(p + down));
-	    inout(p) = accu.to_result();
+	      accu.take(safe_cast_to<arg>(inout(p + down)));
+	    inout(p) = safe_cast(accu.to_result());
 	  }
 
 	trace::exiting("mln::world::kn::fill_1_from_2_faces");
@@ -121,18 +123,20 @@ namespace mln
       {
 	trace::entering("mln::world::kn::fill_1_from_2_faces");
 
-	mln_precondition(exact(inout_).is_valid());
 	I& inout = exact(inout_);
 	const F& f = exact(f_);
+	mln_precondition(inout.is_valid());
 
 	kn::border::compute_1_faces(inout, f);
 
 	mln_piter(I) p(inout.domain());
 	for_all(p)
 	  if (kn::is_1_face_vertical(p))
-	    inout(p) = f(inout(p + left), inout(p + right));
+	    inout(p) = safe_cast(f(safe_cast(inout(p + left)),
+				   safe_cast(inout(p + right))));
 	  else if (is_1_face_horizontal(p))
-	    inout(p) = f(inout(p + up), inout(p + down));
+	    inout(p) = safe_cast(f(safe_cast(inout(p + up)),
+				   safe_cast(inout(p + down))));
 
 	trace::exiting("mln::world::kn::fill_1_from_2_faces");
       }
diff --git a/milena/mln/world/kn/fill_1_from_aux_2_faces.hh b/milena/mln/world/kn/fill_1_from_aux_2_faces.hh
index 820e78f..d18e3c8 100644
--- a/milena/mln/world/kn/fill_1_from_aux_2_faces.hh
+++ b/milena/mln/world/kn/fill_1_from_aux_2_faces.hh
@@ -35,6 +35,7 @@
 # include <mln/world/kn/is_1_face_vertical.hh>
 # include <mln/world/kn/is_1_face_horizontal.hh>
 # include <mln/world/kn/border/compute_1_faces.hh>
+# include <mln/world/kn/safe_cast.hh>
 
 namespace mln
 {
@@ -96,21 +97,24 @@ namespace mln
       {
 	trace::entering("mln::world::kn::fill_1_from_aux_2_faces");
 
-	mln_precondition(exact(inout_).is_valid());
-	mln_precondition(exact(aux_).is_valid());
-	mln_precondition(exact(inout_).domain() == exact(aux_).domain());
 	I& inout = exact(inout_);
 	const J& aux = exact(aux_);
 	F& f = exact(f_);
 
+	mln_precondition(inout.is_valid());
+	mln_precondition(aux.is_valid());
+	mln_precondition(inout.domain() == aux.domain());
+
 	kn::border::compute_1_faces(inout, f);
 
 	mln_piter(I) p(inout.domain());
 	for_all(p)
 	  if (kn::is_1_face_vertical(p))
-	    inout(p) = f(aux(p + left), aux(p + right));
+	    inout(p) = safe_cast(f(safe_cast(aux(p + left)),
+				   safe_cast(aux(p + right))));
 	  else if (kn::is_1_face_horizontal(p))
-	    inout(p) = f(aux(p + up), aux(p + down));
+	    inout(p) = safe_cast(f(safe_cast(aux(p + up)),
+				   safe_cast(aux(p + down))));
 
 	trace::exiting("mln::world::kn::fill_1_from_aux_2_faces");
       }
@@ -122,33 +126,34 @@ namespace mln
       {
 	trace::entering("mln::world::kn::fill_1_from_aux_2_faces");
 
-	mln_precondition(exact(inout_).is_valid());
-	mln_precondition(exact(aux_).is_valid());
-	mln_precondition(exact(inout_).domain() == exact(aux_).domain());
 	I& inout = exact(inout_);
 	const J& aux = exact(aux_);
 
-	A accu(exact(accu_));
-	mln_box(I) b = inout.domain();
-	mln_piter(I) p(b);
+	mln_precondition(inout.is_valid());
+	mln_precondition(aux.is_valid());
+	mln_precondition(inout.domain() == aux.domain());
+
+	A accu = exact(accu_);
+	typedef mln_argument(A) arg;
+	mln_piter(I) p(inout.domain());
 	for_all(p)
 	  if (kn::is_1_face_vertical(p))
 	  {
 	    accu.init();
 	    if (aux.domain().has(p + left))
-	      accu.take(aux(p + left));
+	      accu.take(safe_cast_to<arg>(aux(p + left)));
 	    if (aux.domain().has(p + right))
-	      accu.take(aux(p + right));
-	    inout(p) = accu.to_result();
+	      accu.take(safe_cast_to<arg>(aux(p + right)));
+	    inout(p) = safe_cast(accu.to_result());
 	  }
 	  else if (kn::is_1_face_horizontal(p))
 	  {
 	    accu.init();
 	    if (aux.domain().has(p + up))
-	      accu.take(aux(p + up));
+	      accu.take(safe_cast_to<arg>(aux(p + up)));
 	    if (aux.domain().has(p + down))
-	      accu.take(aux(p + down));
-	    inout(p) = accu.to_result();
+	      accu.take(safe_cast_to<arg>(aux(p + down)));
+	    inout(p) = safe_cast(accu.to_result());
 	  }
 
 	trace::exiting("mln::world::kn::fill_1_from_aux_2_faces");
diff --git a/milena/mln/world/kn/fill_2_from_1_faces.hh b/milena/mln/world/kn/fill_2_from_1_faces.hh
index 097e50f..c38f69f 100644
--- a/milena/mln/world/kn/fill_2_from_1_faces.hh
+++ b/milena/mln/world/kn/fill_2_from_1_faces.hh
@@ -32,6 +32,7 @@
 
 # include <mln/core/alias/point2d.hh>
 # include <mln/world/kn/is_2_face.hh>
+# include <mln/world/kn/safe_cast.hh>
 
 namespace mln
 {
@@ -83,8 +84,10 @@ namespace mln
 	mln_piter(I) p(inout.domain());
 	for_all(p)
 	  if (kn::is_2_face(p))
-	    inout(p) = f(inout(p + up), inout(p + left),
-			 inout(p + right), inout(p + down));
+	    inout(p) = safe_cast(f(safe_cast(inout(p + up)),
+				   safe_cast(inout(p + left)),
+				   safe_cast(inout(p + right)),
+				   safe_cast(inout(p + down))));
 
 	trace::exiting("mln::world::kn::fill_2_from_1_faces");
       }
@@ -95,25 +98,25 @@ namespace mln
       {
 	trace::entering("mln::world::kn::fill_2_from_1_faces");
 
-	mln_precondition(exact(inout_).is_valid());
 	I& inout = exact(inout_);
-	(void) accu_;
+	mln_precondition(inout.is_valid());
 
-	A accu = A();
+	A accu = exact(accu_);
+	typedef mln_argument(A) arg;
 	mln_piter(I) p(inout.domain());
 	for_all(p)
 	  if (kn::is_2_face(p))
 	  {
 	    accu.init();
 	    if (inout.domain().has(p + up))
-	      accu.take(inout(p + up));
+	      accu.take(safe_cast_to<arg>(inout(p + up)));
 	    if (inout.domain().has(p + left))
-	      accu.take(inout(p + left));
+	      accu.take(safe_cast_to<arg>(inout(p + left)));
 	    if (inout.domain().has(p + right))
-	      accu.take(inout(p + right));
+	      accu.take(safe_cast_to<arg>(inout(p + right)));
 	    if (inout.domain().has(p + down))
-	      accu.take(inout(p + down));
-	    inout(p) = accu.to_result();
+	      accu.take(safe_cast_to<arg>(inout(p + down)));
+	    inout(p) = safe_cast(accu.to_result());
 	  }
 
 	trace::exiting("mln::world::kn::fill_2_from_1_faces");
diff --git a/milena/mln/world/kn/internal/fill_primary_2_faces_from_input.hh b/milena/mln/world/kn/internal/fill_primary_2_faces_from_input.hh
index 6a6e31e..5455a81 100644
--- a/milena/mln/world/kn/internal/fill_primary_2_faces_from_input.hh
+++ b/milena/mln/world/kn/internal/fill_primary_2_faces_from_input.hh
@@ -75,21 +75,20 @@ namespace mln
 					const unsigned inner_border_thickness)
 	{
 	  trace::entering("mln::world::kn::internal::fill_primary_2_faces_from_input");
-	  mlc_equal(mln_site(I), mln_site(J))::check();
-	  mln_precondition(exact(ima_).is_valid());
-	  mln_precondition(exact(ima_kn_).is_valid());
-	  mln_precondition(exact(ima_).domain() <= exact(ima_kn_).domain());
-
 	  I& ima_kn = exact(ima_kn_);
 	  const J& ima = exact(ima_);
 
+	  mlc_equal(mln_site(I), mln_site(J))::check();
+	  mln_precondition(ima.is_valid());
+	  mln_precondition(ima_kn.is_valid());
+	  mln_precondition(ima.domain() <= ima_kn.domain());
+
 	  // Filling Primary 2-Faces
-	  typedef mln_value(I) V;
 	  mln_piter(J) p(ima.domain());
 	  for_all(p)
 	  {
 	    mln_site(I) pout = internal::immerse_point(p, n, inner_border_thickness);
-	    ima_kn(pout) = safe_cast_to<V>(ima(p));
+	    ima_kn(pout) = safe_cast(ima(p));
 	  }
 
 	  kn::border::adjust_duplicate_2_faces(ima_kn, 1);
diff --git a/milena/mln/world/kn/safe_cast.hh b/milena/mln/world/kn/safe_cast.hh
index da60265..9d5202d 100644
--- a/milena/mln/world/kn/safe_cast.hh
+++ b/milena/mln/world/kn/safe_cast.hh
@@ -46,12 +46,36 @@ namespace mln
 
       using namespace mln::value;
 
-      /// \brief Safe convertion function for manipulating Kn-immersed
+      // Forward declaration.
+      namespace internal {
+	template <typename Tsrc> struct to_be_casted_t;
+      }
+
+      /*!
+	Use cases:
+
+	int i; 	float j;
+
+	1. safe_cast(i, j);
+	2. j = safe_cast(i);
+	3. j = safe_cast_to<float>(i);
+       */
+
+      /// \brief Safe conversion function for manipulating Kn-immersed
+      /// images.
+      template <typename Tsrc, typename Tdest>
+      void safe_cast(const Tsrc& src, Tdest& dest);
+
+      /// \brief Safe conversion function for manipulating Kn-immersed
+      /// images.
+      template <typename Tsrc>
+      internal::to_be_casted_t<Tsrc> safe_cast(const Tsrc& src);
+
+      /// \brief Safe conversion function for manipulating Kn-immersed
       /// images.
       template <typename Tdest, typename Tsrc>
       Tdest safe_cast_to(const Tsrc& src);
 
-
     } // end of namespace mln::world::kn
 
   } // end of namespace mln::world
@@ -349,11 +373,45 @@ namespace mln
     namespace kn
     {
 
+      namespace internal
+      {
+
+	template <typename Tsrc>
+	struct to_be_casted_t
+	{
+	  to_be_casted_t(const Tsrc& src) : src(src) {}
+	  Tsrc src;
+
+	  template <typename Tdest>
+	  operator Tdest const()
+	  {
+	    Tdest dest;
+	    safe_cast_(src, dest);
+	    return dest;
+	  }
+	};
+
+      } // end of namespace mln::world::kn::internal
+
+
+      template <typename Tsrc>
+      internal::to_be_casted_t<Tsrc> safe_cast(const Tsrc& src)
+      {
+	internal::to_be_casted_t<Tsrc> tmp(src);
+	return tmp;
+      }
+
+      template <typename Tsrc, typename Tdest>
+      void safe_cast(const Tsrc& src, Tdest& dest)
+      {
+	safe_cast_(src, dest);
+      }
+
       template <typename Tdest, typename Tsrc>
       Tdest safe_cast_to(const Tsrc& src)
       {
 	Tdest dest;
-	safe_cast_(src, dest);
+	safe_cast(src, dest);
 	return dest;
       }
 
diff --git a/milena/mln/world/kn/un_immerse.hh b/milena/mln/world/kn/un_immerse.hh
index ead7132..0d125e8 100644
--- a/milena/mln/world/kn/un_immerse.hh
+++ b/milena/mln/world/kn/un_immerse.hh
@@ -92,8 +92,8 @@ namespace mln
 	B
 	domain_K0_from_Kn(const Box<B>& b_, const unsigned n)
 	{
-	  mln_precondition(exact(b_).is_valid());
 	  const B& b = exact(b_);
+	  mln_precondition(b.is_valid());
 	  return B(un_immerse_point(b.pmin(), n),
 		   un_immerse_point(b.pmax(), n));
 	}
@@ -109,15 +109,15 @@ namespace mln
 		 const V& new_value_type)
       {
 	trace::entering("mln::world::kn::un_immerse");
-	mln_precondition(exact(ima_).is_valid());
 	const I& ima = exact(ima_);
 	(void) new_value_type;
+	mln_precondition(ima.is_valid());
 
 	mln_ch_value(I,V) output(internal::domain_K0_from_Kn(ima.domain(), n));
 
 	mln_piter(I) p(output.domain());
 	for_all(p)
-	  output(p) = safe_cast_to<V>(ima(internal::immerse_point(p, n)));
+	  output(p) = safe_cast(ima(internal::immerse_point(p, n)));
 
 	trace::exiting("mln::world::kn::un_immerse");
 	return output;
-- 
1.7.2.5