diff --git a/src/handle.cc b/src/handle.cc
index c5a8c13e81b6b611c75130f302e56ce1cc4fdff4..1022ad1b0754a3644abb074aeb61650925515af1 100644
--- a/src/handle.cc
+++ b/src/handle.cc
@@ -32,8 +32,7 @@
 #include <hpp/constraints/generic-transformation.hh>
 
 #include <hpp/constraints/implicit.hh>
-#include <hpp/constraints/explicit.hh>
-#include <hpp/core/explicit-relative-transformation.hh>
+#include <hpp/constraints/explicit/relative-pose.hh>
 
 namespace hpp {
   namespace manipulation {
@@ -70,6 +69,15 @@ namespace hpp {
       return false;
     }
 
+    inline std::size_t maskSize (const std::vector<bool>& mask)
+    {
+      std::size_t res (0);
+      for (std::size_t i = 0; i < 6; ++i) {
+        if (mask[i]) ++res;
+      }
+      return res;
+    }
+
     inline bool is6Dmask (const std::vector<bool>& mask)
     {
       for (std::size_t i = 0; i < 6; ++i) if (!mask[i]) return false;
@@ -111,23 +119,20 @@ namespace hpp {
     ImplicitPtr_t Handle::createGrasp
     (const GripperPtr_t& gripper, std::string n) const
     {
-      using core::ExplicitRelativeTransformation;
       if (n.empty()) {
         n = gripper->name() + "_grasps_" + name() + "_" + maskToStr (mask_);
       }
       // If handle is on a freeflying object, create an explicit constraint
       if (is6Dmask(mask_) && isHandleOnFreeflyer (*this)) {
-	return ExplicitRelativeTransformation::create
+	return constraints::explicit_::RelativePose::create
 	  (n, gripper->joint ()->robot (), gripper->joint (), joint (),
-	   gripper->objectPositionInJoint (), localPosition())->createNumericalConstraint();
+	   gripper->objectPositionInJoint (), localPosition(),
+           mask_, ComparisonTypes_t (6, constraints::EqualToZero));
       }
-      return ImplicitPtr_t
-	(Implicit::create (RelativeTransformation::create
-				      (n,
-				       gripper->joint()->robot(),
-				       gripper->joint (), joint (),
-				       gripper->objectPositionInJoint (),
-				       localPosition(), mask_)));
+      return constraints::implicit::RelativePose::create
+        (n, gripper->joint ()->robot (), gripper->joint (), joint (),
+         gripper->objectPositionInJoint (), localPosition(),
+         mask_, ComparisonTypes_t (maskSize (mask_), constraints::EqualToZero));
     }
 
     ImplicitPtr_t Handle::createGraspComplement
@@ -146,14 +151,10 @@ namespace hpp {
             );
       } else {
         std::vector<bool> Cmask = complementMask(mask_);
-        RelativeTransformationPtr_t function = RelativeTransformation::create
-          (n,
-           gripper->joint()->robot(),
-           gripper->joint (), joint (),
-           gripper->objectPositionInJoint (),
-           localPosition(), Cmask);
-        return Implicit::create (function,
-            ComparisonTypes_t(function->outputSize(), constraints::Equality));
+        return constraints::implicit::RelativePose::create
+          (n, gripper->joint ()->robot (), gripper->joint (), joint (),
+           gripper->objectPositionInJoint (), localPosition(),
+           Cmask, ComparisonTypes_t (maskSize (Cmask), constraints::Equality));
       }
     }
 
@@ -177,23 +178,15 @@ namespace hpp {
       }
       // If handle is on a freeflying object, create an explicit constraint
       if (isHandleOnFreeflyer (*this)) {
-        ExplicitPtr_t enc
-          (ExplicitRelativeTransformation::create
-           (n, gripper->joint ()->robot (), gripper->joint (), joint (),
-            gripper->objectPositionInJoint (),
-            localPosition())->createNumericalConstraint());
-        enc->comparisonType (comp);
-        return enc;
+	return constraints::explicit_::RelativePose::create
+	  (n, gripper->joint ()->robot (), gripper->joint (), joint (),
+	   gripper->objectPositionInJoint (), localPosition(),
+           std::vector <bool> (6, true), comp);
       }
-      return ImplicitPtr_t
-	(Implicit::create (RelativeTransformation::create
-				      (n,
-				       gripper->joint()->robot(),
-				       gripper->joint (), joint (),
-				       gripper->objectPositionInJoint (),
-				       localPosition(),
-                                       list_of (true)(true)(true)(true)(true)
-                                       (true)), comp));
+      return constraints::implicit::RelativePose::create
+        (n, gripper->joint ()->robot (), gripper->joint (), joint (),
+         gripper->objectPositionInJoint (), localPosition(),
+         std::vector <bool> (true, 6), comp);
     }
 
     ImplicitPtr_t Handle::createPreGrasp
