diff --git a/doc/Doxyfile.extra.in b/doc/Doxyfile.extra.in
index 89de0f4ba2e5f3e270ebb04b9b58172689bd28de..f1b42d017004736ce179932247030b8d451378ad 100644
--- a/doc/Doxyfile.extra.in
+++ b/doc/Doxyfile.extra.in
@@ -1,3 +1,14 @@
-TAGFILES	= @HPP_MODEL_DOXYGENDOCDIR@/hpp-model.doxytag = @HPP_MODEL_DOXYGENDOCDIR@/hpp-model.doxytag \
-		@HPP_CORE_DOXYGENDOCDIR@/hpp-core.doxytag = @HPP_CORE_DOXYGENDOCDIR@/hpp-core.doxytag \
-		@HPP_CONSTRAINTS_DOXYGENDOCDIR@/hpp-constraints.doxytag = @HPP_CONSTRAINTS_DOXYGENDOCDIR@/hpp-constraints.doxytag
+INPUT     = @CMAKE_SOURCE_DIR@/doc \
+            @CMAKE_SOURCE_DIR@/include \
+            @CMAKE_BINARY_DIR@/doc
+
+TAGFILES	= @HPP_MODEL_DOXYGENDOCDIR@/hpp-model.doxytag=@HPP_MODEL_DOXYGENDOCDIR@ \
+            @HPP_CORE_DOXYGENDOCDIR@/hpp-core.doxytag=@HPP_CORE_DOXYGENDOCDIR@ \
+            @HPP_CONSTRAINTS_DOXYGENDOCDIR@/hpp-constraints.doxytag=@HPP_CONSTRAINTS_DOXYGENDOCDIR@
+
+HTML_EXTRA_FILES = @CMAKE_SOURCE_DIR@/doc/ObjectManipulation_MasterThesis_JosephMirabel.pdf
+
+ALIASES   += Link{1}="\ref \1"
+ALIASES   += Link{2}="\ref \1 \"\2\""
+ALIASES   += LHPP{2}="\Link{hpp::\1::\2, \2}"
+ALIASES   += LModel{1}="\LHPP{model, \1}"
diff --git a/doc/ObjectManipulation_MasterThesis_JosephMirabel.pdf b/doc/ObjectManipulation_MasterThesis_JosephMirabel.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..40e09433d7dd51bb75abce9affc5e783255b31a9
Binary files /dev/null and b/doc/ObjectManipulation_MasterThesis_JosephMirabel.pdf differ
diff --git a/doc/main.hh b/doc/main.hh
new file mode 100644
index 0000000000000000000000000000000000000000..931527e92cf542dc73b4446ffcde08da08a6a51e
--- /dev/null
+++ b/doc/main.hh
@@ -0,0 +1,48 @@
+namespace hpp {
+  namespace manipulation {
+    namespace graph {
+/**
+ \mainpage
+
+ \section sec_intro_hpp_manipulation Introduction
+
+ This package implements a solver for manipulation planning problems. A manipulation planning problem
+ is defined by:
+ \li Robot Build a \LModel{Device} from several \LModel{Device} and Object,
+ \li Object A \LModel{Device} with Handle,
+ \li Graph A graph of constraints defining the rules of a manipulation problem,
+ \li ManipulationPlanner Implements a RRT-based algorithm to solve manipulation planning problems.
+
+ \section sec_graph_hpp_manipulation Constraint graph
+ The graph of constraint, also referred to as constraint graph, represents the rules of a manipulation problem.
+ The component of the graph are:
+ \li Node represents a state of the Robot with constraints,
+ \li Edge represents a transition between two Node with parametric constraints.
+
+ Node contains a set of \LHPP{core,Constraint} that a configuration of the Robot should satisfy
+ to be in the represented state. To ensure that a configuration is in only one state, the Node are
+ ordered in a NodeSelector. The method NodeSelector::getNode(ConfigurationIn_t) const returns a
+ pointer to the first Node for which Node::contains(ConfigurationIn_t) const returns true.
+ For optimization only, another set of \LHPP{core,Constraint} is used for \LHPP{core,StraightPath} lying in this Node.
+
+ Edge has methods Edge::isInNodeFrom, to tell if a corresponding path lyes in Edge::from() or Edge::to(),
+ and Edge::node(), to retrive this Node.
+ Edge also contains two sets of \LHPP{core,Constraint}:
+ \li Edge::configConstraint() returns a \LHPP{core,ConstraintSet} used to generate a configuration lying in Edge::to()
+     and respecting the offset (previsously set using hpp::core::Constraint::offsetFromConfig),
+ \li Edge::pathConstraint() returns a \LHPP{core,ConstraintSet} to be inserted in \LHPP{core,Path} represented
+     by this Edge.
+ 
+ \note
+   For implementation details, see graph::Graph.
+   For more information about parametric and non-parametric constraints, see \LHPP{core,DifferentiableFunction}
+   and \LHPP{core,ConfigProjector}
+
+ \section sec_solver_hpp_manipulation Manipulation planner
+
+ ManipulationPlanner class implements an algorithm based on RRT. See
+ <a href="ObjectManipulation_MasterThesis_JosephMirabel.pdf">this master thesis</a> for details about the algorithm.
+ **/
+    }
+  }
+}
diff --git a/include/hpp/manipulation/graph/edge.hh b/include/hpp/manipulation/graph/edge.hh
index 351f74213d1fd0f8328b34f6511cfc9f6eef41d3..9edfaf82fde503beab3398ef0708b2242ac45186 100644
--- a/include/hpp/manipulation/graph/edge.hh
+++ b/include/hpp/manipulation/graph/edge.hh
@@ -135,11 +135,19 @@ namespace hpp {
           friend class Graph;
       }; // class Edge
 
