diff --git a/src/graph-path-validation.cc b/src/graph-path-validation.cc
index c6d80ae4be162ba0da93c7e6ef50f0afb30c6794..f50e2c905a1e90ff885a9de3c24850df06f62bd6 100644
--- a/src/graph-path-validation.cc
+++ b/src/graph-path-validation.cc
@@ -34,40 +34,40 @@ namespace hpp {
           const PathPtr_t& path, bool reverse, PathPtr_t& validPart)
     {
       assert (path);
-      PathPtr_t pathGraphValid;
-      bool graphValid = impl_validate (path, reverse, pathGraphValid);
-      bool collisionValid = pathValidation_->validate (pathGraphValid, reverse, validPart);
-      return graphValid && collisionValid;
+      return impl_validate (path, reverse, validPart);
     }
 
     bool GraphPathValidation::impl_validate (
         const PathVectorPtr_t& path, bool reverse, PathPtr_t& validPart)
     {
-      size_t start = 0,
-             end = path->numberPaths ();
-      int inc = 1;
-      value_type timeOffset = path->timeRange().first;
-      if (reverse) {
-        std::swap (start, end);
-        start--;end--;
-        inc = -1;
-        timeOffset = path->timeRange ().second;
-      }
       PathPtr_t validSubPart;
-      for (size_t index = start; index != end; index += inc) {
-        // We should stop at the first non valid subpath.
-        if (!impl_validate (path->pathAtRank (index), reverse, validSubPart)) {
-          if (reverse)
-            validPart = path->extract (
-                std::make_pair (timeOffset - validSubPart->timeRange().second,
-                                path->timeRange().second));
-          else
-            validPart = path->extract (
-                std::make_pair (path->timeRange().first,
-                                timeOffset + validSubPart->timeRange().second));
-          return false;
+      if (reverse) {
+        // TODO: This has never been tested.
+        for (int i = path->numberPaths () - 1; i >= 0; i--) {
+          // We should stop at the first non valid subpath.
+          if (!impl_validate (path->pathAtRank (i), true, validSubPart)) {
+            PathVectorPtr_t p = PathVector::create (path->outputSize());
+            for (int v = path->numberPaths () - 1; v > i; v--)
+              p->appendPath (path->pathAtRank(i)->copy());
+            // TODO: Make sure this subpart is generated by the steering method.
+            p->appendPath (validSubPart);
+            validPart = p;
+            return false;
+          }
+        }
+      } else {
+        for (size_t i = 0; i != path->numberPaths (); i++) {
+          // We should stop at the first non valid subpath.
+          if (!impl_validate (path->pathAtRank (i), false, validSubPart)) {
+            PathVectorPtr_t p = PathVector::create (path->outputSize());
+            for (size_t v = 0; v < i; v++)
+              p->appendPath (path->pathAtRank(i)->copy());
+            // TODO: Make sure this subpart is generated by the steering method.
+            p->appendPath (validSubPart);
+            validPart = p;
+            return false;
+          }
         }
-        timeOffset += inc * path->pathAtRank (index)->length();
       }
       // Here, every subpath is valid.
       validPart = path;
@@ -81,28 +81,53 @@ namespace hpp {
       if (pathVector)
         return impl_validate (pathVector, reverse, validPart);
 
-      value_type tmin = path->timeRange ().first;
-      value_type tmax = path->timeRange ().second;
-      if (reverse)
-        std::swap (tmin, tmax);
-      const Path& configAt (*path);
-      graph::Nodes_t origNodes = constraintGraph_->getNode (configAt (tmin));
-      graph::Nodes_t destNodes = constraintGraph_->getNode (configAt (tmax));
+      PathPtr_t pathNoCollision;
+      if (pathValidation_->validate (path, reverse, pathNoCollision)) {
+        validPart = path;
+        return true;
+      }
+      const Path& newPath (*pathNoCollision);
+      value_type newTmin = pathNoCollision->timeRange ().first,
+                 newTmax = pathNoCollision->timeRange ().second,
+                 oldTmin = path->timeRange ().first,
+                 oldTmax = path->timeRange ().second;
+      graph::Nodes_t origNodes, destNodes;
+      try {
+        origNodes = constraintGraph_->getNode (newPath (newTmin));
+        destNodes = constraintGraph_->getNode (newPath (newTmax));
+
+        if (origNodes == constraintGraph_->getNode ((*path) (oldTmin))
+            && destNodes == constraintGraph_->getNode ((*path) (oldTmax))) {
+          validPart = pathNoCollision;
+          return false;
+        }
+      } catch (std::logic_error& e) {
+        /// A configuration has no node, which may be because the path could not be projected.
+        /// Path should be considered invalid.
+        validPart = path->extract (std::make_pair (oldTmin,oldTmin));
+        return false;
+      }
+
+      // Here, the full path is not valid. Moreover, it does not correspond to the same
+      // edge of the constraint graph. Two option are possible:
+      // - Use the steering method to create a new path and validate it.
+      // - Return a null path.
+      assert (!reverse && "This has never been tested with reverse path");
       std::vector <graph::Edges_t> possibleEdges (constraintGraph_->getEdge (origNodes, destNodes));
       // We check for all of them if both nodes are on the same leaf.
       ConstraintSetPtr_t constraints;
       while (!possibleEdges.empty ()) {
         constraints = constraintGraph_->pathConstraint (possibleEdges.back());
-        constraints->offsetFromConfig(configAt (tmin));
-        assert (constraints->isSatisfied (configAt (tmin)));
-        if (constraints == path->constraints ()
-            && constraints->isSatisfied (configAt (tmax))) {
-          validPart = path;
-          return true;
+        constraints->offsetFromConfig(newPath (newTmin));
+        assert (constraints->isSatisfied (newPath (newTmin)));
+        if (constraints->isSatisfied (newPath (newTmax))) {
+          pathNoCollision->constraints (constraints);
+          impl_validate (pathNoCollision, reverse, validPart);
+          return false;
         }
         possibleEdges.pop_back();
       }
-      validPart = PathPtr_t ();
+      validPart = path->extract (std::make_pair (oldTmin,oldTmin));
       return false;
     }
   } // namespace manipulation