@@ -204,12 +197,12 @@ namespace hpp {
       if (n.empty())
         n = "Pregrasp_ " + maskToStr(mask_) + "_" + name ()
           + "_" + gripper->name ();
-      return ImplicitPtr_t
-	(Implicit::create (RelativeTransformation::create
-				      (n,
-				       gripper->joint()->robot(),
-				       gripper->joint (), joint (),
-                                       transform, localPosition(), mask_)));
+      ImplicitPtr_t result
+        (constraints::implicit::RelativePose::create
+         (n, gripper->joint()->robot(), gripper->joint (), joint (),
+          transform, localPosition(), mask_, ComparisonTypes_t
+          (maskSize (mask_), constraints::EqualToZero)));
+      return result;
     }
 
     HandlePtr_t Handle::clone () const
diff --git a/src/steering-method/cross-state-optimization.cc b/src/steering-method/cross-state-optimization.cc
index dbc37768018dd93922d971f81c15c193622cab22..a154034084f1c2fdca52e006cb00d8ed3730cc74 100644
--- a/src/steering-method/cross-state-optimization.cc
+++ b/src/steering-method/cross-state-optimization.cc
@@ -217,15 +217,17 @@ namespace hpp {
         typedef std::vector<States_t> StatesPerConf_t;
         StatesPerConf_t statesPerConf_;
         struct RightHandSideSetter {
-          DifferentiableFunctionPtr_t impF;
+          ImplicitPtr_t impF;
           size_type expFidx;
           Configuration_t* qrhs;
           vector_t rhs;
           RightHandSideSetter () : qrhs (NULL) {}
           // TODO delete this constructor
-          RightHandSideSetter (DifferentiableFunctionPtr_t _impF, size_type _expFidx, Configuration_t* _qrhs)
+          RightHandSideSetter (ImplicitPtr_t _impF, size_type _expFidx,
+                               Configuration_t* _qrhs)
             : impF(_impF), expFidx(_expFidx), qrhs (_qrhs) {}
-          RightHandSideSetter (DifferentiableFunctionPtr_t _impF, size_type _expFidx, vector_t _rhs)
+          RightHandSideSetter (ImplicitPtr_t _impF, size_type _expFidx,
+                               vector_t _rhs)
             : impF(_impF), expFidx(_expFidx), qrhs (NULL), rhs (_rhs) {}
           void apply(constraints::solver::BySubstitution& s)
           {
@@ -235,8 +237,8 @@ namespace hpp {
               else              s.explicitConstraintSet().rightHandSide
                                   (expFidx, rhs);
             } else {
-              if (qrhs != NULL) s.rightHandSideFromInput (impF, DifferentiableFunctionPtr_t(), *qrhs);
-              else              s.rightHandSide          (impF, DifferentiableFunctionPtr_t(), rhs);
+              if (qrhs != NULL) s.rightHandSideFromConfig (impF, *qrhs);
+              else              s.rightHandSide          (impF, rhs);
             }
           }
         };
@@ -280,6 +282,7 @@ namespace hpp {
             std::ostringstream os;
             os << lj->jointName() << " | " << i << " -> " << (i+1);
             DifferentiableFunctionPtr_t f, f_implicit;
+            ImplicitPtr_t c_implicit;
             // i = Input, o = Output,
             // c = Config, v = Velocity
             RowBlockIndices ic, oc, ov;
@@ -298,7 +301,7 @@ namespace hpp {
             } else if (i == N) {
               f = lj->explicitFunction();
               // Currently, this function is mandatory because if the same
-              // joint is locked all along the path, then, one of the LockedJoint 
+              // joint is locked all along the path, then, one of the LockedJoint
               // has to be treated implicitely.
               // TODO it would be smarter to detect this case beforehand. If the
               // chain in broken in the middle, an explicit formulation exists
@@ -323,11 +326,16 @@ namespace hpp {
 
             // It is important to use the index of the function since the same
             // function may be added several times on different part.
-            size_type expFidx = solver.explicitConstraintSet().add
-              (f, ic, oc, iv, ov, cts);
+            constraints::ExplicitPtr_t ec
+              (constraints::Explicit::create (solver.configSpace (), f,
+                                              ic.indices (), oc.indices (),
+                                              iv.indices (), ov.indices (),
+                                              cts));
+            size_type expFidx = solver.explicitConstraintSet().add (ec);
             if (expFidx < 0) {
               if (f_implicit) {
-                solver.add (constraints::Implicit::create (f_implicit, cts));
+                c_implicit = constraints::Implicit::create (f_implicit, cts);
+                solver.add (c_implicit);
               } else {
                 HPP_THROW (std::invalid_argument,
                     "Could not add locked joint " << lj->jointName() <<
@@ -336,10 +344,13 @@ namespace hpp {
             }
 
             // Setting the right hand side must be done later
-            if (rhs.size() > 0)
-              rhsSetters_.push_back (RightHandSideSetter(
-                    f_implicit, expFidx, rhs));
+            if (rhs.size() > 0) {
+              assert (c_implicit);
+              rhsSetters_.push_back
+                (RightHandSideSetter(c_implicit, expFidx, rhs));
+            }
             f_implicit.reset();
+            c_implicit.reset();
           }
 
           // TODO handle numerical constraints
@@ -347,11 +358,12 @@ namespace hpp {
           constraints::ExplicitPtr_t enc;
           const NumericalConstraints_t& ncs = trans->numericalConstraints();
           for (NumericalConstraints_t::const_iterator _nc = ncs.begin();
-              _nc != ncs.end(); ++_nc) {
+               _nc != ncs.end(); ++_nc) {
             constraints::ImplicitPtr_t nc (*_nc);
             enc = HPP_DYNAMIC_PTR_CAST (constraints::Explicit, nc);
 
             DifferentiableFunctionPtr_t f, ef;
+            constraints::ImplicitPtr_t constraint;
             // i = Input, o = Output,
             // c = Config, v = Velocity
             // Configuration_t* qrhs;
@@ -384,18 +396,24 @@ namespace hpp {
               cts = ComparisonTypes_t (f->outputSize(), constraints::EqualToZero);
               // qrhs = NULL;
             }
-
+            constraint = constraints::Implicit::create (f, cts);
             size_type expFidx = -1;
-            if (ef) expFidx = solver.explicitConstraintSet().add
-                      (ef, ic, oc, iv, ov, cts);
-            if (expFidx < 0) solver.add
-                               (constraints::Implicit::create (f, cts));
+            // if (ef) {
+            //   constraints::ExplicitPtr_t ec
+            //     (constraints::Explicit::create (solver.configSpace (), ef,
+            //                                     ic.indices (), oc.indices (),
+            //                                     iv.indices (), ov.indices (),
+            //                                     cts));
+            //   expFidx = solver.explicitConstraintSet().add (ec);
+            // }
+            if (expFidx < 0) solver.add (constraint);
 
             // TODO This must be done later...
             // if (qrhs != NULL) {
             if (rhs.size() > 0) {
-              // solver.rightHandSideFromInput (f, ef, rhs);
-              rhsSetters_.push_back (RightHandSideSetter(f, expFidx, rhs));
+              // solver.rightHandSideFromConfig (f, ef, rhs);
+              rhsSetters_.push_back (RightHandSideSetter
+                                     (constraint, expFidx, rhs));
             }
           }
         }
@@ -430,18 +448,11 @@ namespace hpp {
             enc = HPP_DYNAMIC_PTR_CAST (constraints::Explicit, nc);
             bool added = false;
             if (enc) {
-              added = solver.explicitConstraintSet().add (
-                  enc->explicitFunction(),
-                  _row(enc->inputConf()     , i * nq),
-                  _row(enc->outputConf()    , i * nq),
-                  _col(enc->inputVelocity() , i * nv),
-                  _row(enc->outputVelocity(), i * nv),
-                  enc->comparisonType ());
+              added = solver.explicitConstraintSet().add
+                (explicitConstraintOnWaypoint (enc, i));
             }
             if (!added)
-              solver.add (constraints::Implicit::create
-                          (_stateFunction(nc->functionPtr(), i),
-                           nc->comparisonType()));
+              solver.add (implicitConstraintOnWayPoint (nc, i));
           }
         }
         void _add (const LockedJoints_t& ljs, const std::size_t i)
@@ -449,27 +460,46 @@ namespace hpp {
           for (LockedJoints_t::const_iterator _lj = ljs.begin();
               _lj != ljs.end(); ++_lj) {
             LockedJointPtr_t lj (*_lj);
-            size_type expFidx = solver.explicitConstraintSet().add (
-                lj->explicitFunction(),
-                _row(lj->inputConf()     , i * nq),
-                _row(lj->outputConf()    , i * nq),
-                _col(lj->inputVelocity() , i * nv),
-                _row(lj->outputVelocity(), i * nv),
-                lj->comparisonType ());
+            size_type expFidx = solver.explicitConstraintSet().add
+              (explicitConstraintOnWaypoint (lj, i));
             if (expFidx < 0)
               throw std::invalid_argument ("Could not add locked joint " + lj->jointName());
 
             // This must be done later
-            rhsSetters_.push_back (RightHandSideSetter(
-                  DifferentiableFunctionPtr_t(),
-                  expFidx,
-                  lj->rightHandSide()));
+            rhsSetters_.push_back
+              (RightHandSideSetter(constraints::Implicit::create
+                                   (DifferentiableFunctionPtr_t()),
+                                   expFidx,
+                                   lj->rightHandSide()));
             // solver.rightHandSide (DifferentiableFunctionPtr_t(),
                 // lj->explicitFunction(),
                 // lj->rightHandSide());
           }
         }
 
+        /// Apply constraint on a give waypoint
+        /// \param constaint explicit constraint defined on the configuration
+        ///        space,
+        /// \param i rank of the waypoint in the vector of parameters.
+        constraints::ExplicitPtr_t explicitConstraintOnWaypoint
+        (const constraints::ExplicitPtr_t& constraint,
+         std::size_t i)
+        {
+          assert (i < N);
+          // size_type nq (constraint->explicitFunction ().inputSize ()),
+          //   nv (constraint->function ().inputDerrivativeSize ());
+          segments_t ic (constraint->inputConf ()),
+            oc (constraint->outputConf ()),
+            iv (constraint->inputVelocity ()),
+            ov (constraint->outputVelocity ());
+          // TODO: implicit formulation should be built from input constraint
+          return constraints::Explicit::create
+            (solver.configSpace (), constraint->functionPtr (),
+             _row (ic, i*nq).indices (), _row (oc, i*nq).indices (),
+             _col (iv, i*nv).indices (), _col (ov, i*nv).indices (),
+             constraint->comparisonType ());
+        }
+
         RowBlockIndices _row (segments_t s, const std::size_t& shift)
         {
           for (std::size_t j = 0; j < s.size(); ++j) s[j].first += shift;
@@ -480,6 +510,19 @@ namespace hpp {
           for (std::size_t j = 0; j < s.size(); ++j) s[j].first += shift;
           return ColBlockIndices (s);
         }
+        constraints::ImplicitPtr_t implicitConstraintOnWayPoint
+        (const constraints::ImplicitPtr_t& constraint, std::size_t i)
+        {
+          assert (i < N);
+          ImplicitPtr_t res (constraints::Implicit::create
+                             (StateFunction::Ptr_t
+                              (new StateFunction (constraint->functionPtr (),
+                                                  N * nq, N * nv,
+                                                  segment_t (i * nq, nq),
+                                                  segment_t (i * nv, nv))),
+                              constraint->comparisonType ()));
+          return res;
+        }
         StateFunction::Ptr_t _stateFunction(const DifferentiableFunctionPtr_t inner, const std::size_t i)
         {
           assert (i < N);
@@ -665,7 +708,7 @@ namespace hpp {
         // d.maxDepth = 2;
         d.maxDepth = problem_.getParameter ("CrossStateOptimization/maxDepth").intValue();
 
-        // Find 
+        // Find
         d.queue1.push (d.addInitState());
         std::size_t idxSol = (d.s1 == d.s2 ? 1 : 0);
         bool maxDepthReached = findTransitions (d);