-      /// Edge with waypoints
-      /// Waypoint are handled recursively, i.e. class WaypointEdge contains only a
-      /// Node and an Edge, comparatively to class Edge.
+      /// Edge with waypoint.
+      /// Waypoints are handled recursively, i.e.\ class WaypointEdge contains only a
+      /// Node and an Edge, the second Edge being itself.
+      /// In this package, the Node in a WaypointEdge is semantically different from other Node
+      /// because it does not correspond to a state with different manipulation rules. It has
+      /// the same rules as another Node (either Edge::from() or Edge::to()).
+      ///
+      /// Semantically, a waypoint Node is fully part of the WaypointEdge. When a corresponding path
+      /// reaches it, no planning is required to know what to do next. To the contrary, when a path reaches
+      /// Edge::from() or Edge::to(), there may be several possibilities.
+      ///
       /// \note
-      ///   For instance, let's say, between the two nodes \f$N_f\f$ and \f$N_t\f$,
+      ///   Implementation details: let's say, between the two nodes \f$N_f\f$ and \f$N_t\f$,
       ///   two waypoints are required:
       ///   \f$ N_f \xrightarrow{e_0} n_0 \xrightarrow{e_1} n_1 \xrightarrow{E} N_t\f$.
       ///   The outmost WaypointEdg contains:
diff --git a/include/hpp/manipulation/graph/node.hh b/include/hpp/manipulation/graph/node.hh
index 6dde6d6285416b42f47b569b3dfdf77edc02a4da..aeac55092372a813a8a04595353438a3e35e781b 100644
--- a/include/hpp/manipulation/graph/node.hh
+++ b/include/hpp/manipulation/graph/node.hh
@@ -52,9 +52,10 @@ namespace hpp {
               = Edge::create);
 
           /// Check whether the configuration is in this state.
-          /// \return True if this state contains this configuration
-          /// \param config The configuration to be tested.
-          /// \note You should note use that to know in which states a
+          /// \code
+          ///   return configConstraint()->isSatisfied (config);
+          /// \endcode
+          /// \note You should not use this method to know in which states a
           /// configuration is. This only checks if the configuration satisfies
           /// the constraints. Instead, use the class NodeSelector.
           virtual bool contains (ConfigurationIn_t config);