diff --git a/CMakeLists.txt b/CMakeLists.txt
index 15bafb7fa8191f30cf1f3d7cb453963c7af03e9e..490c2768f875123e5730278bf89d4b35e8e17525 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -68,6 +68,7 @@ SET (${PROJECT_NAME}_HEADERS
   include/hpp/manipulation/graph/node.hh
   include/hpp/manipulation/graph/edge.hh
   include/hpp/manipulation/graph/node-selector.hh
+  include/hpp/manipulation/graph/guided-node-selector.hh
   include/hpp/manipulation/graph/graph.hh
   include/hpp/manipulation/graph/statistics.hh
   include/hpp/manipulation/graph/graph-component.hh
diff --git a/include/hpp/manipulation/graph/fwd.hh b/include/hpp/manipulation/graph/fwd.hh
index ff2f0529ebd3dd02f93d044ffefd6355ea54b7d9..baf21abbc5feccc8f1f6d4b09a6b735a5ed69f4c 100644
--- a/include/hpp/manipulation/graph/fwd.hh
+++ b/include/hpp/manipulation/graph/fwd.hh
@@ -30,6 +30,7 @@ namespace hpp {
       HPP_PREDEF_CLASS (WaypointEdge);
       HPP_PREDEF_CLASS (LevelSetEdge);
       HPP_PREDEF_CLASS (NodeSelector);
+      HPP_PREDEF_CLASS (GuidedNodeSelector);
       HPP_PREDEF_CLASS (GraphComponent);
       typedef boost::shared_ptr < Graph > GraphPtr_t;
       typedef boost::shared_ptr < Node > NodePtr_t;
@@ -37,6 +38,7 @@ namespace hpp {
       typedef boost::shared_ptr < WaypointEdge > WaypointEdgePtr_t;
       typedef boost::shared_ptr < LevelSetEdge > LevelSetEdgePtr_t;
       typedef boost::shared_ptr < NodeSelector > NodeSelectorPtr_t;
+      typedef boost::shared_ptr < GuidedNodeSelector > GuidedNodeSelectorPtr_t;
       typedef boost::shared_ptr < GraphComponent > GraphComponentPtr_t;
       typedef std::vector < NodePtr_t > Nodes_t;
       typedef std::vector < EdgePtr_t > Edges_t;
diff --git a/include/hpp/manipulation/graph/guided-node-selector.hh b/include/hpp/manipulation/graph/guided-node-selector.hh
new file mode 100644
index 0000000000000000000000000000000000000000..0d3ca92bd2b5e071f2ee9ce7e0feb51c11d8691d
--- /dev/null
+++ b/include/hpp/manipulation/graph/guided-node-selector.hh
@@ -0,0 +1,70 @@
+// Copyright (c) 2014, LAAS-CNRS
+// Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
+//
+// This file is part of hpp-manipulation.
+// hpp-manipulation is free software: you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation, either version
+// 3 of the License, or (at your option) any later version.
+//
+// hpp-manipulation 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 Lesser Public License for more details.  You should have
+// received a copy of the GNU Lesser General Public License along with
+// hpp-manipulation. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef HPP_MANIPULATION_GRAPH_GUIDED_NODE_SELECTOR_HH
+# define HPP_MANIPULATION_GRAPH_GUIDED_NODE_SELECTOR_HH
+
+#include "hpp/manipulation/fwd.hh"
+#include "hpp/manipulation/graph/fwd.hh"
+#include "hpp/manipulation/graph/node-selector.hh"
+
+namespace hpp {
+  namespace manipulation {
+    namespace graph {
+      class HPP_MANIPULATION_DLLAPI GuidedNodeSelector : public NodeSelector
+      {
+        public:
+          /// Create a new GuidedNodeSelector.
+          static GuidedNodeSelectorPtr_t create(const std::string& name,
+              const core::RoadmapPtr_t& roadmap);
+
+          /// Set the target
+          void setNodeList (const Nodes_t& nodeList);
+
+          /// Select randomly an outgoing edge of the given node.
+          virtual EdgePtr_t chooseEdge(const core::NodePtr_t& from) const;
+
+          /// Print the object in a stream.
+          std::ostream& dotPrint (std::ostream& os, dot::DrawingAttributes da = dot::DrawingAttributes ()) const;
+
+        protected:
+          /// Initialization of the object.
+          void init (const GuidedNodeSelectorPtr_t& weak);
+
+          /// Constructor
+          GuidedNodeSelector (const std::string& name,
+              const core::RoadmapPtr_t roadmap) :
+            NodeSelector (name), roadmap_ (roadmap)
+          {}
+
+          /// Print the object in a stream.
+          std::ostream& print (std::ostream& os) const;
+
+        private:
+          /// The target
+          Nodes_t nodeList_;
+
+          /// The roadmap
+          core::RoadmapPtr_t roadmap_;
+
+          /// Weak pointer to itself.
+          GuidedNodeSelectorWkPtr_t wkPtr_;
+      }; // Class NodeSelector
+    } // namespace graph
+  } // namespace manipulation
+} // namespace hpp
+
+#endif // HPP_MANIPULATION_GRAPH_GUIDED_NODE_SELECTOR_HH
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 9d0bd2eb2a6932345994ab4313d4b7e2a3df8f14..a8eb9efa733b34dd9a705f0fd067618f110235fb 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -34,6 +34,7 @@ ADD_LIBRARY(${LIBRARY_NAME} SHARED
   graph/graph.cc
   graph/graph-component.cc
   graph/node-selector.cc
+  graph/guided-node-selector.cc
   graph/statistics.cc
 
   graph/dot.cc
diff --git a/src/astar.hh b/src/astar.hh
new file mode 100644
index 0000000000000000000000000000000000000000..e1f43ffb325304319e7c3bdcc9ff62a615ef074e
--- /dev/null
+++ b/src/astar.hh
@@ -0,0 +1,164 @@
+//
+// Copyright (c) 2015 CNRS
+// Authors: Florent Lamiraux, Joseph Mirabel
+//
+// This file is part of hpp-core
+// hpp-core is free software: you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation, either version
+// 3 of the License, or (at your option) any later version.
+//
+// hpp-core 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 Lesser Public License for more details.  You should have
+// received a copy of the GNU Lesser General Public License along with
+// hpp-core  If not, see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef HPP_CORE_ASTAR_HH
+# define HPP_CORE_ASTAR_HH
+
+# include <limits>
+# include <hpp/core/distance.hh>
+# include <hpp/core/node.hh>
+# include <hpp/core/edge.hh>
+
+# include <hpp/manipulation/fwd.hh>
+# include <hpp/manipulation/graph/node-selector.hh>
+//# include <hpp/core/path-vector.hh>
+
+namespace hpp {
+  namespace manipulation {
+    class Astar
+    {
+    public:
+      typedef std::map <core::NodePtr_t, value_type> CostMap_t;
+      struct CostMapCompFunctor {
+	CostMap_t& cost_;
+	CostMapCompFunctor (CostMap_t& cost) : cost_ (cost) {}
+	bool operator () (const core::NodePtr_t& n1, const core::NodePtr_t& n2)
+	{ return cost_ [n1] < cost_ [n2]; }
+	bool operator () (const core::NodePtr_t& n1, const value_type& val)
+	{ return cost_ [n1] < val; }
+      }; // struc CostMapCompFunctor
+
+      typedef std::list <graph::NodePtr_t> Nodes_t;
+      typedef std::list <core::NodePtr_t> RoadmapNodes_t;
+      typedef std::list <core::EdgePtr_t> RoadmapEdges_t;
+      typedef std::map <core::NodePtr_t, core::EdgePtr_t> Parent_t;
+
+      Astar (const core::DistancePtr_t distance,
+          const graph::NodeSelectorPtr_t& nodeSelector, const core::NodePtr_t& from) :
+	distance_ (distance), selector_ (nodeSelector),
+        from_ (from)
+      {
+        open_.push_back (from);
+        costFromStart_ [from] = 0;
+      }
+
+      Nodes_t solution (const core::NodePtr_t to)
+      {
+	if (parent_.find (to) != parent_.end () ||
+            findPath (to))
+        {
+          core::NodePtr_t node = to;
+          Nodes_t nodes;
+
+          while (node) {
+            Parent_t::const_iterator itNode = parent_.find (node);
+            if (itNode != parent_.end ()) {
+              node = itNode->second->from ();
+              nodes.push_front (selector_->getNode (*node->configuration()));
+            }
+            else node = core::NodePtr_t ();
+          }
+          // We may want to clean it a little
+          // std::unique (nodes.begin(), nodes.end ());
+          return nodes;
+        }
+        return Nodes_t();
+      }
+
+    private:
+      bool findPath (const core::NodePtr_t& to)
+      {
+        // Recompute the estimated cost to goal
+        for (CostMap_t::iterator it = estimatedCostToGoal_.begin ();
+            it != estimatedCostToGoal_.end (); ++it) {
+          it->second = getCostFromStart (it->first) + heuristic (it->first, to);
+        }
+        open_.sort (CostMapCompFunctor (estimatedCostToGoal_));
+
+	while (!open_.empty ()) {
+	  RoadmapNodes_t::iterator itv = open_.begin ();
+          core::NodePtr_t current (*itv);
+	  if (current == to) {
+	    return true;
+	  }
+	  open_.erase (itv);
+	  closed_.push_back (current);
+	  for (RoadmapEdges_t::const_iterator itEdge = current->outEdges ().begin ();
+	       itEdge != current->outEdges ().end (); ++itEdge) {
+            core::NodePtr_t child ((*itEdge)->to ());
+	    if (std::find (closed_.begin(), closed_.end(),
+                  child) == closed_.end ()) {
+	      // node is not in closed set
+              value_type transitionCost = edgeCost (*itEdge);
+              value_type tmpCost = getCostFromStart (current) + transitionCost;
+	      bool childNotInOpenSet = (std::find (open_.begin (),
+						   open_.end (),
+						   child) == open_.end ());
+	      if ((childNotInOpenSet) || (tmpCost < getCostFromStart (child))) {
+		parent_ [child] = *itEdge;
+		costFromStart_ [child] = tmpCost;
+                value_type estimatedCost = tmpCost + heuristic (child, to);
+                estimatedCostToGoal_ [child] = estimatedCost;
+                if (childNotInOpenSet) {
+                  // Find the first element not strictly smaller than child
+                  RoadmapNodes_t::iterator pos =
+                    std::lower_bound (open_.begin (), open_.end (),
+                        estimatedCost, CostMapCompFunctor (estimatedCostToGoal_));
+                  open_.insert (pos, child);
+                }
+	      }
+	    }
+	  }
+	}
+        return false;
+      }
+
+      inline value_type heuristic (const core::NodePtr_t node, const core::NodePtr_t to) const
+      {
+	const ConfigurationPtr_t& config = node->configuration ();
+	return (*distance_) (*config, *to->configuration ());
+      }
+
+      inline value_type edgeCost (const core::EdgePtr_t& edge) const
+      {
+	return edge->path ()->length ();
+      }
+
+      value_type getCostFromStart (const core::NodePtr_t& to) const
+      {
+        CostMap_t::const_iterator it = costFromStart_.find (to);
+        if (it == costFromStart_.end())
+          return std::numeric_limits <value_type>::max();
+        return it->second;
+      }
+
+      RoadmapNodes_t closed_;
+      RoadmapNodes_t open_;
+      std::map <core::NodePtr_t, value_type> costFromStart_;
+      std::map <core::NodePtr_t, value_type> estimatedCostToGoal_;
+      Parent_t parent_;
+      core::DistancePtr_t distance_;
+      graph::NodeSelectorPtr_t selector_;
+      core::NodePtr_t from_;
+
+    }; // class Astar
+  } // namespace manipulation
+} // namespace hpp
+
+
+#endif // HPP_CORE_ASTAR_HH
diff --git a/src/graph/guided-node-selector.cc b/src/graph/guided-node-selector.cc
new file mode 100644
index 0000000000000000000000000000000000000000..39cef5847372de997f3bf4b5765d3076e232dfda
--- /dev/null
+++ b/src/graph/guided-node-selector.cc
@@ -0,0 +1,148 @@
+// Copyright (c) 2014, LAAS-CNRS
+// Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
+//
+// This file is part of hpp-manipulation.
+// hpp-manipulation is free software: you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation, either version
+// 3 of the License, or (at your option) any later version.
+//
+// hpp-manipulation 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 Lesser Public License for more details.  You should have
+// received a copy of the GNU Lesser General Public License along with
+// hpp-manipulation. If not, see <http://www.gnu.org/licenses/>.
+
+#include "hpp/manipulation/graph/guided-node-selector.hh"
+
+#include <hpp/util/assertion.hh>
+#include <hpp/model/configuration.hh>
+#include <hpp/core/steering-method.hh>
+
+#include "../astar.hh"
+#include "hpp/manipulation/roadmap.hh"
+
+#include <cstdlib>
+
+namespace hpp {
+  namespace manipulation {
+    namespace graph {
+      GuidedNodeSelectorPtr_t GuidedNodeSelector::create(const std::string& name,
+          const core::RoadmapPtr_t& roadmap)
+      {
+        GuidedNodeSelector* ptr = new GuidedNodeSelector (name, roadmap);
+        GuidedNodeSelectorPtr_t shPtr (ptr);
+        ptr->init (shPtr);
+        return shPtr;
+      }
+
+      void GuidedNodeSelector::init (const GuidedNodeSelectorPtr_t& weak)
+      {
+        NodeSelector::init (weak);
+        wkPtr_ = weak;
+      }
+
+      void GuidedNodeSelector::setNodeList (const Nodes_t& nodeList)
+      {
+        nodeList_ = nodeList;
+      }
+
+      EdgePtr_t GuidedNodeSelector::chooseEdge(const core::NodePtr_t& from) const
+      {
+        if (nodeList_.empty ()) return NodeSelector::chooseEdge (from);
+        Astar::Nodes_t list;
+        bool reverse = false;
+        if (from->connectedComponent () == roadmap_->initNode ()->connectedComponent ()) {
+          Astar alg (roadmap_->distance (), wkPtr_.lock(), roadmap_->initNode ());
+          list = alg.solution (from);
+        } else {
+          core::Nodes_t::const_iterator itg = roadmap_->goalNodes ().begin ();
+          for (; itg != roadmap_->goalNodes ().end (); ++itg)
+            if ((*itg)->connectedComponent () == from->connectedComponent ())
+              break;
+          if (itg == roadmap_->goalNodes ().end ()) {
+            hppDout (error, "This configuration can reach neither the initial "
+                "configuration nor any of the goal configurations.");
+            return EdgePtr_t ();
+          }
+          reverse = true;
+          Astar alg (roadmap_->distance (), wkPtr_.lock(), from);
+          list = alg.solution (*itg);
+        }
+        std::unique (list.begin(), list.end ());
+        // Check if the beginning of nodeList is list
+        if (list.size() <= nodeList_.size()) {
+          Neighbors_t nn;
+          if (reverse) {
+            Nodes_t::const_reverse_iterator it1 = nodeList_.rbegin ();
+            Astar::Nodes_t::const_reverse_iterator it2 = list.rbegin();
+            Astar::Nodes_t::const_reverse_iterator itEnd2 = list.rend();
+            do {
+              if (*it1 != *it2) {
+                hppDout (error, "The target sequence of nodes does not end with "
+                    "the sequence of nodes to reach this configuration.");
+                return EdgePtr_t ();
+              }
+              ++it1;
+            } while (++it2 != itEnd2);
+            NodePtr_t node = getNode (*from->configuration ());
+            HPP_ASSERT (node == list.front ());
+            const Neighbors_t& n = node->neighbors();
+            /// You stay in the same node
+            for (Neighbors_t::const_iterator it = n.begin (); it != n.end (); ++it)
+              if (it->second->to () == node)
+                nn.insert (it->second, it->first);
+            const Neighbors_t& n1 = (*it1)->neighbors ();
+            /// Go from node it1 to node
+            for (Neighbors_t::const_iterator it = n1.begin (); it != n1.end (); ++it)
+              if (it->second->to () == node)
+                nn.insert (it->second, it->first);
+          } else {
+            Nodes_t::const_iterator it1 = nodeList_.begin ();
+            Astar::Nodes_t::const_iterator it2 = list.begin();
+            Astar::Nodes_t::const_iterator itEnd2 = list.end();
+            do {
+              if (*it1 != *it2) {
+                hppDout (error, "The target sequence of nodes does not start with "
+                    "the sequence of nodes to reach this configuration.");
+                return EdgePtr_t ();
+              }
+              ++it1;
+            } while (++it2 != itEnd2);
+            NodePtr_t node = getNode (*from->configuration ());
+            HPP_ASSERT (node == list.back ());
+            const Neighbors_t& n = node->neighbors();
+            for (Neighbors_t::const_iterator it = n.begin (); it != n.end (); ++it)
+              /// You stay in the same node
+              /// or go from node to node it1 
+              if (it->second->to () == node || it->second->to () == *it1)
+                nn.insert (it->second, it->first);
+          }
+          if (nn.size () > 0)
+            return nn ();
+          hppDout (error, "This node has no neighbors to get to an admissible states.");
+        }
+        return EdgePtr_t ();
+      }
+
+      std::ostream& GuidedNodeSelector::dotPrint (std::ostream& os, dot::DrawingAttributes) const
+      {
+        for (Nodes_t::const_iterator it = orderedStates_.begin();
+            orderedStates_.end() != it; ++it)
+          (*it)->dotPrint (os);
+        return os;
+      }
+
+      std::ostream& GuidedNodeSelector::print (std::ostream& os) const
+      {
+        os << "|-- ";
+        GraphComponent::print (os) << std::endl;
+        for (Nodes_t::const_iterator it = orderedStates_.begin();
+            orderedStates_.end() != it; ++it)
+          os << *(*it);
+        return os;
+      }
+    } // namespace graph
+  } // namespace manipulation
+} // namespace hpp